zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #21809
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/markos-scratch into lp:zorba.
Commit message:
exact match for flwor exprs
Requested reviews:
Markos Zaharioudakis (markos-za)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/163204
exact match for flwor exprs
--
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/163204
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/compiler/expression/flwor_expr.h'
--- src/compiler/expression/flwor_expr.h 2013-05-04 20:20:05 +0000
+++ src/compiler/expression/flwor_expr.h 2013-05-09 18:54:27 +0000
@@ -391,19 +391,25 @@
- Data Members:
- theGroupVars : For each grouping var X, theGroupVars contains a pair of
- exprs: the 1st element of the pair is a reference to X in
- the groupby's input tuple stream, and the 2nd element is
- a var_expr representing the variable gX that the groupby
- produces for X in its output tuple stream.
- theNonGroupVars : For each non-grouping var Y, theGroupVars contains a pair of
- exprs: the 1st element of the pair is a reference to Y in
- the groupby's input tuple stream, and the 2nd element is
- a var_expr representing the variable gY that the groupby
- produces for Y in its output tuple stream. For each tuple
- T produced by the groupby, gY is the concatenation of all
- the Y values in the input tuples that were grouped into T.
- theCollations : The collations to use when comparing values for grouping.
+ theGroupVars:
+ -------------
+ For each grouping var X, theGroupVars contains a pair of exprs: the 1st
+ element of the pair is the expr that computes the grouping keys for X;
+ the 2nd element is a var_expr representing the variable gX that the groupby
+ produces for X in its output tuple stream.
+
+ theNonGroupVars:
+ ----------------
+ For each non-grouping var Y, theNonGroupVars contains a pair of exprs: the
+ 1st element of the pair is a reference to Y in the groupby's input tuple
+ stream, and the 2nd element is a var_expr representing the variable gY that
+ the groupby produces for Y in its output tuple stream. For each tuple T
+ produced by the groupby, gY is the concatenation of all the Y values in the
+ input tuples that were grouped into T.
+
+ theCollations:
+ --------------
+ The collations to use when comparing values for grouping.
********************************************************************************/
class groupby_clause : public flwor_clause
{
=== modified file 'src/compiler/rewriter/tools/expr_tools.cpp'
--- src/compiler/rewriter/tools/expr_tools.cpp 2013-04-27 16:36:36 +0000
+++ src/compiler/rewriter/tools/expr_tools.cpp 2013-05-09 18:54:27 +0000
@@ -79,11 +79,28 @@
/*******************************************************************************
********************************************************************************/
+#define MATCH_WINCOND_VAR(qv, vv) \
+ if (qv != NULL && vv != NULL) \
+ { \
+ subst[vv] = qv; \
+ } \
+ else if (qv != NULL || vv != NULL) \
+ { \
+ return false; \
+ }
+
+
+/*******************************************************************************
+
+********************************************************************************/
bool match_exact(expr* query, expr* view, expr::substitution_t& subst)
{
if (query == view)
return true;
+ if (query == NULL || view == NULL)
+ return false;
+
if (query->get_expr_kind() != view->get_expr_kind())
{
if (query->get_expr_kind() == var_expr_kind)
@@ -458,6 +475,190 @@
}
}
+ case flwor_expr_kind:
+ case gflwor_expr_kind:
+ {
+ flwor_expr* qe = static_cast<flwor_expr*>(query);
+ flwor_expr* ve = static_cast<flwor_expr*>(view);
+
+ csize numClauses = qe->num_clauses();
+
+ if (numClauses != ve->num_clauses())
+ return false;
+
+ for (csize i = 0; i < numClauses; ++i)
+ {
+ flwor_clause* qc = qe->get_clause(i);
+ flwor_clause* vc = ve->get_clause(i);
+
+ if (qc->get_kind() != vc->get_kind())
+ return false;
+
+ switch (qc->get_kind())
+ {
+ case flwor_clause::for_clause:
+ case flwor_clause::let_clause:
+ {
+ forlet_clause* qflc = static_cast<forlet_clause*>(qc);
+ forlet_clause* vflc = static_cast<forlet_clause*>(vc);
+
+ if (!match_exact(qflc->get_expr(), vflc->get_expr(), subst))
+ return false;
+
+ subst[vflc->get_var()] = qflc->get_var();
+
+ break;
+ }
+ case flwor_clause::where_clause:
+ {
+ where_clause* qwc = static_cast<where_clause*>(qc);
+ where_clause* vwc = static_cast<where_clause*>(vc);
+
+ if (!match_exact(qwc->get_expr(), vwc->get_expr(), subst))
+ return false;
+
+ break;
+ }
+ case flwor_clause::orderby_clause:
+ {
+ orderby_clause* qoc = static_cast<orderby_clause*>(qc);
+ orderby_clause* voc = static_cast<orderby_clause*>(vc);
+
+ csize numColumns = qoc->num_columns();
+
+ if (numColumns != voc->num_columns())
+ return false;
+
+ for (csize i = 0; i < numColumns; ++i)
+ {
+ if (match_exact(qoc->get_column_expr(i), voc->get_column_expr(i), subst))
+ return false;
+ }
+
+ break;
+ }
+ case flwor_clause::groupby_clause:
+ {
+ groupby_clause* qgc = static_cast<groupby_clause*>(qc);
+ groupby_clause* vgc = static_cast<groupby_clause*>(vc);
+
+ csize numGVars = qgc->numGroupingVars();
+ csize numNGVars = qgc->numNonGroupingVars();
+
+ if (numGVars != vgc->numGroupingVars() ||
+ numNGVars != vgc->numNonGroupingVars())
+ return false;
+
+ var_rebind_list_t::const_iterator qite = qgc->beginGroupVars();
+ var_rebind_list_t::const_iterator qend = qgc->endGroupVars();
+ var_rebind_list_t::const_iterator vite = vgc->beginGroupVars();
+
+ for (; qite != qend; ++qite, ++vite)
+ {
+ if (!match_exact((*qite).first, (*vite).first, subst))
+ return false;
+
+ subst[(*vite).second] = (*qite).second;
+ }
+
+ qite = qgc->beginNonGroupVars();
+ qend = qgc->endNonGroupVars();
+ vite = vgc->beginNonGroupVars();
+
+ for (; qite != qend; ++qite, ++vite)
+ {
+ if (!match_exact((*qite).first, (*vite).first, subst))
+ return false;
+
+ subst[(*vite).second] = (*qite).second;
+ }
+
+ break;
+ }
+ case flwor_clause::window_clause:
+ {
+ window_clause* qwc = static_cast<window_clause*>(qc);
+ window_clause* vwc = static_cast<window_clause*>(vc);
+
+ if (!match_exact(qwc->get_expr(), vwc->get_expr(), subst))
+ return false;
+
+ subst[vwc->get_var()] = qwc->get_var();
+
+ flwor_wincond* qcond = qwc->get_win_start();
+ flwor_wincond* vcond = vwc->get_win_start();
+
+ if (qcond != NULL && vcond != NULL)
+ {
+ if (qcond->is_only() != vcond->is_only())
+ return false;
+
+ MATCH_WINCOND_VAR(qcond->get_in_vars().posvar, vcond->get_in_vars().posvar);
+ MATCH_WINCOND_VAR(qcond->get_in_vars().curr, vcond->get_in_vars().curr);
+ MATCH_WINCOND_VAR(qcond->get_in_vars().prev, vcond->get_in_vars().prev);
+ MATCH_WINCOND_VAR(qcond->get_in_vars().next, vcond->get_in_vars().next);
+
+ if (!match_exact(qcond->get_expr(), vcond->get_expr(), subst))
+ return false;
+
+ MATCH_WINCOND_VAR(qcond->get_out_vars().posvar, vcond->get_out_vars().posvar);
+ MATCH_WINCOND_VAR(qcond->get_out_vars().curr, vcond->get_out_vars().curr);
+ MATCH_WINCOND_VAR(qcond->get_out_vars().prev, vcond->get_out_vars().prev);
+ MATCH_WINCOND_VAR(qcond->get_out_vars().next, vcond->get_out_vars().next);
+ }
+ else if (qcond != NULL || vcond != NULL)
+ {
+ return false;
+ }
+
+ qcond = qwc->get_win_stop();
+ vcond = vwc->get_win_stop();
+
+ if (qcond != NULL && vcond != NULL)
+ {
+ if (qcond->is_only() != vcond->is_only())
+ return false;
+
+ MATCH_WINCOND_VAR(qcond->get_in_vars().posvar, vcond->get_in_vars().posvar);
+ MATCH_WINCOND_VAR(qcond->get_in_vars().curr, vcond->get_in_vars().curr);
+ MATCH_WINCOND_VAR(qcond->get_in_vars().prev, vcond->get_in_vars().prev);
+ MATCH_WINCOND_VAR(qcond->get_in_vars().next, vcond->get_in_vars().next);
+
+ if (!match_exact(qcond->get_expr(), vcond->get_expr(), subst))
+ return false;
+
+ MATCH_WINCOND_VAR(qcond->get_out_vars().posvar, vcond->get_out_vars().posvar);
+ MATCH_WINCOND_VAR(qcond->get_out_vars().curr, vcond->get_out_vars().curr);
+ MATCH_WINCOND_VAR(qcond->get_out_vars().prev, vcond->get_out_vars().prev);
+ MATCH_WINCOND_VAR(qcond->get_out_vars().next, vcond->get_out_vars().next);
+ }
+ else if (qcond != NULL || vcond != NULL)
+ {
+ return false;
+ }
+
+ break;
+ }
+ case flwor_clause::count_clause:
+ {
+ count_clause* qcc = static_cast<count_clause*>(qc);
+ count_clause* vcc = static_cast<count_clause*>(vc);
+
+ subst[vcc->get_var()] = qcc->get_var();
+
+ break;
+ }
+ default:
+ ZORBA_ASSERT(false);
+ }
+ }
+
+ if (!match_exact(qe->get_return_expr(), ve->get_return_expr(), subst))
+ return false;
+
+ return true;
+ }
+
case cast_expr_kind:
case castable_expr_kind:
case instanceof_expr_kind:
=== added file 'test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_vrange_06.iter'
--- test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_vrange_06.iter 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpCompilerResults/IterPlan/zorba/index/match_vrange_06.iter 2013-05-09 18:54:27 +0000
@@ -0,0 +1,88 @@
+Iterator tree for index:
+<flwor::FLWORIterator>
+ <ForVariable name="$$context-item">
+ <ZorbaCollectionIterator>
+ <SingletonIterator value="xs:QName(http://28.io/collections,db28,foo)"/>
+ </ZorbaCollectionIterator>
+ </ForVariable>
+ <ReturnClause>
+ <ValueIndexEntryBuilderIterator>
+ <ForVarIterator varname="$$context-item"/>
+ <PromoteIterator type="xs:string">
+ <FnDataIterator>
+ <DynamicFnCallIterator>
+ <ForVarIterator varname="$$context-item"/>
+ <SingletonIterator value="xs:string(_id)"/>
+ </DynamicFnCallIterator>
+ </FnDataIterator>
+ </PromoteIterator>
+ </ValueIndexEntryBuilderIterator>
+ </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for index:
+<flwor::FLWORIterator>
+ <ForVariable name="$$context-item">
+ <ZorbaCollectionIterator>
+ <SingletonIterator value="xs:QName(http://28.io/collections,db28,foo)"/>
+ </ZorbaCollectionIterator>
+ </ForVariable>
+ <ReturnClause>
+ <ValueIndexEntryBuilderIterator>
+ <ForVarIterator varname="$$context-item"/>
+ <PromoteIterator type="xs:string">
+ <FnDataIterator>
+ <flwor::TupleStreamIterator>
+ <flwor::OuterForIterator varname="$$context-item">
+ <flwor::TupleSourceIterator/>
+ <DynamicFnCallIterator>
+ <ForVarIterator varname="$$context-item"/>
+ <SingletonIterator value="xs:string(properties)"/>
+ </DynamicFnCallIterator>
+ </flwor::OuterForIterator>
+ <DynamicFnCallIterator>
+ <ForVarIterator varname="$$context-item"/>
+ <SingletonIterator value="xs:string(STREET)"/>
+ </DynamicFnCallIterator>
+ </flwor::TupleStreamIterator>
+ </FnDataIterator>
+ </PromoteIterator>
+ </ValueIndexEntryBuilderIterator>
+ </ReturnClause>
+</flwor::FLWORIterator>
+
+Iterator tree for main query:
+<SequentialIterator>
+ <ApplyIterator>
+ <ZorbaCreateCollectionIterator>
+ <SingletonIterator value="xs:QName(http://28.io/collections,db28,foo)"/>
+ </ZorbaCreateCollectionIterator>
+ </ApplyIterator>
+ <ApplyIterator>
+ <CreateIndexIterator>
+ <SingletonIterator value="xs:QName(http://28.io/collections,db28,foo__id_)"/>
+ </CreateIndexIterator>
+ </ApplyIterator>
+ <ApplyIterator>
+ <CreateIndexIterator>
+ <SingletonIterator value="xs:QName(http://28.io/collections,db28,street)"/>
+ </CreateIndexIterator>
+ </ApplyIterator>
+ <flwor::FLWORIterator>
+ <ForVariable name="i">
+ <ProbeIndexRangeValueIterator>
+ <SingletonIterator value="xs:QName(http://28.io/collections,db28,street)"/>
+ <SingletonIterator value="xs:string(Sheridan)"/>
+ <SingletonIterator value="xs:string(Sheridan)"/>
+ <SingletonIterator value="xs:boolean(true)"/>
+ <SingletonIterator value="xs:boolean(true)"/>
+ <SingletonIterator value="xs:boolean(true)"/>
+ <SingletonIterator value="xs:boolean(true)"/>
+ </ProbeIndexRangeValueIterator>
+ </ForVariable>
+ <ReturnClause>
+ <ForVarIterator varname="i"/>
+ </ReturnClause>
+ </flwor::FLWORIterator>
+</SequentialIterator>
+
=== added file 'test/rbkt/ExpQueryResults/zorba/index/match_vrange_06.xml.res'
=== added file 'test/rbkt/Queries/zorba/index/match_vrange_06.xq'
--- test/rbkt/Queries/zorba/index/match_vrange_06.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_vrange_06.xq 2013-05-09 18:54:27 +0000
@@ -0,0 +1,23 @@
+
+import module namespace db28 = "http://28.io/collections" at "match_vrange_06.xqlib";
+
+import module namespace ddl =
+"http://www.zorba-xquery.com/modules/store/static/collections/ddl";
+
+import module namespace dml =
+"http://www.zorba-xquery.com/modules/store/static/collections/dml";
+
+import module namespace iddl =
+"http://www.zorba-xquery.com/modules/store/static/indexes/ddl";
+
+
+ddl:create(xs:QName("db28:foo"));
+
+iddl:create(xs:QName("db28:foo__id_"));
+
+iddl:create(xs:QName("db28:street"));
+
+for $i in dml:collection(xs:QName("db28:foo"))
+where $i("properties")("STREET") eq "Sheridan"
+return $i
+
=== added file 'test/rbkt/Queries/zorba/index/match_vrange_06.xqlib'
--- test/rbkt/Queries/zorba/index/match_vrange_06.xqlib 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/match_vrange_06.xqlib 2013-05-09 18:54:27 +0000
@@ -0,0 +1,16 @@
+
+module namespace db28 = "http://28.io/collections";
+
+import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml";
+
+declare namespace an = "http://www.zorba-xquery.com/annotations";
+
+declare %an:mutable %an:unordered %an:mutable-nodes collection db28:foo;
+
+declare %an:manual %an:value-range index db28:foo__id_
+on nodes dml:collection(xs:QName("db28:foo"))
+by .("_id") as xs:string;
+
+declare %an:manual %an:value-range index db28:street
+on nodes dml:collection(xs:QName("db28:foo"))
+by .("properties")("STREET") as xs:string;
Follow ups