← Back to team overview

zorba-coders team mailing list archive

[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