zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #24382
[Merge] lp:~zorba-coders/zorba/skiplimit into lp:zorba
William Candillon has proposed merging lp:~zorba-coders/zorba/skiplimit into lp:zorba.
Requested reviews:
William Candillon (wcandillon)
Markos Zaharioudakis (markos-za)
Ghislain Fourny (gislenius)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/skiplimit/+merge/175747
Add offset limit clauses to the FLWOR.
These clauses are similar to limit and offset from SQL.
For example:
for $i in (1 to 10)
offset 5
limit 2
return $i
--
https://code.launchpad.net/~zorba-coders/zorba/skiplimit/+merge/175747
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/compiler/parser/parser.y'
--- src/compiler/parser/parser.y 2013-06-17 20:05:21 +0000
+++ src/compiler/parser/parser.y 2013-07-19 07:42:35 +0000
@@ -325,6 +325,8 @@
%token QUOTE "'\"'"
%token RBRACE "'}'"
%token RBRACK "']'"
+%token OFFSET "'offset'"
+%token LIMIT "'limit'"
%token RETURN "'return'"
%token RPAR "')'"
%token SATISFIES "'satisfies'"
@@ -637,6 +639,8 @@
%type <node> BlockVarDecl
%type <node> WhereClause
%type <node> CountClause
+%type <node> OffsetClause
+%type <node> LimitClause
%type <node> Wildcard
/* left-hand sides: expressions */
@@ -883,7 +887,7 @@
%destructor { release_hack( $$ ); } SchemaPrefix SequenceType SequenceTypeList Setter SignList SingleType TextTest NamespaceTest TypeDeclaration TypeName TypeName_WITH_HOOK
%destructor { release_hack( $$ ); } URILiteralList ValueComp CollectionDecl IndexDecl IndexKeySpec IndexKeyList IntegrityConstraintDecl CtxItemDecl CtxItemDecl2 CtxItemDecl3
%destructor { release_hack( $$ ); } CtxItemDecl4 VarDecl VarGetsDecl VarGetsDeclList VarInDecl VarInDeclList WindowVarDecl WindowVars WindowVars2 WindowVars3 FLWORWinCond
-%destructor { release_hack( $$ ); } VersionDecl VFO_Decl VFO_DeclList WhereClause CountClause Wildcard DecimalFormatDecl TypedFunctionTest AnyFunctionTest TypeList
+%destructor { release_hack( $$ ); } VersionDecl VFO_Decl VFO_DeclList WhereClause CountClause LimitClause OffsetClause Wildcard DecimalFormatDecl TypedFunctionTest AnyFunctionTest TypeList
%destructor { release_hack( $$ ); } SwitchCaseClause SwitchCaseClauseList SwitchCaseOperandList
#ifdef XQUERY_PARSER
@@ -2712,8 +2716,23 @@
| OrderByClause
| GroupByClause
| CountClause
-;
-
+ | OffsetClause
+ | LimitClause
+;
+
+OffsetClause :
+ OFFSET ExprSingle
+ {
+ $$ = new OffsetClause(LOC (@$), $2);
+ }
+;
+
+LimitClause :
+ LIMIT ExprSingle
+ {
+ $$ = new LimitClause(LOC (@$), $2);
+ }
+;
FLWORClauseList :
ForLetWinClause
=== modified file 'src/compiler/parser/scanner.l'
--- src/compiler/parser/scanner.l 2013-04-23 13:20:31 +0000
+++ src/compiler/parser/scanner.l 2013-07-19 07:42:35 +0000
@@ -557,6 +557,8 @@
"by" { return token::BY; }
"stable" { return token::STABLE; }
"or" { return token::OR; }
+"limit" { return token::LIMIT; }
+"offset" { return token::OFFSET; }
"return" { return token::RETURN; }
#ifdef JSONIQ_SCANNER
"select" { return token::RETURN; }
=== modified file 'src/compiler/parsetree/parsenode_print_xml_visitor.cpp'
--- src/compiler/parsetree/parsenode_print_xml_visitor.cpp 2013-06-07 13:46:26 +0000
+++ src/compiler/parsetree/parsenode_print_xml_visitor.cpp 2013-07-19 07:42:35 +0000
@@ -726,6 +726,8 @@
BEGIN_END_TAG (ContextItemExpr)
BEGIN_END_TAG (CopyNamespacesDecl)
BEGIN_END_TAG (CountClause)
+BEGIN_END_TAG (LimitClause)
+BEGIN_END_TAG (OffsetClause)
BEGIN_END_TAG (DefaultCollationDecl)
BEGIN_END_TAG (DeleteExpr)
END_TAG (DirAttr)
=== modified file 'src/compiler/parsetree/parsenode_print_xqdoc_visitor.cpp'
--- src/compiler/parsetree/parsenode_print_xqdoc_visitor.cpp 2013-07-01 18:59:06 +0000
+++ src/compiler/parsetree/parsenode_print_xqdoc_visitor.cpp 2013-07-19 07:42:35 +0000
@@ -1529,6 +1529,8 @@
XQDOC_NO_BEGIN_END_TAG (VarRef)
XQDOC_NO_BEGIN_END_TAG (VFO_DeclList)
XQDOC_NO_BEGIN_END_TAG (WhereClause)
+XQDOC_NO_BEGIN_END_TAG (OffsetClause)
+XQDOC_NO_BEGIN_END_TAG (LimitClause)
XQDOC_NO_BEGIN_END_TAG (WhileExpr)
XQDOC_NO_BEGIN_END_TAG (Wildcard)
XQDOC_NO_BEGIN_END_TAG (WindowClause)
=== modified file 'src/compiler/parsetree/parsenode_print_xquery_visitor.cpp'
--- src/compiler/parsetree/parsenode_print_xquery_visitor.cpp 2013-06-07 13:46:26 +0000
+++ src/compiler/parsetree/parsenode_print_xquery_visitor.cpp 2013-07-19 07:42:35 +0000
@@ -1199,6 +1199,24 @@
}
DEFAULT_END_VISIT (WhereClause)
+ void* begin_visit(const OffsetClause& n)
+ {
+ os << "offset ";
+ n.get_offset()->accept(*this);
+ return 0;
+ }
+ DEFAULT_END_VISIT (OffsetClause)
+
+
+ void* begin_visit(const LimitClause& n)
+ {
+ os << "limit ";
+ n.get_limit()->accept(*this);
+ return 0;
+ }
+ DEFAULT_END_VISIT (LimitClause)
+
+
void* begin_visit(const CountClause& n)
{
os << "count $" << n.get_varname();
=== modified file 'src/compiler/parsetree/parsenode_visitor.h'
--- src/compiler/parsetree/parsenode_visitor.h 2013-06-17 13:32:23 +0000
+++ src/compiler/parsetree/parsenode_visitor.h 2013-07-19 07:42:35 +0000
@@ -146,6 +146,8 @@
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( VFO_DeclList );
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( WhereClause );
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( CountClause );
+ DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( OffsetClause );
+ DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( LimitClause );
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( Wildcard );
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( QName );
DECL_PARSENODE_VISITOR_VISIT_MEM_FNS( DecimalFormatNode );
=== modified file 'src/compiler/parsetree/parsenodes.cpp'
--- src/compiler/parsetree/parsenodes.cpp 2013-06-17 18:00:35 +0000
+++ src/compiler/parsetree/parsenodes.cpp 2013-07-19 07:42:35 +0000
@@ -1783,6 +1783,37 @@
END_VISITOR();
}
+OffsetClause::OffsetClause(
+ const QueryLoc& loc_,
+ rchandle<exprnode> _offset_h)
+:
+ FLWORClause(loc_),
+ offset_h(_offset_h)
+{}
+
+
+void OffsetClause::accept( parsenode_visitor &v ) const
+{
+ BEGIN_VISITOR();
+ ACCEPT (offset_h);
+ END_VISITOR();
+}
+
+LimitClause::LimitClause(
+ const QueryLoc& loc_,
+ rchandle<exprnode> _limit_h)
+:
+ FLWORClause(loc_),
+ limit_h(_limit_h)
+{}
+
+
+void LimitClause::accept( parsenode_visitor &v ) const
+{
+ BEGIN_VISITOR();
+ ACCEPT (limit_h);
+ END_VISITOR();
+}
void CountClause::accept(parsenode_visitor& v) const
{
=== modified file 'src/compiler/parsetree/parsenodes.h'
--- src/compiler/parsetree/parsenodes.h 2013-06-17 18:00:35 +0000
+++ src/compiler/parsetree/parsenodes.h 2013-07-19 07:42:35 +0000
@@ -180,6 +180,8 @@
class VarGetsDeclList;
class VarGetsDecl;
class WhereClause;
+class OffsetClause;
+class LimitClause;
class GroupByClause;
class GroupSpecList;
class GroupSpec;
@@ -2235,6 +2237,31 @@
void accept(parsenode_visitor&) const;
};
+class OffsetClause : public FLWORClause
+{
+protected:
+ rchandle<exprnode> offset_h;
+
+public:
+ OffsetClause(const QueryLoc&, rchandle<exprnode>);
+
+ rchandle<exprnode> get_offset() const { return offset_h; }
+
+ void accept(parsenode_visitor&) const;
+};
+
+class LimitClause : public FLWORClause
+{
+protected:
+ rchandle<exprnode> limit_h;
+
+public:
+ LimitClause(const QueryLoc&, rchandle<exprnode>);
+
+ rchandle<exprnode> get_limit() const { return limit_h; }
+
+ void accept(parsenode_visitor&) const;
+};
/*******************************************************************************
GroupByClause ::= "group" "by" GroupingSpecList
=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp 2013-07-06 06:59:32 +0000
+++ src/compiler/translator/translator.cpp 2013-07-19 07:42:35 +0000
@@ -678,6 +678,8 @@
std::vector<flwor_clause*> theFlworClausesStack;
+ expr* theOffsetExpr;
+
std::vector<const parsenode*> theTryStack;
std::stack<NodeSortInfo> theNodeSortStack;
@@ -6857,6 +6859,7 @@
TRACE_VISIT();
theFlworClausesStack.push_back(NULL);
+ theOffsetExpr = CREATE(const)(theRootSctx, theUDF, loc, numeric_consts<xs_integer>::one());
return no_state;
}
@@ -7907,6 +7910,90 @@
theFlworClausesStack.push_back(clause);
}
+void* begin_visit(const OffsetClause& v)
+{
+ TRACE_VISIT ();
+ return no_state;
+}
+
+void end_visit(const OffsetClause& v, void* /*visit_state*/)
+{
+ TRACE_VISIT_OUT ();
+
+ expr* theOffsetExpr = pop_nodestack();
+
+ //'offset offset_expr' is rewritten to:
+ //count $Q{http://zorba.io/internals}count
+ //where ${http://zorba.io/internals}count ge offset_expr
+
+ //1. Add Count Clause
+ push_scope();
+ store::Item_t countVar;
+ theSctx->expand_qname(countVar, "http://zorba.io/internals", "", "count", loc);
+ var_expr* varExpr = bind_var(loc, countVar, var_expr::count_var, NULL);
+ count_clause* countClause = theExprManager->create_count_clause(theRootSctx,
+ loc,
+ varExpr);
+ theFlworClausesStack.push_back(countClause);
+
+ //2. Create WhereExpr
+ function* f = BUILTIN_FUNC(OP_GREATER_EQUAL_2);
+ expr* left = lookup_var(countVar, loc, true);
+ expr* right = theOffsetExpr;
+ expr* whereExpr = theExprManager->create_fo_expr(theRootSctx, theUDF, loc, f, left, right);
+
+ //3. Add WhereClause
+ whereExpr = wrap_in_bev(whereExpr);
+ wrap_in_debugger_expr(whereExpr, whereExpr->get_loc());
+ where_clause* clause = theExprManager->create_where_clause(theRootSctx,
+ loc,
+ whereExpr);
+ theFlworClausesStack.push_back(clause);
+}
+
+void* begin_visit(const LimitClause& v)
+{
+ TRACE_VISIT ();
+ return no_state;
+}
+
+void end_visit(const LimitClause& v, void* /*visit_state*/)
+{
+ TRACE_VISIT_OUT ();
+ //'limit 3' is rewritten to:
+ //count $Q{http://zorba.io/internals}count
+ //where ${http://zorba.io/internals}count lt ($offset + 3)
+
+ expr* limitExpr = pop_nodestack();
+
+ //1. Add Count Clause
+ push_scope();
+ store::Item_t countVar;
+ theSctx->expand_qname(countVar, "http://zorba.io/internals", "", "count", loc);
+ var_expr* varExpr = bind_var(loc, countVar, var_expr::count_var, NULL);
+ count_clause* countClause = theExprManager->create_count_clause(theRootSctx,
+ loc,
+ varExpr);
+ theFlworClausesStack.push_back(countClause);
+
+ //4. Create (offset_expr + limit_expr) expr
+ function* add = BUILTIN_FUNC(OP_ADD_2);
+ expr* limitPlusOffsetExpr = theExprManager->create_fo_expr(theRootSctx, theUDF, loc, add, theOffsetExpr, limitExpr);
+
+ //3. Create WhereExpr
+ function* f = BUILTIN_FUNC(OP_LESS_2);
+ expr* left = lookup_var(countVar, loc, true);
+ expr* right = limitPlusOffsetExpr;
+ expr* whereExpr = theExprManager->create_fo_expr(theRootSctx, theUDF, loc, f, left, right);
+
+ //4. Add WhereClause
+ whereExpr = wrap_in_bev(whereExpr);
+ wrap_in_debugger_expr(whereExpr, whereExpr->get_loc());
+ where_clause* clause = theExprManager->create_where_clause(theRootSctx,
+ loc,
+ whereExpr);
+ theFlworClausesStack.push_back(clause);
+}
/*******************************************************************************
CountClause ::= "count" "$" VarName
=== added directory 'test/rbkt/ExpQueryResults/zorba/offset-limit'
=== added file 'test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-1.xml.res'
--- test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-1.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-1.xml.res 2013-07-19 07:42:35 +0000
@@ -0,0 +1,1 @@
+5 6
=== added file 'test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-2.xml.res 2013-07-19 07:42:35 +0000
@@ -0,0 +1,1 @@
+5 6 7 8 9 10
=== added file 'test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-3.xml.res'
--- test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-3.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-3.xml.res 2013-07-19 07:42:35 +0000
@@ -0,0 +1,1 @@
+1 2 3 4 5
=== added file 'test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-4.xml.res'
--- test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-4.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-4.xml.res 2013-07-19 07:42:35 +0000
@@ -0,0 +1,1 @@
+
=== added file 'test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-5.xml.res'
--- test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-5.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/offset-limit/offset-limit-5.xml.res 2013-07-19 07:42:35 +0000
@@ -0,0 +1,1 @@
+3
=== added directory 'test/rbkt/Queries/zorba/offset-limit'
=== added file 'test/rbkt/Queries/zorba/offset-limit/offset-limit-1.xq'
--- test/rbkt/Queries/zorba/offset-limit/offset-limit-1.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/offset-limit/offset-limit-1.xq 2013-07-19 07:42:35 +0000
@@ -0,0 +1,4 @@
+for $i in (1 to 10)
+offset 5
+limit 2
+return $i
=== added file 'test/rbkt/Queries/zorba/offset-limit/offset-limit-2.xq'
--- test/rbkt/Queries/zorba/offset-limit/offset-limit-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/offset-limit/offset-limit-2.xq 2013-07-19 07:42:35 +0000
@@ -0,0 +1,3 @@
+for $i in (1 to 10)
+offset 5
+return $i
=== added file 'test/rbkt/Queries/zorba/offset-limit/offset-limit-3.xq'
--- test/rbkt/Queries/zorba/offset-limit/offset-limit-3.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/offset-limit/offset-limit-3.xq 2013-07-19 07:42:35 +0000
@@ -0,0 +1,3 @@
+for $i in (1 to 10)
+limit 5
+return $i
=== added file 'test/rbkt/Queries/zorba/offset-limit/offset-limit-4.xq'
--- test/rbkt/Queries/zorba/offset-limit/offset-limit-4.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/offset-limit/offset-limit-4.xq 2013-07-19 07:42:35 +0000
@@ -0,0 +1,7 @@
+for $i in (1 to 10)
+offset 2
+limit 5
+limit 2
+offset 5
+limit 1
+return $i
=== added file 'test/rbkt/Queries/zorba/offset-limit/offset-limit-5.xq'
--- test/rbkt/Queries/zorba/offset-limit/offset-limit-5.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/offset-limit/offset-limit-5.xq 2013-07-19 07:42:35 +0000
@@ -0,0 +1,7 @@
+for $i in (1 to 10)
+offset 2
+limit 5
+limit 2
+offset 2
+limit 1
+return $i
Follow ups