Merge lp:~zorba-coders/zorba/gen-flwor-opt into lp:zorba

Proposed by Markos Zaharioudakis
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
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

To post a comment you must log in.
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
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/zo/testing/zorbatest/tester/TarmacLander.cmake:275 (message):
  Validation queue job gen-flwor-opt-2013-02-26T07-24-42.137Z is finished.
  The final status was:

  22 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
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/zo/testing/zorbatest/tester/TarmacLander.cmake:275 (message):
  Validation queue job gen-flwor-opt-2013-02-26T09-56-30.35Z is finished.
  The final status was:

  16 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
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/zo/testing/zorbatest/tester/TarmacLander.cmake:275 (message):
  Validation queue job gen-flwor-opt-2013-02-26T16-15-22.294Z is finished.
  The final status was:

  18 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
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/zo/testing/zorbatest/tester/TarmacLander.cmake:275 (message):
  Validation queue job gen-flwor-opt-2013-02-26T20-53-20.631Z is finished.
  The final status was:

  18 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Attempt to merge into lp:zorba failed due to conflicts:

text conflict in ChangeLog

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
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/zo/testing/zorbatest/tester/TarmacLander.cmake:275 (message):
  Validation queue job gen-flwor-opt-2013-02-28T11-32-29.632Z is finished.
  The final status was:

  2 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
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/zo/testing/zorbatest/tester/TarmacLander.cmake:275 (message):
  Validation queue job gen-flwor-opt-2013-02-28T12-50-12.909Z is finished.
  The final status was:

  2 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

Revision history for this message
Markos Zaharioudakis (markos-za) :
review: Approve
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
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/zo/testing/zorbatest/tester/TarmacLander.cmake:275 (message):
  Validation queue job gen-flwor-opt-2013-02-28T20-52-18.552Z is finished.
  The final status was:

  5 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

lp:~zorba-coders/zorba/gen-flwor-opt updated
10676. By Markos Zaharioudakis

bug fix

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job gen-flwor-opt-2013-02-28T21-55-21.647Z is finished. The final status was:

All tests succeeded!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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>
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches