Merge lp:~zorba-coders/zorba/expr-matching into lp:zorba

Proposed by Markos Zaharioudakis
Status: Merged
Approved by: Markos Zaharioudakis
Approved revision: 11152
Merged at revision: 11204
Proposed branch: lp:~zorba-coders/zorba/expr-matching
Merge into: lp:zorba
Diff against target: 12863 lines (+9480/-1096)
108 files modified
src/compiler/api/compiler_api.h (+10/-4)
src/compiler/api/compilercb.h (+2/-0)
src/compiler/codegen/plan_visitor.cpp (+18/-17)
src/compiler/expression/expr.h (+69/-62)
src/compiler/expression/expr_base.cpp (+37/-19)
src/compiler/expression/expr_base.h (+1/-1)
src/compiler/expression/expr_clone.cpp (+1/-1)
src/compiler/expression/expr_consts.h (+25/-8)
src/compiler/expression/expr_iter.cpp (+5/-5)
src/compiler/expression/expr_manager.cpp (+4/-3)
src/compiler/expression/expr_manager.h (+3/-3)
src/compiler/expression/expr_put.cpp (+12/-8)
src/compiler/expression/flwor_expr.cpp (+36/-29)
src/compiler/expression/flwor_expr.h (+21/-18)
src/compiler/expression/path_expr.cpp (+93/-0)
src/compiler/expression/path_expr.h (+23/-5)
src/compiler/expression/var_expr.cpp (+2/-2)
src/compiler/expression/var_expr.h (+3/-3)
src/compiler/rewriter/rewriters/default_optimizer.cpp (+54/-15)
src/compiler/rewriter/rules/CMakeLists.txt (+1/-0)
src/compiler/rewriter/rules/flwor_rules.cpp (+20/-27)
src/compiler/rewriter/rules/fold_rules.h (+49/-0)
src/compiler/rewriter/rules/hoist_rules.cpp (+1/-1)
src/compiler/rewriter/rules/index_join_rule.cpp (+1/-1)
src/compiler/rewriter/rules/index_matching_rule.cpp (+1064/-0)
src/compiler/rewriter/rules/index_matching_rule.h (+96/-0)
src/compiler/rewriter/rules/ruleset.h (+2/-2)
src/compiler/rewriter/tools/dataflow_annotations.cpp (+1/-1)
src/compiler/rewriter/tools/expr_tools.cpp (+486/-8)
src/compiler/rewriter/tools/expr_tools.h (+3/-0)
src/compiler/translator/translator.cpp (+132/-127)
src/compiler/xqddf/collection_decl.h (+10/-12)
src/compiler/xqddf/value_index.cpp (+184/-28)
src/compiler/xqddf/value_index.h (+18/-12)
src/context/sctx_map_iterator.h (+2/-2)
src/context/static_context.cpp (+28/-1)
src/context/static_context.h (+2/-0)
src/functions/func_booleans_impl.cpp (+2/-2)
src/functions/func_collections_impl.cpp (+5/-3)
src/functions/func_eval.cpp (+3/-0)
src/functions/func_index_ddl.h (+8/-1)
src/runtime/collections/collections_impl.cpp (+6/-8)
src/runtime/core/apply_updates.cpp (+2/-2)
src/runtime/core/sequencetypes.cpp (+6/-0)
src/runtime/eval/eval.cpp (+2/-0)
src/runtime/indexing/index_ddl.cpp (+59/-36)
src/store/naive/simple_index.cpp (+3/-3)
src/store/naive/simple_index_value.cpp (+5/-2)
src/store/util/item_vector.cpp (+7/-7)
src/system/zorba_properties.h (+40/-19)
src/types/typeimpl.cpp (+1/-1)
src/types/typeops.cpp (+2/-25)
src/util/dynamic_bitset.cpp (+3/-2)
src/util/dynamic_bitset.h (+2/-2)
test/rbkt/ExpCompilerResults/IterPlan/zorba/hashjoins/gary1.iter (+150/-172)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_01.iter (+127/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_02.iter (+165/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_03.iter (+165/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_04.iter (+228/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_05.iter (+315/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_06.iter (+334/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_veq_07.iter (+155/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_vrange_01.iter (+239/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_vrange_02.iter (+296/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_vrange_02a.iter (+330/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_vrange_02b.iter (+303/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_vrange_03.iter (+294/-0)
test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/hashjoin-gary1.iter (+150/-172)
test/rbkt/ExpCompilerResults/IterPlan/zorba/no-copy/q4.iter (+49/-67)
test/rbkt/ExpCompilerResults/IterPlan/zorba/xmark/q4.iter (+49/-67)
test/rbkt/ExpCompilerResults/IterPlan/zorba/xray/ppm_10.iter (+78/-79)
test/rbkt/ExpQueryResults/zorba/index/match_veq_01.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/index/match_veq_02.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/index/match_veq_03.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/index/match_veq_04.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/index/match_veq_05.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/index/match_veq_06.xml.res (+3/-0)
test/rbkt/ExpQueryResults/zorba/index/match_veq_07.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/index/match_vrange_01.xml.res (+2/-0)
test/rbkt/ExpQueryResults/zorba/index/match_vrange_02.xml.res (+6/-0)
test/rbkt/ExpQueryResults/zorba/index/match_vrange_02a.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/index/match_vrange_02b.xml.res (+4/-0)
test/rbkt/ExpQueryResults/zorba/index/match_vrange_03.xml.res (+5/-0)
test/rbkt/Queries/zorba/collections/collection_001.xqdata (+1/-1)
test/rbkt/Queries/zorba/collections/dynamic1.xq (+12/-0)
test/rbkt/Queries/zorba/index/auction.xml (+2182/-0)
test/rbkt/Queries/zorba/index/match_veq_01.xq (+39/-0)
test/rbkt/Queries/zorba/index/match_veq_01.xqlib (+23/-0)
test/rbkt/Queries/zorba/index/match_veq_02.xq (+50/-0)
test/rbkt/Queries/zorba/index/match_veq_02.xqlib (+24/-0)
test/rbkt/Queries/zorba/index/match_veq_03.xq (+50/-0)
test/rbkt/Queries/zorba/index/match_veq_03.xqlib (+22/-0)
test/rbkt/Queries/zorba/index/match_veq_04.xq (+51/-0)
test/rbkt/Queries/zorba/index/match_veq_04.xqlib (+21/-0)
test/rbkt/Queries/zorba/index/match_veq_05.xq (+67/-0)
test/rbkt/Queries/zorba/index/match_veq_05.xqlib (+21/-0)
test/rbkt/Queries/zorba/index/match_veq_06.xq (+26/-0)
test/rbkt/Queries/zorba/index/match_veq_06.xqlib (+101/-0)
test/rbkt/Queries/zorba/index/match_veq_07.xq (+27/-0)
test/rbkt/Queries/zorba/index/match_veq_07.xqlib (+30/-0)
test/rbkt/Queries/zorba/index/match_vrange_01.xq (+54/-0)
test/rbkt/Queries/zorba/index/match_vrange_01.xqlib (+31/-0)
test/rbkt/Queries/zorba/index/match_vrange_02.xq (+122/-0)
test/rbkt/Queries/zorba/index/match_vrange_02.xqlib (+31/-0)
test/rbkt/Queries/zorba/index/match_vrange_02a.xq (+105/-0)
test/rbkt/Queries/zorba/index/match_vrange_02b.xq (+108/-0)
test/rbkt/Queries/zorba/index/match_vrange_03.xq (+122/-0)
test/rbkt/Queries/zorba/index/match_vrange_03.xqlib (+31/-0)
To merge this branch: bzr merge lp:~zorba-coders/zorba/expr-matching
Reviewer Review Type Date Requested Status
Markos Zaharioudakis Approve
Review via email: mp+141028@code.launchpad.net

Commit message

Index matching for value-equality indexes

Description of the change

Index matching for value-equality indexes

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 :

Validation queue job expr-matching-2013-01-11T23-35-10.801Z is finished. The final status was:

All tests succeeded!

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

Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1. Got: 2 Pending.

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/expr-matching 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 expr-matching-2013-01-29T14-30-13.686Z is finished.
  The final status was:

  14 tests did not succeed - changes not commited.

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

lp:~zorba-coders/zorba/expr-matching updated
11152. By Markos Zaharioudakis

a 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 expr-matching-2013-01-29T18-33-17.542Z 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 'src/compiler/api/compiler_api.h'
2--- src/compiler/api/compiler_api.h 2012-10-08 12:09:36 +0000
3+++ src/compiler/api/compiler_api.h 2013-01-29 17:56:25 +0000
4@@ -23,9 +23,13 @@
5 #include "common/shared_types.h"
6 #include <zorba/api_shared_types.h>
7
8-namespace zorba {
9-
10-
11+namespace zorba
12+{
13+
14+
15+/********************************************************************************
16+
17+********************************************************************************/
18 class XQueryCompiler
19 {
20 public:
21@@ -59,7 +63,6 @@
22 ulong& nextDynamicVarId,
23 audit::ScopedRecord& aAuditRecord);
24
25-protected:
26 expr* normalize(parsenode_t ast);
27
28 expr* optimize(expr* expr);
29@@ -72,6 +75,9 @@
30 };
31
32
33+/********************************************************************************
34+
35+********************************************************************************/
36 class XQueryCompilerSubsystem
37 {
38 friend class GlobalEnvironment;
39
40=== modified file 'src/compiler/api/compilercb.h'
41--- src/compiler/api/compilercb.h 2012-12-06 22:49:35 +0000
42+++ src/compiler/api/compilercb.h 2013-01-29 17:56:25 +0000
43@@ -253,6 +253,8 @@
44
45 ExprManager* getExprManager() const { return theEM; }
46
47+ uint8_t getVisitId() { return theNextVisitId++; }
48+
49 //
50 // Pragmas
51 //
52
53=== modified file 'src/compiler/codegen/plan_visitor.cpp'
54--- src/compiler/codegen/plan_visitor.cpp 2012-12-21 22:05:39 +0000
55+++ src/compiler/codegen/plan_visitor.cpp 2013-01-29 17:56:25 +0000
56@@ -995,7 +995,7 @@
57
58 if (i > 0 &&
59 v.get_clause(i-1)->get_kind() != flwor_clause::order_clause &&
60- v.get_clause(i-1)->get_kind() != flwor_clause::group_clause)
61+ v.get_clause(i-1)->get_kind() != flwor_clause::groupby_clause)
62 {
63 orderby_clause* mat = theCCB->theEM->
64 create_orderby_clause(v.get_sctx(),
65@@ -1011,7 +1011,7 @@
66
67 if (i == numClauses -1 ||
68 (i < numClauses - 1 &&
69- v.get_clause(i+1)->get_kind() != flwor_clause::group_clause))
70+ v.get_clause(i+1)->get_kind() != flwor_clause::groupby_clause))
71 {
72 orderby_clause* mat = theCCB->theEM->
73 create_orderby_clause(v.get_sctx(),
74@@ -1029,7 +1029,7 @@
75 break;
76 }
77 case flwor_clause::where_clause:
78- case flwor_clause::group_clause:
79+ case flwor_clause::groupby_clause:
80 case flwor_clause::order_clause:
81 case flwor_clause::count_clause:
82 {
83@@ -1046,7 +1046,7 @@
84
85 if (v.get_return_expr()->is_sequential() &&
86 lastClause->get_kind() != flwor_clause::order_clause &&
87- lastClause->get_kind() != flwor_clause::group_clause)
88+ lastClause->get_kind() != flwor_clause::groupby_clause)
89 {
90 orderby_clause* mat = theCCB->theEM->
91 create_orderby_clause(v.get_sctx(),
92@@ -1098,9 +1098,9 @@
93 break;
94 }
95
96- case flwor_clause::group_clause:
97+ case flwor_clause::groupby_clause:
98 {
99- const group_clause* gc = reinterpret_cast<const group_clause*>(c);
100+ const groupby_clause* gc = reinterpret_cast<const groupby_clause*>(c);
101
102 const flwor_clause::rebind_list_t& gvars = gc->get_grouping_vars();
103 const flwor_clause::rebind_list_t& ngvars = gc->get_nongrouping_vars();
104@@ -1242,11 +1242,11 @@
105 break;
106 }
107
108- case flwor_clause::group_clause:
109+ case flwor_clause::groupby_clause:
110 {
111- const group_clause* gbc = static_cast<const group_clause *>(c);
112- const group_clause::rebind_list_t& grouping_vars = gbc->get_grouping_vars();
113- const group_clause::rebind_list_t& nongrouping_vars = gbc->get_nongrouping_vars();
114+ const groupby_clause* gbc = static_cast<const groupby_clause *>(c);
115+ const groupby_clause::rebind_list_t& grouping_vars = gbc->get_grouping_vars();
116+ const groupby_clause::rebind_list_t& nongrouping_vars = gbc->get_nongrouping_vars();
117
118 for (unsigned i = 0; i < grouping_vars.size(); ++i)
119 {
120@@ -1689,7 +1689,7 @@
121 //
122 // GROUPBY
123 //
124- else if (c.get_kind() == flwor_clause::group_clause)
125+ else if (c.get_kind() == flwor_clause::groupby_clause)
126 {
127 std::vector<flwor::GroupingSpec> gspecs;
128 std::vector<flwor::NonGroupingSpec> ngspecs;
129@@ -1825,7 +1825,7 @@
130 //
131 // GROUPBY
132 //
133- case flwor_clause::group_clause:
134+ case flwor_clause::groupby_clause:
135 {
136 std::vector<flwor::GroupingSpec> gspecs;
137 std::vector<flwor::NonGroupingSpec> ngspecs;
138@@ -1954,10 +1954,10 @@
139 std::vector<flwor::GroupingSpec>& gspecs,
140 std::vector<flwor::NonGroupingSpec>& ngspecs)
141 {
142- const group_clause* gbc = static_cast<const group_clause*>(clauseVarMap->theClause);
143+ const groupby_clause* gbc = static_cast<const groupby_clause*>(clauseVarMap->theClause);
144
145- const group_clause::rebind_list_t& gvars = gbc->get_grouping_vars();
146- const group_clause::rebind_list_t& ngvars = gbc->get_nongrouping_vars();
147+ const groupby_clause::rebind_list_t& gvars = gbc->get_grouping_vars();
148+ const groupby_clause::rebind_list_t& ngvars = gbc->get_nongrouping_vars();
149
150 const std::vector<std::string>& collations = gbc->get_collations();
151
152@@ -2158,6 +2158,7 @@
153 false));
154 }
155
156+
157 #ifdef ZORBA_WITH_DEBUGGER
158 bool begin_visit(debugger_expr& v)
159 {
160@@ -2428,8 +2429,8 @@
161 void end_visit(instanceof_expr& v)
162 {
163 CODEGEN_TRACE_OUT("");
164- PlanIter_t p = pop_itstack ();
165- push_itstack (new InstanceOfIterator (sctx, qloc, p, v.get_target_type ()));
166+ PlanIter_t p = pop_itstack();
167+ push_itstack (new InstanceOfIterator (sctx, qloc, p, v.get_target_type()));
168 }
169
170
171
172=== modified file 'src/compiler/expression/expr.h'
173--- src/compiler/expression/expr.h 2012-12-21 22:05:39 +0000
174+++ src/compiler/expression/expr.h 2013-01-29 17:56:25 +0000
175@@ -189,7 +189,7 @@
176 };
177
178
179-/***************************************************************************//**
180+/*******************************************************************************
181 Base for cast, treat, promote, castable, instanceof
182 ********************************************************************************/
183 class cast_or_castable_base_expr : public expr
184@@ -222,8 +222,8 @@
185 };
186
187
188-/***************************************************************************//**
189- Base for cast, treat, promote
190+/*******************************************************************************
191+ Base for cast, promote, treat
192 ********************************************************************************/
193 class cast_base_expr : public cast_or_castable_base_expr
194 {
195@@ -241,7 +241,7 @@
196 };
197
198
199-/***************************************************************************//**
200+/*******************************************************************************
201 CastExpr ::= UnaryExpr ( "cast" "as" SingleType )?
202
203 SingleType ::= AtomicType "?"?
204@@ -275,65 +275,12 @@
205
206
207 /***************************************************************************//**
208- TreatExpr ::= CastableExpr ( "treat" "as" SequenceType )?
209-
210- theCheckPrime : Normally, this is true. If false, then during runtime, only
211- the cardinality of theInputExpr will be checked w.r.t. the
212- quantifier of theTargetType. theCheckPrime is set to false
213- by the optimizer, if it discovers that the prime type of the
214- static type of theInputExpr is a subtype of the prime type of
215- theTargetType.
216-
217- theFnQName : Stores the QName of the function, if the treat expr is used
218- to cast the function's body to its result type
219-********************************************************************************/
220-class treat_expr : public cast_base_expr
221-{
222- friend class ExprManager;
223- friend class ExprIterator;
224- friend class expr;
225-
226-protected:
227- TreatErrorKind theErrorKind;
228- bool theCheckPrime;
229- store::Item_t theQName;
230-
231-protected:
232- treat_expr(
233- CompilerCB* ccb,
234- static_context* sctx,
235- user_function* udf,
236- const QueryLoc&,
237- expr*,
238- const xqtref_t&,
239- TreatErrorKind err,
240- bool check_prime = true,
241- store::Item* qname = NULL);
242-
243-public:
244- TreatErrorKind get_err() const { return theErrorKind; }
245-
246- bool get_check_prime() const { return theCheckPrime; }
247-
248- void set_check_prime(bool check_prime) { theCheckPrime = check_prime; }
249-
250- void set_qname(const store::Item_t& qname) { theQName = qname; }
251-
252- store::Item_t get_qname() const { return theQName; }
253-
254- void accept(expr_visitor&);
255-
256- std::ostream& put(std::ostream&) const;
257-};
258-
259-
260-/***************************************************************************//**
261 This is an internal zorba expr. Its semantics are the following:
262
263 1. Let "input sequence" be the result of theInputExpr, and "output sequence"
264 be the result of the promote_expr.
265
266- 2. The input sequence is assumed to be mepty or consist of atomic items only.
267+ 2. The input sequence is assumed to be empty or consist of atomic items only.
268
269 4. theTargetType is always a subtype of xs:anyAtomicType*
270
271@@ -350,17 +297,20 @@
272 - If the actual type is untypedAtomic and the target type is not QName,
273 F(I) = cast(I, target type), else
274 - If the actual type is (subtype of) decimal and the target type is float,
275- F(I) = cast(I, target type), else
276+ F(I) = cast(I, float), else
277 - If the actual type is (subtype of) decimal or float and the target type is double,
278- F(I) = cast(I, target type), else
279+ F(I) = cast(I, double), else
280 - If the actual type is anyURI and the target type is string,
281 F(I) = cast(I, string), else
282 - F(I) = raise error
283
284 4. Put F(I) in the output sequence.
285
286- theFnQName:
287- -----------
288+ theErrorKind :
289+ --------------
290+
291+ theQName:
292+ ---------
293 Stores the QName of the function, if the promote expr is used to cast the
294 function's body to its result type
295
296@@ -400,6 +350,62 @@
297
298
299 /***************************************************************************//**
300+ TreatExpr ::= CastableExpr ( "treat" "as" SequenceType )?
301+
302+ theCheckPrime :
303+ ---------------
304+ Normally, this is true. If false, then during runtime, only the cardinality of
305+ theInputExpr will be checked w.r.t. the quantifier of theTargetType.
306+ theCheckPrime is set to false by the optimizer, if it discovers that the prime
307+ type of the static type of theInputExpr is a subtype of the prime type of
308+ theTargetType.
309+
310+ theQName :
311+ ------------
312+ Stores the QName of the function, if the treat expr is used to cast the
313+ function's body to its result type
314+********************************************************************************/
315+class treat_expr : public cast_base_expr
316+{
317+ friend class ExprManager;
318+ friend class ExprIterator;
319+ friend class expr;
320+
321+protected:
322+ TreatErrorKind theErrorKind;
323+ bool theCheckPrime;
324+ store::Item_t theQName;
325+
326+protected:
327+ treat_expr(
328+ CompilerCB* ccb,
329+ static_context* sctx,
330+ user_function* udf,
331+ const QueryLoc&,
332+ expr*,
333+ const xqtref_t&,
334+ TreatErrorKind err,
335+ bool check_prime = true,
336+ store::Item* qname = NULL);
337+
338+public:
339+ TreatErrorKind get_err() const { return theErrorKind; }
340+
341+ bool get_check_prime() const { return theCheckPrime; }
342+
343+ void set_check_prime(bool check_prime) { theCheckPrime = check_prime; }
344+
345+ void set_qname(const store::Item_t& qname) { theQName = qname; }
346+
347+ store::Item_t get_qname() const { return theQName; }
348+
349+ void accept(expr_visitor&);
350+
351+ std::ostream& put(std::ostream&) const;
352+};
353+
354+
355+/***************************************************************************//**
356 Base for castable, instanceof
357 ********************************************************************************/
358 class castable_base_expr : public cast_or_castable_base_expr
359@@ -455,6 +461,7 @@
360 InstanceofExpr ::= TreatExpr ( "instance" "of" SequenceType )?
361
362 theCheckPrimeOnly :
363+ -------------------
364 Normally, this is false. It is set to true only if this is an instanceof expr
365 that is created during the translation of a PredicateList (see translator.cpp).
366 This flag is used during the PartialEval rule.
367
368=== modified file 'src/compiler/expression/expr_base.cpp'
369--- src/compiler/expression/expr_base.cpp 2012-12-06 22:49:35 +0000
370+++ src/compiler/expression/expr_base.cpp 2013-01-29 17:56:25 +0000
371@@ -966,7 +966,7 @@
372
373 break;
374 }
375- case flwor_clause::group_clause:
376+ case flwor_clause::groupby_clause:
377 case flwor_clause::count_clause:
378 {
379 if (found)
380@@ -1165,45 +1165,63 @@
381 qname. This method is used to extract the qname from the expression that is
382 given as an arg to collection and index related functions.
383 ********************************************************************************/
384-const store::Item* expr::getQName(static_context* sctx) const
385+const store::Item* expr::getQName() const
386 {
387- RootTypeManager& rtm = GENV_TYPESYSTEM;
388-
389- TypeManager* tm = sctx->get_typemanager();
390-
391 if (get_expr_kind() == const_expr_kind)
392 {
393 const const_expr* qnameExpr = static_cast<const const_expr*>(this);
394
395- xqtref_t valueType = tm->create_value_type(qnameExpr->get_val());
396+ store::SchemaTypeCode valueType = qnameExpr->get_val()->getTypeCode();
397
398- if (TypeOps::is_subtype(tm, *valueType, *rtm.QNAME_TYPE_ONE, get_loc()))
399+ if (TypeOps::is_subtype(valueType, store::XS_QNAME))
400 {
401 return qnameExpr->get_val();
402 }
403 }
404+ else if (get_var() != NULL)
405+ {
406+ const var_expr* var = get_var();
407+
408+ if (var->get_kind() == var_expr::prolog_var &&
409+ var->num_set_exprs() == 1 &&
410+ var->get_set_expr(0)->get_expr_kind() == var_decl_expr_kind)
411+ {
412+ const var_decl_expr* decl =
413+ static_cast<const var_decl_expr*>(var->get_set_expr(0));
414+
415+ return decl->get_init_expr()->getQName();
416+ }
417+ }
418+ else if (get_expr_kind() == treat_expr_kind)
419+ {
420+ const treat_expr* treatExpr = static_cast<const treat_expr*>(this);
421+ const expr* argExpr = treatExpr->get_input();
422+ return argExpr->getQName();
423+ }
424 else if (get_expr_kind() == promote_expr_kind)
425 {
426 // We get here if the optimizer is turned off.
427
428 const promote_expr* promoteExpr = static_cast<const promote_expr*>(this);
429-
430 const expr* argExpr = promoteExpr->get_input();
431- const fo_expr* dataExpr = dynamic_cast<const fo_expr*>(argExpr);
432-
433- if (dataExpr != NULL &&
434- dataExpr->get_func()->getKind() == FunctionConsts::FN_DATA_1)
435+
436+ if (argExpr->get_expr_kind() == fo_expr_kind)
437 {
438- argExpr = dataExpr->get_arg(0);
439+ const fo_expr* dataExpr = static_cast<const fo_expr*>(argExpr);
440
441- if (argExpr->get_expr_kind() == const_expr_kind)
442+ if (dataExpr->get_func()->getKind() == FunctionConsts::FN_DATA_1)
443 {
444- const const_expr* qnameExpr = static_cast<const const_expr*>(argExpr);
445- xqtref_t valueType = tm->create_value_type(qnameExpr->get_val());
446+ argExpr = dataExpr->get_arg(0);
447
448- if (TypeOps::is_subtype(tm, *valueType, *rtm.QNAME_TYPE_ONE, get_loc()))
449+ if (argExpr->get_expr_kind() == const_expr_kind)
450 {
451- return qnameExpr->get_val();
452+ const const_expr* qnameExpr = static_cast<const const_expr*>(argExpr);
453+ store::SchemaTypeCode valueType = qnameExpr->get_val()->getTypeCode();
454+
455+ if (TypeOps::is_subtype(valueType, store::XS_QNAME))
456+ {
457+ return qnameExpr->get_val();
458+ }
459 }
460 }
461 }
462
463=== modified file 'src/compiler/expression/expr_base.h'
464--- src/compiler/expression/expr_base.h 2012-12-06 22:49:35 +0000
465+++ src/compiler/expression/expr_base.h 2013-01-29 17:56:25 +0000
466@@ -396,7 +396,7 @@
467
468 const var_expr* get_var() const;
469
470- const store::Item* getQName(static_context* sctx) const;
471+ const store::Item* getQName() const;
472
473 void clear_annotations();
474
475
476=== modified file 'src/compiler/expression/expr_clone.cpp'
477--- src/compiler/expression/expr_clone.cpp 2012-12-21 22:05:39 +0000
478+++ src/compiler/expression/expr_clone.cpp 2013-01-29 17:56:25 +0000
479@@ -252,7 +252,7 @@
480 const flwor_expr* e = static_cast<const flwor_expr*>(this);
481
482 flwor_expr* cloneExpr = theCCB->theEM->
483- create_flwor_expr(theSctx, udf, theLoc, e->theIsGeneral);
484+ create_flwor_expr(theSctx, udf, theLoc, e->is_general());
485
486 csize numClauses = e->num_clauses();
487
488
489=== modified file 'src/compiler/expression/expr_consts.h'
490--- src/compiler/expression/expr_consts.h 2012-10-24 11:32:56 +0000
491+++ src/compiler/expression/expr_consts.h 2013-01-29 17:56:25 +0000
492@@ -28,7 +28,8 @@
493 PROMOTE_TYPE_PROMOTION,
494 PROMOTE_JSONIQ_ARRAY_SELECTOR,
495 PROMOTE_JSONIQ_OBJECT_SELECTOR,
496- PROMOTE_JSONIQ_SELECTOR
497+ PROMOTE_JSONIQ_SELECTOR,
498+ PROMOTE_INDEX_KEY
499 };
500
501
502@@ -164,18 +165,34 @@
503 };
504
505
506+/*******************************************************************************
507+ ATTENTION !!!
508+ The ordering of the enum values in IKMPORTANT. DO NOT CHANGE IT.
509+ ATTENTION !!!
510+********************************************************************************/
511 class CompareConsts
512 {
513 public:
514 enum CompareType
515 {
516- UNKNOWN,
517- VALUE_EQUAL, GENERAL_EQUAL, NODE_EQUAL,
518- VALUE_NOT_EQUAL, GENERAL_NOT_EQUAL, NODE_NOT_EQUAL,
519- VALUE_LESS, GENERAL_LESS,
520- VALUE_LESS_EQUAL, GENERAL_LESS_EQUAL,
521- VALUE_GREATER, GENERAL_GREATER,
522- VALUE_GREATER_EQUAL, GENERAL_GREATER_EQUAL
523+ UNKNOWN = 0,
524+
525+ VALUE_EQUAL = 1,
526+ GENERAL_EQUAL = 2,
527+ NODE_EQUAL = 3,
528+ VALUE_NOT_EQUAL = 4,
529+ GENERAL_NOT_EQUAL = 5,
530+ NODE_NOT_EQUAL = 6,
531+
532+ VALUE_LESS = 7,
533+ GENERAL_LESS = 8,
534+ VALUE_LESS_EQUAL = 9,
535+ GENERAL_LESS_EQUAL = 10,
536+
537+ VALUE_GREATER = 11,
538+ GENERAL_GREATER = 12,
539+ VALUE_GREATER_EQUAL = 13,
540+ GENERAL_GREATER_EQUAL = 14
541 };
542 };
543
544
545=== modified file 'src/compiler/expression/expr_iter.cpp'
546--- src/compiler/expression/expr_iter.cpp 2012-12-12 07:36:20 +0000
547+++ src/compiler/expression/expr_iter.cpp 2013-01-29 17:56:25 +0000
548@@ -203,9 +203,9 @@
549 return;
550 }
551
552- case flwor_clause::group_clause:
553+ case flwor_clause::groupby_clause:
554 {
555- group_clause* gc = static_cast<group_clause *>(c);
556+ groupby_clause* gc = static_cast<groupby_clause *>(c);
557
558 theGroupVarsIter = gc->theGroupVars.begin();
559 theGroupVarsEnd = gc->theGroupVars.end();
560@@ -315,7 +315,7 @@
561 flwor_clause* c = NULL;
562 window_clause* wc = NULL;
563 orderby_clause* oc = NULL;
564- group_clause* gc = NULL;
565+ groupby_clause* gc = NULL;
566 flwor_wincond* wincond = NULL;
567
568 EXPR_ITER_BEGIN();
569@@ -362,9 +362,9 @@
570 }
571 }
572
573- else if (c->get_kind() == flwor_clause::group_clause)
574+ else if (c->get_kind() == flwor_clause::groupby_clause)
575 {
576- gc = static_cast<group_clause *>(c);
577+ gc = static_cast<groupby_clause *>(c);
578
579 theGroupVarsIter = gc->theGroupVars.begin();
580 theGroupVarsEnd = gc->theGroupVars.end();
581
582=== modified file 'src/compiler/expression/expr_manager.cpp'
583--- src/compiler/expression/expr_manager.cpp 2012-12-21 22:05:39 +0000
584+++ src/compiler/expression/expr_manager.cpp 2013-01-29 17:56:25 +0000
585@@ -423,7 +423,7 @@
586 static_context* sctx,
587 user_function* udf,
588 const QueryLoc& loc,
589- store::Item_t val)
590+ const store::Item_t& val)
591 {
592 CREATE_AND_RETURN_EXPR(const_expr, sctx, udf, loc, val);
593 }
594@@ -518,6 +518,7 @@
595 CREATE_AND_RETURN_EXPR(eval_expr, sctx, udf, loc, e, scriptingKind, nsCtx);
596 }
597
598+
599 #ifdef ZORBA_WITH_DEBUGGER
600
601 debugger_expr* ExprManager::create_debugger_expr(
602@@ -947,14 +948,14 @@
603 }
604
605
606-group_clause* ExprManager::create_group_clause(
607+groupby_clause* ExprManager::create_groupby_clause(
608 static_context* sctx,
609 const QueryLoc& loc,
610 const flwor_clause::rebind_list_t& gvars,
611 const flwor_clause::rebind_list_t& ngvars,
612 const std::vector<std::string>& collations)
613 {
614- CREATE_AND_RETURN(group_clause, sctx, theCCB, loc, gvars, ngvars, collations);
615+ CREATE_AND_RETURN(groupby_clause, sctx, theCCB, loc, gvars, ngvars, collations);
616 }
617
618
619
620=== modified file 'src/compiler/expression/expr_manager.h'
621--- src/compiler/expression/expr_manager.h 2012-12-21 22:05:39 +0000
622+++ src/compiler/expression/expr_manager.h 2013-01-29 17:56:25 +0000
623@@ -43,7 +43,7 @@
624 class flwor_wincond;
625 class copy_clause;
626 class window_clause;
627-class group_clause;
628+class groupby_clause;
629 class where_clause;
630 class count_clause;
631 class orderby_clause;
632@@ -264,7 +264,7 @@
633 static_context* sctx,
634 user_function* udf,
635 const QueryLoc&,
636- store::Item_t);
637+ const store::Item_t&);
638
639 const_expr* create_const_expr(
640 static_context* sctx,
641@@ -576,7 +576,7 @@
642 const flwor_wincond_vars& out_vars,
643 expr* cond);
644
645- group_clause* create_group_clause(
646+ groupby_clause* create_groupby_clause(
647 static_context* sctx,
648 const QueryLoc& loc,
649 const var_rebind_list_t& gvars,
650
651=== modified file 'src/compiler/expression/expr_put.cpp'
652--- src/compiler/expression/expr_put.cpp 2012-12-06 22:49:35 +0000
653+++ src/compiler/expression/expr_put.cpp 2013-01-29 17:56:25 +0000
654@@ -252,6 +252,7 @@
655 END_PUT();
656 }
657
658+
659 ostream& flwor_wincond::put(ostream& os) const
660 {
661 BEGIN_PUT(flwor_wincond);
662@@ -262,7 +263,7 @@
663 }
664
665
666-ostream& group_clause::put(ostream& os) const
667+ostream& groupby_clause::put(ostream& os) const
668 {
669 BEGIN_PUT_NL(GROUPBY);
670
671@@ -352,9 +353,9 @@
672 static_cast<const window_clause *>(&c)->put(os);
673 break;
674 }
675- case flwor_clause::group_clause:
676+ case flwor_clause::groupby_clause:
677 {
678- static_cast<const group_clause *>(&c)->put(os);
679+ static_cast<const groupby_clause *>(&c)->put(os);
680 break;
681 }
682 case flwor_clause::order_clause:
683@@ -755,13 +756,16 @@
684
685 ostream& order_expr::put(ostream& os) const
686 {
687- BEGIN_PUT(order_expr);
688-
689 switch (theType)
690 {
691- case doc_ordered: os << "ordered\n"; break;
692- case doc_unordered: os << "unordered\n"; break;
693- default: os << "??\n";
694+ case doc_ordered:
695+ os << indent << "ordered" << expr_addr(this) << " [\n" << inc_indent;
696+ break;
697+ case doc_unordered:
698+ os << indent << "unordered" << expr_addr(this) << " [\n" << inc_indent;
699+ break;
700+ default:
701+ os << "??\n";
702 }
703 theInput->put(os) << endl;
704
705
706=== modified file 'src/compiler/expression/flwor_expr.cpp'
707--- src/compiler/expression/flwor_expr.cpp 2012-10-26 07:13:42 +0000
708+++ src/compiler/expression/flwor_expr.cpp 2013-01-29 17:56:25 +0000
709@@ -526,7 +526,7 @@
710 /*******************************************************************************
711
712 ********************************************************************************/
713-group_clause::group_clause(
714+groupby_clause::groupby_clause(
715 static_context* sctx,
716 CompilerCB* ccb,
717 const QueryLoc& loc,
718@@ -534,7 +534,7 @@
719 const rebind_list_t& ngvars,
720 const std::vector<std::string>& collations)
721 :
722- flwor_clause(sctx, ccb, loc, flwor_clause::group_clause),
723+ flwor_clause(sctx, ccb, loc, flwor_clause::groupby_clause),
724 theGroupVars(gvars),
725 theNonGroupVars(ngvars),
726 theCollations(collations)
727@@ -543,14 +543,22 @@
728 csize numNGVars = theNonGroupVars.size();
729
730 for (csize i = 0; i < numGVars; ++i)
731+ {
732+ expr::checkSimpleExpr(theGroupVars[i].first);
733+
734 theGroupVars[i].second->set_flwor_clause(this);
735+ }
736
737 for (csize i = 0; i < numNGVars; ++i)
738+ {
739+ expr::checkSimpleExpr(theNonGroupVars[i].first);
740+
741 theNonGroupVars[i].second->set_flwor_clause(this);
742+ }
743 }
744
745
746-group_clause::~group_clause()
747+groupby_clause::~groupby_clause()
748 {
749 csize numGVars = theGroupVars.size();
750 csize numNGVars = theNonGroupVars.size();
751@@ -563,7 +571,7 @@
752 }
753
754
755-expr* group_clause::get_input_for_group_var(const var_expr* var)
756+expr* groupby_clause::get_input_for_group_var(const var_expr* var)
757 {
758 csize numVars = theGroupVars.size();
759 for (csize i = 0; i < numVars; ++i)
760@@ -576,7 +584,7 @@
761 }
762
763
764-expr* group_clause::get_input_for_nongroup_var(const var_expr* var)
765+expr* groupby_clause::get_input_for_nongroup_var(const var_expr* var)
766 {
767 csize numVars = theNonGroupVars.size();
768 for (csize i = 0; i < numVars; ++i)
769@@ -589,7 +597,7 @@
770 }
771
772
773-flwor_clause* group_clause::clone(
774+flwor_clause* groupby_clause::clone(
775 user_function* udf,
776 expr::substitution_t& subst) const
777 {
778@@ -626,7 +634,7 @@
779 subst[theNonGroupVars[i].second] = cloneNonGroupVars[i].second;
780 }
781
782- return theCCB->theEM->create_group_clause(theContext,
783+ return theCCB->theEM->create_groupby_clause(theContext,
784 get_loc(),
785 cloneGroupVars,
786 cloneNonGroupVars,
787@@ -788,7 +796,6 @@
788 bool general)
789 :
790 expr(ccb, sctx, udf, loc, (general ? gflwor_expr_kind : flwor_expr_kind)),
791- theIsGeneral(general),
792 theHasSequentialClauses(false),
793 theReturnExpr(NULL)
794 {
795@@ -934,13 +941,13 @@
796 /*******************************************************************************
797 For simple flwor only.
798 ********************************************************************************/
799-group_clause* flwor_expr::get_group_clause() const
800+groupby_clause* flwor_expr::get_group_clause() const
801 {
802 csize numClauses = num_clauses();
803 for (csize i = 0; i < numClauses; ++i)
804 {
805- if (theClauses[i]->get_kind() == flwor_clause::group_clause)
806- return reinterpret_cast<group_clause*>(theClauses[i]);
807+ if (theClauses[i]->get_kind() == flwor_clause::groupby_clause)
808+ return static_cast<groupby_clause*>(theClauses[i]);
809 }
810
811 return NULL;
812@@ -1011,7 +1018,7 @@
813 Returns a set containing all the variables defined by the clauses of this
814 flwor expr.
815 ******************************************************************************/
816-void flwor_expr::get_vars(expr::FreeVars& vars) const
817+void flwor_expr::get_vars(std::vector<var_expr*>& vars) const
818 {
819 csize numClauses = num_clauses();
820
821@@ -1025,34 +1032,34 @@
822 {
823 const for_clause* fc = static_cast<const for_clause *>(&c);
824
825- vars.insert(fc->get_var());
826+ vars.push_back(fc->get_var());
827
828 if (fc->get_pos_var() != NULL)
829- vars.insert(fc->get_pos_var());
830+ vars.push_back(fc->get_pos_var());
831
832 break;
833 }
834 case flwor_clause::let_clause:
835 {
836 const let_clause* lc = static_cast<const let_clause *>(&c);
837- vars.insert(lc->get_var());
838+ vars.push_back(lc->get_var());
839 break;
840 }
841 case flwor_clause::window_clause:
842 {
843 const window_clause* wc = static_cast<const window_clause *>(&c);
844
845- vars.insert(wc->get_var());
846+ vars.push_back(wc->get_var());
847
848 if (wc->get_win_start() != NULL)
849 {
850 const flwor_wincond* cond = wc->get_win_start();
851 const flwor_wincond::vars& condvars = cond->get_out_vars();
852
853- if (condvars.posvar != NULL) vars.insert(condvars.posvar);
854- if (condvars.curr != NULL) vars.insert(condvars.curr);
855- if (condvars.prev != NULL) vars.insert(condvars.prev);
856- if (condvars.next != NULL) vars.insert(condvars.next);
857+ if (condvars.posvar != NULL) vars.push_back(condvars.posvar);
858+ if (condvars.curr != NULL) vars.push_back(condvars.curr);
859+ if (condvars.prev != NULL) vars.push_back(condvars.prev);
860+ if (condvars.next != NULL) vars.push_back(condvars.next);
861 }
862
863 if (wc->get_win_stop() != NULL)
864@@ -1060,24 +1067,24 @@
865 const flwor_wincond* cond = wc->get_win_stop();
866 const flwor_wincond::vars& condvars = cond->get_out_vars();
867
868- if (condvars.posvar != NULL) vars.insert(condvars.posvar);
869- if (condvars.curr != NULL) vars.insert(condvars.curr);
870- if (condvars.prev != NULL) vars.insert(condvars.prev);
871- if (condvars.next != NULL) vars.insert(condvars.next);
872+ if (condvars.posvar != NULL) vars.push_back(condvars.posvar);
873+ if (condvars.curr != NULL) vars.push_back(condvars.curr);
874+ if (condvars.prev != NULL) vars.push_back(condvars.prev);
875+ if (condvars.next != NULL) vars.push_back(condvars.next);
876 }
877
878 break;
879 }
880- case flwor_clause::group_clause:
881+ case flwor_clause::groupby_clause:
882 {
883- const group_clause* gc = static_cast<const group_clause *>(&c);
884+ const groupby_clause* gc = static_cast<const groupby_clause *>(&c);
885
886 flwor_clause::rebind_list_t::const_iterator ite = gc->beginGroupVars();
887 flwor_clause::rebind_list_t::const_iterator end = gc->endGroupVars();
888
889 for (; ite != end; ++ite)
890 {
891- vars.insert((*ite).second);
892+ vars.push_back((*ite).second);
893 }
894
895 ite = gc->beginNonGroupVars();
896@@ -1085,7 +1092,7 @@
897
898 for (; ite != end; ++ite)
899 {
900- vars.insert((*ite).second);
901+ vars.push_back((*ite).second);
902 }
903
904 break;
905@@ -1093,7 +1100,7 @@
906 case flwor_clause::count_clause:
907 {
908 const count_clause* cc = static_cast<const count_clause *>(&c);
909- vars.insert(cc->get_var());
910+ vars.push_back(cc->get_var());
911 break;
912 }
913 default:
914
915=== modified file 'src/compiler/expression/flwor_expr.h'
916--- src/compiler/expression/flwor_expr.h 2012-10-29 11:41:36 +0000
917+++ src/compiler/expression/flwor_expr.h 2013-01-29 17:56:25 +0000
918@@ -55,7 +55,7 @@
919 for_clause,
920 let_clause,
921 window_clause,
922- group_clause,
923+ groupby_clause,
924 order_clause,
925 count_clause,
926 where_clause,
927@@ -242,15 +242,15 @@
928
929 protected:
930 window_clause(
931- static_context* sctx,
932- CompilerCB* ccb,
933- const QueryLoc& loc,
934- WindowKind winKind,
935- var_expr* varExpr,
936- expr* domainExpr,
937- flwor_wincond* winStart,
938- flwor_wincond* winStop,
939- bool lazy = false);
940+ static_context* sctx,
941+ CompilerCB* ccb,
942+ const QueryLoc& loc,
943+ WindowKind winKind,
944+ var_expr* varExpr,
945+ expr* domainExpr,
946+ flwor_wincond* winStart,
947+ flwor_wincond* winStop,
948+ bool lazy = false);
949
950 public:
951 ~window_clause();
952@@ -405,7 +405,7 @@
953 the Y values in the input tuples that were grouped into T.
954 theCollations : The collations to use when comparing values for grouping.
955 ********************************************************************************/
956-class group_clause : public flwor_clause
957+class groupby_clause : public flwor_clause
958 {
959 friend class expr;
960 friend class flwor_expr;
961@@ -417,7 +417,7 @@
962 rebind_list_t theNonGroupVars;
963 std::vector<std::string> theCollations;
964
965- group_clause(
966+ groupby_clause(
967 static_context* sctx,
968 CompilerCB* ccb,
969 const QueryLoc& loc,
970@@ -426,7 +426,7 @@
971 const std::vector<std::string>& collations);
972
973 public:
974- ~group_clause();
975+ ~groupby_clause();
976
977 const std::vector<std::string>& get_collations() const { return theCollations; }
978
979@@ -515,6 +515,10 @@
980
981 const std::vector<OrderModifier>& get_modifiers() const { return theModifiers; }
982
983+ bool is_ascending(csize i) const { return theModifiers[i].theAscending; }
984+
985+ const std::string& get_collation(csize i) const { return theModifiers[i].theCollation; }
986+
987 const std::vector<expr*>& get_column_exprs() const { return theOrderingExprs; }
988
989 std::vector<expr*>::iterator begin() { return theOrderingExprs.begin(); }
990@@ -648,7 +652,6 @@
991 typedef std::vector<flwor_clause*> clause_list_t;
992
993 protected:
994- bool theIsGeneral;
995 bool theHasSequentialClauses;
996 clause_list_t theClauses;
997 expr * theReturnExpr;
998@@ -662,9 +665,9 @@
999 bool general);
1000
1001 public:
1002- bool is_general() const { return theIsGeneral; }
1003+ bool is_general() const { return get_expr_kind() == gflwor_expr_kind; }
1004
1005- void set_general(bool v) { theIsGeneral = true; }
1006+ void set_general(bool v) { theKind = (v ? gflwor_expr_kind : flwor_expr_kind); }
1007
1008 expr* get_return_expr() const { return theReturnExpr; }
1009
1010@@ -698,14 +701,14 @@
1011
1012 long defines_variable(const var_expr* v) const;
1013
1014- void get_vars(expr::FreeVars& vars) const;
1015+ void get_vars(std::vector<var_expr*>& vars) const;
1016
1017 // The following 5 methods are for the simple flwor only. They should be
1018 // removed eventually.
1019 expr* get_where() const;
1020 void set_where(expr* e);
1021 void remove_where_clause();
1022- group_clause* get_group_clause() const;
1023+ groupby_clause* get_group_clause() const;
1024 orderby_clause* get_order_clause() const;
1025 csize num_forlet_clauses();
1026
1027
1028=== modified file 'src/compiler/expression/path_expr.cpp'
1029--- src/compiler/expression/path_expr.cpp 2012-10-09 14:06:08 +0000
1030+++ src/compiler/expression/path_expr.cpp 2013-01-29 17:56:25 +0000
1031@@ -208,6 +208,99 @@
1032 }
1033
1034
1035+bool match_expr::matches(const match_expr* other) const
1036+{
1037+ if (theTestKind != other->theTestKind)
1038+ return false;
1039+
1040+ switch (theTestKind)
1041+ {
1042+ case match_name_test:
1043+ {
1044+ if (getWildKind() != other->getWildKind())
1045+ return false;
1046+
1047+ if (getWildName() != other->getWildName())
1048+ return false;
1049+
1050+ if (getWildKind() == match_no_wild || getWildKind() == match_name_wild)
1051+ {
1052+ return getQName()->equals(other->getQName());
1053+ }
1054+
1055+ return true;
1056+ }
1057+ case match_anykind_test:
1058+ case match_text_test:
1059+ case match_comment_test:
1060+ {
1061+ return true;
1062+ }
1063+ case match_pi_test:
1064+ {
1065+ if (theQName == NULL && other->theQName == NULL)
1066+ return true;
1067+
1068+ if (theQName == NULL || other->theQName == NULL)
1069+ return false;
1070+
1071+ return theQName->equals(other->theQName);
1072+ }
1073+ case match_doc_test:
1074+ {
1075+ if (theDocTestKind != other->theDocTestKind)
1076+ return false;
1077+
1078+ if (theDocTestKind == match_xs_elem_test)
1079+ goto schema_test;
1080+
1081+ // else fall through
1082+ }
1083+ case match_elem_test:
1084+ case match_attr_test:
1085+ {
1086+ if (theQName == NULL || other->theQName == NULL)
1087+ {
1088+ if (theQName != NULL || other->theQName != NULL)
1089+ return false;
1090+ }
1091+ else if (!theQName->equals(other->theQName))
1092+ {
1093+ return false;
1094+ }
1095+
1096+ if (theTypeName == NULL || other->theTypeName == NULL)
1097+ {
1098+ if (theTypeName != NULL || other->theTypeName != NULL)
1099+ return false;
1100+ }
1101+ else if (!theTypeName->equals(other->theTypeName))
1102+ {
1103+ return false;
1104+ }
1105+
1106+ if (theNilledAllowed != other->theNilledAllowed)
1107+ return false;
1108+
1109+ return true;
1110+ }
1111+ case match_xs_elem_test:
1112+ case match_xs_attr_test:
1113+ {
1114+schema_test:
1115+ return (theQName->equals(other->theQName) &&
1116+ theTypeName->equals(other->theTypeName));
1117+ }
1118+ default:
1119+ {
1120+ ZORBA_ASSERT(false);
1121+ }
1122+ }
1123+
1124+ return false;
1125+}
1126+
1127+
1128 }
1129
1130 /* vim:set et sw=2 ts=2: */
1131
1132=== modified file 'src/compiler/expression/path_expr.h'
1133--- src/compiler/expression/path_expr.h 2012-10-09 14:06:08 +0000
1134+++ src/compiler/expression/path_expr.h 2013-01-29 17:56:25 +0000
1135@@ -159,9 +159,25 @@
1136 PITest | CommentTest | TextTest | AnyKindTest
1137
1138 If a match_expr represents a KindTest, then theWildKind and theWildName data
1139- members are not used. If a match_expr represents a NameTest, then theTypeName
1140- and theNilledAllowed data members are not used.
1141-
1142+ members are not used.
1143+
1144+ If a match_expr represents a NameTest, then theTypeName and theNilledAllowed
1145+ data members are not used. In this case, theWildKind is used to distinguish
1146+ among 4 subcases:
1147+
1148+ 1. no wildcard:
1149+ theQName holds the expanded qname to match against an element or attribute
1150+ node. theWildName is not used.
1151+
1152+ 2. full wildcard (*):
1153+ Neither theQName nor theWildName are used.
1154+
1155+ 3. localname wildcard (pre:*):
1156+ theQName holds an artificial qname: "ns:wildcard", where ns is the URI
1157+ associated with pre. theWildName holds the pre.
1158+
1159+ 4. prefix wildcard (*:name):
1160+ theQName is not used and theWildName holds the local name.
1161 ********************************************************************************/
1162 class match_expr : public expr
1163 {
1164@@ -177,6 +193,7 @@
1165 zstring theWildName;
1166
1167 store::Item_t theQName;
1168+
1169 store::Item_t theTypeName;
1170 bool theNilledAllowed;
1171
1172@@ -202,8 +219,7 @@
1173
1174 const zstring& getWildName() const { return theWildName; }
1175
1176- template<class StringType>
1177- void setWildName(const StringType& v) { theWildName = v; }
1178+ void setWildName(const zstring& v) { theWildName = v; }
1179
1180 store::Item* getQName() const { return theQName.getp(); }
1181
1182@@ -221,6 +237,8 @@
1183
1184 void compute_scripting_kind();
1185
1186+ bool matches(const match_expr* other) const;
1187+
1188 void accept(expr_visitor&);
1189
1190 std::ostream& put(std::ostream&) const;
1191
1192=== modified file 'src/compiler/expression/var_expr.cpp'
1193--- src/compiler/expression/var_expr.cpp 2012-12-06 22:49:35 +0000
1194+++ src/compiler/expression/var_expr.cpp 2013-01-29 17:56:25 +0000
1195@@ -255,12 +255,12 @@
1196 }
1197 else if (theVarKind == groupby_var)
1198 {
1199- return reinterpret_cast<group_clause*>(theFlworClause)->
1200+ return reinterpret_cast<groupby_clause*>(theFlworClause)->
1201 get_input_for_group_var(this);
1202 }
1203 else if (theVarKind == non_groupby_var)
1204 {
1205- return reinterpret_cast<group_clause*>(theFlworClause)->
1206+ return reinterpret_cast<groupby_clause*>(theFlworClause)->
1207 get_input_for_nongroup_var(this);
1208 }
1209 }
1210
1211=== modified file 'src/compiler/expression/var_expr.h'
1212--- src/compiler/expression/var_expr.h 2012-12-06 22:49:35 +0000
1213+++ src/compiler/expression/var_expr.h 2013-01-29 17:56:25 +0000
1214@@ -88,8 +88,8 @@
1215
1216 theParamPos:
1217 ------------
1218- For arg vars, it is the position, within the param list, of parameter that is
1219- bound to this arg var.
1220+ For arg vars, it is the position, within the param list, of the parameter that
1221+ is bound to this arg var.
1222
1223 theSetExprs:
1224 ------------
1225@@ -129,8 +129,8 @@
1226 for_var,
1227 let_var,
1228 pos_var,
1229+ score_var,
1230 win_var,
1231- score_var,
1232 wincond_out_var,
1233 wincond_out_pos_var,
1234 wincond_in_var,
1235
1236=== modified file 'src/compiler/rewriter/rewriters/default_optimizer.cpp'
1237--- src/compiler/rewriter/rewriters/default_optimizer.cpp 2012-10-26 18:24:00 +0000
1238+++ src/compiler/rewriter/rewriters/default_optimizer.cpp 2013-01-29 17:56:25 +0000
1239@@ -17,9 +17,12 @@
1240
1241 #include "compiler/rewriter/framework/rule_driver.h"
1242 #include "compiler/rewriter/rules/ruleset.h"
1243+#include "compiler/rewriter/rules/fold_rules.h"
1244+#include "compiler/rewriter/rules/index_matching_rule.h"
1245 #include "compiler/rewriter/rewriters/common_rewriter.h"
1246 #include "compiler/rewriter/rewriters/default_optimizer.h"
1247 #include "compiler/rewriter/tools/expr_tools.h"
1248+#include "compiler/xqddf/value_index.h"
1249 //#include "compiler/rewriter/tools/udf_graph.h"
1250 #include "compiler/api/compilercb.h"
1251
1252@@ -27,25 +30,14 @@
1253
1254 #include "system/properties.h"
1255
1256+#include "context/static_context.h"
1257+
1258+//#include "store/api/store.h"
1259+
1260
1261 namespace zorba
1262 {
1263
1264-class FoldRules : public RuleMajorDriver
1265-{
1266-public:
1267- FoldRules()
1268- {
1269- ADD_RULE(MarkExprs);
1270- ADD_RULE(MarkFreeVars);
1271- ADD_RULE(FoldConst);
1272- ADD_RULE(PartialEval);
1273- ADD_RULE(RefactorPredFLWOR);
1274- ADD_RULE(EliminateUnusedLetVars);
1275- ADD_RULE(MergeFLWOR);
1276- }
1277-};
1278-
1279
1280 DefaultOptimizer::DefaultOptimizer()
1281 {
1282@@ -183,6 +175,53 @@
1283 }
1284 }
1285
1286+ // index matching
1287+ if (Properties::instance()->useIndexes())
1288+ {
1289+ static_context* sctx = rCtx.theRoot->get_sctx();
1290+
1291+ std::vector<IndexDecl*> indexDecls;
1292+ sctx->get_index_decls(indexDecls);
1293+
1294+ if (!indexDecls.empty())
1295+ {
1296+ MarkFreeVars freeVarsRule;
1297+ bool modified;
1298+ freeVarsRule.apply(rCtx, rCtx.theRoot, modified);
1299+ }
1300+
1301+ std::vector<IndexDecl*>::const_iterator ite = indexDecls.begin();
1302+ std::vector<IndexDecl*>::const_iterator end = indexDecls.end();
1303+ for (; ite != end; ++ite)
1304+ {
1305+ bool local_modified = false;
1306+
1307+ //store::Index* idx = GENV_STORE.getIndex((*ite)->getName());
1308+
1309+ //if (idx != NULL)
1310+ if (!(*ite)->isTemp())
1311+ {
1312+ IndexMatchingRule rule(*ite);
1313+
1314+ expr* e = rule.apply(rCtx, rCtx.getRoot(), local_modified);
1315+
1316+ if (e != rCtx.getRoot())
1317+ rCtx.setRoot(e);
1318+ }
1319+
1320+ if (local_modified)
1321+ {
1322+ if (Properties::instance()->printIntermediateOpt())
1323+ {
1324+ std::cout << "After index matching : " << std::endl;
1325+ rCtx.getRoot()->put(std::cout) << std::endl;
1326+ }
1327+
1328+ modified = true;
1329+ }
1330+ }
1331+ }
1332+
1333 // Index Joins
1334 if (Properties::instance()->inferJoins())
1335 {
1336
1337=== modified file 'src/compiler/rewriter/rules/CMakeLists.txt'
1338--- src/compiler/rewriter/rules/CMakeLists.txt 2012-09-19 21:16:15 +0000
1339+++ src/compiler/rewriter/rules/CMakeLists.txt 2013-01-29 17:56:25 +0000
1340@@ -21,4 +21,5 @@
1341 path_rules.cpp
1342 hoist_rules.cpp
1343 index_join_rule.cpp
1344+ index_matching_rule.cpp
1345 )
1346
1347=== modified file 'src/compiler/rewriter/rules/flwor_rules.cpp'
1348--- src/compiler/rewriter/rules/flwor_rules.cpp 2012-12-21 05:13:20 +0000
1349+++ src/compiler/rewriter/rules/flwor_rules.cpp 2013-01-29 17:56:25 +0000
1350@@ -229,9 +229,9 @@
1351
1352 switch (c->get_kind())
1353 {
1354- case flwor_clause::group_clause:
1355+ case flwor_clause::groupby_clause:
1356 {
1357- group_clause* gc = static_cast<group_clause *>(c);
1358+ groupby_clause* gc = static_cast<groupby_clause *>(c);
1359
1360 flwor_clause::rebind_list_t::iterator ite = gc->beginNonGroupVars();
1361 flwor_clause::rebind_list_t::iterator end = gc->endNonGroupVars();
1362@@ -370,9 +370,9 @@
1363 {
1364 break;
1365 }
1366- else if (clause->get_kind() == flwor_clause::group_clause)
1367+ else if (clause->get_kind() == flwor_clause::groupby_clause)
1368 {
1369- group_clause* gc = static_cast<group_clause*>(clause);
1370+ groupby_clause* gc = static_cast<groupby_clause*>(clause);
1371
1372 const flwor_clause::rebind_list_t& gVars = gc->get_grouping_vars();
1373
1374@@ -697,9 +697,9 @@
1375
1376 break;
1377 }
1378- case flwor_clause::group_clause:
1379+ case flwor_clause::groupby_clause:
1380 {
1381- group_clause* cl = static_cast<group_clause*>(clause);
1382+ groupby_clause* cl = static_cast<groupby_clause*>(clause);
1383
1384 csize numExprs = cl->numGroupingVars();
1385
1386@@ -1491,7 +1491,7 @@
1387 {
1388 checkClause = flworExpr->get_clause(checkClausePos);
1389
1390- if (checkClause->get_kind() == flwor_clause::group_clause ||
1391+ if (checkClause->get_kind() == flwor_clause::groupby_clause ||
1392 (checkClause->get_kind() == flwor_clause::count_clause && eq))
1393 return false;
1394
1395@@ -1587,7 +1587,7 @@
1396 const flwor_clause* c = flwor->get_clause(i);
1397
1398 if (c->get_kind() == flwor_clause::where_clause ||
1399- c->get_kind() == flwor_clause::group_clause ||
1400+ c->get_kind() == flwor_clause::groupby_clause ||
1401 c->get_kind() == flwor_clause::order_clause)
1402 {
1403 goto next1;
1404@@ -1601,7 +1601,7 @@
1405 {
1406 const flwor_clause* c = returnFlwor->get_clause(i);
1407
1408- if (c->get_kind() == flwor_clause::group_clause ||
1409+ if (c->get_kind() == flwor_clause::groupby_clause ||
1410 c->get_kind() == flwor_clause::order_clause)
1411 {
1412 goto next1;
1413@@ -1651,7 +1651,7 @@
1414 if (nestedClauseKind == flwor_clause::for_clause)
1415 {
1416 xqtref_t nestedDomainType =
1417- static_cast<for_clause*>(nestedClause)->get_expr()->get_return_type();
1418+ static_cast<for_clause*>(nestedClause)->get_expr()->get_return_type();
1419
1420 if (nestedDomainType->get_quantifier() != TypeConstants::QUANT_ONE)
1421 {
1422@@ -1685,18 +1685,9 @@
1423 flwor_clause::ClauseKind nestedClauseKind = nestedClause->get_kind();
1424
1425 if (nestedClauseKind != flwor_clause::let_clause &&
1426- nestedClauseKind != flwor_clause::for_clause)
1427+ nestedClauseKind != flwor_clause::for_clause &&
1428+ nestedClauseKind != flwor_clause::where_clause)
1429 {
1430-#if 1
1431- // temp hack until we have an optimized general flwor
1432- if (nestedClauseKind == flwor_clause::where_clause &&
1433- i == numClauses-1 &&
1434- flwor->get_where() == NULL &&
1435- nestedFlwor->get_return_expr()->get_var() != NULL)
1436- {
1437- continue;
1438- }
1439-#endif
1440 merge = false;
1441 break;
1442 }
1443@@ -1709,12 +1700,14 @@
1444 for (csize j = 0; j < numNestedClauses; ++j)
1445 {
1446 flwor_clause* nestedClause = nestedFlwor->get_clause(j);
1447-#if 1
1448- if (nestedClause->get_kind() == flwor_clause::where_clause)
1449- flwor->add_clause(i+j+1, nestedClause);
1450- else
1451-#endif
1452- flwor->add_clause(i+j, nestedClause);
1453+ flwor->add_clause(i+j, nestedClause);
1454+
1455+ if (!flwor->is_general() &&
1456+ nestedClause->get_kind() == flwor_clause::where_clause &&
1457+ i != numClauses - 1)
1458+ {
1459+ flwor->set_general(true);
1460+ }
1461 }
1462
1463 c->set_expr(nestedFlwor->get_return_expr());
1464
1465=== added file 'src/compiler/rewriter/rules/fold_rules.h'
1466--- src/compiler/rewriter/rules/fold_rules.h 1970-01-01 00:00:00 +0000
1467+++ src/compiler/rewriter/rules/fold_rules.h 2013-01-29 17:56:25 +0000
1468@@ -0,0 +1,49 @@
1469+/*
1470+ * Copyright 2006-2008 The FLWOR Foundation.
1471+ *
1472+ * Licensed under the Apache License, Version 2.0 (the "License");
1473+ * you may not use this file except in compliance with the License.
1474+ * You may obtain a copy of the License at
1475+ *
1476+ * http://www.apache.org/licenses/LICENSE-2.0
1477+ *
1478+ * Unless required by applicable law or agreed to in writing, software
1479+ * distributed under the License is distributed on an "AS IS" BASIS,
1480+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1481+ * See the License for the specific language governing permissions and
1482+ * limitations under the License.
1483+ */
1484+#pragma once
1485+#ifndef ZORBA_COMPILER_REWRITER_FOLD_RULES
1486+#define ZORBA_COMPILER_REWRITER_FOLD_RULES
1487+
1488+#include "stdafx.h"
1489+
1490+#include "compiler/rewriter/framework/rule_driver.h"
1491+#include "compiler/rewriter/rewriters/common_rewriter.h"
1492+#include "compiler/rewriter/rules/ruleset.h"
1493+
1494+
1495+namespace zorba
1496+{
1497+
1498+class FoldRules : public RuleMajorDriver
1499+{
1500+public:
1501+ FoldRules()
1502+ {
1503+ ADD_RULE(MarkExprs);
1504+ ADD_RULE(MarkFreeVars);
1505+ ADD_RULE(FoldConst);
1506+ ADD_RULE(PartialEval);
1507+ ADD_RULE(RefactorPredFLWOR);
1508+ ADD_RULE(EliminateUnusedLetVars);
1509+ ADD_RULE(MergeFLWOR);
1510+ }
1511+};
1512+
1513+
1514+}
1515+
1516+#endif
1517+/* vim:set et sw=2 ts=2: */
1518
1519=== modified file 'src/compiler/rewriter/rules/hoist_rules.cpp'
1520--- src/compiler/rewriter/rules/hoist_rules.cpp 2012-12-06 22:49:35 +0000
1521+++ src/compiler/rewriter/rules/hoist_rules.cpp 2013-01-29 17:56:25 +0000
1522@@ -408,7 +408,7 @@
1523 assert(step->theExpr->get_expr_kind() == flwor_expr_kind);
1524
1525 flwor_expr* flwor = static_cast<flwor_expr*>(step->theExpr);
1526- group_clause* gc = flwor->get_group_clause();
1527+ groupby_clause* gc = flwor->get_group_clause();
1528
1529 // If any free variable is a group-by variable, give up.
1530 if (gc != NULL)
1531
1532=== modified file 'src/compiler/rewriter/rules/index_join_rule.cpp'
1533--- src/compiler/rewriter/rules/index_join_rule.cpp 2012-12-06 22:49:35 +0000
1534+++ src/compiler/rewriter/rules/index_join_rule.cpp 2013-01-29 17:56:25 +0000
1535@@ -702,7 +702,7 @@
1536
1537 sctx->bind_index(idx, loc);
1538
1539- buildExpr = idx->getBuildExpr(rCtx.getCompilerCB(), loc);
1540+ buildExpr = idx->getBuildExpr(loc);
1541
1542 createExpr->set_arg(1, buildExpr);
1543
1544
1545=== added file 'src/compiler/rewriter/rules/index_matching_rule.cpp'
1546--- src/compiler/rewriter/rules/index_matching_rule.cpp 1970-01-01 00:00:00 +0000
1547+++ src/compiler/rewriter/rules/index_matching_rule.cpp 2013-01-29 17:56:25 +0000
1548@@ -0,0 +1,1064 @@
1549+
1550+
1551+/*
1552+ * Copyright 2006-2008 The FLWOR Foundation.
1553+ *
1554+ * Licensed under the Apache License, Version 2.0 (the "License");
1555+ * you may not use this file except in compliance with the License.
1556+ * You may obtain a copy of the License at
1557+ *
1558+ * http://www.apache.org/licenses/LICENSE-2.0
1559+ *
1560+ * Unless required by applicable law or agreed to in writing, software
1561+ * distributed under the License is distributed on an "AS IS" BASIS,
1562+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1563+ * See the License for the specific language governing permissions and
1564+ * limitations under the License.
1565+ */
1566+#include "stdafx.h"
1567+
1568+
1569+#include "compiler/expression/expr.h"
1570+#include "compiler/expression/expr_iter.h"
1571+
1572+#include "compiler/xqddf/value_index.h"
1573+#include "compiler/xqddf/collection_decl.h"
1574+
1575+#include "compiler/rewriter/rules/index_matching_rule.h"
1576+#include "compiler/rewriter/rules/fold_rules.h"
1577+#include "compiler/rewriter/tools/expr_tools.h"
1578+
1579+#include "compiler/api/compilercb.h"
1580+
1581+#include "functions/function.h"
1582+#include "functions/library.h"
1583+
1584+#include "types/typeops.h"
1585+
1586+#include "util/dynamic_bitset.h"
1587+
1588+#include "diagnostics/assert.h"
1589+
1590+#include "system/properties.h"
1591+
1592+
1593+namespace zorba
1594+{
1595+
1596+
1597+/*******************************************************************************
1598+
1599+********************************************************************************/
1600+IndexMatchingRule::PredInfo::PredInfo(
1601+ where_clause* wc,
1602+ csize wcPos,
1603+ fo_expr* andExpr,
1604+ csize argPos)
1605+ :
1606+ theClause(wc),
1607+ theClausePos(wcPos),
1608+ theAndExpr(andExpr),
1609+ theArgPos(argPos)
1610+{
1611+ if (theAndExpr)
1612+ {
1613+ assert(theAndExpr->get_func()->getKind() == FunctionConsts::OP_AND_N);
1614+
1615+ theExpr = theAndExpr->get_arg(theArgPos);
1616+ }
1617+ else
1618+ {
1619+ theExpr = theClause->get_expr();
1620+ }
1621+}
1622+
1623+
1624+/*******************************************************************************
1625+
1626+********************************************************************************/
1627+IndexMatchingRule::IndexMatchingRule(IndexDecl* decl)
1628+ :
1629+ RewriteRule(RewriteRule::IndexJoin, "IndexJoin"),
1630+ theIndexDecl(decl),
1631+ theViewExpr(NULL),
1632+ theDoTrace(true)
1633+{
1634+ theViewExpr = decl->getViewExpr();
1635+
1636+ csize numVClauses = theViewExpr->num_clauses();
1637+
1638+ theKeyClauses.reserve(numVClauses);
1639+
1640+ for (csize i = 1; i < numVClauses; ++i)
1641+ {
1642+ assert(theViewExpr->get_clause(i)->get_kind() == flwor_clause::let_clause);
1643+ let_clause* lc = static_cast<let_clause*>(theViewExpr->get_clause(i));
1644+ theKeyClauses.push_back(lc);
1645+ }
1646+
1647+ std::ostringstream msg;
1648+ msg << "normalization of candidate index: " << decl->getName()->getStringValue();
1649+
1650+ RewriterContext rCtx(theViewExpr->get_ccb(),
1651+ theViewExpr,
1652+ theViewExpr->get_udf(),
1653+ msg.str(),
1654+ true);
1655+ FoldRules foldRules;
1656+ foldRules.rewrite(rCtx);
1657+
1658+ if (Properties::instance()->printIntermediateOpt() && theDoTrace)
1659+ {
1660+ std::cout << "Canonical view expr for candidate index : "
1661+ << decl->getName()->getStringValue() << std::endl;
1662+ rCtx.getRoot()->put(std::cout) << std::endl;
1663+ }
1664+}
1665+
1666+
1667+/*******************************************************************************
1668+
1669+********************************************************************************/
1670+expr* IndexMatchingRule::apply(RewriterContext& rCtx, expr* node, bool& modified)
1671+{
1672+ modified = false;
1673+
1674+ // TODO remove this
1675+ if (theIndexDecl->isGeneral())
1676+ return node;
1677+
1678+ if (node->get_expr_kind() == flwor_expr_kind ||
1679+ node->get_expr_kind() == gflwor_expr_kind)
1680+ {
1681+ theQueryExpr = static_cast<flwor_expr*>(node);
1682+
1683+ bool matched = matchIndex();
1684+
1685+ if (matched)
1686+ modified = true;
1687+ }
1688+
1689+ ExprIterator iter(node);
1690+ while (!iter.done())
1691+ {
1692+ expr* currChild = **iter;
1693+
1694+ bool childModified = false;
1695+
1696+ expr* newChild = apply(rCtx, currChild, childModified);
1697+
1698+ ZORBA_ASSERT(currChild == newChild);
1699+
1700+ if (childModified)
1701+ modified = true;
1702+
1703+ iter.next();
1704+ }
1705+
1706+ return node;
1707+}
1708+
1709+
1710+/*******************************************************************************
1711+ Match a flwor expr with an index
1712+********************************************************************************/
1713+bool IndexMatchingRule::matchIndex()
1714+{
1715+ CompilerCB* ccb = theQueryExpr->get_ccb();
1716+ static_context* sctx = theQueryExpr->get_sctx();
1717+ user_function* udf = theQueryExpr->get_udf();
1718+
1719+ csize numVClauses = theViewExpr->num_clauses();
1720+ csize numQClauses = theQueryExpr->num_clauses();
1721+ csize nextQueryClause = 0;
1722+
1723+ theUnmatchedQPreds.clear();
1724+ theMatchedQPreds.clear();
1725+ theProbeArgs.clear();
1726+ theProbeArgs.reserve(theKeyClauses.size() + 1);
1727+
1728+ expr::substitution_t subst;
1729+
1730+ for_clause* firstMatchedFOR = NULL;
1731+ csize firstMatchedFORpos = 0;
1732+ csize lastMatchedFORpos = 0;
1733+ csize lastMatchedWHEREpos = 0;
1734+ csize firstOrderByPos = 0;
1735+ DynamicBitset matchedClauses(numQClauses);
1736+ matchedClauses.reset();
1737+
1738+ std::vector<PredInfo> vpreds;
1739+
1740+ // Match the FOR and WHERE clauses of the view FLWOR. For now, we can match
1741+ // only indexes whose domain and key expressions consist of FOR, LET, and
1742+ // WHERE clauses only.
1743+ for (csize vi = 0; vi < numVClauses; ++vi)
1744+ {
1745+ flwor_clause* vc = theViewExpr->get_clause(vi);
1746+
1747+ switch (vc->get_kind())
1748+ {
1749+ case flwor_clause::for_clause:
1750+ {
1751+ for_clause* vfc = static_cast<for_clause*>(vc);
1752+ expr* vdomExpr = vfc->get_expr();
1753+ var_expr* vvarExpr = vfc->get_var();
1754+
1755+ bool matched = false;
1756+
1757+ for (csize qi = nextQueryClause; qi < numQClauses && !matched; ++qi)
1758+ {
1759+ flwor_clause* qc = theQueryExpr->get_clause(qi);
1760+
1761+ switch (qc->get_kind())
1762+ {
1763+ case flwor_clause::for_clause:
1764+ {
1765+ for_clause* qfc = static_cast<for_clause*>(qc);
1766+ expr* qdomExpr = qfc->get_expr();
1767+ var_expr* qvarExpr = qfc->get_var();
1768+
1769+ if (!qfc->is_allowing_empty() &&
1770+ expr_tools::match_exact(qdomExpr, vdomExpr, subst))
1771+ {
1772+ nextQueryClause = qi+1;
1773+ subst[vvarExpr] = qvarExpr;
1774+ matchedClauses.set(qi, true);
1775+
1776+ if (firstMatchedFOR == NULL)
1777+ {
1778+ firstMatchedFOR = qfc;
1779+ firstMatchedFORpos = qi;
1780+ }
1781+
1782+ lastMatchedFORpos = qi;
1783+ matched = true;
1784+ break;
1785+ }
1786+ else if (firstMatchedFOR != NULL)
1787+ {
1788+ // TODO allow for FOR clause reordering, if conditions allow it
1789+ return false;
1790+ }
1791+
1792+ break;
1793+ }
1794+ case flwor_clause::let_clause:
1795+ {
1796+ if (firstMatchedFOR != NULL)
1797+ {
1798+ let_clause* qlc = static_cast<let_clause*>(qc);
1799+ expr* qdomExpr = qlc->get_expr();
1800+
1801+ if (qdomExpr->is_sequential())
1802+ return false;
1803+ }
1804+ break;
1805+ }
1806+ case flwor_clause::window_clause:
1807+ case flwor_clause::order_clause:
1808+ {
1809+ if (firstMatchedFOR != NULL)
1810+ {
1811+ // TODO allow for FOR clause reordering, if conditions allow it
1812+ return false; // todo
1813+ }
1814+
1815+ break;
1816+ }
1817+ case flwor_clause::where_clause:
1818+ {
1819+ getWherePreds(qi, static_cast<where_clause*>(qc), theUnmatchedQPreds);
1820+ break;
1821+ }
1822+ case flwor_clause::count_clause:
1823+ case flwor_clause::groupby_clause:
1824+ case flwor_clause::materialize_clause:
1825+ {
1826+ if (firstMatchedFOR != NULL)
1827+ return false;
1828+
1829+ break;
1830+ }
1831+ default:
1832+ ZORBA_ASSERT(false);
1833+ }
1834+ }
1835+
1836+ if (!matched)
1837+ return false;
1838+
1839+ break;
1840+ }
1841+ case flwor_clause::let_clause:
1842+ {
1843+ break;
1844+ }
1845+ case flwor_clause::where_clause:
1846+ {
1847+ where_clause* vwc = static_cast<where_clause*>(vc);
1848+ getWherePreds(vi, vwc, vpreds);
1849+
1850+ break;
1851+ }
1852+ default:
1853+ {
1854+ assert(false);
1855+ return false;
1856+ }
1857+ }
1858+ }
1859+
1860+ // Collect the rest of the query preds, if any, as well as the first orderby
1861+ for (csize qi = nextQueryClause; qi < numQClauses; ++qi)
1862+ {
1863+ flwor_clause* qc = theQueryExpr->get_clause(qi);
1864+
1865+ switch (qc->get_kind())
1866+ {
1867+ case flwor_clause::where_clause:
1868+ {
1869+ getWherePreds(qi, static_cast<where_clause*>(qc), theUnmatchedQPreds);
1870+ break;
1871+ }
1872+ case flwor_clause::order_clause:
1873+ {
1874+ if (firstOrderByPos == 0)
1875+ firstOrderByPos = qi;
1876+
1877+ break;
1878+ }
1879+ default:
1880+ break;
1881+ }
1882+ }
1883+
1884+ // Find a match for each index predicate
1885+ std::vector<PredInfo>::iterator vpredIte = vpreds.begin();
1886+ std::vector<PredInfo>::iterator vpredEnd = vpreds.end();
1887+
1888+ for (; vpredIte != vpredEnd; ++vpredIte)
1889+ {
1890+ expr* vpredExpr = vpredIte->theExpr;
1891+ bool matched = false;
1892+
1893+ std::vector<PredInfo>::iterator qpredIte = theUnmatchedQPreds.begin();
1894+ std::vector<PredInfo>::iterator qpredEnd = theUnmatchedQPreds.end();
1895+
1896+ for (; qpredIte != qpredEnd; ++qpredIte)
1897+ {
1898+ PredInfo& qpred = *qpredIte;
1899+ expr* qpredExpr = qpred.theExpr;
1900+
1901+ if (expr_tools::match_exact(qpredExpr, vpredExpr, subst))
1902+ {
1903+ matched = true;
1904+ theMatchedQPreds.push_back(qpred);
1905+ theUnmatchedQPreds.erase(qpredIte);
1906+
1907+ if (qpred.theClausePos > lastMatchedWHEREpos)
1908+ lastMatchedWHEREpos = qpred.theClausePos;
1909+
1910+ break;
1911+ }
1912+ }
1913+
1914+ if (!matched)
1915+ return false;
1916+ }
1917+
1918+ // Create the index-name expr and make it the 1st arg of the probe function
1919+ store::Item_t indexName = theIndexDecl->getName();
1920+
1921+ expr* qnameExpr = ccb->theEM->
1922+ create_const_expr(sctx, udf, firstMatchedFOR->get_loc(), indexName);
1923+
1924+ theProbeArgs.push_back(qnameExpr);
1925+
1926+ // Match the key exprs
1927+ if (theIndexDecl->isOrdered())
1928+ {
1929+ if (!matchKeyExprsForRangeIndex(subst, lastMatchedWHEREpos) &&
1930+ vpreds.empty())
1931+ return false;
1932+ }
1933+ else
1934+ {
1935+ if (!matchKeyExprsForEqIndex(subst, lastMatchedWHEREpos))
1936+ return false;
1937+ }
1938+
1939+ // Make sure thare are no "ilegal" query clauses between the last matched FOR
1940+ // clause and the last WHERE clause containing a matched pred.
1941+ for (csize i = lastMatchedFORpos + 1; i < lastMatchedWHEREpos; ++i)
1942+ {
1943+ flwor_clause* qc = theQueryExpr->get_clause(i);
1944+
1945+ switch (qc->get_kind())
1946+ {
1947+ case flwor_clause::for_clause:
1948+ case flwor_clause::let_clause:
1949+ case flwor_clause::window_clause:
1950+ {
1951+ forletwin_clause* qflwc = static_cast<forletwin_clause*>(qc);
1952+ expr* qdomExpr = qflwc->get_expr();
1953+
1954+ if (qdomExpr->is_sequential())
1955+ return false;
1956+
1957+ break;
1958+ }
1959+ case flwor_clause::count_clause:
1960+ case flwor_clause::groupby_clause:
1961+ case flwor_clause::materialize_clause:
1962+ {
1963+ return false;
1964+ }
1965+ case flwor_clause::where_clause:
1966+ case flwor_clause::order_clause:
1967+ {
1968+ break;
1969+ }
1970+ default:
1971+ ZORBA_ASSERT(false);
1972+ }
1973+ }
1974+
1975+ // Match orderby exprs, if any, with the index key exprs
1976+ if (theIndexDecl->isOrdered() && firstOrderByPos != 0)
1977+ {
1978+ orderby_clause* ob =
1979+ static_cast<orderby_clause*>(theQueryExpr->get_clause(firstOrderByPos));
1980+
1981+ csize numKeys = theKeyClauses.size();
1982+ csize numSortKeys = ob->num_columns();
1983+
1984+ if (numSortKeys <= numKeys)
1985+ {
1986+ csize i;
1987+ for (i = 0; i < numSortKeys; ++i)
1988+ {
1989+ if (!ob->is_ascending(i) ||
1990+ ob->get_collation(i) != theIndexDecl->getCollation(i))
1991+ break;
1992+
1993+ if (!matchKeyExpr(ob->get_column_expr(i),
1994+ theKeyClauses[i]->get_expr(),
1995+ subst))
1996+ break;
1997+ }
1998+
1999+ if (i == numSortKeys)
2000+ matchedClauses.set(firstOrderByPos, true);
2001+ }
2002+ }
2003+
2004+ // Mark the flwor vars of the query flwor expr as "not used" initially
2005+ std::vector<var_expr*> queryVars;
2006+ theQueryExpr->get_vars(queryVars);
2007+
2008+ for (csize i = 0; i < queryVars.size(); ++i)
2009+ {
2010+ queryVars[i]->setVisitId(0);
2011+ }
2012+
2013+ // Check for dependencies on query vars that will be eliminated by the rewrite
2014+ const var_expr* domVar = theViewExpr->get_return_expr()->get_var();
2015+ assert(domVar);
2016+ assert(subst[domVar]->get_expr_kind() == var_expr_kind);
2017+ domVar = static_cast<const var_expr*>(subst[domVar]);
2018+
2019+ for (csize i = 0; i < theUnmatchedQPreds.size(); ++i)
2020+ {
2021+ expr* pred = theUnmatchedQPreds[i].theExpr;
2022+ if (!checkFreeVars(pred, domVar, matchedClauses))
2023+ return false;
2024+ }
2025+
2026+ if (!checkFreeVars(theQueryExpr->get_return_expr(), domVar, matchedClauses))
2027+ return false;
2028+
2029+ for (csize i = numQClauses-1; i > 0; --i)
2030+ {
2031+ if (matchedClauses.get(i))
2032+ continue;
2033+
2034+ flwor_clause* c = theQueryExpr->get_clause(i);
2035+
2036+ switch (c->get_kind())
2037+ {
2038+ case flwor_clause::for_clause:
2039+ case flwor_clause::let_clause:
2040+ {
2041+ forlet_clause* flc = static_cast<forlet_clause*>(c);
2042+ var_expr* var = flc->get_var();
2043+ var_expr* posVar = flc->get_pos_var();
2044+
2045+ if (!var->isVisited(1) && (posVar == NULL || !posVar->isVisited(1)))
2046+ {
2047+ if (c->get_kind() == flwor_clause::let_clause)
2048+ matchedClauses.set(i, true);
2049+
2050+ continue;
2051+ }
2052+
2053+ if (!checkFreeVars(flc->get_expr(), domVar, matchedClauses))
2054+ return false;
2055+
2056+ break;
2057+ }
2058+ case flwor_clause::window_clause:
2059+ {
2060+ window_clause* wc = static_cast<window_clause*>(c);
2061+ var_expr* var = wc->get_var();
2062+ flwor_wincond* startCond = wc->get_win_start();
2063+ flwor_wincond* stopCond = wc->get_win_stop();
2064+
2065+ bool used = var->isVisited(1);
2066+
2067+ if (! used && startCond)
2068+ {
2069+ const flwor_wincond_vars& vars = startCond->get_out_vars();
2070+
2071+ if ((vars.posvar && vars.posvar->isVisited(1)) ||
2072+ (vars.curr && vars.curr->isVisited(1)) ||
2073+ (vars.prev && vars.prev->isVisited(1)) ||
2074+ (vars.next && vars.next->isVisited(1)))
2075+ used = true;
2076+ }
2077+
2078+ if (! used && stopCond)
2079+ {
2080+ const flwor_wincond_vars& vars = stopCond->get_out_vars();
2081+
2082+ if ((vars.posvar && vars.posvar->isVisited(1)) ||
2083+ (vars.curr && vars.curr->isVisited(1)) ||
2084+ (vars.prev && vars.prev->isVisited(1)) ||
2085+ (vars.next && vars.next->isVisited(1)))
2086+ used = true;
2087+ }
2088+
2089+ if (used)
2090+ {
2091+ if (!checkFreeVars(wc->get_expr(), domVar, matchedClauses))
2092+ return false;
2093+
2094+ if (startCond &&
2095+ !checkFreeVars(startCond->get_expr(), domVar, matchedClauses))
2096+ return false;
2097+
2098+ if (stopCond &&
2099+ !checkFreeVars(stopCond->get_expr(), domVar, matchedClauses))
2100+ return false;
2101+ }
2102+
2103+ break;
2104+ }
2105+ case flwor_clause::order_clause:
2106+ {
2107+ orderby_clause* oc = static_cast<orderby_clause*>(c);
2108+
2109+ std::vector<expr*>::const_iterator ite = oc->begin();
2110+ std::vector<expr*>::const_iterator end = oc->end();
2111+ for (; ite != end; ++ite)
2112+ {
2113+ if (!checkFreeVars(*ite, domVar, matchedClauses))
2114+ return false;
2115+ }
2116+
2117+ break;
2118+ }
2119+ case flwor_clause::groupby_clause:
2120+ {
2121+ groupby_clause* gc = static_cast<groupby_clause*>(c);
2122+
2123+ flwor_clause::rebind_list_t::const_iterator ite = gc->beginGroupVars();
2124+ flwor_clause::rebind_list_t::const_iterator end = gc->endGroupVars();
2125+ for (; ite != end; ++ite)
2126+ {
2127+ if (!checkFreeVars(ite->first, domVar, matchedClauses))
2128+ return false;
2129+ }
2130+
2131+ ite = gc->beginNonGroupVars();
2132+ end = gc->endNonGroupVars();
2133+ for (; ite != end; ++ite)
2134+ {
2135+ if (!checkFreeVars(ite->first, domVar, matchedClauses))
2136+ return false;
2137+ }
2138+
2139+ break;
2140+ }
2141+ case flwor_clause::count_clause:
2142+ case flwor_clause::where_clause:
2143+ case flwor_clause::materialize_clause:
2144+ {
2145+ break;
2146+ }
2147+ default:
2148+ {
2149+ ZORBA_ASSERT(false);
2150+ }
2151+ }
2152+ }
2153+
2154+ // Do the rewrite
2155+ for (csize i = 0; i < theMatchedQPreds.size(); ++i)
2156+ {
2157+ PredInfo& pred = theMatchedQPreds[i];
2158+
2159+ if (pred.theAndExpr != NULL)
2160+ {
2161+ fo_expr* andExpr = pred.theAndExpr;
2162+
2163+ pred.theAndExpr->remove_arg(pred.theArgPos);
2164+
2165+ csize j = i+1;
2166+ while (j < theMatchedQPreds.size() &&
2167+ theMatchedQPreds[j].theAndExpr == andExpr)
2168+ {
2169+ if (theMatchedQPreds[j].theArgPos > pred.theArgPos)
2170+ --theMatchedQPreds[j].theArgPos;
2171+
2172+ ++j;
2173+ }
2174+
2175+ if (andExpr->num_args() == 1)
2176+ {
2177+ pred.theClause->set_expr(pred.theAndExpr->get_arg(0));
2178+ }
2179+ else if (andExpr->num_args() == 0)
2180+ {
2181+ matchedClauses.set(pred.theClausePos, true);
2182+ }
2183+ }
2184+ else
2185+ {
2186+ matchedClauses.set(pred.theClausePos, true);
2187+ }
2188+ }
2189+
2190+ fo_expr* probeExpr;
2191+
2192+ if (theIndexDecl->isOrdered())
2193+ {
2194+ probeExpr = ccb->theEM->
2195+ create_fo_expr(sctx,
2196+ udf,
2197+ firstMatchedFOR->get_loc(),
2198+ BUILTIN_FUNC(FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N),
2199+ theProbeArgs);
2200+ }
2201+ else
2202+ {
2203+ probeExpr = ccb->theEM->
2204+ create_fo_expr(sctx,
2205+ udf,
2206+ firstMatchedFOR->get_loc(),
2207+ BUILTIN_FUNC(FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N),
2208+ theProbeArgs);
2209+ }
2210+
2211+ if (! (theQueryExpr->ignoresSortedNodes() ||
2212+ firstOrderByPos != 0 ||
2213+ (theIndexDecl->numSources() == 1 &&
2214+ !sctx->lookup_collection(theIndexDecl->getSourceName(0))->isOrdered())))
2215+ {
2216+ probeExpr = ccb->theEM->
2217+ create_fo_expr(sctx,
2218+ udf,
2219+ firstMatchedFOR->get_loc(),
2220+ BUILTIN_FUNC(OP_SORT_NODES_ASC_1),
2221+ probeExpr);
2222+ }
2223+
2224+ firstMatchedFOR->set_expr(probeExpr);
2225+
2226+ csize numRemoved = 0;
2227+ for (csize i = firstMatchedFORpos + 1; i < matchedClauses.size(); ++i)
2228+ {
2229+ if (matchedClauses.get(i))
2230+ {
2231+ theQueryExpr->remove_clause(i - numRemoved);
2232+ ++numRemoved;
2233+ }
2234+ }
2235+
2236+ return true;
2237+}
2238+
2239+
2240+/*******************************************************************************
2241+
2242+********************************************************************************/
2243+void IndexMatchingRule::getWherePreds(
2244+ csize clausePos,
2245+ where_clause* wc,
2246+ std::vector<PredInfo>& preds)
2247+{
2248+ expr* whereExpr = wc->get_expr();
2249+
2250+ if (whereExpr->get_function_kind() == FunctionConsts::OP_AND_N)
2251+ {
2252+ fo_expr* andExpr = static_cast<fo_expr*>(whereExpr);
2253+ csize numArgs = andExpr->num_args();
2254+
2255+ for (csize i = 0; i < numArgs; ++i)
2256+ {
2257+ preds.push_back(PredInfo(wc, clausePos, andExpr, i));
2258+ }
2259+ }
2260+ else
2261+ {
2262+ preds.push_back(PredInfo(wc, clausePos, NULL, 0));
2263+ }
2264+}
2265+
2266+
2267+/*******************************************************************************
2268+
2269+********************************************************************************/
2270+bool IndexMatchingRule::matchKeyExprsForRangeIndex(
2271+ expr::substitution_t& subst,
2272+ csize& lastMatchedWHEREpos)
2273+{
2274+ CompilerCB* ccb = theQueryExpr->get_ccb();
2275+ static_context* sctx = theQueryExpr->get_sctx();
2276+ user_function* udf = theQueryExpr->get_udf();
2277+
2278+ expr* trueExpr = ccb->theEM->create_const_expr(sctx, udf, QueryLoc::null, true);
2279+ expr* falseExpr = ccb->theEM->create_const_expr(sctx, udf, QueryLoc::null, false);
2280+
2281+ bool matchedFirstKey = false;
2282+
2283+ std::vector<let_clause*>::const_iterator keyIte = theKeyClauses.begin();
2284+ std::vector<let_clause*>::const_iterator keyEnd = theKeyClauses.end();
2285+
2286+ for (; keyIte != keyEnd; ++keyIte)
2287+ {
2288+ expr* bounds[2] = { NULL };
2289+ bool boundsIncluded[2] = { false };
2290+ expr* keyExpr = (*keyIte)->get_expr();
2291+
2292+ std::vector<PredInfo>::iterator qpredIte = theUnmatchedQPreds.begin();
2293+ std::vector<PredInfo>::iterator qpredEnd = theUnmatchedQPreds.end();
2294+
2295+ for (; qpredIte != qpredEnd; ++qpredIte)
2296+ {
2297+ PredInfo& qpred = *qpredIte;
2298+
2299+ if (qpred.theExpr->get_expr_kind() != fo_expr_kind)
2300+ continue;
2301+
2302+ fo_expr* qpredExpr = static_cast<fo_expr*>(qpred.theExpr);
2303+ function* qpredFunc = qpredExpr->get_func();
2304+
2305+ if (qpredFunc->getKind() == FunctionConsts::FN_BOOLEAN_1)
2306+ {
2307+ if (qpredExpr->get_arg(0)->get_expr_kind() != fo_expr_kind)
2308+ continue;
2309+
2310+ qpredExpr = static_cast<fo_expr*>(qpredExpr->get_arg(0));
2311+ qpredFunc = qpredExpr->get_func();
2312+ }
2313+
2314+ CompareConsts::CompareType compKind = qpredFunc->comparisonKind();
2315+
2316+ if (compKind == CompareConsts::VALUE_EQUAL ||
2317+ compKind == CompareConsts::VALUE_LESS ||
2318+ compKind == CompareConsts::VALUE_LESS_EQUAL ||
2319+ compKind == CompareConsts::VALUE_GREATER ||
2320+ compKind == CompareConsts::VALUE_GREATER_EQUAL)
2321+ {
2322+ int matched = -1;
2323+
2324+ if (matchKeyExpr(qpredExpr->get_arg(0), keyExpr, subst))
2325+ matched = 0;
2326+ else if (matchKeyExpr(qpredExpr->get_arg(1), keyExpr, subst))
2327+ matched = 1;
2328+
2329+ if (matched < 0)
2330+ continue;
2331+
2332+ if (compKind == CompareConsts::VALUE_EQUAL)
2333+ {
2334+ bounds[0] = bounds[1] = qpredExpr->get_arg(1 - matched);
2335+ boundsIncluded[0] = boundsIncluded[1] = true;
2336+ matched = 2;
2337+ }
2338+ else if (compKind == CompareConsts::VALUE_LESS)
2339+ {
2340+ if (bounds[1-matched] == NULL)
2341+ {
2342+ bounds[1-matched] = qpredExpr->get_arg(1 - matched);
2343+ boundsIncluded[1-matched] = false;
2344+ matched = 2;
2345+ }
2346+ }
2347+ else if (compKind == CompareConsts::VALUE_LESS_EQUAL)
2348+ {
2349+ if (bounds[1-matched] == NULL)
2350+ {
2351+ bounds[1-matched] = qpredExpr->get_arg(1 - matched);
2352+ boundsIncluded[1-matched] = true;
2353+ matched = 2;
2354+ }
2355+ }
2356+ else if (compKind == CompareConsts::VALUE_GREATER)
2357+ {
2358+ if (bounds[matched] == NULL)
2359+ {
2360+ bounds[matched] = qpredExpr->get_arg(1 - matched);
2361+ boundsIncluded[matched] = false;
2362+ matched = 2;
2363+ }
2364+ }
2365+ else if (compKind == CompareConsts::VALUE_GREATER_EQUAL)
2366+ {
2367+ if (bounds[matched] == NULL)
2368+ {
2369+ bounds[matched] = qpredExpr->get_arg(1 - matched);
2370+ boundsIncluded[matched] = true;
2371+ matched = 2;
2372+ }
2373+ }
2374+
2375+ if (matched == 2)
2376+ {
2377+ theMatchedQPreds.push_back(qpred);
2378+ theUnmatchedQPreds.erase(qpredIte);
2379+ --qpredIte;
2380+
2381+ if (qpred.theClausePos > lastMatchedWHEREpos)
2382+ lastMatchedWHEREpos = qpred.theClausePos;
2383+ }
2384+
2385+ if ((bounds[0] != NULL && bounds[1] != NULL) || theUnmatchedQPreds.empty())
2386+ break;
2387+ }
2388+ } // for each query pred
2389+
2390+ // $lowerBound
2391+ if (bounds[0] != NULL)
2392+ theProbeArgs.push_back(bounds[0]);
2393+ else
2394+ theProbeArgs.push_back(ccb->theEM->create_seq(sctx, udf, QueryLoc::null));
2395+
2396+ // $upperBound
2397+ if (bounds[1] != NULL)
2398+ theProbeArgs.push_back(bounds[1]);
2399+ else
2400+ theProbeArgs.push_back(ccb->theEM->create_seq(sctx, udf, QueryLoc::null));
2401+
2402+ // $haveLowerBound
2403+ if (bounds[0] != NULL)
2404+ theProbeArgs.push_back(trueExpr);
2405+ else
2406+ theProbeArgs.push_back(falseExpr);
2407+
2408+ // $haveUpperBound
2409+ if (bounds[1] != NULL)
2410+ theProbeArgs.push_back(trueExpr);
2411+ else
2412+ theProbeArgs.push_back(falseExpr);
2413+
2414+ // $lowerBoundIncluded
2415+ if (boundsIncluded[0])
2416+ theProbeArgs.push_back(trueExpr);
2417+ else
2418+ theProbeArgs.push_back(falseExpr);
2419+
2420+ // $upperBoundIncluded
2421+ if (boundsIncluded[1])
2422+ theProbeArgs.push_back(trueExpr);
2423+ else
2424+ theProbeArgs.push_back(falseExpr);
2425+
2426+ if (keyIte == theKeyClauses.begin() &&
2427+ (bounds[0] != NULL || bounds[1] != NULL))
2428+ matchedFirstKey = true;
2429+ }
2430+
2431+ if (!matchedFirstKey)
2432+ {
2433+ return false;
2434+ }
2435+
2436+ return true;
2437+}
2438+
2439+
2440+/*******************************************************************************
2441+
2442+********************************************************************************/
2443+bool IndexMatchingRule::matchKeyExprsForEqIndex(
2444+ expr::substitution_t& subst,
2445+ csize& lastMatchedWHEREpos)
2446+{
2447+ std::vector<let_clause*>::const_iterator keyIte = theKeyClauses.begin();
2448+ std::vector<let_clause*>::const_iterator keyEnd = theKeyClauses.end();
2449+
2450+ for (; keyIte != keyEnd; ++keyIte)
2451+ {
2452+ int matched = -1;
2453+ expr* keyExpr = (*keyIte)->get_expr();
2454+
2455+ std::vector<PredInfo>::iterator qpredIte = theUnmatchedQPreds.begin();
2456+ std::vector<PredInfo>::iterator qpredEnd = theUnmatchedQPreds.end();
2457+
2458+ for (; qpredIte != qpredEnd; ++qpredIte)
2459+ {
2460+ PredInfo& qpred = *qpredIte;
2461+
2462+ if (qpred.theExpr->get_expr_kind() != fo_expr_kind)
2463+ continue;
2464+
2465+ fo_expr* qpredExpr = static_cast<fo_expr*>(qpred.theExpr);
2466+ function* qpredFunc = qpredExpr->get_func();
2467+
2468+ if (qpredFunc->getKind() == FunctionConsts::FN_BOOLEAN_1)
2469+ {
2470+ if (qpredExpr->get_arg(0)->get_expr_kind() != fo_expr_kind)
2471+ continue;
2472+
2473+ qpredExpr = static_cast<fo_expr*>(qpredExpr->get_arg(0));
2474+ qpredFunc = qpredExpr->get_func();
2475+ }
2476+
2477+ CompareConsts::CompareType compKind = qpredFunc->comparisonKind();
2478+
2479+ if (compKind != CompareConsts::VALUE_EQUAL)
2480+ continue;
2481+
2482+ if (matchKeyExpr(qpredExpr->get_arg(0), keyExpr, subst))
2483+ matched = 0;
2484+ else if (matchKeyExpr(qpredExpr->get_arg(1), keyExpr, subst))
2485+ matched = 1;
2486+
2487+ if (matched >= 0)
2488+ {
2489+ theMatchedQPreds.push_back(qpred);
2490+ theUnmatchedQPreds.erase(qpredIte);
2491+
2492+ if (qpred.theClausePos > lastMatchedWHEREpos)
2493+ lastMatchedWHEREpos = qpred.theClausePos;
2494+
2495+ theProbeArgs.push_back(qpredExpr->get_arg(1 - matched));
2496+
2497+ // do not try to match another query pred with the current index key.
2498+ break;
2499+ }
2500+ }
2501+
2502+ if (matched < 0)
2503+ return false;
2504+ }
2505+
2506+ return true;
2507+}
2508+
2509+
2510+/*******************************************************************************
2511+
2512+********************************************************************************/
2513+bool IndexMatchingRule::matchKeyExpr(
2514+ expr* qexpr,
2515+ expr* vexpr,
2516+ expr::substitution_t& subst)
2517+{
2518+ if (qexpr->get_expr_kind() == promote_expr_kind &&
2519+ vexpr->get_expr_kind() == promote_expr_kind)
2520+ {
2521+ promote_expr* qe = static_cast<promote_expr*>(qexpr);
2522+ promote_expr* ve = static_cast<promote_expr*>(vexpr);
2523+ xqtref_t qtype = qe->get_return_type();
2524+ xqtref_t vtype = ve->get_target_type();
2525+
2526+ TypeManager* tm = qe->get_type_manager();
2527+ RootTypeManager& rtm = GENV_TYPESYSTEM;
2528+
2529+ if (TypeOps::is_subtype(tm, *qtype, *vtype) ||
2530+ (TypeOps::is_subtype(tm, *qtype, *rtm.UNTYPED_ATOMIC_TYPE_STAR) &&
2531+ TypeOps::is_subtype(tm, *vtype, *rtm.STRING_TYPE_STAR)))
2532+ {
2533+ return expr_tools::match_exact(qe->get_input(), ve->get_input(), subst);
2534+ }
2535+
2536+ return false;
2537+ }
2538+ else if (vexpr->get_expr_kind() == promote_expr_kind &&
2539+ qexpr->get_expr_kind() != promote_expr_kind)
2540+ {
2541+ promote_expr* ve = static_cast<promote_expr*>(vexpr);
2542+ xqtref_t qtype = qexpr->get_return_type();
2543+ xqtref_t vtype = ve->get_target_type();
2544+
2545+ TypeManager* tm = qexpr->get_type_manager();
2546+ RootTypeManager& rtm = GENV_TYPESYSTEM;
2547+
2548+ if (TypeOps::is_subtype(tm, *qtype, *vtype) ||
2549+ (TypeOps::is_subtype(tm, *qtype, *rtm.UNTYPED_ATOMIC_TYPE_STAR) &&
2550+ TypeOps::is_subtype(tm, *vtype, *rtm.STRING_TYPE_STAR)))
2551+ {
2552+ return expr_tools::match_exact(qexpr, ve->get_input(), subst);
2553+ }
2554+
2555+ return false;
2556+ }
2557+ else if (vexpr->get_expr_kind() == treat_expr_kind &&
2558+ qexpr->get_expr_kind() != treat_expr_kind)
2559+ {
2560+ treat_expr* ve = static_cast<treat_expr*>(vexpr);
2561+
2562+ return expr_tools::match_exact(qexpr, ve->get_input(), subst);
2563+ }
2564+
2565+ return expr_tools::match_exact(qexpr, vexpr, subst);
2566+}
2567+
2568+
2569+/*******************************************************************************
2570+
2571+********************************************************************************/
2572+bool IndexMatchingRule::checkFreeVars(
2573+ const expr* qexpr,
2574+ const var_expr* domVar,
2575+ const DynamicBitset& matchedClauses)
2576+{
2577+ const expr::FreeVars& freeVars = qexpr->getFreeVars();
2578+
2579+ expr::FreeVars::const_iterator ite = freeVars.begin();
2580+ expr::FreeVars::const_iterator end = freeVars.end();
2581+ for (; ite != end; ++ite)
2582+ {
2583+ var_expr* freeVar = *ite;
2584+
2585+ if (freeVar == domVar)
2586+ continue;
2587+
2588+ if (freeVar->get_flwor_clause()->get_flwor_expr() == theQueryExpr)
2589+ {
2590+ freeVar->setVisitId(1);
2591+ }
2592+
2593+ if (freeVar->get_kind() != var_expr::for_var)
2594+ continue;
2595+
2596+ for (csize i = 0; i < matchedClauses.size(); ++i)
2597+ {
2598+ if (matchedClauses.get(i) &&
2599+ freeVar->get_flwor_clause() == theQueryExpr->get_clause(i))
2600+ {
2601+ return false;
2602+ }
2603+ }
2604+ }
2605+
2606+ return true;
2607+}
2608+
2609+
2610+}
2611+
2612+/* vim:set et sw=2 ts=2: */
2613
2614=== added file 'src/compiler/rewriter/rules/index_matching_rule.h'
2615--- src/compiler/rewriter/rules/index_matching_rule.h 1970-01-01 00:00:00 +0000
2616+++ src/compiler/rewriter/rules/index_matching_rule.h 2013-01-29 17:56:25 +0000
2617@@ -0,0 +1,96 @@
2618+/*
2619+ * Copyright 2006-2008 The FLWOR Foundation.
2620+ *
2621+ * Licensed under the Apache License, Version 2.0 (the "License");
2622+ * you may not use this file except in compliance with the License.
2623+ * You may obtain a copy of the License at
2624+ *
2625+ * http://www.apache.org/licenses/LICENSE-2.0
2626+ *
2627+ * Unless required by applicable law or agreed to in writing, software
2628+ * distributed under the License is distributed on an "AS IS" BASIS,
2629+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2630+ * See the License for the specific language governing permissions and
2631+ * limitations under the License.
2632+ */
2633+#pragma once
2634+#ifndef ZORBA_COMPILER_REWRITER_INDEX_MATCHING_H
2635+#define ZORBA_COMPILER_REWRITER_INDEX_MATCHING_H
2636+
2637+
2638+#include "compiler/rewriter/rules/rule_base.h"
2639+
2640+
2641+namespace zorba
2642+{
2643+
2644+class IndexDecl;
2645+class flwor_expr;
2646+class DynamicBitset;
2647+class fo_expr;
2648+class where_clause;
2649+
2650+
2651+/*******************************************************************************
2652+
2653+********************************************************************************/
2654+class IndexMatchingRule : public RewriteRule
2655+{
2656+ struct PredInfo
2657+ {
2658+ where_clause * theClause;
2659+ csize theClausePos;
2660+
2661+ fo_expr * theAndExpr;
2662+ csize theArgPos;
2663+
2664+ expr * theExpr;
2665+
2666+ PredInfo(where_clause* wc, csize wcPos, fo_expr* andExpr, csize argPos);
2667+ };
2668+
2669+protected:
2670+ IndexDecl * theIndexDecl;
2671+ flwor_expr * theViewExpr;
2672+ std::vector<let_clause*> theKeyClauses;
2673+ flwor_expr * theQueryExpr;
2674+ bool theDoTrace;
2675+
2676+ std::vector<PredInfo> theUnmatchedQPreds;
2677+ std::vector<PredInfo> theMatchedQPreds;
2678+ std::vector<expr*> theProbeArgs;
2679+
2680+public:
2681+ IndexMatchingRule(IndexDecl* decl);
2682+
2683+ expr* apply(RewriterContext& rCtx, expr* node, bool& modified);
2684+
2685+protected:
2686+ bool matchIndex();
2687+
2688+ void getWherePreds(
2689+ csize clausePos,
2690+ where_clause* wc,
2691+ std::vector<PredInfo>& preds);
2692+
2693+ bool matchKeyExprsForEqIndex(
2694+ expr::substitution_t& subst,
2695+ csize& lastMatchedWHEREpos);
2696+
2697+ bool matchKeyExprsForRangeIndex(
2698+ expr::substitution_t& subst,
2699+ csize& lastMatchedWHEREpos);
2700+
2701+ bool matchKeyExpr(expr* qexpr, expr* vexpr, expr::substitution_t& subst);
2702+
2703+ bool checkFreeVars(
2704+ const expr* qexpr,
2705+ const var_expr* domVar,
2706+ const DynamicBitset& matchedFORs);
2707+};
2708+
2709+
2710+}
2711+
2712+#endif
2713+/* vim:set et sw=2 ts=2: */
2714
2715=== modified file 'src/compiler/rewriter/rules/ruleset.h'
2716--- src/compiler/rewriter/rules/ruleset.h 2012-10-30 13:33:05 +0000
2717+++ src/compiler/rewriter/rules/ruleset.h 2013-01-29 17:56:25 +0000
2718@@ -144,7 +144,7 @@
2719 expr* apply(RewriterContext& rCtx, expr* node, bool& modified);
2720 };
2721
2722-#if 1
2723+
2724 /*******************************************************************************
2725
2726 ********************************************************************************/
2727@@ -159,7 +159,7 @@
2728
2729 expr* apply(RewriterContext& rCtx, expr* node, bool& modified);
2730 };
2731-#endif
2732+
2733
2734 /*******************************************************************************
2735
2736
2737=== modified file 'src/compiler/rewriter/tools/dataflow_annotations.cpp'
2738--- src/compiler/rewriter/tools/dataflow_annotations.cpp 2012-12-28 10:42:12 +0000
2739+++ src/compiler/rewriter/tools/dataflow_annotations.cpp 2013-01-29 17:56:25 +0000
2740@@ -408,7 +408,7 @@
2741 break;
2742 }
2743 case flwor_clause::order_clause:
2744- case flwor_clause::group_clause:
2745+ case flwor_clause::groupby_clause:
2746 {
2747 return;
2748 }
2749
2750=== modified file 'src/compiler/rewriter/tools/expr_tools.cpp'
2751--- src/compiler/rewriter/tools/expr_tools.cpp 2012-12-25 20:27:54 +0000
2752+++ src/compiler/rewriter/tools/expr_tools.cpp 2013-01-29 17:56:25 +0000
2753@@ -20,9 +20,11 @@
2754 #include "compiler/expression/flwor_expr.h"
2755 #include "compiler/expression/expr.h"
2756 #include "compiler/expression/path_expr.h"
2757+#include "compiler/expression/script_exprs.h"
2758 #include "compiler/expression/ft_expr.h"
2759 #include "compiler/expression/ftnode.h"
2760 #include "compiler/expression/expr_iter.h"
2761+#include "compiler/api/compilercb.h"
2762
2763 #include "functions/func_errors_and_diagnostics.h"
2764
2765@@ -48,6 +50,482 @@
2766 /*******************************************************************************
2767
2768 ********************************************************************************/
2769+static void normalize_comp(
2770+ CompareConsts::CompareType& comp,
2771+ expr*& arg0,
2772+ expr*& arg1)
2773+{
2774+ switch (comp)
2775+ {
2776+ case CompareConsts::VALUE_GREATER:
2777+ case CompareConsts::GENERAL_GREATER:
2778+ case CompareConsts::VALUE_GREATER_EQUAL:
2779+ case CompareConsts::GENERAL_GREATER_EQUAL:
2780+ {
2781+ comp = static_cast<CompareConsts::CompareType>(static_cast<int>(comp) - 4);
2782+
2783+ expr* tmp = arg0;
2784+ arg0 = arg1;
2785+ arg1 = tmp;
2786+
2787+ break;
2788+ }
2789+ default:
2790+ break;
2791+ }
2792+}
2793+
2794+
2795+/*******************************************************************************
2796+
2797+********************************************************************************/
2798+bool match_exact(expr* query, expr* view, expr::substitution_t& subst)
2799+{
2800+ if (query == view)
2801+ return true;
2802+
2803+ if (query->get_expr_kind() != view->get_expr_kind())
2804+ {
2805+ if (query->get_expr_kind() == var_expr_kind)
2806+ {
2807+ var_expr* qe = static_cast<var_expr*>(query);
2808+
2809+ if (qe->get_kind() != var_expr::let_var)
2810+ return false;
2811+
2812+ return match_exact(qe->get_domain_expr(), view, subst);
2813+ }
2814+ else if (view->get_expr_kind() == var_expr_kind)
2815+ {
2816+ var_expr* ve = static_cast<var_expr*>(view);
2817+
2818+ switch (ve->get_kind())
2819+ {
2820+ case var_expr::for_var:
2821+ {
2822+ expr::substitution_t::iterator ite = subst.find(view);
2823+
2824+ if (ite != subst.end())
2825+ {
2826+ return match_exact(query, ite->second, subst);
2827+ }
2828+ else
2829+ {
2830+ assert(false);
2831+ subst[view] = query;
2832+ return true;
2833+ }
2834+ }
2835+ case var_expr::let_var:
2836+ {
2837+ return match_exact(query, ve->get_domain_expr(), subst);
2838+ }
2839+ case var_expr::pos_var:
2840+ {
2841+ return false;
2842+ }
2843+ case var_expr::win_var:
2844+ case var_expr::wincond_out_var:
2845+ case var_expr::wincond_out_pos_var:
2846+ case var_expr::wincond_in_var:
2847+ case var_expr::wincond_in_pos_var:
2848+ case var_expr::groupby_var:
2849+ case var_expr::non_groupby_var:
2850+ case var_expr::count_var:
2851+ {
2852+ ZORBA_ASSERT(false); // TODO
2853+ }
2854+ case var_expr::score_var:
2855+ case var_expr::prolog_var:
2856+ case var_expr::local_var:
2857+ case var_expr::copy_var:
2858+ case var_expr::catch_var:
2859+ case var_expr::arg_var:
2860+ case var_expr::eval_var:
2861+ {
2862+ ZORBA_ASSERT(false);
2863+ }
2864+ default:
2865+ {
2866+ ZORBA_ASSERT(false);
2867+ }
2868+ }
2869+ }
2870+ else if (view->get_function_kind() == FunctionConsts::OP_UNHOIST_1)
2871+ {
2872+ fo_expr* vfo = static_cast<fo_expr*>(view);
2873+ return match_exact(query, vfo->get_arg(0), subst);
2874+ }
2875+ else if (query->get_function_kind() == FunctionConsts::OP_UNHOIST_1)
2876+ {
2877+ fo_expr* qfo = static_cast<fo_expr*>(query);
2878+ return match_exact(qfo->get_arg(0), view, subst);
2879+ }
2880+ else if (view->get_function_kind() == FunctionConsts::OP_HOIST_1)
2881+ {
2882+ fo_expr* vfo = static_cast<fo_expr*>(view);
2883+ return match_exact(query, vfo->get_arg(0), subst);
2884+ }
2885+ else if (query->get_function_kind() == FunctionConsts::OP_HOIST_1)
2886+ {
2887+ fo_expr* qfo = static_cast<fo_expr*>(query);
2888+ return match_exact(qfo->get_arg(0), view, subst);
2889+ }
2890+ else if (view->get_expr_kind() == wrapper_expr_kind)
2891+ {
2892+ wrapper_expr* vwe = static_cast<wrapper_expr*>(view);
2893+ return match_exact(query, vwe->get_input(), subst);
2894+ }
2895+ else if (query->get_expr_kind() == wrapper_expr_kind)
2896+ {
2897+ wrapper_expr* qwe = static_cast<wrapper_expr*>(query);
2898+ return match_exact(qwe->get_input(), view, subst);
2899+ }
2900+ else
2901+ {
2902+ return false;
2903+ }
2904+ }
2905+
2906+ switch (query->get_expr_kind())
2907+ {
2908+ case var_expr_kind:
2909+ {
2910+ var_expr* qe = static_cast<var_expr*>(query);
2911+ var_expr* ve = static_cast<var_expr*>(view);
2912+
2913+ var_expr::var_kind qkind = qe->get_kind();
2914+ var_expr::var_kind vkind = ve->get_kind();
2915+
2916+ if (qkind != vkind)
2917+ {
2918+ if (qkind == var_expr::let_var)
2919+ {
2920+ return match_exact(qe->get_domain_expr(), view, subst);
2921+ }
2922+
2923+ return false;
2924+ }
2925+
2926+ switch (qkind)
2927+ {
2928+ case var_expr::for_var:
2929+ case var_expr::pos_var:
2930+ {
2931+ expr::substitution_t::iterator ite = subst.find(view);
2932+
2933+ if (ite != subst.end())
2934+ {
2935+ return (qe == ite->second);
2936+ }
2937+ else
2938+ {
2939+ assert(false);
2940+ subst[view] = query;
2941+ return true;
2942+ }
2943+ }
2944+ case var_expr::let_var:
2945+ {
2946+ return match_exact(qe->get_domain_expr(), ve->get_domain_expr(), subst);
2947+ }
2948+ case var_expr::win_var:
2949+ case var_expr::wincond_out_var:
2950+ case var_expr::wincond_out_pos_var:
2951+ case var_expr::wincond_in_var:
2952+ case var_expr::wincond_in_pos_var:
2953+ case var_expr::groupby_var:
2954+ case var_expr::non_groupby_var:
2955+ case var_expr::count_var:
2956+ {
2957+ ZORBA_ASSERT(false); // TODO
2958+ }
2959+ case var_expr::score_var:
2960+ case var_expr::prolog_var:
2961+ case var_expr::local_var:
2962+ case var_expr::copy_var:
2963+ case var_expr::catch_var:
2964+ case var_expr::arg_var:
2965+ case var_expr::eval_var:
2966+ {
2967+ ZORBA_ASSERT(false);
2968+ }
2969+ default:
2970+ {
2971+ ZORBA_ASSERT(false);
2972+ }
2973+ }
2974+
2975+ break;
2976+ }
2977+
2978+ case fo_expr_kind:
2979+ {
2980+ fo_expr* qe = static_cast<fo_expr*>(query);
2981+ fo_expr* ve = static_cast<fo_expr*>(view);
2982+
2983+ if (qe->get_func() != ve->get_func())
2984+ {
2985+ function* vfunc = ve->get_func();
2986+ function* qfunc = qe->get_func();
2987+
2988+ if (qfunc->isComparisonFunction() && vfunc->isComparisonFunction())
2989+ {
2990+ CompareConsts::CompareType qcomp = qe->get_func()->comparisonKind();
2991+ CompareConsts::CompareType vcomp = ve->get_func()->comparisonKind();
2992+
2993+ expr* qarg0 = qe->get_arg(0);
2994+ expr* qarg1 = qe->get_arg(1);
2995+ expr* varg0 = ve->get_arg(0);
2996+ expr* varg1 = ve->get_arg(1);
2997+
2998+ normalize_comp(qcomp, qarg0, qarg1);
2999+ normalize_comp(vcomp, varg0, varg1);
3000+
3001+ if (qcomp == vcomp &&
3002+ match_exact(qarg0, varg0, subst) &&
3003+ match_exact(qarg1, varg1, subst))
3004+ return true;
3005+ }
3006+ else if (vfunc->getKind() == FunctionConsts::OP_UNHOIST_1)
3007+ {
3008+ return match_exact(query, ve->get_arg(0), subst);
3009+ }
3010+ else if (qfunc->getKind() == FunctionConsts::OP_UNHOIST_1)
3011+ {
3012+ return match_exact(qe->get_arg(0), view, subst);
3013+ }
3014+ else if (vfunc->getKind() == FunctionConsts::OP_HOIST_1)
3015+ {
3016+ return match_exact(query, ve->get_arg(0), subst);
3017+ }
3018+ else if (qfunc->getKind() == FunctionConsts::OP_HOIST_1)
3019+ {
3020+ return match_exact(qe->get_arg(0), view, subst);
3021+ }
3022+
3023+ return false;
3024+ }
3025+
3026+ function* func = qe->get_func();
3027+
3028+ csize numArgs = qe->num_args();
3029+
3030+ if (numArgs != ve->num_args())
3031+ return false;
3032+
3033+ csize i = 0;
3034+ for (; i < numArgs; i++)
3035+ {
3036+ if (!match_exact(qe->get_arg(i), ve->get_arg(i), subst))
3037+ break;
3038+ }
3039+
3040+ if (i < numArgs)
3041+ {
3042+ if (func->getKind() == FunctionConsts::STATIC_COLLECTIONS_DML_COLLECTION_1)
3043+ {
3044+ const store::Item* collName1 = ve->get_arg(0)->getQName();
3045+ const store::Item* collName2 = qe->get_arg(0)->getQName();
3046+
3047+ if (collName1 != NULL && collName2 != NULL && collName1->equals(collName2))
3048+ return true;
3049+#if 0
3050+ if (collName != NULL && qe->get_arg(0)->get_var() != NULL)
3051+ {
3052+ const var_expr* var = qe->get_arg(0)->get_var();
3053+
3054+ if (var->get_kind() == var_expr::prolog_var &&
3055+ var->num_set_exprs() == 1 &&
3056+ var->get_set_expr(0)->get_expr_kind() == var_decl_expr_kind)
3057+ {
3058+ const var_decl_expr* decl =
3059+ static_cast<const var_decl_expr*>(var->get_set_expr(0));
3060+
3061+ const store::Item* collName2 = decl->get_init_expr()->getQName();
3062+
3063+ if (collName2 != NULL && collName->equals(collName2))
3064+ return true;
3065+ }
3066+ }
3067+#endif
3068+ }
3069+ else if (func->isComparisonFunction())
3070+ {
3071+ CompareConsts::CompareType compKind = func->comparisonKind();
3072+
3073+ if (CompareConsts::VALUE_EQUAL <= compKind &&
3074+ compKind <= CompareConsts::NODE_NOT_EQUAL)
3075+ {
3076+ if (match_exact(qe->get_arg(0), ve->get_arg(1), subst) &&
3077+ match_exact(qe->get_arg(1), ve->get_arg(0), subst))
3078+ return true;
3079+ }
3080+ }
3081+
3082+ return false;
3083+ }
3084+
3085+ return true;
3086+ }
3087+
3088+ case relpath_expr_kind:
3089+ {
3090+ relpath_expr* qe = static_cast<relpath_expr*>(query);
3091+ relpath_expr* ve = static_cast<relpath_expr*>(view);
3092+
3093+ csize vnumSteps = ve->size();
3094+ csize qnumSteps = qe->size();
3095+ csize numSteps = (vnumSteps < qnumSteps ? vnumSteps : qnumSteps);
3096+
3097+ for (csize i = numSteps-1; i > 0; --i)
3098+ {
3099+ axis_step_expr* qstep = static_cast<axis_step_expr*>((*qe)[i]);
3100+ axis_step_expr* vstep = static_cast<axis_step_expr*>((*ve)[i]);
3101+
3102+ if (qstep->getAxis() != vstep->getAxis())
3103+ return false;
3104+
3105+ match_expr* qtest = qstep->getTest();
3106+ match_expr* vtest = vstep->getTest();
3107+
3108+ if (!qtest->matches(vtest))
3109+ return false;
3110+ }
3111+
3112+ // <vsource>/b/c vs <qsource>/a/b/c
3113+ if (vnumSteps < qnumSteps)
3114+ {
3115+ expr* vsource = (*ve)[0];
3116+
3117+ if (vsource->get_expr_kind() != var_expr_kind)
3118+ return false;
3119+
3120+ relpath_expr* qpath = query->get_ccb()->getExprManager()->
3121+ create_relpath_expr(qe->get_sctx(), qe->get_udf(), qe->get_loc());
3122+
3123+ for (csize i = 0; i < qnumSteps - vnumSteps; ++i)
3124+ qpath->add_back((*qe)[i]);
3125+
3126+ return match_exact(qpath, vsource, subst);
3127+ }
3128+ // <vsource>/a/b/c vs <qsource>/b/c
3129+ else if (qnumSteps < vnumSteps)
3130+ {
3131+ expr* qsource = (*qe)[0];
3132+
3133+ if (qsource->get_expr_kind() != var_expr_kind)
3134+ return false;
3135+
3136+ relpath_expr* vpath = query->get_ccb()->getExprManager()->
3137+ create_relpath_expr(ve->get_sctx(), ve->get_udf(), ve->get_loc());
3138+
3139+ for (csize i = 0; i < vnumSteps - qnumSteps; ++i)
3140+ vpath->add_back((*ve)[i]);
3141+
3142+ return match_exact(qsource, vpath, subst);
3143+ }
3144+ else
3145+ {
3146+ return match_exact((*qe)[0], (*ve)[0], subst);
3147+ }
3148+ }
3149+
3150+ case cast_expr_kind:
3151+ case castable_expr_kind:
3152+ case instanceof_expr_kind:
3153+ {
3154+ cast_or_castable_base_expr* qe = static_cast<cast_or_castable_base_expr*>(query);
3155+ cast_or_castable_base_expr* ve = static_cast<cast_or_castable_base_expr*>(view);
3156+
3157+ TypeManager* tm = qe->get_type_manager();
3158+
3159+ if (!TypeOps::is_equal(tm, *qe->get_target_type(), *ve->get_target_type()))
3160+ return false;
3161+
3162+ return match_exact(qe->get_input(), ve->get_input(), subst);
3163+ }
3164+
3165+ case promote_expr_kind:
3166+ {
3167+ promote_expr* qe = static_cast<promote_expr*>(query);
3168+ promote_expr* ve = static_cast<promote_expr*>(view);
3169+
3170+ TypeManager* tm = qe->get_type_manager();
3171+
3172+ if (!TypeOps::is_subtype(tm, *qe->get_return_type(), *ve->get_target_type()))
3173+ return false;
3174+
3175+ return match_exact(qe->get_input(), ve->get_input(), subst);
3176+ }
3177+
3178+ case treat_expr_kind:
3179+ {
3180+ treat_expr* qe = static_cast<treat_expr*>(query);
3181+ treat_expr* ve = static_cast<treat_expr*>(view);
3182+
3183+ TypeManager* tm = qe->get_type_manager();
3184+
3185+ if (qe->get_check_prime() != ve->get_check_prime())
3186+ return false;
3187+
3188+ if (!qe->get_check_prime())
3189+ {
3190+ if (qe->get_target_type()->get_quantifier() !=
3191+ ve->get_target_type()->get_quantifier())
3192+ return false;
3193+ }
3194+ else if (!TypeOps::is_equal(tm, *qe->get_target_type(), *ve->get_target_type()))
3195+ {
3196+ return false;
3197+ }
3198+
3199+ return match_exact(qe->get_input(), ve->get_input(), subst);
3200+ }
3201+
3202+ case wrapper_expr_kind:
3203+ {
3204+ wrapper_expr* qe = static_cast<wrapper_expr*>(query);
3205+ wrapper_expr* ve = static_cast<wrapper_expr*>(view);
3206+
3207+ return match_exact(qe->get_input(), ve->get_input(), subst);
3208+ }
3209+
3210+ case const_expr_kind:
3211+ {
3212+ const_expr* qe = static_cast<const_expr*>(query);
3213+ const_expr* ve = static_cast<const_expr*>(view);
3214+
3215+ try
3216+ {
3217+ // TODO: collation, timezone ???? Implement the full eq spec ????
3218+ return qe->get_val()->equals(ve->get_val());
3219+ }
3220+ catch (ZorbaException&)
3221+ {
3222+ return false;
3223+ }
3224+ break;
3225+ }
3226+
3227+ case delete_expr_kind:
3228+ case insert_expr_kind:
3229+ case rename_expr_kind:
3230+ case replace_expr_kind:
3231+ case transform_expr_kind:
3232+ default:
3233+ {
3234+ ZORBA_ASSERT(false);
3235+ }
3236+ }
3237+
3238+ return false;
3239+}
3240+
3241+
3242+/*******************************************************************************
3243+
3244+********************************************************************************/
3245 bool count_var_uses_rec(
3246 expr* e,
3247 var_expr* var,
3248@@ -241,10 +719,10 @@
3249
3250 /*******************************************************************************
3251 Let FLWOR(e) be the set of flwor exprs within the expr tree rooted at expr e.
3252- Let FV(e) be the set of variables defined in any of the flwor exprs in FLWOR(e).
3253- This method assigns a prefix id to each variable in FV(e) and stores the mapping
3254- between var_expr and prefix id in "varmap". It also returns the number of vars
3255- in FV(e).
3256+ Let FV(e) be the set of variables defined in any of the flwor exprs in
3257+ FLWOR(e). This method assigns a prefix id to each variable in FV(e) and
3258+ stores the mapping between var_expr and prefix id in "varidmap" and the
3259+ reverse mapping in "idvapmap". It also returns the number of vars in FV(e).
3260
3261 Given 2 vars v1 and v2 in FV(e), their prefix ids allows to check if v1 is
3262 defined before v2: v1 is defined before v2 iff id(v1) < id(v2).
3263@@ -302,9 +780,9 @@
3264 if (stopCond != NULL)
3265 add_wincond_vars(stopCond, numVars, varidmap, idvarmap);
3266 }
3267- else if (c->get_kind() == flwor_clause::group_clause)
3268+ else if (c->get_kind() == flwor_clause::groupby_clause)
3269 {
3270- const group_clause* gc = static_cast<const group_clause *>(c);
3271+ const groupby_clause* gc = static_cast<const groupby_clause *>(c);
3272
3273 const flwor_clause::rebind_list_t& gvars = gc->get_grouping_vars();
3274 csize numGroupVars = gvars.size();
3275@@ -513,9 +991,9 @@
3276 if (stopCond != NULL)
3277 remove_wincond_vars(stopCond, varmap, freeset);
3278 }
3279- else if (c->get_kind() == flwor_clause::group_clause)
3280+ else if (c->get_kind() == flwor_clause::groupby_clause)
3281 {
3282- const group_clause* gc = static_cast<const group_clause *>(c);
3283+ const groupby_clause* gc = static_cast<const groupby_clause *>(c);
3284
3285 const flwor_clause::rebind_list_t& gvars = gc->get_grouping_vars();
3286 csize numGroupVars = gvars.size();
3287
3288=== modified file 'src/compiler/rewriter/tools/expr_tools.h'
3289--- src/compiler/rewriter/tools/expr_tools.h 2012-10-29 11:41:36 +0000
3290+++ src/compiler/rewriter/tools/expr_tools.h 2013-01-29 17:56:25 +0000
3291@@ -46,6 +46,9 @@
3292 namespace expr_tools
3293 {
3294
3295+bool match_exact(expr* query, expr* ast, expr::substitution_t& subst);
3296+
3297+
3298 int count_variable_uses(
3299 expr* root,
3300 var_expr* var,
3301
3302=== modified file 'src/compiler/translator/translator.cpp'
3303--- src/compiler/translator/translator.cpp 2013-01-19 20:47:55 +0000
3304+++ src/compiler/translator/translator.cpp 2013-01-29 17:56:25 +0000
3305@@ -1347,20 +1347,20 @@
3306 csize n = foExpr->num_args();
3307
3308 const function* func = foExpr->get_func();
3309+ FunctionConsts::FunctionKind fkind = func->getKind();
3310
3311- if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ||
3312- func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
3313+ if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ||
3314+ fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
3315 {
3316 csize nStarterParams =
3317- (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N
3318- ? 1 : 2);
3319+ (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ? 1 : 2);
3320
3321 if (n < (6 + nStarterParams) || (n - nStarterParams) % 6 != 0)
3322 {
3323 const store::Item* qname = NULL;
3324
3325 if (n > 0)
3326- qname = foExpr->get_arg(0)->getQName(theSctx);
3327+ qname = foExpr->get_arg(0)->getQName();
3328
3329 zstring lMsgPart;
3330 ztd::to_string(nStarterParams, &lMsgPart);
3331@@ -1384,21 +1384,21 @@
3332
3333 xqtref_t paramType;
3334
3335- if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N)
3336+ if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N)
3337 {
3338 if (i == 0)
3339 paramType = sign[i];
3340 else
3341 paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
3342 }
3343- else if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_SKIP_N)
3344+ else if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_SKIP_N)
3345 {
3346 if (i <= 1)
3347 paramType = sign[i];
3348 else
3349 paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
3350 }
3351- else if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N)
3352+ else if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N)
3353 {
3354 if (i == 0)
3355 paramType = sign[i];
3356@@ -1407,7 +1407,7 @@
3357 else
3358 paramType = theRTM.BOOLEAN_TYPE_ONE;
3359 }
3360- else if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
3361+ else if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
3362 {
3363 if (i <= 1)
3364 paramType = sign[i];
3365@@ -1416,10 +1416,10 @@
3366 else
3367 paramType = theRTM.BOOLEAN_TYPE_ONE;
3368 }
3369- else if (func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_N ||
3370- func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_N_N ||
3371- func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_U_N ||
3372- func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_S_N)
3373+ else if (fkind == FunctionConsts::FN_ZORBA_INVOKE_N ||
3374+ fkind == FunctionConsts::FN_ZORBA_INVOKE_N_N ||
3375+ fkind == FunctionConsts::FN_ZORBA_INVOKE_U_N ||
3376+ fkind == FunctionConsts::FN_ZORBA_INVOKE_S_N)
3377 {
3378 if (i == 0)
3379 paramType = sign[i];
3380@@ -1435,10 +1435,7 @@
3381 // or match should be added. This is used by the reflection:invoke() function,
3382 if (paramType != NULL)
3383 {
3384- if (TypeOps::is_subtype(tm,
3385- *paramType,
3386- *theRTM.ANY_ATOMIC_TYPE_STAR,
3387- loc))
3388+ if (TypeOps::is_subtype(tm, *paramType, *theRTM.ANY_ATOMIC_TYPE_STAR, loc))
3389 {
3390 argExpr = wrap_in_type_promotion(argExpr,
3391 paramType,
3392@@ -1465,11 +1462,11 @@
3393 ********************************************************************************/
3394 expr* wrap_in_atomization(expr* e)
3395 {
3396- return theExprManager->create_fo_expr(theRootSctx,
3397- theUDF,
3398- e->get_loc(),
3399- BUILTIN_FUNC(FN_DATA_1),
3400- e);
3401+ return CREATE(fo)(theRootSctx,
3402+ theUDF,
3403+ e->get_loc(),
3404+ BUILTIN_FUNC(FN_DATA_1),
3405+ e);
3406 }
3407
3408
3409@@ -1484,13 +1481,13 @@
3410 {
3411 e = wrap_in_atomization(e);
3412
3413- return theExprManager->create_promote_expr(theRootSctx,
3414- theUDF,
3415- e->get_loc(),
3416- e,
3417- type,
3418- errorKind,
3419- qname);
3420+ return CREATE(promote)(theRootSctx,
3421+ theUDF,
3422+ e->get_loc(),
3423+ e,
3424+ type,
3425+ errorKind,
3426+ qname);
3427 }
3428
3429
3430@@ -4294,8 +4291,8 @@
3431 TypeConstants::quantifier_t quant;
3432 if (v.getType() == 0)
3433 {
3434- lNodeType = theRTM.DOCUMENT_UNTYPED_TYPE_ONE;
3435- lCollectionType = theRTM.DOCUMENT_UNTYPED_TYPE_STAR;
3436+ lNodeType = theRTM.ANY_NODE_UNTYPED_TYPE_ONE;
3437+ lCollectionType = theRTM.ANY_NODE_UNTYPED_TYPE_STAR;
3438 quant = TypeConstants::QUANT_STAR;
3439 }
3440 else
3441@@ -4504,7 +4501,7 @@
3442 IndexDecl_t index = theIndexDecl;
3443 theIndexDecl = NULL;
3444
3445- index->analyze(theCCB);
3446+ index->analyze();
3447
3448 // Register the index in the sctx of the current module. Raise error if such
3449 // a binding exists already in the sctx.
3450@@ -4622,6 +4619,7 @@
3451 return no_state;
3452 }
3453
3454+
3455 void end_visit(const IndexKeyList& v, void* /*visit_state*/)
3456 {
3457 TRACE_VISIT_OUT();
3458@@ -4651,8 +4649,6 @@
3459 ERROR_PARAMS(index->getName()->getStringValue()));
3460 }
3461
3462- keyExpr = wrap_in_atomization(keyExpr);
3463-
3464 xqtref_t type;
3465 xqtref_t ptype;
3466
3467@@ -4664,6 +4660,8 @@
3468 ERROR_PARAMS(index->getName()->getStringValue(),
3469 ZED(ZDST0027_NO_KEY_TYPE_DECL)));
3470 }
3471+
3472+ keyExpr = wrap_in_atomization(keyExpr);
3473 }
3474 else
3475 {
3476@@ -4714,11 +4712,26 @@
3477 ptype->toSchemaString()));
3478 }
3479
3480- keyExpr = wrap_in_type_match(keyExpr,
3481- type,
3482- loc,
3483- TREAT_INDEX_KEY,
3484- index->getName());
3485+ if (!index->isGeneral() &&
3486+ (TypeOps::is_subtype(tm, *ptype, *theRTM.STRING_TYPE_ONE, kloc) ||
3487+ TypeOps::is_subtype(tm, *ptype, *theRTM.DOUBLE_TYPE_ONE, kloc) ||
3488+ TypeOps::is_subtype(tm, *ptype, *theRTM.FLOAT_TYPE_ONE, kloc)))
3489+ {
3490+ keyExpr = wrap_in_type_promotion(keyExpr,
3491+ type,
3492+ PROMOTE_INDEX_KEY,
3493+ index->getName());
3494+ }
3495+ else
3496+ {
3497+ keyExpr = wrap_in_atomization(keyExpr);
3498+
3499+ keyExpr = wrap_in_type_match(keyExpr,
3500+ type,
3501+ loc,
3502+ TREAT_INDEX_KEY,
3503+ index->getName());
3504+ }
3505
3506 keyTypes[i] = ptype->getBaseBuiltinType();
3507 }
3508@@ -4727,12 +4740,11 @@
3509 {
3510 // Eliminate duplicate key values, as they don't play any role in a
3511 // general comparison predicate.
3512- keyExpr = theExprManager->
3513- create_fo_expr(theRootSctx,
3514- theUDF,
3515- keyExpr->get_loc(),
3516- BUILTIN_FUNC(FN_DISTINCT_VALUES_1),
3517- keyExpr);
3518+ keyExpr = CREATE(fo)(theRootSctx,
3519+ theUDF,
3520+ keyExpr->get_loc(),
3521+ BUILTIN_FUNC(FN_DISTINCT_VALUES_1),
3522+ keyExpr);
3523 }
3524
3525 std::string collationUri;
3526@@ -4742,8 +4754,7 @@
3527 collationUri = collationSpec->get_uri().str();
3528
3529 if (! theSctx->is_known_collation(collationUri))
3530- RAISE_ERROR(err::XQST0076, kloc,
3531- ERROR_PARAMS(collationUri));
3532+ RAISE_ERROR(err::XQST0076, kloc, ERROR_PARAMS(collationUri));
3533 }
3534 else if (ptype != NULL &&
3535 TypeOps::is_subtype(tm, *ptype, *theRTM.STRING_TYPE_ONE, loc))
3536@@ -6247,9 +6258,9 @@
3537 pop_scope();
3538 break;
3539 }
3540- case flwor_clause::group_clause:
3541+ case flwor_clause::groupby_clause:
3542 {
3543- group_clause* gc = static_cast<group_clause*>(curClause);
3544+ groupby_clause* gc = static_cast<groupby_clause*>(curClause);
3545
3546 csize numGVars = gc->numGroupingVars();
3547
3548@@ -6877,8 +6888,8 @@
3549 csize numGroupSpecs = groupSpecs.size();
3550
3551 std::vector<std::string> collations;
3552- group_clause::rebind_list_t grouping_rebind;
3553- group_clause::rebind_list_t nongrouping_rebind;
3554+ groupby_clause::rebind_list_t grouping_rebind;
3555+ groupby_clause::rebind_list_t nongrouping_rebind;
3556
3557 static_context* sctx = theSctx;
3558
3559@@ -6984,12 +6995,12 @@
3560 nongrouping_rebind.push_back(std::pair<expr*, var_expr*>(inputExpr, ngVar));
3561 }
3562
3563- group_clause* clause = theExprManager->
3564- create_group_clause(theRootSctx,
3565- loc,
3566- grouping_rebind,
3567- nongrouping_rebind,
3568- collations);
3569+ groupby_clause* clause = theExprManager->
3570+ create_groupby_clause(theRootSctx,
3571+ loc,
3572+ grouping_rebind,
3573+ nongrouping_rebind,
3574+ collations);
3575
3576 theFlworClausesStack.push_back(clause);
3577 }
3578@@ -9823,7 +9834,7 @@
3579 matchExpr->setWildKind(match_all_wild);
3580 break;
3581 }
3582- case ParseConstants::wild_elem:
3583+ case ParseConstants::wild_elem: // pre:*
3584 {
3585 matchExpr->setWildKind(match_name_wild);
3586 matchExpr->setWildName(wildcard->getNsOrPrefix());
3587@@ -9844,16 +9855,16 @@
3588 }
3589
3590 theSctx->expand_qname(qnItem,
3591- ns,
3592- prefix,
3593- localname,
3594- wildcard->get_location());
3595+ ns,
3596+ prefix,
3597+ localname,
3598+ wildcard->get_location());
3599
3600 matchExpr->setQName(qnItem);
3601
3602 break;
3603 }
3604- case ParseConstants::wild_prefix:
3605+ case ParseConstants::wild_prefix: // *:name
3606 {
3607 matchExpr->setWildKind(match_prefix_wild);
3608 matchExpr->setWildName(wildcard->getLocalName());
3609@@ -11044,7 +11055,7 @@
3610 // Create and normalize the fo expr
3611 std::reverse(arguments.begin(), arguments.end());
3612
3613- fo_expr* foExpr = theExprManager->create_fo_expr(theRootSctx, theUDF, loc, f, arguments);
3614+ fo_expr* foExpr = CREATE(fo)(theRootSctx, theUDF, loc, f, arguments);
3615
3616 normalize_fo(foExpr);
3617
3618@@ -11062,37 +11073,36 @@
3619 }
3620
3621 // Some further normalization is required for certain builtin functions
3622- FunctionConsts::FunctionKind lKind = f->getKind();
3623- switch (lKind)
3624+ FunctionConsts::FunctionKind fkind = f->getKind();
3625+ switch (fkind)
3626 {
3627 case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_GENERAL_N:
3628 case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_GENERAL_N:
3629 {
3630 FunctionConsts::FunctionKind fkind = FunctionConsts::OP_SORT_DISTINCT_NODES_ASC_1;
3631
3632- resultExpr = theExprManager->create_fo_expr(theRootSctx, theUDF,
3633- foExpr->get_loc(),
3634- BuiltinFunctionLibrary::getFunction(fkind),
3635- foExpr);
3636+ resultExpr = CREATE(fo)(theRootSctx,
3637+ theUDF,
3638+ foExpr->get_loc(),
3639+ BuiltinFunctionLibrary::getFunction(fkind),
3640+ foExpr);
3641
3642 break;
3643 }
3644 case FunctionConsts::FN_ANALYZE_STRING_2:
3645 case FunctionConsts::FN_ANALYZE_STRING_3:
3646 {
3647- resultExpr = wrap_in_validate_expr_strict(
3648- foExpr,
3649- "http://www.w3.org/2005/xpath-functions");
3650+ resultExpr =
3651+ wrap_in_validate_expr_strict(foExpr, "http://www.w3.org/2005/xpath-functions");
3652
3653 break;
3654 }
3655 case FunctionConsts::FN_SERIALIZE_2:
3656 {
3657- import_schema_auto_prefix(
3658- loc,
3659- "http://www.w3.org/2010/xslt-xquery-serialization",
3660- NULL);
3661-
3662+ import_schema_auto_prefix(loc,
3663+ "http://www.w3.org/2010/xslt-xquery-serialization",
3664+ NULL);
3665+
3666 break;
3667 }
3668 case FunctionConsts::FN_ZORBA_EVAL_1:
3669@@ -11102,12 +11112,12 @@
3670 {
3671 expr_script_kind_t scriptingKind;
3672
3673- if (lKind == FunctionConsts::FN_ZORBA_EVAL_1 ||
3674- lKind == FunctionConsts::FN_ZORBA_EVAL_N_1)
3675+ if (fkind == FunctionConsts::FN_ZORBA_EVAL_1 ||
3676+ fkind == FunctionConsts::FN_ZORBA_EVAL_N_1)
3677 {
3678 scriptingKind = SIMPLE_EXPR;
3679 }
3680- else if (lKind == FunctionConsts::FN_ZORBA_EVAL_U_1)
3681+ else if (fkind == FunctionConsts::FN_ZORBA_EVAL_U_1)
3682 {
3683 scriptingKind = UPDATING_EXPR;
3684 }
3685@@ -11116,13 +11126,12 @@
3686 scriptingKind = SEQUENTIAL_FUNC_EXPR;
3687 }
3688
3689- eval_expr* evalExpr = theExprManager->
3690- create_eval_expr(theRootSctx,
3691- theUDF,
3692- loc,
3693- foExpr->get_arg(0),
3694- scriptingKind,
3695- theNSCtx);
3696+ eval_expr* evalExpr = CREATE(eval)(theRootSctx,
3697+ theUDF,
3698+ loc,
3699+ foExpr->get_arg(0),
3700+ scriptingKind,
3701+ theNSCtx);
3702
3703 resultExpr = evalExpr;
3704
3705@@ -11164,16 +11173,16 @@
3706 zstring query_params;
3707 std::vector<var_expr*> temp_vars;
3708
3709- if (lKind == FunctionConsts::FN_ZORBA_INVOKE_N ||
3710- lKind == FunctionConsts::FN_ZORBA_INVOKE_N_N)
3711+ if (fkind == FunctionConsts::FN_ZORBA_INVOKE_N ||
3712+ fkind == FunctionConsts::FN_ZORBA_INVOKE_N_N)
3713 {
3714 scriptingKind = SIMPLE_EXPR;
3715 }
3716- else if (lKind == FunctionConsts::FN_ZORBA_INVOKE_U_N)
3717+ else if (fkind == FunctionConsts::FN_ZORBA_INVOKE_U_N)
3718 {
3719 scriptingKind = UPDATING_EXPR;
3720 }
3721- else if (lKind == FunctionConsts::FN_ZORBA_INVOKE_S_N)
3722+ else if (fkind == FunctionConsts::FN_ZORBA_INVOKE_S_N)
3723 {
3724 scriptingKind = SEQUENTIAL_FUNC_EXPR;
3725 }
3726@@ -11185,8 +11194,7 @@
3727 }
3728
3729 // create a flwor with LETs to hold the parameters
3730- flwor_expr* flworExpr = theExprManager->
3731- create_flwor_expr(theRootSctx, theUDF, loc, false);
3732+ flwor_expr* flworExpr = CREATE(flwor)(theRootSctx, theUDF, loc, false);
3733
3734 // wrap function's QName
3735 expr* qnameExpr = wrap_in_type_promotion(arguments[0],
3736@@ -13052,8 +13060,8 @@
3737 TRACE_VISIT_OUT();
3738
3739 // if the top of the stack is an axis step expr, add a node test expr to it.
3740- axis_step_expr* axisExpr =
3741- dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
3742+ axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
3743+
3744 if (axisExpr != NULL)
3745 {
3746 match_expr* me = theExprManager->create_match_expr(theRootSctx, theUDF, loc);
3747@@ -13157,8 +13165,7 @@
3748 expand_elem_qname(typeNameItem, typeName->get_name(), loc);
3749
3750 // if the top of the stack is an axis step expr, add a node test expr to it.
3751- axis_step_expr* axisExpr =
3752- dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
3753+ axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
3754
3755 xqtref_t contentType;
3756
3757@@ -13201,19 +13208,16 @@
3758
3759
3760 /*******************************************************************************
3761-
3762 SchemaElementTest ::= "schema-element" "(" ElementDeclaration ")"
3763
3764 ElementDeclaration ::= ElementName
3765-
3766 ********************************************************************************/
3767 void* begin_visit(const SchemaElementTest& v)
3768 {
3769 TRACE_VISIT();
3770
3771 #ifndef ZORBA_NO_XMLSCHEMA
3772- axis_step_expr* axisExpr =
3773- dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
3774+ axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
3775 rchandle<QName> elemName = v.get_elem();
3776 ZORBA_ASSERT(elemName != NULL);
3777
3778@@ -13240,8 +13244,7 @@
3779 theTypeStack.push(seqmatch);
3780 }
3781 #else /* ZORBA_NO_XMLSCHEMA */
3782- RAISE_ERROR(zerr::ZXQP0005_NOT_ENABLED, loc,
3783- ERROR_PARAMS(ZED(XMLSchema)));
3784+ RAISE_ERROR(zerr::ZXQP0005_NOT_ENABLED, loc, ERROR_PARAMS(ZED(XMLSchema)));
3785 #endif /* ZORBA_NO_XMLSCHEMA */
3786 return no_state;
3787 }
3788@@ -13253,6 +13256,11 @@
3789 }
3790
3791
3792+/*******************************************************************************
3793+ AttributeTest ::= "attribute" "(" (AttribNameOrWildcard ("," TypeName)?)? ")"
3794+
3795+ AttribNameOrWildcard ::= AttributeName | "*"
3796+********************************************************************************/
3797 void* begin_visit(const AttributeTest& v)
3798 {
3799 TRACE_VISIT();
3800@@ -13292,8 +13300,8 @@
3801 }
3802
3803 // if the top of the stack is an axis step expr, add a node test expr to it.
3804- axis_step_expr* axisExpr =
3805- dynamic_cast<axis_step_expr*> (peek_nodestk_or_null());
3806+ axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*> (peek_nodestk_or_null());
3807+
3808 if (axisExpr != NULL)
3809 {
3810 match_expr* match = theExprManager->create_match_expr(theRootSctx, theUDF, loc);
3811@@ -13321,13 +13329,18 @@
3812 }
3813
3814
3815+/*******************************************************************************
3816+ SchemaAttributeTest ::= "schema-attribute" "(" AttributeDeclaration ")"
3817+
3818+ SchemaDeclaration ::= AttributeName
3819+********************************************************************************/
3820 void* begin_visit(const SchemaAttributeTest& v)
3821 {
3822 TRACE_VISIT();
3823
3824 #ifndef ZORBA_NO_XMLSCHEMA
3825- axis_step_expr* axisExpr =
3826- dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
3827+ axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
3828+
3829 rchandle<QName> attrName = v.get_attr();
3830 ZORBA_ASSERT(attrName != NULL);
3831
3832@@ -13348,19 +13361,14 @@
3833 }
3834 else
3835 {
3836- xqtref_t seqmatch = CTX_TM->create_schema_attribute_type(attrQNameItem,
3837- TypeConstants::QUANT_ONE,
3838- loc);
3839+ xqtref_t seqmatch = CTX_TM->
3840+ create_schema_attribute_type(attrQNameItem, TypeConstants::QUANT_ONE, loc);
3841
3842 theTypeStack.push(seqmatch);
3843 }
3844
3845 #else /* ZORBA_NO_XMLSCHEMA */
3846- throw XQUERY_EXCEPTION(
3847- zerr::ZXQP0005_NOT_ENABLED,
3848- ERROR_PARAMS( ZED( XMLSchema ) ),
3849- ERROR_LOC( loc )
3850- );
3851+ RAISE_ERROR(zerr::ZXQP0005_NOT_ENABLED, loc, ERROR_PARAMS(ZED(XMLSchema)));
3852 #endif /* ZORBA_NO_XMLSCHEMA */
3853 return no_state;
3854 }
3855@@ -13437,8 +13445,8 @@
3856 {
3857 TRACE_VISIT_OUT();
3858
3859- axis_step_expr* axisExpr =
3860- dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
3861+ axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
3862+
3863 std::string target = v.get_target().str();
3864
3865 store::Item_t qname = NULL;
3866@@ -13451,16 +13459,12 @@
3867 // is not in the lexical space of NCName, a type error is raised [err:XPTY0004]
3868
3869 zstring lNormalizedTarget;
3870- ascii::normalize_whitespace( target, &lNormalizedTarget );
3871+ ascii::normalize_whitespace(target, &lNormalizedTarget);
3872
3873- if (!GenericCast::instance()->castableToNCName(lNormalizedTarget))
3874+ if (!GenericCast::castableToNCName(lNormalizedTarget))
3875 {
3876- throw XQUERY_EXCEPTION(err::XPTY0004,
3877- ERROR_PARAMS(ZED(BadType_23o), lNormalizedTarget,
3878- ZED( NoCastTo_45o ), "NCName"
3879- ),
3880- ERROR_LOC( loc )
3881- );
3882+ RAISE_ERROR(err::XPTY0004, loc,
3883+ ERROR_PARAMS(ZED(BadType_23o), lNormalizedTarget, ZED(NoCastTo_45o), "NCName"));
3884 }
3885
3886 // bugfix (see above); pass normalized string instead of original target
3887@@ -13473,6 +13477,7 @@
3888 match->setTestKind(match_pi_test);
3889 if (target != "")
3890 match->setQName(qname);
3891+
3892 axisExpr->setTest(match);
3893 }
3894 else
3895@@ -13489,7 +13494,7 @@
3896 TypeConstants::QUANT_ONE,
3897 false,
3898 false);
3899- theTypeStack.push (t);
3900+ theTypeStack.push(t);
3901 }
3902 }
3903 }
3904
3905=== modified file 'src/compiler/xqddf/collection_decl.h'
3906--- src/compiler/xqddf/collection_decl.h 2012-09-19 21:16:15 +0000
3907+++ src/compiler/xqddf/collection_decl.h 2013-01-29 17:56:25 +0000
3908@@ -53,30 +53,28 @@
3909
3910 public:
3911 StaticallyKnownCollection(
3912- store::Item_t& aName,
3913- const AnnotationList_t& aAnnotationList,
3914- xqtref_t& aNodeType,
3915- xqtref_t& aCollectionType,
3916- StaticContextConsts::declaration_property_t aUpdateProperty,
3917- StaticContextConsts::declaration_property_t aOrderProperty,
3918- StaticContextConsts::node_modifier_t aNodeModifier
3919- );
3920+ store::Item_t& name,
3921+ const AnnotationList_t& nannotationList,
3922+ xqtref_t& nodeType,
3923+ xqtref_t& collectionType,
3924+ StaticContextConsts::declaration_property_t updateProperty,
3925+ StaticContextConsts::declaration_property_t orderProperty,
3926+ StaticContextConsts::node_modifier_t nodeModifier);
3927
3928 ~StaticallyKnownCollection();
3929
3930 const store::Item* getName() const { return theName.getp(); }
3931
3932- AnnotationList*
3933- getAnnotations() const { return theAnnotations.getp(); };
3934+ AnnotationList* getAnnotations() const { return theAnnotations.getp(); };
3935
3936 StaticContextConsts::declaration_property_t getUpdateProperty() const
3937 {
3938 return theUpdateProperty;
3939 }
3940
3941- StaticContextConsts::declaration_property_t getOrderProperty() const
3942+ bool isOrdered() const
3943 {
3944- return theOrderProperty;
3945+ return theOrderProperty == StaticContextConsts::decl_ordered;
3946 }
3947
3948 StaticContextConsts::node_modifier_t getNodeModifier() const
3949
3950=== modified file 'src/compiler/xqddf/value_index.cpp'
3951--- src/compiler/xqddf/value_index.cpp 2012-10-24 11:32:56 +0000
3952+++ src/compiler/xqddf/value_index.cpp 2013-01-29 17:56:25 +0000
3953@@ -268,12 +268,21 @@
3954 }
3955
3956
3957+/*******************************************************************************
3958+
3959+********************************************************************************/
3960+const std::string& IndexDecl::getCollation(csize i) const
3961+{
3962+ return theOrderModifiers[i].theCollation;
3963+}
3964+
3965+
3966 /******************************************************************************
3967 Check that the domain and key exprs satisfy the constraints specified by the
3968 XQDDF spec. This method is called from the translator, after the domain and
3969 key exprs have been translated and optimized.
3970 *******************************************************************************/
3971-void IndexDecl::analyze(CompilerCB* ccb)
3972+void IndexDecl::analyze()
3973 {
3974 store::Item_t dotQName;
3975 GENV_ITEMFACTORY->createQName(dotQName, "", "", static_context::DOT_VAR_NAME);
3976@@ -285,7 +294,7 @@
3977 if (var)
3978 dotVar = var->getVar();
3979
3980- expr::FreeVars varExprs;
3981+ std::vector<var_expr*> varExprs;
3982
3983 // Check constraints on the domain expr
3984 analyzeExprInternal(getDomainExpr(),
3985@@ -341,12 +350,12 @@
3986 {
3987 // Have to do this here (rather than during runtime) so that we don't have to
3988 // serialize the index exprs.
3989- (void)getDocIndexer(ccb, theLocation);
3990+ (void)getDocIndexer(theLocation);
3991 }
3992
3993 // Have to do this here (rather than during runtime) so that we don't have to
3994 // serialize the index exprs.
3995- (void)getBuildPlan(ccb, theLocation);
3996+ (void)getBuildPlan(theLocation);
3997 }
3998
3999
4000@@ -366,10 +375,12 @@
4001 expr* e,
4002 std::vector<store::Item*>& sourceNames,
4003 std::vector<expr*>& sourceExprs,
4004- FreeVars& varExprs,
4005+ std::vector<var_expr*>& varExprs,
4006 expr* dotVar)
4007 {
4008- if (e->get_expr_kind() == fo_expr_kind)
4009+ switch (e->get_expr_kind())
4010+ {
4011+ case fo_expr_kind:
4012 {
4013 fo_expr* foExpr = static_cast<fo_expr*>(e);
4014 const function* func = foExpr->get_func();
4015@@ -386,7 +397,7 @@
4016 {
4017 const expr* argExpr = foExpr->get_arg(0);
4018
4019- const store::Item* qname = argExpr->getQName(theSctx);
4020+ const store::Item* qname = argExpr->getQName();
4021
4022 if (qname != NULL)
4023 {
4024@@ -405,21 +416,27 @@
4025 ERROR_PARAMS(theName->getStringValue()));
4026 }
4027 }
4028+
4029+ break;
4030 }
4031- else if (e->get_expr_kind() == var_decl_expr_kind)
4032+ case var_decl_expr_kind:
4033 {
4034 var_expr* varExpr = static_cast<var_decl_expr*>(e)->get_var_expr();
4035
4036 ZORBA_ASSERT(varExpr->get_kind() == var_expr::local_var);
4037
4038- varExprs.insert(varExpr);
4039+ varExprs.push_back(varExpr);
4040+
4041+ break;
4042 }
4043- else if (e->get_expr_kind() == flwor_expr_kind ||
4044- e->get_expr_kind() == gflwor_expr_kind)
4045+ case flwor_expr_kind:
4046+ case gflwor_expr_kind:
4047 {
4048 static_cast<const flwor_expr*>(e)->get_vars(varExprs);
4049+
4050+ break;
4051 }
4052- else if (e->get_expr_kind() == var_expr_kind)
4053+ case var_expr_kind:
4054 {
4055 if (e == dotVar)
4056 {
4057@@ -427,12 +444,21 @@
4058 ERROR_PARAMS(theName->getStringValue()));
4059 }
4060
4061+ var_expr* var = static_cast<var_expr*>(e);
4062+
4063 if (e != getDomainVariable() &&
4064- varExprs.find(static_cast<var_expr*>(e)) == varExprs.end())
4065+ std::find(varExprs.begin(), varExprs.end(), var) == varExprs.end())
4066 {
4067 RAISE_ERROR(zerr::ZDST0031_INDEX_HAS_FREE_VARS, e->get_loc(),
4068 ERROR_PARAMS(theName->getStringValue()));
4069 }
4070+
4071+ break;
4072+ }
4073+ default:
4074+ {
4075+ break;
4076+ }
4077 }
4078
4079 ExprIterator iter(e);
4080@@ -445,6 +471,140 @@
4081
4082
4083 /******************************************************************************
4084+ Create the expression that represents the index as a view.
4085+
4086+ For now, this is done for value indexes only
4087+
4088+ for $newdot at $newpos in cloned_domain_expr
4089+ return value-index-entry-builder($$newdot, cloned_key1_expr, ..., cloned_keyN_expr)
4090+*******************************************************************************/
4091+flwor_expr* IndexDecl::getViewExpr()
4092+{
4093+ theDomainClause = NULL;
4094+
4095+ expr* domainExpr = getDomainExpr();
4096+ var_expr* dot = getDomainVariable();
4097+ var_expr* pos = getDomainPositionVariable();
4098+ static_context* sctx = domainExpr->get_sctx();
4099+ user_function* udf = domainExpr->get_udf();
4100+
4101+ assert(theIsTemp || udf == NULL);
4102+
4103+ const QueryLoc& domloc = domainExpr->get_loc();
4104+
4105+ // Clone the domain expr, the domain variable, and the domain pos variable.
4106+ // These 2 vars are referenced by the key exprs..
4107+ expr::substitution_t subst;
4108+ expr* newdom = domainExpr->clone(udf, subst);
4109+
4110+ var_expr* newdot = theCCB->theEM->
4111+ create_var_expr(sctx, udf, domloc, dot->get_kind(), dot->get_name());
4112+
4113+ var_expr* newpos = theCCB->theEM->
4114+ create_var_expr(sctx, udf, domloc, pos->get_kind(), pos->get_name());
4115+
4116+ //
4117+ // Create for clause (this has to be done here so that the cloned dot var gets
4118+ // associated with the cloned domain expr; this is needed before cloning the
4119+ // key expr) :
4120+ //
4121+ // for $newdot at $newpos in new_domain_expr
4122+ //
4123+ for_clause* fc = theCCB->theEM->
4124+ create_for_clause(sctx, domloc, newdot, newdom, newpos);
4125+
4126+ //
4127+ // Create flwor expr:
4128+ //
4129+ // for $newdot at $newpos in new_domain_expr
4130+ // return $newdot
4131+ //
4132+
4133+ expr* returnExpr = theCCB->theEM->create_wrapper_expr(sctx, udf, domloc, newdot);
4134+
4135+ flwor_expr* flworExpr = theCCB->theEM->create_flwor_expr(sctx, udf, domloc, false);
4136+ flworExpr->set_return_expr(returnExpr);
4137+ flworExpr->add_clause(fc);
4138+
4139+ //
4140+ // Handle the key exprs
4141+ //
4142+ // for $newdot at $newpos in new_domain_expr
4143+ // let $key_1 := new_key_expr_1
4144+ // .....
4145+ // let $key_N := new_key_expr_N
4146+ // where $key_1 eq $arg_1 and ... and $key_N eq $arg_N
4147+ // return $newdot
4148+ //
4149+ //function* compFunc = BUILTIN_FUNC(OP_EQUAL_2);
4150+ //std::vector<expr*> predExprs;
4151+ csize numKeys = theKeyExprs.size();
4152+
4153+ for (csize i = 0; i < numKeys; ++i)
4154+ {
4155+ // clone the key expr
4156+ subst.clear();
4157+ subst[dot] = newdot;
4158+ subst[pos] = newpos;
4159+
4160+ expr* keyClone = theKeyExprs[i]->clone(udf, subst);
4161+
4162+ const QueryLoc& keyloc = keyClone->get_loc();
4163+
4164+ // create the LET clause
4165+ std::string localName = "$$key_" + ztd::to_string(i);
4166+ store::Item_t keyVarName;
4167+ GENV_ITEMFACTORY->createQName(keyVarName, "", "", localName);
4168+
4169+ var_expr* keyVar = theCCB->theEM->
4170+ create_var_expr(sctx, udf, keyloc, var_expr::let_var, keyVarName);
4171+
4172+ let_clause* lc = theCCB->theEM->create_let_clause(sctx, keyloc, keyVar, keyClone);
4173+
4174+ flworExpr->add_clause(lc);
4175+
4176+#if 0
4177+ // create the predicate
4178+ expr* op1 = theCCB->theEM->create_wrapper_expr(sctx, udf, keyloc, keyVar);
4179+
4180+ localName = "$$arg_" + ztd::to_string(i);
4181+ store::Item_t argVarName;
4182+ GENV_ITEMFACTORY->createQName(argVarName, "", "", localName);
4183+
4184+ expr* op2 = theCCB->theEM->
4185+ create_var_expr(sctx, udf, keyloc, var_expr::arg_var, keyVarName);
4186+
4187+ expr* pred = theCCB->theEM->
4188+ create_fo_expr(sctx, udf, keyloc, compFunc, op1, op2);
4189+
4190+ predExprs.push_back(pred);
4191+#endif
4192+ }
4193+
4194+#if 0
4195+ expr* whereExpr;
4196+
4197+ if (predExprs.size() > 1)
4198+ {
4199+ whereExpr = theCCB->theEM->
4200+ create_fo_expr(sctx, udf, domloc, BUILTIN_FUNC(OP_AND_N), predExprs);
4201+ }
4202+ else
4203+ {
4204+ whereExpr = predExprs[0];
4205+ }
4206+
4207+ where_clause* wc = theCCB->theEM->
4208+ create_where_clause(sctx, whereExpr->get_loc(), whereExpr);
4209+
4210+ flworExpr->add_clause(wc);
4211+#endif
4212+
4213+ return flworExpr;
4214+}
4215+
4216+
4217+/******************************************************************************
4218 Create the expression that "builds" the index, if not done already. The expr
4219 to build is the following, for value and general indexes, respectively:
4220
4221@@ -458,7 +618,7 @@
4222 then populates the index by creating entries out of the items returned by
4223 this expr.
4224 *******************************************************************************/
4225-expr* IndexDecl::getBuildExpr(CompilerCB* ccb, const QueryLoc& loc)
4226+expr* IndexDecl::getBuildExpr(const QueryLoc& loc)
4227 {
4228 if (theBuildExpr != NULL)
4229 return theBuildExpr;
4230@@ -545,11 +705,11 @@
4231
4232 theBuildExpr = flworExpr;
4233
4234- if (ccb->theConfig.optimize_cb != NULL)
4235+ if (theCCB->theConfig.optimize_cb != NULL)
4236 {
4237 std::string msg = "build expr for index " + theName->getStringValue().str();
4238
4239- ccb->theConfig.optimize_cb(theBuildExpr, msg);
4240+ theCCB->theConfig.optimize_cb(theBuildExpr, msg);
4241 }
4242
4243 return theBuildExpr;
4244@@ -559,15 +719,15 @@
4245 /*******************************************************************************
4246
4247 ********************************************************************************/
4248-PlanIterator* IndexDecl::getBuildPlan(CompilerCB* ccb, const QueryLoc& loc)
4249+PlanIterator* IndexDecl::getBuildPlan(const QueryLoc& loc)
4250 {
4251 if (theBuildPlan != NULL)
4252 return theBuildPlan.getp();
4253
4254- expr* buildExpr = getBuildExpr(ccb, loc);
4255+ expr* buildExpr = getBuildExpr(loc);
4256
4257 ulong nextVarId = 1;
4258- theBuildPlan = codegen("index", buildExpr, ccb, nextVarId);
4259+ theBuildPlan = codegen("index", buildExpr, theCCB, nextVarId);
4260
4261 return theBuildPlan.getp();
4262 }
4263@@ -577,9 +737,7 @@
4264 Called from ApplyIterator::nextImpl before it actually starts applying the
4265 updates.
4266 ********************************************************************************/
4267-DocIndexer* IndexDecl::getDocIndexer(
4268- CompilerCB* ccb,
4269- const QueryLoc& loc)
4270+DocIndexer* IndexDecl::getDocIndexer(const QueryLoc& loc)
4271 {
4272 if (theDocIndexer != NULL)
4273 return theDocIndexer.getp();
4274@@ -587,9 +745,7 @@
4275 if (theMaintenanceMode != DOC_MAP)
4276 return NULL;
4277
4278- std::stringstream ss;
4279- ss << "$$idx_doc_var_" << this;
4280- std::string varname = ss.str();
4281+ std::string varname = "$$idx_doc_var";
4282 store::Item_t docVarName;
4283 GENV_ITEMFACTORY->createQName(docVarName, "", "", varname.c_str());
4284
4285@@ -697,11 +853,11 @@
4286 flworExpr->set_return_expr(returnExpr);
4287 flworExpr->add_clause(fc);
4288
4289- if (ccb->theConfig.optimize_cb != NULL)
4290+ if (theCCB->theConfig.optimize_cb != NULL)
4291 {
4292 std::string msg = "entry-creator expr for index " + theName->getStringValue().str();
4293
4294- ccb->theConfig.optimize_cb(flworExpr, msg);
4295+ theCCB->theConfig.optimize_cb(flworExpr, msg);
4296 }
4297
4298 theDocIndexerExpr = flworExpr;
4299@@ -709,7 +865,7 @@
4300 //
4301 // Generate the runtime plan for theDocIndexerExpr
4302 //
4303- theDocIndexerPlan = codegen("doc indexer", flworExpr, ccb, nextVarId);
4304+ theDocIndexerPlan = codegen("doc indexer", flworExpr, theCCB, nextVarId);
4305
4306 //
4307 // Create theDocIndexer obj
4308
4309=== modified file 'src/compiler/xqddf/value_index.h'
4310--- src/compiler/xqddf/value_index.h 2012-10-22 15:10:23 +0000
4311+++ src/compiler/xqddf/value_index.h 2013-01-29 17:56:25 +0000
4312@@ -31,6 +31,8 @@
4313 class ExprManager;
4314 class dynamic_context;
4315 class DocIndexer;
4316+class flwor_expr;
4317+
4318 typedef rchandle<DocIndexer> DocIndexer_t;
4319
4320
4321@@ -353,29 +355,33 @@
4322
4323 void setOrderModifiers(const std::vector<OrderModifier>& modifiers);
4324
4325+ const std::string& getCollation(csize i) const;
4326+
4327 csize numSources() const { return theSourceNames.size(); }
4328
4329 const store::Item* getSourceName(csize i) const { return theSourceNames[i]; }
4330
4331 const expr* getDomainSourceExpr(csize i) const { return theDomainSourceExprs[i]; }
4332
4333- void analyze(CompilerCB* ccb);
4334-
4335- expr* getBuildExpr(CompilerCB* ccb, const QueryLoc& loc);
4336-
4337- PlanIterator* getBuildPlan(CompilerCB* ccb, const QueryLoc& loc);
4338-
4339- DocIndexer* getDocIndexer(CompilerCB* ccb, const QueryLoc& loc);
4340+ void analyze();
4341+
4342+ flwor_expr* getViewExpr();
4343+
4344+ expr* getBuildExpr(const QueryLoc& loc);
4345+
4346+ PlanIterator* getBuildPlan(const QueryLoc& loc);
4347+
4348+ DocIndexer* getDocIndexer(const QueryLoc& loc);
4349
4350 std::string toString();
4351
4352 private:
4353 void analyzeExprInternal(
4354- expr* e,
4355- std::vector<store::Item*>& sourceNames,
4356- std::vector<expr*>& sourceExprs,
4357- FreeVars& varExprs,
4358- expr* dotVar);
4359+ expr* e,
4360+ std::vector<store::Item*>& sourceNames,
4361+ std::vector<expr*>& sourceExprs,
4362+ std::vector<var_expr*>& varExprs,
4363+ expr* dotVar);
4364 };
4365
4366
4367
4368=== modified file 'src/context/sctx_map_iterator.h'
4369--- src/context/sctx_map_iterator.h 2012-09-19 21:16:15 +0000
4370+++ src/context/sctx_map_iterator.h 2013-01-29 17:56:25 +0000
4371@@ -45,8 +45,8 @@
4372
4373 public:
4374 SctxMapIterator(
4375- const static_context* aSctx,
4376- ItemsMap* (static_context::*aMapGetter)() const);
4377+ const static_context* aSctx,
4378+ ItemsMap* (static_context::*aMapGetter)() const);
4379
4380 virtual ~SctxMapIterator();
4381
4382
4383=== modified file 'src/context/static_context.cpp'
4384--- src/context/static_context.cpp 2013-01-24 09:47:40 +0000
4385+++ src/context/static_context.cpp 2013-01-29 17:56:25 +0000
4386@@ -550,6 +550,7 @@
4387 ns == ZORBA_JSON_FN_NS ||
4388 ns == ZORBA_FETCH_FN_NS ||
4389 ns == ZORBA_NODE_FN_NS ||
4390+ ns == ZORBA_UTIL_FN_NS ||
4391 #ifndef ZORBA_NO_FULL_TEXT
4392 ns == ZORBA_FULL_TEXT_FN_NS ||
4393 #endif /* ZORBA_NO_FULL_TEXT */
4394@@ -3153,7 +3154,7 @@
4395 }
4396
4397
4398-/***************************************************************************//**
4399+/*******************************************************************************
4400
4401 ********************************************************************************/
4402 store::Iterator_t static_context::index_names() const
4403@@ -3162,6 +3163,32 @@
4404 }
4405
4406
4407+/*******************************************************************************
4408+
4409+********************************************************************************/
4410+void static_context::get_index_decls(std::vector<IndexDecl*>& decls) const
4411+{
4412+ const static_context* sctx = this;
4413+
4414+ while (sctx != NULL)
4415+ {
4416+ if (sctx->theIndexMap)
4417+ {
4418+ IndexMap::iterator ite = sctx->theIndexMap->begin();
4419+ IndexMap::iterator end = sctx->theIndexMap->end();
4420+
4421+ for (; ite != end; ++ite)
4422+ {
4423+ IndexDecl* decl = ite.getValue().getp();
4424+ decls.push_back(decl);
4425+ }
4426+ }
4427+
4428+ sctx = sctx->theParent;
4429+ }
4430+}
4431+
4432+
4433 /////////////////////////////////////////////////////////////////////////////////
4434 // //
4435 // XQDDF Integrity Constraints //
4436
4437=== modified file 'src/context/static_context.h'
4438--- src/context/static_context.h 2013-01-11 17:37:08 +0000
4439+++ src/context/static_context.h 2013-01-29 17:56:25 +0000
4440@@ -957,6 +957,8 @@
4441
4442 IndexDecl* lookup_index(const store::Item* qname) const;
4443
4444+ void get_index_decls(std::vector<IndexDecl*>& decls) const;
4445+
4446 store::Iterator_t index_names() const;
4447
4448
4449
4450=== modified file 'src/functions/func_booleans_impl.cpp'
4451--- src/functions/func_booleans_impl.cpp 2012-12-28 10:24:59 +0000
4452+++ src/functions/func_booleans_impl.cpp 2013-01-29 17:56:25 +0000
4453@@ -129,8 +129,8 @@
4454 xqtref_t getReturnType(const fo_expr* caller) const;
4455
4456 function* specialize(
4457- static_context* sctx,
4458- const std::vector<xqtref_t>& argTypes) const;
4459+ static_context* sctx,
4460+ const std::vector<xqtref_t>& argTypes) const;
4461 };
4462
4463
4464
4465=== modified file 'src/functions/func_collections_impl.cpp'
4466--- src/functions/func_collections_impl.cpp 2012-12-11 13:33:18 +0000
4467+++ src/functions/func_collections_impl.cpp 2013-01-29 17:56:25 +0000
4468@@ -78,7 +78,7 @@
4469
4470 static_context* sctx = caller->get_sctx();
4471
4472- const store::Item* qname = caller->get_arg(0)->getQName(sctx);
4473+ const store::Item* qname = caller->get_arg(0)->getQName();
4474
4475 if (qname != NULL)
4476 {
4477@@ -90,8 +90,10 @@
4478 }
4479 else
4480 {
4481- RAISE_ERROR(zerr::ZDDY0001_COLLECTION_NOT_DECLARED, caller->get_loc(),
4482- ERROR_PARAMS(qname->getStringValue()));
4483+ return theSignature.returnType();
4484+
4485+ //RAISE_ERROR(zerr::ZDDY0001_COLLECTION_NOT_DECLARED, caller->get_loc(),
4486+ //ERROR_PARAMS(qname->getStringValue()));
4487 }
4488 }
4489 else
4490
4491=== modified file 'src/functions/func_eval.cpp'
4492--- src/functions/func_eval.cpp 2012-09-19 21:16:15 +0000
4493+++ src/functions/func_eval.cpp 2013-01-29 17:56:25 +0000
4494@@ -91,6 +91,8 @@
4495 CODEGEN_DECL();
4496 };
4497
4498+
4499+
4500 PlanIter_t fn_zorba_eval::codegen(
4501 CompilerCB*,
4502 static_context* sctx,
4503@@ -102,6 +104,7 @@
4504 return NULL;
4505 }
4506
4507+
4508 PlanIter_t fn_zorba_eval_n::codegen(
4509 CompilerCB*,
4510 static_context* sctx,
4511
4512=== modified file 'src/functions/func_index_ddl.h'
4513--- src/functions/func_index_ddl.h 2012-09-19 21:16:15 +0000
4514+++ src/functions/func_index_ddl.h 2013-01-29 17:56:25 +0000
4515@@ -249,7 +249,14 @@
4516
4517 /*******************************************************************************
4518 fn-zorba-ddl:probe-index-range-value(
4519- $indexName as xs:QName, ....) as node()*
4520+ $indexName as xs:QName,
4521+ $lowerBound1 as xs:anyAtomicType?,
4522+ $upperBound1 as xs:anyAtomicType?,
4523+ $haveLowerBound1 as xs:boolean,
4524+ $haveUpperBound1 as xs:boolean,
4525+ $lowerBoundIncluded1 as xs:boolean,
4526+ $upperBoundIncluded1 as xs:boolean,
4527+ ....) as node()*
4528
4529 Note: the translator wraps calls to this function with an OP_NODE_SORT_ASC
4530 function.
4531
4532=== modified file 'src/runtime/collections/collections_impl.cpp'
4533--- src/runtime/collections/collections_impl.cpp 2013-01-17 04:43:05 +0000
4534+++ src/runtime/collections/collections_impl.cpp 2013-01-29 17:56:25 +0000
4535@@ -789,7 +789,7 @@
4536 ZORBA_ASSERT(false);
4537 }
4538
4539- if (collectionDecl->getOrderProperty() == StaticContextConsts::decl_unordered)
4540+ if (collectionDecl && !collectionDecl->isOrdered())
4541 {
4542 RAISE_ERROR(zerr::ZDDY0012_COLLECTION_UNORDERED_BAD_OPERATION, loc,
4543 ERROR_PARAMS(name->getStringValue(), "insert" ));
4544@@ -869,7 +869,7 @@
4545 ZORBA_ASSERT(false);
4546 }
4547
4548- if (collectionDecl->getOrderProperty() == StaticContextConsts::decl_unordered)
4549+ if (collectionDecl && !collectionDecl->isOrdered())
4550 {
4551 RAISE_ERROR(zerr::ZDDY0012_COLLECTION_UNORDERED_BAD_OPERATION, loc,
4552 ERROR_PARAMS(name->getStringValue(), "insert"));
4553@@ -957,7 +957,7 @@
4554 ZORBA_ASSERT(false);
4555 }
4556
4557- if (collectionDecl->getOrderProperty() == StaticContextConsts::decl_unordered)
4558+ if (collectionDecl && !collectionDecl->isOrdered())
4559 {
4560 RAISE_ERROR(zerr::ZDDY0012_COLLECTION_UNORDERED_BAD_OPERATION, loc,
4561 ERROR_PARAMS(name->getStringValue(), "insert" ));
4562@@ -1048,7 +1048,7 @@
4563 ZORBA_ASSERT(false);
4564 }
4565
4566- if (collectionDecl->getOrderProperty() == StaticContextConsts::decl_unordered)
4567+ if (collectionDecl && !collectionDecl->isOrdered())
4568 {
4569 RAISE_ERROR(zerr::ZDDY0011_COLLECTION_NODE_NOT_FOUND, loc,
4570 ERROR_PARAMS(name->getStringValue()));
4571@@ -1678,8 +1678,7 @@
4572 }
4573 }
4574
4575- if (collectionDecl &&
4576- collectionDecl->getOrderProperty() == StaticContextConsts::decl_unordered)
4577+ if (collectionDecl && !collectionDecl->isOrdered())
4578 {
4579 RAISE_ERROR(zerr::ZDDY0012_COLLECTION_UNORDERED_BAD_OPERATION, loc,
4580 ERROR_PARAMS(name->getStringValue(), "delete" ));
4581@@ -1775,8 +1774,7 @@
4582 }
4583 }
4584
4585- if (collectionDecl &&
4586- collectionDecl->getOrderProperty() == StaticContextConsts::decl_unordered)
4587+ if (collectionDecl && !collectionDecl->isOrdered())
4588 {
4589 RAISE_ERROR(zerr::ZDDY0012_COLLECTION_UNORDERED_BAD_OPERATION, loc,
4590 ERROR_PARAMS(name->getStringValue(), "delete"));
4591
4592=== modified file 'src/runtime/core/apply_updates.cpp'
4593--- src/runtime/core/apply_updates.cpp 2012-12-01 00:06:15 +0000
4594+++ src/runtime/core/apply_updates.cpp 2013-01-29 17:56:25 +0000
4595@@ -174,7 +174,7 @@
4596
4597 if (indexDecl->getMaintenanceMode() == IndexDecl::DOC_MAP)
4598 {
4599- DocIndexer* docIndexer = indexDecl->getDocIndexer(ccb, loc);
4600+ DocIndexer* docIndexer = indexDecl->getDocIndexer(loc);
4601 assert(docIndexer != NULL);
4602
4603 docIndexer->setup(ccb);
4604@@ -215,7 +215,7 @@
4605
4606 if (zorbaIndex->getMaintenanceMode() == IndexDecl::REBUILD)
4607 {
4608- PlanIter_t buildPlan = zorbaIndex->getBuildPlan(ccb, loc);
4609+ PlanIter_t buildPlan = zorbaIndex->getBuildPlan(loc);
4610
4611 PlanWrapper_t planWrapper = new PlanWrapper(buildPlan,
4612 ccb,
4613
4614=== modified file 'src/runtime/core/sequencetypes.cpp'
4615--- src/runtime/core/sequencetypes.cpp 2013-01-17 04:43:05 +0000
4616+++ src/runtime/core/sequencetypes.cpp 2013-01-29 17:56:25 +0000
4617@@ -534,6 +534,12 @@
4618 break;
4619 }
4620 #endif
4621+ case PROMOTE_INDEX_KEY:
4622+ {
4623+ RAISE_ERROR(zerr::ZDTY0011_INDEX_KEY_TYPE_ERROR, loc,
4624+ ERROR_PARAMS(valueType, targetType, theQName->getStringValue()));
4625+ break;
4626+ }
4627 default:
4628 {
4629 ZORBA_ASSERT(false);
4630
4631=== modified file 'src/runtime/eval/eval.cpp'
4632--- src/runtime/eval/eval.cpp 2013-01-08 08:34:08 +0000
4633+++ src/runtime/eval/eval.cpp 2013-01-29 17:56:25 +0000
4634@@ -18,6 +18,7 @@
4635 #include <sstream>
4636
4637 #include "store/api/temp_seq.h"
4638+#include "store/api/item_factory.h"
4639
4640 #include "runtime/eval/eval.h"
4641
4642@@ -31,6 +32,7 @@
4643 #include "compiler/api/compiler_api.h"
4644 #include "compiler/expression/var_expr.h"
4645 #include "compiler/expression/expr_manager.h"
4646+#include "compiler/rewriter/tools/expr_tools.h"
4647
4648 #include "context/dynamic_context.h"
4649 #include "context/static_context.h"
4650
4651=== modified file 'src/runtime/indexing/index_ddl.cpp'
4652--- src/runtime/indexing/index_ddl.cpp 2013-01-17 04:43:05 +0000
4653+++ src/runtime/indexing/index_ddl.cpp 2013-01-29 17:56:25 +0000
4654@@ -82,16 +82,7 @@
4655 xqtref_t searchKeyType = tm->create_value_type(searchKey);
4656 xqtref_t indexKeyType = (indexDecl->getKeyTypes())[keyNo];
4657
4658- if (indexKeyType != NULL &&
4659- !TypeOps::is_subtype(tm, *searchKeyType, *indexKeyType))
4660- {
4661- RAISE_ERROR(err::XPTY0004, loc,
4662- ERROR_PARAMS(ZED(SearchKeyTypeMismatch_234),
4663- *searchKeyType,
4664- indexDecl->getName()->getStringValue(),
4665- *indexKeyType));
4666- }
4667- else if (indexKeyType == NULL)
4668+ if (indexKeyType == NULL)
4669 {
4670 ZORBA_ASSERT(indexDecl->isGeneral());
4671
4672@@ -113,6 +104,47 @@
4673 indexDecl->getName()->getStringValue()));
4674 }
4675 }
4676+ else if (!TypeOps::is_subtype(tm, *searchKeyType, *indexKeyType))
4677+ {
4678+ store::SchemaTypeCode searchKeyTypeCode = searchKey->getTypeCode();
4679+
4680+ if (TypeOps::is_subtype(tm, *indexKeyType, *rtm.STRING_TYPE_ONE) &&
4681+ (searchKeyTypeCode == store::XS_UNTYPED_ATOMIC ||
4682+ searchKeyTypeCode == store::XS_ANY_URI))
4683+ {
4684+ return;
4685+ }
4686+
4687+ if (TypeOps::is_subtype(tm, *indexKeyType, *rtm.DOUBLE_TYPE_ONE))
4688+ {
4689+ if (TypeOps::is_subtype(searchKeyTypeCode, store::XS_DECIMAL))
4690+ {
4691+ GENV_STORE.getItemFactory()->
4692+ createDouble(searchKey, xs_double(searchKey->getDecimalValue()));
4693+ }
4694+ else if (TypeOps::is_subtype(searchKeyTypeCode, store::XS_FLOAT))
4695+ {
4696+ GENV_STORE.getItemFactory()->
4697+ createDouble(searchKey, xs_double(searchKey->getFloatValue()));
4698+ }
4699+
4700+ return;
4701+ }
4702+
4703+ if (TypeOps::is_subtype(tm, *indexKeyType, *rtm.FLOAT_TYPE_ONE) &&
4704+ TypeOps::is_subtype(searchKeyTypeCode, store::XS_DECIMAL))
4705+ {
4706+ GENV_STORE.getItemFactory()->
4707+ createDouble(searchKey, xs_float(searchKey->getDecimalValue()));
4708+ return;
4709+ }
4710+
4711+ RAISE_ERROR(err::XPTY0004, loc,
4712+ ERROR_PARAMS(ZED(SearchKeyTypeMismatch_234),
4713+ *searchKeyType,
4714+ indexDecl->getName()->getStringValue(),
4715+ *indexKeyType));
4716+ }
4717 }
4718
4719
4720@@ -242,23 +274,17 @@
4721
4722 if ((indexDecl = theSctx->lookup_index(qname)) == NULL)
4723 {
4724- throw XQUERY_EXCEPTION(
4725- zerr::ZDDY0021_INDEX_NOT_DECLARED,
4726- ERROR_PARAMS( qname->getStringValue() ),
4727- ERROR_LOC( loc )
4728- );
4729+ RAISE_ERROR(zerr::ZDDY0021_INDEX_NOT_DECLARED, loc,
4730+ ERROR_PARAMS(qname->getStringValue()));
4731 }
4732
4733 if (GENV_STORE.getIndex(qname) != NULL)
4734 {
4735- throw XQUERY_EXCEPTION(
4736- zerr::ZDDY0022_INDEX_ALREADY_EXISTS,
4737- ERROR_PARAMS( qname->getStringValue() ),
4738- ERROR_LOC( loc )
4739- );
4740+ RAISE_ERROR(zerr::ZDDY0022_INDEX_ALREADY_EXISTS, loc,
4741+ ERROR_PARAMS(qname->getStringValue()));
4742 }
4743
4744- buildPlan = indexDecl->getBuildPlan(ccb, loc);
4745+ buildPlan = indexDecl->getBuildPlan(loc);
4746
4747 planWrapper = new PlanWrapper(buildPlan, ccb, NULL, NULL, 0, false, 0);
4748
4749@@ -266,7 +292,8 @@
4750
4751 result = GENV_ITEMFACTORY->createPendingUpdateList();
4752
4753- reinterpret_cast<store::PUL*>(result.getp())->addCreateIndex(&loc, qname, spec, planWrapper);
4754+ reinterpret_cast<store::PUL*>(result.getp())->
4755+ addCreateIndex(&loc, qname, spec, planWrapper);
4756
4757 STACK_PUSH(true, state);
4758
4759@@ -387,7 +414,7 @@
4760 );
4761 }
4762
4763- buildPlan = indexDecl->getBuildPlan(ccb, loc);
4764+ buildPlan = indexDecl->getBuildPlan(loc);
4765
4766 planWrapper = new PlanWrapper(buildPlan, ccb, dctx, NULL, 0, false, 0);
4767
4768@@ -607,7 +634,7 @@
4769 TypeManager* tm = theSctx->get_typemanager();
4770 RootTypeManager& rtm = GENV_TYPESYSTEM;
4771 xs_integer lSkip = xs_integer::zero();
4772- ulong lAmountNonKeyParams = (theSkip ? 2 : 1);
4773+ ulong numNonKeyParams = (theSkip ? 2 : 1);
4774
4775 try
4776 {
4777@@ -627,16 +654,13 @@
4778 ERROR_PARAMS(qnameItem->getStringValue()));
4779 }
4780
4781- if ( state->theIndexDecl->getNumKeyExprs()
4782- != numChildren - lAmountNonKeyParams )
4783+ if (state->theIndexDecl->getNumKeyExprs() != numChildren - numNonKeyParams)
4784 {
4785 RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
4786- ERROR_PARAMS(
4787- qnameItem->getStringValue(),
4788- "index",
4789- numChildren - lAmountNonKeyParams,
4790- state->theIndexDecl->getNumKeyExprs())
4791- );
4792+ ERROR_PARAMS(qnameItem->getStringValue(),
4793+ "index",
4794+ numChildren - numNonKeyParams,
4795+ state->theIndexDecl->getNumKeyExprs()));
4796 }
4797
4798 state->theIndex = (state->theIndexDecl->isTemp() ?
4799@@ -666,7 +690,7 @@
4800 lSkip = xs_integer::zero();
4801 }
4802
4803- for (i = lAmountNonKeyParams; i < numChildren; ++i)
4804+ for (i = numNonKeyParams; i < numChildren; ++i)
4805 {
4806 if (!consumeNext(keyItem, theChildren[i], planState))
4807 {
4808@@ -676,12 +700,11 @@
4809
4810 if (theCheckKeyType)
4811 {
4812- checkKeyType(loc, tm, state->theIndexDecl,
4813- i - lAmountNonKeyParams, keyItem);
4814+ checkKeyType(loc, tm, state->theIndexDecl, i - numNonKeyParams, keyItem);
4815 }
4816
4817 if (state->theIndexDecl->isGeneral() &&
4818- (state->theIndexDecl->getKeyTypes())[i - lAmountNonKeyParams] == NULL)
4819+ (state->theIndexDecl->getKeyTypes())[i - numNonKeyParams] == NULL)
4820 {
4821 xqtref_t searchKeyType = tm->create_value_type(keyItem);
4822
4823
4824=== modified file 'src/store/naive/simple_index.cpp'
4825--- src/store/naive/simple_index.cpp 2013-01-16 15:16:33 +0000
4826+++ src/store/naive/simple_index.cpp 2013-01-29 17:56:25 +0000
4827@@ -488,7 +488,7 @@
4828 bool lowerIncl,
4829 bool upperIncl)
4830 {
4831- ulong size = theLowerBounds.size();
4832+ csize size = theLowerBounds.size();
4833 theLowerBounds.resize(size + 1);
4834 theUpperBounds.resize(size + 1);
4835 theRangeFlags.resize(size + 1);
4836@@ -507,13 +507,13 @@
4837 ********************************************************************************/
4838 bool IndexBoxValueCondition::test(const store::IndexKey& key) const
4839 {
4840- ulong numCols = theLowerBounds.size();
4841+ csize numCols = theLowerBounds.size();
4842
4843 ZORBA_ASSERT(numCols <= theIndex->getNumColumns());
4844
4845 long timezone = theIndex->getSpecification().theTimezone;
4846
4847- for (ulong i = 0; i < numCols; i++)
4848+ for (csize i = 0; i < numCols; i++)
4849 {
4850 const XQPCollator* collator = theIndex->getCollator(i);
4851
4852
4853=== modified file 'src/store/naive/simple_index_value.cpp'
4854--- src/store/naive/simple_index_value.cpp 2013-01-03 21:23:14 +0000
4855+++ src/store/naive/simple_index_value.cpp 2013-01-29 17:56:25 +0000
4856@@ -386,14 +386,17 @@
4857 (*pos).second->transfer_back(value);
4858 key = const_cast<store::IndexKey*>((*pos).first);
4859
4860+ //std::cout << "Index Entry Insert [" << *key << ","
4861+ // << *((*pos).second) << "]" << std::endl;
4862+
4863 return true;
4864 }
4865
4866 ValueIndexValue* valueSet = new ValueIndexValue(1);
4867 (*valueSet)[0].transfer(value);
4868
4869- //std::cout << "Index Entry Insert [" << key << ","
4870- // << valueSet << "]" << std::endl;
4871+ //std::cout << "Index Entry Insert [" << *key << ","
4872+ // << *valueSet << "]" << std::endl;
4873
4874 // Note: ownership of the key obj passes to the index.
4875 theMap.insert(key, valueSet);
4876
4877=== modified file 'src/store/util/item_vector.cpp'
4878--- src/store/util/item_vector.cpp 2012-09-19 21:16:15 +0000
4879+++ src/store/util/item_vector.cpp 2013-01-29 17:56:25 +0000
4880@@ -40,16 +40,16 @@
4881 ********************************************************************************/
4882 std::ostream& operator<<(std::ostream& os, const ItemVector& key)
4883 {
4884- ulong size = (ulong)key.theItems.size();
4885-
4886- os << "[";
4887-
4888- for (ulong i = 0; i < size; i++)
4889+ csize size = key.theItems.size();
4890+
4891+ os << "[ ";
4892+
4893+ for (csize i = 0; i < size; ++i)
4894 {
4895 if (key.theItems[i] == NULL)
4896- os << "NULL";
4897+ os << "NULL ";
4898 else
4899- os << key.theItems[i]->getStringValue();
4900+ os << key.theItems[i]->getStringValue() << " ";
4901 }
4902
4903 os << "]";
4904
4905=== modified file 'src/system/zorba_properties.h'
4906--- src/system/zorba_properties.h 2012-09-19 21:16:15 +0000
4907+++ src/system/zorba_properties.h 2013-01-29 17:56:25 +0000
4908@@ -79,6 +79,7 @@
4909 bool theInlineUdf;
4910 bool theLoopHoisting;
4911 bool theInferJoins;
4912+ bool theUseIndexes;
4913 bool theNoCopyOptim;
4914 int theSerializeOnlyQuery;
4915 bool theTraceTranslator;
4916@@ -123,6 +124,7 @@
4917 theInlineUdf = true;
4918 theLoopHoisting = true;
4919 theInferJoins = true;
4920+ theUseIndexes = true;
4921 theNoCopyOptim = true;
4922 theSerializeOnlyQuery = -1;
4923 theTraceTranslator = false;
4924@@ -161,11 +163,12 @@
4925 const bool &forceGflwor () const { return theForceGflwor; }
4926 const bool &reorderGlobals () const { return theReorderGlobals; }
4927 const bool &specializeNum () const { return theSpecializeNum; }
4928- const bool &specializeCmp () const { return theSpecializeCmp; }
4929- const bool &inlineUdf () const { return theInlineUdf; }
4930- const bool &loopHoisting () const { return theLoopHoisting; }
4931- const bool &inferJoins () const { return theInferJoins; }
4932- const bool &noCopyOptim() const { return theNoCopyOptim; }
4933+ const bool& specializeCmp () const { return theSpecializeCmp; }
4934+ const bool& inlineUdf () const { return theInlineUdf; }
4935+ const bool& loopHoisting () const { return theLoopHoisting; }
4936+ const bool& inferJoins () const { return theInferJoins; }
4937+ const bool& useIndexes() const { return theUseIndexes; }
4938+ const bool& noCopyOptim() const { return theNoCopyOptim; }
4939 const int& serializeOnlyQuery() const { return theSerializeOnlyQuery; }
4940 const bool &traceTranslator () const { return theTraceTranslator; }
4941 const bool &traceCodegen () const { return theTraceCodegen; }
4942@@ -301,33 +304,47 @@
4943
4944 init_val (*argv, theSpecializeCmp, d);
4945 }
4946- else if (strcmp (*argv, "--inline-udf") == 0) {
4947+ else if (strcmp (*argv, "--inline-udf") == 0)
4948+ {
4949 int d = 2;
4950 if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
4951 if (*argv == NULL) { result = "No value given for --inline-udf option"; break; }
4952
4953 init_val (*argv, theInlineUdf, d);
4954 }
4955- else if (strcmp (*argv, "--loop-hoisting") == 0) {
4956+ else if (strcmp (*argv, "--loop-hoisting") == 0)
4957+ {
4958 int d = 2;
4959 if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
4960 if (*argv == NULL) { result = "No value given for --loop-hoisting option"; break; }
4961
4962 init_val (*argv, theLoopHoisting, d);
4963 }
4964- else if (strcmp (*argv, "--infer-joins") == 0) {
4965+ else if (strcmp (*argv, "--infer-joins") == 0)
4966+ {
4967 int d = 2;
4968- if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
4969+ if ((*argv)[1] == '-' || (*argv)[2] == '\0') { d = 0; ++argv; }
4970 if (*argv == NULL) { result = "No value given for --infer-joins option"; break; }
4971
4972- init_val (*argv, theInferJoins, d);
4973- }
4974- else if (strcmp (*argv, "--no-copy-optim") == 0)
4975- {
4976- int d = 2;
4977- if ((*argv) [1] == '-' || (*argv) [2] == '\0') { d = 0; ++argv; }
4978- if (*argv == NULL) { result = "No value given for --no-copy-optim option"; break; }
4979- init_val (*argv, theNoCopyOptim, d);
4980+ init_val(*argv, theInferJoins, d);
4981+ }
4982+ else if (strcmp(*argv, "--use-indexes") == 0)
4983+ {
4984+ int d = 2;
4985+ if ((*argv)[1] == '-' || (*argv)[2] == '\0') { d = 0; ++argv; }
4986+ if (*argv == NULL) { result = "No value given for --use-indexes option"; break; }
4987+
4988+ init_val(*argv, theUseIndexes, d);
4989+ }
4990+ else if (strcmp(*argv, "--no-copy-optim") == 0)
4991+ {
4992+ int d = 2;
4993+ if ((*argv)[1] == '-' || (*argv)[2] == '\0') { d = 0; ++argv; }
4994+ if (*argv == NULL)
4995+ {
4996+ result = "No value given for --no-copy-optim option"; break;
4997+ }
4998+ init_val(*argv, theNoCopyOptim, d);
4999 }
5000 else if (strcmp (*argv, "--serialize-only-query") == 0)
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches