1 /* 2 * Copyright 2006-2008 The FLWOR Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 #ifndef ZORBA_COMPILER_FLWOR_EXPR_H 19 #define ZORBA_COMPILER_FLWOR_EXPR_H 20 21 #include "common/shared_types.h" 22 23 #include "compiler/expression/expr_base.h" 24 #include "compiler/expression/var_expr.h" 25 #include "compiler/expression/expr_utils.h" 26 27 namespace zorba 28 { 29 30 class ExprManager; 31 32 class order_modifier; 33 class flwor_clause; 34 class for_clause; 35 class let_clause; 36 class window_clause; 37 class flwor_wincond; 38 class orderby_clause; 39 class materialize_clause; 40 class group_clause; 41 class flwor_expr; 42 43 /***************************************************************************//** 44 45 ********************************************************************************/ 46 class flwor_clause 47 { 48 friend class flwor_expr; 49 friend class ExprIterator; 50 friend class ExprManager; 51 52 public: 53 typedef std::vector<std::pair<expr*, var_expr*> > rebind_list_t; 54 55 typedef enum 56 { 57 for_clause, 58 let_clause, 59 window_clause, 60 group_clause, 61 order_clause, 62 count_clause, 63 where_clause, 64 materialize_clause 65 } ClauseKind; 66 67 protected: 68 static_context * theContext; 69 QueryLoc theLocation; 70 71 ClauseKind theKind; 72 flwor_expr * theFlworExpr; 73 74 CompilerCB * const theCCB; 75 76 protected: flwor_clause(static_context * sctx,CompilerCB * ccb,const QueryLoc & loc,ClauseKind kind)77 flwor_clause( 78 static_context* sctx, 79 CompilerCB* ccb, 80 const QueryLoc& loc, 81 ClauseKind kind) 82 : 83 theContext(sctx), 84 theLocation(loc), 85 theKind(kind), 86 theFlworExpr(NULL), 87 theCCB(ccb) 88 { 89 } 90 91 public: 92 virtual ~flwor_clause(); 93 get_loc()94 const QueryLoc& get_loc() const { return theLocation; } 95 get_kind()96 ClauseKind get_kind() const { return theKind; } 97 get_flwor_expr()98 flwor_expr* get_flwor_expr() const { return theFlworExpr; } 99 get_expr()100 virtual expr* get_expr() const { return NULL; } 101 set_expr(expr * v)102 virtual void set_expr(expr* v) { } 103 get_pos_var()104 virtual var_expr* get_pos_var() const { return NULL; } 105 get_score_var()106 virtual var_expr* get_score_var() const { return NULL; } 107 108 virtual flwor_clause* clone(expr::substitution_t& substitution) const = 0; 109 }; 110 111 112 /***************************************************************************//** 113 114 ForClause ::= "outer"? "for" "$" VarName TypeDeclaration? PositionalVar? 115 "in" DomainExpr 116 117 LetClause ::= "let" "$" VarName TypeDeclaration? ":=" DomainExpr 118 119 WindowClause ::= "for" (TumblingWindowClause | SlidingWindowClause) 120 121 TumblingWindowClause ::= "tumbling" "window" 122 "$" VarName TypeDeclaration? "in" DomainExpr 123 WindowStartCondition 124 WindowEndCondition? 125 126 SlidingWindowClause ::= "sliding" "window" 127 "$" VarName TypeDeclaration? "in" DomainExpr 128 WindowStartCondition 129 WindowEndCondition 130 131 DomainExpr ::= ExprSingle 132 133 PositionalVar ::= "at" "$" VarName 134 135 TypeDeclaration ::= "as" SequenceType 136 137 ********************************************************************************/ 138 class forletwin_clause : public flwor_clause 139 { 140 friend class flwor_expr; 141 friend class ExprManager; 142 friend class ExprIterator; 143 144 protected: 145 var_expr * theVarExpr; 146 expr * theDomainExpr; 147 148 protected: 149 forletwin_clause( 150 static_context* sctx, 151 CompilerCB* ccb, 152 const QueryLoc& loc, 153 ClauseKind kind, 154 var_expr* varExpr, 155 expr* domainExpr); 156 157 public: 158 ~forletwin_clause(); 159 160 void set_expr(expr* v); 161 get_expr()162 expr* get_expr() const { return theDomainExpr; } 163 get_var()164 var_expr* get_var() const { return theVarExpr; } 165 166 void set_var(var_expr* v); 167 }; 168 169 170 /***************************************************************************//** 171 172 ********************************************************************************/ 173 class for_clause : public forletwin_clause 174 { 175 friend class flwor_expr; 176 friend class ExprManager; 177 friend class ExprIterator; 178 179 protected: 180 var_expr * thePosVarExpr; 181 var_expr * theScoreVarExpr; 182 bool theAllowingEmpty; 183 184 protected: 185 for_clause( 186 static_context* sctx, 187 CompilerCB* ccb, 188 const QueryLoc& loc, 189 var_expr* varExpr, 190 expr* domainExpr, 191 var_expr* posVarExpr = NULL, 192 var_expr* scoreVarExpr = NULL, 193 bool isOuter = false); 194 195 public: 196 ~for_clause(); 197 is_allowing_empty()198 bool is_allowing_empty() const { return theAllowingEmpty; } 199 set_allowing_empty(bool allowing_empty)200 void set_allowing_empty(bool allowing_empty) { theAllowingEmpty = allowing_empty; } 201 202 var_expr* get_pos_var() const; 203 204 var_expr* get_score_var() const; 205 206 void set_pos_var(var_expr* v); 207 208 void set_score_var(var_expr* v); 209 210 flwor_clause* clone(expr::substitution_t& substitution) const; 211 212 std::ostream& put(std::ostream&) const; 213 }; 214 215 216 /***************************************************************************//** 217 theScoreVarExpr : 218 theLazyEval : Whether the window var can be materilized lazily or not. 219 ********************************************************************************/ 220 class let_clause : public forletwin_clause 221 { 222 friend class flwor_expr; 223 friend class ExprManager; 224 friend class ExprIterator; 225 226 protected: 227 var_expr * theScoreVarExpr; 228 bool theLazyEval; 229 230 protected: 231 let_clause( 232 static_context* sctx, 233 CompilerCB* ccb, 234 const QueryLoc& loc, 235 var_expr* varExpr, 236 expr* domainExpr, 237 bool lazy = false); 238 239 public: 240 ~let_clause(); 241 242 var_expr* get_score_var() const; 243 244 void set_score_var(var_expr* v); 245 setLazyEval(bool v)246 void setLazyEval(bool v) { theLazyEval = v; } 247 lazyEval()248 bool lazyEval() const { return theLazyEval; } 249 250 flwor_clause* clone(expr::substitution_t& substitution) const; 251 252 std::ostream& put(std::ostream&) const; 253 }; 254 255 256 /***************************************************************************//** 257 theWindowKind : 258 theWinStartCond : 259 theWinStopCond : 260 theLazyEval : Whether the window var can be materilized lazily or not. 261 ********************************************************************************/ 262 class window_clause : public forletwin_clause 263 { 264 friend class flwor_expr; 265 friend class ExprManager; 266 friend class ExprIterator; 267 268 public: 269 typedef enum { tumbling_window, sliding_window } window_t; 270 271 protected: 272 window_t theWindowKind; 273 flwor_wincond * theWinStartCond; 274 flwor_wincond * theWinStopCond; 275 bool theLazyEval; 276 277 protected: 278 window_clause( 279 static_context* sctx, 280 CompilerCB* ccb, 281 const QueryLoc& loc, 282 window_t winKind, 283 var_expr* varExpr, 284 expr* domainExpr, 285 flwor_wincond* winStart, 286 flwor_wincond* winStop, 287 bool lazy = false); 288 289 public: 290 ~window_clause(); 291 get_winkind()292 window_t get_winkind() const { return theWindowKind; } 293 get_win_start()294 flwor_wincond* get_win_start() const { return theWinStartCond; } 295 get_win_stop()296 flwor_wincond* get_win_stop() const { return theWinStopCond; } 297 298 void set_win_start(flwor_wincond* cond); 299 300 void set_win_stop(flwor_wincond* cond); 301 setLazyEval(bool v)302 void setLazyEval(bool v) { theLazyEval = v; } 303 lazyEval()304 bool lazyEval() const { return theLazyEval; } 305 306 flwor_clause* clone(expr::substitution_t& substitution) const; 307 308 std::ostream& put(std::ostream&) const; 309 }; 310 311 312 /***************************************************************************//** 313 314 Class flwor_wincond represents a start/stop condition of a window clause. 315 316 - Syntax: 317 318 WindowStartCondition ::= "start" WindowVars "when" ExprSingle 319 320 WindowEndCondition ::= "only"? "end" WindowVars "when" ExprSingle 321 322 WindowVars ::= ("$" CurrentItem)? 323 PositionalVar? 324 ("previous" "$" PreviousItem)? 325 ("next" "$" NextItem)? 326 327 - Data Members: 328 329 theIsOnly : The "only" flag, if this is an end condition 330 theInputVars : The var_exprs for the 4 condition vars that iterate over the 331 window domain expr and whose values are used to compute the 332 condition expr during each iteration. These vars are visible 333 only during the evaluation of the condition expr. 334 theOutputVars: When the condition expr evaluates to true, the current values 335 of theInputVars are copied to theOutputVars. So, theOutputVars 336 describe the starting/ending point of an established window 337 and they are visible to the rest of the query (i.e., they 338 become columns in the output stream produced by the window 339 clause). 340 theCondExpr : The start/end condition expr. 341 ********************************************************************************/ 342 class flwor_wincond 343 { 344 friend class flwor_expr; 345 friend class ExprManager; 346 friend class ExprIterator; 347 348 public: 349 struct vars 350 { 351 var_expr* posvar; 352 var_expr* curr; 353 var_expr* prev; 354 var_expr* next; 355 356 vars(); 357 ~vars(); 358 void set_flwor_clause(flwor_clause* c); 359 360 void clone(ExprManager* mgr, vars& cloneVars, expr::substitution_t& subst) const; 361 362 std::ostream& put(std::ostream&) const; 363 }; 364 365 protected: 366 bool theIsOnly; 367 vars theInputVars; 368 vars theOutputVars; 369 expr * theCondExpr; 370 371 CompilerCB * const theCCB; 372 373 protected: 374 flwor_wincond( 375 CompilerCB* ccb, 376 static_context* sctx, 377 bool isOnly, 378 const vars& in_vars, 379 const vars& out_vars, 380 expr* cond); 381 382 public: 383 ~flwor_wincond(); 384 get_cond()385 expr* get_cond() const { return theCondExpr; } 386 set_cond(expr * cond)387 void set_cond(expr* cond) { theCondExpr = cond; } 388 is_only()389 bool is_only() const { return theIsOnly; } 390 get_in_vars()391 const vars& get_in_vars() const { return theInputVars; } 392 get_out_vars()393 const vars& get_out_vars() const { return theOutputVars; } 394 395 void set_flwor_clause(flwor_clause *); 396 397 flwor_wincond* clone(expr::substitution_t& substitution) const; 398 399 std::ostream& put(std::ostream&) const; 400 }; 401 402 403 /***************************************************************************//** 404 - Syntax: 405 406 GroupByClause ::= "group" "by" GroupingSpecList 407 408 GroupSpecList ::= GroupingSpec ("," GroupingSpec)* 409 410 GroupSpec ::= "$" VarName (TypeDeclaration? ":=" ExprSingle)? 411 ("collation" URILiteral)? 412 413 - Data Members: 414 415 theGroupVars : For each grouping var X, theGroupVars contains a pair of 416 exprs: the 1st element of the pair is a reference to X in 417 the groupby's input tuple stream, and the 2nd element is 418 a var_expr representing the variable gX that the groupby 419 produces for X in its output tuple stream. 420 theNonGroupVars : For each non-grouping var Y, theGroupVars contains a pair of 421 exprs: the 1st element of the pair is a reference to Y in 422 the groupby's input tuple stream, and the 2nd element is 423 a var_expr representing the variable gY that the groupby 424 produces for Y in its output tuple stream. For each tuple 425 T produced by the groupby, gY is the concatenation of all 426 the Y values in the input tuples that were grouped into T. 427 theCollations : The collations to use when comparing values for grouping. 428 ********************************************************************************/ 429 class group_clause : public flwor_clause 430 { 431 friend class flwor_expr; 432 friend class ExprManager; 433 friend class ExprIterator; 434 435 protected: 436 rebind_list_t theGroupVars; 437 rebind_list_t theNonGroupVars; 438 std::vector<std::string> theCollations; 439 440 group_clause( 441 static_context* sctx, 442 CompilerCB* ccb, 443 const QueryLoc& loc, 444 const rebind_list_t& gvars, 445 rebind_list_t ngvars, 446 const std::vector<std::string>& collations); 447 448 public: 449 ~group_clause(); 450 get_collations()451 const std::vector<std::string>& get_collations() const { return theCollations; } 452 getNumGroupingVars()453 csize getNumGroupingVars() const { return theGroupVars.size(); } 454 getNumNonGroupingVars()455 csize getNumNonGroupingVars() const { return theNonGroupVars.size(); } 456 get_grouping_vars()457 const rebind_list_t& get_grouping_vars() const { return theGroupVars; } 458 get_nongrouping_vars()459 const rebind_list_t& get_nongrouping_vars() const { return theNonGroupVars; } 460 set_grouping_vars(rebind_list_t & v)461 void set_grouping_vars(rebind_list_t& v) { theGroupVars = v; } 462 set_nongrouping_ars(rebind_list_t & v)463 void set_nongrouping_ars(rebind_list_t& v) { theNonGroupVars = v; } 464 removeNonGroupingVar(rebind_list_t::iterator ite)465 void removeNonGroupingVar(rebind_list_t::iterator ite) { theNonGroupVars.erase(ite); } 466 beginGroupVars()467 rebind_list_t::iterator beginGroupVars() { return theGroupVars.begin(); } 468 beginGroupVars()469 rebind_list_t::const_iterator beginGroupVars() const { return theGroupVars.begin(); } 470 endGroupVars()471 rebind_list_t::iterator endGroupVars() { return theGroupVars.end(); } 472 endGroupVars()473 rebind_list_t::const_iterator endGroupVars() const { return theGroupVars.end(); } 474 beginNonGroupVars()475 rebind_list_t::iterator beginNonGroupVars() { return theNonGroupVars.begin(); } 476 beginNonGroupVars()477 rebind_list_t::const_iterator beginNonGroupVars() const { return theNonGroupVars.begin(); } 478 endNonGroupVars()479 rebind_list_t::iterator endNonGroupVars() { return theNonGroupVars.end(); } 480 endNonGroupVars()481 rebind_list_t::const_iterator endNonGroupVars() const { return theNonGroupVars.end(); } 482 483 expr* get_input_for_group_var(const var_expr* var); 484 485 expr* get_input_for_nongroup_var(const var_expr* var); 486 487 flwor_clause* clone(expr::substitution_t& substitution) const; 488 489 std::ostream& put(std::ostream&) const; 490 }; 491 492 493 494 /***************************************************************************//** 495 496 OrderByClause ::= (("order" "by") | ("stable" "order" "by")) OrderSpecList 497 498 OrderSpecList ::= OrderSpec ("," OrderSpec)* 499 500 OrderSpec ::= ExprSingle OrderModifier 501 502 OrderModifier ::= ("ascending" | "descending")? 503 ("empty" ("greatest" | "least"))? 504 ("collation" URILiteral)? 505 506 ********************************************************************************/ 507 class orderby_clause : public flwor_clause 508 { 509 friend class ExprIterator; 510 friend class ExprManager; 511 friend class flwor_expr; 512 513 protected: 514 515 bool theStableOrder; 516 std::vector<OrderModifier> theModifiers; 517 std::vector<expr*> theOrderingExprs; 518 519 protected: 520 orderby_clause( 521 static_context* sctx, 522 CompilerCB* ccb, 523 const QueryLoc& loc, 524 bool stable, 525 const std::vector<OrderModifier>& modifiers, 526 const std::vector<expr*>& orderingExprs); 527 528 public: is_stable()529 bool is_stable() const { return theStableOrder; } 530 get_modifiers()531 const std::vector<OrderModifier>& get_modifiers() const { return theModifiers; } 532 get_column_exprs()533 const std::vector<expr*>& get_column_exprs() const { return theOrderingExprs; } 534 begin()535 std::vector<expr*>::iterator begin() { return theOrderingExprs.begin(); } 536 end()537 std::vector<expr*>::iterator end() { return theOrderingExprs.end(); } 538 begin()539 std::vector<expr*>::const_iterator begin() const 540 { 541 return theOrderingExprs.begin(); 542 } 543 end()544 std::vector<expr*>::const_iterator end() const 545 { 546 return theOrderingExprs.end(); 547 } 548 num_columns()549 csize num_columns() const { return theOrderingExprs.size(); } 550 get_column_expr(csize i)551 expr* get_column_expr(csize i) const { return theOrderingExprs[i]; } 552 set_column_expr(csize i,expr * e)553 void set_column_expr(csize i, expr* e) { theOrderingExprs[i] = e; } 554 555 flwor_clause* clone(expr::substitution_t& substitution) const; 556 557 std::ostream& put(std::ostream&) const; 558 }; 559 560 561 /***************************************************************************//** 562 Used to meterialize the tuple stream at the location where the clause 563 appears at. It is needed to implement sequential flwor exprs. Materialize 564 clauses are created and inserted in the flwor expr during codegen. 565 ********************************************************************************/ 566 class materialize_clause : public flwor_clause 567 { 568 friend class ExprIterator; 569 friend class ExprManager; 570 friend class flwor_expr; 571 572 materialize_clause(static_context* sctx, CompilerCB* ccb, const QueryLoc& loc); 573 574 public: 575 flwor_clause* clone(expr::substitution_t& substitution) const; 576 577 std::ostream& put(std::ostream&) const; 578 }; 579 580 581 582 /***************************************************************************//** 583 CountClause ::= "count" "$" VarName 584 ********************************************************************************/ 585 class count_clause : public flwor_clause 586 { 587 friend class ExprIterator; 588 friend class ExprManager; 589 590 protected: 591 var_expr * theVarExpr; 592 593 count_clause(static_context* sctx, CompilerCB* ccb, const QueryLoc& loc, var_expr* var); 594 595 public: 596 ~count_clause(); 597 get_var()598 var_expr* get_var() const { return theVarExpr; } 599 600 flwor_clause* clone(expr::substitution_t& substitution) const; 601 }; 602 603 604 /***************************************************************************//** 605 WhereClause ::= ExprSingle 606 ********************************************************************************/ 607 class where_clause : public flwor_clause 608 { 609 friend class ExprIterator; 610 friend class ExprManager; 611 friend class flwor_expr; 612 613 expr * theWhereExpr; 614 615 where_clause(static_context* sctx, CompilerCB* ccb, const QueryLoc& loc, expr* where); 616 617 public: get_expr()618 expr* get_expr() const { return theWhereExpr; } 619 620 void set_expr(expr* where); 621 622 flwor_clause* clone(expr::substitution_t& substitution) const; 623 }; 624 625 626 /***************************************************************************//** 627 628 - For the Generalized FLWOR: 629 630 FLWORExpr ::= InitialClause IntermediateClause* ReturnClause 631 632 InitialClause ::= ForClause | LetClause | WindowClause 633 634 IntermediateClause ::= InitialClause | 635 WhereClause | 636 GroupByClause | 637 OrderByClause | 638 CountClause 639 640 - For the traditional FLWOR: 641 642 FLWORExpr ::= InitialClause FLWORClauseList? ReturnClause 643 644 InitialClause ::= ForClause | LetClause 645 646 FLWORClauseList ::= (ForClause | LetClause)* 647 WhereCluase? 648 GroupByClause? 649 OrderByClause? 650 651 ********************************************************************************/ 652 class flwor_expr : public expr 653 { 654 friend class ExprIterator; 655 friend class expr; 656 friend class ExprManager; 657 658 public: 659 typedef std::vector<flwor_clause*> clause_list_t; 660 661 protected: 662 bool theIsGeneral; 663 bool theHasSequentialClauses; 664 clause_list_t theClauses; 665 expr * theReturnExpr; 666 667 protected: 668 flwor_expr(CompilerCB* ccb, static_context* sctx, const QueryLoc& loc, bool general); 669 670 public: is_general()671 bool is_general() const { return theIsGeneral; } 672 set_general(bool v)673 void set_general(bool v) { theIsGeneral = true; } 674 get_return_expr()675 expr* get_return_expr() const { return theReturnExpr; } 676 set_return_expr(expr * e)677 void set_return_expr(expr* e) 678 { 679 theReturnExpr = e; 680 compute_scripting_kind(); 681 } 682 has_sequential_clauses()683 bool has_sequential_clauses() const { return theHasSequentialClauses; } 684 685 void compute_scripting_kind(); 686 num_clauses()687 csize num_clauses() const { return theClauses.size(); } 688 689 void add_clause(flwor_clause* c, bool computeScriptingKind = true); 690 691 void add_clause(csize pos, flwor_clause* c); 692 693 void add_where(expr* e); 694 695 void remove_clause(csize pos); 696 697 flwor_clause* get_clause(csize i) const; 698 clause_begin()699 clause_list_t::const_iterator clause_begin() const { return theClauses.begin(); } 700 clause_end()701 clause_list_t::const_iterator clause_end() const { return theClauses.end(); } 702 703 long defines_variable(const var_expr* v) const; 704 705 void get_vars_defined(std::vector<var_expr*>& varExprs) const; 706 707 expr* cloneImpl(substitution_t& substitution) const; 708 709 // The following 5 methods are for the simple flwor only. They should be 710 // removed eventually. 711 expr* get_where() const; 712 void set_where(expr* e); 713 void remove_where_clause(); 714 group_clause* get_group_clause() const; 715 orderby_clause* get_order_clause() const; 716 csize num_forlet_clauses(); 717 718 void accept(expr_visitor&); 719 720 std::ostream& put(std::ostream&) const; 721 }; 722 723 724 725 } // namespace zorba 726 727 #endif 728 729 /* 730 * Local variables: 731 * mode: c++ 732 * End: 733 */ 734 /* vim:set et sw=2 ts=2: */ 735