Merge lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba
- gen-flwor-opt
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Markos Zaharioudakis |
Approved revision: | 10676 |
Merged at revision: | 11268 |
Proposed branch: | lp:~zorba-coders/zorba/gen-flwor-opt |
Merge into: | lp:zorba |
Diff against target: |
11608 lines (+5426/-3905) 104 files modified
ChangeLog (+3/-0) src/compiler/codegen/plan_visitor.cpp (+38/-46) src/compiler/expression/expr_base.cpp (+17/-1) src/compiler/expression/expr_base.h (+2/-0) src/compiler/expression/expr_clone.cpp (+9/-0) src/compiler/expression/expr_iter.cpp (+2/-2) src/compiler/expression/expr_put.cpp (+5/-3) src/compiler/expression/flwor_expr.cpp (+124/-26) src/compiler/expression/flwor_expr.h (+8/-3) src/compiler/expression/script_exprs.cpp (+24/-1) src/compiler/expression/script_exprs.h (+3/-1) src/compiler/expression/var_expr.h (+13/-0) src/compiler/parsetree/parsenodes.cpp (+7/-6) src/compiler/parsetree/parsenodes.h (+3/-3) src/compiler/rewriter/framework/rewriter_context.cpp (+1/-9) src/compiler/rewriter/framework/rewriter_context.h (+0/-36) src/compiler/rewriter/rewriters/default_optimizer.cpp (+4/-22) src/compiler/rewriter/rules/flwor_rules.cpp (+24/-12) src/compiler/rewriter/rules/fold_rules.cpp (+4/-3) src/compiler/rewriter/rules/hoist_rules.cpp (+25/-16) src/compiler/rewriter/rules/index_join_rule.cpp (+854/-510) src/compiler/rewriter/rules/index_join_rule.h (+96/-0) src/compiler/rewriter/rules/index_matching_rule.cpp (+4/-4) src/compiler/rewriter/rules/nodeid_rules.cpp (+1/-1) src/compiler/rewriter/rules/ruleset.h (+0/-12) src/compiler/rewriter/tools/dataflow_annotations.cpp (+1/-1) src/compiler/rewriter/tools/expr_tools.cpp (+121/-68) src/compiler/rewriter/tools/expr_tools.h (+31/-7) src/compiler/translator/translator.cpp (+18/-14) src/runtime/core/path_iterators.cpp (+10/-8) src/util/dynamic_bitset.cpp (+1/-1) src/util/dynamic_bitset.h (+18/-15) src/zorbaserialization/archiver.cpp (+3/-1) test/fots_driver/fots-driver.xq (+0/-1) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9067.iter (+45/-49) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9068.iter (+57/-61) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9197.iter (+45/-49) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9198.iter (+48/-52) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9199.iter (+48/-52) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9204.iter (+56/-60) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9206.iter (+40/-44) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9207.iter (+48/-52) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9210.iter (+43/-47) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9211.iter (+46/-50) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9212.iter (+54/-58) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9389.iter (+42/-46) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9390.iter (+47/-51) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9391.iter (+47/-51) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9392.iter (+30/-34) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9399.iter (+41/-45) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9400.iter (+41/-45) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/gflwor_02.iter (+187/-0) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/gflwor_03.iter (+181/-0) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/gflwor_04.iter (+110/-0) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/gflwor_05.iter (+115/-0) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/idx1.iter (+71/-75) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/idx10.iter (+134/-0) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/idx11.iter (+61/-0) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/idx3.iter (+88/-0) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/idx4.iter (+101/-98) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/idx8.iter (+99/-0) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/idx9.iter (+86/-0) test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/q8.iter (+68/-72) test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_04.iter (+7/-7) test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_05.iter (+17/-17) test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_11.iter (+55/-46) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-9198.iter (+48/-52) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-9199.iter (+48/-52) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-9212.iter (+54/-58) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-9389.iter (+42/-46) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-9390.iter (+47/-51) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-9392.iter (+30/-34) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-idx1.iter (+71/-75) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-idx4.iter (+101/-98) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-q8.iter (+68/-72) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/q10.iter (+201/-205) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/q8.iter (+68/-72) test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/q9.iter (+117/-125) test/rbkt/ExpCompilerResults/IterPlan/zorba/optim/hoist01.iter (+0/-6) test/rbkt/ExpCompilerResults/IterPlan/zorba/w3c/rdb-queries-results-q5.iter (+257/-261) test/rbkt/ExpCompilerResults/IterPlan/zorba/xmark/q10.iter (+201/-205) test/rbkt/ExpCompilerResults/IterPlan/zorba/xmark/q8.iter (+68/-72) test/rbkt/ExpCompilerResults/IterPlan/zorba/xmark/q9.iter (+117/-125) test/rbkt/ExpQueryResults/zorba/hashjoins/gflwor_02.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/hashjoins/gflwor_03.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/hashjoins/gflwor_04.xml.res (+6/-0) test/rbkt/ExpQueryResults/zorba/hashjoins/gflwor_05.xml.res (+3/-0) test/rbkt/ExpQueryResults/zorba/hashjoins/idx11.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/hashjoins/no_idx2.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/hashjoins/no_idx3.xml.res (+1/-0) test/rbkt/ExpQueryResults/zorba/hashjoins/no_idx5.xml.res (+3/-0) test/rbkt/Queries/zorba/hashjoins/gflwor_01.xq (+13/-0) test/rbkt/Queries/zorba/hashjoins/gflwor_02.xq (+22/-0) test/rbkt/Queries/zorba/hashjoins/gflwor_03.xq (+21/-0) test/rbkt/Queries/zorba/hashjoins/gflwor_04.xq (+101/-0) test/rbkt/Queries/zorba/hashjoins/gflwor_05.xq (+9/-0) test/rbkt/Queries/zorba/hashjoins/idx10.xq (+0/-129) test/rbkt/Queries/zorba/hashjoins/idx11.xq (+8/-0) test/rbkt/Queries/zorba/hashjoins/idx4.xq (+0/-1) test/rbkt/Queries/zorba/hashjoins/idx8.xq (+0/-171) test/rbkt/Queries/zorba/hashjoins/no_idx2.xq (+20/-0) test/rbkt/Queries/zorba/hashjoins/no_idx3.xq (+20/-0) test/rbkt/Queries/zorba/hashjoins/no_idx5.xq (+24/-0) test/rbkt/testdriver.cpp (+1/-1) |
To merge this branch: | bzr merge lp:~zorba-coders/zorba/gen-flwor-opt |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Markos Zaharioudakis | Approve | ||
Review via email: mp+147161@code.launchpad.net |
Commit message
Extended automatic hash-join rule to general flwor and scripting
Description of the change
Extended automatic hash-join rule to general flwor and scripting
Zorba Build Bot (zorba-buildbot) wrote : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job gen-flwor-
The final status was:
22 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job gen-flwor-
The final status was:
16 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job gen-flwor-
The final status was:
18 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job gen-flwor-
The final status was:
18 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Attempt to merge into lp:zorba failed due to conflicts:
text conflict in ChangeLog
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job gen-flwor-
The final status was:
2 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job gen-flwor-
The final status was:
2 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
Markos Zaharioudakis (markos-za) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
The attempt to merge lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba failed. Below is the output from the failed tests.
CMake Error at /home/ceej/
Validation queue job gen-flwor-
The final status was:
5 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
- 10676. By Markos Zaharioudakis
-
bug fix
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job gen-flwor-
All tests succeeded!
Preview Diff
1 | === modified file 'ChangeLog' |
2 | --- ChangeLog 2013-02-28 05:14:35 +0000 |
3 | +++ ChangeLog 2013-02-28 21:53:23 +0000 |
4 | @@ -19,11 +19,14 @@ |
5 | * Extended optimization rules for subsequence function (pushing $startingLoc |
6 | parameter into collection skip if $sourceSeq parameter is from a |
7 | collection). |
8 | + * Extented index join rule to general flwor expressions. |
9 | |
10 | Bug Fixes/Other Changes: |
11 | * Fixed bug #1124273 (xqdoc crash because of annotation literals) |
12 | * Fixed bug #867027 (XQST0059 error messages inconsistent) |
13 | * Fixed bug #1095889 (Improve error message for xml-parsing error). |
14 | + * Fixed bug in index join rule (copy var ids after cloning index domain expr). |
15 | + * Added missing wrapper expressions around some variable references. |
16 | * Fixed bug in the throwing of error XQTY0086 during node construction. |
17 | * Fixed bug #1122396 (Associate origin/destination URI to I/O stream) |
18 | * Fixed bug #1111786 (xml/json parse error location in catch clause). |
19 | |
20 | === modified file 'src/compiler/codegen/plan_visitor.cpp' |
21 | --- src/compiler/codegen/plan_visitor.cpp 2013-02-17 00:59:54 +0000 |
22 | +++ src/compiler/codegen/plan_visitor.cpp 2013-02-28 21:53:23 +0000 |
23 | @@ -810,7 +810,7 @@ |
24 | ZORBA_ASSERT(clauseVarMap->find_var(&var) < 0); |
25 | |
26 | if (flworExpr == clauseVarMap->theClause->get_flwor_expr() && |
27 | - ((clauseVarMap->theClause->get_kind() == flwor_clause::order_clause && |
28 | + ((clauseVarMap->theClause->get_kind() == flwor_clause::orderby_clause && |
29 | flworExpr->is_general()) || |
30 | clauseVarMap->theClause->get_kind() == flwor_clause::materialize_clause)) |
31 | { |
32 | @@ -892,10 +892,12 @@ |
33 | { |
34 | CODEGEN_TRACE_IN(""); |
35 | |
36 | - bool isGeneral = v.is_general(); |
37 | - |
38 | csize numClauses = v.num_clauses(); |
39 | |
40 | + bool isGeneral = v.compute_is_general(); |
41 | + |
42 | + v.set_general(isGeneral); |
43 | + |
44 | if (v.is_sequential()) |
45 | { |
46 | if (!isGeneral) |
47 | @@ -962,6 +964,7 @@ |
48 | |
49 | if (isGeneral) |
50 | { |
51 | + static_context* sctx = v.get_sctx(); |
52 | std::vector<OrderModifier> modifiers; |
53 | std::vector<expr*> orderingExprs; |
54 | |
55 | @@ -971,7 +974,6 @@ |
56 | while (i < numClauses) |
57 | { |
58 | const flwor_clause* c = v.get_clause(i); |
59 | - |
60 | flwor_clause::ClauseKind k = c->get_kind(); |
61 | |
62 | switch (k) |
63 | @@ -990,42 +992,32 @@ |
64 | ++numForClauses; |
65 | } |
66 | |
67 | - if (domExpr->is_sequential()) |
68 | + if (domExpr->is_sequential() && |
69 | + (k == flwor_clause::for_clause || |
70 | + k == flwor_clause::window_clause || |
71 | + numForClauses > 0)) |
72 | { |
73 | - if (k == flwor_clause::for_clause || |
74 | - k == flwor_clause::window_clause || |
75 | - numForClauses > 0) |
76 | - { |
77 | - if (i > 0 && |
78 | - v.get_clause(i-1)->get_kind() != flwor_clause::order_clause && |
79 | - v.get_clause(i-1)->get_kind() != flwor_clause::groupby_clause) |
80 | - { |
81 | - orderby_clause* mat = theCCB->theEM-> |
82 | - create_orderby_clause(v.get_sctx(), |
83 | - c->get_loc(), |
84 | - true, |
85 | - modifiers, |
86 | - orderingExprs); |
87 | - |
88 | - v.add_clause(i, mat); |
89 | - ++i; |
90 | - ++numClauses; |
91 | - } |
92 | - |
93 | - if (i == numClauses -1 || |
94 | - (i < numClauses - 1 && |
95 | - v.get_clause(i+1)->get_kind() != flwor_clause::groupby_clause)) |
96 | - { |
97 | - orderby_clause* mat = theCCB->theEM-> |
98 | - create_orderby_clause(v.get_sctx(), |
99 | - c->get_loc(), |
100 | - true, |
101 | - modifiers, |
102 | - orderingExprs); |
103 | - |
104 | - v.add_clause(i+1, mat); |
105 | - ++numClauses; |
106 | - } |
107 | + if (i > 0 && |
108 | + v.get_clause(i-1)->get_kind() != flwor_clause::orderby_clause && |
109 | + v.get_clause(i-1)->get_kind() != flwor_clause::groupby_clause) |
110 | + { |
111 | + orderby_clause* mat = theCCB->theEM-> |
112 | + create_orderby_clause(sctx, c->get_loc(), true, modifiers, orderingExprs); |
113 | + |
114 | + v.add_clause(i, mat); |
115 | + ++i; |
116 | + ++numClauses; |
117 | + } |
118 | + |
119 | + if (i == numClauses -1 || |
120 | + (i < numClauses - 1 && |
121 | + v.get_clause(i+1)->get_kind() != flwor_clause::groupby_clause)) |
122 | + { |
123 | + orderby_clause* mat = theCCB->theEM-> |
124 | + create_orderby_clause(sctx, c->get_loc(), true, modifiers, orderingExprs); |
125 | + |
126 | + v.add_clause(i+1, mat); |
127 | + ++numClauses; |
128 | } |
129 | } |
130 | |
131 | @@ -1033,7 +1025,7 @@ |
132 | } |
133 | case flwor_clause::where_clause: |
134 | case flwor_clause::groupby_clause: |
135 | - case flwor_clause::order_clause: |
136 | + case flwor_clause::orderby_clause: |
137 | case flwor_clause::count_clause: |
138 | { |
139 | break; |
140 | @@ -1048,11 +1040,11 @@ |
141 | const flwor_clause* lastClause = v.get_clause(v.num_clauses()-1); |
142 | |
143 | if (v.get_return_expr()->is_sequential() && |
144 | - lastClause->get_kind() != flwor_clause::order_clause && |
145 | + lastClause->get_kind() != flwor_clause::orderby_clause && |
146 | lastClause->get_kind() != flwor_clause::groupby_clause) |
147 | { |
148 | orderby_clause* mat = theCCB->theEM-> |
149 | - create_orderby_clause(v.get_sctx(), |
150 | + create_orderby_clause(sctx, |
151 | v.get_return_expr()->get_loc(), |
152 | true, |
153 | modifiers, |
154 | @@ -1123,7 +1115,7 @@ |
155 | break; |
156 | } |
157 | |
158 | - case flwor_clause::order_clause: |
159 | + case flwor_clause::orderby_clause: |
160 | { |
161 | const orderby_clause* oc = reinterpret_cast<const orderby_clause*>(c); |
162 | |
163 | @@ -1270,7 +1262,7 @@ |
164 | break; |
165 | } |
166 | |
167 | - case flwor_clause::order_clause: |
168 | + case flwor_clause::orderby_clause: |
169 | case flwor_clause::materialize_clause: |
170 | { |
171 | break; |
172 | @@ -1625,7 +1617,7 @@ |
173 | // |
174 | // ORDERBY |
175 | // |
176 | - else if (c.get_kind() == flwor_clause::order_clause) |
177 | + else if (c.get_kind() == flwor_clause::orderby_clause) |
178 | { |
179 | csize numVars = clauseVarMap->theVarRebinds.size(); |
180 | csize numForVars = 0; |
181 | @@ -1807,7 +1799,7 @@ |
182 | // |
183 | // ORDERBY |
184 | // |
185 | - case flwor_clause::order_clause: |
186 | + case flwor_clause::orderby_clause: |
187 | { |
188 | const orderby_clause* obc = static_cast<const orderby_clause*>(&c); |
189 | unsigned numColumns = obc->num_columns(); |
190 | |
191 | === modified file 'src/compiler/expression/expr_base.cpp' |
192 | --- src/compiler/expression/expr_base.cpp 2013-01-11 22:58:12 +0000 |
193 | +++ src/compiler/expression/expr_base.cpp 2013-02-28 21:53:23 +0000 |
194 | @@ -974,7 +974,7 @@ |
195 | |
196 | break; |
197 | } |
198 | - case flwor_clause::order_clause: |
199 | + case flwor_clause::orderby_clause: |
200 | { |
201 | if (found) |
202 | return false; |
203 | @@ -1161,6 +1161,22 @@ |
204 | |
205 | |
206 | /******************************************************************************* |
207 | + |
208 | +********************************************************************************/ |
209 | +expr* expr::skip_wrappers() const |
210 | +{ |
211 | + const expr* e = this; |
212 | + |
213 | + while (e->get_expr_kind() == wrapper_expr_kind) |
214 | + { |
215 | + e = static_cast<const wrapper_expr*>(e)->get_input(); |
216 | + } |
217 | + |
218 | + return const_cast<expr*>(e); |
219 | +} |
220 | + |
221 | + |
222 | +/******************************************************************************* |
223 | If "this" is a const expr that returns a qname, evaluate and return this |
224 | qname. This method is used to extract the qname from the expression that is |
225 | given as an arg to collection and index related functions. |
226 | |
227 | === modified file 'src/compiler/expression/expr_base.h' |
228 | --- src/compiler/expression/expr_base.h 2013-01-11 22:58:12 +0000 |
229 | +++ src/compiler/expression/expr_base.h 2013-02-28 21:53:23 +0000 |
230 | @@ -398,6 +398,8 @@ |
231 | |
232 | const store::Item* getQName() const; |
233 | |
234 | + expr* skip_wrappers() const; |
235 | + |
236 | void clear_annotations(); |
237 | |
238 | xqtref_t get_return_type_with_empty_input(const expr* input) const; |
239 | |
240 | === modified file 'src/compiler/expression/expr_clone.cpp' |
241 | --- src/compiler/expression/expr_clone.cpp 2013-01-11 22:58:12 +0000 |
242 | +++ src/compiler/expression/expr_clone.cpp 2013-02-28 21:53:23 +0000 |
243 | @@ -602,8 +602,17 @@ |
244 | |
245 | checked_vector<expr*> seq2; |
246 | for (csize i = 0; i < e->theArgs.size(); ++i) |
247 | + { |
248 | seq2.push_back(e->theArgs[i]->clone(udf, subst)); |
249 | |
250 | + if (e->theArgs[i]->get_expr_kind() == var_decl_expr_kind) |
251 | + { |
252 | + var_decl_expr* varDeclExpr = static_cast<var_decl_expr*>(e->theArgs[i]); |
253 | + var_expr* varExpr = varDeclExpr->get_var_expr(); |
254 | + varExpr->set_block_expr(e); |
255 | + } |
256 | + } |
257 | + |
258 | newExpr = theCCB->theEM-> |
259 | create_block_expr(theSctx, udf, theLoc, true, seq2, NULL); |
260 | |
261 | |
262 | === modified file 'src/compiler/expression/expr_iter.cpp' |
263 | --- src/compiler/expression/expr_iter.cpp 2013-01-11 22:58:12 +0000 |
264 | +++ src/compiler/expression/expr_iter.cpp 2013-02-28 21:53:23 +0000 |
265 | @@ -189,7 +189,7 @@ |
266 | return; |
267 | } |
268 | |
269 | - case flwor_clause::order_clause: |
270 | + case flwor_clause::orderby_clause: |
271 | { |
272 | orderby_clause* oc = static_cast<orderby_clause *>(c); |
273 | |
274 | @@ -384,7 +384,7 @@ |
275 | } |
276 | } |
277 | |
278 | - else if (c->get_kind() == flwor_clause::order_clause) |
279 | + else if (c->get_kind() == flwor_clause::orderby_clause) |
280 | { |
281 | oc = static_cast<orderby_clause *>(c); |
282 | |
283 | |
284 | === modified file 'src/compiler/expression/expr_put.cpp' |
285 | --- src/compiler/expression/expr_put.cpp 2013-01-12 22:10:40 +0000 |
286 | +++ src/compiler/expression/expr_put.cpp 2013-02-28 21:53:23 +0000 |
287 | @@ -337,8 +337,10 @@ |
288 | } |
289 | case flwor_clause::count_clause: |
290 | { |
291 | - os << indent << "COUNT $"; |
292 | - put_qname(static_cast<const count_clause *>(&c)->get_var()->get_name(), os); |
293 | + const count_clause* cc = static_cast<const count_clause *>(&c); |
294 | + os << indent << "COUNT " << expr_addr(cc) << " "; |
295 | + put_qname(cc->get_var()->get_name(), os); |
296 | + os << expr_addr(cc->get_var()); |
297 | os << endl; |
298 | break; |
299 | } |
300 | @@ -358,7 +360,7 @@ |
301 | static_cast<const groupby_clause *>(&c)->put(os); |
302 | break; |
303 | } |
304 | - case flwor_clause::order_clause: |
305 | + case flwor_clause::orderby_clause: |
306 | { |
307 | static_cast<const orderby_clause *>(&c)->put(os); |
308 | break; |
309 | |
310 | === modified file 'src/compiler/expression/flwor_expr.cpp' |
311 | --- src/compiler/expression/flwor_expr.cpp 2012-12-21 03:45:19 +0000 |
312 | +++ src/compiler/expression/flwor_expr.cpp 2013-02-28 21:53:23 +0000 |
313 | @@ -653,7 +653,7 @@ |
314 | const std::vector<OrderModifier>& modifiers, |
315 | const std::vector<expr*>& orderingExprs) |
316 | : |
317 | - flwor_clause(sctx, ccb, loc, flwor_clause::order_clause), |
318 | + flwor_clause(sctx, ccb, loc, flwor_clause::orderby_clause), |
319 | theStableOrder(stable), |
320 | theModifiers(modifiers), |
321 | theOrderingExprs(orderingExprs) |
322 | @@ -831,6 +831,33 @@ |
323 | /******************************************************************************* |
324 | |
325 | ********************************************************************************/ |
326 | +void flwor_expr::remove_clause(flwor_clause* c, csize posHint) |
327 | +{ |
328 | + if (posHint < theClauses.size() && theClauses[posHint] == c) |
329 | + return remove_clause(posHint); |
330 | + |
331 | + csize numClauses = theClauses.size(); |
332 | + csize i = 0; |
333 | + for (; i < numClauses; ++i) |
334 | + { |
335 | + if (theClauses[i] != c) |
336 | + continue; |
337 | + |
338 | + if (theClauses[i]->theFlworExpr == this) |
339 | + theClauses[i]->theFlworExpr = NULL; |
340 | + |
341 | + theClauses.erase(theClauses.begin() + i); |
342 | + |
343 | + return; |
344 | + } |
345 | + |
346 | + assert(i < numClauses); |
347 | +} |
348 | + |
349 | + |
350 | +/******************************************************************************* |
351 | + |
352 | +********************************************************************************/ |
353 | void flwor_expr::add_clause(flwor_clause* c, bool computeScriptingKind) |
354 | { |
355 | theClauses.push_back(c); |
356 | @@ -907,24 +934,6 @@ |
357 | /******************************************************************************* |
358 | For simple flwor only. |
359 | ********************************************************************************/ |
360 | -void flwor_expr::remove_where_clause() |
361 | -{ |
362 | - csize numClauses = num_clauses(); |
363 | - for (csize i = 0; i < numClauses; ++i) |
364 | - { |
365 | - if (theClauses[i]->get_kind() == flwor_clause::where_clause) |
366 | - { |
367 | - theClauses[i]->theFlworExpr = NULL; |
368 | - theClauses.erase(theClauses.begin() + i); |
369 | - return; |
370 | - } |
371 | - } |
372 | -} |
373 | - |
374 | - |
375 | -/******************************************************************************* |
376 | - For simple flwor only. |
377 | -********************************************************************************/ |
378 | expr* flwor_expr::get_where() const |
379 | { |
380 | csize numClauses = num_clauses(); |
381 | @@ -962,7 +971,7 @@ |
382 | csize numClauses = num_clauses(); |
383 | for (csize i = 0; i < numClauses; ++i) |
384 | { |
385 | - if (theClauses[i]->get_kind() == flwor_clause::order_clause) |
386 | + if (theClauses[i]->get_kind() == flwor_clause::orderby_clause) |
387 | return reinterpret_cast<orderby_clause*>(theClauses[i]); |
388 | } |
389 | |
390 | @@ -995,22 +1004,34 @@ |
391 | /******************************************************************************* |
392 | |
393 | ********************************************************************************/ |
394 | -long flwor_expr::defines_variable(const var_expr* v) const |
395 | +bool flwor_expr::defines_var(const var_expr* v) const |
396 | +{ |
397 | + return v->get_flwor_clause()->get_flwor_expr() == this; |
398 | +} |
399 | + |
400 | + |
401 | +/******************************************************************************* |
402 | + |
403 | +********************************************************************************/ |
404 | +bool flwor_expr::get_var_pos(const var_expr* v, csize& pos) const |
405 | { |
406 | const flwor_clause* varClause = v->get_flwor_clause(); |
407 | |
408 | if (varClause == NULL) |
409 | - return -1; |
410 | + return false; |
411 | |
412 | csize numClauses = theClauses.size(); |
413 | |
414 | for (csize i = 0; i < numClauses; ++i) |
415 | { |
416 | if (theClauses[i] == varClause) |
417 | - return i; |
418 | + { |
419 | + pos = i; |
420 | + return true; |
421 | + } |
422 | } |
423 | |
424 | - return -1; |
425 | + return false; |
426 | } |
427 | |
428 | |
429 | @@ -1115,9 +1136,9 @@ |
430 | ********************************************************************************/ |
431 | void flwor_expr::compute_scripting_kind() |
432 | { |
433 | - ulong numClauses = num_clauses(); |
434 | + csize numClauses = num_clauses(); |
435 | |
436 | - for (ulong i = 0; i < numClauses; ++i) |
437 | + for (csize i = 0; i < numClauses; ++i) |
438 | { |
439 | const flwor_clause* c = theClauses[i]; |
440 | flwor_clause::ClauseKind k = c->get_kind(); |
441 | @@ -1163,5 +1184,82 @@ |
442 | } |
443 | |
444 | |
445 | +/******************************************************************************* |
446 | + |
447 | +********************************************************************************/ |
448 | +bool flwor_expr::compute_is_general() |
449 | +{ |
450 | + bool has_where = false; |
451 | + bool has_order = false; |
452 | + bool has_group = false; |
453 | + |
454 | + csize numClauses = num_clauses(); |
455 | + |
456 | + for (csize i = 0; i < numClauses; ++i) |
457 | + { |
458 | + const flwor_clause* c = get_clause(i); |
459 | + |
460 | + switch (c->get_kind()) |
461 | + { |
462 | + case flwor_clause::for_clause: |
463 | + case flwor_clause::let_clause: |
464 | + { |
465 | + if (has_group || has_where || has_order) |
466 | + return true; |
467 | + |
468 | + const forlet_clause* flc = static_cast<const forlet_clause*>(c); |
469 | + |
470 | + if (flc->is_allowing_empty()) |
471 | + return true; |
472 | + |
473 | + break; |
474 | + } |
475 | + case flwor_clause::window_clause: |
476 | + { |
477 | + return true; |
478 | + } |
479 | + case flwor_clause::where_clause: |
480 | + { |
481 | + if (has_where || has_group || has_order) |
482 | + return true; |
483 | + |
484 | + has_where = true; |
485 | + break; |
486 | + } |
487 | + case flwor_clause::orderby_clause: |
488 | + { |
489 | + if (has_order) |
490 | + return true; |
491 | + |
492 | + has_order = true; |
493 | + break; |
494 | + } |
495 | + case flwor_clause::groupby_clause: |
496 | + { |
497 | + if (has_group || has_order) |
498 | + return true; |
499 | + |
500 | + has_group = true; |
501 | + break; |
502 | + } |
503 | + case flwor_clause::count_clause: |
504 | + { |
505 | + return true; |
506 | + } |
507 | + case flwor_clause::materialize_clause: |
508 | + { |
509 | + break; |
510 | + } |
511 | + default: |
512 | + { |
513 | + ZORBA_ASSERT(false); |
514 | + } |
515 | + } |
516 | + } |
517 | + |
518 | + return false; |
519 | +} |
520 | + |
521 | + |
522 | } // namespace zorba |
523 | /* vim:set et sw=2 ts=2: */ |
524 | |
525 | === modified file 'src/compiler/expression/flwor_expr.h' |
526 | --- src/compiler/expression/flwor_expr.h 2013-01-12 22:10:40 +0000 |
527 | +++ src/compiler/expression/flwor_expr.h 2013-02-28 21:53:23 +0000 |
528 | @@ -56,7 +56,7 @@ |
529 | let_clause, |
530 | window_clause, |
531 | groupby_clause, |
532 | - order_clause, |
533 | + orderby_clause, |
534 | count_clause, |
535 | where_clause, |
536 | materialize_clause |
537 | @@ -669,6 +669,8 @@ |
538 | |
539 | void set_general(bool v) { theKind = (v ? gflwor_expr_kind : flwor_expr_kind); } |
540 | |
541 | + bool compute_is_general(); |
542 | + |
543 | expr* get_return_expr() const { return theReturnExpr; } |
544 | |
545 | expr** get_return_expr_ref() { return &theReturnExpr; } |
546 | @@ -693,13 +695,17 @@ |
547 | |
548 | void remove_clause(csize pos); |
549 | |
550 | + void remove_clause(flwor_clause* c, csize posHint); |
551 | + |
552 | flwor_clause* get_clause(csize i) const; |
553 | |
554 | clause_list_t::const_iterator clause_begin() const { return theClauses.begin(); } |
555 | |
556 | clause_list_t::const_iterator clause_end() const { return theClauses.end(); } |
557 | |
558 | - long defines_variable(const var_expr* v) const; |
559 | + bool defines_var(const var_expr* v) const; |
560 | + |
561 | + bool get_var_pos(const var_expr* v, csize& pos) const; |
562 | |
563 | void get_vars(std::vector<var_expr*>& vars) const; |
564 | |
565 | @@ -707,7 +713,6 @@ |
566 | // removed eventually. |
567 | expr* get_where() const; |
568 | void set_where(expr* e); |
569 | - void remove_where_clause(); |
570 | groupby_clause* get_group_clause() const; |
571 | orderby_clause* get_order_clause() const; |
572 | csize num_forlet_clauses(); |
573 | |
574 | === modified file 'src/compiler/expression/script_exprs.cpp' |
575 | --- src/compiler/expression/script_exprs.cpp 2012-12-06 22:49:35 +0000 |
576 | +++ src/compiler/expression/script_exprs.cpp 2013-02-28 21:53:23 +0000 |
577 | @@ -65,7 +65,7 @@ |
578 | } |
579 | |
580 | |
581 | -void block_expr::add_at(csize pos, expr* arg) |
582 | +void block_expr::add(csize pos, expr* arg) |
583 | { |
584 | assert(arg->get_expr_kind() != var_set_expr_kind); |
585 | |
586 | @@ -102,6 +102,8 @@ |
587 | |
588 | var_expr* varExpr = varDeclExpr->get_var_expr(); |
589 | |
590 | + varExpr->set_block_expr(this); |
591 | + |
592 | expr* initExpr = varDeclExpr->get_init_expr(); |
593 | |
594 | if (initExpr != NULL) |
595 | @@ -167,6 +169,27 @@ |
596 | } |
597 | |
598 | |
599 | +bool block_expr::get_var_pos(const var_expr* v, csize& pos) const |
600 | +{ |
601 | + csize numArgs = theArgs.size(); |
602 | + for (csize i = 0; i < numArgs; ++i) |
603 | + { |
604 | + if (theArgs[i]->get_expr_kind() == var_decl_expr_kind) |
605 | + { |
606 | + var_decl_expr* decl = static_cast<var_decl_expr*>(theArgs[i]); |
607 | + |
608 | + if (decl->get_var_expr() == v) |
609 | + { |
610 | + pos = i; |
611 | + return true; |
612 | + } |
613 | + } |
614 | + } |
615 | + |
616 | + return false; |
617 | +} |
618 | + |
619 | + |
620 | /******************************************************************************* |
621 | |
622 | ********************************************************************************/ |
623 | |
624 | === modified file 'src/compiler/expression/script_exprs.h' |
625 | --- src/compiler/expression/script_exprs.h 2012-12-06 22:49:35 +0000 |
626 | +++ src/compiler/expression/script_exprs.h 2013-02-28 21:53:23 +0000 |
627 | @@ -123,7 +123,7 @@ |
628 | public: |
629 | ~block_expr(); |
630 | |
631 | - void add_at(csize pos, expr* arg); |
632 | + void add(csize pos, expr* arg); |
633 | |
634 | csize size() const { return theArgs.size(); } |
635 | |
636 | @@ -131,6 +131,8 @@ |
637 | |
638 | expr* operator[](csize i) { return theArgs[i]; } |
639 | |
640 | + bool get_var_pos(const var_expr* v, csize& pos) const; |
641 | + |
642 | void accept(expr_visitor&); |
643 | |
644 | std::ostream& put(std::ostream&) const; |
645 | |
646 | === modified file 'src/compiler/expression/var_expr.h' |
647 | --- src/compiler/expression/var_expr.h 2012-12-12 16:15:04 +0000 |
648 | +++ src/compiler/expression/var_expr.h 2013-02-28 21:53:23 +0000 |
649 | @@ -29,6 +29,7 @@ |
650 | class var_expr; |
651 | class VarInfo; |
652 | class var_set_expr; |
653 | +class block_expr; |
654 | |
655 | |
656 | /****************************************************************************** |
657 | @@ -74,6 +75,12 @@ |
658 | ---------------- |
659 | The type, if any, specified in the declaration of the variable |
660 | |
661 | + theBlockExpr: |
662 | + ------------- |
663 | + If this is a prolog or a local var, theBlockExpr points to the block expr |
664 | + where the var is declared at (prolog and local vars are always declared |
665 | + in block exprs). |
666 | + |
667 | theFlworClause: |
668 | --------------- |
669 | If this is a var declared in flwor clause, theFlworClause points to the |
670 | @@ -159,6 +166,8 @@ |
671 | |
672 | xqtref_t theDeclaredType; |
673 | |
674 | + block_expr * theBlockExpr; |
675 | + |
676 | flwor_clause * theFlworClause; |
677 | |
678 | copy_clause * theCopyClause; |
679 | @@ -228,6 +237,10 @@ |
680 | |
681 | void set_type(xqtref_t t); |
682 | |
683 | + void set_block_expr(const block_expr* b) { theBlockExpr = const_cast<block_expr*>(b); } |
684 | + |
685 | + block_expr* get_block_expr() const { return theBlockExpr; } |
686 | + |
687 | void set_flwor_clause(flwor_clause* c) { theFlworClause = c; } |
688 | |
689 | flwor_clause* get_flwor_clause() const { return theFlworClause; } |
690 | |
691 | === modified file 'src/compiler/parsetree/parsenodes.cpp' |
692 | --- src/compiler/parsetree/parsenodes.cpp 2013-01-19 20:47:55 +0000 |
693 | +++ src/compiler/parsetree/parsenodes.cpp 2013-02-28 21:53:23 +0000 |
694 | @@ -1317,15 +1317,15 @@ |
695 | |
696 | |
697 | FLWORExpr::FLWORExpr( |
698 | - const QueryLoc& loc_, |
699 | + const QueryLoc& loc, |
700 | rchandle<FLWORClauseList> clauses_, |
701 | rchandle<exprnode> ret_, |
702 | const QueryLoc& return_loc_, |
703 | bool force_general) |
704 | : |
705 | - exprnode (loc_), |
706 | - clauses (clauses_), |
707 | - return_val_h (ret_), |
708 | + exprnode(loc), |
709 | + clauses(clauses_), |
710 | + return_val_h(ret_), |
711 | return_location(return_loc_) |
712 | { |
713 | for (unsigned i = 0; i < clauses->size (); i++) |
714 | @@ -1342,7 +1342,7 @@ |
715 | } |
716 | } |
717 | |
718 | - compute_general (); |
719 | + compute_general(); |
720 | |
721 | if (force_general) |
722 | general = true; |
723 | @@ -1435,7 +1435,8 @@ |
724 | } |
725 | else if (typeid (*cp) == typeid (GroupByClause)) |
726 | { |
727 | - if (has_group || has_order) non_10 = general = true; |
728 | + non_10 = true; |
729 | + if (has_group || has_order) general = true; |
730 | has_group = true; |
731 | } |
732 | else if (typeid (*cp) == typeid (CountClause)) |
733 | |
734 | === modified file 'src/compiler/parsetree/parsenodes.h' |
735 | --- src/compiler/parsetree/parsenodes.h 2013-01-19 20:47:55 +0000 |
736 | +++ src/compiler/parsetree/parsenodes.h 2013-02-28 21:53:23 +0000 |
737 | @@ -1895,9 +1895,9 @@ |
738 | const QueryLoc& return_loc_, |
739 | bool force_general = false); |
740 | |
741 | - bool is_general () const { return general; } |
742 | + bool is_general() const { return general; } |
743 | |
744 | - bool is_non_10 () const { return non_10; } |
745 | + bool is_non_10() const { return non_10; } |
746 | |
747 | const QueryLoc& get_return_location() const { return return_location; } |
748 | |
749 | @@ -1914,7 +1914,7 @@ |
750 | void accept(parsenode_visitor&) const; |
751 | |
752 | protected: |
753 | - void compute_general (); |
754 | + void compute_general(); |
755 | }; |
756 | |
757 | |
758 | |
759 | === modified file 'src/compiler/rewriter/framework/rewriter_context.cpp' |
760 | --- src/compiler/rewriter/framework/rewriter_context.cpp 2012-10-26 18:24:00 +0000 |
761 | +++ src/compiler/rewriter/framework/rewriter_context.cpp 2013-02-28 21:53:23 +0000 |
762 | @@ -44,10 +44,7 @@ |
763 | theUDF(udf), |
764 | theMessage(msg), |
765 | m_tempvarCounter(0), |
766 | - theIsInOrderedMode(orderedMode), |
767 | - theVarIdMap(NULL), |
768 | - theIdVarMap(NULL), |
769 | - theExprVarsMap(NULL) |
770 | + theIsInOrderedMode(orderedMode) |
771 | { |
772 | theForSerializationOnly = theCCB->theConfig.for_serialization_only; |
773 | |
774 | @@ -64,11 +61,6 @@ |
775 | |
776 | RewriterContext::~RewriterContext() |
777 | { |
778 | - delete theVarIdMap; |
779 | - |
780 | - delete theIdVarMap; |
781 | - |
782 | - delete theExprVarsMap; |
783 | } |
784 | |
785 | |
786 | |
787 | === modified file 'src/compiler/rewriter/framework/rewriter_context.h' |
788 | --- src/compiler/rewriter/framework/rewriter_context.h 2012-10-26 18:24:00 +0000 |
789 | +++ src/compiler/rewriter/framework/rewriter_context.h 2013-02-28 21:53:23 +0000 |
790 | @@ -32,10 +32,6 @@ |
791 | |
792 | class user_function; |
793 | |
794 | -typedef std::map<var_expr *, ulong> VarIdMap; |
795 | -typedef std::vector<var_expr*> IdVarMap; |
796 | -typedef std::map<const expr *, DynamicBitset> ExprVarsMap; |
797 | - |
798 | |
799 | /******************************************************************************* |
800 | |
801 | @@ -43,32 +39,6 @@ |
802 | -------- |
803 | The root node of the expr DAG that is going to be optimized using this context. |
804 | |
805 | - theVarIdMap: |
806 | - ------------ |
807 | - Maps a var_expr to its unique "prefix" id. The "prefix" id has the following |
808 | - property: for 2 vars v1 and v2, v1 is defined before v2 if and only if |
809 | - prefix-id(v1) < prefix-id(v2). See index_flwor_vars() function in |
810 | - tools/expr_tools.cpp for more details. |
811 | - |
812 | - theIdVarMap: |
813 | - ------------ |
814 | - This is the reverse mapping of theVarIdMap. |
815 | - |
816 | - theExprVarsMap: |
817 | - --------------- |
818 | - An entry into this map maps an expr to the variables that are referenced by |
819 | - that expr and/or its sub-exprs. (Note: given that the domain expr of a var |
820 | - $x is not considered a sub-expr of $x, if $x is referenced by an expr E and |
821 | - the domain expr of $x references another var $y, $y is NOT considered to be |
822 | - referenced by E). Only variables that have been assigned a prolog id (i.e., |
823 | - the ones that appear in theVarIdMap) are considered. The set of vars referenced |
824 | - by an expr is implemented by a bitset that is indexed by prolog var ids and |
825 | - whose size (in number of bits) is equal to the size of theVarIdMap. |
826 | - |
827 | - theFlworStack: |
828 | - -------------- |
829 | - The current "in-scope" flwor exprs, ie., flwor exprs that the rule has |
830 | - entered but not exited yet. |
831 | ********************************************************************************/ |
832 | class RewriterContext |
833 | { |
834 | @@ -89,12 +59,6 @@ |
835 | |
836 | bool theIsInOrderedMode; |
837 | |
838 | - VarIdMap * theVarIdMap; |
839 | - IdVarMap * theIdVarMap; |
840 | - ExprVarsMap * theExprVarsMap; |
841 | - std::vector<expr*> theFlworStack; |
842 | - std::vector<bool> theInReturnClause; |
843 | - |
844 | public: |
845 | RewriterContext( |
846 | CompilerCB* cb, |
847 | |
848 | === modified file 'src/compiler/rewriter/rewriters/default_optimizer.cpp' |
849 | --- src/compiler/rewriter/rewriters/default_optimizer.cpp 2012-12-14 18:01:41 +0000 |
850 | +++ src/compiler/rewriter/rewriters/default_optimizer.cpp 2013-02-28 21:53:23 +0000 |
851 | @@ -19,11 +19,13 @@ |
852 | #include "compiler/rewriter/rules/ruleset.h" |
853 | #include "compiler/rewriter/rules/fold_rules.h" |
854 | #include "compiler/rewriter/rules/index_matching_rule.h" |
855 | +#include "compiler/rewriter/rules/index_join_rule.h" |
856 | #include "compiler/rewriter/rewriters/common_rewriter.h" |
857 | #include "compiler/rewriter/rewriters/default_optimizer.h" |
858 | #include "compiler/rewriter/tools/expr_tools.h" |
859 | + |
860 | #include "compiler/xqddf/value_index.h" |
861 | -//#include "compiler/rewriter/tools/udf_graph.h" |
862 | + |
863 | #include "compiler/api/compilercb.h" |
864 | |
865 | #include "functions/udf.h" |
866 | @@ -32,7 +34,6 @@ |
867 | |
868 | #include "context/static_context.h" |
869 | |
870 | -//#include "store/api/store.h" |
871 | |
872 | |
873 | namespace zorba |
874 | @@ -225,31 +226,12 @@ |
875 | // Index Joins |
876 | if (Properties::instance()->inferJoins()) |
877 | { |
878 | - IndexJoinRule rule; |
879 | bool local_modified = false; |
880 | |
881 | - rCtx.theVarIdMap = new VarIdMap; |
882 | - rCtx.theIdVarMap = new IdVarMap; |
883 | - rCtx.theExprVarsMap = new ExprVarsMap; |
884 | - |
885 | - ulong numVars = 0; |
886 | - expr_tools::index_flwor_vars(rCtx.getRoot(), |
887 | - numVars, |
888 | - *rCtx.theVarIdMap, |
889 | - rCtx.theIdVarMap); |
890 | + IndexJoinRule rule(&rCtx); |
891 | |
892 | do |
893 | { |
894 | - assert(rCtx.theFlworStack.empty()); |
895 | - |
896 | - rCtx.theExprVarsMap->clear(); |
897 | - |
898 | - DynamicBitset freeset(numVars); |
899 | - expr_tools::build_expr_to_vars_map(rCtx.getRoot(), |
900 | - *rCtx.theVarIdMap, |
901 | - freeset, |
902 | - *rCtx.theExprVarsMap); |
903 | - |
904 | local_modified = false; |
905 | |
906 | expr* e = rule.apply(rCtx, rCtx.getRoot(), local_modified); |
907 | |
908 | === modified file 'src/compiler/rewriter/rules/flwor_rules.cpp' |
909 | --- src/compiler/rewriter/rules/flwor_rules.cpp 2012-12-29 20:25:12 +0000 |
910 | +++ src/compiler/rewriter/rules/flwor_rules.cpp 2013-02-28 21:53:23 +0000 |
911 | @@ -102,6 +102,10 @@ |
912 | theVarExpr(var), |
913 | theSubstExpr(subst) |
914 | { |
915 | + while (theSubstExpr->get_expr_kind() == wrapper_expr_kind) |
916 | + { |
917 | + theSubstExpr = static_cast<wrapper_expr*>(theSubstExpr)->get_input(); |
918 | + } |
919 | } |
920 | |
921 | expr* apply(RewriterContext& rCtx, expr* node, bool& modified); |
922 | @@ -116,7 +120,9 @@ |
923 | |
924 | while (!iter.done()) |
925 | { |
926 | - if (**iter == theVarExpr) |
927 | + expr* childExpr = **iter; |
928 | + |
929 | + if (childExpr == theVarExpr) |
930 | { |
931 | #if 0 |
932 | std::vector<expr*>::iterator ite = thePath.begin(); |
933 | @@ -134,7 +140,13 @@ |
934 | } |
935 | else |
936 | { |
937 | - apply(rCtx, **iter, modified); |
938 | + apply(rCtx, childExpr, modified); |
939 | + } |
940 | + |
941 | + if (childExpr->isNonDiscardable() && !node->isNonDiscardable()) |
942 | + { |
943 | + node->setNonDiscardable(ANNOTATION_TRUE); |
944 | + modified = true; |
945 | } |
946 | |
947 | iter.next(); |
948 | @@ -452,7 +464,7 @@ |
949 | theFlwor->remove_clause(0); |
950 | continue; |
951 | } |
952 | - else if (clause->get_kind() == flwor_clause::order_clause) |
953 | + else if (clause->get_kind() == flwor_clause::orderby_clause) |
954 | { |
955 | theFlwor->remove_clause(0); |
956 | continue; |
957 | @@ -670,7 +682,7 @@ |
958 | |
959 | break; |
960 | } |
961 | - case flwor_clause::order_clause: |
962 | + case flwor_clause::orderby_clause: |
963 | { |
964 | orderby_clause* cl = static_cast<orderby_clause*>(clause); |
965 | |
966 | @@ -1518,18 +1530,18 @@ |
967 | *rtm.INTEGER_TYPE_QUESTION, |
968 | posExpr->get_loc())) |
969 | { |
970 | - VarIdMap varidMap; |
971 | - ulong numFlworVars = 0; |
972 | + expr_tools::VarIdMap varidMap; |
973 | + csize numFlworVars = 0; |
974 | expr_tools::index_flwor_vars(flworExpr, numFlworVars, varidMap, NULL); |
975 | |
976 | DynamicBitset varset(numFlworVars); |
977 | - ExprVarsMap exprVarMap; |
978 | + expr_tools::ExprVarsMap exprVarMap; |
979 | expr_tools::build_expr_to_vars_map(posExpr, varidMap, varset, exprVarMap); |
980 | |
981 | var_expr* forVar = forClause->get_var(); |
982 | ulong forVarId = varidMap[forVar]; |
983 | |
984 | - std::vector<ulong> posExprVarIds; |
985 | + std::vector<csize> posExprVarIds; |
986 | exprVarMap[posExpr].getSet(posExprVarIds); |
987 | |
988 | csize numPosExprVars = posExprVarIds.size(); |
989 | @@ -1588,7 +1600,7 @@ |
990 | |
991 | if (c->get_kind() == flwor_clause::where_clause || |
992 | c->get_kind() == flwor_clause::groupby_clause || |
993 | - c->get_kind() == flwor_clause::order_clause) |
994 | + c->get_kind() == flwor_clause::orderby_clause) |
995 | { |
996 | goto next1; |
997 | } |
998 | @@ -1602,7 +1614,7 @@ |
999 | const flwor_clause* c = returnFlwor->get_clause(i); |
1000 | |
1001 | if (c->get_kind() == flwor_clause::groupby_clause || |
1002 | - c->get_kind() == flwor_clause::order_clause) |
1003 | + c->get_kind() == flwor_clause::orderby_clause) |
1004 | { |
1005 | goto next1; |
1006 | } |
1007 | @@ -1634,7 +1646,7 @@ |
1008 | |
1009 | if (c->get_kind() == flwor_clause::let_clause) |
1010 | { |
1011 | - expr* domainExpr = static_cast<let_clause*>(c)->get_expr(); |
1012 | + expr* domainExpr = static_cast<let_clause*>(c)->get_expr()->skip_wrappers(); |
1013 | |
1014 | if (domainExpr->get_expr_kind() == flwor_expr_kind && |
1015 | !domainExpr->is_sequential()) |
1016 | @@ -1670,7 +1682,7 @@ |
1017 | else if (c->get_kind() == flwor_clause::for_clause && |
1018 | static_cast<for_clause*>(c)->get_pos_var() == NULL) |
1019 | { |
1020 | - expr* domainExpr = static_cast<for_clause*>(c)->get_expr(); |
1021 | + expr* domainExpr = static_cast<for_clause*>(c)->get_expr()->skip_wrappers(); |
1022 | |
1023 | if (domainExpr->get_expr_kind() == flwor_expr_kind && |
1024 | !domainExpr->is_sequential()) |
1025 | |
1026 | === modified file 'src/compiler/rewriter/rules/fold_rules.cpp' |
1027 | --- src/compiler/rewriter/rules/fold_rules.cpp 2013-01-08 11:07:41 +0000 |
1028 | +++ src/compiler/rewriter/rules/fold_rules.cpp 2013-02-28 21:53:23 +0000 |
1029 | @@ -161,8 +161,9 @@ |
1030 | |
1031 | if (!f->isUdf()) |
1032 | { |
1033 | - if (FunctionConsts::FN_ERROR_0 <= f->getKind() && |
1034 | - f->getKind() <= FunctionConsts::FN_TRACE_2) |
1035 | + if (f->getKind() == FunctionConsts::OP_CREATE_INTERNAL_INDEX_2 || |
1036 | + (FunctionConsts::FN_ERROR_0 <= f->getKind() && |
1037 | + f->getKind() <= FunctionConsts::FN_TRACE_2)) |
1038 | { |
1039 | curNonDiscardable = ANNOTATION_TRUE_FIXED; |
1040 | curUnfoldable = ANNOTATION_TRUE_FIXED; |
1041 | @@ -562,7 +563,7 @@ |
1042 | - Replace empty(E) with true if the return type of E is the emtpy sequence, or |
1043 | false if the return type of E has QUANT_ONE or QUANT_PLUS. |
1044 | - Replace exists(E) with false if the return type of E is the emtpy sequence, or |
1045 | - truee if the return type of E has QUANT_ONE or QUANT_PLUS. |
1046 | + true if the return type of E has QUANT_ONE or QUANT_PLUS. |
1047 | |
1048 | Replace EBV(E) with true if the return type of E is subtype on node()+ and E |
1049 | is not NONDISCARDABLE. |
1050 | |
1051 | === modified file 'src/compiler/rewriter/rules/hoist_rules.cpp' |
1052 | --- src/compiler/rewriter/rules/hoist_rules.cpp 2012-12-12 16:15:04 +0000 |
1053 | +++ src/compiler/rewriter/rules/hoist_rules.cpp 2013-02-28 21:53:23 +0000 |
1054 | @@ -41,15 +41,15 @@ |
1055 | static bool hoist_expressions( |
1056 | RewriterContext&, |
1057 | expr*, |
1058 | - const VarIdMap&, |
1059 | - const ExprVarsMap&, |
1060 | + const expr_tools::VarIdMap&, |
1061 | + const expr_tools::ExprVarsMap&, |
1062 | struct PathHolder*); |
1063 | |
1064 | static expr* try_hoisting( |
1065 | RewriterContext&, |
1066 | expr*, |
1067 | - const VarIdMap&, |
1068 | - const ExprVarsMap&, |
1069 | + const expr_tools::VarIdMap&, |
1070 | + const expr_tools::ExprVarsMap&, |
1071 | struct PathHolder*); |
1072 | |
1073 | static bool non_hoistable (const expr*); |
1074 | @@ -58,7 +58,7 @@ |
1075 | |
1076 | static bool contains_var( |
1077 | var_expr*, |
1078 | - const VarIdMap&, |
1079 | + const expr_tools::VarIdMap&, |
1080 | const DynamicBitset&); |
1081 | |
1082 | static bool is_enclosed_expr(const expr*); |
1083 | @@ -98,13 +98,22 @@ |
1084 | { |
1085 | assert(node == rCtx.getRoot()); |
1086 | |
1087 | - ulong numVars = 0; |
1088 | - VarIdMap varmap; |
1089 | + csize numVars = 0; |
1090 | + expr_tools::VarIdMap varmap; |
1091 | |
1092 | expr_tools::index_flwor_vars(node, numVars, varmap, NULL); |
1093 | |
1094 | - ExprVarsMap freevarMap; |
1095 | - DynamicBitset freeset(numVars); |
1096 | + /* |
1097 | + expr_tools::VarIdMap::const_iterator ite = varmap.begin(); |
1098 | + expr_tools::VarIdMap::const_iterator end = varmap.end(); |
1099 | + for (; ite != end; ++ite) |
1100 | + { |
1101 | + std::cerr << "[ " << ite->first << " --> " << ite->second << "]" << std::endl; |
1102 | + } |
1103 | + */ |
1104 | + |
1105 | + expr_tools::ExprVarsMap freevarMap; |
1106 | + DynamicBitset freeset(numVars+1); |
1107 | expr_tools::build_expr_to_vars_map(node, varmap, freeset, freevarMap); |
1108 | |
1109 | PathHolder root; |
1110 | @@ -128,8 +137,8 @@ |
1111 | static bool hoist_expressions( |
1112 | RewriterContext& rCtx, |
1113 | expr* e, |
1114 | - const VarIdMap& varmap, |
1115 | - const ExprVarsMap& freevarMap, |
1116 | + const expr_tools::VarIdMap& varmap, |
1117 | + const expr_tools::ExprVarsMap& freevarMap, |
1118 | struct PathHolder* path) |
1119 | { |
1120 | bool status = false; |
1121 | @@ -349,8 +358,8 @@ |
1122 | static expr* try_hoisting( |
1123 | RewriterContext& rCtx, |
1124 | expr* e, |
1125 | - const VarIdMap& varmap, |
1126 | - const ExprVarsMap& freevarMap, |
1127 | + const expr_tools::VarIdMap& varmap, |
1128 | + const expr_tools::ExprVarsMap& freevarMap, |
1129 | struct PathHolder* path) |
1130 | { |
1131 | if (non_hoistable(e) || e->constructsNodes()) |
1132 | @@ -364,7 +373,7 @@ |
1133 | |
1134 | assert(udf == rCtx.theUDF); |
1135 | |
1136 | - std::map<const expr*, DynamicBitset>::const_iterator fvme = freevarMap.find(e); |
1137 | + expr_tools::ExprVarsMap::const_iterator fvme = freevarMap.find(e); |
1138 | ZORBA_ASSERT(fvme != freevarMap.end()); |
1139 | const DynamicBitset& varset = fvme->second; |
1140 | |
1141 | @@ -534,7 +543,7 @@ |
1142 | ********************************************************************************/ |
1143 | static bool contains_var( |
1144 | var_expr* v, |
1145 | - const VarIdMap& varmap, |
1146 | + const expr_tools::VarIdMap& varmap, |
1147 | const DynamicBitset& varset) |
1148 | { |
1149 | if (v == NULL) |
1150 | @@ -542,7 +551,7 @@ |
1151 | return false; |
1152 | } |
1153 | |
1154 | - VarIdMap::const_iterator i = varmap.find(v); |
1155 | + expr_tools::VarIdMap::const_iterator i = varmap.find(v); |
1156 | if (i == varmap.end()) |
1157 | { |
1158 | return false; |
1159 | |
1160 | === modified file 'src/compiler/rewriter/rules/index_join_rule.cpp' |
1161 | --- src/compiler/rewriter/rules/index_join_rule.cpp 2012-12-07 01:31:50 +0000 |
1162 | +++ src/compiler/rewriter/rules/index_join_rule.cpp 2013-02-28 21:53:23 +0000 |
1163 | @@ -16,7 +16,7 @@ |
1164 | #include "stdafx.h" |
1165 | |
1166 | #include "compiler/api/compilercb.h" |
1167 | -#include "compiler/rewriter/rules/ruleset.h" |
1168 | +#include "compiler/rewriter/rules/index_join_rule.h" |
1169 | #include "compiler/expression/flwor_expr.h" |
1170 | #include "compiler/expression/script_exprs.h" |
1171 | #include "compiler/expression/expr.h" |
1172 | @@ -37,163 +37,307 @@ |
1173 | namespace zorba |
1174 | { |
1175 | |
1176 | -struct PredicateInfo; |
1177 | - |
1178 | -static bool isIndexJoinPredicate(RewriterContext&, PredicateInfo&); |
1179 | - |
1180 | -static void rewriteJoin(RewriterContext&, PredicateInfo&, bool&); |
1181 | - |
1182 | -static var_expr* findForVar(static_context*, RewriterContext&, const expr*, ulong&); |
1183 | - |
1184 | -static bool checkVarDependency(RewriterContext&, expr*, ulong); |
1185 | - |
1186 | -static bool expandVars(RewriterContext&, expr*, ulong, long&); |
1187 | - |
1188 | -static bool findFlworForVar(RewriterContext&, const var_expr*, flwor_expr*&, ulong&, ulong&); |
1189 | - |
1190 | - |
1191 | struct PredicateInfo |
1192 | { |
1193 | flwor_expr * theFlworExpr; |
1194 | + csize theWherePos; |
1195 | expr * thePredicate; |
1196 | + |
1197 | expr * theOuterOp; |
1198 | var_expr * theOuterVar; |
1199 | - ulong theOuterVarId; |
1200 | + csize theOuterVarId; |
1201 | + |
1202 | expr * theInnerOp; |
1203 | var_expr * theInnerVar; |
1204 | + csize theInnerVarId; |
1205 | + |
1206 | bool theIsGeneral; |
1207 | + |
1208 | + csize theStackPos; |
1209 | + csize theChildPos; |
1210 | }; |
1211 | |
1212 | |
1213 | /******************************************************************************* |
1214 | - This rule analyzes the where clause of flwor exprs to deterimne whether any |
1215 | - predicate in the clause is a join predicate and whether the associated join |
1216 | - can be converted into a hashjoin using an index that is built on-th-fly. |
1217 | + |
1218 | +********************************************************************************/ |
1219 | +IndexJoinRule::IndexJoinRule(RewriterContext* rctx) |
1220 | + : |
1221 | + RewriteRule(RewriteRule::IndexJoin, "IndexJoin"), |
1222 | + theRCtx(rctx), |
1223 | + theRootExpr(rctx->getRoot()) |
1224 | +{ |
1225 | + theVarIdMap = new expr_tools::VarIdMap; |
1226 | + theIdVarMap = new expr_tools::IdVarMap; |
1227 | + theExprVarsMap = new expr_tools::ExprVarsMap; |
1228 | + |
1229 | + theIdVarMap->reserve(32); |
1230 | + theIdVarMap->push_back(0); // because varids are starting from 1 |
1231 | + |
1232 | + csize numVars = 0; |
1233 | + expr_tools::index_flwor_vars(theRootExpr, numVars, *theVarIdMap, theIdVarMap); |
1234 | + |
1235 | + DynamicBitset freeset(numVars+1); |
1236 | + expr_tools::build_expr_to_vars_map(theRootExpr, |
1237 | + *theVarIdMap, |
1238 | + freeset, |
1239 | + *theExprVarsMap); |
1240 | +} |
1241 | + |
1242 | + |
1243 | +/******************************************************************************* |
1244 | + |
1245 | +********************************************************************************/ |
1246 | +IndexJoinRule::~IndexJoinRule() |
1247 | +{ |
1248 | + assert(theVarDefExprs.empty()); |
1249 | + assert(theChildPositions.empty()); |
1250 | + |
1251 | + delete theVarIdMap; |
1252 | + delete theIdVarMap; |
1253 | + delete theExprVarsMap; |
1254 | +} |
1255 | + |
1256 | + |
1257 | +/******************************************************************************* |
1258 | + This rule analyzes the where clauses of flwor exprs to deterimne whether any |
1259 | + predicate in a clause is a join predicate and whether the associated join |
1260 | + can be converted into a hashjoin using an index that is built on-the-fly. |
1261 | ********************************************************************************/ |
1262 | expr* IndexJoinRule::apply(RewriterContext& rCtx, expr* node, bool& modified) |
1263 | { |
1264 | + assert(node != theRootExpr || theVarDefExprs.empty()); |
1265 | + assert(node != theRootExpr || theChildPositions.empty()); |
1266 | + |
1267 | flwor_expr* flworExpr = NULL; |
1268 | |
1269 | - if (node->get_expr_kind() == gflwor_expr_kind) |
1270 | - return node; |
1271 | + expr_kind_t nodeKind = node->get_expr_kind(); |
1272 | |
1273 | - if (node->get_expr_kind() == trycatch_expr_kind) |
1274 | - { |
1275 | - rCtx.theFlworStack.push_back(node); |
1276 | - } |
1277 | - else if (node->get_expr_kind() == flwor_expr_kind) |
1278 | + if (nodeKind == flwor_expr_kind || nodeKind == gflwor_expr_kind) |
1279 | { |
1280 | flworExpr = static_cast<flwor_expr *>(node); |
1281 | |
1282 | // Push the flwor expr into the stack |
1283 | - rCtx.theFlworStack.push_back(flworExpr); |
1284 | - rCtx.theInReturnClause.push_back(false); |
1285 | - |
1286 | - expr* whereExpr = flworExpr->get_where(); |
1287 | - |
1288 | - if (whereExpr == NULL) |
1289 | - goto drilldown; |
1290 | - |
1291 | - PredicateInfo predInfo; |
1292 | - predInfo.theFlworExpr = flworExpr; |
1293 | - predInfo.thePredicate = whereExpr; |
1294 | - |
1295 | - if (isIndexJoinPredicate(rCtx, predInfo)) |
1296 | + theVarDefExprs.push_back(flworExpr); |
1297 | + theChildPositions.push_back(0); |
1298 | + |
1299 | + csize numClauses = flworExpr->num_clauses(); |
1300 | + for (csize i = 0; i < numClauses; ++i) |
1301 | { |
1302 | - rewriteJoin(rCtx, predInfo, modified); |
1303 | - |
1304 | - if (modified) |
1305 | + flwor_clause* c = flworExpr->get_clause(i); |
1306 | + |
1307 | + if (c->get_kind() != flwor_clause::where_clause) |
1308 | + continue; |
1309 | + |
1310 | + const where_clause* wc = static_cast<const where_clause *>(c); |
1311 | + expr* whereExpr = wc->get_expr(); |
1312 | + |
1313 | + PredicateInfo predInfo; |
1314 | + predInfo.theFlworExpr = flworExpr; |
1315 | + predInfo.theWherePos = i; |
1316 | + predInfo.thePredicate = whereExpr; |
1317 | + |
1318 | + if (isIndexJoinPredicate(predInfo)) |
1319 | { |
1320 | - predInfo.theFlworExpr->remove_where_clause(); |
1321 | - |
1322 | - expr* e = rCtx.theFlworStack.back(); |
1323 | - |
1324 | - ZORBA_ASSERT(e == node || e->get_expr_kind() == block_expr_kind); |
1325 | - |
1326 | - rCtx.theFlworStack.pop_back(); |
1327 | - rCtx.theInReturnClause.pop_back(); |
1328 | + rewriteJoin(predInfo); |
1329 | + modified = true; |
1330 | + |
1331 | + predInfo.theFlworExpr->remove_clause(c, i); |
1332 | + |
1333 | + expr* e = theVarDefExprs.back(); |
1334 | + ZORBA_ASSERT(e == node); |
1335 | + theVarDefExprs.pop_back(); |
1336 | + theChildPositions.pop_back(); |
1337 | return e; |
1338 | } |
1339 | - } |
1340 | - else if (whereExpr->get_function_kind() == FunctionConsts::OP_AND_N) |
1341 | - { |
1342 | - // TODO: consider multi-key indices |
1343 | - ExprIterator iter(whereExpr); |
1344 | - while (!iter.done()) |
1345 | + else if (whereExpr->get_function_kind() == FunctionConsts::OP_AND_N) |
1346 | { |
1347 | - PredicateInfo predInfo; |
1348 | - predInfo.theFlworExpr = flworExpr; |
1349 | - predInfo.thePredicate = (**iter); |
1350 | - |
1351 | - if (isIndexJoinPredicate(rCtx, predInfo)) |
1352 | + // TODO: consider multi-key indices |
1353 | + ExprIterator iter(whereExpr); |
1354 | + while (!iter.done()) |
1355 | { |
1356 | - rewriteJoin(rCtx, predInfo, modified); |
1357 | - |
1358 | - if (modified) |
1359 | + PredicateInfo predInfo; |
1360 | + predInfo.theFlworExpr = flworExpr; |
1361 | + predInfo.theWherePos = i; |
1362 | + predInfo.thePredicate = (**iter); |
1363 | + |
1364 | + if (isIndexJoinPredicate(predInfo)) |
1365 | { |
1366 | + rewriteJoin(predInfo); |
1367 | + |
1368 | + modified = true; |
1369 | + |
1370 | + // TODO: just remove the pred instead of replacing it with true. |
1371 | expr* trueExpr = rCtx.theEM-> |
1372 | create_const_expr(flworExpr->get_sctx(), |
1373 | flworExpr->get_udf(), |
1374 | flworExpr->get_loc(), |
1375 | true); |
1376 | (**iter) = trueExpr; |
1377 | - |
1378 | - expr* e = rCtx.theFlworStack.back(); |
1379 | - |
1380 | - ZORBA_ASSERT(e == node || e->get_expr_kind() == block_expr_kind); |
1381 | - |
1382 | - rCtx.theFlworStack.pop_back(); |
1383 | - rCtx.theInReturnClause.pop_back(); |
1384 | + |
1385 | + expr* e = theVarDefExprs.back(); |
1386 | + ZORBA_ASSERT(e == node); |
1387 | + theVarDefExprs.pop_back(); |
1388 | + theChildPositions.pop_back(); |
1389 | return e; |
1390 | } |
1391 | - } |
1392 | + |
1393 | + iter.next(); |
1394 | + } |
1395 | + } |
1396 | + } |
1397 | + } |
1398 | + |
1399 | + // No index-join rewrite done, so drill down. |
1400 | + |
1401 | + if (nodeKind == flwor_expr_kind || nodeKind == gflwor_expr_kind) |
1402 | + { |
1403 | + csize numClauses = flworExpr->num_clauses(); |
1404 | + csize clausePos = 0; |
1405 | + csize numClauseChildren; |
1406 | + |
1407 | + ExprIterator iter(node); |
1408 | + while (!iter.done() && !modified) |
1409 | + { |
1410 | + theChildPositions.back() = clausePos; |
1411 | + |
1412 | + if (clausePos == numClauses) |
1413 | + { |
1414 | + numClauseChildren = 1; |
1415 | + } |
1416 | + else |
1417 | + { |
1418 | + flwor_clause* c = flworExpr->get_clause(clausePos); |
1419 | + |
1420 | + switch (c->get_kind()) |
1421 | + { |
1422 | + case flwor_clause::for_clause: |
1423 | + case flwor_clause::let_clause: |
1424 | + case flwor_clause::where_clause: |
1425 | + { |
1426 | + numClauseChildren = 1; |
1427 | + break; |
1428 | + } |
1429 | + case flwor_clause::window_clause: |
1430 | + { |
1431 | + window_clause* wc = static_cast<window_clause *>(c); |
1432 | + numClauseChildren = 1; |
1433 | + if (wc->get_win_start()) ++numClauseChildren; |
1434 | + if (wc->get_win_stop()) ++numClauseChildren; |
1435 | + break; |
1436 | + } |
1437 | + case flwor_clause::groupby_clause: |
1438 | + { |
1439 | + groupby_clause* gc = static_cast<groupby_clause *>(c); |
1440 | + numClauseChildren = gc->numGroupingVars() + gc->numNonGroupingVars(); |
1441 | + break; |
1442 | + } |
1443 | + case flwor_clause::orderby_clause: |
1444 | + { |
1445 | + orderby_clause* oc = static_cast<orderby_clause *>(c); |
1446 | + numClauseChildren = oc->num_columns(); |
1447 | + break; |
1448 | + } |
1449 | + case flwor_clause::count_clause: |
1450 | + case flwor_clause::materialize_clause: |
1451 | + { |
1452 | + numClauseChildren = 0; |
1453 | + break; |
1454 | + } |
1455 | + default: |
1456 | + ZORBA_ASSERT(false); |
1457 | + } |
1458 | + } |
1459 | + |
1460 | + for (csize j = 0; j < numClauseChildren; ++j) |
1461 | + { |
1462 | + expr* currChild = **iter; |
1463 | + expr* newChild = apply(rCtx, currChild, modified); |
1464 | + ZORBA_ASSERT(currChild == newChild); |
1465 | + |
1466 | + if (modified) |
1467 | + break; |
1468 | |
1469 | iter.next(); |
1470 | } |
1471 | - } |
1472 | - } |
1473 | - |
1474 | - drilldown: |
1475 | - |
1476 | - ExprIterator iter(node); |
1477 | - while (!iter.done()) |
1478 | - { |
1479 | - expr* currChild = **iter; |
1480 | - |
1481 | - if (flworExpr != NULL && currChild == flworExpr->get_return_expr()) |
1482 | - rCtx.theInReturnClause.back() = true; |
1483 | - |
1484 | - expr* newChild = apply(rCtx, currChild, modified); |
1485 | - |
1486 | - if (currChild != newChild) |
1487 | - { |
1488 | - assert(modified); |
1489 | - **iter = newChild; |
1490 | - } |
1491 | - |
1492 | - if (modified) |
1493 | - break; |
1494 | - |
1495 | - iter.next(); |
1496 | - } |
1497 | - |
1498 | - if (node->get_expr_kind() == trycatch_expr_kind) |
1499 | - { |
1500 | - rCtx.theFlworStack.pop_back(); |
1501 | - return node; |
1502 | - } |
1503 | - else if (node->get_expr_kind() == flwor_expr_kind) |
1504 | - { |
1505 | - expr* e = rCtx.theFlworStack.back(); |
1506 | - |
1507 | - ZORBA_ASSERT(e == node || e->get_expr_kind() == block_expr_kind); |
1508 | - |
1509 | - rCtx.theFlworStack.pop_back(); |
1510 | - rCtx.theInReturnClause.pop_back(); |
1511 | + |
1512 | + ++clausePos; |
1513 | + } |
1514 | + |
1515 | + // drill out |
1516 | + expr* e = theVarDefExprs.back(); |
1517 | + ZORBA_ASSERT(e == node); |
1518 | + theVarDefExprs.pop_back(); |
1519 | + theChildPositions.pop_back(); |
1520 | return e; |
1521 | } |
1522 | + else if (nodeKind == trycatch_expr_kind) |
1523 | + { |
1524 | + // drill in |
1525 | + theVarDefExprs.push_back(node); |
1526 | + theChildPositions.push_back(0); |
1527 | + |
1528 | + ExprIterator iter(node); |
1529 | + while (!iter.done()) |
1530 | + { |
1531 | + expr* currChild = **iter; |
1532 | + expr* newChild = apply(rCtx, currChild, modified); |
1533 | + ZORBA_ASSERT(currChild == newChild); |
1534 | + |
1535 | + if (modified) |
1536 | + break; |
1537 | + |
1538 | + iter.next(); |
1539 | + } |
1540 | + |
1541 | + // drill out |
1542 | + theVarDefExprs.pop_back(); |
1543 | + theChildPositions.pop_back(); |
1544 | + |
1545 | + return node; |
1546 | + } |
1547 | + else if (nodeKind == block_expr_kind) |
1548 | + { |
1549 | + // drill in |
1550 | + theVarDefExprs.push_back(node); |
1551 | + theChildPositions.push_back(0); |
1552 | + |
1553 | + block_expr* block = static_cast<block_expr*>(node); |
1554 | + csize numArgs = block->size(); |
1555 | + for (csize i = 0; i < numArgs; ++i) |
1556 | + { |
1557 | + theChildPositions.back() = i; |
1558 | + |
1559 | + expr* currChild = (*block)[i]; |
1560 | + expr* newChild = apply(rCtx, currChild, modified); |
1561 | + ZORBA_ASSERT(currChild == newChild); |
1562 | + |
1563 | + if (modified) |
1564 | + break; |
1565 | + } |
1566 | + |
1567 | + // drill out |
1568 | + ZORBA_ASSERT(theVarDefExprs.back() == node); |
1569 | + theVarDefExprs.pop_back(); |
1570 | + theChildPositions.pop_back(); |
1571 | + |
1572 | + return node; |
1573 | + } |
1574 | else |
1575 | { |
1576 | + ExprIterator iter(node); |
1577 | + while (!iter.done()) |
1578 | + { |
1579 | + expr* currChild = **iter; |
1580 | + expr* newChild = apply(rCtx, currChild, modified); |
1581 | + ZORBA_ASSERT(currChild == newChild); |
1582 | + |
1583 | + if (modified) |
1584 | + break; |
1585 | + |
1586 | + iter.next(); |
1587 | + } |
1588 | + |
1589 | return node; |
1590 | } |
1591 | } |
1592 | @@ -203,7 +347,7 @@ |
1593 | Check whether the given predicate is a join predicate that can be converted |
1594 | to a hashjoin. |
1595 | ********************************************************************************/ |
1596 | -static bool isIndexJoinPredicate(RewriterContext& rCtx, PredicateInfo& predInfo) |
1597 | +bool IndexJoinRule::isIndexJoinPredicate(PredicateInfo& predInfo) |
1598 | { |
1599 | const fo_expr* foExpr = NULL; |
1600 | const function* fn; |
1601 | @@ -232,22 +376,20 @@ |
1602 | if (opKind != CompareConsts::VALUE_EQUAL && opKind != CompareConsts::GENERAL_EQUAL) |
1603 | return false; |
1604 | |
1605 | - static_context* sctx = predExpr->get_sctx(); |
1606 | - |
1607 | predInfo.theIsGeneral = (opKind == CompareConsts::GENERAL_EQUAL); |
1608 | |
1609 | expr* op1 = foExpr->get_arg(0); |
1610 | expr* op2 = foExpr->get_arg(1); |
1611 | |
1612 | - // Analyze each operand of the eq to see if it depends on a single for |
1613 | + // Analyze each operand of the eq to see if it depends on a single LOOP |
1614 | // variable. If that is not true, we reject this predicate. |
1615 | - ulong var1id; |
1616 | - var_expr* var1 = findForVar(sctx, rCtx, op1, var1id); |
1617 | + csize var1id; |
1618 | + var_expr* var1 = findLoopVar(op1, var1id); |
1619 | if (var1 == NULL) |
1620 | return false; |
1621 | |
1622 | - ulong var2id; |
1623 | - var_expr* var2 = findForVar(sctx, rCtx, op2, var2id); |
1624 | + csize var2id; |
1625 | + var_expr* var2 = findLoopVar(op2, var2id); |
1626 | if (var2 == NULL) |
1627 | return false; |
1628 | |
1629 | @@ -255,8 +397,6 @@ |
1630 | return false; |
1631 | |
1632 | // Determine the outer and inner side of the join |
1633 | - ulong outerVarId; |
1634 | - |
1635 | if (var1id < var2id) |
1636 | { |
1637 | predInfo.theOuterOp = op1; |
1638 | @@ -264,7 +404,7 @@ |
1639 | predInfo.theOuterVarId = var1id; |
1640 | predInfo.theInnerOp = op2; |
1641 | predInfo.theInnerVar = var2; |
1642 | - outerVarId = var1id; |
1643 | + predInfo.theInnerVarId = var2id; |
1644 | } |
1645 | else |
1646 | { |
1647 | @@ -273,26 +413,84 @@ |
1648 | predInfo.theOuterVarId = var2id; |
1649 | predInfo.theInnerOp = op1; |
1650 | predInfo.theInnerVar = var1; |
1651 | - outerVarId = var2id; |
1652 | + predInfo.theInnerVarId = var1id; |
1653 | } |
1654 | |
1655 | + static_context* sctx = predExpr->get_sctx(); |
1656 | TypeManager* tm = sctx->get_typemanager(); |
1657 | RootTypeManager& rtm = GENV_TYPESYSTEM; |
1658 | |
1659 | - // The domain of the outer var must contain more than 1 item. |
1660 | - xqtref_t outerDomainType = predInfo.theOuterVar->get_domain_expr()->get_return_type(); |
1661 | - |
1662 | - if (outerDomainType->max_card() < 2) |
1663 | - return false; |
1664 | - |
1665 | - // The expr that defines the inner var must not depend on the outer var. |
1666 | - expr* innerDomainExpr = predInfo.theInnerVar->get_forlet_clause()->get_expr(); |
1667 | - if (checkVarDependency(rCtx, innerDomainExpr, outerVarId)) |
1668 | + // Make sure that the inner loop var has a domain expression |
1669 | + if (predInfo.theInnerVar->get_kind() != var_expr::for_var && |
1670 | + predInfo.theInnerVar->get_kind() != var_expr::pos_var) |
1671 | + return false; |
1672 | + |
1673 | + if (predInfo.theInnerVar->get_flwor_clause() == |
1674 | + predInfo.theOuterVar->get_flwor_clause()) |
1675 | + return false; |
1676 | + |
1677 | + forlet_clause* innerVarClause = predInfo.theInnerVar->get_forlet_clause(); |
1678 | + |
1679 | + // The inner var must not be an outer FOR var |
1680 | + if (innerVarClause->is_allowing_empty()) |
1681 | return false; |
1682 | |
1683 | // The predicate must be in the same flwor that defines the inner var (this |
1684 | // way we can be sure that the pred acts as a filter over the inner var). |
1685 | - if (predInfo.theFlworExpr->defines_variable(predInfo.theInnerVar) < 0) |
1686 | + if (!predInfo.theFlworExpr->defines_var(predInfo.theInnerVar)) |
1687 | + return false; |
1688 | + |
1689 | + // There should be no COUNT clause and no sequential clauses between the |
1690 | + // WHERE clause and the inner var clause. |
1691 | + for (csize i = predInfo.theWherePos; i > 0; --i) |
1692 | + { |
1693 | + flwor_clause* c = predInfo.theFlworExpr->get_clause(i-1); |
1694 | + |
1695 | + switch (c->get_kind()) |
1696 | + { |
1697 | + case flwor_clause::for_clause: |
1698 | + case flwor_clause::let_clause: |
1699 | + case flwor_clause::window_clause: |
1700 | + { |
1701 | + forletwin_clause* flwc = static_cast<forletwin_clause*>(c); |
1702 | + if (flwc->get_expr()->is_sequential()) |
1703 | + return false; |
1704 | + |
1705 | + break; |
1706 | + } |
1707 | + case flwor_clause::count_clause: |
1708 | + { |
1709 | + return false; |
1710 | + } |
1711 | + case flwor_clause::orderby_clause: |
1712 | + case flwor_clause::where_clause: |
1713 | + { |
1714 | + break; |
1715 | + } |
1716 | + case flwor_clause::groupby_clause: |
1717 | + case flwor_clause::materialize_clause: |
1718 | + default: |
1719 | + { |
1720 | + ZORBA_ASSERT(false); |
1721 | + } |
1722 | + } |
1723 | + |
1724 | + if (c == innerVarClause) |
1725 | + break; |
1726 | + } |
1727 | + |
1728 | + // Let OV be the outer LOOP var and BV be the inner-most non-LET variable that |
1729 | + // the index expression depends on. The index must be created somewhere between |
1730 | + // BV anmd OV. The checkVarDeps method finds BV and checks that BV is defined |
1731 | + // before OV. |
1732 | + expr* innerDomainExpr = innerVarClause->get_expr(); |
1733 | + csize boundaryVarId = 0; |
1734 | + if (checkVarDeps(innerDomainExpr, predInfo.theOuterVarId, boundaryVarId)) |
1735 | + return false; |
1736 | + |
1737 | + // Check whether it is possible to place the index creation somewhere between |
1738 | + // BV and OV, and if so, determine the exact location. |
1739 | + if (!findIndexPos(predInfo, boundaryVarId)) |
1740 | return false; |
1741 | |
1742 | // Type checks |
1743 | @@ -309,9 +507,9 @@ |
1744 | { |
1745 | // Normally, other rewrite rules should have added the necessary casting |
1746 | // to the eq operands so that their static types have quantifiers ONE |
1747 | - // or QUESTION and the associated prime types are not xs:anyAtomicType. |
1748 | - // But just in case those rules have been disabled, we check again here |
1749 | - // and reject the hashjoin rewrite if these condition are violated. |
1750 | + // or QUESTION. But just in case those rules have been disabled, we |
1751 | + // check again here and reject the hashjoin rewrite if these conditions |
1752 | + // are violated. |
1753 | |
1754 | if (innerQuant != TypeConstants::QUANT_ONE && |
1755 | innerQuant != TypeConstants::QUANT_QUESTION) |
1756 | @@ -321,15 +519,9 @@ |
1757 | outerQuant != TypeConstants::QUANT_QUESTION) |
1758 | return false; |
1759 | |
1760 | - // The type of the outer/inner operands in the join predicate must not be |
1761 | - // xs:untypedAtomic or xs:anyAtomic. |
1762 | - /* |
1763 | - if (TypeOps::is_equal(tm, *primeOuterType, *rtm.UNTYPED_ATOMIC_TYPE_ONE, outerLoc) || |
1764 | - TypeOps::is_equal(tm, *primeInnerType, *rtm.UNTYPED_ATOMIC_TYPE_ONE, innerLoc)) |
1765 | - return false; |
1766 | - */ |
1767 | - if (TypeOps::is_equal(tm, *primeOuterType, *rtm.ANY_ATOMIC_TYPE_ONE, outerLoc) || |
1768 | - TypeOps::is_equal(tm, *primeInnerType, *rtm.ANY_ATOMIC_TYPE_ONE, innerLoc)) |
1769 | + // The type of the inner operand in the join predicate must not be |
1770 | + // xs:anyAtomic. |
1771 | + if (TypeOps::is_equal(tm, *primeInnerType, *rtm.ANY_ATOMIC_TYPE_ONE, innerLoc)) |
1772 | return false; |
1773 | |
1774 | // The prime type of the outer operand in the join predicate must be a |
1775 | @@ -356,22 +548,26 @@ |
1776 | |
1777 | |
1778 | /******************************************************************************* |
1779 | - Check if "curExpr" references a single var and that var is a FOR var. If so, |
1780 | - return that FOR var and its prefix id; otherwise return NULL. |
1781 | + Check if "curExpr" references a single var and that var is a LOOP var, i.e., |
1782 | + a GROUPBY var or a FOR var whose domain expr has a max cardinality > 1. If so, |
1783 | + return that LOOP var and its prefix id; otherwise return NULL. If "curExpr" |
1784 | + references a single LET var, the check is applied recurdively to the domain |
1785 | + expr of the LET var. |
1786 | + |
1787 | + TODO: it is possible to relax the conditions to allow curExpr to reference |
1788 | + a single LOOP var plus local/global vars. But then we must make sure we |
1789 | + don't cross these additional var when we look for the place where to put the |
1790 | + index creation. |
1791 | ********************************************************************************/ |
1792 | -static var_expr* findForVar( |
1793 | - static_context* sctx, |
1794 | - RewriterContext& rCtx, |
1795 | - const expr* curExpr, |
1796 | - ulong& varid) |
1797 | +var_expr* IndexJoinRule::findLoopVar(expr* curExpr, csize& varid) |
1798 | { |
1799 | var_expr* var = NULL; |
1800 | |
1801 | while (true) |
1802 | { |
1803 | - std::vector<ulong> varidSet; |
1804 | + std::vector<csize> varidSet; |
1805 | |
1806 | - const DynamicBitset& bitset = (*rCtx.theExprVarsMap)[curExpr]; |
1807 | + const DynamicBitset& bitset = (*theExprVarsMap)[curExpr]; |
1808 | |
1809 | bitset.getSet(varidSet); |
1810 | |
1811 | @@ -379,34 +575,52 @@ |
1812 | return NULL; |
1813 | |
1814 | varid = varidSet[0]; |
1815 | - var = (*rCtx.theIdVarMap)[varid]; |
1816 | - |
1817 | - if (var->get_kind() == var_expr::for_var) |
1818 | - { |
1819 | - curExpr = var->get_domain_expr(); |
1820 | - |
1821 | - if (curExpr->is_sequential()) |
1822 | - return NULL; |
1823 | - |
1824 | - xqtref_t domainType = var->get_domain_expr()->get_return_type(); |
1825 | - |
1826 | - if (domainType->get_quantifier() != TypeConstants::QUANT_ONE) |
1827 | + var = (*theIdVarMap)[varid]; |
1828 | + |
1829 | + switch (var->get_kind()) |
1830 | + { |
1831 | + case var_expr::for_var: |
1832 | + case var_expr::pos_var: |
1833 | + { |
1834 | + for_clause* fc = var->get_forlet_clause(); |
1835 | + curExpr = fc->get_expr(); |
1836 | + |
1837 | + xqtref_t domainType = curExpr->get_return_type(); |
1838 | + TypeConstants::quantifier_t quant = domainType->get_quantifier(); |
1839 | + |
1840 | + if (quant == TypeConstants::QUANT_STAR || quant == TypeConstants::QUANT_PLUS) |
1841 | { |
1842 | - // found a real FOR var, so we return it. |
1843 | return var; |
1844 | } |
1845 | - } |
1846 | - else if (var->get_kind() == var_expr::let_var) |
1847 | + else if (quant == TypeConstants::QUANT_ONE) |
1848 | + { |
1849 | + // this FOR var is equivalent to a LET var, so we drill into its |
1850 | + // domain expr |
1851 | + continue; |
1852 | + } |
1853 | + else |
1854 | + { |
1855 | + return false; |
1856 | + } |
1857 | + } |
1858 | + case var_expr::groupby_var: |
1859 | + case var_expr::wincond_out_var: |
1860 | + case var_expr::wincond_out_pos_var: |
1861 | + case var_expr::wincond_in_var: |
1862 | + case var_expr::wincond_in_pos_var: |
1863 | + { |
1864 | + return var; |
1865 | + } |
1866 | + case var_expr::let_var: |
1867 | { |
1868 | curExpr = var->get_domain_expr(); |
1869 | - |
1870 | - if (curExpr->is_sequential()) |
1871 | - return NULL; |
1872 | + break; |
1873 | } |
1874 | - else |
1875 | + default: |
1876 | { |
1877 | return NULL; |
1878 | } |
1879 | + } |
1880 | } |
1881 | |
1882 | return var; |
1883 | @@ -414,269 +628,374 @@ |
1884 | |
1885 | |
1886 | /******************************************************************************* |
1887 | - Check if "curExpr" depends on the var V with the given prefix id. The method |
1888 | - returns true if "curExpr" references V or references another var whose domain |
1889 | - expr depends on V. |
1890 | -********************************************************************************/ |
1891 | -static bool checkVarDependency( |
1892 | - RewriterContext& rCtx, |
1893 | - expr* curExpr, |
1894 | - ulong searchVarId) |
1895 | -{ |
1896 | - const DynamicBitset& bitset = (*rCtx.theExprVarsMap)[curExpr]; |
1897 | - |
1898 | - if (bitset.get(searchVarId)) |
1899 | - return true; |
1900 | - |
1901 | - std::vector<ulong> varidSet; |
1902 | - bitset.getSet(varidSet); |
1903 | - |
1904 | - csize numVars = varidSet.size(); |
1905 | - for (csize i = 0; i < numVars; ++i) |
1906 | - { |
1907 | - const var_expr* var = (*rCtx.theIdVarMap)[varidSet[i]]; |
1908 | - curExpr = var->get_forletwin_clause()->get_expr(); |
1909 | - |
1910 | - if (checkVarDependency(rCtx, curExpr, searchVarId)) |
1911 | + Return true iff "idxExpr" references the outer loop var OV or any other var |
1912 | + that is defined after OV. Also find and return the id of the "boundary" var |
1913 | + BV that is the inner-most variable that the indExp depends on. |
1914 | + |
1915 | + NOTE: for the purposes of this method, LET vars are "transparent", i.e., the |
1916 | + method is applied recursively on the domain expr of each LET var that is |
1917 | + referenced by idxExpr. |
1918 | +********************************************************************************/ |
1919 | +bool IndexJoinRule::checkVarDeps( |
1920 | + expr* idxExpr, |
1921 | + csize outerVarId, |
1922 | + csize& boundVarId) |
1923 | +{ |
1924 | + const DynamicBitset& bitset = (*theExprVarsMap)[idxExpr]; |
1925 | + |
1926 | + csize numVars = bitset.size(); |
1927 | + for (csize varid = 0; varid < numVars; ++varid) |
1928 | + { |
1929 | + if (!bitset.get(varid)) |
1930 | + continue; |
1931 | + |
1932 | + if (varid >= outerVarId) |
1933 | + { |
1934 | + if (varid == outerVarId) |
1935 | + return true; |
1936 | + |
1937 | + const var_expr* var = (*theIdVarMap)[varid]; |
1938 | + |
1939 | + if (var->get_kind() == var_expr::let_var) |
1940 | + { |
1941 | + expr* domExpr = var->get_forlet_clause()->get_expr(); |
1942 | + if (checkVarDeps(domExpr, outerVarId, boundVarId)) |
1943 | + return true; |
1944 | + } |
1945 | + else |
1946 | + { |
1947 | + return true; |
1948 | + } |
1949 | + } |
1950 | + else if (varid > boundVarId) |
1951 | + { |
1952 | + boundVarId = varid; |
1953 | + } |
1954 | + } |
1955 | + |
1956 | + return false; |
1957 | +} |
1958 | + |
1959 | + |
1960 | +/******************************************************************************* |
1961 | + |
1962 | +********************************************************************************/ |
1963 | +bool IndexJoinRule::findIndexPos(PredicateInfo& predInfo, csize boundVarId) |
1964 | +{ |
1965 | + csize numStackedExprs = theVarDefExprs.size(); |
1966 | + |
1967 | + // |
1968 | + // Find the position of the outer loop var |
1969 | + // |
1970 | + var_expr* outerVar = predInfo.theOuterVar; |
1971 | + flwor_expr* outerFlwor = outerVar->get_flwor_clause()->get_flwor_expr(); |
1972 | + csize outerStackPos = numStackedExprs; |
1973 | + csize outerVarPos; |
1974 | + |
1975 | + bool found = outerFlwor->get_var_pos(outerVar, outerVarPos); |
1976 | + ZORBA_ASSERT(found); |
1977 | + |
1978 | + for (csize i = 0; i < numStackedExprs; ++i) |
1979 | + { |
1980 | + if (theVarDefExprs[i] == outerFlwor) |
1981 | + { |
1982 | + outerStackPos = i; |
1983 | + break; |
1984 | + } |
1985 | + } |
1986 | + |
1987 | + assert(outerStackPos < numStackedExprs); |
1988 | + |
1989 | + // |
1990 | + // Find the position of the inner loop var |
1991 | + // |
1992 | + var_expr* innerVar = predInfo.theInnerVar; |
1993 | + flwor_expr* innerFlwor = innerVar->get_flwor_clause()->get_flwor_expr(); |
1994 | + csize innerStackPos = numStackedExprs - 1; |
1995 | + csize innerVarPos; |
1996 | + |
1997 | + found = innerFlwor->get_var_pos(innerVar, innerVarPos); |
1998 | + ZORBA_ASSERT(found); |
1999 | + |
2000 | + // |
2001 | + // Make sure that there are no sequential clauses/exprs and no trycatch exprs |
2002 | + // in the path between the inner and the outer loop vars. |
2003 | + // |
2004 | + theChildPositions[numStackedExprs-1] = innerVarPos; |
2005 | + |
2006 | + for (csize i = outerStackPos; i <= innerStackPos; ++i) |
2007 | + { |
2008 | + expr* currExpr = theVarDefExprs[i]; |
2009 | + expr_kind_t currKind = currExpr->get_expr_kind(); |
2010 | + |
2011 | + if (currKind == flwor_expr_kind || currKind == gflwor_expr_kind) |
2012 | + { |
2013 | + flwor_expr* flwor = static_cast<flwor_expr*>(currExpr); |
2014 | + csize numClauses = flwor->num_clauses(); |
2015 | + csize startClause; |
2016 | + csize stopClause; |
2017 | + bool checkReturn = false; |
2018 | + |
2019 | + if (outerStackPos == innerStackPos) |
2020 | + { |
2021 | + startClause = outerVarPos; |
2022 | + stopClause = innerVarPos; |
2023 | + } |
2024 | + else if (i == outerStackPos) |
2025 | + { |
2026 | + startClause = outerVarPos; |
2027 | + stopClause = numClauses - 1; |
2028 | + checkReturn = true; |
2029 | + } |
2030 | + else |
2031 | + { |
2032 | + startClause = 0; |
2033 | + stopClause = theChildPositions[i]; |
2034 | + if (stopClause == numClauses) |
2035 | + { |
2036 | + --stopClause; |
2037 | + checkReturn = true; |
2038 | + } |
2039 | + } |
2040 | + |
2041 | + for (csize j = startClause; j <= stopClause; ++j) |
2042 | + { |
2043 | + flwor_clause* c = flwor->get_clause(j); |
2044 | + |
2045 | + switch (c->get_kind()) |
2046 | + { |
2047 | + case flwor_clause::for_clause: |
2048 | + case flwor_clause::let_clause: |
2049 | + case flwor_clause::window_clause: |
2050 | + { |
2051 | + forletwin_clause* flwc = static_cast<forletwin_clause*>(c); |
2052 | + |
2053 | + if (flwc->get_expr()->is_sequential()) |
2054 | + return false; |
2055 | + |
2056 | + break; |
2057 | + } |
2058 | + default: |
2059 | + break; |
2060 | + } |
2061 | + } |
2062 | + |
2063 | + if (checkReturn && flwor->get_return_expr()->is_sequential()) |
2064 | + return false; |
2065 | + } |
2066 | + else if (currKind == trycatch_expr_kind) |
2067 | + { |
2068 | + return false; |
2069 | + } |
2070 | + else if (currKind == block_expr_kind) |
2071 | + { |
2072 | + block_expr* block = static_cast<block_expr*>(currExpr); |
2073 | + |
2074 | + for (csize j = 0; j <= theChildPositions[i]; ++j) |
2075 | + { |
2076 | + if ((*block)[j]->is_sequential()) |
2077 | + return false; |
2078 | + } |
2079 | + } |
2080 | + } |
2081 | + |
2082 | + // |
2083 | + // Find the position of the boundary var |
2084 | + // |
2085 | + var_expr* boundVar = NULL; |
2086 | + expr* boundExpr; |
2087 | + csize boundStackPos; |
2088 | + csize boundVarPos; |
2089 | + |
2090 | + if (boundVarId == 0) |
2091 | + { |
2092 | + boundStackPos = 0; |
2093 | + boundVarPos = 0; |
2094 | + } |
2095 | + else |
2096 | + { |
2097 | + boundVar = (*theIdVarMap)[boundVarId]; |
2098 | + ZORBA_ASSERT(boundVar); |
2099 | + |
2100 | + if (boundVar->get_kind() == var_expr::catch_var) |
2101 | + { |
2102 | + // Not worth bothering about index exprs accessing catch vars |
2103 | + return false; |
2104 | + } |
2105 | + else if (boundVar->get_kind() == var_expr::prolog_var || |
2106 | + boundVar->get_kind() == var_expr::local_var) |
2107 | + { |
2108 | + block_expr* blockExpr = boundVar->get_block_expr(); |
2109 | + ZORBA_ASSERT(blockExpr); |
2110 | + boundExpr = blockExpr; |
2111 | + |
2112 | + found = blockExpr->get_var_pos(boundVar, boundVarPos); |
2113 | + ZORBA_ASSERT(found); |
2114 | + } |
2115 | + else |
2116 | + { |
2117 | + flwor_clause* boundClause = boundVar->get_flwor_clause(); |
2118 | + ZORBA_ASSERT(boundClause); |
2119 | + flwor_expr* boundFlwor = boundClause->get_flwor_expr(); |
2120 | + boundExpr = boundFlwor; |
2121 | + |
2122 | + found = boundFlwor->get_var_pos(boundVar, boundVarPos); |
2123 | + ZORBA_ASSERT(found); |
2124 | + } |
2125 | + |
2126 | + for (csize i = 0; i < numStackedExprs; ++i) |
2127 | + { |
2128 | + if (theVarDefExprs[i] == boundExpr) |
2129 | + { |
2130 | + boundStackPos = i; |
2131 | + break; |
2132 | + } |
2133 | + } |
2134 | + } |
2135 | + |
2136 | + ZORBA_ASSERT(boundStackPos < numStackedExprs); |
2137 | + |
2138 | + // |
2139 | + // Try to place the index creation as early as possible, but without crossing |
2140 | + // any sequential expr or trycatch expr or the definition of the boundary var. |
2141 | + // |
2142 | + theChildPositions[outerStackPos] = outerVarPos; |
2143 | + |
2144 | + for (csize i = outerStackPos; i >= boundStackPos; --i) |
2145 | + { |
2146 | + expr* currExpr = theVarDefExprs[i]; |
2147 | + expr_kind_t currKind = currExpr->get_expr_kind(); |
2148 | + |
2149 | + if (currKind == flwor_expr_kind || currKind == gflwor_expr_kind) |
2150 | + { |
2151 | + flwor_expr* flwor = static_cast<flwor_expr*>(currExpr); |
2152 | + csize numClauses = flwor->num_clauses(); |
2153 | + csize stopClause = 0; |
2154 | + csize startClause = theChildPositions[i]; |
2155 | + bool checkReturn = false; |
2156 | + |
2157 | + if (startClause == numClauses) |
2158 | + { |
2159 | + checkReturn = true; |
2160 | + --startClause; |
2161 | + } |
2162 | + |
2163 | + if (checkReturn && flwor->get_return_expr()->is_sequential()) |
2164 | + { |
2165 | + predInfo.theStackPos = i+1; |
2166 | + predInfo.theChildPos = 0; |
2167 | + return true; |
2168 | + } |
2169 | + |
2170 | + for (csize j = startClause+1; j > stopClause; --j) |
2171 | + { |
2172 | + if (i == boundStackPos && j-1 == boundVarPos) |
2173 | + { |
2174 | + predInfo.theStackPos = i; |
2175 | + predInfo.theChildPos = (boundVarId == 0 ? j-1 : j); |
2176 | + return true; |
2177 | + } |
2178 | + |
2179 | + flwor_clause* c = flwor->get_clause(j-1); |
2180 | + |
2181 | + switch (c->get_kind()) |
2182 | + { |
2183 | + case flwor_clause::for_clause: |
2184 | + case flwor_clause::let_clause: |
2185 | + case flwor_clause::window_clause: |
2186 | + { |
2187 | + forletwin_clause* flwc = static_cast<forletwin_clause*>(c); |
2188 | + |
2189 | + if (flwc->get_expr()->is_sequential()) |
2190 | + { |
2191 | + predInfo.theStackPos = i; |
2192 | + predInfo.theChildPos = j; |
2193 | + return true; |
2194 | + } |
2195 | + break; |
2196 | + } |
2197 | + default: |
2198 | + break; |
2199 | + } |
2200 | + } |
2201 | + } |
2202 | + else if (currKind == trycatch_expr_kind) |
2203 | + { |
2204 | + predInfo.theStackPos = i+1; |
2205 | + predInfo.theChildPos = 0; |
2206 | return true; |
2207 | + } |
2208 | + else if (currKind == block_expr_kind) |
2209 | + { |
2210 | + block_expr* block = static_cast<block_expr*>(currExpr); |
2211 | + csize stopArg = 0; |
2212 | + csize startArg = theChildPositions[i]; |
2213 | + |
2214 | + for (csize j = startArg+1; j > stopArg; --j) |
2215 | + { |
2216 | + csize arg = j-1; |
2217 | + |
2218 | + if ((*block)[arg]->is_sequential() || |
2219 | + (i == boundStackPos && arg == boundVarPos)) |
2220 | + { |
2221 | + predInfo.theStackPos = i; |
2222 | + predInfo.theChildPos = j; |
2223 | + return true; |
2224 | + } |
2225 | + } |
2226 | + } |
2227 | + |
2228 | + if (i == 0) |
2229 | + break; |
2230 | } |
2231 | |
2232 | - return false; |
2233 | + predInfo.theStackPos = 0; |
2234 | + predInfo.theChildPos = 0; |
2235 | + return true; |
2236 | } |
2237 | |
2238 | |
2239 | /******************************************************************************* |
2240 | |
2241 | ********************************************************************************/ |
2242 | -static void rewriteJoin( |
2243 | - RewriterContext& rCtx, |
2244 | - PredicateInfo& predInfo, |
2245 | - bool& modified) |
2246 | +void IndexJoinRule::rewriteJoin(PredicateInfo& predInfo) |
2247 | { |
2248 | - // std::cout << "!!!!! Found Join Index Predicate !!!!!" << std::endl << std::endl; |
2249 | - |
2250 | - const QueryLoc& loc = predInfo.thePredicate->get_loc(); |
2251 | + CompilerCB* ccb = theRootExpr->get_ccb(); |
2252 | + ExprManager* em = ccb->getExprManager(); |
2253 | static_context* sctx = predInfo.thePredicate->get_sctx(); |
2254 | user_function* udf = predInfo.thePredicate->get_udf(); |
2255 | - for_clause* fc = predInfo.theInnerVar->get_forlet_clause(); |
2256 | - |
2257 | - assert(udf == rCtx.theUDF); |
2258 | - |
2259 | - long maxInnerVarId = -1; |
2260 | - |
2261 | - // The index domain expr is the expr that defines the inner var, expanded, if |
2262 | - // possible, so that it does not reference any variables defined after the outer |
2263 | - // var (because the index must be built ouside the loop of the outer FOR var). |
2264 | - // Note: must clone fc->get_expr() because expandVars modifies its input, but |
2265 | - // fc->get_expr should not be modified, because we may discover later that the |
2266 | - // rewrite is not possible after all, |
2267 | - expr::substitution_t subst; |
2268 | - expr* domainExpr = fc->get_expr()->clone(udf, subst); |
2269 | - |
2270 | - if (!expandVars(rCtx, domainExpr, predInfo.theOuterVarId, maxInnerVarId)) |
2271 | - return; |
2272 | - |
2273 | - // |
2274 | - // Create the index name and the "create-index()" expr |
2275 | + const QueryLoc& loc = predInfo.theInnerVar->get_loc(); |
2276 | + |
2277 | + for_clause* innerClause = predInfo.theInnerVar->get_forlet_clause(); |
2278 | + |
2279 | + // |
2280 | + // The index domain expr is the expr that defines the inner var, expanded so |
2281 | + // that it does not reference any LET variables defined after the outer var |
2282 | + // |
2283 | + expr* indexDomainExpr = innerClause->get_expr(); |
2284 | + expandVars(indexDomainExpr, predInfo.theOuterVarId, predInfo.theInnerVarId); |
2285 | + |
2286 | + // |
2287 | + // Create the index declaration |
2288 | // |
2289 | std::ostringstream os; |
2290 | - os << "tempIndex" << rCtx.theCCB->theTempIndexCounter++; |
2291 | + os << "tempIndex" << ccb->theTempIndexCounter++; |
2292 | |
2293 | store::Item_t qname; |
2294 | GENV_ITEMFACTORY->createQName(qname, "", "", os.str().c_str()); |
2295 | |
2296 | - expr* qnameExpr(rCtx.theEM->create_const_expr(sctx, udf, loc, qname)); |
2297 | - expr* buildExpr = NULL; |
2298 | - |
2299 | - fo_expr* createExpr = rCtx.theEM-> |
2300 | - create_fo_expr(sctx, |
2301 | - udf, |
2302 | - loc, |
2303 | - BUILTIN_FUNC(OP_CREATE_INTERNAL_INDEX_2), |
2304 | - qnameExpr, |
2305 | - buildExpr); |
2306 | - |
2307 | - // |
2308 | - // Find where to place the create-index expr |
2309 | - // |
2310 | - if (maxInnerVarId >= 0) |
2311 | - { |
2312 | - // The domain expr depends on some flwor var that is defined before the outer |
2313 | - // var. In this case, we find the flwor expr defining the inner-most var V |
2314 | - // referenced by the domain expr of the index. Let F be this flwor expr. If |
2315 | - // F does not define the outer var as well, then we create the index in the |
2316 | - // return expr of F. Otherwise, we first break up F by creating a sub-flwor |
2317 | - // expr (subF) and moving all clauses of F that appear after V's defining |
2318 | - // clause into subF, making the return expr of f be the return expr of subF, |
2319 | - // and setting subF as the return expr of F. Then, we create the index in |
2320 | - // the return expr of F. |
2321 | - |
2322 | - const var_expr* mostInnerVar = (*rCtx.theIdVarMap)[maxInnerVarId]; |
2323 | - flwor_clause* mostInnerVarClause = mostInnerVar->get_flwor_clause(); |
2324 | - |
2325 | - flwor_expr* innerFlwor = NULL; |
2326 | - ulong innerPosInStack = 0; |
2327 | - ulong mostInnerVarPos = 0; |
2328 | - |
2329 | - if (!findFlworForVar(rCtx, |
2330 | - mostInnerVar, |
2331 | - innerFlwor, |
2332 | - mostInnerVarPos, |
2333 | - innerPosInStack)) |
2334 | - return; |
2335 | - |
2336 | - csize numClauses = innerFlwor->num_clauses(); |
2337 | - |
2338 | - if (innerFlwor->defines_variable(predInfo.theOuterVar) >= 0 || |
2339 | - mostInnerVarPos < numClauses-1) |
2340 | - { |
2341 | - ZORBA_ASSERT(mostInnerVarPos < numClauses-1); |
2342 | - |
2343 | - const QueryLoc& nestedLoc = mostInnerVarClause->get_loc(); |
2344 | - |
2345 | - flwor_expr* nestedFlwor = rCtx.theEM-> |
2346 | - create_flwor_expr(sctx, udf, nestedLoc, false); |
2347 | - |
2348 | - for (csize i = mostInnerVarPos+1; i < numClauses; ++i) |
2349 | - { |
2350 | - nestedFlwor->add_clause(innerFlwor->get_clause(i)); |
2351 | - } |
2352 | - |
2353 | - for (csize i = numClauses - 1; i > mostInnerVarPos; --i) |
2354 | - { |
2355 | - innerFlwor->remove_clause(i); |
2356 | - } |
2357 | - |
2358 | - nestedFlwor->set_return_expr(innerFlwor->get_return_expr()); |
2359 | - |
2360 | - std::vector<expr*> args(2); |
2361 | - args[0] = createExpr; |
2362 | - args[1] = nestedFlwor; |
2363 | - |
2364 | - block_expr* seqExpr = rCtx.theEM-> |
2365 | - create_block_expr(sctx, udf, loc, false, args, NULL); |
2366 | - |
2367 | - innerFlwor->set_return_expr(seqExpr); |
2368 | - |
2369 | - if (predInfo.theFlworExpr == innerFlwor) |
2370 | - { |
2371 | - // The where clause has moved to the nested flwor. |
2372 | - predInfo.theFlworExpr = nestedFlwor; |
2373 | - } |
2374 | - } |
2375 | - else |
2376 | - { |
2377 | - expr* returnExpr = innerFlwor->get_return_expr(); |
2378 | - |
2379 | - if (returnExpr->get_expr_kind() == block_expr_kind) |
2380 | - { |
2381 | - block_expr* seqExpr = static_cast<block_expr*>(returnExpr); |
2382 | - |
2383 | - csize numArgs = seqExpr->size(); |
2384 | - csize arg; |
2385 | - for (arg = 0; arg < numArgs; ++arg) |
2386 | - { |
2387 | - if ((*seqExpr)[arg]->get_function_kind() != |
2388 | - FunctionConsts::OP_CREATE_INTERNAL_INDEX_2) |
2389 | - { |
2390 | - break; |
2391 | - } |
2392 | - } |
2393 | - |
2394 | - seqExpr->add_at(arg, createExpr); |
2395 | - } |
2396 | - else |
2397 | - { |
2398 | - std::vector<expr*> args(2); |
2399 | - args[0] = createExpr; |
2400 | - args[1] = returnExpr; |
2401 | - |
2402 | - block_expr* seqExpr = rCtx.theEM-> |
2403 | - create_block_expr(sctx, udf, loc, false, args, NULL); |
2404 | - |
2405 | - innerFlwor->set_return_expr(seqExpr); |
2406 | - } |
2407 | - } |
2408 | - } |
2409 | - else |
2410 | - { |
2411 | - // The inner domain expr does not reference any flwor vars. In this case, |
2412 | - // find the flwor expr defining the outer var and create the index just |
2413 | - // before this flwor. |
2414 | - flwor_expr* outerFlworExpr = NULL; |
2415 | - ulong outerPosInStack = 0; |
2416 | - ulong dummy = 0; |
2417 | - |
2418 | - if (!findFlworForVar(rCtx, |
2419 | - predInfo.theOuterVar, |
2420 | - outerFlworExpr, |
2421 | - dummy, |
2422 | - outerPosInStack)) |
2423 | - return; |
2424 | - |
2425 | - // Build outer sequential expr |
2426 | - std::vector<expr*> args(2); |
2427 | - args[0] = createExpr; |
2428 | - args[1] = outerFlworExpr; |
2429 | - |
2430 | - block_expr* seqExpr = rCtx.theEM-> |
2431 | - create_block_expr(sctx, udf, loc, false, args, NULL); |
2432 | - |
2433 | - rCtx.theFlworStack[outerPosInStack] = seqExpr; |
2434 | - } |
2435 | - |
2436 | - modified = true; |
2437 | - |
2438 | - // |
2439 | - // Replace the expr defining the inner var with an index probe. |
2440 | - // |
2441 | - fo_expr* probeExpr = NULL; |
2442 | - |
2443 | - if (predInfo.theIsGeneral) |
2444 | - { |
2445 | - probeExpr = rCtx.theEM-> |
2446 | - create_fo_expr(sctx, |
2447 | - udf, |
2448 | - loc, |
2449 | - BUILTIN_FUNC(FN_ZORBA_XQDDF_PROBE_INDEX_POINT_GENERAL_N), |
2450 | - qnameExpr, |
2451 | - const_cast<expr*>(predInfo.theOuterOp)); |
2452 | - |
2453 | - probeExpr = rCtx.theEM-> |
2454 | - create_fo_expr(sctx, |
2455 | - udf, |
2456 | - loc, |
2457 | - BUILTIN_FUNC(OP_SORT_DISTINCT_NODES_ASC_1), |
2458 | - probeExpr); |
2459 | - } |
2460 | - else |
2461 | - { |
2462 | - probeExpr = rCtx.theEM-> |
2463 | - create_fo_expr(sctx, |
2464 | - udf, |
2465 | - loc, |
2466 | - BUILTIN_FUNC(FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N), |
2467 | - qnameExpr, |
2468 | - const_cast<expr*>(predInfo.theOuterOp)); |
2469 | - } |
2470 | - |
2471 | - fc->set_expr(probeExpr); |
2472 | - |
2473 | - // |
2474 | - // Create the IndexDecl obj |
2475 | - // |
2476 | - IndexDecl_t idx = new IndexDecl(sctx, rCtx.theCCB, loc, qname); |
2477 | + IndexDecl_t idx = new IndexDecl(sctx, ccb, loc, qname); |
2478 | |
2479 | if (predInfo.theIsGeneral) |
2480 | idx->setGeneral(true); |
2481 | |
2482 | idx->setTemp(true); |
2483 | |
2484 | - idx->setDomainExpr(domainExpr); |
2485 | - |
2486 | - idx->setDomainVariable(rCtx.createTempVar(sctx, loc, var_expr::for_var)); |
2487 | - |
2488 | - idx->setDomainPositionVariable(rCtx.createTempVar(sctx, loc, var_expr::pos_var)); |
2489 | + idx->setDomainExpr(indexDomainExpr); |
2490 | + |
2491 | + idx->setDomainVariable(theRCtx->createTempVar(sctx, loc, var_expr::for_var)); |
2492 | + |
2493 | + idx->setDomainPositionVariable(theRCtx->createTempVar(sctx, loc, var_expr::pos_var)); |
2494 | |
2495 | std::vector<expr*> columnExprs(1); |
2496 | std::vector<xqtref_t> columnTypes(1); |
2497 | @@ -700,20 +1019,114 @@ |
2498 | |
2499 | idx->setOrderModifiers(modifiers); |
2500 | |
2501 | + // |
2502 | + // Create the "create-index()" expr |
2503 | + // |
2504 | + expr* qnameExpr = em->create_const_expr(sctx, udf, loc, qname); |
2505 | + |
2506 | + expr* buildExpr = idx->getBuildExpr(loc); |
2507 | + |
2508 | + function* f = BUILTIN_FUNC(OP_CREATE_INTERNAL_INDEX_2); |
2509 | + fo_expr* createExpr = em->create_fo_expr(sctx, udf, loc, f, qnameExpr, buildExpr); |
2510 | + |
2511 | + DynamicBitset indexVars; |
2512 | + expr_tools::build_expr_to_vars_map(createExpr, |
2513 | + *theVarIdMap, |
2514 | + indexVars, |
2515 | + *theExprVarsMap); |
2516 | + |
2517 | + // |
2518 | + // Place the create-index expr to its target position |
2519 | + // |
2520 | + expr* targetExpr = theVarDefExprs[predInfo.theStackPos]; |
2521 | + csize targetPos = predInfo.theChildPos; |
2522 | + expr_kind_t targetKind = targetExpr->get_expr_kind(); |
2523 | + |
2524 | + if (targetKind == block_expr_kind) |
2525 | + { |
2526 | + block_expr* block = static_cast<block_expr*>(targetExpr); |
2527 | + |
2528 | + block->add(targetPos, createExpr); |
2529 | + } |
2530 | + else if (targetKind == flwor_expr_kind || targetKind == gflwor_expr_kind) |
2531 | + { |
2532 | + flwor_expr* flwor = static_cast<flwor_expr*>(targetExpr); |
2533 | + csize numClauses = flwor->num_clauses(); |
2534 | + |
2535 | + if (targetPos == numClauses) |
2536 | + { |
2537 | + std::vector<expr*> args(2); |
2538 | + args[0] = createExpr; |
2539 | + args[1] = flwor->get_return_expr(); |
2540 | + |
2541 | + block_expr* block = em->create_block_expr(sctx, udf, loc, false, args, NULL); |
2542 | + |
2543 | + DynamicBitset blockVars = indexVars; |
2544 | + blockVars.set_union((*theExprVarsMap)[flwor->get_return_expr()]); |
2545 | + (*theExprVarsMap)[block] = blockVars; |
2546 | + |
2547 | + flwor->set_return_expr(block); |
2548 | + } |
2549 | + else |
2550 | + { |
2551 | + var_expr* dummyVar = theRCtx->createTempVar(sctx, loc, var_expr::let_var); |
2552 | + |
2553 | + let_clause* createClause = |
2554 | + em->create_let_clause(sctx, loc, dummyVar, createExpr, false); |
2555 | + |
2556 | + flwor->add_clause(targetPos, createClause); |
2557 | + } |
2558 | + } |
2559 | + else |
2560 | + { |
2561 | + ZORBA_ASSERT(false); |
2562 | + } |
2563 | + |
2564 | + // |
2565 | + // Replace the expr defining the inner var with an index probe. |
2566 | + // |
2567 | + fo_expr* probeExpr = NULL; |
2568 | + |
2569 | + if (predInfo.theIsGeneral) |
2570 | + { |
2571 | + probeExpr = em-> |
2572 | + create_fo_expr(sctx, |
2573 | + udf, |
2574 | + loc, |
2575 | + BUILTIN_FUNC(FN_ZORBA_XQDDF_PROBE_INDEX_POINT_GENERAL_N), |
2576 | + qnameExpr, |
2577 | + const_cast<expr*>(predInfo.theOuterOp)); |
2578 | + |
2579 | + probeExpr = em-> |
2580 | + create_fo_expr(sctx, |
2581 | + udf, |
2582 | + loc, |
2583 | + BUILTIN_FUNC(OP_SORT_DISTINCT_NODES_ASC_1), |
2584 | + probeExpr); |
2585 | + } |
2586 | + else |
2587 | + { |
2588 | + probeExpr = em-> |
2589 | + create_fo_expr(sctx, |
2590 | + udf, |
2591 | + loc, |
2592 | + BUILTIN_FUNC(FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N), |
2593 | + qnameExpr, |
2594 | + const_cast<expr*>(predInfo.theOuterOp)); |
2595 | + } |
2596 | + |
2597 | + DynamicBitset probeVars = (*theExprVarsMap)[predInfo.theOuterOp]; |
2598 | + (*theExprVarsMap)[probeExpr] = probeVars; |
2599 | + |
2600 | + innerClause->set_expr(probeExpr); |
2601 | + |
2602 | sctx->bind_index(idx, loc); |
2603 | |
2604 | - buildExpr = idx->getBuildExpr(loc); |
2605 | - |
2606 | - createExpr->set_arg(1, buildExpr); |
2607 | - |
2608 | if (Properties::instance()->printIntermediateOpt()) |
2609 | { |
2610 | std::cout << std::endl << idx->toString() << std::endl; |
2611 | } |
2612 | |
2613 | - //idx->setDomainExpr(NULL); |
2614 | - //idx->setDomainVariable(NULL); |
2615 | - |
2616 | #if 0 |
2617 | if (predInfo.theIsGeneral) |
2618 | std::cout << "!!!!! Applied General Hash Join !!!!!" << std::endl << std::endl; |
2619 | @@ -723,133 +1136,64 @@ |
2620 | } |
2621 | |
2622 | |
2623 | - |
2624 | /******************************************************************************* |
2625 | |
2626 | ********************************************************************************/ |
2627 | -static bool expandVars( |
2628 | - RewriterContext& rCtx, |
2629 | - expr* subExpr, |
2630 | - ulong outerVarId, |
2631 | - long& maxVarId) |
2632 | +void IndexJoinRule::expandVars(expr* e, csize outerVarId, csize innerVarId) |
2633 | { |
2634 | - if (subExpr->get_expr_kind() == wrapper_expr_kind) |
2635 | + if (e->get_expr_kind() == wrapper_expr_kind) |
2636 | { |
2637 | - wrapper_expr* wrapper = reinterpret_cast<wrapper_expr*>(subExpr); |
2638 | + wrapper_expr* wrapper = static_cast<wrapper_expr*>(e); |
2639 | |
2640 | if (wrapper->get_input()->get_expr_kind() == var_expr_kind) |
2641 | { |
2642 | - var_expr* var = reinterpret_cast<var_expr*>(wrapper->get_input()); |
2643 | - long varid = -1; |
2644 | + var_expr* var = static_cast<var_expr*>(wrapper->get_input()); |
2645 | + csize varid = 0; |
2646 | |
2647 | - if (rCtx.theVarIdMap->find(var) != rCtx.theVarIdMap->end()) |
2648 | - { |
2649 | - varid = (*rCtx.theVarIdMap)[var]; |
2650 | - } |
2651 | - else if (var->get_kind() == var_expr::local_var) |
2652 | - { |
2653 | - // TODO: allow index domain exprs to reference local vars |
2654 | - return false; |
2655 | - } |
2656 | + ZORBA_ASSERT(theVarIdMap->find(var) != theVarIdMap->end()); |
2657 | + |
2658 | + varid = (*theVarIdMap)[var]; |
2659 | |
2660 | // If it is a variable that is defined after the outer var |
2661 | - if (varid > (long)outerVarId) |
2662 | + if (outerVarId <= varid && varid < innerVarId) |
2663 | { |
2664 | if (var->get_kind() == var_expr::let_var) |
2665 | { |
2666 | wrapper->set_expr(var->get_forlet_clause()->get_expr()); |
2667 | |
2668 | - return expandVars(rCtx, wrapper, outerVarId, maxVarId); |
2669 | + return expandVars(wrapper, outerVarId, innerVarId); |
2670 | } |
2671 | else if (var->get_kind() == var_expr::for_var) |
2672 | { |
2673 | #if 1 |
2674 | - return false; |
2675 | + ZORBA_ASSERT(false); |
2676 | #else |
2677 | // TODO: to expand a FOR var, we must make sure that the expr is a |
2678 | // map w.r.t. that var. |
2679 | wrapper->set_expr(var->get_forlet_clause()->get_expr()); |
2680 | - |
2681 | - return expandVars(rCtx, wrapper, outerVarId, maxVarId); |
2682 | + return expandVars(wrapper, outerVarId, maxVarId); |
2683 | #endif |
2684 | } |
2685 | else |
2686 | { |
2687 | - return false; |
2688 | + ZORBA_ASSERT(false); |
2689 | } |
2690 | } |
2691 | - else |
2692 | - { |
2693 | - if (varid > maxVarId) |
2694 | - maxVarId = varid; |
2695 | - |
2696 | - return true; |
2697 | - } |
2698 | } |
2699 | } |
2700 | - else if (subExpr->get_expr_kind() == var_expr_kind) |
2701 | + else if (e->get_expr_kind() == var_expr_kind) |
2702 | { |
2703 | ZORBA_ASSERT(false); |
2704 | } |
2705 | - |
2706 | - ExprIterator iter(subExpr); |
2707 | - while (!iter.done()) |
2708 | - { |
2709 | - if (!expandVars(rCtx, **iter, outerVarId, maxVarId)) |
2710 | - return false; |
2711 | - |
2712 | - iter.next(); |
2713 | - } |
2714 | - |
2715 | - return true; |
2716 | -} |
2717 | - |
2718 | - |
2719 | -/******************************************************************************* |
2720 | - Find the flwor expr defining the given var. |
2721 | -********************************************************************************/ |
2722 | -static bool findFlworForVar( |
2723 | - RewriterContext& rCtx, |
2724 | - const var_expr* var, |
2725 | - flwor_expr*& flworExpr, |
2726 | - ulong& varPos, |
2727 | - ulong& posInStack) |
2728 | -{ |
2729 | - flworExpr = NULL; |
2730 | - |
2731 | - long numFlwors = (long)rCtx.theFlworStack.size(); |
2732 | - |
2733 | - for (long i = numFlwors - 1; i >= 0; --i) |
2734 | - { |
2735 | - if (rCtx.theFlworStack[i]->get_expr_kind() == trycatch_expr_kind) |
2736 | - return false; |
2737 | - |
2738 | - assert(rCtx.theFlworStack[i]->get_expr_kind() == flwor_expr_kind); |
2739 | - |
2740 | - flworExpr = static_cast<flwor_expr*>(rCtx.theFlworStack[i]); |
2741 | - |
2742 | - if (i < numFlwors - 1 && |
2743 | - rCtx.theInReturnClause[i] == true && |
2744 | - flworExpr->is_sequential()) |
2745 | - return false; |
2746 | - |
2747 | - // This condition is rather conservative and can be relaxed. TODO |
2748 | - if (flworExpr->has_sequential_clauses()) |
2749 | - return false; |
2750 | - |
2751 | - long pos; |
2752 | - if ((pos = flworExpr->defines_variable(var)) >= 0) |
2753 | + else |
2754 | + { |
2755 | + ExprIterator iter(e); |
2756 | + while (!iter.done()) |
2757 | { |
2758 | - varPos = pos; |
2759 | - posInStack = i; |
2760 | - break; |
2761 | + expandVars(**iter, outerVarId, innerVarId); |
2762 | + iter.next(); |
2763 | } |
2764 | - |
2765 | - flworExpr = NULL; |
2766 | } |
2767 | - |
2768 | - assert(flworExpr != NULL); |
2769 | - return true; |
2770 | } |
2771 | |
2772 | |
2773 | |
2774 | === added file 'src/compiler/rewriter/rules/index_join_rule.h' |
2775 | --- src/compiler/rewriter/rules/index_join_rule.h 1970-01-01 00:00:00 +0000 |
2776 | +++ src/compiler/rewriter/rules/index_join_rule.h 2013-02-28 21:53:23 +0000 |
2777 | @@ -0,0 +1,96 @@ |
2778 | +/* |
2779 | + * Copyright 2006-2008 The FLWOR Foundation. |
2780 | + * |
2781 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
2782 | + * you may not use this file except in compliance with the License. |
2783 | + * You may obtain a copy of the License at |
2784 | + * |
2785 | + * http://www.apache.org/licenses/LICENSE-2.0 |
2786 | + * |
2787 | + * Unless required by applicable law or agreed to in writing, software |
2788 | + * distributed under the License is distributed on an "AS IS" BASIS, |
2789 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
2790 | + * See the License for the specific language governing permissions and |
2791 | + * limitations under the License. |
2792 | + */ |
2793 | +#pragma once |
2794 | +#ifndef ZORBA_COMPILER_REWRITER_INDEX_JOINS_H |
2795 | +#define ZORBA_COMPILER_REWRITER_INDEX_JOINS_H |
2796 | + |
2797 | + |
2798 | +#include "compiler/rewriter/rules/rule_base.h" |
2799 | +#include "compiler/rewriter/tools/expr_tools.h" |
2800 | + |
2801 | +namespace zorba |
2802 | +{ |
2803 | + |
2804 | +class DynamicBitset; |
2805 | +struct PredicateInfo; |
2806 | + |
2807 | + |
2808 | +/******************************************************************************* |
2809 | + |
2810 | + theVarDefExprs: |
2811 | + --------------- |
2812 | + A stack Keeping track of "in-scope" variable-defining exprs. Var-defining |
2813 | + exprs are flwors, trycatch, and block exprs (TOD: include transform exprs). |
2814 | + "in-scope" means that the rule has entered the expr but not exited it yet. |
2815 | + |
2816 | + theClauses: |
2817 | + ----------- |
2818 | + |
2819 | + theVarIdMap: |
2820 | + ------------ |
2821 | + Maps a var_expr to its unique "prefix" id. See tools/expr_tools/h for more |
2822 | + details. |
2823 | + |
2824 | + theIdVarMap: |
2825 | + ------------ |
2826 | + This is the reverse mapping of theVarIdMap. |
2827 | + |
2828 | + theExprVarsMap: |
2829 | + --------------- |
2830 | + An entry into this map maps an expr to the variables that are referenced by |
2831 | + that expr and/or its sub-exprs. See tools/expr_tools/h for more details. |
2832 | + |
2833 | +********************************************************************************/ |
2834 | +class IndexJoinRule : public RewriteRule |
2835 | +{ |
2836 | +protected: |
2837 | + RewriterContext * theRCtx; |
2838 | + |
2839 | + expr * theRootExpr; |
2840 | + |
2841 | + std::vector<expr*> theVarDefExprs; |
2842 | + std::vector<csize> theChildPositions; |
2843 | + |
2844 | + expr_tools::VarIdMap * theVarIdMap; |
2845 | + expr_tools::IdVarMap * theIdVarMap; |
2846 | + expr_tools::ExprVarsMap * theExprVarsMap; |
2847 | + |
2848 | +public: |
2849 | + IndexJoinRule(RewriterContext* rctx); |
2850 | + |
2851 | + ~IndexJoinRule(); |
2852 | + |
2853 | + expr* apply(RewriterContext& rCtx, expr* node, bool& modified); |
2854 | + |
2855 | +protected: |
2856 | + bool isIndexJoinPredicate(PredicateInfo& predInfo); |
2857 | + |
2858 | + var_expr* findLoopVar(expr* predExpr, csize& loopVarId); |
2859 | + |
2860 | + bool checkVarDeps(expr* idxExpr, csize outerVarId, csize& boundVarId); |
2861 | + |
2862 | + bool findIndexPos(PredicateInfo& predInfo, csize boundVarId); |
2863 | + |
2864 | + void rewriteJoin(PredicateInfo& predInfo); |
2865 | + |
2866 | + void expandVars(expr* idxExpr, csize outerVarId, csize innerVarId); |
2867 | +}; |
2868 | + |
2869 | + |
2870 | +} |
2871 | + |
2872 | +#endif |
2873 | +/* vim:set et sw=2 ts=2: */ |
2874 | |
2875 | === modified file 'src/compiler/rewriter/rules/index_matching_rule.cpp' |
2876 | --- src/compiler/rewriter/rules/index_matching_rule.cpp 2013-02-22 00:08:45 +0000 |
2877 | +++ src/compiler/rewriter/rules/index_matching_rule.cpp 2013-02-28 21:53:23 +0000 |
2878 | @@ -256,7 +256,7 @@ |
2879 | break; |
2880 | } |
2881 | case flwor_clause::window_clause: |
2882 | - case flwor_clause::order_clause: |
2883 | + case flwor_clause::orderby_clause: |
2884 | { |
2885 | if (firstMatchedFOR != NULL) |
2886 | { |
2887 | @@ -321,7 +321,7 @@ |
2888 | getWherePreds(qi, static_cast<where_clause*>(qc), theUnmatchedQPreds); |
2889 | break; |
2890 | } |
2891 | - case flwor_clause::order_clause: |
2892 | + case flwor_clause::orderby_clause: |
2893 | { |
2894 | if (firstOrderByPos == 0) |
2895 | firstOrderByPos = qi; |
2896 | @@ -415,7 +415,7 @@ |
2897 | return false; |
2898 | } |
2899 | case flwor_clause::where_clause: |
2900 | - case flwor_clause::order_clause: |
2901 | + case flwor_clause::orderby_clause: |
2902 | { |
2903 | break; |
2904 | } |
2905 | @@ -554,7 +554,7 @@ |
2906 | |
2907 | break; |
2908 | } |
2909 | - case flwor_clause::order_clause: |
2910 | + case flwor_clause::orderby_clause: |
2911 | { |
2912 | orderby_clause* oc = static_cast<orderby_clause*>(c); |
2913 | |
2914 | |
2915 | === modified file 'src/compiler/rewriter/rules/nodeid_rules.cpp' |
2916 | --- src/compiler/rewriter/rules/nodeid_rules.cpp 2013-01-11 22:58:12 +0000 |
2917 | +++ src/compiler/rewriter/rules/nodeid_rules.cpp 2013-02-28 21:53:23 +0000 |
2918 | @@ -250,7 +250,7 @@ |
2919 | where_clause* wc = static_cast<where_clause*>(clause); |
2920 | apply(rCtx, wc->get_expr(), modified); |
2921 | } |
2922 | - else if (clause->get_kind() == flwor_clause::order_clause) |
2923 | + else if (clause->get_kind() == flwor_clause::orderby_clause) |
2924 | { |
2925 | // apply the rule recursively on the orderby exprs |
2926 | orderby_clause* oc = static_cast<orderby_clause*>(clause); |
2927 | |
2928 | === modified file 'src/compiler/rewriter/rules/ruleset.h' |
2929 | --- src/compiler/rewriter/rules/ruleset.h 2012-12-12 16:15:04 +0000 |
2930 | +++ src/compiler/rewriter/rules/ruleset.h 2013-02-28 21:53:23 +0000 |
2931 | @@ -236,18 +236,6 @@ |
2932 | |
2933 | |
2934 | |
2935 | -/******************************************************************************* |
2936 | - |
2937 | -********************************************************************************/ |
2938 | -class IndexJoinRule : public RewriteRule |
2939 | -{ |
2940 | -public: |
2941 | - IndexJoinRule() : RewriteRule(RewriteRule::IndexJoin, "IndexJoin") {} |
2942 | - |
2943 | - expr* apply(RewriterContext& rCtx, expr* node, bool& modified); |
2944 | -}; |
2945 | - |
2946 | - |
2947 | } |
2948 | |
2949 | #endif /* ZORBA_REWRITE_RULE_H */ |
2950 | |
2951 | === modified file 'src/compiler/rewriter/tools/dataflow_annotations.cpp' |
2952 | --- src/compiler/rewriter/tools/dataflow_annotations.cpp 2013-01-11 22:58:12 +0000 |
2953 | +++ src/compiler/rewriter/tools/dataflow_annotations.cpp 2013-02-28 21:53:23 +0000 |
2954 | @@ -407,7 +407,7 @@ |
2955 | { |
2956 | break; |
2957 | } |
2958 | - case flwor_clause::order_clause: |
2959 | + case flwor_clause::orderby_clause: |
2960 | case flwor_clause::groupby_clause: |
2961 | { |
2962 | return; |
2963 | |
2964 | === modified file 'src/compiler/rewriter/tools/expr_tools.cpp' |
2965 | --- src/compiler/rewriter/tools/expr_tools.cpp 2013-02-27 13:13:26 +0000 |
2966 | +++ src/compiler/rewriter/tools/expr_tools.cpp 2013-02-28 21:53:23 +0000 |
2967 | @@ -16,7 +16,6 @@ |
2968 | #include "stdafx.h" |
2969 | |
2970 | #include "compiler/rewriter/tools/expr_tools.h" |
2971 | -#include "compiler/rewriter/framework/rewriter_context.h" |
2972 | #include "compiler/expression/flwor_expr.h" |
2973 | #include "compiler/expression/expr.h" |
2974 | #include "compiler/expression/path_expr.h" |
2975 | @@ -38,9 +37,9 @@ |
2976 | namespace expr_tools |
2977 | { |
2978 | |
2979 | -static void add_wincond_vars(const flwor_wincond*, ulong&, VarIdMap&, IdVarMap*); |
2980 | +static void add_wincond_vars(const flwor_wincond*, csize&, VarIdMap&, IdVarMap*); |
2981 | |
2982 | -static void add_var(var_expr*, ulong&, VarIdMap&, IdVarMap*); |
2983 | +static void add_var(var_expr*, csize&, VarIdMap&, IdVarMap*); |
2984 | |
2985 | static void remove_wincond_vars(const flwor_wincond*, const VarIdMap&, DynamicBitset&); |
2986 | |
2987 | @@ -718,18 +717,19 @@ |
2988 | |
2989 | |
2990 | /******************************************************************************* |
2991 | - Let FLWOR(e) be the set of flwor exprs within the expr tree rooted at expr e. |
2992 | - Let FV(e) be the set of variables defined in any of the flwor exprs in |
2993 | - FLWOR(e). This method assigns a prefix id to each variable in FV(e) and |
2994 | - stores the mapping between var_expr and prefix id in "varidmap" and the |
2995 | - reverse mapping in "idvapmap". It also returns the number of vars in FV(e). |
2996 | + Let VDE(e) be the set of variable-defining exprs (i.e., flwor, trycatch, or |
2997 | + vardecl exprs) within the expr tree rooted at expr e. Let V(e) be the set of |
2998 | + variables defined in any of the exprs in VDE(e). This method assigns a prefix |
2999 | + id to each variable in V(e) and stores the mapping between var_expr and prefix |
3000 | + id in "varidmap" and the reverse mapping in "idvapmap". It also returns the |
3001 | + number of vars in V(e). |
3002 | |
3003 | - Given 2 vars v1 and v2 in FV(e), their prefix ids allows to check if v1 is |
3004 | + Given 2 vars v1 and v2 in V(e), their prefix ids allows to check if v1 is |
3005 | defined before v2: v1 is defined before v2 iff id(v1) < id(v2). |
3006 | ********************************************************************************/ |
3007 | void index_flwor_vars( |
3008 | const expr* e, |
3009 | - ulong& numVars, |
3010 | + csize& numVars, |
3011 | VarIdMap& varidmap, |
3012 | IdVarMap* idvarmap) |
3013 | { |
3014 | @@ -738,32 +738,28 @@ |
3015 | { |
3016 | const flwor_expr* flwor = static_cast<const flwor_expr *>(e); |
3017 | |
3018 | - for (flwor_expr::clause_list_t::const_iterator i = flwor->clause_begin(); |
3019 | - i != flwor->clause_end(); |
3020 | - ++i) |
3021 | + flwor_expr::clause_list_t::const_iterator i = flwor->clause_begin(); |
3022 | + flwor_expr::clause_list_t::const_iterator end = flwor->clause_end(); |
3023 | + for (; i != end; ++i) |
3024 | { |
3025 | const flwor_clause* c = *i; |
3026 | |
3027 | - if (c->get_kind() == flwor_clause::for_clause) |
3028 | - { |
3029 | - const for_clause* fc = static_cast<const for_clause *>(c); |
3030 | - |
3031 | - add_var(fc->get_var(), numVars, varidmap, idvarmap); |
3032 | - add_var(fc->get_pos_var(), numVars, varidmap, idvarmap); |
3033 | - add_var(fc->get_score_var(), numVars, varidmap, idvarmap); |
3034 | - |
3035 | - index_flwor_vars(fc->get_expr(), numVars, varidmap, idvarmap); |
3036 | - } |
3037 | - else if (c->get_kind() == flwor_clause::let_clause) |
3038 | - { |
3039 | - const let_clause* lc = static_cast<const let_clause *>(c); |
3040 | - |
3041 | - add_var(lc->get_var(), numVars, varidmap, idvarmap); |
3042 | - add_var(lc->get_score_var(), numVars, varidmap, idvarmap); |
3043 | - |
3044 | - index_flwor_vars(lc->get_expr(), numVars, varidmap, idvarmap); |
3045 | - } |
3046 | - else if (c->get_kind() == flwor_clause::window_clause) |
3047 | + switch (c->get_kind()) |
3048 | + { |
3049 | + case flwor_clause::for_clause: |
3050 | + case flwor_clause::let_clause: |
3051 | + { |
3052 | + const forlet_clause* flc = static_cast<const forlet_clause *>(c); |
3053 | + |
3054 | + add_var(flc->get_var(), numVars, varidmap, idvarmap); |
3055 | + add_var(flc->get_pos_var(), numVars, varidmap, idvarmap); |
3056 | + add_var(flc->get_score_var(), numVars, varidmap, idvarmap); |
3057 | + |
3058 | + index_flwor_vars(flc->get_expr(), numVars, varidmap, idvarmap); |
3059 | + |
3060 | + break; |
3061 | + } |
3062 | + case flwor_clause::window_clause: |
3063 | { |
3064 | const window_clause* wc = static_cast<const window_clause *>(c); |
3065 | |
3066 | @@ -779,8 +775,10 @@ |
3067 | |
3068 | if (stopCond != NULL) |
3069 | add_wincond_vars(stopCond, numVars, varidmap, idvarmap); |
3070 | + |
3071 | + break; |
3072 | } |
3073 | - else if (c->get_kind() == flwor_clause::groupby_clause) |
3074 | + case flwor_clause::groupby_clause: |
3075 | { |
3076 | const groupby_clause* gc = static_cast<const groupby_clause *>(c); |
3077 | |
3078 | @@ -808,20 +806,26 @@ |
3079 | { |
3080 | add_var(ngvars[i].second, numVars, varidmap, idvarmap); |
3081 | } |
3082 | + |
3083 | + break; |
3084 | } |
3085 | - else if (c->get_kind() == flwor_clause::count_clause) |
3086 | + case flwor_clause::count_clause: |
3087 | { |
3088 | const count_clause* cc = static_cast<const count_clause *>(c); |
3089 | |
3090 | add_var(cc->get_var(), numVars, varidmap, idvarmap); |
3091 | + |
3092 | + break; |
3093 | } |
3094 | - else if (c->get_kind() == flwor_clause::where_clause) |
3095 | + case flwor_clause::where_clause: |
3096 | { |
3097 | const where_clause* wc = static_cast<const where_clause *>(c); |
3098 | |
3099 | index_flwor_vars(wc->get_expr(), numVars, varidmap, idvarmap); |
3100 | + |
3101 | + break; |
3102 | } |
3103 | - else if (c->get_kind() == flwor_clause::order_clause) |
3104 | + case flwor_clause::orderby_clause: |
3105 | { |
3106 | const orderby_clause* obc = static_cast<const orderby_clause *>(c); |
3107 | csize numExprs = obc->num_columns(); |
3108 | @@ -829,6 +833,17 @@ |
3109 | { |
3110 | index_flwor_vars(obc->get_column_expr(i), numVars, varidmap, idvarmap); |
3111 | } |
3112 | + |
3113 | + break; |
3114 | + } |
3115 | + case flwor_clause::materialize_clause: |
3116 | + { |
3117 | + break; |
3118 | + } |
3119 | + default: |
3120 | + { |
3121 | + ZORBA_ASSERT(false); |
3122 | + } |
3123 | } |
3124 | } |
3125 | |
3126 | @@ -847,7 +862,7 @@ |
3127 | const catch_clause* clause = (*trycatch)[i]; |
3128 | |
3129 | catch_clause::var_map_t& trycatchVars = |
3130 | - const_cast<catch_clause*>(clause)->get_vars(); |
3131 | + const_cast<catch_clause*>(clause)->get_vars(); |
3132 | |
3133 | catch_clause::var_map_t::const_iterator ite = trycatchVars.begin(); |
3134 | catch_clause::var_map_t::const_iterator end = trycatchVars.end(); |
3135 | @@ -860,6 +875,14 @@ |
3136 | index_flwor_vars(trycatch->get_catch_expr(i), numVars, varidmap, idvarmap); |
3137 | } |
3138 | } |
3139 | + else if (e->get_expr_kind() == var_decl_expr_kind) |
3140 | + { |
3141 | + const var_decl_expr* vdecl = static_cast<const var_decl_expr*>(e); |
3142 | + add_var(vdecl->get_var_expr(), numVars, varidmap, idvarmap); |
3143 | + |
3144 | + if (vdecl->get_init_expr()) |
3145 | + index_flwor_vars(vdecl->get_init_expr(), numVars, varidmap, idvarmap); |
3146 | + } |
3147 | else |
3148 | { |
3149 | ExprConstIterator iter(e); |
3150 | @@ -881,7 +904,7 @@ |
3151 | ********************************************************************************/ |
3152 | static void add_wincond_vars( |
3153 | const flwor_wincond* cond, |
3154 | - ulong& numVars, |
3155 | + csize& numVars, |
3156 | VarIdMap& varidmap, |
3157 | IdVarMap* idvarmap) |
3158 | { |
3159 | @@ -907,13 +930,13 @@ |
3160 | ********************************************************************************/ |
3161 | static void add_var( |
3162 | var_expr* v, |
3163 | - ulong& numVars, |
3164 | + csize& numVars, |
3165 | VarIdMap& varidmap, |
3166 | IdVarMap* idvarmap) |
3167 | { |
3168 | if (v != NULL) |
3169 | { |
3170 | - varidmap[v] = numVars++; |
3171 | + varidmap[v] = ++numVars; |
3172 | if (idvarmap) |
3173 | idvarmap->push_back(v); |
3174 | } |
3175 | @@ -922,9 +945,9 @@ |
3176 | |
3177 | /******************************************************************************* |
3178 | For each expr E in the expr tree rooted at "e", this method computes the set |
3179 | - of variables that belong to FV(e) and are referenced by E. Let V(E) be this |
3180 | + of variables that belong to V(e) and are referenced by E. Let V(E) be this |
3181 | set. V(E) is implemented as a bitset ("freeset") whose size is equal to the |
3182 | - size of FV(e) and whose i-th bit is on iff the var with prefix id i belongs |
3183 | + size of V(e) and whose i-th bit is on iff the var with prefix id i belongs |
3184 | to V(E). The mapping between E and V(E) is stored in "freevarMap". |
3185 | ********************************************************************************/ |
3186 | void build_expr_to_vars_map( |
3187 | @@ -935,7 +958,7 @@ |
3188 | { |
3189 | if (e->get_expr_kind() == var_expr_kind) |
3190 | { |
3191 | - set_bit(static_cast<var_expr *>(e), varmap, freeset, true); |
3192 | + set_bit(static_cast<var_expr*>(e), varmap, freeset, true); |
3193 | freevarMap[e] = freeset; |
3194 | return; |
3195 | } |
3196 | @@ -964,28 +987,26 @@ |
3197 | { |
3198 | flwor_expr* flwor = static_cast<flwor_expr *>(e); |
3199 | |
3200 | - for(flwor_expr::clause_list_t::const_iterator i = flwor->clause_begin(); |
3201 | - i != flwor->clause_end(); |
3202 | - ++i) |
3203 | + for (flwor_expr::clause_list_t::const_iterator i = flwor->clause_begin(); |
3204 | + i != flwor->clause_end(); |
3205 | + ++i) |
3206 | { |
3207 | const flwor_clause* c = *i; |
3208 | |
3209 | - if (c->get_kind() == flwor_clause::for_clause) |
3210 | - { |
3211 | - const for_clause* fc = static_cast<const for_clause *>(c); |
3212 | - |
3213 | - set_bit(fc->get_var(), varmap, freeset, false); |
3214 | - set_bit(fc->get_pos_var(), varmap, freeset, false); |
3215 | - set_bit(fc->get_score_var(), varmap, freeset, false); |
3216 | - } |
3217 | - else if (c->get_kind() == flwor_clause::let_clause) |
3218 | - { |
3219 | - const let_clause* lc = static_cast<const let_clause *>(c); |
3220 | - |
3221 | - set_bit(lc->get_var(), varmap, freeset, false); |
3222 | - set_bit(lc->get_score_var(), varmap, freeset, false); |
3223 | - } |
3224 | - else if (c->get_kind() == flwor_clause::window_clause) |
3225 | + switch (c->get_kind()) |
3226 | + { |
3227 | + case flwor_clause::for_clause: |
3228 | + case flwor_clause::let_clause: |
3229 | + { |
3230 | + const forlet_clause* flc = static_cast<const forlet_clause *>(c); |
3231 | + |
3232 | + set_bit(flc->get_var(), varmap, freeset, false); |
3233 | + set_bit(flc->get_pos_var(), varmap, freeset, false); |
3234 | + set_bit(flc->get_score_var(), varmap, freeset, false); |
3235 | + |
3236 | + break; |
3237 | + } |
3238 | + case flwor_clause::window_clause: |
3239 | { |
3240 | const window_clause* wc = static_cast<const window_clause *>(c); |
3241 | |
3242 | @@ -999,8 +1020,10 @@ |
3243 | |
3244 | if (stopCond != NULL) |
3245 | remove_wincond_vars(stopCond, varmap, freeset); |
3246 | + |
3247 | + break; |
3248 | } |
3249 | - else if (c->get_kind() == flwor_clause::groupby_clause) |
3250 | + case flwor_clause::groupby_clause: |
3251 | { |
3252 | const groupby_clause* gc = static_cast<const groupby_clause *>(c); |
3253 | |
3254 | @@ -1019,12 +1042,27 @@ |
3255 | { |
3256 | set_bit(ngvars[i].second, varmap, freeset, false); |
3257 | } |
3258 | + |
3259 | + break; |
3260 | } |
3261 | - else if (c->get_kind() == flwor_clause::count_clause) |
3262 | + case flwor_clause::count_clause: |
3263 | { |
3264 | const count_clause* cc = static_cast<const count_clause *>(c); |
3265 | |
3266 | set_bit(cc->get_var(), varmap, freeset, false); |
3267 | + |
3268 | + break; |
3269 | + } |
3270 | + case flwor_clause::where_clause: |
3271 | + case flwor_clause::orderby_clause: |
3272 | + case flwor_clause::materialize_clause: |
3273 | + { |
3274 | + break; |
3275 | + } |
3276 | + default: |
3277 | + { |
3278 | + ZORBA_ASSERT(false); |
3279 | + } |
3280 | } |
3281 | } |
3282 | } |
3283 | @@ -1039,17 +1077,32 @@ |
3284 | const catch_clause* clause = (*trycatch)[i]; |
3285 | |
3286 | catch_clause::var_map_t& trycatchVars = |
3287 | - const_cast<catch_clause*>(clause)->get_vars(); |
3288 | + const_cast<catch_clause*>(clause)->get_vars(); |
3289 | |
3290 | catch_clause::var_map_t::const_iterator ite = trycatchVars.begin(); |
3291 | catch_clause::var_map_t::const_iterator end = trycatchVars.end(); |
3292 | for (; ite != end; ++ite) |
3293 | { |
3294 | - var_expr* trycatchVar = (*ite).second; |
3295 | - set_bit(trycatchVar, varmap, freeset, false); |
3296 | + var_expr* v = (*ite).second; |
3297 | + set_bit(v, varmap, freeset, false); |
3298 | } |
3299 | } |
3300 | } |
3301 | + else if (e->get_expr_kind() == block_expr_kind) |
3302 | + { |
3303 | + block_expr* block = static_cast<block_expr*>(e); |
3304 | + |
3305 | + csize numArgs = block->size(); |
3306 | + |
3307 | + for (csize i = 0; i < numArgs; ++i) |
3308 | + { |
3309 | + if ((*block)[i]->get_expr_kind() != var_decl_expr_kind) |
3310 | + continue; |
3311 | + |
3312 | + var_expr* v = static_cast<var_decl_expr*>((*block)[i])->get_var_expr(); |
3313 | + set_bit(v, varmap, freeset, false); |
3314 | + } |
3315 | + } |
3316 | |
3317 | freevarMap[e] = freeset; |
3318 | } |
3319 | |
3320 | === modified file 'src/compiler/rewriter/tools/expr_tools.h' |
3321 | --- src/compiler/rewriter/tools/expr_tools.h 2012-11-30 13:46:07 +0000 |
3322 | +++ src/compiler/rewriter/tools/expr_tools.h 2013-02-28 21:53:23 +0000 |
3323 | @@ -48,12 +48,7 @@ |
3324 | |
3325 | bool match_exact(expr* query, expr* ast, expr::substitution_t& subst); |
3326 | |
3327 | - |
3328 | -int count_variable_uses( |
3329 | - expr* root, |
3330 | - var_expr* var, |
3331 | - int limit, |
3332 | - std::vector<expr**>* path); |
3333 | +int count_variable_uses(expr* root, var_expr* v, int limit, std::vector<expr**>* path); |
3334 | |
3335 | |
3336 | /******************************************************************************* |
3337 | @@ -63,10 +58,39 @@ |
3338 | |
3339 | |
3340 | /******************************************************************************* |
3341 | + Each entry of VarIdMap maps a var_expr to its unique "prefix" id. The "prefix" |
3342 | + id has the following property: for 2 vars v1 and v2, v1 is defined before v2 |
3343 | + if and only if prefix-id(v1) < prefix-id(v2). See the index_flwor_vars() |
3344 | + function in expr_tools.cpp for more details. |
3345 | +********************************************************************************/ |
3346 | +typedef std::map<var_expr *, ulong> VarIdMap; |
3347 | + |
3348 | + |
3349 | +/******************************************************************************* |
3350 | + This is the reverse mapping of VarIdMap. |
3351 | +********************************************************************************/ |
3352 | +typedef std::vector<var_expr*> IdVarMap; |
3353 | + |
3354 | + |
3355 | +/******************************************************************************* |
3356 | + An entry into this map maps an expr to the variables that are referenced by |
3357 | + that expr and/or its sub-exprs. (Note: in this context, the domain expr of a |
3358 | + var $x is not considered a sub-expr of $x, and as a result, if $x is |
3359 | + referenced by an expr E and the domain expr of $x references another var $y, |
3360 | + $y is NOT considered to be referenced by E). Only variables that have been |
3361 | + assigned a prefix id (i.e., vars that appear in an associated VarIdMap) are |
3362 | + considered. The set of vars referenced by an expr is implemented by a bitset |
3363 | + that is indexed by prefix var id and whose size (in number of bits) is equal |
3364 | + to the size of the associated VarIdMap. |
3365 | +********************************************************************************/ |
3366 | +typedef std::map<const expr *, DynamicBitset> ExprVarsMap; |
3367 | + |
3368 | + |
3369 | +/******************************************************************************* |
3370 | Util functions used by rules: HoistExprsOutOfLoops and IndexJoin. |
3371 | ********************************************************************************/ |
3372 | |
3373 | -void index_flwor_vars(const expr*, ulong&, VarIdMap&, IdVarMap*); |
3374 | +void index_flwor_vars(const expr*, csize&, VarIdMap&, IdVarMap*); |
3375 | |
3376 | void build_expr_to_vars_map(expr*, const VarIdMap&, DynamicBitset&, ExprVarsMap&); |
3377 | |
3378 | |
3379 | === modified file 'src/compiler/translator/translator.cpp' |
3380 | --- src/compiler/translator/translator.cpp 2013-02-26 22:03:23 +0000 |
3381 | +++ src/compiler/translator/translator.cpp 2013-02-28 21:53:23 +0000 |
3382 | @@ -1730,23 +1730,27 @@ |
3383 | |
3384 | if (withContextSize) |
3385 | { |
3386 | - // create a LET var equal to the seq returned by the input epxr |
3387 | + // create a LET var whose domain expr is the input epxr |
3388 | let_clause* lcInputSeq = wrap_in_letclause(inputExpr); |
3389 | + var_expr* lcInputVar = lcInputSeq->get_var(); |
3390 | |
3391 | // compute the size of the input seq |
3392 | - fo_expr* countExpr = theExprManager-> |
3393 | - create_fo_expr(theRootSctx, |
3394 | - theUDF, |
3395 | - loc, |
3396 | - BUILTIN_FUNC(FN_COUNT_1), |
3397 | - lcInputSeq->get_var()); |
3398 | + expr* varWrapper = CREATE(wrapper)(theRootSctx, theUDF, loc, lcInputVar); |
3399 | + |
3400 | + fo_expr* countExpr = CREATE(fo)(theRootSctx, |
3401 | + theUDF, |
3402 | + loc, |
3403 | + BUILTIN_FUNC(FN_COUNT_1), |
3404 | + varWrapper); |
3405 | |
3406 | normalize_fo(countExpr); |
3407 | |
3408 | forlet_clause* lcLast = wrap_in_letclause(countExpr, loc, LAST_IDX_VARNAME); |
3409 | |
3410 | // Iterate over the input seq |
3411 | - for_clause* fcDot = wrap_in_forclause(lcInputSeq->get_var(), |
3412 | + varWrapper = CREATE(wrapper)(theRootSctx, theUDF, loc, lcInputVar); |
3413 | + |
3414 | + for_clause* fcDot = wrap_in_forclause(varWrapper, |
3415 | loc, |
3416 | DOT_VARNAME, |
3417 | DOT_POS_VARNAME); |
3418 | @@ -6304,7 +6308,7 @@ |
3419 | pop_scope(); |
3420 | break; |
3421 | } |
3422 | - case flwor_clause::order_clause: |
3423 | + case flwor_clause::orderby_clause: |
3424 | case flwor_clause::where_clause: |
3425 | case flwor_clause::count_clause: |
3426 | { |
3427 | @@ -6621,9 +6625,10 @@ |
3428 | { |
3429 | TRACE_VISIT_OUT(); |
3430 | |
3431 | - window_clause* windowClause = |
3432 | - dynamic_cast<window_clause*>(theFlworClausesStack.back()); |
3433 | - assert(windowClause != NULL); |
3434 | + assert(theFlworClausesStack.back()->get_kind() == flwor_clause::window_clause); |
3435 | + |
3436 | + window_clause* windowClause = |
3437 | + static_cast<window_clause*>(theFlworClausesStack.back()); |
3438 | |
3439 | // Pop the window var and associate it with this window clause |
3440 | var_expr* windowVarExpr = pop_nodestack_var(); |
3441 | @@ -6672,8 +6677,7 @@ |
3442 | rchandle<WindowVars> vars = cond->get_winvars(); |
3443 | pop_wincond_vars(vars, inputCondVarExprs[i]); |
3444 | |
3445 | - conds[i] = theExprManager->create_flwor_wincond( |
3446 | - theSctx, |
3447 | + conds[i] = theExprManager->create_flwor_wincond(theSctx, |
3448 | cond->is_only(), |
3449 | inputCondVarExprs[i], |
3450 | outputCondVarExprs[i], |
3451 | |
3452 | === modified file 'src/runtime/core/path_iterators.cpp' |
3453 | --- src/runtime/core/path_iterators.cpp 2012-10-12 21:07:51 +0000 |
3454 | +++ src/runtime/core/path_iterators.cpp 2013-02-28 21:53:23 +0000 |
3455 | @@ -1134,12 +1134,12 @@ |
3456 | do |
3457 | { |
3458 | if (!consumeNext(state->theContextNode, theChild.getp(), planState)) |
3459 | - return false; |
3460 | + goto done; |
3461 | |
3462 | if (!state->theContextNode->isNode()) |
3463 | { |
3464 | assert(false); |
3465 | - throw XQUERY_EXCEPTION( err::XPTY0020, ERROR_LOC( loc ) ); |
3466 | + throw XQUERY_EXCEPTION(err::XPTY0020, ERROR_LOC(loc)); |
3467 | } |
3468 | } |
3469 | while (!isElementOrDocumentNode(state->theContextNode.getp())); |
3470 | @@ -1172,7 +1172,8 @@ |
3471 | state->theChildren->close(); |
3472 | } |
3473 | |
3474 | - STACK_END (state); |
3475 | + done: |
3476 | + STACK_END(state); |
3477 | } |
3478 | |
3479 | |
3480 | @@ -1245,8 +1246,7 @@ |
3481 | { |
3482 | if (!consumeNext(state->theContextNode, theChild.getp(), planState)) |
3483 | { |
3484 | - state->reset(planState); |
3485 | - return false; |
3486 | + goto done; |
3487 | } |
3488 | |
3489 | if (!state->theContextNode->isNode()) |
3490 | @@ -1309,6 +1309,7 @@ |
3491 | state->clear(); |
3492 | } |
3493 | |
3494 | + done: |
3495 | STACK_END(state); |
3496 | } |
3497 | |
3498 | @@ -1340,7 +1341,7 @@ |
3499 | do |
3500 | { |
3501 | if (!consumeNext(state->theContextNode, theChild.getp(), planState)) |
3502 | - return false; |
3503 | + goto done; |
3504 | |
3505 | if (!state->theContextNode->isNode()) |
3506 | { |
3507 | @@ -1409,7 +1410,8 @@ |
3508 | state->clear(); |
3509 | } |
3510 | |
3511 | - STACK_END (state); |
3512 | + done: |
3513 | + STACK_END(state); |
3514 | } |
3515 | |
3516 | |
3517 | @@ -1573,7 +1575,7 @@ |
3518 | state->clear(); |
3519 | } |
3520 | |
3521 | - STACK_END (state); |
3522 | + STACK_END(state); |
3523 | } |
3524 | |
3525 | |
3526 | |
3527 | === modified file 'src/util/dynamic_bitset.cpp' |
3528 | --- src/util/dynamic_bitset.cpp 2012-12-07 01:30:55 +0000 |
3529 | +++ src/util/dynamic_bitset.cpp 2013-02-28 21:53:23 +0000 |
3530 | @@ -25,7 +25,7 @@ |
3531 | std::ostream& operator <<(std::ostream& s, const DynamicBitset& set) |
3532 | { |
3533 | s << "BitSet[" << set.size() << "] = {"; |
3534 | - for(std::size_t i = 0; i < set.size(); ++i) |
3535 | + for(csize i = 0; i < set.size(); ++i) |
3536 | { |
3537 | if (set.get(i)) |
3538 | { |
3539 | |
3540 | === modified file 'src/util/dynamic_bitset.h' |
3541 | --- src/util/dynamic_bitset.h 2012-12-07 01:30:55 +0000 |
3542 | +++ src/util/dynamic_bitset.h 2013-02-28 21:53:23 +0000 |
3543 | @@ -22,6 +22,9 @@ |
3544 | #include "zorbamisc/config/stdint.h" |
3545 | #include "zorbamisc/config/platform.h" |
3546 | |
3547 | +#include "store/api/shared_types.h" |
3548 | + |
3549 | + |
3550 | namespace zorba { |
3551 | |
3552 | class DynamicBitset |
3553 | @@ -30,13 +33,13 @@ |
3554 | typedef std::vector<uint8_t> bits_t; |
3555 | |
3556 | private: |
3557 | - ulong m_num_bits; |
3558 | + csize m_num_bits; |
3559 | bits_t m_bits; |
3560 | |
3561 | public: |
3562 | - DynamicBitset() { } |
3563 | + DynamicBitset() : m_num_bits(0) { } |
3564 | |
3565 | - DynamicBitset(ulong size) |
3566 | + DynamicBitset(csize size) |
3567 | : |
3568 | m_num_bits(size), |
3569 | m_bits((size >> 3) + ((size & 7) ? 1 : 0)) |
3570 | @@ -45,20 +48,20 @@ |
3571 | |
3572 | ~DynamicBitset() { } |
3573 | |
3574 | - ulong size() const |
3575 | + csize size() const |
3576 | { |
3577 | return m_num_bits; |
3578 | } |
3579 | |
3580 | - void getSet(std::vector<ulong>& set) const |
3581 | + void getSet(std::vector<csize>& set) const |
3582 | { |
3583 | - ulong numBytes = (ulong)m_bits.size(); |
3584 | - for (ulong i = 0; i < numBytes; ++i) |
3585 | + csize numBytes = m_bits.size(); |
3586 | + for (csize i = 0; i < numBytes; ++i) |
3587 | { |
3588 | if (m_bits[i] == 0) |
3589 | continue; |
3590 | |
3591 | - for (ulong j = 0; j < 8; ++j) |
3592 | + for (csize j = 0; j < 8; ++j) |
3593 | { |
3594 | if ((m_bits[i] & (128 >> j)) != 0) // 128 = 1000 0000 |
3595 | set.push_back(i * 8 + j); |
3596 | @@ -77,16 +80,16 @@ |
3597 | return (byte & (128 >> getBitWithinByte(bit))) != 0; |
3598 | } |
3599 | |
3600 | - void set(ulong bit, bool value) |
3601 | + void set(csize bit, bool value) |
3602 | { |
3603 | - ulong off = getByteIndex(bit); |
3604 | + csize off = getByteIndex(bit); |
3605 | if (!value && m_bits.size() <= (unsigned)off) |
3606 | return; |
3607 | |
3608 | if (m_bits.size() <= (unsigned)off) |
3609 | m_bits.resize(off + 1); |
3610 | |
3611 | - ulong bitnum = getBitWithinByte(bit); |
3612 | + csize bitnum = getBitWithinByte(bit); |
3613 | if (value) |
3614 | { |
3615 | m_bits[off] |= (128 >> bitnum); |
3616 | @@ -108,7 +111,7 @@ |
3617 | |
3618 | DynamicBitset& set_union(const DynamicBitset& rhs) |
3619 | { |
3620 | - ulong idx = 0; |
3621 | + csize idx = 0; |
3622 | while(idx < m_bits.size() && idx < rhs.m_bits.size()) |
3623 | { |
3624 | m_bits[idx] |= rhs.m_bits[idx]; |
3625 | @@ -128,7 +131,7 @@ |
3626 | |
3627 | DynamicBitset& set_intersect(const DynamicBitset& rhs) |
3628 | { |
3629 | - ulong idx = 0; |
3630 | + csize idx = 0; |
3631 | while(idx < m_bits.size() && idx < rhs.m_bits.size()) |
3632 | { |
3633 | m_bits[idx] &= rhs.m_bits[idx]; |
3634 | @@ -143,12 +146,12 @@ |
3635 | |
3636 | |
3637 | private: |
3638 | - static ulong getByteIndex(ulong bit) |
3639 | + static csize getByteIndex(csize bit) |
3640 | { |
3641 | return bit >> 3; |
3642 | } |
3643 | |
3644 | - static ulong getBitWithinByte(ulong bit) |
3645 | + static csize getBitWithinByte(csize bit) |
3646 | { |
3647 | // bit = 8 ==> bit & 7 = 0, |
3648 | // bit = 9 ==> bit & 7 = 1, etc |
3649 | |
3650 | === modified file 'src/zorbaserialization/archiver.cpp' |
3651 | --- src/zorbaserialization/archiver.cpp 2012-09-19 21:16:15 +0000 |
3652 | +++ src/zorbaserialization/archiver.cpp 2013-02-28 21:53:23 +0000 |
3653 | @@ -67,7 +67,9 @@ |
3654 | theOnlyForEval(only_for_eval), |
3655 | theAllowDelay2(allow_delay) |
3656 | { |
3657 | - assert(theKind == ARCHIVE_FIELD_NORMAL); |
3658 | + assert(theKind == ARCHIVE_FIELD_NORMAL || |
3659 | + (theKind == ARCHIVE_FIELD_PTR && |
3660 | + (type == TYPE_COLLATOR || type == TYPE_STD_STRING))); |
3661 | |
3662 | theValue.uint64v = 0; |
3663 | |
3664 | |
3665 | === modified file 'test/fots_driver/fots-driver.xq' |
3666 | --- test/fots_driver/fots-driver.xq 2013-02-26 06:30:28 +0000 |
3667 | +++ test/fots_driver/fots-driver.xq 2013-02-28 21:53:23 +0000 |
3668 | @@ -582,7 +582,6 @@ |
3669 | }; |
3670 | |
3671 | |
3672 | - |
3673 | (:~ |
3674 | : A helper functrion to process a specified subset of all test-cases and |
3675 | : report the outcome for each such test case. |
3676 | |
3677 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9067.iter' |
3678 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9067.iter 2012-12-18 15:09:02 +0000 |
3679 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9067.iter 2013-02-28 21:53:23 +0000 |
3680 | @@ -8,60 +8,56 @@ |
3681 | </OpToIterator> |
3682 | </HoistIterator> |
3683 | </LetVariable> |
3684 | - <ReturnClause> |
3685 | - <SequentialIterator> |
3686 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
3687 | - <flwor::FLWORIterator> |
3688 | - <ForVariable name="$$opt_temp_2"> |
3689 | - <UnhoistIterator> |
3690 | - <LetVarIterator varname="$$opt_temp_0"/> |
3691 | - </UnhoistIterator> |
3692 | - </ForVariable> |
3693 | - <ReturnClause> |
3694 | - <ValueIndexEntryBuilderIterator> |
3695 | - <ForVarIterator varname="$$opt_temp_2"/> |
3696 | - <ForVarIterator varname="$$opt_temp_2"/> |
3697 | - </ValueIndexEntryBuilderIterator> |
3698 | - </ReturnClause> |
3699 | - </flwor::FLWORIterator> |
3700 | - </CreateInternalIndexIterator> |
3701 | + <LetVariable name="$$opt_temp_4" materialize="true"> |
3702 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
3703 | <flwor::FLWORIterator> |
3704 | - <ForVariable name="b"> |
3705 | - <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
3706 | - <FnDocIterator> |
3707 | - <SingletonIterator value="xs:string(books.xml)"/> |
3708 | - </FnDocIterator> |
3709 | - </DescendantAxisIterator> |
3710 | - </ForVariable> |
3711 | - <ForVariable name="$$opt_temp_1"> |
3712 | - <HoistIterator> |
3713 | - <FnCountIterator> |
3714 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
3715 | - <ForVarIterator varname="b"/> |
3716 | - </ChildAxisIterator> |
3717 | - </FnCountIterator> |
3718 | - </HoistIterator> |
3719 | - </ForVariable> |
3720 | - <ForVariable name="er"> |
3721 | - <ProbeIndexPointValueIterator> |
3722 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
3723 | - <UnhoistIterator> |
3724 | - <ForVarIterator varname="$$opt_temp_1"/> |
3725 | - </UnhoistIterator> |
3726 | - </ProbeIndexPointValueIterator> |
3727 | + <ForVariable name="$$opt_temp_2"> |
3728 | + <UnhoistIterator> |
3729 | + <LetVarIterator varname="$$opt_temp_0"/> |
3730 | + </UnhoistIterator> |
3731 | </ForVariable> |
3732 | <ReturnClause> |
3733 | - <ElementIterator> |
3734 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
3735 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
3736 | - <EnclosedIterator attr_cont="true"> |
3737 | - <ForVarIterator varname="er"/> |
3738 | - </EnclosedIterator> |
3739 | - </AttributeIterator> |
3740 | - </ElementIterator> |
3741 | + <ValueIndexEntryBuilderIterator> |
3742 | + <ForVarIterator varname="$$opt_temp_2"/> |
3743 | + <ForVarIterator varname="$$opt_temp_2"/> |
3744 | + </ValueIndexEntryBuilderIterator> |
3745 | </ReturnClause> |
3746 | </flwor::FLWORIterator> |
3747 | - </SequentialIterator> |
3748 | + </CreateInternalIndexIterator> |
3749 | + </LetVariable> |
3750 | + <ForVariable name="b"> |
3751 | + <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
3752 | + <FnDocIterator> |
3753 | + <SingletonIterator value="xs:string(books.xml)"/> |
3754 | + </FnDocIterator> |
3755 | + </DescendantAxisIterator> |
3756 | + </ForVariable> |
3757 | + <ForVariable name="$$opt_temp_1"> |
3758 | + <HoistIterator> |
3759 | + <FnCountIterator> |
3760 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
3761 | + <ForVarIterator varname="b"/> |
3762 | + </ChildAxisIterator> |
3763 | + </FnCountIterator> |
3764 | + </HoistIterator> |
3765 | + </ForVariable> |
3766 | + <ForVariable name="er"> |
3767 | + <ProbeIndexPointValueIterator> |
3768 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
3769 | + <UnhoistIterator> |
3770 | + <ForVarIterator varname="$$opt_temp_1"/> |
3771 | + </UnhoistIterator> |
3772 | + </ProbeIndexPointValueIterator> |
3773 | + </ForVariable> |
3774 | + <ReturnClause> |
3775 | + <ElementIterator> |
3776 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
3777 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
3778 | + <EnclosedIterator attr_cont="true"> |
3779 | + <ForVarIterator varname="er"/> |
3780 | + </EnclosedIterator> |
3781 | + </AttributeIterator> |
3782 | + </ElementIterator> |
3783 | </ReturnClause> |
3784 | </flwor::FLWORIterator> |
3785 | |
3786 | |
3787 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9068.iter' |
3788 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9068.iter 2012-12-18 15:09:02 +0000 |
3789 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9068.iter 2013-02-28 21:53:23 +0000 |
3790 | @@ -8,72 +8,68 @@ |
3791 | </OpToIterator> |
3792 | </HoistIterator> |
3793 | </LetVariable> |
3794 | - <ReturnClause> |
3795 | - <SequentialIterator> |
3796 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
3797 | - <flwor::FLWORIterator> |
3798 | - <ForVariable name="$$opt_temp_3"> |
3799 | - <UnhoistIterator> |
3800 | - <LetVarIterator varname="$$opt_temp_0"/> |
3801 | - </UnhoistIterator> |
3802 | - </ForVariable> |
3803 | - <ReturnClause> |
3804 | - <ValueIndexEntryBuilderIterator> |
3805 | - <ForVarIterator varname="$$opt_temp_3"/> |
3806 | - <ForVarIterator varname="$$opt_temp_3"/> |
3807 | - </ValueIndexEntryBuilderIterator> |
3808 | - </ReturnClause> |
3809 | - </flwor::FLWORIterator> |
3810 | - </CreateInternalIndexIterator> |
3811 | + <LetVariable name="$$opt_temp_5" materialize="true"> |
3812 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
3813 | <flwor::FLWORIterator> |
3814 | - <ForVariable name="b"> |
3815 | - <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
3816 | - <FnDocIterator> |
3817 | - <SingletonIterator value="xs:string(books.xml)"/> |
3818 | - </FnDocIterator> |
3819 | - </DescendantAxisIterator> |
3820 | - </ForVariable> |
3821 | - <LetVariable name="$$opt_temp_2" materialize="true"> |
3822 | - <HoistIterator> |
3823 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,title)" typename="*" nill allowed="0"> |
3824 | - <ForVarIterator varname="b"/> |
3825 | - </ChildAxisIterator> |
3826 | - </HoistIterator> |
3827 | - </LetVariable> |
3828 | - <ForVariable name="$$opt_temp_1"> |
3829 | - <HoistIterator> |
3830 | - <FnCountIterator> |
3831 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
3832 | - <ForVarIterator varname="b"/> |
3833 | - </ChildAxisIterator> |
3834 | - </FnCountIterator> |
3835 | - </HoistIterator> |
3836 | - </ForVariable> |
3837 | - <ForVariable name="er"> |
3838 | - <ProbeIndexPointValueIterator> |
3839 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
3840 | - <UnhoistIterator> |
3841 | - <ForVarIterator varname="$$opt_temp_1"/> |
3842 | - </UnhoistIterator> |
3843 | - </ProbeIndexPointValueIterator> |
3844 | + <ForVariable name="$$opt_temp_3"> |
3845 | + <UnhoistIterator> |
3846 | + <LetVarIterator varname="$$opt_temp_0"/> |
3847 | + </UnhoistIterator> |
3848 | </ForVariable> |
3849 | <ReturnClause> |
3850 | - <ElementIterator> |
3851 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
3852 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
3853 | - <EnclosedIterator attr_cont="true"> |
3854 | - <ForVarIterator varname="er"/> |
3855 | - </EnclosedIterator> |
3856 | - </AttributeIterator> |
3857 | - <EnclosedIterator attr_cont="false"> |
3858 | - <UnhoistIterator> |
3859 | - <LetVarIterator varname="$$opt_temp_2"/> |
3860 | - </UnhoistIterator> |
3861 | - </EnclosedIterator> |
3862 | - </ElementIterator> |
3863 | + <ValueIndexEntryBuilderIterator> |
3864 | + <ForVarIterator varname="$$opt_temp_3"/> |
3865 | + <ForVarIterator varname="$$opt_temp_3"/> |
3866 | + </ValueIndexEntryBuilderIterator> |
3867 | </ReturnClause> |
3868 | </flwor::FLWORIterator> |
3869 | - </SequentialIterator> |
3870 | + </CreateInternalIndexIterator> |
3871 | + </LetVariable> |
3872 | + <ForVariable name="b"> |
3873 | + <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
3874 | + <FnDocIterator> |
3875 | + <SingletonIterator value="xs:string(books.xml)"/> |
3876 | + </FnDocIterator> |
3877 | + </DescendantAxisIterator> |
3878 | + </ForVariable> |
3879 | + <LetVariable name="$$opt_temp_2" materialize="true"> |
3880 | + <HoistIterator> |
3881 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,title)" typename="*" nill allowed="0"> |
3882 | + <ForVarIterator varname="b"/> |
3883 | + </ChildAxisIterator> |
3884 | + </HoistIterator> |
3885 | + </LetVariable> |
3886 | + <ForVariable name="$$opt_temp_1"> |
3887 | + <HoistIterator> |
3888 | + <FnCountIterator> |
3889 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
3890 | + <ForVarIterator varname="b"/> |
3891 | + </ChildAxisIterator> |
3892 | + </FnCountIterator> |
3893 | + </HoistIterator> |
3894 | + </ForVariable> |
3895 | + <ForVariable name="er"> |
3896 | + <ProbeIndexPointValueIterator> |
3897 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
3898 | + <UnhoistIterator> |
3899 | + <ForVarIterator varname="$$opt_temp_1"/> |
3900 | + </UnhoistIterator> |
3901 | + </ProbeIndexPointValueIterator> |
3902 | + </ForVariable> |
3903 | + <ReturnClause> |
3904 | + <ElementIterator> |
3905 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
3906 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
3907 | + <EnclosedIterator attr_cont="true"> |
3908 | + <ForVarIterator varname="er"/> |
3909 | + </EnclosedIterator> |
3910 | + </AttributeIterator> |
3911 | + <EnclosedIterator attr_cont="false"> |
3912 | + <UnhoistIterator> |
3913 | + <LetVarIterator varname="$$opt_temp_2"/> |
3914 | + </UnhoistIterator> |
3915 | + </EnclosedIterator> |
3916 | + </ElementIterator> |
3917 | </ReturnClause> |
3918 | </flwor::FLWORIterator> |
3919 | |
3920 | |
3921 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9197.iter' |
3922 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9197.iter 2012-12-18 15:09:02 +0000 |
3923 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9197.iter 2013-02-28 21:53:23 +0000 |
3924 | @@ -11,60 +11,56 @@ |
3925 | </OpToIterator> |
3926 | </HoistIterator> |
3927 | </LetVariable> |
3928 | - <ReturnClause> |
3929 | - <SequentialIterator> |
3930 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
3931 | - <flwor::FLWORIterator> |
3932 | - <ForVariable name="$$opt_temp_2"> |
3933 | - <UnhoistIterator> |
3934 | - <LetVarIterator varname="$$opt_temp_0"/> |
3935 | - </UnhoistIterator> |
3936 | - </ForVariable> |
3937 | - <ReturnClause> |
3938 | - <ValueIndexEntryBuilderIterator> |
3939 | - <ForVarIterator varname="$$opt_temp_2"/> |
3940 | - <ForVarIterator varname="$$opt_temp_2"/> |
3941 | - </ValueIndexEntryBuilderIterator> |
3942 | - </ReturnClause> |
3943 | - </flwor::FLWORIterator> |
3944 | - </CreateInternalIndexIterator> |
3945 | + <LetVariable name="$$opt_temp_4" materialize="true"> |
3946 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
3947 | <flwor::FLWORIterator> |
3948 | - <ForVariable name="book"> |
3949 | - <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
3950 | - <FnDocIterator> |
3951 | - <SingletonIterator value="xs:string(books.xml)"/> |
3952 | - </FnDocIterator> |
3953 | - </DescendantAxisIterator> |
3954 | - </ForVariable> |
3955 | - <ForVariable name="$$opt_temp_1"> |
3956 | - <HoistIterator> |
3957 | - <FnCountIterator> |
3958 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
3959 | - <ForVarIterator varname="book"/> |
3960 | - </ChildAxisIterator> |
3961 | - </FnCountIterator> |
3962 | - </HoistIterator> |
3963 | - </ForVariable> |
3964 | - <ForVariable name="anzahl"> |
3965 | - <ProbeIndexPointValueIterator> |
3966 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
3967 | - <UnhoistIterator> |
3968 | - <ForVarIterator varname="$$opt_temp_1"/> |
3969 | - </UnhoistIterator> |
3970 | - </ProbeIndexPointValueIterator> |
3971 | + <ForVariable name="$$opt_temp_2"> |
3972 | + <UnhoistIterator> |
3973 | + <LetVarIterator varname="$$opt_temp_0"/> |
3974 | + </UnhoistIterator> |
3975 | </ForVariable> |
3976 | <ReturnClause> |
3977 | - <ElementIterator> |
3978 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
3979 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
3980 | - <EnclosedIterator attr_cont="true"> |
3981 | - <ForVarIterator varname="anzahl"/> |
3982 | - </EnclosedIterator> |
3983 | - </AttributeIterator> |
3984 | - </ElementIterator> |
3985 | + <ValueIndexEntryBuilderIterator> |
3986 | + <ForVarIterator varname="$$opt_temp_2"/> |
3987 | + <ForVarIterator varname="$$opt_temp_2"/> |
3988 | + </ValueIndexEntryBuilderIterator> |
3989 | </ReturnClause> |
3990 | </flwor::FLWORIterator> |
3991 | - </SequentialIterator> |
3992 | + </CreateInternalIndexIterator> |
3993 | + </LetVariable> |
3994 | + <ForVariable name="book"> |
3995 | + <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
3996 | + <FnDocIterator> |
3997 | + <SingletonIterator value="xs:string(books.xml)"/> |
3998 | + </FnDocIterator> |
3999 | + </DescendantAxisIterator> |
4000 | + </ForVariable> |
4001 | + <ForVariable name="$$opt_temp_1"> |
4002 | + <HoistIterator> |
4003 | + <FnCountIterator> |
4004 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4005 | + <ForVarIterator varname="book"/> |
4006 | + </ChildAxisIterator> |
4007 | + </FnCountIterator> |
4008 | + </HoistIterator> |
4009 | + </ForVariable> |
4010 | + <ForVariable name="anzahl"> |
4011 | + <ProbeIndexPointValueIterator> |
4012 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4013 | + <UnhoistIterator> |
4014 | + <ForVarIterator varname="$$opt_temp_1"/> |
4015 | + </UnhoistIterator> |
4016 | + </ProbeIndexPointValueIterator> |
4017 | + </ForVariable> |
4018 | + <ReturnClause> |
4019 | + <ElementIterator> |
4020 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
4021 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
4022 | + <EnclosedIterator attr_cont="true"> |
4023 | + <ForVarIterator varname="anzahl"/> |
4024 | + </EnclosedIterator> |
4025 | + </AttributeIterator> |
4026 | + </ElementIterator> |
4027 | </ReturnClause> |
4028 | </flwor::FLWORIterator> |
4029 | </EnclosedIterator> |
4030 | |
4031 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9198.iter' |
4032 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9198.iter 2012-12-18 15:09:02 +0000 |
4033 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9198.iter 2013-02-28 21:53:23 +0000 |
4034 | @@ -11,63 +11,59 @@ |
4035 | </OpToIterator> |
4036 | </HoistIterator> |
4037 | </LetVariable> |
4038 | - <ReturnClause> |
4039 | - <SequentialIterator> |
4040 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4041 | - <flwor::FLWORIterator> |
4042 | - <ForVariable name="$$opt_temp_2"> |
4043 | - <UnhoistIterator> |
4044 | - <LetVarIterator varname="$$opt_temp_0"/> |
4045 | - </UnhoistIterator> |
4046 | - </ForVariable> |
4047 | - <ReturnClause> |
4048 | - <ValueIndexEntryBuilderIterator> |
4049 | - <ForVarIterator varname="$$opt_temp_2"/> |
4050 | - <ForVarIterator varname="$$opt_temp_2"/> |
4051 | - </ValueIndexEntryBuilderIterator> |
4052 | - </ReturnClause> |
4053 | - </flwor::FLWORIterator> |
4054 | - </CreateInternalIndexIterator> |
4055 | + <LetVariable name="$$opt_temp_4" materialize="true"> |
4056 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4057 | <flwor::FLWORIterator> |
4058 | - <ForVariable name="book"> |
4059 | - <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
4060 | - <FnDocIterator> |
4061 | - <SingletonIterator value="xs:string(books.xml)"/> |
4062 | - </FnDocIterator> |
4063 | - </DescendantAxisIterator> |
4064 | - </ForVariable> |
4065 | - <ForVariable name="$$opt_temp_1"> |
4066 | - <HoistIterator> |
4067 | - <FnCountIterator> |
4068 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4069 | - <ForVarIterator varname="book"/> |
4070 | - </ChildAxisIterator> |
4071 | - </FnCountIterator> |
4072 | - </HoistIterator> |
4073 | - </ForVariable> |
4074 | - <ForVariable name="anzahl"> |
4075 | - <ProbeIndexPointValueIterator> |
4076 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4077 | - <UnhoistIterator> |
4078 | - <ForVarIterator varname="$$opt_temp_1"/> |
4079 | - </UnhoistIterator> |
4080 | - </ProbeIndexPointValueIterator> |
4081 | + <ForVariable name="$$opt_temp_2"> |
4082 | + <UnhoistIterator> |
4083 | + <LetVarIterator varname="$$opt_temp_0"/> |
4084 | + </UnhoistIterator> |
4085 | </ForVariable> |
4086 | <ReturnClause> |
4087 | - <ElementIterator> |
4088 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
4089 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
4090 | - <EnclosedIterator attr_cont="true"> |
4091 | - <ForVarIterator varname="anzahl"/> |
4092 | - </EnclosedIterator> |
4093 | - </AttributeIterator> |
4094 | - <EnclosedIterator attr_cont="false"> |
4095 | - <ForVarIterator varname="book"/> |
4096 | - </EnclosedIterator> |
4097 | - </ElementIterator> |
4098 | + <ValueIndexEntryBuilderIterator> |
4099 | + <ForVarIterator varname="$$opt_temp_2"/> |
4100 | + <ForVarIterator varname="$$opt_temp_2"/> |
4101 | + </ValueIndexEntryBuilderIterator> |
4102 | </ReturnClause> |
4103 | </flwor::FLWORIterator> |
4104 | - </SequentialIterator> |
4105 | + </CreateInternalIndexIterator> |
4106 | + </LetVariable> |
4107 | + <ForVariable name="book"> |
4108 | + <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
4109 | + <FnDocIterator> |
4110 | + <SingletonIterator value="xs:string(books.xml)"/> |
4111 | + </FnDocIterator> |
4112 | + </DescendantAxisIterator> |
4113 | + </ForVariable> |
4114 | + <ForVariable name="$$opt_temp_1"> |
4115 | + <HoistIterator> |
4116 | + <FnCountIterator> |
4117 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4118 | + <ForVarIterator varname="book"/> |
4119 | + </ChildAxisIterator> |
4120 | + </FnCountIterator> |
4121 | + </HoistIterator> |
4122 | + </ForVariable> |
4123 | + <ForVariable name="anzahl"> |
4124 | + <ProbeIndexPointValueIterator> |
4125 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4126 | + <UnhoistIterator> |
4127 | + <ForVarIterator varname="$$opt_temp_1"/> |
4128 | + </UnhoistIterator> |
4129 | + </ProbeIndexPointValueIterator> |
4130 | + </ForVariable> |
4131 | + <ReturnClause> |
4132 | + <ElementIterator> |
4133 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
4134 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
4135 | + <EnclosedIterator attr_cont="true"> |
4136 | + <ForVarIterator varname="anzahl"/> |
4137 | + </EnclosedIterator> |
4138 | + </AttributeIterator> |
4139 | + <EnclosedIterator attr_cont="false"> |
4140 | + <ForVarIterator varname="book"/> |
4141 | + </EnclosedIterator> |
4142 | + </ElementIterator> |
4143 | </ReturnClause> |
4144 | </flwor::FLWORIterator> |
4145 | </EnclosedIterator> |
4146 | |
4147 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9199.iter' |
4148 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9199.iter 2012-12-18 15:09:02 +0000 |
4149 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9199.iter 2013-02-28 21:53:23 +0000 |
4150 | @@ -11,63 +11,59 @@ |
4151 | </OpToIterator> |
4152 | </HoistIterator> |
4153 | </LetVariable> |
4154 | - <ReturnClause> |
4155 | - <SequentialIterator> |
4156 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4157 | - <flwor::FLWORIterator> |
4158 | - <ForVariable name="$$opt_temp_2"> |
4159 | - <UnhoistIterator> |
4160 | - <LetVarIterator varname="$$opt_temp_0"/> |
4161 | - </UnhoistIterator> |
4162 | - </ForVariable> |
4163 | - <ReturnClause> |
4164 | - <ValueIndexEntryBuilderIterator> |
4165 | - <ForVarIterator varname="$$opt_temp_2"/> |
4166 | - <ForVarIterator varname="$$opt_temp_2"/> |
4167 | - </ValueIndexEntryBuilderIterator> |
4168 | - </ReturnClause> |
4169 | - </flwor::FLWORIterator> |
4170 | - </CreateInternalIndexIterator> |
4171 | + <LetVariable name="$$opt_temp_4" materialize="true"> |
4172 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4173 | <flwor::FLWORIterator> |
4174 | - <ForVariable name="book"> |
4175 | - <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
4176 | - <FnDocIterator> |
4177 | - <SingletonIterator value="xs:string(books.xml)"/> |
4178 | - </FnDocIterator> |
4179 | - </DescendantAxisIterator> |
4180 | - </ForVariable> |
4181 | - <ForVariable name="$$opt_temp_1"> |
4182 | - <HoistIterator> |
4183 | - <FnCountIterator> |
4184 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4185 | - <ForVarIterator varname="book"/> |
4186 | - </ChildAxisIterator> |
4187 | - </FnCountIterator> |
4188 | - </HoistIterator> |
4189 | - </ForVariable> |
4190 | - <ForVariable name="anzahl"> |
4191 | - <ProbeIndexPointValueIterator> |
4192 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4193 | - <UnhoistIterator> |
4194 | - <ForVarIterator varname="$$opt_temp_1"/> |
4195 | - </UnhoistIterator> |
4196 | - </ProbeIndexPointValueIterator> |
4197 | + <ForVariable name="$$opt_temp_2"> |
4198 | + <UnhoistIterator> |
4199 | + <LetVarIterator varname="$$opt_temp_0"/> |
4200 | + </UnhoistIterator> |
4201 | </ForVariable> |
4202 | <ReturnClause> |
4203 | - <ElementIterator> |
4204 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
4205 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
4206 | - <EnclosedIterator attr_cont="true"> |
4207 | - <ForVarIterator varname="anzahl"/> |
4208 | - </EnclosedIterator> |
4209 | - </AttributeIterator> |
4210 | - <EnclosedIterator attr_cont="false"> |
4211 | - <ForVarIterator varname="book"/> |
4212 | - </EnclosedIterator> |
4213 | - </ElementIterator> |
4214 | + <ValueIndexEntryBuilderIterator> |
4215 | + <ForVarIterator varname="$$opt_temp_2"/> |
4216 | + <ForVarIterator varname="$$opt_temp_2"/> |
4217 | + </ValueIndexEntryBuilderIterator> |
4218 | </ReturnClause> |
4219 | </flwor::FLWORIterator> |
4220 | - </SequentialIterator> |
4221 | + </CreateInternalIndexIterator> |
4222 | + </LetVariable> |
4223 | + <ForVariable name="book"> |
4224 | + <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
4225 | + <FnDocIterator> |
4226 | + <SingletonIterator value="xs:string(books.xml)"/> |
4227 | + </FnDocIterator> |
4228 | + </DescendantAxisIterator> |
4229 | + </ForVariable> |
4230 | + <ForVariable name="$$opt_temp_1"> |
4231 | + <HoistIterator> |
4232 | + <FnCountIterator> |
4233 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4234 | + <ForVarIterator varname="book"/> |
4235 | + </ChildAxisIterator> |
4236 | + </FnCountIterator> |
4237 | + </HoistIterator> |
4238 | + </ForVariable> |
4239 | + <ForVariable name="anzahl"> |
4240 | + <ProbeIndexPointValueIterator> |
4241 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4242 | + <UnhoistIterator> |
4243 | + <ForVarIterator varname="$$opt_temp_1"/> |
4244 | + </UnhoistIterator> |
4245 | + </ProbeIndexPointValueIterator> |
4246 | + </ForVariable> |
4247 | + <ReturnClause> |
4248 | + <ElementIterator> |
4249 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
4250 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
4251 | + <EnclosedIterator attr_cont="true"> |
4252 | + <ForVarIterator varname="anzahl"/> |
4253 | + </EnclosedIterator> |
4254 | + </AttributeIterator> |
4255 | + <EnclosedIterator attr_cont="false"> |
4256 | + <ForVarIterator varname="book"/> |
4257 | + </EnclosedIterator> |
4258 | + </ElementIterator> |
4259 | </ReturnClause> |
4260 | </flwor::FLWORIterator> |
4261 | </EnclosedIterator> |
4262 | |
4263 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9204.iter' |
4264 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9204.iter 2012-12-18 15:09:02 +0000 |
4265 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9204.iter 2013-02-28 21:53:23 +0000 |
4266 | @@ -8,72 +8,68 @@ |
4267 | </OpToIterator> |
4268 | </HoistIterator> |
4269 | </LetVariable> |
4270 | + <LetVariable name="$$opt_temp_4" materialize="true"> |
4271 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4272 | + <flwor::FLWORIterator> |
4273 | + <ForVariable name="$$opt_temp_2"> |
4274 | + <UnhoistIterator> |
4275 | + <LetVarIterator varname="$$opt_temp_0"/> |
4276 | + </UnhoistIterator> |
4277 | + </ForVariable> |
4278 | + <ReturnClause> |
4279 | + <ValueIndexEntryBuilderIterator> |
4280 | + <ForVarIterator varname="$$opt_temp_2"/> |
4281 | + <ForVarIterator varname="$$opt_temp_2"/> |
4282 | + </ValueIndexEntryBuilderIterator> |
4283 | + </ReturnClause> |
4284 | + </flwor::FLWORIterator> |
4285 | + </CreateInternalIndexIterator> |
4286 | + </LetVariable> |
4287 | + <ForVariable name="book"> |
4288 | + <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
4289 | + <FnDocIterator> |
4290 | + <SingletonIterator value="xs:string(books.xml)"/> |
4291 | + </FnDocIterator> |
4292 | + </DescendantAxisIterator> |
4293 | + </ForVariable> |
4294 | + <ForVariable name="$$opt_temp_1"> |
4295 | + <HoistIterator> |
4296 | + <FnCountIterator> |
4297 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4298 | + <ForVarIterator varname="book"/> |
4299 | + </ChildAxisIterator> |
4300 | + </FnCountIterator> |
4301 | + </HoistIterator> |
4302 | + </ForVariable> |
4303 | <ReturnClause> |
4304 | - <SequentialIterator> |
4305 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4306 | + <ElementIterator> |
4307 | + <SingletonIterator value="xs:QName(,,karteikasten)"/> |
4308 | + <EnclosedIterator attr_cont="false"> |
4309 | <flwor::FLWORIterator> |
4310 | - <ForVariable name="$$opt_temp_2"> |
4311 | - <UnhoistIterator> |
4312 | - <LetVarIterator varname="$$opt_temp_0"/> |
4313 | - </UnhoistIterator> |
4314 | + <ForVariable name="anzahl"> |
4315 | + <ProbeIndexPointValueIterator> |
4316 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4317 | + <UnhoistIterator> |
4318 | + <ForVarIterator varname="$$opt_temp_1"/> |
4319 | + </UnhoistIterator> |
4320 | + </ProbeIndexPointValueIterator> |
4321 | </ForVariable> |
4322 | <ReturnClause> |
4323 | - <ValueIndexEntryBuilderIterator> |
4324 | - <ForVarIterator varname="$$opt_temp_2"/> |
4325 | - <ForVarIterator varname="$$opt_temp_2"/> |
4326 | - </ValueIndexEntryBuilderIterator> |
4327 | + <ElementIterator> |
4328 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
4329 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
4330 | + <EnclosedIterator attr_cont="true"> |
4331 | + <ForVarIterator varname="anzahl"/> |
4332 | + </EnclosedIterator> |
4333 | + </AttributeIterator> |
4334 | + <EnclosedIterator attr_cont="false"> |
4335 | + <ForVarIterator varname="book"/> |
4336 | + </EnclosedIterator> |
4337 | + </ElementIterator> |
4338 | </ReturnClause> |
4339 | </flwor::FLWORIterator> |
4340 | - </CreateInternalIndexIterator> |
4341 | - <flwor::FLWORIterator> |
4342 | - <ForVariable name="book"> |
4343 | - <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
4344 | - <FnDocIterator> |
4345 | - <SingletonIterator value="xs:string(books.xml)"/> |
4346 | - </FnDocIterator> |
4347 | - </DescendantAxisIterator> |
4348 | - </ForVariable> |
4349 | - <ForVariable name="$$opt_temp_1"> |
4350 | - <HoistIterator> |
4351 | - <FnCountIterator> |
4352 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4353 | - <ForVarIterator varname="book"/> |
4354 | - </ChildAxisIterator> |
4355 | - </FnCountIterator> |
4356 | - </HoistIterator> |
4357 | - </ForVariable> |
4358 | - <ReturnClause> |
4359 | - <ElementIterator> |
4360 | - <SingletonIterator value="xs:QName(,,karteikasten)"/> |
4361 | - <EnclosedIterator attr_cont="false"> |
4362 | - <flwor::FLWORIterator> |
4363 | - <ForVariable name="anzahl"> |
4364 | - <ProbeIndexPointValueIterator> |
4365 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4366 | - <UnhoistIterator> |
4367 | - <ForVarIterator varname="$$opt_temp_1"/> |
4368 | - </UnhoistIterator> |
4369 | - </ProbeIndexPointValueIterator> |
4370 | - </ForVariable> |
4371 | - <ReturnClause> |
4372 | - <ElementIterator> |
4373 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
4374 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
4375 | - <EnclosedIterator attr_cont="true"> |
4376 | - <ForVarIterator varname="anzahl"/> |
4377 | - </EnclosedIterator> |
4378 | - </AttributeIterator> |
4379 | - <EnclosedIterator attr_cont="false"> |
4380 | - <ForVarIterator varname="book"/> |
4381 | - </EnclosedIterator> |
4382 | - </ElementIterator> |
4383 | - </ReturnClause> |
4384 | - </flwor::FLWORIterator> |
4385 | - </EnclosedIterator> |
4386 | - </ElementIterator> |
4387 | - </ReturnClause> |
4388 | - </flwor::FLWORIterator> |
4389 | - </SequentialIterator> |
4390 | + </EnclosedIterator> |
4391 | + </ElementIterator> |
4392 | </ReturnClause> |
4393 | </flwor::FLWORIterator> |
4394 | |
4395 | |
4396 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9206.iter' |
4397 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9206.iter 2012-09-19 21:16:15 +0000 |
4398 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9206.iter 2013-02-28 21:53:23 +0000 |
4399 | @@ -12,55 +12,51 @@ |
4400 | </DescendantAxisIterator> |
4401 | </HoistIterator> |
4402 | </LetVariable> |
4403 | - <ReturnClause> |
4404 | - <SequentialIterator> |
4405 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4406 | - <flwor::FLWORIterator> |
4407 | - <ForVariable name="$$opt_temp_1"> |
4408 | - <UnhoistIterator> |
4409 | - <LetVarIterator varname="$$opt_temp_0"/> |
4410 | - </UnhoistIterator> |
4411 | - </ForVariable> |
4412 | - <ReturnClause> |
4413 | - <ValueIndexEntryBuilderIterator> |
4414 | - <ForVarIterator varname="$$opt_temp_1"/> |
4415 | - <FnCountIterator> |
4416 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4417 | - <ForVarIterator varname="$$opt_temp_1"/> |
4418 | - </ChildAxisIterator> |
4419 | - </FnCountIterator> |
4420 | - </ValueIndexEntryBuilderIterator> |
4421 | - </ReturnClause> |
4422 | - </flwor::FLWORIterator> |
4423 | - </CreateInternalIndexIterator> |
4424 | + <LetVariable name="$$opt_temp_3" materialize="true"> |
4425 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4426 | <flwor::FLWORIterator> |
4427 | - <ForVariable name="anzahl"> |
4428 | - <OpToIterator> |
4429 | - <SingletonIterator value="xs:integer(1)"/> |
4430 | - <SingletonIterator value="xs:integer(2)"/> |
4431 | - </OpToIterator> |
4432 | - </ForVariable> |
4433 | - <ForVariable name="book"> |
4434 | - <ProbeIndexPointValueIterator> |
4435 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4436 | - <ForVarIterator varname="anzahl"/> |
4437 | - </ProbeIndexPointValueIterator> |
4438 | + <ForVariable name="$$opt_temp_1"> |
4439 | + <UnhoistIterator> |
4440 | + <LetVarIterator varname="$$opt_temp_0"/> |
4441 | + </UnhoistIterator> |
4442 | </ForVariable> |
4443 | <ReturnClause> |
4444 | - <ElementIterator> |
4445 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
4446 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
4447 | - <EnclosedIterator attr_cont="true"> |
4448 | - <ForVarIterator varname="anzahl"/> |
4449 | - </EnclosedIterator> |
4450 | - </AttributeIterator> |
4451 | - <EnclosedIterator attr_cont="false"> |
4452 | - <ForVarIterator varname="book"/> |
4453 | - </EnclosedIterator> |
4454 | - </ElementIterator> |
4455 | + <ValueIndexEntryBuilderIterator> |
4456 | + <ForVarIterator varname="$$opt_temp_1"/> |
4457 | + <FnCountIterator> |
4458 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4459 | + <ForVarIterator varname="$$opt_temp_1"/> |
4460 | + </ChildAxisIterator> |
4461 | + </FnCountIterator> |
4462 | + </ValueIndexEntryBuilderIterator> |
4463 | </ReturnClause> |
4464 | </flwor::FLWORIterator> |
4465 | - </SequentialIterator> |
4466 | + </CreateInternalIndexIterator> |
4467 | + </LetVariable> |
4468 | + <ForVariable name="anzahl"> |
4469 | + <OpToIterator> |
4470 | + <SingletonIterator value="xs:integer(1)"/> |
4471 | + <SingletonIterator value="xs:integer(2)"/> |
4472 | + </OpToIterator> |
4473 | + </ForVariable> |
4474 | + <ForVariable name="book"> |
4475 | + <ProbeIndexPointValueIterator> |
4476 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4477 | + <ForVarIterator varname="anzahl"/> |
4478 | + </ProbeIndexPointValueIterator> |
4479 | + </ForVariable> |
4480 | + <ReturnClause> |
4481 | + <ElementIterator> |
4482 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
4483 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
4484 | + <EnclosedIterator attr_cont="true"> |
4485 | + <ForVarIterator varname="anzahl"/> |
4486 | + </EnclosedIterator> |
4487 | + </AttributeIterator> |
4488 | + <EnclosedIterator attr_cont="false"> |
4489 | + <ForVarIterator varname="book"/> |
4490 | + </EnclosedIterator> |
4491 | + </ElementIterator> |
4492 | </ReturnClause> |
4493 | </flwor::FLWORIterator> |
4494 | </EnclosedIterator> |
4495 | |
4496 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9207.iter' |
4497 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9207.iter 2012-12-18 15:09:02 +0000 |
4498 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9207.iter 2013-02-28 21:53:23 +0000 |
4499 | @@ -11,63 +11,59 @@ |
4500 | </OpToIterator> |
4501 | </HoistIterator> |
4502 | </LetVariable> |
4503 | - <ReturnClause> |
4504 | - <SequentialIterator> |
4505 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4506 | - <flwor::FLWORIterator> |
4507 | - <ForVariable name="$$opt_temp_2"> |
4508 | - <UnhoistIterator> |
4509 | - <LetVarIterator varname="$$opt_temp_0"/> |
4510 | - </UnhoistIterator> |
4511 | - </ForVariable> |
4512 | - <ReturnClause> |
4513 | - <ValueIndexEntryBuilderIterator> |
4514 | - <ForVarIterator varname="$$opt_temp_2"/> |
4515 | - <ForVarIterator varname="$$opt_temp_2"/> |
4516 | - </ValueIndexEntryBuilderIterator> |
4517 | - </ReturnClause> |
4518 | - </flwor::FLWORIterator> |
4519 | - </CreateInternalIndexIterator> |
4520 | + <LetVariable name="$$opt_temp_4" materialize="true"> |
4521 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4522 | <flwor::FLWORIterator> |
4523 | - <ForVariable name="book"> |
4524 | - <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
4525 | - <FnDocIterator> |
4526 | - <SingletonIterator value="xs:string(books.xml)"/> |
4527 | - </FnDocIterator> |
4528 | - </DescendantAxisIterator> |
4529 | - </ForVariable> |
4530 | - <ForVariable name="$$opt_temp_1"> |
4531 | - <HoistIterator> |
4532 | - <FnCountIterator> |
4533 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4534 | - <ForVarIterator varname="book"/> |
4535 | - </ChildAxisIterator> |
4536 | - </FnCountIterator> |
4537 | - </HoistIterator> |
4538 | - </ForVariable> |
4539 | - <ForVariable name="anzahl"> |
4540 | - <ProbeIndexPointValueIterator> |
4541 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4542 | - <UnhoistIterator> |
4543 | - <ForVarIterator varname="$$opt_temp_1"/> |
4544 | - </UnhoistIterator> |
4545 | - </ProbeIndexPointValueIterator> |
4546 | + <ForVariable name="$$opt_temp_2"> |
4547 | + <UnhoistIterator> |
4548 | + <LetVarIterator varname="$$opt_temp_0"/> |
4549 | + </UnhoistIterator> |
4550 | </ForVariable> |
4551 | <ReturnClause> |
4552 | - <ElementIterator> |
4553 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
4554 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
4555 | - <EnclosedIterator attr_cont="true"> |
4556 | - <ForVarIterator varname="anzahl"/> |
4557 | - </EnclosedIterator> |
4558 | - </AttributeIterator> |
4559 | - <EnclosedIterator attr_cont="false"> |
4560 | - <ForVarIterator varname="book"/> |
4561 | - </EnclosedIterator> |
4562 | - </ElementIterator> |
4563 | + <ValueIndexEntryBuilderIterator> |
4564 | + <ForVarIterator varname="$$opt_temp_2"/> |
4565 | + <ForVarIterator varname="$$opt_temp_2"/> |
4566 | + </ValueIndexEntryBuilderIterator> |
4567 | </ReturnClause> |
4568 | </flwor::FLWORIterator> |
4569 | - </SequentialIterator> |
4570 | + </CreateInternalIndexIterator> |
4571 | + </LetVariable> |
4572 | + <ForVariable name="book"> |
4573 | + <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
4574 | + <FnDocIterator> |
4575 | + <SingletonIterator value="xs:string(books.xml)"/> |
4576 | + </FnDocIterator> |
4577 | + </DescendantAxisIterator> |
4578 | + </ForVariable> |
4579 | + <ForVariable name="$$opt_temp_1"> |
4580 | + <HoistIterator> |
4581 | + <FnCountIterator> |
4582 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4583 | + <ForVarIterator varname="book"/> |
4584 | + </ChildAxisIterator> |
4585 | + </FnCountIterator> |
4586 | + </HoistIterator> |
4587 | + </ForVariable> |
4588 | + <ForVariable name="anzahl"> |
4589 | + <ProbeIndexPointValueIterator> |
4590 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4591 | + <UnhoistIterator> |
4592 | + <ForVarIterator varname="$$opt_temp_1"/> |
4593 | + </UnhoistIterator> |
4594 | + </ProbeIndexPointValueIterator> |
4595 | + </ForVariable> |
4596 | + <ReturnClause> |
4597 | + <ElementIterator> |
4598 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
4599 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
4600 | + <EnclosedIterator attr_cont="true"> |
4601 | + <ForVarIterator varname="anzahl"/> |
4602 | + </EnclosedIterator> |
4603 | + </AttributeIterator> |
4604 | + <EnclosedIterator attr_cont="false"> |
4605 | + <ForVarIterator varname="book"/> |
4606 | + </EnclosedIterator> |
4607 | + </ElementIterator> |
4608 | </ReturnClause> |
4609 | </flwor::FLWORIterator> |
4610 | </EnclosedIterator> |
4611 | |
4612 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9210.iter' |
4613 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9210.iter 2012-09-19 21:16:15 +0000 |
4614 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9210.iter 2013-02-28 21:53:23 +0000 |
4615 | @@ -12,59 +12,55 @@ |
4616 | </DescendantAxisIterator> |
4617 | </HoistIterator> |
4618 | </LetVariable> |
4619 | + <LetVariable name="$$opt_temp_3" materialize="true"> |
4620 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4621 | + <flwor::FLWORIterator> |
4622 | + <ForVariable name="$$opt_temp_1"> |
4623 | + <UnhoistIterator> |
4624 | + <LetVarIterator varname="$$opt_temp_0"/> |
4625 | + </UnhoistIterator> |
4626 | + </ForVariable> |
4627 | + <ReturnClause> |
4628 | + <ValueIndexEntryBuilderIterator> |
4629 | + <ForVarIterator varname="$$opt_temp_1"/> |
4630 | + <FnCountIterator> |
4631 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4632 | + <ForVarIterator varname="$$opt_temp_1"/> |
4633 | + </ChildAxisIterator> |
4634 | + </FnCountIterator> |
4635 | + </ValueIndexEntryBuilderIterator> |
4636 | + </ReturnClause> |
4637 | + </flwor::FLWORIterator> |
4638 | + </CreateInternalIndexIterator> |
4639 | + </LetVariable> |
4640 | + <ForVariable name="anzahl"> |
4641 | + <OpToIterator> |
4642 | + <SingletonIterator value="xs:integer(1)"/> |
4643 | + <SingletonIterator value="xs:integer(2)"/> |
4644 | + </OpToIterator> |
4645 | + </ForVariable> |
4646 | <ReturnClause> |
4647 | - <SequentialIterator> |
4648 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4649 | + <ElementIterator> |
4650 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
4651 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
4652 | + <EnclosedIterator attr_cont="true"> |
4653 | + <ForVarIterator varname="anzahl"/> |
4654 | + </EnclosedIterator> |
4655 | + </AttributeIterator> |
4656 | + <EnclosedIterator attr_cont="false"> |
4657 | <flwor::FLWORIterator> |
4658 | - <ForVariable name="$$opt_temp_1"> |
4659 | - <UnhoistIterator> |
4660 | - <LetVarIterator varname="$$opt_temp_0"/> |
4661 | - </UnhoistIterator> |
4662 | + <ForVariable name="book"> |
4663 | + <ProbeIndexPointValueIterator> |
4664 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4665 | + <ForVarIterator varname="anzahl"/> |
4666 | + </ProbeIndexPointValueIterator> |
4667 | </ForVariable> |
4668 | <ReturnClause> |
4669 | - <ValueIndexEntryBuilderIterator> |
4670 | - <ForVarIterator varname="$$opt_temp_1"/> |
4671 | - <FnCountIterator> |
4672 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4673 | - <ForVarIterator varname="$$opt_temp_1"/> |
4674 | - </ChildAxisIterator> |
4675 | - </FnCountIterator> |
4676 | - </ValueIndexEntryBuilderIterator> |
4677 | + <ForVarIterator varname="book"/> |
4678 | </ReturnClause> |
4679 | </flwor::FLWORIterator> |
4680 | - </CreateInternalIndexIterator> |
4681 | - <flwor::FLWORIterator> |
4682 | - <ForVariable name="anzahl"> |
4683 | - <OpToIterator> |
4684 | - <SingletonIterator value="xs:integer(1)"/> |
4685 | - <SingletonIterator value="xs:integer(2)"/> |
4686 | - </OpToIterator> |
4687 | - </ForVariable> |
4688 | - <ReturnClause> |
4689 | - <ElementIterator> |
4690 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
4691 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
4692 | - <EnclosedIterator attr_cont="true"> |
4693 | - <ForVarIterator varname="anzahl"/> |
4694 | - </EnclosedIterator> |
4695 | - </AttributeIterator> |
4696 | - <EnclosedIterator attr_cont="false"> |
4697 | - <flwor::FLWORIterator> |
4698 | - <ForVariable name="book"> |
4699 | - <ProbeIndexPointValueIterator> |
4700 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4701 | - <ForVarIterator varname="anzahl"/> |
4702 | - </ProbeIndexPointValueIterator> |
4703 | - </ForVariable> |
4704 | - <ReturnClause> |
4705 | - <ForVarIterator varname="book"/> |
4706 | - </ReturnClause> |
4707 | - </flwor::FLWORIterator> |
4708 | - </EnclosedIterator> |
4709 | - </ElementIterator> |
4710 | - </ReturnClause> |
4711 | - </flwor::FLWORIterator> |
4712 | - </SequentialIterator> |
4713 | + </EnclosedIterator> |
4714 | + </ElementIterator> |
4715 | </ReturnClause> |
4716 | </flwor::FLWORIterator> |
4717 | </EnclosedIterator> |
4718 | |
4719 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9211.iter' |
4720 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9211.iter 2012-09-19 21:16:15 +0000 |
4721 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9211.iter 2013-02-28 21:53:23 +0000 |
4722 | @@ -12,62 +12,58 @@ |
4723 | </DescendantAxisIterator> |
4724 | </HoistIterator> |
4725 | </LetVariable> |
4726 | + <LetVariable name="$$opt_temp_3" materialize="true"> |
4727 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4728 | + <flwor::FLWORIterator> |
4729 | + <ForVariable name="$$opt_temp_1"> |
4730 | + <UnhoistIterator> |
4731 | + <LetVarIterator varname="$$opt_temp_0"/> |
4732 | + </UnhoistIterator> |
4733 | + </ForVariable> |
4734 | + <ReturnClause> |
4735 | + <ValueIndexEntryBuilderIterator> |
4736 | + <ForVarIterator varname="$$opt_temp_1"/> |
4737 | + <FnCountIterator> |
4738 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4739 | + <ForVarIterator varname="$$opt_temp_1"/> |
4740 | + </ChildAxisIterator> |
4741 | + </FnCountIterator> |
4742 | + </ValueIndexEntryBuilderIterator> |
4743 | + </ReturnClause> |
4744 | + </flwor::FLWORIterator> |
4745 | + </CreateInternalIndexIterator> |
4746 | + </LetVariable> |
4747 | + <ForVariable name="anzahl"> |
4748 | + <OpToIterator> |
4749 | + <SingletonIterator value="xs:integer(1)"/> |
4750 | + <SingletonIterator value="xs:integer(2)"/> |
4751 | + </OpToIterator> |
4752 | + </ForVariable> |
4753 | + <OrderBySpec> |
4754 | + <ForVarIterator varname="anzahl"/> |
4755 | + </OrderBySpec> |
4756 | <ReturnClause> |
4757 | - <SequentialIterator> |
4758 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4759 | + <ElementIterator> |
4760 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
4761 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
4762 | + <EnclosedIterator attr_cont="true"> |
4763 | + <ForVarIterator varname="anzahl"/> |
4764 | + </EnclosedIterator> |
4765 | + </AttributeIterator> |
4766 | + <EnclosedIterator attr_cont="false"> |
4767 | <flwor::FLWORIterator> |
4768 | - <ForVariable name="$$opt_temp_1"> |
4769 | - <UnhoistIterator> |
4770 | - <LetVarIterator varname="$$opt_temp_0"/> |
4771 | - </UnhoistIterator> |
4772 | + <ForVariable name="book"> |
4773 | + <ProbeIndexPointValueIterator> |
4774 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4775 | + <ForVarIterator varname="anzahl"/> |
4776 | + </ProbeIndexPointValueIterator> |
4777 | </ForVariable> |
4778 | <ReturnClause> |
4779 | - <ValueIndexEntryBuilderIterator> |
4780 | - <ForVarIterator varname="$$opt_temp_1"/> |
4781 | - <FnCountIterator> |
4782 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4783 | - <ForVarIterator varname="$$opt_temp_1"/> |
4784 | - </ChildAxisIterator> |
4785 | - </FnCountIterator> |
4786 | - </ValueIndexEntryBuilderIterator> |
4787 | + <ForVarIterator varname="book"/> |
4788 | </ReturnClause> |
4789 | </flwor::FLWORIterator> |
4790 | - </CreateInternalIndexIterator> |
4791 | - <flwor::FLWORIterator> |
4792 | - <ForVariable name="anzahl"> |
4793 | - <OpToIterator> |
4794 | - <SingletonIterator value="xs:integer(1)"/> |
4795 | - <SingletonIterator value="xs:integer(2)"/> |
4796 | - </OpToIterator> |
4797 | - </ForVariable> |
4798 | - <OrderBySpec> |
4799 | - <ForVarIterator varname="anzahl"/> |
4800 | - </OrderBySpec> |
4801 | - <ReturnClause> |
4802 | - <ElementIterator> |
4803 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
4804 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
4805 | - <EnclosedIterator attr_cont="true"> |
4806 | - <ForVarIterator varname="anzahl"/> |
4807 | - </EnclosedIterator> |
4808 | - </AttributeIterator> |
4809 | - <EnclosedIterator attr_cont="false"> |
4810 | - <flwor::FLWORIterator> |
4811 | - <ForVariable name="book"> |
4812 | - <ProbeIndexPointValueIterator> |
4813 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4814 | - <ForVarIterator varname="anzahl"/> |
4815 | - </ProbeIndexPointValueIterator> |
4816 | - </ForVariable> |
4817 | - <ReturnClause> |
4818 | - <ForVarIterator varname="book"/> |
4819 | - </ReturnClause> |
4820 | - </flwor::FLWORIterator> |
4821 | - </EnclosedIterator> |
4822 | - </ElementIterator> |
4823 | - </ReturnClause> |
4824 | - </flwor::FLWORIterator> |
4825 | - </SequentialIterator> |
4826 | + </EnclosedIterator> |
4827 | + </ElementIterator> |
4828 | </ReturnClause> |
4829 | </flwor::FLWORIterator> |
4830 | </EnclosedIterator> |
4831 | |
4832 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9212.iter' |
4833 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9212.iter 2012-09-19 21:16:15 +0000 |
4834 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9212.iter 2013-02-28 21:53:23 +0000 |
4835 | @@ -12,70 +12,66 @@ |
4836 | </DescendantAxisIterator> |
4837 | </HoistIterator> |
4838 | </LetVariable> |
4839 | + <LetVariable name="$$opt_temp_3" materialize="true"> |
4840 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4841 | + <flwor::FLWORIterator> |
4842 | + <ForVariable name="$$opt_temp_1"> |
4843 | + <UnhoistIterator> |
4844 | + <LetVarIterator varname="$$opt_temp_0"/> |
4845 | + </UnhoistIterator> |
4846 | + </ForVariable> |
4847 | + <ReturnClause> |
4848 | + <ValueIndexEntryBuilderIterator> |
4849 | + <ForVarIterator varname="$$opt_temp_1"/> |
4850 | + <FnCountIterator> |
4851 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4852 | + <ForVarIterator varname="$$opt_temp_1"/> |
4853 | + </ChildAxisIterator> |
4854 | + </FnCountIterator> |
4855 | + </ValueIndexEntryBuilderIterator> |
4856 | + </ReturnClause> |
4857 | + </flwor::FLWORIterator> |
4858 | + </CreateInternalIndexIterator> |
4859 | + </LetVariable> |
4860 | + <ForVariable name="book"> |
4861 | + <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
4862 | + <FnDocIterator> |
4863 | + <SingletonIterator value="xs:string(books.xml)"/> |
4864 | + </FnDocIterator> |
4865 | + </DescendantAxisIterator> |
4866 | + </ForVariable> |
4867 | + <ForVariable name="anzahl"> |
4868 | + <FnCountIterator> |
4869 | + <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4870 | + <ForVarIterator varname="book"/> |
4871 | + </ChildAxisIterator> |
4872 | + </FnCountIterator> |
4873 | + </ForVariable> |
4874 | + <OrderBySpec> |
4875 | + <ForVarIterator varname="anzahl"/> |
4876 | + </OrderBySpec> |
4877 | <ReturnClause> |
4878 | - <SequentialIterator> |
4879 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4880 | + <ElementIterator> |
4881 | + <SingletonIterator value="xs:QName(,,gruppe)"/> |
4882 | + <AttributeIterator qname="xs:QName(,,anzahl)"> |
4883 | + <EnclosedIterator attr_cont="true"> |
4884 | + <ForVarIterator varname="anzahl"/> |
4885 | + </EnclosedIterator> |
4886 | + </AttributeIterator> |
4887 | + <EnclosedIterator attr_cont="false"> |
4888 | <flwor::FLWORIterator> |
4889 | - <ForVariable name="$$opt_temp_1"> |
4890 | - <UnhoistIterator> |
4891 | - <LetVarIterator varname="$$opt_temp_0"/> |
4892 | - </UnhoistIterator> |
4893 | + <ForVariable name="book"> |
4894 | + <ProbeIndexPointValueIterator> |
4895 | + <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4896 | + <ForVarIterator varname="anzahl"/> |
4897 | + </ProbeIndexPointValueIterator> |
4898 | </ForVariable> |
4899 | <ReturnClause> |
4900 | - <ValueIndexEntryBuilderIterator> |
4901 | - <ForVarIterator varname="$$opt_temp_1"/> |
4902 | - <FnCountIterator> |
4903 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4904 | - <ForVarIterator varname="$$opt_temp_1"/> |
4905 | - </ChildAxisIterator> |
4906 | - </FnCountIterator> |
4907 | - </ValueIndexEntryBuilderIterator> |
4908 | + <ForVarIterator varname="book"/> |
4909 | </ReturnClause> |
4910 | </flwor::FLWORIterator> |
4911 | - </CreateInternalIndexIterator> |
4912 | - <flwor::FLWORIterator> |
4913 | - <ForVariable name="book"> |
4914 | - <DescendantAxisIterator test kind="match_name_test" qname="xs:QName(,,book)" typename="*" nill allowed="0"> |
4915 | - <FnDocIterator> |
4916 | - <SingletonIterator value="xs:string(books.xml)"/> |
4917 | - </FnDocIterator> |
4918 | - </DescendantAxisIterator> |
4919 | - </ForVariable> |
4920 | - <ForVariable name="anzahl"> |
4921 | - <FnCountIterator> |
4922 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4923 | - <ForVarIterator varname="book"/> |
4924 | - </ChildAxisIterator> |
4925 | - </FnCountIterator> |
4926 | - </ForVariable> |
4927 | - <OrderBySpec> |
4928 | - <ForVarIterator varname="anzahl"/> |
4929 | - </OrderBySpec> |
4930 | - <ReturnClause> |
4931 | - <ElementIterator> |
4932 | - <SingletonIterator value="xs:QName(,,gruppe)"/> |
4933 | - <AttributeIterator qname="xs:QName(,,anzahl)"> |
4934 | - <EnclosedIterator attr_cont="true"> |
4935 | - <ForVarIterator varname="anzahl"/> |
4936 | - </EnclosedIterator> |
4937 | - </AttributeIterator> |
4938 | - <EnclosedIterator attr_cont="false"> |
4939 | - <flwor::FLWORIterator> |
4940 | - <ForVariable name="book"> |
4941 | - <ProbeIndexPointValueIterator> |
4942 | - <SingletonIterator value="xs:QName(,,tempIndex0)"/> |
4943 | - <ForVarIterator varname="anzahl"/> |
4944 | - </ProbeIndexPointValueIterator> |
4945 | - </ForVariable> |
4946 | - <ReturnClause> |
4947 | - <ForVarIterator varname="book"/> |
4948 | - </ReturnClause> |
4949 | - </flwor::FLWORIterator> |
4950 | - </EnclosedIterator> |
4951 | - </ElementIterator> |
4952 | - </ReturnClause> |
4953 | - </flwor::FLWORIterator> |
4954 | - </SequentialIterator> |
4955 | + </EnclosedIterator> |
4956 | + </ElementIterator> |
4957 | </ReturnClause> |
4958 | </flwor::FLWORIterator> |
4959 | </EnclosedIterator> |
4960 | |
4961 | === modified file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9389.iter' |
4962 | --- test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9389.iter 2012-09-19 21:16:15 +0000 |
4963 | +++ test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/9389.iter 2013-02-28 21:53:23 +0000 |
4964 | @@ -12,57 +12,53 @@ |
4965 | </DescendantAxisIterator> |
4966 | </HoistIterator> |
4967 | </LetVariable> |
4968 | - <ReturnClause> |
4969 | - <SequentialIterator> |
4970 | - <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4971 | - <flwor::FLWORIterator> |
4972 | - <ForVariable name="$$opt_temp_1"> |
4973 | - <UnhoistIterator> |
4974 | - <LetVarIterator varname="$$opt_temp_0"/> |
4975 | - </UnhoistIterator> |
4976 | - </ForVariable> |
4977 | - <ReturnClause> |
4978 | - <ValueIndexEntryBuilderIterator> |
4979 | - <ForVarIterator varname="$$opt_temp_1"/> |
4980 | - <FnCountIterator> |
4981 | - <ChildAxisIterator test kind="match_name_test" qname="xs:QName(,,author)" typename="*" nill allowed="0"> |
4982 | - <ForVarIterator varname="$$opt_temp_1"/> |
4983 | - </ChildAxisIterator> |
4984 | - </FnCountIterator> |
4985 | - </ValueIndexEntryBuilderIterator> |
4986 | - </ReturnClause> |
4987 | - </flwor::FLWORIterator> |
4988 | - </CreateInternalIndexIterator> |
4989 | + <LetVariable name="$$opt_temp_3" materialize="true"> |
4990 | + <CreateInternalIndexIterator name="xs:QName(,,tempIndex0)"> |
4991 | <flwor::FLWORIterator> |
4992 | - <ForVariable name="anzahl"> |
4993 | - <OpToIterator> |
4994 | - <SingletonIterator value="xs:integer(1)"/> |
4995 | - <SingletonIterator value="xs:integer(5)"/> |
4996 | - </OpToIterator> |
4997 | + <ForVariable name="$$opt_temp_1"> |
4998 | + <UnhoistIterator> |
4999 | + <LetVarIterator varname="$$opt_temp_0"/> |
5000 | + </UnhoistIterator> |
Validation queue starting for merge proposal. zorbatest. lambda. nu:8080/ remotequeue/ gen-flwor- opt-2013- 02-26T07- 24-42.137Z/ log.html
Log at: http://