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;
-- Mailing list: https://launchpad.net/~zorba-coders Post to : zorba-coders@lists.launchpad.net Unsubscribe : https://launchpad.net/~zorba-coders More help : https://help.launchpad.net/ListHelp