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 #include "stdafx.h"
17 
18 #include "compiler/expression/expr_base.h"
19 #include "compiler/expression/expr.h"
20 #include "compiler/expression/fo_expr.h"
21 #include "compiler/expression/flwor_expr.h"
22 #include "compiler/expression/script_exprs.h"
23 #include "compiler/expression/path_expr.h"
24 #include "compiler/expression/expr_iter.h"
25 #include "compiler/expression/expr_visitor.h"
26 #include "compiler/expression/expr_manager.h"
27 
28 #include "compiler/api/compilercb.h"
29 
30 #include "functions/function.h"
31 #include "functions/library.h"
32 #include "functions/func_errors_and_diagnostics.h"
33 
34 #include "types/root_typemanager.h"
35 #include "types/typeops.h"
36 
37 #include "system/globalenv.h"
38 
39 #include "diagnostics/xquery_diagnostics.h"
40 #include "diagnostics/assert.h"
41 
42 
43 namespace zorba
44 {
45 
46 
47 #define DEBUG_RT(e, t) t
48 
49 #ifndef DEBUG_RT
50 #define DEBUG_RT(e, t) print_expr_and_type(e, t)
51 
print_expr_and_type(expr * e,xqtref_t t)52 static xqtref_t print_expr_and_type(expr* e, xqtref_t t)
53 {
54   if (Properties::instance()->printStaticTypes())
55   {
56     std::cout << "Return type for " << e << ":\n";
57     e->put(std::cout);
58     std::cout << " => " << t->toString() << std::endl;
59   }
60   return t;
61 }
62 
63 #endif
64 
65 
66 typedef std::set<const var_expr *> var_ptr_set;
67 
68 
69 /////////////////////////////////////////////////////////////////////////////////
70 //                                                                             //
71 //  Base expr class                                                            //
72 //                                                                             //
73 /////////////////////////////////////////////////////////////////////////////////
74 
75 /*******************************************************************************
76 
77 ********************************************************************************/
78 expr* expr::iter_end_expr = NULL;
79 
80 expr** expr::iter_done = &expr::iter_end_expr;
81 
82 
83 /*******************************************************************************
84 
85 ********************************************************************************/
is_sequential(unsigned short theScriptingKind)86 bool expr::is_sequential(unsigned short theScriptingKind)
87 {
88   return (theScriptingKind & (VAR_SETTING_EXPR |
89                               APPLYING_EXPR |
90                               EXITING_EXPR |
91                               BREAKING_EXPR |
92                               SEQUENTIAL_FUNC_EXPR)) != 0;
93 }
94 
95 
checkNonUpdating(const expr * e)96 void expr::checkNonUpdating(const expr* e)
97 {
98   if (e != 0 && e->is_updating())
99   {
100     throw XQUERY_EXCEPTION(err::XUST0001,
101                            ERROR_PARAMS(ZED(XUST0001_Generic)),
102                            ERROR_LOC(e->get_loc()));
103   }
104 }
105 
106 
checkSimpleExpr(const expr * e)107 void expr::checkSimpleExpr(const expr* e)
108 {
109   if (e != 0 && e->is_updating())
110   {
111     throw XQUERY_EXCEPTION(err::XUST0001,
112                            ERROR_PARAMS(ZED(XUST0001_Generic)),
113                            ERROR_LOC(e->get_loc()));
114   }
115 
116   if (e != 0 && e->is_sequential())
117   {
118     throw XQUERY_EXCEPTION(zerr::XSST0006, ERROR_LOC(e->get_loc()));
119   }
120 }
121 
122 
123 /*******************************************************************************
124 
125 ********************************************************************************/
expr(CompilerCB * ccb,static_context * sctx,const QueryLoc & loc,expr_kind_t k)126 expr::expr(CompilerCB* ccb, static_context* sctx, const QueryLoc& loc, expr_kind_t k)
127   :
128   theSctx(sctx),
129   theLoc(loc),
130   theKind(k),
131   theFlags1(0),
132   theCCB(ccb)
133 {
134   theScriptingKind = UNKNOWN_SCRIPTING_KIND;
135 
136   // This is the default. The constructors for certain exprs set different values.
137   setNonDiscardable(ANNOTATION_FALSE);
138   setUnfoldable(ANNOTATION_FALSE);
139 }
140 
141 
142 /*******************************************************************************
143 
144 ********************************************************************************/
~expr()145 expr::~expr()
146 {
147 }
148 
149 
150 /*******************************************************************************
151 
152 ********************************************************************************/
get_type_manager() const153 TypeManager* expr::get_type_manager() const
154 {
155   return theSctx->get_typemanager();
156 }
157 
158 
159 /*******************************************************************************
160 
161 ********************************************************************************/
is_updating() const162 bool expr::is_updating() const
163 {
164   assert(theScriptingKind != UNKNOWN_SCRIPTING_KIND);
165 
166   return (theScriptingKind & UPDATING_EXPR) != 0;
167 }
168 
169 
is_sequential() const170 bool expr::is_sequential() const
171 {
172   assert(theScriptingKind != UNKNOWN_SCRIPTING_KIND);
173 
174   return is_sequential(theScriptingKind);
175 }
176 
177 
is_vacuous() const178 bool expr::is_vacuous() const
179 {
180   assert(theScriptingKind != UNKNOWN_SCRIPTING_KIND);
181 
182   return theScriptingKind == VACUOUS_EXPR;
183 }
184 
185 
is_simple() const186 bool expr::is_simple() const
187 {
188   assert(theScriptingKind != UNKNOWN_SCRIPTING_KIND);
189 
190   return theScriptingKind == SIMPLE_EXPR;
191 }
192 
193 
is_updating_or_vacuous() const194 bool expr::is_updating_or_vacuous() const
195 {
196   return (is_updating() || is_vacuous());
197 }
198 
199 
200 /*******************************************************************************
201 
202 ********************************************************************************/
set_not_exiting()203 void expr::set_not_exiting()
204 {
205   theScriptingKind &= ~EXITING_EXPR;
206 
207   if (theScriptingKind == UNKNOWN_SCRIPTING_KIND)
208   {
209     theScriptingKind = SIMPLE_EXPR;
210   }
211 }
212 
213 
214 /*******************************************************************************
215 
216 ********************************************************************************/
checkScriptingKind() const217 void expr::checkScriptingKind() const
218 {
219   if (is_updating() && is_sequential())
220   {
221     throw XQUERY_EXCEPTION(zerr::XSST0005,  ERROR_LOC(get_loc()));
222   }
223 
224 #ifndef NDEBUG
225   assert(theScriptingKind != UNKNOWN_SCRIPTING_KIND);
226 
227   if (theScriptingKind & VACUOUS_EXPR)
228     assert(theScriptingKind == VACUOUS_EXPR);
229 
230   if (theScriptingKind & SIMPLE_EXPR)
231     assert(theScriptingKind == SIMPLE_EXPR);
232 
233   if (theScriptingKind & UPDATING_EXPR)
234     assert(theScriptingKind == UPDATING_EXPR);
235 #endif
236 }
237 
238 
239 /*******************************************************************************
240 
241 ********************************************************************************/
clone() const242 expr* expr::clone() const
243 {
244   substitution_t subst;
245   return clone(subst);
246 }
247 
248 
clone(substitution_t & subst) const249 expr* expr::clone(substitution_t& subst) const
250 {
251   expr* lNewExpr = cloneImpl(subst);
252 
253   if (containsPragma())
254   {
255     lNewExpr->setContainsPragma(ANNOTATION_TRUE);
256     std::vector<pragma*> lPragmas;
257     theCCB->lookup_pragmas(this, lPragmas);
258     for (size_t i = 0; i < lPragmas.size(); ++i)
259     {
260       theCCB->add_pragma(lNewExpr, lPragmas[i]);
261     }
262   }
263   return lNewExpr;
264 }
265 
266 
cloneImpl(substitution_t & subst) const267 expr* expr::cloneImpl(substitution_t& subst) const
268 {
269   throw XQUERY_EXCEPTION(zerr::ZXQP0003_INTERNAL_ERROR, ERROR_LOC(get_loc()));
270 }
271 
272 
273 /*******************************************************************************
274 
275 ********************************************************************************/
accept_children(expr_visitor & v)276 void expr::accept_children(expr_visitor& v)
277 {
278   ExprIterator iter(this);
279   while (!iter.done())
280   {
281     if (**iter != NULL)
282       (**iter)->accept(v);
283 
284     iter.next();
285   }
286 }
287 
288 
289 /*******************************************************************************
290 
291 ********************************************************************************/
toString() const292 std::string expr::toString() const
293 {
294   std::ostringstream oss;
295   put(oss);
296   return oss.str();
297 }
298 
299 
300 /*******************************************************************************
301 
302 ********************************************************************************/
setFreeVars(FreeVars & s)303 void expr::setFreeVars(FreeVars& s)
304 {
305   theFreeVars.swap(s);
306 }
307 
308 
309 /*******************************************************************************
310 
311 ********************************************************************************/
clear_annotations()312 void expr::clear_annotations()
313 {
314   theFreeVars.clear();
315 
316   if (getProducesSortedNodes() != ANNOTATION_TRUE_FIXED)
317     setProducesSortedNodes(ANNOTATION_UNKNOWN);
318 
319   if (getProducesDistinctNodes() != ANNOTATION_TRUE_FIXED)
320     setProducesDistinctNodes(ANNOTATION_UNKNOWN);
321 
322   if (getIgnoresSortedNodes() != ANNOTATION_TRUE_FIXED)
323     setIgnoresSortedNodes(ANNOTATION_UNKNOWN);
324 
325   if (getIgnoresDuplicateNodes() != ANNOTATION_TRUE_FIXED)
326     setIgnoresDuplicateNodes(ANNOTATION_UNKNOWN);
327 
328   if (getNonDiscardable() != ANNOTATION_TRUE_FIXED)
329     setNonDiscardable(ANNOTATION_UNKNOWN);
330 
331   if (getUnfoldable() != ANNOTATION_TRUE_FIXED)
332     setUnfoldable(ANNOTATION_UNKNOWN);
333 
334   //theFlags1 = 0;
335   //setNonDiscardable(ANNOTATION_FALSE);
336   //setUnfoldable(ANNOTATION_FALSE);
337 
338   ExprIterator iter(this);
339   while (!iter.done())
340   {
341     (**iter)->clear_annotations();
342     iter.next();
343   }
344 }
345 
346 
347 
348 /*******************************************************************************
349   Returns true if the expr contains a nondeterministic function call
350 ********************************************************************************/
is_nondeterministic() const351 bool expr::is_nondeterministic() const
352 {
353   if (get_expr_kind() == fo_expr_kind)
354   {
355     const fo_expr* fo = static_cast<const fo_expr*>(this);
356     if (!fo->get_func()->isDeterministic())
357       return true;
358   }
359 
360   ExprConstIterator iter(this);
361   while(!iter.done())
362   {
363     const expr* ce = iter.get_expr();
364     if (ce != NULL && ce->is_nondeterministic())
365         return true;
366 
367     iter.next();
368   }
369 
370   return false;
371 }
372 
373 
374 /*******************************************************************************
375   Annotation : produces-sorted-nodes
376   Tells whether the expression produces nodes in document order or not.
377 ********************************************************************************/
getProducesSortedNodes() const378 BoolAnnotationValue expr::getProducesSortedNodes() const
379 {
380   return (BoolAnnotationValue)(theFlags1 & PRODUCES_SORTED_NODES_MASK);
381 }
382 
383 
setProducesSortedNodes(BoolAnnotationValue v)384 void expr::setProducesSortedNodes(BoolAnnotationValue v)
385 {
386   theFlags1 &= ~PRODUCES_SORTED_NODES_MASK;
387   theFlags1 |= v;
388 }
389 
390 
producesSortedNodes() const391 bool expr::producesSortedNodes() const
392 {
393   return (getProducesSortedNodes() == ANNOTATION_TRUE);
394 }
395 
396 
397 /*******************************************************************************
398   Annotation : produces-distinct-nodes
399   Tells whether the expression produces distinct nodes or not.
400 ********************************************************************************/
getProducesDistinctNodes() const401 BoolAnnotationValue expr::getProducesDistinctNodes() const
402 {
403   return (BoolAnnotationValue)
404          ((theFlags1 & PRODUCES_DISTINCT_NODES_MASK) >> PRODUCES_DISTINCT_NODES);
405 }
406 
407 
setProducesDistinctNodes(BoolAnnotationValue v)408 void expr::setProducesDistinctNodes(BoolAnnotationValue v)
409 {
410   theFlags1 &= ~PRODUCES_DISTINCT_NODES_MASK;
411   theFlags1 |= (v << PRODUCES_DISTINCT_NODES);
412 }
413 
414 
producesDistinctNodes() const415 bool expr::producesDistinctNodes() const
416 {
417   return (getProducesDistinctNodes() == ANNOTATION_TRUE);
418 }
419 
420 
421 /*******************************************************************************
422   Annotation : ignores-sorted-nodes
423   Tells whether the expression  needs to produce nodes in doc order or not.
424 ********************************************************************************/
getIgnoresSortedNodes() const425 BoolAnnotationValue expr::getIgnoresSortedNodes() const
426 {
427   return (BoolAnnotationValue)
428          ((theFlags1 & IGNORES_SORTED_NODES_MASK) >> IGNORES_SORTED_NODES);
429 }
430 
431 
setIgnoresSortedNodes(BoolAnnotationValue v)432 void expr::setIgnoresSortedNodes(BoolAnnotationValue v)
433 {
434   theFlags1 &= ~IGNORES_SORTED_NODES_MASK;
435   theFlags1 |= (v << IGNORES_SORTED_NODES);
436 }
437 
438 
ignoresSortedNodes() const439 bool expr::ignoresSortedNodes() const
440 {
441   return (getIgnoresSortedNodes() == ANNOTATION_TRUE);
442 }
443 
444 
445 /*******************************************************************************
446   Annotation : ignores-duplicates-nodes
447   Tells whether the expression needs to produce distinct nodes or not.
448 ********************************************************************************/
getIgnoresDuplicateNodes() const449 BoolAnnotationValue expr::getIgnoresDuplicateNodes() const
450 {
451   return (BoolAnnotationValue)
452          ((theFlags1 & IGNORES_DUPLICATE_NODES_MASK) >> IGNORES_DUPLICATE_NODES);
453 }
454 
455 
setIgnoresDuplicateNodes(BoolAnnotationValue v)456 void expr::setIgnoresDuplicateNodes(BoolAnnotationValue v)
457 {
458   theFlags1 &= ~IGNORES_DUPLICATE_NODES_MASK;
459   theFlags1 |= (v << IGNORES_DUPLICATE_NODES);
460 }
461 
462 
ignoresDuplicateNodes() const463 bool expr::ignoresDuplicateNodes() const
464 {
465   return (getIgnoresDuplicateNodes() == ANNOTATION_TRUE);
466 }
467 
468 
469 /*******************************************************************************
470 
471 ********************************************************************************/
getNonDiscardable() const472 BoolAnnotationValue expr::getNonDiscardable() const
473 {
474   return (BoolAnnotationValue)
475          ((theFlags1 & NON_DISCARDABLE_MASK) >> NON_DISCARDABLE);
476 }
477 
478 
setNonDiscardable(BoolAnnotationValue v)479 void expr::setNonDiscardable(BoolAnnotationValue v)
480 {
481   theFlags1 &= ~NON_DISCARDABLE_MASK;
482   theFlags1 |= (v << NON_DISCARDABLE);
483 }
484 
485 
isNonDiscardable() const486 bool expr::isNonDiscardable() const
487 {
488   BoolAnnotationValue v = getNonDiscardable();
489   return (v == ANNOTATION_TRUE || v == ANNOTATION_TRUE_FIXED);
490 }
491 
492 
493 /*******************************************************************************
494 
495 ********************************************************************************/
getUnfoldable() const496 BoolAnnotationValue expr::getUnfoldable() const
497 {
498   return (BoolAnnotationValue)
499          ((theFlags1 & UNFOLDABLE_MASK) >> UNFOLDABLE);
500 }
501 
502 
setUnfoldable(BoolAnnotationValue v)503 void expr::setUnfoldable(BoolAnnotationValue v)
504 {
505   theFlags1 &= ~UNFOLDABLE_MASK;
506   theFlags1 |= (v << UNFOLDABLE);
507 }
508 
509 
isUnfoldable() const510 bool expr::isUnfoldable() const
511 {
512   BoolAnnotationValue v = getUnfoldable();
513   return (v == ANNOTATION_TRUE || v == ANNOTATION_TRUE_FIXED);
514 }
515 
516 
517 /*******************************************************************************
518 
519 ********************************************************************************/
getContainsRecursiveCall() const520 BoolAnnotationValue expr::getContainsRecursiveCall() const
521 {
522   return (BoolAnnotationValue)
523          ((theFlags1 & CONTAINS_RECURSIVE_CALL_MASK) >> CONTAINS_RECURSIVE_CALL);
524 }
525 
526 
setContainsRecursiveCall(BoolAnnotationValue v)527 void expr::setContainsRecursiveCall(BoolAnnotationValue v)
528 {
529   theFlags1 &= ~CONTAINS_RECURSIVE_CALL_MASK;
530   theFlags1 |= (v << CONTAINS_RECURSIVE_CALL);
531 }
532 
533 
containsRecursiveCall() const534 bool expr::containsRecursiveCall() const
535 {
536   BoolAnnotationValue v = getContainsRecursiveCall();
537   return (v == ANNOTATION_TRUE || v == ANNOTATION_TRUE_FIXED);
538 }
539 
540 
541 /*******************************************************************************
542 
543 ********************************************************************************/
getInUnsafeContext() const544 BoolAnnotationValue expr::getInUnsafeContext() const
545 {
546   return (BoolAnnotationValue)
547          ((theFlags1 & IN_UNSAFE_CONTEXT_MASK) >> IN_UNSAFE_CONTEXT);
548 }
549 
550 
setInUnsafeContext(BoolAnnotationValue v)551 void expr::setInUnsafeContext(BoolAnnotationValue v)
552 {
553   theFlags1 &= ~IN_UNSAFE_CONTEXT_MASK;
554   theFlags1 |= (v << IN_UNSAFE_CONTEXT);
555 }
556 
557 
inUnsafeContext() const558 bool expr::inUnsafeContext() const
559 {
560   BoolAnnotationValue v = getInUnsafeContext();
561   return (v == ANNOTATION_TRUE || v == ANNOTATION_TRUE_FIXED);
562 }
563 
564 
565 /*******************************************************************************
566 
567 ********************************************************************************/
getContainsPragma() const568 BoolAnnotationValue expr::getContainsPragma() const
569 {
570   return (BoolAnnotationValue)
571          ((theFlags1 & CONTAINS_PRAGMA_MASK) >> CONTAINS_PRAGMA);
572 }
573 
574 
setContainsPragma(BoolAnnotationValue v)575 void expr::setContainsPragma(BoolAnnotationValue v)
576 {
577   theFlags1 &= ~CONTAINS_PRAGMA_MASK;
578   theFlags1 |= (v << CONTAINS_PRAGMA);
579 }
580 
581 
containsPragma() const582 bool expr::containsPragma() const
583 {
584   BoolAnnotationValue v = getContainsPragma();
585   return (v == ANNOTATION_TRUE || v == ANNOTATION_TRUE_FIXED);
586 }
587 
588 
589 /*******************************************************************************
590   This annotation tells whether the expr must produce nodes that belong to
591   "standalone" trees or not. A tree is standalone if it does not contain
592   references to other trees. Such references are created when the optimizer
593   decides that it is ok to avoid copying the referenced subtree (as would be
594   required by required by a strict implementation of the spec, eg., during
595   node construction).
596 ********************************************************************************/
getMustCopyNodes() const597 BoolAnnotationValue expr::getMustCopyNodes() const
598 {
599   return (BoolAnnotationValue)
600          ((theFlags1 & MUST_COPY_NODES_MASK) >> MUST_COPY_NODES);
601 }
602 
603 
setMustCopyNodes(BoolAnnotationValue v)604 void expr::setMustCopyNodes(BoolAnnotationValue v)
605 {
606   theFlags1 &= ~MUST_COPY_NODES_MASK;
607   theFlags1 |= (v << MUST_COPY_NODES);
608 }
609 
610 
611 /*******************************************************************************
612   Return true if the expr does not reference any variables.
613 ********************************************************************************/
is_constant() const614 bool expr::is_constant() const
615 {
616   if (get_expr_kind() == var_expr_kind)
617   {
618     return false;
619   }
620 
621   ExprConstIterator iter(this);
622   while (!iter.done())
623   {
624     if (!iter.get_expr()->is_constant())
625     {
626       return false;
627     }
628 
629     iter.next();
630   }
631 
632   return true;
633 }
634 
635 
636 /*******************************************************************************
637   Replace all references to "oldExpr" inside "e" with references to "newExpr".
638 ********************************************************************************/
replace_expr(expr * oldExpr,expr * newExpr)639 void expr::replace_expr(expr* oldExpr, expr* newExpr)
640 {
641   ExprIterator iter(this);
642   while (!iter.done())
643   {
644     if ((**iter) == oldExpr)
645     {
646       (**iter) = newExpr;
647     }
648     else
649     {
650       (**iter)->replace_expr(oldExpr, newExpr);
651     }
652 
653     iter.next();
654   }
655 }
656 
657 
658 /*******************************************************************************
659   Return true if the given expr is a subexpr of "this".
660 ********************************************************************************/
contains_expr(const expr * e) const661 bool expr::contains_expr(const expr* e) const
662 {
663   ExprConstIterator iter(this);
664   while (!iter.done())
665   {
666     if (iter.get_expr() == e)
667     {
668       return true;
669     }
670     else if (iter.get_expr()->contains_expr(e))
671     {
672       return true;
673     }
674 
675     iter.next();
676   }
677 
678   return false;
679 }
680 
681 
682 /*******************************************************************************
683   Check if the expr tree rooted at e contains any node-constructor expr. If so,
684   e cannot be hoisted.
685 ********************************************************************************/
contains_node_construction() const686 bool expr::contains_node_construction() const
687 {
688   expr_kind_t kind = get_expr_kind();
689 
690   if (kind == elem_expr_kind ||
691       kind == attr_expr_kind ||
692       kind == text_expr_kind ||
693       kind == doc_expr_kind  ||
694       kind == pi_expr_kind)
695   {
696     return true;
697   }
698 
699   ExprConstIterator iter(this);
700   while(!iter.done())
701   {
702     const expr* ce = iter.get_expr();
703     if (ce)
704     {
705       if (ce->contains_node_construction())
706       {
707         return true;
708       }
709     }
710     iter.next();
711   }
712   return false;
713 }
714 
715 
716 /*******************************************************************************
717 
718 ********************************************************************************/
get_exprs_of_kind(expr_kind_t kind,bool deep,std::vector<expr * > & exprs) const719 void expr::get_exprs_of_kind(
720     expr_kind_t kind,
721     bool deep,
722     std::vector<expr*>& exprs) const
723 {
724   if (kind == get_expr_kind())
725   {
726     exprs.push_back(const_cast<expr*>(this));
727 
728     if (!deep)
729       return;
730   }
731 
732   ExprConstIterator iter(this);
733   while(!iter.done())
734   {
735     const expr* ce = iter.get_expr();
736     if (ce)
737     {
738       ce->get_exprs_of_kind(kind, deep, exprs);
739     }
740 
741     iter.next();
742   }
743 }
744 
745 
746 /*******************************************************************************
747 
748 ********************************************************************************/
get_fo_exprs_of_kind(FunctionConsts::FunctionKind kind,bool deep,std::vector<expr * > & exprs) const749 void expr::get_fo_exprs_of_kind(
750     FunctionConsts::FunctionKind kind,
751     bool deep,
752     std::vector<expr*>& exprs) const
753 {
754   if (get_expr_kind() == fo_expr_kind)
755   {
756     if (static_cast<const fo_expr*>(this)->get_func()->getKind() == kind)
757     {
758       exprs.push_back(const_cast<expr*>(this));
759 
760       if (!deep)
761         return;
762     }
763   }
764 
765   ExprConstIterator iter(this);
766   while(!iter.done())
767   {
768     const expr* ce = iter.get_expr();
769     if (ce)
770     {
771       ce->get_fo_exprs_of_kind(kind, deep, exprs);
772     }
773 
774     iter.next();
775   }
776 }
777 
778 
779 /*******************************************************************************
780   If "this" is a var_expr or a wrapper_expr over a var_expr, return the var_expr;
781   otherwise return NULL.
782 ********************************************************************************/
get_var() const783 const var_expr* expr::get_var() const
784 {
785   expr_kind_t kind = get_expr_kind();
786   const expr* currExpr = this;
787 
788   while (kind == wrapper_expr_kind)
789   {
790     const wrapper_expr* wrapperExpr = static_cast<const wrapper_expr*>(currExpr);
791     currExpr = wrapperExpr->get_expr();
792     kind = currExpr->get_expr_kind();
793   }
794 
795   if (kind == var_expr_kind)
796     return static_cast<const var_expr*>(currExpr);
797 
798   return NULL;
799 }
800 
801 
802 /*******************************************************************************
803   This method tries to see if "this" is a map with respect to the given expr.
804 
805   Let E1 be an expr and E2 be a sub-expr of E1, Then, E1 is a map w.r.t. E2 iff
806 
807   for each value v2 of E2 with a cardinality N >= 1:
808 
809   v1 == CONCATENATE { v1i, i = 1, ..., N }, where
810 
811   v1 is the value of E1 when E2 is bound to v2 and
812   v1i is the value of E1 when E2 is bound to the i-th item in v2
813 
814   If the method returns true, then "this" is guaranteed to be a map. If it
815   returns false, it may still be a map, but this algorithm could not determine
816   that.
817 ********************************************************************************/
is_map(expr * e,static_context * sctx) const818 bool expr::is_map(expr* e, static_context* sctx) const
819 {
820   if (is_updating())
821     return false;
822 
823   xqtref_t type = e->get_return_type();
824   TypeConstants::quantifier_t q = type->get_quantifier();
825 
826   if (q == TypeConstants::QUANT_ONE || q == TypeConstants::QUANT_QUESTION)
827     return true;
828 
829   bool found = false;
830 
831   return is_map_internal(e, found);
832 }
833 
834 
is_map_internal(const expr * e,bool & found) const835 bool expr::is_map_internal(const expr* e, bool& found) const
836 {
837   if (found)
838     return true;
839 
840   if (this == e)
841   {
842     found = true;
843     return true;
844   }
845 
846   switch(get_expr_kind())
847   {
848 #ifdef ZORBA_WITH_DEBUGGER
849   case debugger_expr_kind:
850   {
851     const debugger_expr* debugExpr = static_cast<const debugger_expr *>(this);
852     return debugExpr->get_expr()->is_map_internal(e, found);
853   }
854 #endif
855 
856   case order_expr_kind:
857   {
858     const order_expr* orderExpr = static_cast<const order_expr *>(this);
859     return orderExpr->get_expr()->is_map_internal(e, found);
860   }
861 
862   case wrapper_expr_kind:
863   {
864     const wrapper_expr* wrapperExpr = static_cast<const wrapper_expr *>(this);
865     return wrapperExpr->get_expr()->is_map_internal(e, found);
866   }
867 
868   case const_expr_kind:
869   case var_expr_kind:
870     return true;
871 
872   case fo_expr_kind:
873   {
874     const fo_expr* foExpr = static_cast<const fo_expr *>(this);
875     const function* func = foExpr->get_func();
876     csize numArgs = foExpr->num_args();
877 
878     for (csize i = 0; i < numArgs; ++i)
879     {
880       const expr* argExpr = foExpr->get_arg(i);
881 
882       if (func->isMap(i))
883       {
884         if (argExpr->is_map_internal(e, found) && found)
885         {
886           return true;
887         }
888         else if (found)
889         {
890           return false;
891         }
892       }
893       else if (argExpr->contains_expr(e))
894       {
895         return false;
896       }
897     }
898 
899     return true;
900   }
901 
902   case flwor_expr_kind:
903   case gflwor_expr_kind:
904   {
905     const flwor_expr* flworExpr = static_cast<const flwor_expr *>(this);
906     bool haveOrderBy = false;
907     csize numClauses = flworExpr->num_clauses();
908 
909     for (csize i = 0; i < numClauses; ++i)
910     {
911       const flwor_clause* clause = flworExpr->get_clause(i);
912 
913       switch (clause->get_kind())
914       {
915       case flwor_clause::for_clause:
916       {
917         if (found)
918           break;
919 
920         if (clause->get_expr()->is_map_internal(e, found) && found)
921         {
922           break;
923         }
924         else if (found)
925         {
926           return false;
927         }
928 
929         break;
930       }
931       case flwor_clause::let_clause:
932       case flwor_clause::where_clause:
933       {
934         if (found)
935           break;
936 
937         if (clause->get_expr()->contains_expr(e))
938           return false;
939 
940         break;
941       }
942       case flwor_clause::window_clause:
943       {
944         if (found)
945           break;
946 
947         if (clause->get_expr()->contains_expr(e))
948           return false;
949 
950         const window_clause* wc = static_cast<const window_clause*>(clause);
951         flwor_wincond* startCond = wc->get_win_start();
952         flwor_wincond* stopCond = wc->get_win_stop();
953 
954         if (startCond && startCond->get_cond()->contains_expr(e))
955           return false;
956 
957         if (stopCond && stopCond->get_cond()->contains_expr(e))
958           return false;
959 
960         break;
961       }
962       case flwor_clause::group_clause:
963       case flwor_clause::count_clause:
964       {
965         if (found)
966           return false;
967 
968         break;
969       }
970       case flwor_clause::order_clause:
971       {
972         if (found)
973           return false;
974 
975         const orderby_clause* obc = static_cast<const orderby_clause*>(clause);
976 
977         csize numColumns = obc->num_columns();
978         for (csize k = 0; k < numColumns; ++k)
979         {
980           if (obc->get_column_expr(k)->contains_expr(e))
981             return false;
982         }
983 
984         haveOrderBy = true;
985         break;
986       }
987       default:
988         ZORBA_ASSERT(false);
989       }
990     } // for each clause
991 
992     if (found)
993     {
994       return true;
995     }
996     else
997     {
998       const expr* retExpr = flworExpr->get_return_expr();
999 
1000       if (retExpr->is_map_internal(e, found) && found && !haveOrderBy)
1001       {
1002         // TODO: actually we should return true only if the ordering mode for
1003         // the return expr is unordered.
1004         return true;
1005       }
1006       else if (!found)
1007       {
1008         return true;
1009       }
1010       else
1011       {
1012         return false;
1013       }
1014     }
1015   }
1016 
1017   case if_expr_kind:
1018   {
1019     const if_expr* ifExpr = static_cast<const if_expr*>(this);
1020 
1021     if (ifExpr->get_cond_expr()->contains_expr(e))
1022       return false;
1023 
1024     if (ifExpr->get_then_expr()->is_map_internal(e, found) &&
1025         ifExpr->get_else_expr()->is_map_internal(e, found))
1026       return true;
1027 
1028     return false;
1029   }
1030 
1031   case relpath_expr_kind:
1032   {
1033     const relpath_expr* pathExpr = static_cast<const relpath_expr*>(this);
1034     return (*pathExpr)[0]->is_map_internal(e, found);
1035   }
1036 
1037   case treat_expr_kind:
1038   {
1039     const treat_expr* treatExpr = static_cast<const treat_expr*>(this);
1040     TypeConstants::quantifier_t q = treatExpr->get_target_type()->get_quantifier();
1041 
1042     if (q == TypeConstants::QUANT_STAR || q == TypeConstants::QUANT_PLUS)
1043     {
1044       const expr* argExpr = treatExpr->get_input();
1045       return argExpr->is_map_internal(e, found);
1046     }
1047 
1048     return false;
1049   }
1050 
1051   case promote_expr_kind:
1052   {
1053     const promote_expr* promoteExpr = static_cast<const promote_expr*>(this);
1054     TypeConstants::quantifier_t q = promoteExpr->get_target_type()->get_quantifier();
1055 
1056     if (q == TypeConstants::QUANT_STAR || q == TypeConstants::QUANT_PLUS)
1057     {
1058       const expr* argExpr = promoteExpr->get_input();
1059       return argExpr->is_map_internal(e, found);
1060     }
1061 
1062     return false;
1063   }
1064 
1065   case instanceof_expr_kind:
1066   case castable_expr_kind:
1067   case name_cast_expr_kind:
1068   case cast_expr_kind:
1069   case validate_expr_kind:
1070   {
1071     return !contains_expr(e);
1072   }
1073 
1074   case doc_expr_kind:
1075   case elem_expr_kind:
1076   case attr_expr_kind:
1077   case text_expr_kind:
1078   case pi_expr_kind:
1079 #ifdef ZORBA_WITH_JSON
1080   case json_object_expr_kind:
1081   case json_direct_object_expr_kind:
1082   case json_array_expr_kind:
1083 #endif
1084   {
1085     return !contains_expr(e);
1086   }
1087 
1088   case trycatch_expr_kind:
1089   case extension_expr_kind:
1090   {
1091     return !contains_expr(e);
1092   }
1093 
1094   case transform_expr_kind:
1095   {
1096     const transform_expr* transformExpr = static_cast<const transform_expr*>(this);
1097 
1098     if (transformExpr->getReturnExpr()->is_map_internal(e, found) && found)
1099       return true;
1100 
1101     return !contains_expr(e);
1102   }
1103 
1104   case eval_expr_kind:
1105     return false; // TODO
1106 
1107   case var_decl_expr_kind:
1108   case var_set_expr_kind:
1109   {
1110     return !contains_expr(e);
1111   }
1112 
1113   case apply_expr_kind:
1114     return false;
1115 
1116   case block_expr_kind:
1117   case exit_expr_kind:
1118   case flowctl_expr_kind:
1119   case while_expr_kind:
1120     return false; // TODO
1121 
1122   case exit_catcher_expr_kind:
1123   {
1124     const exit_catcher_expr* catcherExpr = static_cast<const exit_catcher_expr*>(this);
1125     return catcherExpr->get_expr()->is_map_internal(e, found);
1126   }
1127 
1128   case insert_expr_kind:
1129   case delete_expr_kind:
1130   case rename_expr_kind:
1131   case replace_expr_kind:
1132     ZORBA_ASSERT(false);
1133 
1134   default:
1135     ZORBA_ASSERT(false);
1136   }
1137 
1138   return true;
1139 }
1140 
1141 
1142 /*******************************************************************************
1143 
1144 ********************************************************************************/
get_function_kind() const1145 FunctionConsts::FunctionKind expr::get_function_kind() const
1146 {
1147   if (get_expr_kind() == fo_expr_kind)
1148   {
1149     return static_cast<const fo_expr*>(this)->get_func()->getKind();
1150   }
1151 
1152   return FunctionConsts::FN_UNKNOWN;
1153 }
1154 
1155 
1156 /*******************************************************************************
1157   If "this" is a const expr that returns a qname, evaluate and return this
1158   qname. This method is used to extract the qname from the expression that is
1159   given as an arg to collection and index related functions.
1160 ********************************************************************************/
getQName(static_context * sctx) const1161 const store::Item* expr::getQName(static_context* sctx) const
1162 {
1163   RootTypeManager& rtm = GENV_TYPESYSTEM;
1164 
1165   TypeManager* tm = sctx->get_typemanager();
1166 
1167   const const_expr* qnameExpr = dynamic_cast<const const_expr*>(this);
1168 
1169   if (qnameExpr != NULL)
1170   {
1171     xqtref_t valueType = tm->create_value_type(qnameExpr->get_val());
1172 
1173     if (TypeOps::is_subtype(tm, *valueType, *rtm.QNAME_TYPE_ONE, get_loc()))
1174     {
1175       return qnameExpr->get_val();
1176     }
1177   }
1178   else if (get_expr_kind() == promote_expr_kind)
1179   {
1180     // We get here if the optimizer is turned off.
1181 
1182     const promote_expr* promoteExpr = static_cast<const promote_expr*>(this);
1183 
1184     const expr* argExpr = promoteExpr->get_input();
1185     const fo_expr* dataExpr = dynamic_cast<const fo_expr*>(argExpr);
1186 
1187     if (dataExpr != NULL &&
1188         dataExpr->get_func()->getKind() == FunctionConsts::FN_DATA_1)
1189     {
1190       argExpr = dataExpr->get_arg(0);
1191       const const_expr* qnameExpr = dynamic_cast<const const_expr*>(argExpr);
1192 
1193       if (qnameExpr != NULL)
1194       {
1195         xqtref_t valueType = tm->create_value_type(qnameExpr->get_val());
1196 
1197         if (TypeOps::is_subtype(tm, *valueType, *rtm.QNAME_TYPE_ONE, get_loc()))
1198         {
1199           return qnameExpr->get_val();
1200         }
1201       }
1202     }
1203   }
1204 
1205   return NULL;
1206 }
1207 
1208 
1209 
1210 /*******************************************************************************
1211 
1212 ********************************************************************************/
get_return_type_with_empty_input(const expr * input) const1213 xqtref_t expr::get_return_type_with_empty_input(const expr* input) const
1214 {
1215   expr* emptyExpr = theCCB->theEM->create_fo_expr(input->get_sctx(),
1216                                  QueryLoc::null,
1217                                  GET_BUILTIN_FUNCTION(OP_CONCATENATE_N));
1218   expr::substitution_t subst;
1219   subst[input] = emptyExpr;
1220 
1221   expr* cloneExpr = clone(subst);
1222 
1223   return cloneExpr->get_return_type();
1224 }
1225 
1226 
1227 } // namespace zorba
1228 /* vim:set et sw=2 ts=2: */
1229