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 <sstream>
19 #include <iterator>
20 #include <stack>
21 #include <map>
22 #include <bitset>
23 
24 #include <zorba/config.h>
25 #include <zorba/diagnostic_list.h>
26 
27 
28 #include "common/common.h"
29 
30 #include "store/api/item.h"
31 #include "store/api/update_consts.h"
32 #include "store/api/store.h"
33 #include "store/api/item_factory.h"
34 
35 #include "runtime/api/plan_wrapper.h"
36 
37 #include "compiler/translator/prolog_graph.h"
38 #include "compiler/translator/translator.h"
39 #include "compiler/translator/module_version.h"
40 #include "compiler/api/compilercb.h"
41 #include "compiler/api/compiler_api.h"
42 #include "compiler/codegen/plan_visitor.h"
43 #include "compiler/parsetree/parsenodes.h"
44 #include "compiler/parser/parse_constants.h"
45 #include "compiler/parsetree/parsenode_visitor.h"
46 #include "compiler/expression/expr.h"
47 #include "compiler/expression/fo_expr.h"
48 #include "compiler/expression/script_exprs.h"
49 #include "compiler/expression/json_exprs.h"
50 #include "compiler/expression/update_exprs.h"
51 #ifndef ZORBA_NO_FULL_TEXT
52 #include "compiler/expression/ft_expr.h"
53 #include "compiler/expression/ftnode.h"
54 #endif /* ZORBA_NO_FULL_TEXT */
55 #include "compiler/expression/var_expr.h"
56 #include "compiler/expression/flwor_expr.h"
57 #include "compiler/expression/path_expr.h"
58 #include "compiler/expression/function_item_expr.h"
59 #include "compiler/expression/pragma.h"
60 #include "compiler/rewriter/framework/rewriter_context.h"
61 #include "compiler/rewriter/framework/rewriter.h"
62 #include "compiler/rewriter/tools/expr_tools.h"
63 #include "compiler/xqddf/value_index.h"
64 #include "compiler/xqddf/value_ic.h"
65 #include "compiler/xqddf/collection_decl.h"
66 
67 #include "system/globalenv.h"
68 #include "system/properties.h"
69 
70 #include "functions/library.h"
71 #include "functions/signature.h"
72 #include "functions/udf.h"
73 #include "functions/external_function.h"
74 #include "functions/func_ft_module.h"
75 #include "functions/func_ft_module_impl.h"
76 
77 #include "annotations/annotations.h"
78 
79 #include "context/static_context.h"
80 #include "context/static_context_consts.h"
81 #include "context/namespace_context.h"
82 #include "context/dynamic_context.h"
83 
84 #include "types/node_test.h"
85 #include "types/casting.h"
86 #include "types/typeops.h"
87 #include "types/typemanagerimpl.h"
88 #include "types/schema/schema.h"
89 
90 #include "zorbatypes/URI.h"
91 #include "zorbatypes/numconversions.h"
92 #include "zorbamisc/ns_consts.h"
93 
94 #ifdef ZORBA_WITH_DEBUGGER
95 #include "debugger/debugger_commons.h"
96 #endif
97 
98 #include "zorbautils/string_util.h"
99 #include "zorbautils/fatal.h"
100 
101 #include "diagnostics/xquery_diagnostics.h"
102 #include "diagnostics/dict.h"
103 #include "diagnostics/util_macros.h"
104 
105 #include "util/ascii_util.h"
106 #include "util/stl_util.h"
107 #include "util/string_util.h"
108 #include "util/tracer.h"
109 #include "util/utf8_util.h"
110 #include "util/xml_util.h"
111 #include "util/hashmap.h"
112 
113 
114 #define NODE_SORT_OPT
115 
116 namespace zorba
117 {
118 
119 class ModulesInfo;
120 class TranslatorImpl;
121 
122 static expr* translate_aux(
123     TranslatorImpl* rootTranslator,
124     const parsenode& root,
125     static_context* rootSctx,
126     csize rootSctxId,
127     ModulesInfo* minfo,
128     const std::map<zstring, zstring>& modulesStack,
129     bool isLibModule,
130     StaticContextConsts::xquery_version_t maxLibModuleVersion =
131       StaticContextConsts::xquery_version_unknown);
132 
133 
134 /*******************************************************************************
135 
136 ********************************************************************************/
137 #ifndef NDEBUG
138 
139 #define TRACE_VISIT()                                                   \
140   const QueryLoc& loc = v.get_location(); (void)loc;                    \
141                                                                         \
142   if (Properties::instance()->traceTranslator())                        \
143     std::cout << std::string(++thePrintDepth, ' ') << TRACE << ", stk size "   \
144               << theNodeStack.size() << ", tstk size: " << theTypeStack.size() \
145               << ", scope depth " << theScopeDepth << std::endl;
146 
147 
148 #define TRACE_VISIT_OUT()                                               \
149   const QueryLoc& loc = v.get_location(); (void)loc;                    \
150                                                                         \
151   if (Properties::instance()->traceTranslator())                        \
152     std::cout << std::string(thePrintDepth--, ' ') << TRACE << ", stk size: "  \
153               << theNodeStack.size() << ", tstk size: " << theTypeStack.size() \
154               << ", scope depth " << theScopeDepth << std::endl;
155 
156 #else
157 
158 #define TRACE_VISIT()                                              \
159   const QueryLoc& loc = v.get_location(); (void)loc;               \
160 
161 
162 #define TRACE_VISIT_OUT()                                          \
163   const QueryLoc& loc = v.get_location(); (void)loc;               \
164 
165 #endif
166 
167 
168 /*******************************************************************************
169 
170 ********************************************************************************/
171 #define ZANN_CONTAINS( ann ) theAnnotations->contains(AnnotationInternal::ann)
172 
173 
174 /*******************************************************************************
175   Check/set certain bool data members of TranslatorImpl: raise error if true
176   already otherwise set to true.
177 ********************************************************************************/
178 #define CHK_SINGLE_DECL( state, err ) \
179 do { if (state) throw XQUERY_EXCEPTION(err); state = true; } while (0)
180 
181 
182 /*******************************************************************************
183 
184 ********************************************************************************/
185 #define ITEM_FACTORY (GENV.getStore().getItemFactory())
186 
187 #define CTX_TM theSctx->get_typemanager()
188 
189 
190 /*******************************************************************************
191   Internal names for certain implicit vars
192 ********************************************************************************/
193 #define DOT_VARNAME getDotVarName()
194 #define DOT_POS_VARNAME getDotPosVarName()
195 #define LAST_IDX_VARNAME getLastIdxVarName()
196 
197 #define DOT_REF                                             \
198   theExprManager->create_wrapper_expr(theRootSctx,          \
199                    loc,                                     \
200                    lookup_ctx_var(DOT_VARNAME, loc))
201 
202 namespace translator_ns
203 {
204 
205 /*******************************************************************************
206 
207 ********************************************************************************/
peek_stack(std::stack<T> & stk)208 template<class T> T& peek_stack(std::stack<T> &stk)
209 {
210   ZORBA_ASSERT(! stk.empty());
211   return stk.top();
212 }
213 
214 
pop_stack(std::stack<T> & stk)215 template <typename T> T pop_stack(std::stack<T> &stk)
216 {
217   T x = translator_ns::peek_stack(stk);
218   stk.pop();
219   return x;
220 }
221 }
222 
223 
224 /*******************************************************************************
225 
226 ********************************************************************************/
227 struct NodeSortInfo
228 {
229   bool    theSingleInput;
230   bool    theOnlyChildAxes;
231   bool    theHaveFilterSteps;
232   ulong   theNumSteps;
233 
NodeSortInfozorba::NodeSortInfo234   NodeSortInfo()
235     :
236     theSingleInput(true),
237     theOnlyChildAxes(true),
238     theHaveFilterSteps(false),
239     theNumSteps(0)
240   {
241   }
242 };
243 
244 /*******************************************************************************
245 
246   There is only one ModulesInfo instance per compilation. It is created on the
247   stack by the translate() method.
248 
249   theCCB        : The control block for the whole query.
250                   (see compiler/api/compilercb.h).
251 
252   mod_ns_map    : Maps resolved module location uris to target namespaces.
253                   Used to skip compilation of a module that has been compiled
254                   already (for example this is the case when 2 imported modules
255                   both import a common module). It is also used to make sure
256                   that a location uri does not appear in two module import
257                   statements with different target namespaces.
258 
259   mod_sctx_map  : Maps resolved module location uris to sctx objs containing
260                   the var and udf declarations that are exported by the
261                   modules corresponding to the location uris.
262 
263   theInitExprs  : Contains the initializing expr for each prolog var in each
264                   module participating in the compilation (see method
265                   wrap_in_globalvar_assigh())
266 
267   globalSctx    : A single static_context which contains ALL function and
268                   variable declarations from ALL imported modules. This is
269                   used to catch conflicting definitions.
270 
271 ********************************************************************************/
272 class ModulesInfo
273 {
274 public:
275   CompilerCB                        * theCCB;
276   hashmap<zstring, static_context_t>  mod_sctx_map;
277   hashmap<zstring, zstring>           mod_ns_map;
278   checked_vector<expr*>              theInitExprs;
279   std::auto_ptr<static_context>       globalSctx;
280 
281 public:
ModulesInfo(CompilerCB * topCompilerCB)282   ModulesInfo(CompilerCB* topCompilerCB)
283     :
284     theCCB(topCompilerCB),
285     globalSctx(static_cast<static_context *>
286                (topCompilerCB->theRootSctx->get_parent())->create_child_context())
287   {
288   }
289 };
290 
291 
292 
293 /*******************************************************************************
294 
295   A new instance of TranslatorImpl is created for the translation of each
296   module component participating in a query. The instance is destroyed when
297   the translation of the associated module component is finished.
298 
299   theRootTranslator :
300   -------------------
301   Pointer to the root translator (The root translator points to itself).
302 
303   theRTM :
304   --------
305   Reference to the root type manager (cached here for convenience).
306 
307   theCCB :
308   --------
309   The control block for the whole query. (see compiler/api/compilercb.h).
310 
311   theModulesInfo :
312   ----------------
313   Pointer to the unique ModulesInfo instance (see class ModulesInfo above).
314 
315   theModulesStack :
316   -----------------
317   A map containing the URLs of all the module components in the chain of module
318   imports from this module component up to the main module. For each such URL,
319   the map also stores the target namespace URI of module component. This map is
320   used to handle cycles in a chain of module imports.
321 
322   theHaveModuleImportCycle :
323   --------------------------
324 
325   theImportedModules :
326   --------------------
327   A set containing the target namespace uris of the modules directly imported
328   by this  module. Used to check that the same module is not imported twice by
329   this module.
330 
331   theModuleNamespace :
332   --------------------
333   If this translator is working on a library module, theModuleNamespace is the
334   namespace uri of that module.
335 
336   theModulePrefix :
337   -----------------
338   If this translator is working on a library module, theModulePrefix is the
339   prefix associated with the ns uri of that module.
340 
341   theImportedSchemas :
342   --------------------
343    Set of ns uris for all schemas directly imported by this module. Used to
344   check that the same schema is not imported twice by this module.
345 
346   theCurrSctxId :
347   ---------------
348   The numeric id of the last sctx that was added to theSctxMap of the query
349   (see api/xqueryimpl.h).
350 
351   theRootSctx :
352   -------------
353   The root sctx obj of the module that is being translated by this translator.
354   Every time an expr is created, theRootSctx is stored in the expr obj, so that
355   each expr will be executed in the appropriate sctx.
356 
357   theSctx :
358   ---------
359   The "current" static context node. It is initialized with theRootSctx.
360 
361   theSctxList :
362   -------------
363   A list of static contexts which need to be kept alive only during the
364   translation of a module. It's managed in push_scope and pop_scope. In
365   DEBUGGER mode, this list remains empty.
366 
367   theSctxIdStack :
368   ----------------
369   In non-DEBUGGER mode, this stack remains empty.
370 
371   export_sctx :
372   -------------
373 
374   In case this is a library module translator, export_sctx is populated with
375   the variable, function, and xqddf declarations that are exported by the
376   module, i.e., the var, udf, and xqddf declarations that appear in the prolog
377   of this module. The export_sctx is created by the importing module, populated
378   by the imported module, and then merged by the importing module into its own
379   sctx. export_sctx is "shared" between importing and imported modules via the
380   theModulesInfo->mod_sctx_map. export_sctx is needed because module import is
381   not transitive: If M1 imports M2 and M2 imports M3, then M3's declarations
382   must be seen by M2, but not by M1. This means, that the regular root sctx
383   S2 of M2 will contain the decls from both M2 and M3. So, M1 should not import
384   S2 into its own sctx S1. Instead, we create ES2 for M2 and register in there
385   the decls of M2 only; then, we import ES2 to S1.
386 
387   theNSCtx :
388   ----------
389 
390   The "current" namespace bindings node. It is initialized with a newly allocated
391   theNSCtx node, which points to the initial sctx node. The initial sctx node
392   stores all ns bindings that are declared in the prolog. theNSCtx nodes are
393   created to store ns bindings declared in element constructors. In general, the
394   theNSCtx hierarchy (of which the initial sctx node and its ancestors are
395   considered to be part of) defines the namepsace bindings that are in scope
396   for each expr. theNSCtx nodes are kept separate from sctx nodes because sctx
397   nodes may disappear after translation is done, whereas certain exprs need to
398   know their theNSCtx in later compilation phases as well.
399 
400   thePrintDepth :
401   ---------------
402    For pretty tracing
403 
404   theScopeDepth :
405   ---------------
406   Incremented/Decremented every time a scope is pushed/popped. Used for some
407   sanity checking only.
408 
409   thePrologVars :
410   ---------------
411   thePrologVars vector contains one entry for each var V declared in the prolog
412   of this module. The entry maps the var_expr for V to the expr E that initializes
413   V (E is NULL for vars without init expr). At the end of each module translation,
414   the method wrap_in_globalvar_assign() creates appropriate initialization exprs
415   for each var in thePrologVars and registers them in theModulesInfo->theInitExprs,
416   so that they will be incorporated in the whole query plan at the end of the
417   translation of the root module.
418 
419   thePrologGraph :
420   ----------------
421 
422   A data struct implementing the dependency graph among the variables and udfs
423   declared in the prolog of a module. An edge (v1, v2) in this graph indicates
424   that v1 depends on v2 (where v1 and v2 may represent either var or udf decls).
425   Examples:
426   - $x := $y + g($z)  :  $x --> ($y, g, $z)
427   - f { $y + g($z) }  :  f  --> ($y, g, $z)
428   Initially only direct dependencies are registered. The graph is later expanded
429   by the reorder_globals() method to include transitive dependencies as well.
430   Then, the graph is used to sort thePrologVars so that vars are initialized
431   before they are referenced.
432 
433   theCurrentPrologVFDecl :
434   ------------------------
435 
436   During the translation of a variable or function declaration in the prolog,
437   theCurrentPrologVFDecl stores a ptr to associated var_expr or function obj,
438   respectively. It is used in building the thePrologGraph: if theCurrentPrologVFDecl
439   is not NULL, then the translator knows that it is in the scope of a var
440   or function decl, and if that declaration references another var V or calls
441   another function F, then it creates a dependency between the var or function
442   specified by theCurrentPrologVFDecl and V or F. The same mechanism is used to
443   detect "leaf" udfs, i.e., udfs that do not invoke other udfs. Such udfs are
444   inlined by the optimizer.
445 
446   theExitExprs:
447   -------------
448   This vector stores the exit_exprs that are encountered during the translation
449   of the body of a UDF. It is used to associated those exot_exprs with the
450   exit_catcher_expr that is added at the top of the UDF body.
451 
452   theHaveUpdatingExitExprs :
453   --------------------------
454 
455   theHaveSequentialExitExprs :
456   ----------------------------
457 
458   theHaveContextItemDecl :
459   ------------------------
460 
461   theAssignedVars :
462   -------------------
463 
464   Local or global variables which are currently in-scope and for which (a)
465   an assignment statement has been encountered, and (b) the block expr that
466   declares the var has not been exited yet. This is used to determine the
467   category of expressions.
468 
469   theTempVarCounter :
470   -------------------
471 
472   Counter used to generate names for internally generated variables. The names
473   are unique within this translator.
474 
475   theNodestack :
476   --------------
477 
478   If E is the expr that is currently being built, then theNodeStack contains all
479   the ancestors (or ancestor place-holdres) of E in the expr tree.
480 
481   theTypeStack :
482   --------------
483 
484   Stack of the static types for some of the exprs in theNodeStack.
485 
486   theFlworClausesStack :
487   ----------------------
488 
489   theTryStack :
490   ------------------
491 
492   Stack of try exprs. It is used to detect cases where a LET or window var is
493   referenced inside a try block, but defined outside that block. In such cases,
494   lazy materialization of the var must be disabled.
495 
496   theNodeSortStack :
497   ------------------
498 
499   theAnnotations :
500   ----------------
501 
502   Annotations belonging to the "current" variable or function declaration.
503   After the variable or function has been translated, this member is set
504   to null again.
505 
506   theIndexDecl :
507   --------------
508 
509   Used during the translation of an index declaration to hold the IndexDecl obj.
510 
511   theIsInIndexDomain :
512   --------------------
513 
514   Set to true just before translating the domain expr, and set back to false
515   right after the translation of the domain expr is finished. It is used to
516   check that the domain expr does not reference any external context item.
517 
518   hadBSpaceDecl        : Set to true if prolog has boundary space decl. Used to
519                          check that such a decl does not appear more than once.
520   hadBUriDecl          : Set to true if prolog has bas uri decl. Used to check
521                          that such a decl does not appear more than once.
522   hadConstrDecl        : Set to true if prolog has construction mode decl. Used
523                          to check that such a decl does not appear more than once.
524   hadCopyNSDecl        : Set to true if prolog has copy namespaces decl. Used to
525                          check that such a decl does not appear more than once.
526   hadEmptyOrdDecl      : Set to true if prolog has empty seq order decl. Used to
527                          check that such a decl does not appear more than once.
528   hadOrdModeDecl       : Set to true if prolog has doc order decl. Used to
529                          check that such a decl does not appear more than once.
530 
531   xquery_fns_def_dot   : Set of the names of all built-in functions accepting
532                          "." as their default arg. TODO: should be static
533 
534   theIsWSBoundaryStack : Saves true if the previous DirElemContent is a boundary
535                          for whitespace (DirElemConstructor or EnclosedExpr).
536   thePossibleWSContentStack: Saves the previous DirElemContent if it might be
537                          bounded whitespace (if it contains whitespace and its
538                          previous item is a whitespace boundary). It must be
539                          checked if the next item is a whitespace boundary.
540 
541   op_concatenate       : Cached ptr to the function obj for the concat func
542 
543   theMaxLibModuleVersion  : This specifies the maximum module version for an
544                          imported library. In case a version 1.0 module tries
545                          to import a version 1.1 library, an error must be raised.
546                          A value of xquery_version_unknown is interpreted as
547                          "don't care".
548 
549 ********************************************************************************/
550 class TranslatorImpl : public parsenode_visitor
551 {
552 protected:
553   TranslatorImpl                       * theRootTranslator;
554 
555   RootTypeManager                      & theRTM;
556 
557   CompilerCB                           * theCCB;
558 
559   ExprManager                          * theExprManager;
560 
561   ModulesInfo                          * theModulesInfo;
562   std::map<zstring, zstring>             theModulesStack;
563   bool                                   theHaveModuleImportCycle;
564   std::set<std::string>                  theImportedModules;
565   zstring                                theModuleNamespace;
566   zstring                                theModulePrefix;
567 
568   std::set<std::string>                  theImportedSchemas;
569 
570   csize                                  theCurrSctxId;
571 
572   static_context                       * theRootSctx;
573 
574   static_context                       * theSctx;
575 
576   std::vector<static_context_t>          theSctxList;
577 
578   std::stack<csize>                      theSctxIdStack;
579 
580   static_context                       * export_sctx;
581 
582   rchandle<namespace_context>            theNSCtx;
583 
584   ulong                                  thePrintDepth;
585   int                                    theScopeDepth;
586 
587   std::list<GlobalBinding>               thePrologVars;
588 
589   PrologGraph                            thePrologGraph;
590   PrologGraphVertex                      theCurrentPrologVFDecl;
591 
592   std::vector<expr*>                     theExitExprs;
593 
594   bool                                   theHaveUpdatingExitExprs;
595 
596   bool                                   theHaveSequentialExitExprs;
597 
598   bool                                   theHaveContextItemDecl;
599 
600   std::vector<std::vector<var_expr*> >   theAssignedVars;
601 
602   int                                    theTempVarCounter;
603 
604   std::stack<expr*>                     theNodeStack;
605 
606 #ifndef ZORBA_NO_FULL_TEXT
607   std::stack<ftnode*>                    theFTNodeStack;
608 #endif
609 
610   std::stack<xqtref_t>                   theTypeStack;
611 
612   std::vector<flwor_clause*>            theFlworClausesStack;
613 
614   std::vector<const parsenode*>          theTryStack;
615 
616   std::stack<NodeSortInfo>               theNodeSortStack;
617 
618   std::stack<bool>                       theInWhileStack;
619 
620   rchandle<AnnotationList>               theAnnotations;
621 
622   IndexDecl_t                            theIndexDecl;
623   bool                                   theIsInIndexDomain;
624 
625   bool                                   hadBSpaceDecl;
626   bool                                   hadBUriDecl;
627   bool                                   hadConstrDecl;
628   bool                                   hadCopyNSDecl;
629   bool                                   hadDefNSDecl;
630   bool                                   hadEmptyOrdDecl;
631   bool                                   hadOrdModeDecl;
632   bool                                   hadRevalDecl;
633 
634   std::stack<bool>                       theIsWSBoundaryStack;
635   std::stack<const DirElemContent*>      thePossibleWSContentStack;
636 
637   std::bitset<FunctionConsts::FN_MAX_FUNC> xquery_fns_def_dot;
638 
639   function                           * op_concatenate;
640 
641   rchandle<QName>                      theDotVarName;
642   rchandle<QName>                      theDotPosVarName;
643   rchandle<QName>                      theLastIdxVarName;
644 
645   std::vector<var_expr*>              theScopedVars;
646 
647   std::vector<pragma*>                theScopedPragmas;
648 
649   StaticContextConsts::xquery_version_t theMaxLibModuleVersion;
650 
651 public:
652 
TranslatorImpl(TranslatorImpl * rootTranslator,static_context * rootSctx,csize rootSctxId,ModulesInfo * minfo,const std::map<zstring,zstring> & modulesStack,bool isLibModule,StaticContextConsts::xquery_version_t maxLibModuleVersion=StaticContextConsts::xquery_version_unknown)653 TranslatorImpl(
654     TranslatorImpl* rootTranslator,
655     static_context* rootSctx,
656     csize rootSctxId,
657     ModulesInfo* minfo,
658     const std::map<zstring, zstring>& modulesStack,
659     bool isLibModule,
660     StaticContextConsts::xquery_version_t maxLibModuleVersion =
661       StaticContextConsts::xquery_version_unknown)
662   :
663   theRootTranslator(rootTranslator),
664   theRTM(GENV_TYPESYSTEM),
665   theCCB(minfo->theCCB),
666   theExprManager(theCCB->theEM),
667   theModulesInfo(minfo),
668   theModulesStack(modulesStack),
669   theHaveModuleImportCycle(false),
670   theCurrSctxId(rootSctxId),
671   theRootSctx(rootSctx),
672   theSctx(rootSctx),
673   export_sctx(NULL),
674   theNSCtx(new namespace_context(theSctx)),
675   thePrintDepth(0),
676   theScopeDepth(0),
677   thePrologGraph(rootSctx),
678   theHaveUpdatingExitExprs(false),
679   theHaveSequentialExitExprs(false),
680   theHaveContextItemDecl(false),
681   theTempVarCounter(1),
682   theIsInIndexDomain(false),
683   hadBSpaceDecl(false),
684   hadBUriDecl(false),
685   hadConstrDecl(false),
686   hadCopyNSDecl(false),
687   hadDefNSDecl(false),
688   hadEmptyOrdDecl(false),
689   hadOrdModeDecl(false),
690   hadRevalDecl(false),
691   theMaxLibModuleVersion(maxLibModuleVersion)
692 {
693   xquery_fns_def_dot.set(FunctionConsts::FN_STRING_LENGTH_0);
694   xquery_fns_def_dot.set(FunctionConsts::FN_NORMALIZE_SPACE_0);
695   xquery_fns_def_dot.set(FunctionConsts::FN_ROOT_0);
696   xquery_fns_def_dot.set(FunctionConsts::FN_BASE_URI_0);
697   xquery_fns_def_dot.set(FunctionConsts::FN_NAMESPACE_URI_0);
698   xquery_fns_def_dot.set(FunctionConsts::FN_LOCAL_NAME_0);
699   xquery_fns_def_dot.set(FunctionConsts::FN_NAME_0);
700   xquery_fns_def_dot.set(FunctionConsts::FN_STRING_0);
701   xquery_fns_def_dot.set(FunctionConsts::FN_GENERATE_ID_0);
702   xquery_fns_def_dot.set(FunctionConsts::FN_DATA_0);
703   xquery_fns_def_dot.set(FunctionConsts::FN_DOCUMENT_URI_0);
704   xquery_fns_def_dot.set(FunctionConsts::FN_NODE_NAME_0);
705   xquery_fns_def_dot.set(FunctionConsts::FN_NILLED_0);
706   xquery_fns_def_dot.set(FunctionConsts::FN_HAS_CHILDREN_0);
707   xquery_fns_def_dot.set(FunctionConsts::FN_PATH_0);
708 
709 
710   op_concatenate = GET_BUILTIN_FUNCTION(OP_CONCATENATE_N);
711   assert(op_concatenate != NULL);
712 
713   if (rootTranslator == NULL)
714   {
715     QueryLoc loc;
716     theDotVarName = new QName(loc, static_context::DOT_VAR_NAME);
717     theDotPosVarName = new QName(loc, static_context::DOT_POS_VAR_NAME);
718     theLastIdxVarName = new QName(loc, static_context::DOT_SIZE_VAR_NAME);
719 
720     theRootTranslator = this;
721   }
722 }
723 
724 
~TranslatorImpl()725 ~TranslatorImpl()
726 {
727 #ifndef ZORBA_NO_FULL_TEXT
728   while (!theFTNodeStack.empty())
729     delete ztd::pop_stack(theFTNodeStack);
730 #endif
731 }
732 
733 
getDotVarName() const734 const QName* getDotVarName() const
735 {
736   return theRootTranslator->theDotVarName;
737 }
738 
739 
getDotPosVarName() const740 const QName* getDotPosVarName() const
741 {
742   return theRootTranslator->theDotPosVarName;
743 }
744 
getLastIdxVarName() const745 const QName* getLastIdxVarName() const
746 {
747   return theRootTranslator->theLastIdxVarName;
748 }
749 
750 
751 
752 /*******************************************************************************
753   Pop the top n exprs from theNodeStack and return the last expr that was popped.
754 ********************************************************************************/
pop_nodestack(int n=1)755 expr* pop_nodestack(int n = 1)
756 {
757   ZORBA_ASSERT(n >= 0);
758 
759   expr* e_h;
760 
761   for (; n > 0; --n)
762   {
763     ZORBA_FATAL(! theNodeStack.empty(), "");
764     e_h = theNodeStack.top();
765     theNodeStack.pop();
766 
767 #ifndef NDEBUG
768     if (Properties::instance()->traceTranslator())
769     {
770       std::cout << "Popped from nodestack:\n";
771       if (e_h != NULL)
772         e_h->put(std::cout) << std::endl;
773       else
774         std::cout << "NULL" << std::endl;
775     }
776 #endif
777   }
778   return e_h;
779 }
780 
781 
782 /*******************************************************************************
783   Push the given expr into theNodeStack.
784 ********************************************************************************/
push_nodestack(expr * e)785 inline void push_nodestack(expr* e)
786 {
787   theNodeStack.push(e);
788 
789 #ifndef NDEBUG
790   if (Properties::instance()->traceTranslator())
791   {
792     std::cout << "Pushed to nodestack: \n";
793     if (e != NULL)
794       e->put(std::cout) << std::endl;
795     else
796       std::cout << "NULL" << std::endl;
797   }
798 #endif
799 }
800 
801 
802 /*******************************************************************************
803   Assert that the top expr in theNodeStack is a var_expr and pop it.
804 ********************************************************************************/
pop_nodestack_var()805 var_expr* pop_nodestack_var()
806 {
807   expr* e = pop_nodestack();
808   assert (e == NULL || e->get_expr_kind() == var_expr_kind);
809   return static_cast<var_expr *>(e);
810 }
811 
812 
813 /*******************************************************************************
814   Return rchandle to the expr at the top of theNodeStack, or NULL if theNodeStack
815   is empty.
816 ********************************************************************************/
peek_nodestk_or_null()817 expr* peek_nodestk_or_null()
818 {
819   return (theNodeStack.empty()) ? NULL : theNodeStack.top();
820 }
821 
822 
823 /*******************************************************************************
824   Return rchandle to the expr at the top of theNodeStack (crash if theNodeStack
825   is empty).
826 ********************************************************************************/
top_nodestack()827 expr* top_nodestack()
828 {
829   ZORBA_FATAL( !theNodeStack.empty(), "" );
830   return theNodeStack.top();
831 }
832 
833 
834 /*******************************************************************************
835   Check if the top expr in theNodeStack is an axis_step, and if so return
836   rchandle to it (but do not pop). Otherwise, raise error.
837 ********************************************************************************/
expect_axis_step_top()838 axis_step_expr* expect_axis_step_top()
839 {
840   axis_step_expr* axisExpr =
841     dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
842 
843   if (axisExpr == NULL)
844   {
845     std::cout << "Expecting axis step on top of stack; ";
846     if (theNodeStack.top() != NULL)
847       std::cout << "typeid(top()) = " << typeid(*theNodeStack.top()).name() << std::endl;
848     else
849       std::cout << "top is null\n";
850     ZORBA_ASSERT (false);
851   }
852   return axisExpr;
853 }
854 
855 
856 /*******************************************************************************
857 
858 ********************************************************************************/
pop_tstack()859 xqtref_t pop_tstack()
860 {
861   return translator_ns::pop_stack(theTypeStack);
862 }
863 
864 
865 #ifndef ZORBA_NO_FULL_TEXT
866 /*****************************************************************************
867   Pop the top count ftnodes from theFTNodeStack and return the last expr that
868   was popped.
869 ******************************************************************************/
pop_ftstack(int count=1)870 ftnode* pop_ftstack(int count = 1)
871 {
872   ZORBA_ASSERT(count >= 0);
873 
874   ftnode *n = nullptr;
875   while ( count-- > 0 )
876   {
877     ZORBA_FATAL( !theFTNodeStack.empty(), "" );
878     n = theFTNodeStack.top();
879     theFTNodeStack.pop();
880 
881 #ifndef NDEBUG
882     if ( Properties::instance()->traceTranslator() )
883     {
884       std::cout << "Popped from ftnode stack:\n";
885       if ( n )
886         std::cout << *n << std::endl;
887       else
888         std::cout << "NULL" << std::endl;
889     }
890 #endif
891   }
892   return n;
893 }
894 
895 
896 /******************************************************************************
897   Push the given expr into theFTNodeStack.
898  ******************************************************************************/
push_ftstack(ftnode * n)899 inline void push_ftstack( ftnode *n )
900 {
901   theFTNodeStack.push( n );
902 }
903 
904 
top_ftstack()905 inline ftnode* top_ftstack()
906 {
907   ZORBA_FATAL( !theFTNodeStack.empty(), "" );
908   return theFTNodeStack.top();
909 }
910 #endif /* ZORBA_NO_FULL_TEXT */
911 
912 
913 /******************************************************************************
914 
915 *******************************************************************************/
inLibraryModule()916 inline bool inLibraryModule()
917 {
918   return export_sctx != NULL;
919 }
920 
921 
922 /******************************************************************************
923 
924 *******************************************************************************/
inUDFBody()925 inline bool inUDFBody()
926 {
927   return (!theCurrentPrologVFDecl.isNull() && theCurrentPrologVFDecl.isUDF());
928 }
929 
930 
931 /******************************************************************************
932 
933 *******************************************************************************/
sctxid()934 inline csize sctxid()
935 {
936   return theCurrSctxId;
937 }
938 
939 
940 /*******************************************************************************
941   Create new static context, make it the current one for the current module, and
942   register it into the query-level sctx map.
943 ********************************************************************************/
push_scope()944 void push_scope()
945 {
946   // create a new static context for the new scope
947   theSctx = theSctx->create_child_context();
948 
949 #ifdef ZORBA_WITH_DEBUGGER
950   if (theCCB->theDebuggerCommons != NULL)
951   {
952     // in debug mode, we remember all static contexts
953     // this allows the debugger to introspect (during runtime)
954     // all variables in scope
955     theSctxIdStack.push(sctxid());
956     theCurrSctxId = theCCB->theSctxMap.size() + 1;
957     (theCCB->theSctxMap)[sctxid()] = theSctx;
958   }
959   else
960   {
961 #endif
962     // in non-debug mode, we need to make sure that the scoped
963     // contexts are kept around for the compilation of this module.
964     // The static context available at runtime will be the root context
965     // in which the module is compiled. Keeping all contexts around during
966     // runtime seems to be overhead.
967     theSctxList.push_back(theSctx);
968 #ifdef ZORBA_WITH_DEBUGGER
969   }
970 #endif
971 
972   ++theScopeDepth;
973 }
974 
975 
976 /*******************************************************************************
977   Make the parent of the current sctx be the current sctx for the current module.
978 ********************************************************************************/
pop_scope()979 void pop_scope()
980 {
981 #ifdef ZORBA_WITH_DEBUGGER
982   if (theCCB->theDebuggerCommons != NULL)
983   {
984     theCurrSctxId = theSctxIdStack.top();
985     theSctx = (theCCB->theSctxMap)[sctxid()];
986     theSctxIdStack.pop();
987   }
988   else
989   {
990 #endif
991     static_context* parent = (static_context *) theSctx->get_parent();
992     theSctx = parent;
993     theSctxList.pop_back();
994 #ifdef ZORBA_WITH_DEBUGGER
995   }
996 #endif
997 
998   --theScopeDepth;
999 }
1000 
1001 
1002 /*******************************************************************************
1003 
1004 ********************************************************************************/
push_elem_scope()1005 void push_elem_scope()
1006 {
1007   theNSCtx = new namespace_context(&*theNSCtx);
1008 }
1009 
1010 
1011 /*******************************************************************************
1012 
1013 ********************************************************************************/
pop_elem_scope()1014 void pop_elem_scope()
1015 {
1016   theNSCtx = theNSCtx->get_parent();
1017 }
1018 
1019 
1020 /*******************************************************************************
1021   Convert a lexical qname identifying a function to an expanded qname item.
1022   If the lexical qname does not have a prefix, the default function namespace
1023   (if any) will be used to build the expanded qname item.
1024 ********************************************************************************/
expand_function_qname(store::Item_t & qnameItem,const QName * qname,const QueryLoc & loc) const1025 void expand_function_qname(
1026     store::Item_t& qnameItem,
1027     const QName* qname,
1028     const QueryLoc& loc) const
1029 {
1030   theSctx->expand_qname(qnameItem,
1031                         (qname->is_eqname() ?
1032                          qname->get_namespace() :
1033                          theSctx->default_function_ns()),
1034                         qname->get_prefix(),
1035                         qname->get_localname(),
1036                         loc);
1037 }
1038 
1039 
1040 /*******************************************************************************
1041   Convert a lexical qname representing an element tag name or a type name to an
1042   expanded qname item. If the lexical qname does not have a prefix, the default
1043   element namespace (if any) will be used to build the expanded qname item.
1044 ********************************************************************************/
expand_elem_qname(store::Item_t & qnameItem,const QName * qname,const QueryLoc & loc) const1045 void expand_elem_qname(
1046     store::Item_t& qnameItem,
1047     const QName* qname,
1048     const QueryLoc& loc) const
1049 {
1050   theSctx->expand_qname(qnameItem,
1051                         (qname->is_eqname() ?
1052                          qname->get_namespace() :
1053                          theSctx->default_elem_type_ns()),
1054                         qname->get_prefix(),
1055                         qname->get_localname(),
1056                         loc);
1057 }
1058 
1059 
1060 /*******************************************************************************
1061 
1062 ********************************************************************************/
expand_no_default_qname(store::Item_t & qnameItem,const QName * qname,const QueryLoc & loc) const1063 void expand_no_default_qname(
1064     store::Item_t& qnameItem,
1065     const QName* qname,
1066     const QueryLoc& loc) const
1067 {
1068   theSctx->expand_qname(qnameItem,
1069                         qname->get_namespace(),
1070                         qname->get_prefix(),
1071                         qname->get_localname(),
1072                         loc);
1073 }
1074 
1075 
1076 /*******************************************************************************
1077   Create a var_expr for a variable with a given qname item, kind, and type
1078 ********************************************************************************/
create_var(const QueryLoc & loc,store::Item * qname,var_expr::var_kind kind,xqtref_t type=NULL)1079 var_expr* create_var(
1080     const QueryLoc& loc,
1081     store::Item* qname,
1082     var_expr::var_kind kind,
1083     xqtref_t type = NULL)
1084 {
1085   var_expr* e = theExprManager->create_var_expr(theRootSctx, loc, kind, qname);
1086 
1087   if (kind == var_expr::pos_var ||
1088       kind == var_expr::count_var ||
1089       kind == var_expr::wincond_out_pos_var ||
1090       kind == var_expr::wincond_in_pos_var)
1091   {
1092     type = GENV_TYPESYSTEM.POSITIVE_INTEGER_TYPE_ONE;
1093   }
1094 
1095   e->set_type(type);
1096   return e;
1097 }
1098 
1099 
1100 /*******************************************************************************
1101   Create a var_expr for a variable with a given qname, kind, and type. The
1102   given qname is expanded to a qname item. An error is raised if the qname
1103   expansion fails (because there is no namespace binding for the given prefix).
1104 ********************************************************************************/
create_var(const QueryLoc & loc,const QName * qname,var_expr::var_kind kind,xqtref_t type=NULL)1105 var_expr* create_var(
1106     const QueryLoc& loc,
1107     const QName* qname,
1108     var_expr::var_kind kind,
1109     xqtref_t type = NULL)
1110 {
1111   store::Item_t qnameItem;
1112   expand_no_default_qname(qnameItem, qname, loc);
1113   return create_var(loc, qnameItem, kind, type);
1114 }
1115 
1116 
1117 /*******************************************************************************
1118   Create a var_expr for an internal variable with a given kind. The name to be
1119   used for the internally generated variable is unique within this translator.
1120 ********************************************************************************/
create_temp_var(const QueryLoc & loc,var_expr::var_kind kind)1121 var_expr* create_temp_var(const QueryLoc& loc, var_expr::var_kind kind)
1122 {
1123   std::string localName = "$$temp" + ztd::to_string(theTempVarCounter++);
1124 
1125   store::Item_t qnameItem;
1126   GENV_ITEMFACTORY->createQName(qnameItem, "", "", localName.c_str());
1127 
1128   return create_var(loc, qnameItem, kind);
1129 }
1130 
1131 
1132 /*******************************************************************************
1133   Create a binding in the given sctx between a var qname item and a var_expr.
1134   Raise error if a var with the same expanded qname is already in the given
1135   sctx obj.
1136 ********************************************************************************/
bind_var(var_expr * e,static_context * sctx)1137 void bind_var(var_expr* e, static_context* sctx)
1138 {
1139   assert(sctx != NULL);
1140 
1141   switch (e->get_kind())
1142   {
1143   case var_expr::let_var:
1144   {
1145     sctx->bind_var(e, e->get_loc(), err::XQST0039);
1146     break;
1147   }
1148   case var_expr::win_var:
1149   case var_expr::wincond_out_var:
1150   case var_expr::wincond_out_pos_var:
1151   case var_expr::wincond_in_var:
1152   case var_expr::wincond_in_pos_var:
1153   {
1154     sctx->bind_var(e, e->get_loc(), err::XQST0103);
1155     break;
1156   }
1157   default:
1158   {
1159     sctx->bind_var(e, e->get_loc(), err::XQST0049);
1160   }
1161   }
1162 }
1163 
1164 
1165 /*******************************************************************************
1166   Create a var_expr for a variable with a given qname item, kind, and type.
1167   Then, create a binding in the given sctx between the var qname item and the
1168   var_expr. Raise error if a var with the same expanded qname item is already
1169   in the given sctx obj.
1170 ********************************************************************************/
bind_var(const QueryLoc & loc,store::Item * qname,var_expr::var_kind kind,xqtref_t type=NULL)1171 var_expr* bind_var(
1172     const QueryLoc& loc,
1173     store::Item* qname,
1174     var_expr::var_kind kind,
1175     xqtref_t type = NULL)
1176 {
1177   var_expr* e = create_var(loc, qname, kind, type);
1178   bind_var(e, theSctx);
1179   return e;
1180 }
1181 
1182 
1183 /*******************************************************************************
1184   Create a var_expr for a variable with a given qname, kind, and type. Then,
1185   create a binding in the given sctx between the var qname item and the var_expr.
1186   Raise error if a var with the same expanded qname item is already in the
1187   given sctx obj or if the expansion of the given qname to a qname item fails.
1188 ********************************************************************************/
bind_var(const QueryLoc & loc,const QName * qname,var_expr::var_kind kind,xqtref_t type=NULL)1189 var_expr* bind_var(
1190     const QueryLoc& loc,
1191     const QName* qname,
1192     var_expr::var_kind kind,
1193     xqtref_t type = NULL)
1194 {
1195   var_expr* e = create_var(loc, qname, kind, type);
1196   bind_var(e, theSctx);
1197   return e;
1198 }
1199 
1200 
1201 /*******************************************************************************
1202   Lookup a context variable, i.e., the var (if any) representing the context
1203   item, or the context position, or the context size. The variable is identified
1204   by its lexical qname (DOT_VARNAME, or DOT_POS_VARNAME, or LAST_IDX_VARNAME).
1205 
1206   Search starts from the "current" sctx and moves upwards the ancestor path
1207   until the first instance (if any) of the variable is found.
1208 
1209   If var is not found, the method raises appropriate error.
1210 ********************************************************************************/
lookup_ctx_var(const QName * qname,const QueryLoc & loc)1211 var_expr* lookup_ctx_var(const QName* qname, const QueryLoc& loc)
1212 {
1213   if (theIsInIndexDomain)
1214   {
1215     try
1216     {
1217       return lookup_var(qname, loc, err::XPDY0002);
1218     }
1219     catch (ZorbaException const& e)
1220     {
1221       if (e.diagnostic() == err::XPDY0002)
1222       {
1223         RAISE_ERROR(zerr::ZDST0032_INDEX_REFERENCES_CTX_ITEM, loc,
1224         ERROR_PARAMS(theIndexDecl->getName()->getStringValue()));
1225       }
1226       throw;
1227     }
1228   }
1229   else
1230   {
1231     return lookup_var(qname, loc, err::XPDY0002);
1232   }
1233 }
1234 
1235 
1236 /*******************************************************************************
1237   Lookup variable by lexical qname. Search starts from the "current" ctx and
1238   moves upwards the ancestor path until the first instance (if any) of the var
1239   is found.
1240 
1241   If the lexical qname has a prefix for which no namespace binding exists, the
1242   method raises error.
1243 
1244   If var is not found, the method raises the given error, unless the given error
1245   is zerr::ZXQP0000_NO_ERROR, in which case it returns NULL.
1246 ********************************************************************************/
lookup_var(const QName * qname,const QueryLoc & loc,const Error & err)1247 var_expr* lookup_var(const QName* qname, const QueryLoc& loc, const Error& err)
1248 {
1249   store::Item_t qnameItem;
1250   expand_no_default_qname(qnameItem, qname, loc);
1251 
1252   VarInfo* var = theSctx->lookup_var(qnameItem.getp());
1253 
1254   if (!var)
1255   {
1256     if (err != zerr::ZXQP0000_NO_ERROR)
1257     {
1258       zstring varName = static_context::var_name(qnameItem);
1259       throw XQUERY_EXCEPTION_VAR(err,
1260       ERROR_PARAMS(varName, ZED(VariabledUndeclared)),
1261       ERROR_LOC(loc));
1262     }
1263 
1264     return NULL;
1265   }
1266 
1267   return var->getVar();
1268 }
1269 
1270 
1271 /*******************************************************************************
1272   Lookup variable by expanded qname. Search starts from the "current" sctx and
1273   moves upwards the ancestor path until the first instance (if any) of the var
1274   is found.
1275 
1276   If var is not found, the method raises the given error, unless the given error
1277   is MAX_ZORBA_ERROR_CODE, in which case it returns NULL.
1278 ********************************************************************************/
lookup_var(const store::Item * qname,const QueryLoc & loc,const Error & err)1279 var_expr* lookup_var(const store::Item* qname, const QueryLoc& loc, const Error& err)
1280 {
1281   VarInfo* var = theSctx->lookup_var(qname);
1282 
1283   if (!var)
1284   {
1285     if (err != zerr::ZXQP0000_NO_ERROR)
1286     {
1287       zstring varName = static_context::var_name(qname);
1288       throw XQUERY_EXCEPTION_VAR(err,
1289       ERROR_PARAMS(varName, ZED(VariabledUndeclared)),
1290       ERROR_LOC(loc));
1291     }
1292 
1293     return NULL;
1294   }
1295 
1296   return var->getVar();
1297 }
1298 
1299 
1300 
1301 /*******************************************************************************
1302   Create a binding between the given (function qname item, arity) pair and the
1303   given function object. The binding is created in (a) the current sctx of this
1304   module, (b) the query-level sctx that gathers all declaration of functions and
1305   variables from all modules, and (c) the export_sctx (if any). Raise error if
1306   such a binding exists already in any of these sctxs.
1307 ********************************************************************************/
bind_fn(function_t & f,ulong nargs,const QueryLoc & loc)1308 void bind_fn(
1309     function_t& f,
1310     ulong nargs,
1311     const QueryLoc& loc)
1312 {
1313   theSctx->bind_fn(f, nargs, loc);
1314 
1315   theModulesInfo->globalSctx->bind_fn(f, nargs, loc);
1316 
1317   if (export_sctx != NULL)
1318   {
1319     export_sctx->bind_fn(f, nargs, loc);
1320   }
1321 }
1322 
1323 
1324 /*******************************************************************************
1325   Lookup in the sctx the function object for a function with a given prefix
1326   local name and arity. Return NULL if such a function is not found
1327 ********************************************************************************/
lookup_fn(const QName * qname,ulong arity,const QueryLoc & loc)1328 function* lookup_fn(const QName* qname, ulong arity, const QueryLoc& loc)
1329 {
1330   store::Item_t qnameItem;
1331   expand_function_qname(qnameItem, qname, loc);
1332 
1333   return theSctx->lookup_fn(qnameItem, arity);
1334 }
1335 
1336 
1337 /*******************************************************************************
1338   Create an fn:concatenate() expr
1339 ********************************************************************************/
create_empty_seq(const QueryLoc & loc)1340 fo_expr* create_empty_seq(const QueryLoc& loc)
1341 {
1342   return theExprManager->create_seq(theRootSctx, loc);
1343 }
1344 
1345 
1346 /*******************************************************************************
1347 
1348 ********************************************************************************/
normalize_fo(fo_expr * foExpr)1349 void normalize_fo(fo_expr* foExpr)
1350 {
1351   const QueryLoc& loc = foExpr->get_loc();
1352 
1353   TypeManager* tm = foExpr->get_type_manager();
1354 
1355   const signature& sign = foExpr->get_signature();
1356 
1357   csize n = foExpr->num_args();
1358 
1359   const function* func = foExpr->get_func();
1360 
1361   if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ||
1362       func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
1363   {
1364     csize nStarterParams =
1365       (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N
1366        ? 1 : 2);
1367 
1368     if  (n < (6 + nStarterParams) || (n - nStarterParams) % 6 != 0)
1369     {
1370       const store::Item* qname = NULL;
1371 
1372       if (n > 0)
1373         qname = foExpr->get_arg(0)->getQName(theSctx);
1374 
1375       zstring lMsgPart;
1376       ztd::to_string(nStarterParams, &lMsgPart);
1377       lMsgPart += " + multiple of 6";
1378       if (qname != NULL)
1379       {
1380         RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
1381         ERROR_PARAMS(qname->getStringValue(), "index", n, lMsgPart));
1382       }
1383       else
1384       {
1385         RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
1386         ERROR_PARAMS("anonymous", "index", n, lMsgPart));
1387       }
1388     }
1389   }
1390 
1391   for (csize i = 0; i < n; ++i)
1392   {
1393     expr* argExpr = foExpr->get_arg(i);
1394 
1395     xqtref_t paramType;
1396 
1397     if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N)
1398     {
1399       if (i == 0)
1400         paramType = sign[i];
1401       else
1402         paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
1403     }
1404     else if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_SKIP_N)
1405     {
1406       if (i <= 1)
1407         paramType = sign[i];
1408       else
1409         paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
1410     }
1411     else if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N)
1412     {
1413       if (i == 0)
1414         paramType = sign[i];
1415       else if (i % 6 == 1 || i % 6 == 2)
1416         paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
1417       else
1418         paramType = theRTM.BOOLEAN_TYPE_ONE;
1419     }
1420     else if (func->getKind() == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
1421     {
1422       if (i <= 1)
1423         paramType = sign[i];
1424       else if (i % 6 == 2 || i % 6 == 3)
1425         paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
1426       else
1427         paramType = theRTM.BOOLEAN_TYPE_ONE;
1428     }
1429     else if (func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_N ||
1430              func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_N_N ||
1431              func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_U_N ||
1432              func->getKind() == FunctionConsts::FN_ZORBA_INVOKE_S_N)
1433     {
1434       if (i == 0)
1435         paramType = sign[i];
1436       else
1437         paramType = NULL; // Nothing to check as the target function is not known
1438     }
1439     else
1440     {
1441       paramType = sign[i];
1442     }
1443 
1444     // A NULL value for the parameter's type to signal that no type promotion
1445     // or match should be added. This is used by the reflection:invoke() function,
1446     if (paramType != NULL)
1447     {
1448       if (TypeOps::is_subtype(tm,
1449                               *paramType,
1450                               *theRTM.ANY_ATOMIC_TYPE_STAR,
1451                               loc))
1452       {
1453         argExpr = wrap_in_type_promotion(argExpr,
1454                                          paramType,
1455                                          PromoteIterator::FUNC_PARAM,
1456                                          func->getName());
1457       }
1458       else
1459       {
1460         argExpr = wrap_in_type_match(argExpr,
1461                                      paramType,
1462                                      loc,
1463                                      TreatIterator::FUNC_PARAM,
1464                                      func->getName());
1465       }
1466     }
1467 
1468     foExpr->set_arg(i, argExpr);
1469   }
1470 }
1471 
1472 
1473 /*******************************************************************************
1474   Wrap the given expr in an fn:data() function
1475 ********************************************************************************/
wrap_in_atomization(expr * e)1476 expr* wrap_in_atomization(expr* e)
1477 {
1478   return theExprManager->create_fo_expr(theRootSctx,
1479                                         e->get_loc(),
1480                                         GET_BUILTIN_FUNCTION(FN_DATA_1),
1481                                         e);
1482 }
1483 
1484 
1485 /*******************************************************************************
1486 
1487 ********************************************************************************/
wrap_in_type_promotion(expr * e,const xqtref_t & type,PromoteIterator::ErrorKind errorKind,store::Item * qname=NULL)1488 expr* wrap_in_type_promotion(
1489     expr* e,
1490     const xqtref_t& type,
1491     PromoteIterator::ErrorKind errorKind,
1492     store::Item* qname = NULL)
1493 {
1494   e = wrap_in_atomization(e);
1495 
1496   return theExprManager->create_promote_expr(theRootSctx,
1497                                              e->get_loc(),
1498                                              e,
1499                                              type,
1500                                              errorKind,
1501                                              qname);
1502 }
1503 
1504 
1505 /*******************************************************************************
1506 
1507 ********************************************************************************/
wrap_in_type_match(expr * e,const xqtref_t & type,const QueryLoc & loc,TreatIterator::ErrorKind errorKind,store::Item_t qname=NULL)1508 expr* wrap_in_type_match(
1509     expr* e,
1510     const xqtref_t& type,
1511     const QueryLoc& loc,
1512     TreatIterator::ErrorKind errorKind,
1513     store::Item_t qname = NULL)
1514 {
1515   TypeManager* tm = e->get_type_manager();
1516 
1517   // treat_expr should be avoided for updating expressions, but in that case
1518   // "type" will be item()* anyway
1519   if (TypeOps::is_subtype(tm, *theRTM.ITEM_TYPE_STAR, *type, loc))
1520   {
1521     return e;
1522   }
1523   else
1524   {
1525     return theExprManager->create_treat_expr(theRootSctx,
1526                                              e->get_loc(),
1527                                              e,
1528                                              type,
1529                                              errorKind,
1530                                              true,
1531                                              qname);
1532 }
1533 }
1534 
1535 
1536 /*******************************************************************************
1537 
1538 ********************************************************************************/
wrap_in_enclosed_expr(expr * contentExpr,const QueryLoc & loc)1539 fo_expr* wrap_in_enclosed_expr(expr* contentExpr, const QueryLoc& loc)
1540 {
1541   return theExprManager->create_fo_expr(theRootSctx,
1542                                         loc,
1543                                         GET_BUILTIN_FUNCTION(OP_ENCLOSED_1),
1544                                         contentExpr);
1545 }
1546 
1547 
1548 /*******************************************************************************
1549 
1550 ********************************************************************************/
wrap_in_bev(expr * e)1551 expr* wrap_in_bev(expr * e)
1552 {
1553   fo_expr* fo = theExprManager->create_fo_expr(theRootSctx,
1554                                                e->get_loc(),
1555                                                GET_BUILTIN_FUNCTION(FN_BOOLEAN_1),
1556                                                e);
1557   return fo;
1558 }
1559 
1560 
1561 /*******************************************************************************
1562   Wrap the given expr in one of the following functions:
1563   fn:sort-distinct-nodes-asc-or-atomics, or
1564   fn:sort-distinct-nodes-desc-or-atomics, or
1565   fn:sort-distinct-nodes-asc, or
1566   fn:sort-distinct-nodes-desc
1567 ********************************************************************************/
wrap_in_dos_and_dupelim(expr * expr,bool atomics,bool reverse=false)1568 expr* wrap_in_dos_and_dupelim(expr* expr, bool atomics, bool reverse = false)
1569 {
1570   FunctionConsts::FunctionKind fkind;
1571 
1572   if (reverse && atomics)
1573   {
1574     fkind = FunctionConsts::OP_SORT_DISTINCT_NODES_DESC_OR_ATOMICS_1;
1575   }
1576   else if (reverse)
1577   {
1578     fkind = FunctionConsts::OP_SORT_DISTINCT_NODES_DESC_1;
1579   }
1580   else if (atomics)
1581   {
1582     fkind = FunctionConsts::OP_SORT_DISTINCT_NODES_ASC_OR_ATOMICS_1;
1583   }
1584   else
1585   {
1586     fkind = FunctionConsts::OP_SORT_DISTINCT_NODES_ASC_1;
1587   }
1588 
1589   fo_expr* dos = theExprManager->create_fo_expr(theRootSctx,
1590                                       expr->get_loc(),
1591                                       BuiltinFunctionLibrary::getFunction(fkind),
1592                                       expr);
1593   normalize_fo(dos);
1594 
1595   return &*dos;
1596 }
1597 
1598 
1599 /*******************************************************************************
1600   Create a LET clause for the given LET variable "lv", with the given expr "e" as
1601   its defining expression.
1602 ********************************************************************************/
wrap_in_letclause(expr * e,var_expr * lv)1603 let_clause* wrap_in_letclause(expr* e, var_expr* lv)
1604 {
1605   assert (lv->get_kind () == var_expr::let_var);
1606 
1607   return theExprManager->create_let_clause(theRootSctx,
1608                                            e->get_loc(),
1609                                            lv,
1610                                            e);
1611 }
1612 
1613 
1614 /*******************************************************************************
1615   Create a var_expr for a LET var with the given qname and add that var to the
1616   local sctx obj. Then, create a LET clause for this new var_expr, with the given
1617   expr "e" as its defining expression.
1618 ********************************************************************************/
wrap_in_letclause(expr * e,const QueryLoc & loc,const QName * qname)1619 let_clause* wrap_in_letclause(
1620     expr* e,
1621     const QueryLoc& loc,
1622     const QName* qname)
1623 {
1624   return wrap_in_letclause(e, bind_var(loc, qname, var_expr::let_var));
1625 }
1626 
1627 
1628 /*******************************************************************************
1629   Create a var_expr for a new internal LET var and then create a LET clause for
1630   this new var_expr, with the given expr "e" as its defining expression. NOTE:
1631   the internal var is not registered in the sctx.
1632 ********************************************************************************/
wrap_in_letclause(expr * e)1633 let_clause* wrap_in_letclause(expr* e)
1634 {
1635   return wrap_in_letclause(e, create_temp_var(e->get_loc(), var_expr::let_var));
1636 }
1637 
1638 
1639 /*******************************************************************************
1640   Create a FOR clause for the given FOR variable "fv" and its associated POS var
1641   "pv" (pv may be NULL). Use the given expr "e" as the defining expr for "fv".
1642 ********************************************************************************/
wrap_in_forclause(expr * e,var_expr * fv,var_expr * pv)1643 for_clause* wrap_in_forclause(expr* e, var_expr* fv, var_expr* pv)
1644 {
1645   assert(fv->get_kind () == var_expr::for_var);
1646   if (pv != NULL)
1647   {
1648     assert(pv->get_kind() == var_expr::pos_var);
1649   }
1650 
1651   return theExprManager->create_for_clause(theRootSctx,
1652                                            e->get_loc(),
1653                                            fv,
1654                                            e,
1655                                            pv);
1656 }
1657 
1658 
1659 /*******************************************************************************
1660   Create var_exprs for a FOR var with the given qname and its associated POS
1661   var, whose qname is also given. Then add those vars to the local sctx obj.
1662   Then, create a FOR clause for these new var_exprs, with the given expr as the
1663   defining expression of the FOR var.
1664 ********************************************************************************/
wrap_in_forclause(expr * expr,const QueryLoc & loc,const QName * fv_qname,const QName * pv_qname)1665 for_clause* wrap_in_forclause(
1666     expr* expr,
1667     const QueryLoc& loc,
1668     const QName* fv_qname,
1669     const QName* pv_qname)
1670 {
1671   return wrap_in_forclause(expr,
1672                            bind_var(loc, fv_qname, var_expr::for_var),
1673                            bind_var(loc, pv_qname, var_expr::pos_var));
1674 }
1675 
1676 
1677 /*******************************************************************************
1678   Create a var_expr for a new internal FOR var and then create a FOR clause for
1679   this new var_expr, with the given expr as its defining expression. NOTE:
1680   the internal var is not registered in the sctx.
1681 ********************************************************************************/
wrap_in_forclause(expr * expr,bool add_posvar)1682 for_clause* wrap_in_forclause(expr* expr, bool add_posvar)
1683 {
1684   var_expr* fv = create_temp_var(expr->get_loc(), var_expr::for_var);
1685 
1686   var_expr* pv = (add_posvar ?
1687                    create_temp_var(expr->get_loc(), var_expr::pos_var) :
1688                    NULL);
1689 
1690   return wrap_in_forclause(expr, fv, pv);
1691 }
1692 
1693 
1694 /*******************************************************************************
1695   Create a flwor expr with a single let clause and a return expr. In particular,
1696   the following flwor expr is built:
1697 
1698   let $lv := domExpr
1699   return retExpr
1700 
1701 ********************************************************************************/
wrap_in_let_flwor(expr * domExpr,var_expr * lv,expr * retExpr)1702 flwor_expr* wrap_in_let_flwor(
1703     expr* domExpr,
1704     var_expr* lv,
1705     expr* retExpr)
1706 {
1707   flwor_expr* fe = theExprManager->create_flwor_expr(theRootSctx,
1708                                                      lv->get_loc(),
1709                                                      false);
1710 
1711   fe->add_clause(wrap_in_letclause(domExpr, lv));
1712 
1713   fe->set_return_expr(retExpr);
1714 
1715   return fe;
1716 }
1717 
1718 
1719 /*******************************************************************************
1720   Create a flwor expr that uses the given expr as its input. In particular, if
1721   withContextSize is true, the following flwor is built:
1722 
1723     let $$temp := inputExpr
1724     let $$last-idx := count($$temp)
1725     for $$dot at $$pos in $$temp
1726     .....
1727 
1728   if withContextSize is false, the following flwor is built:
1729 
1730     for $$dot at $$pos in inputExpr
1731     .....
1732 ********************************************************************************/
wrap_expr_in_flwor(expr * inputExpr,bool withContextSize)1733 flwor_expr* wrap_expr_in_flwor(
1734     expr* inputExpr,
1735     bool withContextSize)
1736 {
1737   const QueryLoc& loc = inputExpr->get_loc();
1738 
1739   push_scope();
1740 
1741   flwor_expr* flworExpr = theExprManager->create_flwor_expr(theRootSctx, loc, false);
1742 
1743   if (withContextSize)
1744   {
1745     // create a LET var equal to the seq returned by the input epxr
1746     let_clause* lcInputSeq = wrap_in_letclause(inputExpr);
1747 
1748     // compute the size of the input seq
1749     fo_expr* countExpr = theExprManager->create_fo_expr(theRootSctx,
1750                                               loc,
1751                                               GET_BUILTIN_FUNCTION(FN_COUNT_1),
1752                                               lcInputSeq->get_var());
1753     normalize_fo(countExpr);
1754 
1755     let_clause* lcLast = wrap_in_letclause(countExpr,
1756                                             loc,
1757                                             LAST_IDX_VARNAME);
1758 
1759     // Iterate over the input seq
1760     for_clause* fcDot = wrap_in_forclause(lcInputSeq->get_var(),
1761                                            loc,
1762                                            DOT_VARNAME,
1763                                            DOT_POS_VARNAME);
1764     flworExpr->add_clause(lcInputSeq);
1765     flworExpr->add_clause(lcLast);
1766     flworExpr->add_clause(fcDot);
1767   }
1768   else
1769   {
1770     // Iterate over the input seq
1771     for_clause* fcDot = wrap_in_forclause(inputExpr,
1772                                            loc,
1773                                            DOT_VARNAME,
1774                                            DOT_POS_VARNAME);
1775     flworExpr->add_clause(fcDot);
1776   }
1777 
1778   return flworExpr;
1779 }
1780 
1781 
expandQueryLoc(const QueryLoc & aLocationFrom,const QueryLoc & aLocationTo)1782 QueryLoc expandQueryLoc(const QueryLoc& aLocationFrom, const QueryLoc& aLocationTo)
1783 {
1784   QueryLoc lExpandedLocation(aLocationFrom);
1785   lExpandedLocation.setColumnEnd(aLocationTo.getColumnEnd());
1786   lExpandedLocation.setLineEnd(aLocationTo.getLineEnd());
1787   return lExpandedLocation;
1788 }
1789 
1790 
1791 /*******************************************************************************
1792   In this expression branch, we create the debugger expressions.
1793   Furthermore, we create an entry for all expressions in the map
1794   of breakable expressions. This is done here, in order to be able,
1795   to set breakpoints of expressions which are not translated at the
1796   beginning (e.g. inside functions).
1797 ********************************************************************************/
wrap_in_debugger_expr(expr * aExpr,const QueryLoc & aLoc,bool aIsMainModuleBreakable=false,bool aIsVarDeclaration=false)1798 void wrap_in_debugger_expr(
1799   expr* aExpr,
1800   const QueryLoc& aLoc,
1801   bool aIsMainModuleBreakable = false,
1802   bool aIsVarDeclaration = false)
1803 {
1804 #ifdef ZORBA_WITH_DEBUGGER
1805   if (theCCB->theDebuggerCommons != NULL)
1806   {
1807     std::auto_ptr<debugger_expr> lExpr(theExprManager->create_debugger_expr(theSctx,
1808                                                          aLoc,
1809                                                          aExpr,
1810                                                          theNSCtx,
1811                                                          aIsVarDeclaration));
1812 
1813     // add the breakable expression in the debugger commons as a possible
1814     // breakpoint location
1815     Breakable lBreakable(aLoc);
1816     theCCB->theDebuggerCommons->addBreakable(lBreakable, aIsMainModuleBreakable);
1817 
1818     // retrieve all variables that are in the current scope
1819     typedef std::vector<VarInfo*> VarExprVector;
1820     VarExprVector lAllInScopeVars;
1821     theSctx->getVariables(lAllInScopeVars);
1822 
1823     // for each var, create a eval_var and add it to
1824     // the debugger expression
1825     for (VarExprVector::iterator lIter = lAllInScopeVars.begin();
1826          lIter != lAllInScopeVars.end();
1827          ++lIter)
1828     {
1829       var_expr* argVar = (*lIter)->getVar();
1830 
1831       store::Item* lVarname = argVar->get_name();
1832 
1833       if (lVarname->getStringValue() == "$$dot")
1834       {
1835         continue;
1836       }
1837 
1838       var_expr* evalVar = create_var(lBreakable.getLocation(),
1839                                       lVarname,
1840                                       var_expr::eval_var,
1841                                       NULL);
1842 
1843       expr* argExpr = theExprManager->create_wrapper_expr(theRootSctx,
1844                                         lBreakable.getLocation(),
1845                                         argVar);
1846       lExpr->add_var(evalVar, argExpr);
1847     }
1848 
1849     aExpr = lExpr.release();
1850   }
1851 #endif
1852 }
1853 
1854 
1855 /*******************************************************************************
1856   Collect the var_exprs for all variables that (a) are defined by some clause
1857   in a given range of clauses, and (b) are in-scope when this method is called.
1858 ********************************************************************************/
collect_flwor_vars(const FLWORExpr & e,std::set<const var_expr * > & vars,const FLWORClause * start,const FLWORClause * end,const QueryLoc & loc)1859 void collect_flwor_vars (
1860     const FLWORExpr& e,
1861     std::set<const var_expr *>& vars,
1862     const FLWORClause* start,
1863     const FLWORClause* end,
1864     const QueryLoc& loc)
1865 {
1866   const FLWORClauseList& clauses = *e.get_clause_list();
1867 
1868   // Find the ordinal number of the "end-1" clause.
1869   int i;
1870   for (i = (int)clauses.size() - 1; i >= 0; --i)
1871   {
1872     if (&*clauses[i] == end)
1873     {
1874       --i;
1875       break;
1876     }
1877   }
1878   assert (i >= 0);
1879 
1880   // Look for variables in reverse order (starting from the last clause).
1881   for (;; i--)
1882   {
1883     const FLWORClause& c = *clauses[i];
1884 
1885     if (typeid(c) == typeid(ForClause))
1886     {
1887       const VarInDeclList& varDecls =
1888       *(static_cast<const ForClause*>(&c)->get_vardecl_list());
1889 
1890       for (int j =  (int)varDecls.size() - 1; j >= 0; --j)
1891       {
1892         VarInDecl* varDecl = varDecls[j];
1893 
1894         vars.insert(lookup_var(varDecl->get_var_name(), loc, err::XPST0008));
1895 
1896         if (varDecl->get_posvar() != NULL)
1897           vars.insert(lookup_var(varDecl->get_posvar()->get_name(), loc, err::XPST0008));
1898       }
1899     }
1900     else if (typeid(c) == typeid(LetClause))
1901     {
1902       const VarGetsDeclList& lV =
1903       *(static_cast<const LetClause*>(&c)->get_vardecl_list());
1904 
1905       for (int j =  (int)lV.size() - 1; j >= 0; --j)
1906       {
1907         vars.insert(lookup_var(lV[j]->get_var_name(), loc, err::XPST0008));
1908       }
1909     }
1910     else if (typeid(c) == typeid(WindowClause))
1911     {
1912       const WindowClause& wc = *static_cast<const WindowClause *>(&c);
1913       vars.insert(lookup_var(wc.get_var()->get_var_name(), loc, err::XPST0008));
1914       for (int j = 1; j >= 0; j--)
1915       {
1916         const FLWORWinCond* cond = &*wc[j];
1917         if (cond != NULL)
1918         {
1919           const WindowVars* wv = &*cond->get_winvars();
1920           if (wv != NULL)
1921           {
1922             if (wv->get_next())
1923               vars.insert(lookup_var(wv->get_next(), loc, err::XPST0008));
1924             if (wv->get_prev())
1925               vars.insert(lookup_var(wv->get_prev(), loc, err::XPST0008));
1926             if (wv->get_curr())
1927               vars.insert(lookup_var(wv->get_curr(), loc, err::XPST0008));
1928             if (wv->get_posvar() != NULL)
1929               vars.insert(lookup_var(wv->get_posvar()->get_name(), loc, err::XPST0008));
1930           }
1931         }
1932       }
1933     }
1934     else if (typeid(c) == typeid(CountClause))
1935     {
1936       vars.insert(lookup_var(static_cast<const CountClause*>(&c)->get_varname(),
1937                              loc,
1938                              err::XPST0008));
1939     }
1940     else if (typeid(c) == typeid(OrderByClause))
1941     {
1942       // Nothing to do; orderby does not define any vars.
1943     }
1944     else if (typeid (c) == typeid (GroupByClause))
1945     {
1946       const GroupByClause groupClause = *static_cast<const GroupByClause*>(&c);
1947 
1948       //Group-by clauses may define new variables, otherwise it shadows existing vars.
1949       for(size_t gSpecPos = 0; gSpecPos < groupClause.get_spec_list()->size(); gSpecPos++)
1950       {
1951         GroupSpec* groupSpec = (*(groupClause.get_spec_list()))[gSpecPos];
1952         if (groupSpec->get_binding_expr() != NULL)
1953           vars.insert(lookup_var(groupSpec->get_var_name(), loc, err::XPST0008));
1954       }
1955 
1956       // Group-by redefines ALL previous variables, but the GroupByClause lists
1957       // only the grouping vars. So, to find the var_exprs for the vars defined
1958       // by the GroupByClause, we exploit the fact that the redefined var_exprs
1959       // "shadow" their corresponding var_exprs, that is, each redefined var_expr
1960       // oX appears in the static context after its corresponding var_expr iX and
1961       // both iX and oX  use the same var name. So, we can collect all the oX
1962       // var_exprs by going through all the clauses that appear before this GB
1963       // and looking up, by name, all the vars defined by those clauses.
1964       collect_flwor_vars(e, vars, &*clauses [0], &c, loc);
1965       break;
1966     }
1967 
1968     if (&c == start)
1969       break;
1970   }
1971 }
1972 
1973 
1974 /*******************************************************************************
1975   Create declaration/initialization exprs for a prolog or block-local variable.
1976 
1977   The following 4 cases are considered:
1978   1. non-extrernal var with init expr,
1979   2. external var with init expr,
1980   3. non-extrernal var without init expr,
1981   4. external var without init expr,
1982 
1983   The corresponding expr created here (and added to stmts) are:
1984 
1985   1. var_decl_expr(varExpr, initExpr)
1986 
1987   2. var_decl_expr(varExpr, initExpr)
1988 
1989      In this case, the var_decl_expr will be a NOOP if a value has been assigned
1990      to the external var via the c++ api. If so, this value overrides the
1991      initializing expr in the prolog.
1992 
1993   3. var_decl_expr(varExpr)
1994 
1995   4. var_decl_expr(varExpr)
1996 
1997      In this case, the variable must be initialized via the c++ api before the
1998      query is executed, and it is this external intialization that will declare
1999      the var, ie, add an entry for the var in the dynamic ctx. Nevertheless, we
2000      need to generate the var_decl_expr because it is when this expr is
2001      encounered during codegen that an id will be assigned to the var (and
2002      stored in the var_expr). This id is needed in order to register the var
2003      in the dyn ctx.
2004 
2005   If the var declaration includes a type declaration, then the following expr
2006   is also created and added to stmts:
2007 
2008   treat(ctxvar-get(varName), type)
2009 
2010 ********************************************************************************/
declare_var(const GlobalBinding & b,std::vector<expr * > & stmts)2011 void declare_var(const GlobalBinding& b, std::vector<expr*>& stmts)
2012 {
2013   function* varGet = GET_BUILTIN_FUNCTION(OP_VAR_GET_1);
2014 
2015   expr* initExpr = b.theExpr;
2016   var_expr* varExpr = b.theVar;
2017 
2018   const QueryLoc& loc = varExpr->get_loc();
2019 
2020   xqtref_t varType = varExpr->get_type();
2021 
2022   if (varType == NULL &&
2023       varExpr->get_name()->getLocalName() == static_context::DOT_VAR_NAME)
2024   {
2025     varType = GENV_TYPESYSTEM.ITEM_TYPE_ONE;
2026   }
2027 
2028   if (initExpr != NULL && varType != NULL && !b.is_extern())
2029   {
2030     initExpr = theExprManager->
2031     create_treat_expr(theRootSctx, loc, initExpr, varType, TreatIterator::TYPE_MATCH);
2032   }
2033 
2034   expr* declExpr = theExprManager->
2035   create_var_decl_expr(theRootSctx, loc, varExpr, initExpr);
2036 
2037   stmts.push_back(declExpr);
2038 
2039   // check type for vars that are external
2040   if (varType != NULL && b.is_extern())
2041   {
2042     expr* getExpr = theExprManager->
2043     create_fo_expr(theRootSctx, loc, varGet, varExpr);
2044 
2045     expr* treatExpr = theExprManager->
2046     create_treat_expr(theRootSctx, loc, getExpr, varType, TreatIterator::TYPE_MATCH);
2047 
2048     stmts.push_back(treatExpr);
2049   }
2050 }
2051 
2052 
2053 /*******************************************************************************
2054   Create declaration/initialization exprs for each prolog variable of this
2055   module and put these exprs in theModulesInfo->theInitExprs. Then create a
2056   sequential expr with its children being all the init exprs in
2057   theModulesInfo->theInitExprs plus the given expr "e" as its last child.
2058 
2059   The method is called at the end of the translation of each module. The returned
2060   expr is the result of the module translation. For the root module, the given
2061   "program" expr is the result of translating the MainModule Program. For non-root
2062   modules, "program" is an empty fn:concatenate() expr.
2063 ********************************************************************************/
wrap_in_globalvar_assign(expr * program)2064 expr* wrap_in_globalvar_assign(expr* program)
2065 {
2066   assert(theAssignedVars.size() == 1);
2067 
2068   for (std::list<GlobalBinding>::iterator i = thePrologVars.begin();
2069        i != thePrologVars.end();
2070        ++i)
2071   {
2072     declare_var(*i, theModulesInfo->theInitExprs);
2073   }
2074 
2075   expr* preloadedInitExpr = static_cast<static_context*>(theSctx->get_parent())->
2076                              get_query_expr();
2077 
2078   if (!theModulesInfo->theInitExprs.empty() || preloadedInitExpr != NULL)
2079   {
2080     std::vector<expr*> args;
2081     args.reserve(2 + theModulesInfo->theInitExprs.size());
2082 
2083     if (preloadedInitExpr)
2084       args.push_back(preloadedInitExpr);
2085 
2086     args.insert(args.end(),
2087                 theModulesInfo->theInitExprs.begin(),
2088                 theModulesInfo->theInitExprs.end());
2089 
2090     if (!inLibraryModule())
2091     {
2092       args.push_back(program);
2093     }
2094 
2095     block_expr* res = theExprManager->create_block_expr(theRootSctx,
2096                                      program->get_loc(),
2097                                      theCCB->theIsEval,
2098                                      args,
2099                                      &theAssignedVars[0]);
2100 
2101     assert(theAssignedVars[0].empty());
2102 
2103     return res;
2104   }
2105   else
2106   {
2107     return program;
2108   }
2109 }
2110 
2111 
2112 /*******************************************************************************
2113   Imports a given schema
2114 ********************************************************************************/
import_schema(const QueryLoc & loc,const SchemaPrefix * prefix,const zstring & targetNS,const URILiteralList * atlist)2115 void* import_schema(
2116     const QueryLoc& loc,
2117     const SchemaPrefix* prefix,
2118     const zstring& targetNS,
2119     const URILiteralList* atlist)
2120 {
2121 #ifndef ZORBA_NO_XMLSCHEMA
2122 
2123   if (! theImportedSchemas.insert(targetNS.str()).second)
2124     throw XQUERY_EXCEPTION(err::XQST0058, ERROR_LOC(loc));
2125 
2126   if (prefix != NULL)
2127   {
2128     if (!prefix->get_default_bit() && targetNS.empty())
2129     {
2130       throw XQUERY_EXCEPTION( err::XQST0057, ERROR_LOC(loc));
2131     }
2132 
2133     zstring pfx = prefix->get_prefix();
2134 
2135     if (pfx == "xml" || pfx == "xmlns")
2136       RAISE_ERROR(err::XQST0070, loc, ERROR_PARAMS(pfx, ZED(NoRebindPrefix)));
2137 
2138     if (prefix->get_default_bit())
2139       theSctx->set_default_elem_type_ns(targetNS, true, loc);
2140 
2141     if (! pfx.empty())
2142       theSctx->bind_ns(pfx, targetNS, loc, err::XQST0033);
2143   }
2144 
2145   zstring xsdTNS = zstring(XML_SCHEMA_NS);
2146   if ( xsdTNS.compare(targetNS)==0 )
2147   {
2148     // Xerces doesn't like importing XMLSchema.xsd schema4schema, so we skip it
2149     // see Xerces-C++ bug: https://issues.apache.org/jira/browse/XERCESC-1980
2150     return no_state;
2151   }
2152 
2153   store::Item_t targetNSItem = NULL;
2154   zstring tmp = targetNS;
2155   ITEM_FACTORY->createAnyURI(targetNSItem, tmp);
2156   ZORBA_ASSERT(targetNSItem != NULL);
2157 
2158   // Form up a vector of candidate URIs: any location hints, followed
2159   // by the imported URI itself.
2160   std::vector<zstring> lCandidates;
2161 
2162   if (atlist != NULL)
2163   {
2164     for (ulong i = 0; i < atlist->size(); ++i)
2165     {
2166       // If current uri is relative, turn it to an absolute one, using the
2167       // base uri from the sctx.
2168       lCandidates.push_back(theSctx->resolve_relative_uri((*atlist)[i]));
2169     }
2170   }
2171 
2172   zstring lNsURI = targetNSItem->getStringValue();
2173   lCandidates.push_back(lNsURI);
2174 
2175   try
2176   {
2177     std::auto_ptr<internal::Resource> lSchema;
2178     internal::StreamResource* lStream = NULL;
2179     zstring lErrorMessage;
2180     for (std::vector<zstring>::iterator lIter = lCandidates.begin();
2181          lIter != lCandidates.end();
2182          ++lIter)
2183     {
2184       lSchema = theSctx->resolve_uri(*lIter, internal::EntityData::SCHEMA,
2185                                      lErrorMessage);
2186       lStream = dynamic_cast<internal::StreamResource*>(lSchema.get());
2187       if (lStream != NULL)
2188       {
2189         break;
2190       }
2191     }
2192 
2193     if ( lStream == NULL ) {
2194       throw XQUERY_EXCEPTION(err::XQST0059, ERROR_PARAMS(lNsURI, lErrorMessage));
2195     }
2196 
2197     // If we got this far, we have a valid StreamResource.
2198 
2199     // Create a Schema obj and register it in the typemanger, if the typemanager
2200     // does not have a schema obj already
2201     TypeManager* tm = theSctx->get_typemanager();
2202     tm->initializeSchema();
2203     Schema* schema_p = tm->getSchema();
2204 
2205     // Make Xerxes load and parse the xsd file and create a Xerces
2206     // representaton of it.
2207     schema_p->registerXSD(lNsURI.c_str(), theSctx, lStream, loc);
2208 
2209   }
2210   catch (XQueryException& e)
2211   {
2212     set_source(e, loc);
2213     throw;
2214   }
2215 
2216   return no_state;
2217 
2218 #else
2219   throw XQUERY_EXCEPTION(err::XQST0009, ERROR_LOC(loc));
2220 #endif
2221 }
2222 
2223 
2224 /*******************************************************************************
2225   Imports a given schema allocating it as prefix the last step in the URI path
2226   suffixed with "_"'s if such a prefix is already bound.
2227 ********************************************************************************/
2228 void*
import_schema_auto_prefix(const QueryLoc & aLoc,const zstring & aTargetNs,const URILiteralList * atlist)2229 import_schema_auto_prefix(
2230   const QueryLoc& aLoc,
2231   const zstring& aTargetNs,
2232   const URILiteralList* atlist)
2233 {
2234 #ifndef ZORBA_NO_XMLSCHEMA
2235 
2236   if (theImportedSchemas.find(aTargetNs.str()) == theImportedSchemas.end())
2237   {
2238     // take as prefix the last segment of the URI
2239     std::size_t lLastSlash = aTargetNs.find_last_of("/");
2240     zstring lPrefixStr;
2241     if (lLastSlash + 1 < aTargetNs.size())
2242     {
2243       lPrefixStr = aTargetNs.substr(lLastSlash + 1);
2244     }
2245     // do not allow a "default" namespace binding
2246     if (lPrefixStr == "")
2247     {
2248       lPrefixStr = "_";
2249     }
2250 
2251     // search for name clashes with already existing prefixes
2252     store::NsBindings lNsBindings;
2253     theSctx->get_namespace_bindings(lNsBindings);
2254     store::NsBindings::iterator lIter = lNsBindings.begin();
2255     store::NsBindings::iterator lEnd = lNsBindings.end();
2256     for (; lIter != lEnd; lIter++)
2257     {
2258       // TODO: can be done more efficient by not starting from the beginning,
2259       // but since the chances are small that more than 1 restart is needed,
2260       // it probably compensates to the performance degradation by allocating
2261       // another vector
2262       if (lIter->first == lPrefixStr) {
2263         lPrefixStr += "_";
2264         lIter = lNsBindings.begin();
2265       }
2266     }
2267 
2268     // now import the schema
2269     SchemaPrefix lPrefix(aLoc, lPrefixStr);
2270     import_schema(aLoc, &lPrefix, aTargetNs, atlist);
2271   }
2272 
2273   return no_state;
2274 
2275 #else
2276   throw XQUERY_EXCEPTION(err::XQST0009, ERROR_LOC(aLoc));
2277 #endif
2278 }
2279 
2280 
2281 /******************************************************************************
2282   Wraps an expression in a validate expression. If the schema URI is a
2283   non-empty string, the corresponding schema is imported. If the location is
2284   QueryLoc::null, the wrapped expression's location will be used.
2285 *******************************************************************************/
wrap_in_validate_expr_strict(expr * aExpr,const zstring & aSchemaURI)2286 expr* wrap_in_validate_expr_strict(
2287     expr* aExpr,
2288     const zstring& aSchemaURI)
2289 {
2290   QueryLoc lLoc = aExpr->get_loc();
2291   import_schema_auto_prefix(lLoc, aSchemaURI.c_str(), NULL);
2292 
2293   store::Item_t qname;
2294   return theExprManager->create_validate_expr(theRootSctx,
2295                            lLoc,
2296                            ParseConstants::val_strict,
2297                            qname,
2298                            aExpr,
2299                            theSctx->get_typemanager());
2300 }
2301 
2302 
2303 /////////////////////////////////////////////////////////////////////////////////
2304 //                                                                             //
2305 //  Module, VersionDecl, MainModule, LibraryModule, ModuleDecl                 //
2306 //                                                                             //
2307 /////////////////////////////////////////////////////////////////////////////////
2308 
2309 
2310 /*******************************************************************************
2311   Module ::= 	VersionDecl? (LibraryModule | MainModule)
2312 ********************************************************************************/
2313 
2314 /******************************************************************************
2315   VersionDecl ::= XQUERY ENCODING STRING_LITERAL SEMI |
2316                   XQUERY VERSION STRING_LITERAL SEMI |
2317                   XQUERY VERSION STRING_LITERAL ENCODING STRING_LITERAL SEMI
2318 ********************************************************************************/
begin_visit(const VersionDecl & v)2319 void* begin_visit(const VersionDecl& v)
2320 {
2321   TRACE_VISIT();
2322 
2323   if (v.get_encoding() != "utf-8" &&
2324       !utf8::match_whole(v.get_encoding(), "^[A-Za-z]([A-Za-z0-9._]|[-])*$"))
2325     RAISE_ERROR(err::XQST0087, loc, ERROR_PARAMS(v.get_encoding()));
2326 
2327   std::string versionStr = v.get_version().str();
2328 
2329   StaticContextConsts::xquery_version_t version;
2330 
2331   if (versionStr == "1.0")
2332   {
2333     version = StaticContextConsts::xquery_version_1_0;
2334   }
2335 
2336   else if (versionStr == "1.1" || versionStr == "3.0") //1.1 is the same as 3.0
2337   {
2338     version = StaticContextConsts::xquery_version_3_0;
2339   }
2340   else
2341   {
2342     version = StaticContextConsts::xquery_version_unknown;
2343   }
2344 
2345   if (theMaxLibModuleVersion != StaticContextConsts::xquery_version_unknown
2346       &&
2347       version > theMaxLibModuleVersion)
2348   {
2349     zstring maxversion;
2350     if (theMaxLibModuleVersion == StaticContextConsts::xquery_version_3_0)
2351       maxversion = "3.0";
2352     else
2353       maxversion = "1.0";
2354 
2355     // TODO: the error code might need to be changed after W3C solves
2356     // the bug report concerning modules of version 1.0 importing v3.0 libraries.
2357     RAISE_ERROR(err::XQST0031, loc,
2358     ERROR_PARAMS(versionStr, ZED(LibModVersionMismatch_3 ), maxversion));
2359   }
2360 
2361   if (version == StaticContextConsts::xquery_version_unknown)
2362   {
2363     RAISE_ERROR(err::XQST0031, loc,
2364     ERROR_PARAMS(versionStr, ZED(BadXQueryVersion)));
2365   }
2366 
2367   theSctx->set_xquery_version(version);
2368 
2369   return no_state;
2370 }
2371 
end_visit(const VersionDecl & v,void *)2372 void end_visit(const VersionDecl& v, void* /*visit_state*/)
2373 {
2374   TRACE_VISIT_OUT();
2375 }
2376 
2377 
2378 /*******************************************************************************
2379   MainModule ::= Prolog Program
2380 ********************************************************************************/
begin_visit(const MainModule & v)2381 void* begin_visit(const MainModule& v)
2382 {
2383   TRACE_VISIT();
2384 
2385   theAssignedVars.resize(theAssignedVars.size() + 1);
2386 
2387   // Make sure that the context item is always in-scope inside the main module.
2388   // However, do not create a ver_decl expr for it, because this will create a
2389   // treat_as expr as well, so the ctx item will always appear as being used,
2390   // and as a result it will always have to be set.
2391   var_expr* var1 = bind_var(loc,
2392                             DOT_VARNAME,
2393                             var_expr::prolog_var,
2394                             theSctx->get_context_item_type());
2395   var_expr* var2 = bind_var(loc,
2396                             DOT_POS_VARNAME,
2397                             var_expr::prolog_var,
2398                             theRTM.INTEGER_TYPE_ONE);
2399   var_expr* var3 = bind_var(loc,
2400                             LAST_IDX_VARNAME,
2401                             var_expr::prolog_var,
2402                             theRTM.INTEGER_TYPE_ONE);
2403 
2404   var1->set_external(true);
2405   var2->set_external(true);
2406   var3->set_external(true);
2407 
2408   var1->set_unique_id(dynamic_context::IDVAR_CONTEXT_ITEM);
2409   var2->set_unique_id(dynamic_context::IDVAR_CONTEXT_ITEM_POSITION);
2410   var3->set_unique_id(dynamic_context::IDVAR_CONTEXT_ITEM_SIZE);
2411 
2412   //GlobalBinding b(var, NULL, true);
2413   //declare_var(b, theModulesInfo->theInitExprs);
2414 
2415   return no_state;
2416 }
2417 
end_visit(const MainModule & v,void *)2418 void end_visit(const MainModule& v, void* /*visit_state*/)
2419 {
2420   TRACE_VISIT_OUT();
2421 
2422   expr* program = pop_nodestack();
2423 
2424   assert(theCCB->theIsEval || !program->is_updating());
2425 
2426   // If an appliaction set a type for the context item via the c++ api, then
2427   // create a full declaration for it in order to enforce that type.
2428   if (!theHaveContextItemDecl &&
2429       theRTM.ITEM_TYPE_ONE != theSctx->get_context_item_type())
2430   {
2431     var_expr* var = lookup_ctx_var(DOT_VARNAME, loc);
2432     var->set_external(true);
2433     GlobalBinding b(var, NULL, true);
2434     declare_var(b, theModulesInfo->theInitExprs);
2435   }
2436 
2437   // the main module debug iterator has no location otherwise
2438   // this would take precedence over a child debug iterator
2439   // starting in the same line
2440   wrap_in_debugger_expr(program, program->get_loc(), true);
2441 
2442   program = wrap_in_globalvar_assign(program);
2443 
2444   push_nodestack(program);
2445 
2446   theAssignedVars.pop_back();
2447 
2448   if (theModulesInfo->theCCB->isLoadPrologQuery())
2449     theSctx->set_query_expr(program);
2450 }
2451 
2452 
2453 /*******************************************************************************
2454   LibraryModule ::= ModuleDecl  Prolog
2455 ********************************************************************************/
begin_visit(const LibraryModule & v)2456 void* begin_visit(const LibraryModule& v)
2457 {
2458   TRACE_VISIT();
2459 
2460   theAssignedVars.resize(theAssignedVars.size() + 1);
2461 
2462   return no_state;
2463 }
2464 
end_visit(const LibraryModule & v,void *)2465 void end_visit(const LibraryModule& v, void* /*visit_state*/)
2466 {
2467   TRACE_VISIT_OUT();
2468 
2469   expr* program = wrap_in_globalvar_assign(create_empty_seq(loc));
2470 
2471   theAssignedVars.pop_back();
2472 
2473   // Note: There is no real reason to put the expr returned by
2474   // wrap_in_globalvar_assign() in theNodeStack. The only reason is for the
2475   // translate_aux() function to be able to pick that expr from the stack in
2476   // order to print it.
2477   push_nodestack(program);
2478 }
2479 
2480 
2481 /******************************************************************************
2482   ModuleDecl ::= MODULE NAMESPACE  NCNAME  EQ  URI_LITERAL  SEMI
2483 ********************************************************************************/
begin_visit(const ModuleDecl & v)2484 void* begin_visit(const ModuleDecl& v)
2485 {
2486   TRACE_VISIT();
2487   return no_state;
2488 }
2489 
end_visit(const ModuleDecl & v,void *)2490 void end_visit(const ModuleDecl& v, void* /*visit_state*/)
2491 {
2492   TRACE_VISIT_OUT();
2493 
2494   theModulePrefix = v.get_prefix();
2495   theModuleNamespace = v.get_target_namespace();
2496 
2497   if (theModuleNamespace.empty())
2498     throw XQUERY_EXCEPTION(err::XQST0088, ERROR_LOC(loc));
2499 
2500   if (static_context::is_reserved_module(theModuleNamespace))
2501   {
2502     throw XQUERY_EXCEPTION(
2503       zerr::ZXQP0016_RESERVED_MODULE_TARGET_NAMESPACE,
2504       ERROR_PARAMS( theModuleNamespace ),
2505       ERROR_LOC( loc )
2506     );
2507   }
2508 
2509   if (theModulePrefix == "xml" || theModulePrefix == "xmlns")
2510     throw XQUERY_EXCEPTION(
2511       err::XQST0070,
2512       ERROR_PARAMS( theModulePrefix, ZED( NoRebindPrefix ) ),
2513       ERROR_LOC( loc )
2514     );
2515 
2516   theSctx->bind_ns(theModulePrefix, theModuleNamespace, loc);
2517 
2518   zstring uri;
2519   bool found = theSctx->get_entity_retrieval_uri(uri);
2520   ZORBA_ASSERT(found);
2521   // Note: in future, this will be problematic. When we consider supporting
2522   // importing multiple incompatible versions of modules, mod_sctx_map is
2523   // going to become a more complex multi-keyed structure, where the keys will
2524   // be the namespace URI and the version of the module being imported. However,
2525   // the version is defined by a "declare option", which will not have been
2526   // parsed yet. So at this point, we do not have the full key to look up the
2527   // appropriate static_context.
2528   static_context_t lTmpCtx;
2529   found = theModulesInfo->mod_sctx_map.get(uri, lTmpCtx);
2530   ZORBA_ASSERT(found);
2531 
2532   export_sctx = lTmpCtx;
2533 }
2534 
2535 
2536 /////////////////////////////////////////////////////////////////////////////////
2537 //                                                                             //
2538 //  Prolog                                                                     //
2539 //                                                                             //
2540 /////////////////////////////////////////////////////////////////////////////////
2541 
2542 
2543 /*******************************************************************************
2544 
2545   Prolog ::= SIND_DeclList? VFO_DeclList?
2546 
2547   SIND_DeclList ::= SIND_Decl Separator | SIND_DeclList SIND_Decl Separator
2548 
2549   SIND_Decl ::= Setter | NamespaceDecl | DefaultNamespaceDecl | Import
2550 
2551   VFO_DeclList ::= VFO_Decl Separator | VFO_DeclList VFO_Decl Separator
2552 
2553   VFO_Decl ::= ContextItemDecl | AnnotatedDecl | OptionDecl |
2554                CollectionDecl | IndexDecl | IntegrityConstraintDecl
2555 
2556   AnnotatedDecl ::= "declare" Annotation* (VarDecl | FunctionDecl)
2557 
2558   Annotation ::= "%" EQName ("(" Literal ("," Literal)* ")")?
2559 
2560 ********************************************************************************/
begin_visit(const Prolog & v)2561 void* begin_visit(const Prolog& v)
2562 {
2563   TRACE_VISIT();
2564   return no_state;
2565 }
2566 
end_visit(const Prolog & v,void *)2567 void end_visit(const Prolog& v, void* /*visit_state*/)
2568 {
2569   TRACE_VISIT_OUT();
2570 }
2571 
2572 
2573 /*******************************************************************************
2574   SIND_DeclList ::= SIND_Decl Separator | SIND_DeclList SIND_Decl Separator
2575 ********************************************************************************/
begin_visit(const SIND_DeclList & v)2576 void* begin_visit(const SIND_DeclList& v)
2577 {
2578   TRACE_VISIT();
2579   return no_state;
2580 }
2581 
end_visit(const SIND_DeclList & v,void *)2582 void end_visit(const SIND_DeclList& v, void* /*visit_state*/)
2583 {
2584   TRACE_VISIT_OUT();
2585 }
2586 
2587 
2588 /*******************************************************************************
2589   SIND_Decl ::= Setter | NamespaceDecl | DefaultNamespaceDecl | Import
2590 ********************************************************************************/
2591 
2592 
2593 /******************************************************************************
2594 
2595   Setter ::= BoundarySpaceDecl |
2596              OrderingModeDecl |
2597              EmptyOrderDecl |
2598              CopyNamespacesDecl |
2599              DecimalFormatDecl |
2600              DefaultCollationDecl |
2601              BaseURIDecl |
2602              ConstructionDecl |
2603 
2604              RevalidationDecl // update extension
2605 
2606 ********************************************************************************/
2607 
2608 
2609 /*******************************************************************************
2610   BoundarySpaceDecl ::= DECLARE_BOUNDARY_SPACE  ( PRESERVE | STRIP )
2611 ********************************************************************************/
begin_visit(const BoundarySpaceDecl & v)2612 void* begin_visit(const BoundarySpaceDecl& v)
2613 {
2614   TRACE_VISIT();
2615   CHK_SINGLE_DECL (hadBSpaceDecl, err::XQST0068);
2616   theSctx->set_boundary_space_mode(v.get_boundary_space_mode());
2617   return NULL;
2618 }
2619 
end_visit(const BoundarySpaceDecl & v,void *)2620 void end_visit(const BoundarySpaceDecl& v, void* /*visit_state*/)
2621 {
2622   TRACE_VISIT_OUT();
2623 }
2624 
2625 
2626 /*******************************************************************************
2627   OrderingModeDecl ::= DECLARE_ORDERING  ( ORDERED | UNORDERED )
2628 ********************************************************************************/
begin_visit(const OrderingModeDecl & v)2629 void* begin_visit(const OrderingModeDecl& v)
2630 {
2631   TRACE_VISIT();
2632   CHK_SINGLE_DECL(hadOrdModeDecl, err::XQST0065);
2633   theSctx->set_ordering_mode(v.get_mode());
2634   return NULL;
2635 }
2636 
2637 
end_visit(const OrderingModeDecl & v,void *)2638 void end_visit(const OrderingModeDecl& v, void* /*visit_state*/)
2639 {
2640   TRACE_VISIT_OUT();
2641 }
2642 
2643 
2644 /*******************************************************************************
2645   EmptyOrderDecl ::= DECLARE_DEFAULT_ORDER  EMPTY_GREATEST |
2646                      DECLARE_DEFAULT_ORDER  EMPTY_LEAST
2647 ********************************************************************************/
begin_visit(const EmptyOrderDecl & v)2648 void* begin_visit(const EmptyOrderDecl& v)
2649 {
2650   TRACE_VISIT();
2651 
2652   CHK_SINGLE_DECL(hadEmptyOrdDecl, err::XQST0069);
2653 
2654   theSctx->set_empty_order_mode(v.get_mode());
2655   return no_state;
2656 }
2657 
end_visit(const EmptyOrderDecl & v,void *)2658 void end_visit(const EmptyOrderDecl& v, void* /*visit_state*/)
2659 {
2660   TRACE_VISIT_OUT();
2661 }
2662 
2663 
2664 /*******************************************************************************
2665   CopyNamespacesDecl ::= DECLARE_COPY_NAMESPACES PreserveMode COMMA InheritMode
2666 
2667   PreserveMode ::= "preserve" | "no-preserve"
2668   InheritMode ::=  "inherit" | "no-inherit"
2669 ********************************************************************************/
begin_visit(const CopyNamespacesDecl & v)2670 void* begin_visit(const CopyNamespacesDecl& v)
2671 {
2672   TRACE_VISIT();
2673   CHK_SINGLE_DECL(hadCopyNSDecl, err::XQST0055);
2674   return no_state;
2675 }
2676 
end_visit(const CopyNamespacesDecl & v,void *)2677 void end_visit(const CopyNamespacesDecl& v, void* /*visit_state*/)
2678 {
2679   TRACE_VISIT_OUT();
2680   theSctx->set_inherit_ns(v.inherit_ns());
2681   theSctx->set_preserve_ns(v.preserve_ns());
2682 }
2683 
2684 
2685 /******************************************************************************
2686   DecimalFormatDecl ::= "declare"
2687                         (("decimal-format" QName) | ("default" "decimal-format"))
2688                         (DFPropertyName "=" StringLiteral)*
2689 
2690   DFPropertyName ::= "decimal-separator" | "grouping-separator" |
2691                      "infinity" | "minus-sign" | "NaN" | "percent" |
2692                      "per-mille" | "zero-digit" | "digit" |
2693                      "pattern-separator"
2694 ********************************************************************************/
begin_visit(const DecimalFormatNode & v)2695 void* begin_visit(const DecimalFormatNode& v)
2696 {
2697   TRACE_VISIT();
2698 
2699   store::Item_t qnameItem;
2700 
2701   if (!v.is_default)
2702   {
2703     expand_no_default_qname(qnameItem, v.format_name, loc);
2704   }
2705 
2706   DecimalFormat_t df = new DecimalFormat(v.is_default, qnameItem, v.param_list);
2707   df->validate(loc);
2708   theSctx->add_decimal_format(df, loc);
2709 
2710   return no_state;
2711 }
2712 
end_visit(const DecimalFormatNode & v,void *)2713 void end_visit(const DecimalFormatNode& v, void* /*visit_state*/)
2714 {
2715   TRACE_VISIT_OUT();
2716 }
2717 
2718 
2719 /*******************************************************************************
2720   DefaultCollationDecl ::=	DECLARE_DEFAULT_COLLATION  URI_LITERAL
2721 ********************************************************************************/
begin_visit(DefaultCollationDecl const & v)2722 void* begin_visit(DefaultCollationDecl const& v)
2723 {
2724   TRACE_VISIT();
2725 
2726   theSctx->set_default_collation(v.get_collation().str(), loc);
2727   return NULL;
2728 }
2729 
end_visit(const DefaultCollationDecl & v,void *)2730 void end_visit(const DefaultCollationDecl& v, void* /*visit_state*/)
2731 {
2732   TRACE_VISIT_OUT ();
2733 }
2734 
2735 
2736 /*******************************************************************************
2737   BaseURIDecl ::= DECLARE_BASE_URI  URI_LITERAL
2738 ********************************************************************************/
begin_visit(const BaseURIDecl & v)2739 void* begin_visit(const BaseURIDecl& v)
2740 {
2741   TRACE_VISIT();
2742 
2743   CHK_SINGLE_DECL(hadBUriDecl, err::XQST0032);
2744 
2745   zstring uri(v.get_base_uri());
2746   try
2747   {
2748     theSctx->set_base_uri(uri);
2749   }
2750   catch (ZorbaException& e)
2751   {
2752     e.set_diagnostic( err::XQST0046 );
2753     set_source( e, loc );
2754     throw;
2755   }
2756   return NULL;
2757 }
2758 
2759 
end_visit(const BaseURIDecl & v,void *)2760 void end_visit(const BaseURIDecl& v, void* /*visit_state*/)
2761 {
2762   TRACE_VISIT_OUT();
2763 }
2764 
2765 
2766 /*******************************************************************************
2767   ConstructionDecl ::= DECLARE_CONSTRUCTION  PRESERVE
2768                        DECLARE_CONSTRUCTION  STRIP
2769 ********************************************************************************/
begin_visit(const ConstructionDecl & v)2770 void* begin_visit(const ConstructionDecl& v)
2771 {
2772   TRACE_VISIT();
2773 
2774   CHK_SINGLE_DECL(hadConstrDecl, err::XQST0067);
2775   theSctx->set_construction_mode(v.get_mode());
2776   return NULL;
2777 }
2778 
end_visit(const ConstructionDecl & v,void *)2779 void end_visit (const ConstructionDecl& v, void* /*visit_state*/)
2780 {
2781   TRACE_VISIT_OUT();
2782 }
2783 
2784 
2785 /*******************************************************************************
2786   RevalidationDecl ::= "declare" "revalidation" ("string" | "lax" | "skip")
2787 ********************************************************************************/
begin_visit(const RevalidationDecl & v)2788 void* begin_visit(const RevalidationDecl& v)
2789 {
2790   TRACE_VISIT();
2791 
2792   CHK_SINGLE_DECL (hadBUriDecl, err::XUST0003);
2793   theSctx->set_validation_mode(v.get_mode());
2794   return no_state;
2795 }
2796 
end_visit(const RevalidationDecl & v,void *)2797 void end_visit(const RevalidationDecl& v, void* /*visit_state*/)
2798 {
2799   TRACE_VISIT_OUT();
2800 }
2801 
2802 
2803 /*******************************************************************************
2804   NamespaceDecl ::= ::= DECLARE_NAMESPACE  NCNAME  EQ  URI_LITERAL
2805 ********************************************************************************/
begin_visit(const NamespaceDecl & v)2806 void* begin_visit(const NamespaceDecl& v)
2807 {
2808   TRACE_VISIT();
2809 
2810   zstring pre = v.get_prefix();
2811   zstring uri = v.get_uri();
2812 
2813   if (pre == "xml" || pre == "xmlns")
2814   {
2815     throw XQUERY_EXCEPTION(
2816       err::XQST0070,
2817       ERROR_PARAMS( pre, ZED( NoRebindPrefix ) ),
2818       ERROR_LOC( loc )
2819     );
2820   }
2821   else if (uri == XML_NS || uri == XMLNS_NS)
2822   {
2823     throw XQUERY_EXCEPTION(
2824       err::XQST0070,
2825       ERROR_PARAMS( uri, ZED( NoBindURI ) ),
2826       ERROR_LOC( loc )
2827     );
2828   }
2829 
2830   theSctx->bind_ns(pre, uri, loc);
2831 
2832   return NULL;
2833 }
2834 
end_visit(const NamespaceDecl & v,void *)2835 void end_visit(const NamespaceDecl& v, void* /*visit_state*/)
2836 {
2837   TRACE_VISIT_OUT();
2838 }
2839 
2840 
2841 /*******************************************************************************
2842   DefaultNamespaceDecl ::= DECLARE DEFAULT ELEMENT NAMESPACE URILiteral |
2843                            DECLARE DEFAULT FUNCTION NAMESPACE URILiteral
2844 ********************************************************************************/
begin_visit(DefaultNamespaceDecl const & v)2845 void* begin_visit(DefaultNamespaceDecl const& v)
2846 {
2847   TRACE_VISIT();
2848 
2849   switch (v.get_mode())
2850   {
2851   case ParseConstants::ns_element_default:
2852     theSctx->set_default_elem_type_ns(v.get_default_namespace(), true, loc);
2853     break;
2854   case ParseConstants::ns_function_default:
2855     theSctx->set_default_function_ns(v.get_default_namespace(), true, loc);
2856     break;
2857   }
2858   return NULL;
2859 }
2860 
end_visit(const DefaultNamespaceDecl & v,void *)2861 void end_visit(const DefaultNamespaceDecl& v, void* /*visit_state*/)
2862 {
2863   TRACE_VISIT_OUT();
2864 }
2865 
2866 
2867 /*******************************************************************************
2868   Import ::= SchemaImport | ModuleImport
2869 ********************************************************************************/
2870 
2871 
2872 /*******************************************************************************
2873   SchemaImport ::= "import" "schema" SchemaPrefix? URILiteral
2874                    ("at"  URILiteralList)?
2875 ********************************************************************************/
begin_visit(const SchemaImport & v)2876 void* begin_visit(const SchemaImport& v)
2877 {
2878   TRACE_VISIT();
2879 
2880   return import_schema(loc, v.get_prefix(), v.get_uri(), v.get_at_list());
2881 }
2882 
end_visit(const SchemaImport & v,void *)2883 void end_visit (const SchemaImport& v, void* /*visit_state*/)
2884 {
2885   TRACE_VISIT_OUT ();
2886 }
2887 
2888 
2889 /******************************************************************************
2890   URLLiteralList ::= URI_LITERAL | URILiteralList  COMMA  URI_LITERAL
2891 ********************************************************************************/
begin_visit(const URILiteralList & v)2892 void* begin_visit(const URILiteralList& v)
2893 {
2894   TRACE_VISIT();
2895   return no_state;
2896 }
2897 
end_visit(const URILiteralList & v,void *)2898 void end_visit(const URILiteralList& v, void* /*visit_state*/)
2899 {
2900   TRACE_VISIT_OUT();
2901 }
2902 
2903 
2904 /******************************************************************************
2905   SchemaPrefix ::= ("namespace" NCName "=") | ("default" "element" "namespace")
2906 ********************************************************************************/
begin_visit(const SchemaPrefix & v)2907 void* begin_visit(const SchemaPrefix& v)
2908 {
2909   TRACE_VISIT();
2910   return no_state;
2911 }
2912 
end_visit(const SchemaPrefix & v,void *)2913 void end_visit(const SchemaPrefix& v, void* /*visit_state*/)
2914 {
2915   TRACE_VISIT_OUT();
2916 }
2917 
2918 
2919 /*******************************************************************************
2920   ModuleImport ::= "import" "module" ("namespace" NCName "=")? URILiteral
2921                    ("at" URILiteralList)?
2922 ********************************************************************************/
begin_visit(const ModuleImport & v)2923 void* begin_visit(const ModuleImport& v)
2924 {
2925   TRACE_VISIT();
2926   return no_state;
2927 }
2928 
2929 
end_visit(const ModuleImport & v,void *)2930 void end_visit(const ModuleImport& v, void* /*visit_state*/)
2931 {
2932   TRACE_VISIT_OUT();
2933 
2934   // Create a ModuleVersion based on the input namespace URI.
2935   const ModuleVersion modVer(v.get_uri());
2936 
2937   // targetNS is the target namespace *without* any
2938   // version-declaration fragment.
2939   zstring const targetNS = modVer.namespace_uri();
2940   zstring const pfx = (!v.get_prefix().empty()) ? v.get_prefix() : "";
2941 
2942   if (static_context::is_reserved_module(targetNS))
2943   {
2944     RAISE_ERROR(zerr::ZXQP0016_RESERVED_MODULE_TARGET_NAMESPACE, loc,
2945     ERROR_PARAMS(targetNS));
2946   }
2947 
2948   // The namespace prefix specified in a module import must not be xml or xmlns
2949   // [err:XQST0070]
2950   if (!pfx.empty() && (pfx == "xml" || pfx == "xmlns"))
2951   {
2952     RAISE_ERROR(err::XQST0070, loc, ERROR_PARAMS(pfx, ZED(NoRebindPrefix)));
2953   }
2954 
2955   // The first URILiteral in a module import must be of nonzero length
2956   // [err:XQST0088]
2957   if (targetNS.empty())
2958     throw XQUERY_EXCEPTION(err::XQST0088, ERROR_LOC(loc));
2959 
2960   // It is a static error [err:XQST0047] if more than one module import in a
2961   // Prolog specifies the same target namespace. Note: by checking this here,
2962   // we disallow importing two different versions of the same module from
2963   // within a single module. It is not clear how we could support that anyway,
2964   // since after import, they would both have the same namespace URI, and hence
2965   // any references to that namespace would be ambiguous.
2966   if (! theImportedModules.insert(targetNS.str()).second)
2967     RAISE_ERROR(err::XQST0047, loc, ERROR_PARAMS(targetNS));
2968 
2969   // The namespace prefix specified in a module import must not be the same as
2970   // any namespace prefix bound in the same module by another module import,
2971   // a schema import, a namespace declaration, or a module declaration with a
2972   // different target namespace [err:XQST0033].
2973   if (! pfx.empty() &&
2974       ! (pfx == theModulePrefix &&
2975          targetNS == theModuleNamespace))
2976   {
2977     theSctx->bind_ns(pfx, targetNS, loc, err::XQST0033);
2978   }
2979 
2980   const URILiteralList* atlist = v.get_at_list();
2981 
2982   // If the imported module X is a "pure builtin" one (i.e., contains
2983   // decalrations of zorba builtin functions only), then we don't need
2984   // to process it. We just need to record in the root sctx of the
2985   // importing module that X has been imported.
2986   if (atlist == NULL && static_context::is_builtin_module(targetNS))
2987   {
2988     // just a test, this will throw, if the access is denied
2989     std::vector<zstring> candidateURIs;
2990     theRootSctx->get_candidate_uris(targetNS,
2991                                     internal::EntityData::MODULE,
2992                                     candidateURIs);
2993     theRootSctx->add_imported_builtin_module(targetNS);
2994 #ifdef NDEBUG
2995     // We cannot skip the math or the sctx introspection modules because they
2996     // contain some non-external functions as well.
2997     if (!static_context::is_non_pure_builtin_module(targetNS))
2998     {
2999       return;
3000     }
3001 #else
3002     if (static_context::is_builtin_virtual_module(targetNS))
3003     {
3004       return;
3005     }
3006 #endif
3007   }
3008 
3009   // Create a list of absolute uris identifying the components of the module
3010   // being imported. If there are no "at" clauses, try to generate the
3011   // component URI from the target namespace. This is done using one or more
3012   // user-provided module resolvers. If no such resolvers were provided, or if
3013   // they don't know about the target namespace, the original target namespace
3014   // (including version fragment, if any) itself will be used as the (sole)
3015   // component URI. If there are "at" clauses, then any relative URIs that are
3016   // listed there are converted to absolute ones, using the base uri from the
3017   // sctx.
3018 
3019   std::vector<zstring> compURIs;
3020   if (atlist == NULL || atlist->size() == 0)
3021   {
3022     // Note the use of versioned_uri() here, so that the namespace with any
3023     // version fragment will be passed through to the mappers.
3024     theSctx->get_component_uris(modVer.versioned_uri(),
3025                                 internal::EntityData::MODULE, compURIs);
3026   }
3027   else
3028   {
3029     for (ulong i = 0; i < atlist->size(); ++i)
3030     {
3031       compURIs.push_back(theSctx->resolve_relative_uri((*atlist)[i]).str());
3032     }
3033   }
3034 
3035   // Take each of the URIs collected above and import the module's functions
3036   // and variables into the current static context.
3037   for (std::vector<zstring>::const_iterator ite = compURIs.begin();
3038        ite != compURIs.end();
3039        ++ite)
3040   {
3041     // Create a ModuleVersion for the current component URI.
3042     const ModuleVersion compModVer(*ite);
3043 
3044     // Get the location uri for the module to import (minus version fragment,
3045     // if any). This will be the key for mod_ns_map and mod_sctx_map. Note:
3046     // if in future we support loading multiple versions of the same module,
3047     // this key will have to change.
3048     const zstring compURI = compModVer.namespace_uri();
3049 
3050     // If this import forms a cycle in a chain of module imports, skip it.
3051     // If the importing module is referencing any variable or function of
3052     // the skipped module, an XQST0093 error will be raised when the translator
3053     // tries to process that var or function reference.
3054     std::map<zstring, zstring> modulesStack = theModulesStack;
3055 #if 0
3056     std::map<zstring, zstring>::iterator ite = modulesStack.begin();
3057     std::map<zstring, zstring>::iterator end = modulesStack.end();
3058     for (; ite != end; ++ite)
3059     {
3060       std::cout << "[" << (*ite).first << ", " << (*ite).second << "]" << std::endl;
3061     }
3062     std::cout << std::endl;
3063 #endif
3064     if (! modulesStack.insert(std::pair<zstring, zstring>(compURI, targetNS)).second)
3065     {
3066       theHaveModuleImportCycle = true;
3067       return;
3068     }
3069 
3070     // importedNS is the target namespace of the imported module, as declared
3071     // inside the module itself.
3072     zstring importedNS;
3073     static_context_t importedSctx = NULL;
3074 
3075     // Check whether we have already imported a module component from
3076     // the current uri. If so, check that the target ns of what we
3077     // imported before is the same as what we are trying to import
3078     // now.
3079     if (theModulesInfo->mod_ns_map.get(compURI, importedNS))
3080     {
3081       if (importedNS != targetNS)
3082         RAISE_ERROR(err::XQST0059, loc, ERROR_PARAMS(targetNS, compURI));
3083 
3084       bool found = theModulesInfo->mod_sctx_map.get(compURI, importedSctx);
3085       ZORBA_ASSERT(found);
3086     }
3087 
3088     // We are importing a module for the 1st time.
3089     else
3090     {
3091       // Open the file containing the imported module.
3092       zstring compURL;
3093       std::istream* modfile;
3094 
3095       // Resolve the URI. Again, note the use of versioned_uri() here,
3096       // rather than using compURI directly, because we want the version
3097       // fragment to be passed to the mappers.
3098       zstring lErrorMessage;
3099       std::auto_ptr<internal::Resource> lResource;
3100       internal::StreamResource* lStreamResource = NULL;
3101 
3102       try
3103       {
3104         lResource =
3105         theSctx->resolve_uri(compModVer.versioned_uri(),
3106                              internal::EntityData::MODULE,
3107                              lErrorMessage);
3108 
3109         lStreamResource =
3110         dynamic_cast<internal::StreamResource*> (lResource.get());
3111       }
3112       catch (ZorbaException& e)
3113       {
3114         set_source(e, loc);
3115         throw;
3116       }
3117 
3118       if (lStreamResource != NULL)
3119       {
3120         modfile = lStreamResource->getStream();
3121         compURL = lStreamResource->getStreamUrl();
3122       }
3123       else
3124       {
3125         RAISE_ERROR(err::XQST0059, loc, ERROR_PARAMS(targetNS, compURI, lErrorMessage));
3126       }
3127 
3128       // Get the parent of the query root sctx. This is the user-specified sctx
3129       // (if any) or the zorba root sctx (if no user-specified sctx).
3130       static_context_t independentSctx =
3131       static_cast<static_context *>(theCCB->theRootSctx->get_parent());
3132 
3133       // Create the root sctx for the imported module as a child of the
3134       // independentSctx. Register this sctx in the query-level sctx map.
3135       static_context* moduleRootSctx;
3136       if (theCCB->isLoadPrologQuery())
3137         moduleRootSctx = theCCB->theRootSctx->create_child_context();
3138       else
3139         moduleRootSctx = independentSctx->create_child_context();
3140 
3141       moduleRootSctx->set_entity_retrieval_uri(compURI);
3142       moduleRootSctx->set_module_namespace(targetNS);
3143       moduleRootSctx->set_typemanager(new TypeManagerImpl(&GENV_TYPESYSTEM));
3144       csize moduleRootSctxId = theCCB->theSctxMap.size() + 1;
3145       (theCCB->theSctxMap)[moduleRootSctxId] = moduleRootSctx;
3146 
3147       // Create an sctx where the imported module is going to register
3148       // all the variable and function declarations that appear in its
3149       // prolog. After the translation of the imported module is done,
3150       // this sctx will be merged with the sctx of the importing
3151       // module.
3152       importedSctx = independentSctx->create_child_context();
3153       importedSctx->set_module_namespace(targetNS);
3154 
3155       // Register the imported_sctx in theModulesInfo->mod_sctx_map so
3156       // that it is accessible by both the importing and the imported
3157       // modules.
3158       theModulesInfo->mod_sctx_map.put(compURI, importedSctx);
3159 
3160       // Parse the imported module. fileURL is information only - it is used
3161       // by the parser when creating query locations, etc.
3162       XQueryCompiler xqc(theCCB);
3163       zstring fileURL;
3164       if (compURL.size() != 0)
3165       {
3166         fileURL = compURL;
3167       }
3168       else
3169       {
3170         fileURL = compURI;
3171       }
3172 
3173       rchandle<parsenode> ast = xqc.parse(*modfile, fileURL);
3174 
3175       // Get the target namespace that appears in the module declaration
3176       // of the imported module and check that this ns is the same as the
3177       // target ns in the module import statement.
3178       // Also make sure that the imported module is a library module
3179       LibraryModule* mod_ast = dynamic_cast<LibraryModule *>(&*ast);
3180       if (mod_ast == NULL)
3181         RAISE_ERROR(err::XQST0059, loc, ERROR_PARAMS(targetNS, compURI));
3182 
3183       importedNS = mod_ast->get_decl()->get_target_namespace().str();
3184 
3185       if (importedNS.empty())
3186         throw XQUERY_EXCEPTION(err::XQST0088, ERROR_LOC(loc));
3187 
3188       if (importedNS != targetNS)
3189         RAISE_ERROR(err::XQST0059, loc, ERROR_PARAMS(targetNS, compURI));
3190 
3191       // translate the imported module
3192       translate_aux(theRootTranslator,
3193                     *ast,
3194                     moduleRootSctx,
3195                     moduleRootSctxId,
3196                     theModulesInfo,
3197                     modulesStack,
3198                     true,
3199                     theSctx->xquery_version());
3200 
3201       // Determine the imported version, and verify that it satisfies the
3202       // import specification (if any). QQQ this really should be done whether
3203       // the module was newly-imported or already imported; it should be done
3204       // below just before "Merge the exported sctx". However, currently at
3205       // least, "declare option" information is not stored in the sctx that is
3206       // in mod_sctx_map; therefore, when dealing with an already-imported
3207       // sctx, there's no way to know what version it is. SF bug# 3312333.
3208       if (modVer.is_valid_version())
3209       {
3210         store::Item_t lMajorOpt;
3211         theSctx->expand_qname(lMajorOpt,
3212                               static_context::ZORBA_VERSIONING_NS,
3213                               zstring(""),
3214                               zstring(ZORBA_OPTION_MODULE_VERSION),
3215                               loc);
3216         zstring lImportedVersion;
3217         if (!moduleRootSctx->lookup_option(lMajorOpt, lImportedVersion))
3218         {
3219           lImportedVersion = "0.0";
3220         }
3221         ModuleVersion lImportedModVer(compURI, lImportedVersion);
3222         if (! lImportedModVer.is_valid_version())
3223         {
3224           RAISE_ERROR(zerr::ZXQP0039_INVALID_VERSION_SPECIFICATION, loc,
3225           ERROR_PARAMS(lImportedVersion));
3226         }
3227 
3228         if (!lImportedModVer.satisfies(modVer))
3229         {
3230           RAISE_ERROR(zerr::ZXQP0037_INAPPROPRIATE_MODULE_VERSION, loc,
3231           ERROR_PARAMS(modVer.versioned_uri(), lImportedVersion));
3232         }
3233       }
3234 
3235       // Register the mapping between the current location uri and the
3236       // target namespace.
3237       theModulesInfo->mod_ns_map.put(compURI, importedNS);
3238 
3239 #ifdef ZORBA_WITH_DEBUGGER
3240       // If we compile in debug mode, we add the namespace uri into a
3241       // map, that allows the debugger to set breakpoints at a
3242       // namespace uri and line number
3243       if (theCCB->theDebuggerCommons)
3244       {
3245         theCCB->theDebuggerCommons->addModuleUriMapping
3246           (importedNS.str(), compURL.c_str());
3247       }
3248 #endif
3249     }
3250 
3251     // Merge the exported sctx of the imported module into the sctx of the
3252     // current module. Note: We catch duplicate functions / vars in
3253     // theModulesInfo->globalSctx. We can safely ignore the return value.
3254     // We might even be able to assert() here (not sure though).
3255     theSctx->import_module(importedSctx, loc);
3256 
3257   } // for (vector<zstring>::iterator ite = lURIs.begin();
3258 }
3259 
3260 
3261 /*******************************************************************************
3262   VFO_DeclList ::= VFO_Decl Separator | VFO_DeclList VFO_Decl Separator
3263 
3264   VFO_Decl ::= ContextItemDecl | AnnotatedDecl | OptionDecl |
3265                CollectionDecl | IndexDecl | IntegrityConstraintDecl
3266 
3267   AnnotatedDecl ::= "declare" Annotation* (VarDecl | FunctionDecl)
3268 
3269   Annotation ::= "%" EQName ("(" Literal ("," Literal)* ")")?
3270 
3271 ********************************************************************************/
begin_visit(const VFO_DeclList & v)3272 void* begin_visit(const VFO_DeclList& v)
3273 {
3274   TRACE_VISIT();
3275 
3276   TypeManager* tm = CTX_TM;
3277 
3278   // Function declaration translation must be done in two passes because of
3279   // mutually recursive functions and also because the defining expr of a declared
3280   // var may reference a function that is declared after the var. So, here's the
3281   // 1st pass; it translates
3282   //  (1) the annotations of variable and function declarations
3283   //  (2) the type declarations for the params and return value of functions
3284   //  (3) and then creates the udf object and binds it in the sctx.
3285   // The 1st pass also binds all options, so that the module version information
3286   // is available if we try to load external function libraries.
3287   // The 2nd pass happens when accept() is called on each individual FunctionDecl
3288   // node in the list.
3289 
3290   for (std::vector<rchandle<parsenode> >::const_iterator it = v.begin();
3291        it != v.end();
3292        ++it)
3293   {
3294     const OptionDecl* opt_decl = it->dyn_cast<OptionDecl>();
3295 
3296     if (opt_decl != NULL)
3297     {
3298       store::Item_t qnameItem;
3299       zstring value = opt_decl->get_val().str();
3300 
3301       expand_no_default_qname(qnameItem, opt_decl->get_qname(), loc);
3302 
3303       if (qnameItem->getPrefix().empty() && qnameItem->getNamespace().empty())
3304         RAISE_ERROR(err::XPST0081, loc, ERROR_PARAMS(qnameItem->getStringValue()));
3305 
3306       theSctx->bind_option(qnameItem, value, opt_decl->get_location());
3307 
3308       if (qnameItem->getNamespace() == static_context::ZORBA_OPTION_OPTIM_NS &&
3309           value == "for-serialization-only")
3310       {
3311         if (qnameItem->getLocalName() == "enable")
3312           theCCB->theConfig.for_serialization_only = true;
3313         else
3314           theCCB->theConfig.for_serialization_only = false;
3315       }
3316 
3317       continue;
3318     }
3319 
3320 #if 1
3321     const GlobalVarDecl* var_decl = it->dyn_cast<GlobalVarDecl>().getp();
3322 
3323     if (var_decl != NULL &&
3324         theSctx->xquery_version() >= StaticContextConsts::xquery_version_3_0)
3325     {
3326       const QueryLoc& loc = var_decl->get_location();
3327 
3328       store::Item_t qnameItem;
3329       expand_no_default_qname(qnameItem, var_decl->get_var_name(), loc);
3330 
3331       // All vars declared in a module must be in the same namespace as the module
3332       if (! theModuleNamespace.empty() &&
3333           qnameItem->getNamespace() != theModuleNamespace)
3334       {
3335         RAISE_ERROR(err::XQST0048, loc, ERROR_PARAMS(qnameItem->getStringValue()));
3336       }
3337 
3338       var_expr* ve = create_var(loc, qnameItem, var_expr::prolog_var);
3339 
3340       if (var_decl->is_extern())
3341         ve->set_external(true);
3342 
3343       xqtref_t type;
3344       if (var_decl->get_var_type() != NULL)
3345       {
3346         var_decl->get_var_type()->accept(*this);
3347 
3348         type = pop_tstack();
3349 
3350         ve->set_type(type);
3351       }
3352 
3353       AnnotationListParsenode* annotations = var_decl->get_annotations();
3354       if (annotations)
3355       {
3356         if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
3357         {
3358           RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_Annotations)));
3359         }
3360 
3361         annotations->accept(*this);
3362 
3363         if (theAnnotations)
3364         {
3365           if (ZANN_CONTAINS(fn_private))
3366             ve->set_private(true);
3367 
3368           if (ZANN_CONTAINS(zann_assignable))
3369           {
3370             ve->set_mutable(true);
3371           }
3372           else if (ZANN_CONTAINS(zann_nonassignable))
3373           {
3374             ve->set_mutable(false);
3375           }
3376           else
3377           {
3378             ve->set_mutable(theSctx->is_feature_set(feature::scripting));
3379           }
3380         }
3381         else
3382         {
3383           ve->set_mutable(theSctx->is_feature_set(feature::scripting));
3384         }
3385       }
3386       else
3387       {
3388         ve->set_mutable(theSctx->is_feature_set(feature::scripting));
3389       }
3390 
3391       theAnnotations = NULL;
3392 
3393       // Put a mapping between the var name and the var_expr in the local sctx.
3394       // Raise error if var name exists already in local sctx obj.
3395       bind_var(ve, theSctx);
3396 
3397       // Make sure that there is no other prolog var with the same name in any of
3398       // modules translated so far.
3399       bind_var(ve, theModulesInfo->globalSctx.get());
3400 
3401       // If this is a library module, register the var in the exported sctx as well.
3402       if (export_sctx != NULL)
3403         bind_var(ve, export_sctx);
3404 
3405       continue;
3406     }
3407 #endif
3408 
3409     const FunctionDecl* func_decl = it->dyn_cast<FunctionDecl>().getp();
3410 
3411     if (func_decl == NULL)
3412       continue;
3413 
3414     AnnotationListParsenode* annotations = func_decl->get_annotations();
3415     if (annotations)
3416     {
3417       if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
3418       {
3419         RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_Annotations)));
3420       }
3421 
3422       annotations->accept(*this);
3423     }
3424 
3425     const QueryLoc& loc = func_decl->get_location();
3426 
3427     // Expand the function qname (error is raised if qname resolution fails)
3428     // and check it for errors. The following conditions are checked:
3429     // - Function must be declared in a non-NULL namespace.
3430     // - Function must not be in any of the reserved namespaces.
3431     // - In a module, all exports must be inside the target ns.
3432     const QName* fname = func_decl->get_name();
3433     store::Item_t qnameItem;
3434     expand_function_qname(qnameItem, fname, fname->get_location());
3435 
3436     const zstring& ns = qnameItem->getNamespace();
3437 
3438     if (ns.empty())
3439       RAISE_ERROR(err::XQST0060, loc, ERROR_PARAMS(qnameItem->getStringValue()));
3440 
3441     if (ns == static_context::W3C_FN_NS ||
3442         ns == XML_NS ||
3443         ns == XML_SCHEMA_NS ||
3444         ns == XSI_NS ||
3445         ns == XQUERY_MATH_FN_NS)
3446     {
3447       RAISE_ERROR(err::XQST0045, func_decl->get_location(),
3448       ERROR_PARAMS(qnameItem->getLocalName()));
3449     }
3450 
3451     if (! theModuleNamespace.empty() && ns != theModuleNamespace)
3452       RAISE_ERROR(err::XQST0048, loc, ERROR_PARAMS(qnameItem->getStringValue()));
3453 
3454     // Process the parameter types and the return type in order to create the
3455     // function signature.
3456     rchandle<ParamList> params = func_decl->get_paramlist();
3457     if (params == NULL)
3458       params = new ParamList(loc);
3459 
3460     csize numParams = params->size();
3461 
3462     std::vector<xqtref_t> paramTypes;
3463 
3464     for (std::vector<rchandle<Param> >::const_iterator it = params->begin();
3465          it != params->end();
3466          ++it)
3467     {
3468       const Param* param = (*it);
3469       const SequenceType* paramType = param->get_typedecl();
3470       if (paramType == NULL)
3471       {
3472         paramTypes.push_back(GENV_TYPESYSTEM.ITEM_TYPE_STAR);
3473       }
3474       else
3475       {
3476         paramType->accept(*this);
3477         paramTypes.push_back(pop_tstack());
3478       }
3479     }
3480 
3481     xqtref_t returnType = GENV_TYPESYSTEM.ITEM_TYPE_STAR;
3482 
3483     if (func_decl->get_return_type() != NULL)
3484     {
3485       func_decl->get_return_type()->accept(*this);
3486       returnType = pop_tstack();
3487     }
3488     else if (func_decl->is_updating())
3489     {
3490       // TODO: should we have a different default?
3491       // TODO: if returnType is set to something other than ITEM_TYPE_STAR
3492       // the body of the udf will be wrapped in a treat expr. So, we will
3493       // have an updating expr as input to a treat expr, which is not allowed
3494       // yet.
3495       //returnType = theRTM.EMPTY_TYPE;
3496     }
3497 
3498     // Create the function signature.
3499     bool isVariadic = (theAnnotations ? ZANN_CONTAINS(zann_variadic): false);
3500 
3501     signature sig(qnameItem, paramTypes, returnType, isVariadic);
3502 
3503     // Get the scripting kind of the function
3504     bool isSequential = (theAnnotations ?
3505                          ZANN_CONTAINS(zann_sequential) :
3506                          false);
3507 
3508     expr_script_kind_t scriptKind = SIMPLE_EXPR;
3509 
3510     if (func_decl->is_updating())
3511       scriptKind = UPDATING_EXPR;
3512     else if (isSequential)
3513       scriptKind = SEQUENTIAL_FUNC_EXPR;
3514 
3515     // create the function object
3516     function_t f;
3517 
3518     if (func_decl->is_external())
3519     {
3520       // 1. lookup if the function is a built-in function
3521       f = theSctx->lookup_fn(qnameItem, numParams, false);
3522 
3523       if (f != 0)
3524       {
3525         if (f->isUdf())
3526         {
3527           RAISE_ERROR(err::XQST0034, loc, ERROR_PARAMS(qnameItem->getStringValue()));
3528         }
3529 
3530         // We make sure that the types of the parameters and the return type
3531         // are subtypes of the ones declared in the module
3532         const signature& s = f->getSignature();
3533         if (!s.subtype(tm, sig, loc))
3534         {
3535           RAISE_ERROR(zerr::ZXQP0007_FUNCTION_SIGNATURE_NOT_EQUAL, loc,
3536           ERROR_PARAMS(BUILD_STRING('{',
3537                                     qnameItem->getNamespace(),
3538                                     '}',
3539                                     qnameItem->getLocalName())));
3540         }
3541 
3542         if (isSequential && !f->isSequential())
3543         {
3544           RAISE_ERROR(zerr::ZXQP0010_FUNCTION_NOT_SEQUENTIAL, loc,
3545           ERROR_PARAMS(BUILD_STRING('{',
3546                                     qnameItem->getNamespace(),
3547                                     '}',
3548                                     qnameItem->getLocalName())));
3549         }
3550 
3551         f->setAnnotations(theAnnotations);
3552         theAnnotations = NULL; // important to reset
3553 
3554         // continue with the next declaration, because we don't add already
3555         // built-in functions to the static context
3556         continue;
3557       }
3558 
3559       // 2. if no built-in function is there, we check the static context
3560       // to see if the user has registered an external function
3561       ExternalFunction* ef = 0;
3562       try
3563       {
3564         ef = theSctx->lookup_external_function(qnameItem->getNamespace(),
3565                                                qnameItem->getLocalName());
3566       }
3567       catch (XQueryException& e)
3568       {
3569         set_source(e, loc);
3570         throw;
3571       }
3572 
3573       // The external function must be registered already in the static context
3574       // via the StaticContextImpl::registerExternalModule() user api.
3575       if (ef == NULL)
3576       {
3577         RAISE_ERROR(zerr::ZXQP0008_FUNCTION_IMPL_NOT_FOUND, loc,
3578         ERROR_PARAMS(BUILD_STRING('{',
3579                                   qnameItem->getNamespace(),
3580                                   '}',
3581                                   qnameItem->getLocalName(),
3582                                   isVariadic?"variadic":"#", numParams)));
3583       }
3584       else
3585       {
3586         if (ef->getLocalName().compare(qnameItem->getLocalName().str()) != 0)
3587         {
3588           RAISE_ERROR(zerr::ZXQP0009_FUNCTION_LOCALNAME_MISMATCH, loc,
3589           ERROR_PARAMS(qnameItem->getLocalName(), ef->getLocalName()));
3590         }
3591       }
3592 
3593       ZORBA_ASSERT(ef != NULL);
3594 
3595       f = new external_function(loc,
3596                                 theRootSctx,
3597                                 qnameItem->getNamespace(),
3598                                 sig,
3599                                 scriptKind,
3600                                 ef);
3601     }
3602     else // Process UDF (non-external) function declaration
3603     {
3604       f = new user_function(loc, sig, NULL, scriptKind, theCCB); // no body for now
3605     }
3606 
3607     f->setAnnotations(theAnnotations);
3608     theAnnotations = NULL; // important to reset
3609 
3610     // Create bindings between (function qname item, arity) and function obj
3611     // in the current sctx of this module and, if this is a lib module, in its
3612     // export sctx as well.
3613     bind_fn(f, numParams, loc);
3614   }
3615 
3616   return no_state;
3617 }
3618 
3619 
end_visit(const VFO_DeclList & v,void *)3620 void end_visit(const VFO_DeclList& v, void* /*visit_state*/)
3621 {
3622   TRACE_VISIT_OUT();
3623 
3624   thePrologGraph.reorder_globals(thePrologVars);
3625 }
3626 
3627 
3628 /*******************************************************************************
3629 
3630   AnnotatedDecl ::= "declare" Annotation* (VarDecl | FunctionDecl)
3631 
3632   Annotation ::= "%" EQName ("(" Literal ("," Literal)* ")")?
3633 
3634   FunctionDecl ::= "function" EQName "(" ParamList? ")" ("as" SequenceType)?
3635                         (BlockExpr | "external")
3636 
3637   BlockExpr ::= "{" Statements Expr "}"
3638 
3639   Note: the applicable annotations are private vs public, sequential vs
3640   non-sequential, and deterministic vs nondeterministic.
3641 ********************************************************************************/
begin_visit(const FunctionDecl & v)3642 void* begin_visit(const FunctionDecl& v)
3643 {
3644   TRACE_VISIT();
3645 
3646   push_scope();
3647 
3648   // Get function obj out of function qname (will raise error if prefix in qname
3649   // is not bound to a namespace).
3650   store::Item_t qnameItem;
3651   expand_function_qname(qnameItem, v.get_name(), v.get_name()->get_location());
3652   function* f = theSctx->lookup_fn(qnameItem, v.get_param_count(), false);
3653 
3654   assert(f);
3655 
3656   thePrologGraph.addFuncVertex(f);
3657   theCurrentPrologVFDecl = PrologGraphVertex(f);
3658 
3659   theHaveUpdatingExitExprs = false;
3660   theHaveSequentialExitExprs = false;
3661 
3662   return no_state;
3663 }
3664 
3665 
end_visit(const FunctionDecl & v,void *)3666 void end_visit(const FunctionDecl& v, void* /*visit_state*/)
3667 {
3668   TRACE_VISIT_OUT();
3669 
3670   theCurrentPrologVFDecl.setNull();
3671 
3672   const zstring& fname = v.get_name()->get_qname();
3673 
3674   csize numParams = v.get_param_count();
3675 
3676   function* lFunc = lookup_fn(v.get_name(), numParams, loc);
3677 
3678   // TODO: remove this error
3679   if (lFunc && lFunc->isUpdating() && v.get_return_type() != 0)
3680     RAISE_ERROR(err::XUST0028, loc, ERROR_PARAMS(fname));
3681 
3682   if (v.get_return_type() != NULL)
3683     pop_tstack();
3684 
3685   expr* body = NULL;
3686   user_function* udf = NULL;
3687 
3688   if (!v.is_external())
3689   {
3690     udf = dynamic_cast<user_function *>(lFunc);
3691 
3692     body = pop_nodestack();
3693 
3694     wrap_in_debugger_expr(body, v.get_name()->get_location());
3695 
3696     ZORBA_ASSERT(udf != NULL);
3697     assert(body != NULL);
3698     assert(! (body->get_scripting_detail() & BREAKING_EXPR));
3699 
3700     // Mark the body as non-sequential if the only reason it is marked sequential
3701     // is because it contains exit exprs.
3702     body->set_not_exiting();
3703 
3704     // Check for scripting category inconsistency between the udf declaration
3705     // and its body.
3706     if (udf->isSequential())
3707     {
3708       if (body->is_updating() || theHaveUpdatingExitExprs)
3709       {
3710         RAISE_ERROR(zerr::XSST0002, loc, ERROR_PARAMS(fname));
3711       }
3712 
3713       if (!body->is_sequential())
3714       {
3715         theCCB->theXQueryDiagnostics->add_warning(
3716         NEW_XQUERY_WARNING(zwarn::ZWST0003_FAKE_SEQUENTIAL_FUNCTION,
3717                            WARN_PARAMS(fname),
3718                            WARN_LOC(loc)));
3719       }
3720     }
3721     else if (udf->isUpdating())
3722     {
3723       if (body->is_sequential() || theHaveSequentialExitExprs)
3724       {
3725         RAISE_ERROR(zerr::XSST0003, loc, ERROR_PARAMS(fname));
3726       }
3727 
3728       if (!body->is_updating_or_vacuous())
3729       {
3730         RAISE_ERROR(err::XUST0002, loc, ERROR_PARAMS(ZED(XUST0002_UDF_2), fname));
3731       }
3732     }
3733     else if (body->is_sequential() || theHaveSequentialExitExprs)
3734     {
3735       RAISE_ERROR(zerr::XSST0004, loc, ERROR_PARAMS(fname));
3736     }
3737     else if (body->is_updating() || theHaveUpdatingExitExprs)
3738     {
3739       RAISE_ERROR(err::XUST0001, loc, ERROR_PARAMS(ZED(XUST0001_UDF_2), fname));
3740     }
3741 
3742     // sequential udfs are implicitly declared as non-deterministic (even if
3743     // they are actuall deterministic). We do this to avoid having to declare
3744     // a udf as both sequential and non-deterministic. It is OK to do this,
3745     // because the optimization constraints imposed by sequential are a superset
3746     // of those imposed by non-deterministic.
3747     if (udf->isSequential())
3748       udf->setDeterministic(false);
3749 
3750     // If function has any params, they have been wraped in a flwor expr. Set the
3751     // return clause of the flwor to the body expr of the function, and then make
3752     // this flwor be the actual body of the function.
3753     std::vector<var_expr*> args;
3754     if (numParams > 0)
3755     {
3756       flwor_expr* flwor = dynamic_cast<flwor_expr*>(pop_nodestack());
3757       ZORBA_ASSERT(flwor != NULL);
3758 
3759       for (csize i = 0; i < numParams; ++i)
3760       {
3761         const let_clause* lc = dynamic_cast<const let_clause*>(flwor->get_clause(i));
3762         var_expr* argVar = dynamic_cast<var_expr*>(lc->get_expr());
3763         ZORBA_ASSERT(argVar != NULL);
3764         args.push_back(argVar);
3765       }
3766 
3767       flwor->set_return_expr(body);
3768       body = flwor;
3769 
3770       udf->setArgVars(args);
3771     }
3772 
3773     if (udf->isExiting())
3774     {
3775       body = theExprManager->create_exit_catcher_expr(theRootSctx, loc, body, theExitExprs);
3776     }
3777 
3778     // Wrap the UDF body to the type-related expr that enforce the declared
3779     // return type.
3780     xqtref_t returnType = udf->getSignature().returnType();
3781 
3782     if (TypeOps::is_builtin_simple(CTX_TM, *returnType))
3783     {
3784       body = wrap_in_type_promotion(body,
3785                                     returnType,
3786                                     PromoteIterator::FUNC_RETURN,
3787                                     udf->getName());
3788 
3789       body->set_loc(v.get_return_type()->get_location());
3790     }
3791     else
3792     {
3793       body = wrap_in_type_match(body,
3794                                 returnType,
3795                                 loc,
3796                                 TreatIterator::FUNC_RETURN,
3797                                 udf->getName());
3798     }
3799 
3800     udf->setBody(body);
3801 
3802     if (theCCB->theConfig.translate_cb != NULL)
3803       theCCB->theConfig.translate_cb(&*body, fname.str());
3804   }
3805   else
3806   {
3807     // The flwor expr representing the params is created even for external
3808     // functions. But in this case, it is not really needed. We must still
3809     // pop it from the node stack, but then we just discard it.
3810     if (numParams > 0)
3811     {
3812       flwor_expr* flwor = dynamic_cast<flwor_expr*>(pop_nodestack());
3813       ZORBA_ASSERT(flwor != NULL);
3814     }
3815   }
3816 
3817   pop_scope();
3818 }
3819 
3820 
3821 /*******************************************************************************
3822   ParamList ::= Param ("," Param)*
3823 ********************************************************************************/
begin_visit(const ParamList & v)3824 void* begin_visit(const ParamList& v)
3825 {
3826   TRACE_VISIT();
3827 
3828   if (v.size() > 0)
3829   {
3830     flwor_expr* flwor = theExprManager->create_flwor_expr(theRootSctx, loc, false);
3831     push_nodestack(flwor);
3832   }
3833   return no_state;
3834 }
3835 
3836 
end_visit(const ParamList & v,void *)3837 void end_visit(const ParamList& v, void* /*visit_state*/)
3838 {
3839   TRACE_VISIT_OUT();
3840 }
3841 
3842 
3843 /*******************************************************************************
3844   Param ::= "$" QName TypeDeclaration?
3845 ********************************************************************************/
begin_visit(const Param & v)3846 void* begin_visit(const Param& v)
3847 {
3848   TRACE_VISIT();
3849   return no_state;
3850 }
3851 
3852 
end_visit(const Param & v,void *)3853 void end_visit(const Param& v, void* /*visit_state*/)
3854 {
3855   TRACE_VISIT_OUT();
3856 
3857   flwor_expr* flwor = static_cast<flwor_expr*> (theNodeStack.top());
3858   ZORBA_ASSERT(flwor != NULL);
3859 
3860   store::Item_t qnameItem;
3861   expand_no_default_qname(qnameItem, v.get_name(), loc);
3862 
3863   var_expr* arg_var = create_var(loc, qnameItem, var_expr::arg_var);
3864   var_expr* subst_var = bind_var(loc, qnameItem, var_expr::let_var);
3865 
3866   let_clause* lc = wrap_in_letclause(&*arg_var, subst_var);
3867 
3868   // theCurrentPrologVFDecl might be null in case of inline functions
3869   // inline functions currently can't be sequential anyway
3870   // hence, we can always lazy evaluation
3871   if (inUDFBody())
3872   {
3873     //lc->setLazyEval(!f->isSequential());
3874 
3875     const user_function* udf =
3876     static_cast<const user_function*>(theCurrentPrologVFDecl.getFunction());
3877 
3878     arg_var->set_param_pos(flwor->num_clauses());
3879     arg_var->set_udf(udf);
3880   }
3881   else
3882   {
3883     //lc->setLazyEval(true);
3884   }
3885 
3886   flwor->add_clause(lc);
3887 
3888   // Set the decalred type of the arg and let vars. Note: we do this after
3889   // creating the let clause, so the let clause itself does not do any type
3890   // checking. Type checking will be done by other means before the args
3891   // are bound to the params.
3892   if (v.get_typedecl() != NULL)
3893   {
3894     arg_var->set_type(pop_tstack());
3895     subst_var->set_type(arg_var->get_type());
3896   }
3897 }
3898 
3899 
3900 /*******************************************************************************
3901 
3902   Global declarations:
3903   --------------------
3904 
3905   AnnotatedDecl ::= "declare" Annotation* (VarDecl | FunctionDecl)
3906 
3907   Annotation ::= "%" EQName ("(" Literal ("," Literal)* ")")?
3908 
3909   VarDecl ::= variable" "$" VarName TypeDeclaration?
3910               ((":=" VarValue) | ("external" (":=" VarDefaultValue)?))
3911 
3912   VarValue ::= ExprSingle
3913 
3914   VarDefaultValue ::= ExprSingle
3915 
3916   Note: The ExprSingle in VarValue and VarDefaultValue must be a simple expr.
3917 
3918   Note: the applicable annotations are private vs public, and assignable vs
3919   non-assignable.
3920 ********************************************************************************/
begin_visit(const GlobalVarDecl & v)3921 void* begin_visit(const GlobalVarDecl& v)
3922 {
3923   TRACE_VISIT();
3924 
3925   store::Item_t qnameItem;
3926   expand_no_default_qname(qnameItem, v.get_var_name(), loc);
3927 
3928   var_expr* ve = NULL;
3929 
3930   if (theSctx->xquery_version() >= StaticContextConsts::xquery_version_3_0)
3931   {
3932     ve = lookup_var(qnameItem, loc, err::XPST0008);
3933 
3934     assert(ve);
3935   }
3936   else
3937   {
3938     ve = create_var(loc, qnameItem, var_expr::prolog_var);
3939 
3940     if (v.is_extern())
3941       ve->set_external(true);
3942   }
3943 
3944   thePrologGraph.addVarVertex(ve);
3945   theCurrentPrologVFDecl = PrologGraphVertex(ve);
3946 
3947   push_nodestack(ve);
3948 
3949   return no_state;
3950 }
3951 
3952 
end_visit(const GlobalVarDecl & v,void *)3953 void end_visit(const GlobalVarDecl& v, void* /*visit_state*/)
3954 {
3955   TRACE_VISIT_OUT();
3956 
3957   theCurrentPrologVFDecl.setNull();
3958 
3959   expr* initExpr = (v.get_binding_expr() == NULL ? NULL : pop_nodestack());
3960 
3961   var_expr* ve = dynamic_cast<var_expr*>(pop_nodestack());
3962 
3963   if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
3964   {
3965     // All vars declared in a module must be in the same namespace as the module
3966     if (! theModuleNamespace.empty() &&
3967         ve->get_name()->getNamespace() != theModuleNamespace)
3968     {
3969       RAISE_ERROR(err::XQST0048, loc, ERROR_PARAMS(ve->get_name()->getStringValue()));
3970     }
3971 
3972     ve->set_mutable(false);
3973 
3974     theAnnotations = NULL;
3975 
3976     // Put a mapping between the var name and the var_expr in the local sctx.
3977     // Raise error if var name exists already in local sctx obj.
3978     bind_var(ve, theSctx);
3979 
3980     // Make sure that there is no other prolog var with the same name in any of
3981     // modules translated so far.
3982     bind_var(ve, theModulesInfo->globalSctx.get());
3983 
3984     // If this is a library module, register the var in the exported sctx as well.
3985     if (export_sctx != NULL)
3986       bind_var(ve, export_sctx);
3987   }
3988 
3989   xqtref_t declaredType;
3990   if (v.get_var_type() != NULL)
3991   {
3992     declaredType = pop_tstack();
3993     ve->set_type(declaredType);
3994   }
3995 
3996   // Make sure the initExpr is a simple expr.
3997   if (initExpr != NULL)
3998   {
3999     expr::checkSimpleExpr(initExpr);
4000     ve->set_has_initializer(true);
4001 
4002     if (!ve->is_mutable())
4003     {
4004       xqtref_t derivedType = initExpr->get_return_type();
4005 
4006       if (declaredType == NULL)
4007       {
4008         ve->set_type(initExpr->get_return_type());
4009       }
4010     }
4011   }
4012 
4013 #ifdef ZORBA_WITH_DEBUGGER
4014   if (initExpr != NULL && theCCB->theDebuggerCommons != NULL)
4015   {
4016     QueryLoc lExpandedLocation =
4017     expandQueryLoc(v.get_var_name()->get_location(), initExpr->get_loc());
4018 
4019     wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true);
4020   }
4021 #endif
4022 
4023   // The ve and its associated intExpr will be put into var_decl_expr that
4024   // will creaated by the wrap_in_globalvar_assign() method when it is called
4025   // at the end of the translation of each module.
4026   thePrologVars.push_back(GlobalBinding(ve, initExpr, v.is_extern()));
4027 }
4028 
4029 
4030 /*******************************************************************************
4031   AnnotationList := Annotation*
4032 
4033   Annotation ::= "%" EQName  ("(" Literal  ("," Literal)* ")")?
4034 ********************************************************************************/
4035 
begin_visit(const AnnotationListParsenode & v)4036 void* begin_visit(const AnnotationListParsenode& v)
4037 {
4038   TRACE_VISIT();
4039 
4040   assert(theAnnotations == NULL);
4041 
4042   theAnnotations = new AnnotationList();
4043 
4044   return no_state;
4045 }
4046 
4047 
end_visit(const AnnotationListParsenode & v,void *)4048 void end_visit(const AnnotationListParsenode& v, void* /*visit_state*/)
4049 {
4050   TRACE_VISIT_OUT();
4051 
4052   // detect duplicates and conflicting declarations
4053   theAnnotations->checkConflictingDeclarations(loc);
4054 }
4055 
4056 
begin_visit(const AnnotationParsenode & v)4057 void* begin_visit(const AnnotationParsenode& v)
4058 {
4059   TRACE_VISIT();
4060 
4061   return no_state;
4062 }
4063 
end_visit(const AnnotationParsenode & v,void *)4064 void end_visit(const AnnotationParsenode& v, void* /*visit_state*/)
4065 {
4066   TRACE_VISIT_OUT();
4067 
4068   //bool recognised = false;
4069 
4070   store::Item_t lExpandedQName;
4071   expand_function_qname(lExpandedQName, v.get_qname(), loc);
4072 
4073   zstring annotNS = lExpandedQName->getNamespace();
4074 
4075   if (annotNS == static_context::W3C_XML_NS ||
4076       annotNS == XML_SCHEMA_NS ||
4077       annotNS == XSI_NS ||
4078       annotNS == static_context::W3C_FN_NS ||
4079       annotNS == XQUERY_MATH_FN_NS ||
4080       annotNS == ZORBA_ANNOTATIONS_NS)
4081   {
4082     if (AnnotationInternal::lookup(lExpandedQName) == AnnotationInternal::zann_end)
4083     {
4084       RAISE_ERROR(err::XQST0045, loc,
4085       ERROR_PARAMS( "%" + ("\"" + lExpandedQName->getNamespace() + "\""
4086                     + ":" + lExpandedQName->getLocalName())));
4087     }
4088 
4089     //recognised = true;
4090   }
4091 
4092   std::vector<const_expr*> lLiterals;
4093 
4094   if (v.get_literals())
4095   {
4096     std::vector<rchandle<exprnode> >::const_iterator lIter;
4097 
4098     for (lIter = v.get_literals()->begin();
4099          lIter != v.get_literals()->end();
4100          ++lIter)
4101     {
4102       const_expr* lLiteral = dynamic_cast<const_expr*>(pop_nodestack());
4103       lLiterals.insert(lLiterals.begin(), lLiteral);
4104     }
4105   }
4106 
4107   //if (recognised)
4108     theAnnotations->push_back(lExpandedQName, lLiterals);
4109 }
4110 
4111 
begin_visit(const AnnotationLiteralListParsenode & v)4112 void* begin_visit(const AnnotationLiteralListParsenode& v)
4113 {
4114   TRACE_VISIT();
4115   return no_state;
4116 }
4117 
end_visit(const AnnotationLiteralListParsenode & v,void *)4118 void end_visit(const AnnotationLiteralListParsenode& v, void* /*visit_state*/)
4119 {
4120   TRACE_VISIT_OUT();
4121 }
4122 
4123 
4124 
4125 /*******************************************************************************
4126   ContextItemDecl ::= "declare" "context" "item" ("as" ItemType)?
4127                       ((":=" VarValue) |
4128                       ("external" (":=" VarDefaultValue)?))
4129 ********************************************************************************/
begin_visit(const CtxItemDecl & v)4130 void* begin_visit(const CtxItemDecl& v)
4131 {
4132   TRACE_VISIT();
4133 
4134   if (theSctx->xquery_version() <= StaticContextConsts::xquery_version_1_0)
4135     RAISE_ERROR(err::XPST0003, loc,
4136     ERROR_PARAMS(ZED(XPST0003_XQueryVersionAtLeast30_2), theSctx->xquery_version()));
4137 
4138   theHaveContextItemDecl = true;
4139 
4140   return no_state;
4141 }
4142 
end_visit(const CtxItemDecl & v,void *)4143 void end_visit(const CtxItemDecl& v, void* /*visit_state*/)
4144 {
4145   TRACE_VISIT_OUT();
4146 
4147   expr* initExpr = NULL;
4148   if (v.get_expr() != NULL)
4149     initExpr = pop_nodestack();
4150 
4151   xqtref_t type;
4152 
4153   if (v.get_type() != NULL)
4154   {
4155     type = pop_tstack();
4156     theSctx->set_context_item_type(type, loc);
4157   }
4158   else
4159   {
4160     type = theSctx->get_context_item_type();
4161     assert(type != NULL);
4162   }
4163 
4164   var_expr* var = NULL;
4165 
4166   if (inLibraryModule())
4167   {
4168     var = bind_var(loc, DOT_VARNAME, var_expr::prolog_var, type);
4169   }
4170   else
4171   {
4172     var = lookup_ctx_var(DOT_VARNAME, loc);
4173     assert(var);
4174   }
4175 
4176   var->set_external(v.is_external());
4177   var->set_type(type);
4178 
4179   GlobalBinding b(var, initExpr, true);
4180   declare_var(b, theModulesInfo->theInitExprs);
4181 }
4182 
4183 
4184 /*******************************************************************************
4185   OptionDecl ::= DECLARE_OPTION  QNAME  STRING_LITERAL
4186 ********************************************************************************/
begin_visit(const OptionDecl & v)4187 void* begin_visit(const OptionDecl& v)
4188 {
4189   TRACE_VISIT();
4190 
4191   // Actual binding of options was already done at VFO_DeclList time; here we
4192   // take actions based on certain specific options.
4193 
4194   // TODO probably we should have some kind of option-callback mechanism,
4195   // rather than processing all built-in Zorba options here
4196   //store::Item_t qnameItem;
4197   //zstring value = v.get_val().str();
4198 
4199   //expand_no_default_qname(qnameItem, v.get_qname(), loc);
4200 
4201   return no_state;
4202 }
4203 
end_visit(const OptionDecl & v,void *)4204 void end_visit(const OptionDecl& v, void* /*visit_state*/)
4205 {
4206   TRACE_VISIT_OUT();
4207 }
4208 
4209 
4210 /*******************************************************************************
4211   [*] CollectionDecl ::= "declare" Annotation* "collection" QName
4212                          ("as" CollectionTypeDecl)?
4213 
4214   [*] CollectionTypeDecl ::= KindTest OccurenceIndicator?
4215 ********************************************************************************/
begin_visit(const CollectionDecl & v)4216 void* begin_visit(const CollectionDecl& v)
4217 {
4218   TRACE_VISIT();
4219 
4220   if ( !theSctx->is_feature_set(feature::ddl) )
4221   {
4222     RAISE_ERROR(zerr::ZXQP0050_FEATURE_NOT_AVAILABLE, loc,
4223     ERROR_PARAMS("data-definition (ddl)"));
4224   }
4225 
4226   return no_state;
4227 }
4228 
end_visit(const CollectionDecl & v,void *)4229 void end_visit(const CollectionDecl& v, void* /*visit_state*/)
4230 {
4231   TRACE_VISIT_OUT();
4232 
4233   TypeManager* tm = CTX_TM;
4234 
4235   const QName* lName = v.getName();
4236 
4237   // a collection declaration must allways be in a library module
4238   if (!inLibraryModule())
4239   {
4240     RAISE_ERROR(zerr::ZDST0003_COLLECTION_DECL_IN_MAIN_MODULE, loc,
4241     ERROR_PARAMS(lName->get_qname()));
4242   }
4243 
4244   // Expand the collection qname (error is raised if qname resolution fails).
4245   store::Item_t lExpandedQName;
4246   expand_function_qname(lExpandedQName, lName, lName->get_location());
4247 
4248   if (lExpandedQName->getNamespace() != theModuleNamespace)
4249   {
4250     RAISE_ERROR(zerr::ZDST0007_COLLECTION_DECL_IN_FOREIGN_MODULE, loc,
4251     ERROR_PARAMS(lName->get_qname()));
4252   }
4253 
4254   // Get the static type of the root nodes
4255   xqtref_t lNodeType;
4256   xqtref_t lCollectionType;
4257   TypeConstants::quantifier_t quant;
4258   if (v.getType() == 0)
4259   {
4260     lNodeType = theRTM.DOCUMENT_UNTYPED_TYPE_ONE;
4261     lCollectionType = theRTM.DOCUMENT_UNTYPED_TYPE_STAR;
4262     quant = TypeConstants::QUANT_STAR;
4263   }
4264   else
4265   {
4266     lCollectionType = pop_tstack();
4267     lNodeType = TypeOps::prime_type(tm, *lCollectionType);
4268     quant = lCollectionType->get_quantifier();
4269   }
4270 
4271   AnnotationListParsenode* lAnns = v.get_annotations();
4272   if (lAnns)
4273   {
4274     lAnns->accept(*this);
4275   }
4276 
4277   if ( !theAnnotations )
4278   {
4279     theAnnotations = new AnnotationList();
4280   }
4281 
4282   // compute (redundant) enum values and assign
4283   // default annotations if no annotation for a group
4284   // of annotations exists:
4285   // update mode: mutable
4286   // order mode: unordered
4287   // node modifier: mutable nodes
4288   StaticContextConsts::declaration_property_t lUpdateMode;
4289   StaticContextConsts::declaration_property_t lOrderMode;
4290   StaticContextConsts::node_modifier_t lNodeModifier;
4291 
4292   std::vector<const_expr* > lLiterals;
4293   if (ZANN_CONTAINS(zann_queue))
4294   {
4295     lUpdateMode = StaticContextConsts::decl_queue;
4296   }
4297   else if (ZANN_CONTAINS(zann_append_only))
4298   {
4299     lUpdateMode = StaticContextConsts::decl_append_only;
4300   }
4301   else if (ZANN_CONTAINS(zann_const))
4302   {
4303     lUpdateMode = StaticContextConsts::decl_const;
4304   }
4305   else if (ZANN_CONTAINS(zann_mutable))
4306   {
4307     lUpdateMode = StaticContextConsts::decl_mutable;
4308   }
4309   else
4310   {
4311     theAnnotations->
4312     push_back(AnnotationInternal::lookup(AnnotationInternal::zann_mutable),
4313               lLiterals);
4314 
4315     lUpdateMode = StaticContextConsts::decl_mutable;
4316   }
4317 
4318   if (ZANN_CONTAINS(zann_ordered))
4319   {
4320     lOrderMode = StaticContextConsts::decl_ordered;
4321   }
4322   else if (ZANN_CONTAINS(zann_unordered))
4323   {
4324     lOrderMode = StaticContextConsts::decl_unordered;
4325   }
4326   else
4327   {
4328     theAnnotations->
4329     push_back(AnnotationInternal::lookup(AnnotationInternal::zann_unordered),
4330               lLiterals);
4331 
4332     lOrderMode = StaticContextConsts::decl_unordered;
4333   }
4334 
4335   if (ZANN_CONTAINS(zann_read_only_nodes))
4336   {
4337     lNodeModifier = StaticContextConsts::read_only;
4338   }
4339   else if (ZANN_CONTAINS(zann_mutable_nodes))
4340   {
4341     lNodeModifier = StaticContextConsts::mutable_node;
4342   }
4343   else
4344   {
4345     theAnnotations->
4346     push_back(AnnotationInternal::lookup(AnnotationInternal::zann_mutable_nodes),
4347               lLiterals);
4348 
4349     lNodeModifier = StaticContextConsts::mutable_node;
4350   }
4351 
4352   // Create the collection object and register it in the static context
4353   StaticallyKnownCollection_t lColl = new StaticallyKnownCollection(
4354                                             lExpandedQName,
4355                                             theAnnotations,
4356                                             lNodeType,
4357                                             lCollectionType,
4358                                             lUpdateMode,
4359                                             lOrderMode,
4360                                             lNodeModifier);
4361 
4362   theAnnotations = NULL; // important to reset
4363 
4364   theSctx->bind_collection(lColl, loc);
4365 
4366   assert(export_sctx);
4367   export_sctx->bind_collection(lColl, loc);
4368 
4369   // Create an IC to check that the cardinality of the collection matches its
4370   // declared type.
4371   if (quant != TypeConstants::QUANT_STAR)
4372   {
4373     // TODO
4374   }
4375 }
4376 
4377 
4378 /***************************************************************************//**
4379   IndexDecl ::= "declare" Annotation* "index" QName
4380                 "on" "nodes" IndexDomainExpr "by" IndexKeyList
4381 
4382   IndexDomainExpr := PathExpr
4383 
4384   IndexKeyList := IndexKeySpec+
4385 
4386   IndexKeySpec := PathExpr (TypeDeclaration)? ("collation" UriLiteral)?
4387 
4388   Translation of an index declaration involves the creation and setting-up of
4389   a IndexDecl obj (see compiler/indexing/value_index.h) and the creation in
4390   the current sctx (which is the root sctx of the current module) of a binding
4391   between the index uri and this IndexDecl obj.
4392 ********************************************************************************/
begin_visit(const AST_IndexDecl & v)4393 void* begin_visit(const AST_IndexDecl& v)
4394 {
4395   TRACE_VISIT();
4396 
4397   if ( !theSctx->is_feature_set(feature::ddl) )
4398   {
4399     RAISE_ERROR(zerr::ZXQP0050_FEATURE_NOT_AVAILABLE, v.get_location(),
4400     ERROR_PARAMS("data-definition (ddl)"));
4401   }
4402 
4403   const QName* qname = v.getName();
4404 
4405   if (!inLibraryModule())
4406   {
4407     RAISE_ERROR(zerr::ZDST0023_INDEX_DECL_IN_MAIN_MODULE, loc,
4408     ERROR_PARAMS(qname->get_qname()));
4409   }
4410 
4411   // Expand the index qname (error is raised if qname resolution fails).
4412   store::Item_t qnameItem;
4413   expand_function_qname(qnameItem, qname, qname->get_location());
4414 
4415   if (qnameItem->getNamespace() != theModuleNamespace)
4416   {
4417     RAISE_ERROR(zerr::ZDST0036_INDEX_DECL_IN_FOREIGN_MODULE, loc,
4418     ERROR_PARAMS(qname->get_qname()));
4419   }
4420 
4421   IndexDecl_t index = new IndexDecl(theSctx, theCCB,  loc, qnameItem);
4422   index->setGeneral(false);
4423   index->setUnique(false);
4424   index->setMethod(IndexDecl::HASH);
4425   index->setMaintenanceMode(IndexDecl::MANUAL);
4426 
4427   AnnotationListParsenode* lAnns = v.get_annotations();
4428   if (lAnns)
4429   {
4430     lAnns->accept(*this);
4431   }
4432 
4433   if (theAnnotations)
4434   {
4435     if (ZANN_CONTAINS(zann_general_equality) ||
4436         ZANN_CONTAINS(zann_general_range))
4437     {
4438       index->setGeneral(true);
4439     }
4440     if (ZANN_CONTAINS(zann_general_range) ||
4441         ZANN_CONTAINS(zann_value_range))
4442     {
4443       index->setMethod(IndexDecl::TREE);
4444     }
4445     if (ZANN_CONTAINS(zann_unique))
4446     {
4447       index->setUnique(true);
4448     }
4449     if (ZANN_CONTAINS(zann_automatic))
4450     {
4451       index->setMaintenanceMode(IndexDecl::REBUILD);
4452     }
4453   }
4454 
4455   theAnnotations = NULL;
4456 
4457   theIndexDecl = index;
4458   theIsInIndexDomain = true;
4459 
4460   return no_state;
4461 }
4462 
end_visit(const AST_IndexDecl & v,void *)4463 void end_visit(const AST_IndexDecl& v, void* /*visit_state*/)
4464 {
4465   TRACE_VISIT_OUT();
4466 
4467   IndexDecl_t index = theIndexDecl;
4468   theIndexDecl = NULL;
4469 
4470   index->analyze(theCCB);
4471 
4472   // Register the index in the sctx of the current module. Raise error if such
4473   // a binding exists already in the sctx.
4474   theSctx->bind_index(index, loc);
4475 
4476   // If this is a library module, register the index in the exported sctx as well.
4477   if (export_sctx != NULL)
4478     export_sctx->bind_index(index, loc);
4479 }
4480 
4481 
4482 /***************************************************************************//**
4483   IndexKeyList ::= IndexKeySpec (COMMA IndexKeySpec)*
4484 ********************************************************************************/
begin_visit(const IndexKeyList & v)4485 void* begin_visit(const IndexKeyList& v)
4486 {
4487   TRACE_VISIT();
4488 
4489   theIsInIndexDomain = false;
4490 
4491   IndexDecl* index = theIndexDecl;
4492 
4493   expr* domainExpr = pop_nodestack();
4494 
4495   if (!domainExpr->is_simple())
4496   {
4497     RAISE_ERROR(zerr::ZDST0033_INDEX_NON_SIMPLE_EXPR, domainExpr->get_loc(),
4498     ERROR_PARAMS(index->getName()->getStringValue()));
4499   }
4500 
4501 #ifdef ZORBA_WITH_JSON
4502   domainExpr = wrap_in_type_match(domainExpr,
4503                                   theRTM.STRUCTURED_ITEM_TYPE_STAR,
4504                                   loc,
4505                                   TreatIterator::INDEX_DOMAIN,
4506                                   index->getName());
4507 #else
4508   domainExpr = wrap_in_type_match(domainExpr,
4509                                   theRTM.ANY_NODE_TYPE_STAR,
4510                                   loc,
4511                                   TreatIterator::INDEX_DOMAIN,
4512                                   index->getName());
4513 #endif
4514 
4515   // For general indexes, the domain expression must not return duplicate nodes.
4516   // To see why, consider the following examples:
4517   //
4518   // for $book in collection("books")
4519   // where $book//price > 10
4520   // return $book
4521   //
4522   // An index to optimize the above query would have collection("books") as
4523   // its domain expr, and .//price as its key expr. In this case, the donaim
4524   // expr does not return duplicate nodes, but if books are allowed to have
4525   // multiple  prices, then probing the index for, say prices > 10, may return
4526   // a book B multiple times, if B has more than one price that is > 10. So,
4527   // to get the same result as with no index use, the probe function must do
4528   // duplicate elimination.
4529   //
4530   // Now, consider the following query:
4531   //
4532   // let $xBook := <book>....</book>
4533   // for $book in ($xBook, $xBook, $xBook)
4534   // where $book//price > 10
4535   // return $book
4536   //
4537   // If $xBook has a price > 10, the result of this query will be $xBook 3
4538   // times. If we were using an index for this query, and the probe does
4539   // duplicate as required by the previous example, we would get $xBook only
4540   // once.
4541   //
4542   // So, to decide whether the probe function should do duplicate elimination
4543   // or not, we must be able to distinguish between the above 2 cases. This
4544   // is not easy/possible, so we decide to err in favor of the first example
4545   // and not allow the domain expr to return duplicate nodes.
4546   if (index->isGeneral())
4547   {
4548     domainExpr = theExprManager->create_fo_expr(theRootSctx,
4549                              domainExpr->get_loc(),
4550                              GET_BUILTIN_FUNCTION(OP_CHECK_DISTINCT_NODES_1),
4551                              domainExpr);
4552   }
4553 
4554   std::string msg = "Domain expr for index " + index->getName()->getStringValue().str();
4555 
4556   if (theCCB->theConfig.translate_cb != NULL)
4557     theCCB->theConfig.translate_cb(domainExpr, msg);
4558 
4559   // Optimize the domain expr. We do this even if the optimizer is off.
4560   // if (theCCB->theConfig.opt_level == CompilerCB::config::O1)
4561   {
4562     RewriterContext rCtx(theCCB, domainExpr, NULL, msg, false);
4563     GENV_COMPILERSUBSYS.getDefaultOptimizingRewriter()->rewrite(rCtx);
4564     domainExpr = rCtx.getRoot();
4565 
4566     if (theCCB->theConfig.optimize_cb != NULL)
4567       theCCB->theConfig.optimize_cb(&*domainExpr, msg);
4568   }
4569 
4570   index->setDomainExpr(domainExpr);
4571 
4572   push_scope();
4573 
4574   index->setDomainVariable(bind_var(loc, DOT_VARNAME, var_expr::for_var));
4575 
4576   index->setDomainPositionVariable(bind_var(loc,
4577                                             DOT_POS_VARNAME,
4578                                             var_expr::pos_var));
4579 
4580   return no_state;
4581 }
4582 
end_visit(const IndexKeyList & v,void *)4583 void end_visit(const IndexKeyList& v, void* /*visit_state*/)
4584 {
4585   TRACE_VISIT_OUT();
4586 
4587   TypeManager* tm = CTX_TM;
4588 
4589   ulong numColumns = v.size();
4590 
4591   std::vector<expr*> keyExprs(numColumns);
4592   std::vector<xqtref_t> keyTypes(numColumns);
4593   std::vector<OrderModifier> keyModifiers(numColumns);
4594 
4595   IndexDecl* index = theIndexDecl;
4596 
4597   for (long i = numColumns - 1; i >= 0; --i)
4598   {
4599     const IndexKeySpec* keySpec = v.getKeySpec(i);
4600     const OrderCollationSpec* collationSpec = keySpec->getCollationSpec();
4601 
4602     const QueryLoc& kloc = keySpec->get_location();
4603 
4604     expr* keyExpr = pop_nodestack();
4605 
4606     if (!keyExpr->is_simple())
4607     {
4608       RAISE_ERROR(zerr::ZDST0033_INDEX_NON_SIMPLE_EXPR, keyExpr->get_loc(),
4609       ERROR_PARAMS(index->getName()->getStringValue()));
4610     }
4611 
4612     keyExpr = wrap_in_atomization(keyExpr);
4613 
4614     xqtref_t type;
4615     xqtref_t ptype;
4616 
4617     if (keySpec->getType() == NULL)
4618     {
4619       if (!index->isGeneral())
4620       {
4621         RAISE_ERROR(zerr::ZDST0027_INDEX_BAD_KEY_TYPE, kloc,
4622         ERROR_PARAMS(index->getName()->getStringValue()));
4623       }
4624     }
4625     else
4626     {
4627       type = pop_tstack();
4628       ptype = TypeOps::prime_type(tm, *type);
4629       TypeConstants::quantifier_t quant = type->get_quantifier();
4630 
4631       if (!TypeOps::is_subtype(tm, *ptype, *theRTM.ANY_ATOMIC_TYPE_STAR, kloc))
4632       {
4633         RAISE_ERROR(zerr::ZDST0027_INDEX_BAD_KEY_TYPE, kloc,
4634         ERROR_PARAMS(index->getName()->getStringValue()));
4635       }
4636 
4637       if (!index->isGeneral() &&
4638           (TypeOps::is_equal(tm, *ptype, *theRTM.ANY_ATOMIC_TYPE_ONE, kloc) ||
4639            TypeOps::is_equal(tm, *ptype, *theRTM.UNTYPED_ATOMIC_TYPE_ONE, kloc)))
4640       {
4641         RAISE_ERROR(zerr::ZDST0027_INDEX_BAD_KEY_TYPE, kloc,
4642         ERROR_PARAMS(index->getName()->getStringValue()));
4643       }
4644 
4645       if (!index->isGeneral() &&
4646           quant != TypeConstants::QUANT_ONE &&
4647           quant != TypeConstants::QUANT_QUESTION)
4648       {
4649         RAISE_ERROR(zerr::ZDST0027_INDEX_BAD_KEY_TYPE, kloc,
4650         ERROR_PARAMS(index->getName()->getStringValue()));
4651       }
4652 
4653       if (index->getMethod() == IndexDecl::TREE &&
4654           (TypeOps::is_subtype(tm, *ptype, *theRTM.UNTYPED_ATOMIC_TYPE_ONE, kloc) ||
4655            TypeOps::is_subtype(tm, *ptype, *theRTM.QNAME_TYPE_ONE, kloc) ||
4656            TypeOps::is_subtype(tm, *ptype, *theRTM.NOTATION_TYPE_ONE, kloc) ||
4657            TypeOps::is_subtype(tm, *ptype, *theRTM.BASE64BINARY_TYPE_ONE, kloc) ||
4658            TypeOps::is_subtype(tm, *ptype, *theRTM.HEXBINARY_TYPE_ONE, kloc) ||
4659            TypeOps::is_subtype(tm, *ptype, *theRTM.GYEAR_MONTH_TYPE_ONE, kloc) ||
4660            TypeOps::is_subtype(tm, *ptype, *theRTM.GYEAR_TYPE_ONE, kloc) ||
4661            TypeOps::is_subtype(tm, *ptype, *theRTM.GMONTH_TYPE_ONE, kloc) ||
4662            TypeOps::is_subtype(tm, *ptype, *theRTM.GMONTH_DAY_TYPE_ONE, kloc) ||
4663            TypeOps::is_subtype(tm, *ptype, *theRTM.GDAY_TYPE_ONE, kloc)))
4664       {
4665         RAISE_ERROR(zerr::ZDST0027_INDEX_BAD_KEY_TYPE, kloc,
4666         ERROR_PARAMS(index->getName()->getStringValue()));
4667       }
4668 
4669       keyExpr = wrap_in_type_match(keyExpr,
4670                                    type,
4671                                    loc,
4672                                    TreatIterator::INDEX_KEY,
4673                                    index->getName());
4674 
4675       keyTypes[i] = ptype->getBaseBuiltinType();
4676     }
4677 
4678     if (index->isGeneral())
4679     {
4680       // Eliminate duplicate key values, as they don't play any role in a
4681       // general comparison predicate.
4682       keyExpr = theExprManager->create_fo_expr(theRootSctx,
4683                             keyExpr->get_loc(),
4684                             GET_BUILTIN_FUNCTION(FN_DISTINCT_VALUES_1),
4685                             keyExpr);
4686     }
4687 
4688     std::string collationUri;
4689 
4690     if (collationSpec != NULL)
4691     {
4692       collationUri = collationSpec->get_uri().str();
4693 
4694       if (! theSctx->is_known_collation(collationUri))
4695         RAISE_ERROR(err::XQST0076, kloc,
4696         ERROR_PARAMS(collationUri));
4697     }
4698     else if (ptype != NULL &&
4699              TypeOps::is_subtype(tm, *ptype, *theRTM.STRING_TYPE_ONE, loc))
4700     {
4701       collationUri = theSctx->get_default_collation(loc);
4702     }
4703 
4704     keyModifiers[i].theAscending = true;
4705     keyModifiers[i].theEmptyLeast = true;
4706     keyModifiers[i].theCollation = collationUri;
4707 
4708     std::ostringstream msg;
4709     msg << "key expr " << i << " for index " << index->getName()->getStringValue();
4710 
4711     if (theCCB->theConfig.translate_cb != NULL)
4712       theCCB->theConfig.translate_cb(keyExpr, msg.str());
4713 
4714     // Optimize the key expr. We do this even if the optimizer is off.
4715     // if (theCCB->theConfig.opt_level == CompilerCB::config::O1)
4716     {
4717       RewriterContext rCtx(theCCB, keyExpr, NULL, msg.str(), false);
4718       GENV_COMPILERSUBSYS.getDefaultOptimizingRewriter()->rewrite(rCtx);
4719       keyExpr = rCtx.getRoot();
4720 
4721       if (theCCB->theConfig.optimize_cb != NULL)
4722         theCCB->theConfig.optimize_cb(&*keyExpr, msg.str());
4723     }
4724 
4725     keyExprs[i] = keyExpr;
4726   }
4727 
4728   index->setKeyExpressions(keyExprs);
4729   index->setKeyTypes(keyTypes);
4730   index->setOrderModifiers(keyModifiers);
4731 
4732   pop_scope();
4733 }
4734 
4735 
4736 /***************************************************************************//**
4737   IndexKeySpec ::= PathExpr TypeDeclaration? ("collation" UriLiteral)?
4738 ********************************************************************************/
begin_visit(const IndexKeySpec & v)4739 void* begin_visit(const IndexKeySpec& v)
4740 {
4741   TRACE_VISIT();
4742   return no_state;
4743 }
4744 
end_visit(const IndexKeySpec & v,void *)4745 void end_visit(const IndexKeySpec& v, void* /*visit_state*/)
4746 {
4747   TRACE_VISIT_OUT();
4748 }
4749 
4750 
4751 /***************************************************************************//**
4752   IntegrityConstraintDecl ::= "declare" "integrity" "constraint"
4753       QName ICType
4754   ICType ::= ICCollSimpleCheck | ICCollUniqueKey | ICCollForeachNode |
4755              ICNodeOfType | ICForeighKey
4756   ICCollSimpleCheck ::= "on" "collection" QName "$" QName "check" ExprSimple
4757   ICCollUniqueKey   ::= "on" "collection" QNAME "$" QName "check" "unique"
4758                         "key" "(" Expr ")"
4759   ICCollForeachNode ::= "on" "collection" QNAME "foreach" "node" "$" QName
4760                         "check" ExprSingle
4761   ICNodeOfType      ::= "on" "node" QName "of""type" KindTest "check" ExprSingle
4762   ICForeighKey      ::= "on" "foreign" "key"
4763                         "from" "collection" QName "node" "$" QName "keys"
4764                            "(" Expr ")"
4765                         "to" "collection" QName "node" "$" QName "keys"
4766                            "(" Expr ")"
4767 
4768   Translation of an integrity constraint declaration involves the creation and
4769   setting-up of a IndexDecl obj (see indexing/value_index.h) and the creation
4770   in the current sctx (which is the root sctx of the current module) of a
4771   binding between the index uri and this IndexDecl obj.
4772 *******************************************************************************/
begin_visit(const IntegrityConstraintDecl & v)4773 void* begin_visit(const IntegrityConstraintDecl& v)
4774 {
4775   TRACE_VISIT();
4776 
4777   if ( !theSctx->is_feature_set(feature::ddl) )
4778   {
4779     throw XQUERY_EXCEPTION(
4780       zerr::ZXQP0050_FEATURE_NOT_AVAILABLE,
4781       ERROR_PARAMS( "data-definition (ddl)" ),
4782       ERROR_LOC( v.get_location() )
4783     );
4784   }
4785 
4786   if (!inLibraryModule())
4787   {
4788     throw XQUERY_EXCEPTION(
4789       zerr::ZDST0044_IC_DECL_IN_MAIN_MODULE,
4790       ERROR_PARAMS( v.getName()->get_qname() ),
4791       ERROR_LOC( loc )
4792     );
4793   }
4794 
4795   push_scope();
4796 
4797   switch( v.getICKind() )
4798   {
4799   case IntegrityConstraintDecl::coll_check_simple:
4800   {
4801     const ICCollSimpleCheck& ic = dynamic_cast<const ICCollSimpleCheck&>(v);
4802     /**********************
4803        declare integrity constraint example:ic1
4804          on collection example:coll1 $x check sum($x/size) le 1000;
4805 
4806        sum( dc:collection(example:coll1)/size ) le 1000
4807 
4808        let $x := dc:collection(xs:QName("example:coll1"))
4809        return sum($x/size) le 1000;
4810     **********************/
4811 
4812     // "example:coll1"
4813     expr* qnameStrExpr = theExprManager->
4814     create_const_expr(theRootSctx, loc, ic.getCollName()->get_qname().str());
4815 
4816     zstring prefixStr = ic.getCollName()->get_prefix();
4817     zstring uriStr;
4818     theSctx->lookup_ns(uriStr, prefixStr, loc);
4819 
4820     expr* uriStrExpr = theExprManager->create_const_expr(theRootSctx, loc, uriStr);
4821 
4822     // fn:QName("uri", "example:coll1")
4823     fo_expr* qnameExpr = theExprManager->
4824     create_fo_expr(theRootSctx,
4825                    loc,
4826                    GET_BUILTIN_FUNCTION(FN_QNAME_2),
4827                    uriStrExpr,
4828                    qnameStrExpr);
4829 
4830     // dc:collection(xs:QName("example:coll1"))
4831     function* fn_collection = GET_BUILTIN_FUNCTION(STATIC_COLLECTIONS_DML_COLLECTION_1);
4832     ZORBA_ASSERT(fn_collection != NULL);
4833     std::vector<expr*> argColl;
4834     argColl.push_back(qnameExpr);
4835 
4836     fo_expr* collExpr = theExprManager->
4837     create_fo_expr(theRootSctx, loc, fn_collection, argColl);
4838 
4839     // $x
4840     const QName* varQName = ic.getCollVarName();
4841     var_expr* varExpr = bind_var(loc, varQName, var_expr::let_var, NULL);
4842 
4843     // let $x := dc:collection(xs:QName("example:coll1"))
4844     let_clause* lc = theExprManager->
4845     create_let_clause(theRootSctx, loc, varExpr, collExpr);
4846 
4847     flwor_expr* flworExpr = theExprManager->create_flwor_expr(theRootSctx, loc, false);
4848     flworExpr->add_clause(lc);
4849     // flworExpr-> return clause to be set in end_visitor
4850 
4851     push_nodestack(flworExpr);
4852   }
4853   break;
4854 
4855   case IntegrityConstraintDecl::coll_check_unique_key:
4856   {
4857     /**********************
4858        declare integrity constraint org:icEmployeesIds
4859          on collection org:employees node $x check unique key $x/@id ;
4860 
4861        let $x := dc:collection( xs:QName("org:employees") )
4862        return
4863          (
4864            every $x_ in $x
4865            satisfies
4866              exists( $x_/@id )
4867          )
4868          and
4869          (  functx:are-distinct-values( $x/@id )  )
4870 
4871       implemented as:
4872        let $x := dc:collection( xs:QName("org:employees") )
4873        return
4874          (
4875            fn:empty(
4876              for $x_ in dc:collection( xs:QName("org:employees") )
4877              where not( exists($x_/@id) )
4878              return true)
4879          )
4880          and
4881          (  count(distinct-values( $x/@id )) = count($x/@id)  )
4882     **********************/
4883 
4884     const ICCollUniqueKeyCheck& ic =
4885       dynamic_cast<const ICCollUniqueKeyCheck&>(v);
4886 
4887     // "org:employees"
4888     expr* qnameStrExpr = theExprManager->create_const_expr(theRootSctx,
4889                                          loc,
4890                                          ic.getCollName()->get_qname().str());
4891 
4892     zstring prefixStr = ic.getCollName()->get_prefix();
4893     zstring uriStr;
4894     theSctx->lookup_ns(uriStr, prefixStr, loc);
4895 
4896     expr* uriStrExpr = theExprManager->create_const_expr(theRootSctx, loc, uriStr);
4897 
4898     // fn:QName("org-uri", "org:employees")
4899     fo_expr* qnameExpr = theExprManager->create_fo_expr(theRootSctx, loc,
4900                                       GET_BUILTIN_FUNCTION(FN_QNAME_2),
4901                                       uriStrExpr, qnameStrExpr);
4902 
4903     // dc:collection(xs:QName("org:employees"))
4904     function* fn_collection = GET_BUILTIN_FUNCTION(STATIC_COLLECTIONS_DML_COLLECTION_1);
4905     ZORBA_ASSERT(fn_collection != NULL);
4906     std::vector<expr*> argColl;
4907     argColl.push_back(qnameExpr);
4908     fo_expr* collExpr = theExprManager->create_fo_expr(theRootSctx, loc, fn_collection, argColl);
4909 
4910     // $x
4911     const QName* varQName = ic.getNodeVarName();
4912     store::Item_t varItem;
4913     expand_no_default_qname(varItem, varQName, varQName->get_location());
4914 
4915     // every $x_ in $x satisfies exists ...
4916     // every is implemented as a flowr expr
4917     push_scope();
4918     flwor_expr* evFlworExpr = theExprManager->create_flwor_expr(theRootSctx, loc, false);
4919     evFlworExpr->set_return_expr(theExprManager->create_const_expr(theRootSctx, loc, true));
4920 
4921     // $x_ in dc:collection( xs:QName("org:employees") )
4922     var_expr* evVarExpr = bind_var(loc,
4923                                     varItem,
4924                                     var_expr::for_var,
4925                                     NULL);
4926 
4927     // maybe make one more collExpr?
4928     evFlworExpr->add_clause(wrap_in_forclause(collExpr, evVarExpr, NULL));
4929 
4930     pop_scope();
4931     // end every
4932 
4933     // let $x := dc:collection(xs:QName("org:employees"))
4934     //   return
4935     var_expr* varExpr = bind_var(loc,
4936                                   varItem,
4937                                   var_expr::let_var,
4938                                   NULL);
4939 
4940     let_clause* letClause = theExprManager->create_let_clause(theRootSctx,
4941                                            loc,
4942                                            varExpr,
4943                                            collExpr);
4944 
4945     flwor_expr* flworExpr = theExprManager->create_flwor_expr(theRootSctx,
4946                                                               loc, false);
4947 
4948 
4949 
4950     flworExpr->add_clause(letClause);
4951     // flworExpr->set_return_expr( andExpr ); done in end_visit
4952 
4953     // push evFlworExpr because where clause must be set
4954     push_nodestack(evFlworExpr);
4955     // push the top expresion
4956     push_nodestack(flworExpr);
4957   }
4958   break;
4959 
4960   case IntegrityConstraintDecl::coll_foreach_node:
4961   {
4962     /**********************
4963        declare integrity constraint org:icTransactionsSale
4964          on collection org:transactions foreach node $x
4965            check $x/sale > 0 ;
4966 
4967        every $x in dc:collection( xs:QName("org:transactions") )
4968        satisfies $x/sale > 0
4969 
4970        implemented as:
4971          fn:empty(
4972            for $x in dc:collection( xs:QName("org:transactions") )
4973            where not( $x/sale > 0 )
4974            return true )
4975     **********************/
4976 
4977     const ICCollForeachNode& ic =
4978       dynamic_cast<const ICCollForeachNode&>(v);
4979 
4980     // "org:transactions"
4981     expr* qnameStrExpr = theExprManager->create_const_expr(theRootSctx, loc,
4982                                          ic.getCollName()->get_qname().str());
4983 
4984     zstring prefixStr = ic.getCollName()->get_prefix();
4985     zstring uriStr;
4986     theSctx->lookup_ns(uriStr, prefixStr, loc);
4987 
4988     expr* uriStrExpr = theExprManager->create_const_expr(theRootSctx, loc, uriStr);
4989 
4990     // fn:QName("org-uri", "org:transactions")
4991     fo_expr* qnameExpr = theExprManager->create_fo_expr(theRootSctx, loc,
4992                                       GET_BUILTIN_FUNCTION(FN_QNAME_2),
4993                                       uriStrExpr, qnameStrExpr);
4994 
4995     // dc:collection(xs:QName("org:transactions"))
4996     function* fn_collection = GET_BUILTIN_FUNCTION(STATIC_COLLECTIONS_DML_COLLECTION_1);
4997     ZORBA_ASSERT(fn_collection != NULL);
4998     std::vector<expr*> argColl;
4999     argColl.push_back(qnameExpr);
5000     fo_expr* collExpr = theExprManager->create_fo_expr(theRootSctx, loc, fn_collection, argColl);
5001 
5002     // every $x_ in $x satisfies exists ...
5003     // every is implemented as a flowr expr
5004     //push_scope();
5005     flwor_expr* evFlworExpr = theExprManager->create_flwor_expr(theRootSctx, loc, false);
5006     evFlworExpr->set_return_expr(theExprManager->create_const_expr(theRootSctx, loc, true));
5007 
5008     // $x
5009     const QName* varQName = ic.getCollVarName();
5010 
5011     // $x_ in dc:collection( xs:QName("org:employees") )
5012     var_expr* evVarExpr = bind_var(loc, varQName, var_expr::for_var, NULL);
5013 
5014     // maybe make one more collExpr?
5015     evFlworExpr->add_clause(wrap_in_forclause(collExpr,
5016                                               evVarExpr,
5017                                               NULL));
5018 
5019     //pop_scope();
5020     // end every
5021     push_nodestack(evFlworExpr);
5022   }
5023   break;
5024 
5025   case IntegrityConstraintDecl::foreign_key:
5026   {
5027     /**********************
5028        declare integrity constraint org:icEmpSalesForeignKey
5029          foreign key
5030            from collection org:transactions node $x key $x//sale/empid
5031            to   collection org:employees node $y key $y/id
5032 
5033        every $x in dc:collection( xs:QName("org:transactions") )
5034        satisfies
5035          some $y in dc:collection( xs:QName("org:employees") )
5036          satisfies $y/id eq $x//sale/empid
5037 
5038        i.e. using flwor impl:
5039          fn:empty(
5040            for $x in dc:collection( xs:QName("org:transactions") )
5041            where not(
5042              fn:exists(
5043                for $y in dc:collection( xs:QName("org:employees") )
5044                where $y/id eq $x//sale/empid
5045                return true) )
5046            return true)
5047     **********************/
5048 
5049     const ICForeignKey& ic = dynamic_cast<const ICForeignKey&>(v);
5050 
5051     // TO part
5052     // "org:employees"
5053     expr* toQnameStrExpr = theExprManager->create_const_expr(theRootSctx, loc,
5054                                            ic.getToCollName()->get_qname().str());
5055     zstring toPrefixStr = ic.getToCollName()->get_prefix();
5056     zstring toUriStr;
5057     theSctx->lookup_ns(toUriStr, toPrefixStr, loc);
5058 
5059     expr* toUriStrExpr = theExprManager->create_const_expr(theRootSctx, loc, toUriStr);
5060 
5061     // xs:QName("org:employees")
5062     fo_expr* toQnameExpr = theExprManager->create_fo_expr(theRootSctx, loc,
5063                                         GET_BUILTIN_FUNCTION(FN_QNAME_2),
5064                                         toUriStrExpr, toQnameStrExpr);
5065 
5066     // dc:collection(xs:QName("org:employees"))
5067     function* toFnCollection = GET_BUILTIN_FUNCTION(STATIC_COLLECTIONS_DML_COLLECTION_1);
5068     ZORBA_ASSERT(toFnCollection != NULL);
5069     std::vector<expr*> toArgColl;
5070     toArgColl.push_back(toQnameExpr);
5071     fo_expr* toCollExpr = theExprManager->create_fo_expr(theRootSctx, loc, toFnCollection,
5072                                        toArgColl);
5073 
5074     // some $y in dc:collection( xs:QName("org:employees") )
5075     // satisfies ... eq ...
5076     // implemented using flowr
5077     flwor_expr* someFlworExpr = theExprManager->create_flwor_expr(theRootSctx, loc, false);
5078     someFlworExpr->set_return_expr(theExprManager->create_const_expr(theRootSctx, loc, true));
5079 
5080     // $y
5081     const QName* toVarQName = ic.getToNodeVarName();
5082     var_expr* toVarExpr = bind_var(loc, toVarQName, var_expr::for_var, NULL);
5083 
5084     // for $y in dc:collection(xs:QName("org:employees"))
5085     someFlworExpr->add_clause(wrap_in_forclause(toCollExpr,
5086                                                 toVarExpr,
5087                                                 NULL));
5088 
5089 
5090     // FROM part
5091     // "org:transactions"
5092     expr* fromQnameStrExpr = theExprManager->create_const_expr(theRootSctx, loc,
5093                                              ic.getFromCollName()->get_qname().str());
5094 
5095     zstring fromPrefixStr = ic.getFromCollName()->get_prefix();
5096     zstring fromUriStr;
5097     theSctx->lookup_ns(fromUriStr, fromPrefixStr, loc);
5098 
5099     expr* fromUriStrExpr = theExprManager->create_const_expr(theRootSctx, loc, fromUriStr);
5100 
5101     // fn:QName("org-uri", "org:transactions")
5102     fo_expr* fromQnameExpr = theExprManager->create_fo_expr(theRootSctx, loc,
5103                                           GET_BUILTIN_FUNCTION(FN_QNAME_2),
5104                                           fromUriStrExpr, fromQnameStrExpr);
5105 
5106     // dc:collection(xs:QName("org:transactions"))
5107     function* fromFnCollection = GET_BUILTIN_FUNCTION(STATIC_COLLECTIONS_DML_COLLECTION_1);
5108     ZORBA_ASSERT(fromFnCollection != NULL);
5109     std::vector<expr*> fromArgColl;
5110     fromArgColl.push_back(fromQnameExpr);
5111     fo_expr* fromCollExpr = theExprManager->create_fo_expr(theRootSctx,
5112                                          loc,
5113                                          fromFnCollection,
5114                                          fromArgColl);
5115 
5116     // every $x in dc:collection( xs:QName("org:transactions") )
5117     // satisfies ...
5118     // implemented using flowr
5119     flwor_expr* evFlworExpr = theExprManager->create_flwor_expr(theRootSctx, loc, false);
5120     evFlworExpr->set_return_expr(theExprManager->create_const_expr(theRootSctx, loc, true));
5121 
5122     // $x
5123     const QName* fromVarQName = ic.getFromNodeVarName();
5124     var_expr* fromVarExpr = bind_var(loc, fromVarQName, var_expr::for_var, NULL);
5125 
5126     // for $x in dc:collection(xs:QName("org:transactions"))
5127     evFlworExpr->add_clause(wrap_in_forclause(fromCollExpr,
5128                                               fromVarExpr, NULL));
5129 
5130 
5131     push_nodestack(someFlworExpr);
5132     push_nodestack(evFlworExpr);
5133   }
5134   break;
5135 
5136   default:
5137     ZORBA_ASSERT(false);
5138   }
5139 
5140   return no_state;
5141 }
5142 
5143 
end_visit(const IntegrityConstraintDecl & v,void *)5144 void end_visit(const IntegrityConstraintDecl& v, void* /*visit_state*/)
5145 {
5146   TRACE_VISIT_OUT();
5147 
5148   //fill in the body of the function
5149   expr* body = NULL;
5150   const QName* qname = v.getName();
5151 
5152   // todo cezar: error if user expresions are sequential
5153 
5154   // for each type of IC a different check Expr is constructed
5155   switch( v.getICKind() )
5156   {
5157   case IntegrityConstraintDecl::coll_check_simple:
5158     {
5159       //const ICCollSimpleCheck ic = dynamic_cast<const ICCollSimpleCheck&>(v);
5160 
5161       expr* icExpr = pop_nodestack();
5162 
5163       flwor_expr* flworExpr =
5164         dynamic_cast<flwor_expr*>(pop_nodestack());
5165 
5166       // let ... return ...
5167       flworExpr->set_return_expr( wrap_in_atomization(icExpr) );
5168 
5169       body = flworExpr;
5170     }
5171     break;
5172 
5173   case IntegrityConstraintDecl::coll_check_unique_key:
5174     {
5175       /**********************
5176        declare integrity constraint org:icEmployeesIds
5177          on collection org:employees node $x check unique key $x/@id ;
5178 
5179        let $x := dc:collection( xs:QName("org:employees") )
5180        return
5181          (
5182            every $x_ in $x
5183            satisfies
5184              exists( $x_/@id )
5185          )
5186          and
5187          (  functx:are-distinct-values( $x/@id )  )
5188 
5189       implemented as:
5190        let $x := dc:collection( xs:QName("org:employees") )
5191        return
5192          (
5193            fn:empty(
5194              for $x_ in dc:collection( xs:QName("org:employees") )
5195              where not( exists($x_/@id) )
5196              return true)
5197          )
5198          and
5199          (  count(distinct-values( $x/@id )) = count($x/@id)  )
5200       **********************/
5201 
5202       //////  Get data from stack
5203       // $x/@id
5204       expr* uniKeyExpr = pop_nodestack();
5205 
5206       // flwor result expr
5207       flwor_expr* flworExpr =
5208         dynamic_cast<flwor_expr*>(pop_nodestack());
5209 
5210       // flwor implementing every
5211       flwor_expr* evFlworExpr =
5212         dynamic_cast<flwor_expr*>(pop_nodestack());
5213 
5214 
5215       ////// Set latest details
5216 
5217       //fn:data( userExpr )
5218       expr* atomizedUniKeyExpr = wrap_in_atomization(uniKeyExpr);
5219 
5220       // exists( $x/@id )
5221       expr* existsExpr = theExprManager->create_fo_expr(theRootSctx, loc,
5222                                       GET_BUILTIN_FUNCTION(FN_EXISTS_1),
5223                                       uniKeyExpr);
5224 
5225 #if 0
5226       zstring commentStr("#trace fnExists");
5227       expr* comentExpr = theExprManager->create_const_expr(theRootSctx, loc, commentStr);
5228       fo_expr* fnTraceExpr = theExprManager->create_fo_expr(theRootSctx,
5229                                          loc,
5230                                          GET_BUILTIN_FUNCTION(FN_TRACE_2),
5231                                          existsExpr, comentExpr);
5232 #endif
5233 
5234 
5235       // every ... satisfies evTestExpr
5236       fo_expr* fnNotExpr = theExprManager->create_fo_expr(theRootSctx,
5237                                         loc,
5238                                         GET_BUILTIN_FUNCTION(FN_NOT_1),
5239                                         existsExpr);
5240 
5241       evFlworExpr->add_where(fnNotExpr);
5242 
5243       fo_expr* everyExpr = theExprManager->create_fo_expr(theRootSctx,
5244                                         loc,
5245                                         GET_BUILTIN_FUNCTION(FN_EMPTY_1),
5246                                         evFlworExpr);
5247 
5248       // functx:are-distinct-values( $x/@id )
5249       // implemented as count(distinct-values($seq)) = count($seq)
5250       //distinct-values($seq)
5251       fo_expr* distinctValuesExpr = theExprManager->create_fo_expr(theRootSctx, loc,
5252                                  GET_BUILTIN_FUNCTION(FN_DISTINCT_VALUES_1),
5253                                                  atomizedUniKeyExpr);
5254 
5255       // count($sec)
5256       fo_expr* countSecExpr = theExprManager->create_fo_expr(theRootSctx, loc,
5257                                            GET_BUILTIN_FUNCTION(FN_COUNT_1),
5258                                            atomizedUniKeyExpr);
5259       // count(distinct-values($sec))
5260       fo_expr* countDVExpr = theExprManager->create_fo_expr(theRootSctx, loc,
5261                                           GET_BUILTIN_FUNCTION(FN_COUNT_1),
5262                                           distinctValuesExpr);
5263 
5264       // countDV = countSec
5265       fo_expr* equalExpr = theExprManager->create_fo_expr(theRootSctx, loc,
5266                                         GET_BUILTIN_FUNCTION(OP_EQUAL_2),
5267                                         countDVExpr, countSecExpr);
5268       // (...) and (...)
5269       fo_expr* andExpr = theExprManager->create_fo_expr(theRootSctx, loc,
5270                                       GET_BUILTIN_FUNCTION(OP_AND_N),
5271                                       everyExpr, equalExpr);
5272 
5273       flworExpr->set_return_expr(andExpr);
5274 
5275       body = flworExpr;
5276     }
5277     break;
5278 
5279   case IntegrityConstraintDecl::coll_foreach_node:
5280     {
5281       /**********************
5282        declare integrity constraint org:icTransactionsSale
5283          on collection org:transactions foreach node $x
5284            check $x/sale gt 0 ;
5285 
5286        every $x in dc:collection( xs:QName("org:transactions") )
5287        satisfies $x/sale gt 0
5288 
5289        implemented as:
5290          fn:empty(
5291            for $x in dc:collection( xs:QName("org:transactions") )
5292            where not( $x/sale gt 0 )
5293            return true )
5294        **********************/
5295 
5296       //////  Get data from stack
5297       // $x/sale gt 0
5298       expr* evTestExpr = wrap_in_atomization(pop_nodestack());
5299 
5300       // flwor expr
5301       flwor_expr* evFlworExpr =
5302         dynamic_cast<flwor_expr*>(pop_nodestack());
5303 
5304       // fn:not
5305       fo_expr* fnNotExpr = theExprManager->create_fo_expr(theRootSctx,
5306                                         loc,
5307                                         GET_BUILTIN_FUNCTION(FN_NOT_1),
5308                                         evTestExpr);
5309 
5310       // where not( exists($x/sale gt 0) )
5311       evFlworExpr->add_where(fnNotExpr);
5312 
5313       // fn:empty
5314       fo_expr* emptyExpr = theExprManager->create_fo_expr(theRootSctx,
5315                                         loc,
5316                                         GET_BUILTIN_FUNCTION(FN_EMPTY_1),
5317                                         evFlworExpr);
5318 
5319       body = emptyExpr;
5320     }
5321     break;
5322 
5323   case IntegrityConstraintDecl::foreign_key:
5324     {
5325       //////  Get data from stack
5326       // $y/id
5327       expr* toKeyExpr = wrap_in_atomization(pop_nodestack());
5328 
5329       // $x//sale/empid
5330       expr* fromKeyExpr = wrap_in_atomization(pop_nodestack());
5331 
5332       // result expr
5333       flwor_expr* evFlworExpr = dynamic_cast<flwor_expr*>(pop_nodestack());
5334 
5335       // some flwor expr
5336       flwor_expr* someFlworExpr = dynamic_cast<flwor_expr*>(pop_nodestack());
5337 
5338 
5339       // maybe add fn:data ?
5340       // $y/id eq $x//sale/empid
5341       fo_expr* eqExpr = theExprManager->create_fo_expr(theRootSctx,
5342                                      loc,
5343                                      GET_BUILTIN_FUNCTION(OP_VALUE_EQUAL_2),
5344                                      toKeyExpr,
5345                                      fromKeyExpr);
5346       normalize_fo(eqExpr);
5347 
5348       expr* someTestExpr = eqExpr;
5349       someTestExpr = wrap_in_bev(someTestExpr);
5350       someFlworExpr->add_where(someTestExpr);
5351 
5352       // fn:exists
5353       fo_expr* fnExistsExpr = theExprManager->create_fo_expr(theRootSctx, loc,
5354                                            GET_BUILTIN_FUNCTION(FN_EXISTS_1),
5355                                            someFlworExpr);
5356       // fn:not()
5357       fo_expr* evFnNotExpr = theExprManager->create_fo_expr(theRootSctx,
5358                                           loc,
5359                                           GET_BUILTIN_FUNCTION(FN_NOT_1),
5360                                           fnExistsExpr);
5361 
5362       evFlworExpr->add_where(evFnNotExpr);
5363 
5364       // fn:empty
5365       fo_expr* fnEmptyExpr = theExprManager->create_fo_expr(theRootSctx,
5366                                         loc,
5367                                         GET_BUILTIN_FUNCTION(FN_EMPTY_1),
5368                                         evFlworExpr);
5369 
5370 
5371       body = fnEmptyExpr;
5372     }
5373     break;
5374 
5375   default:
5376     ZORBA_ASSERT(false);
5377   }
5378 
5379   pop_scope();
5380 
5381 
5382   zstring msg = "entry-creator expr for integrity constraint " +
5383     qname->get_localname();
5384 
5385   if (theCCB->theConfig.optimize_cb != NULL)
5386     theCCB->theConfig.optimize_cb(body, msg.str());
5387 
5388   ulong nextVarId = 1;
5389   PlanIter_t icIter = codegen("integrity constraint", body, theCCB, nextVarId);
5390 
5391   // Update static context
5392   store::Item_t qnameItem;
5393   expand_function_qname(qnameItem, qname, qname->get_location());
5394 
5395   if (qnameItem->getNamespace() != theModuleNamespace)
5396   {
5397     throw XQUERY_EXCEPTION(
5398       zerr::ZDST0048_IC_DECL_IN_FOREIGN_MODULE,
5399       ERROR_PARAMS( qname->get_qname() ),
5400       ERROR_LOC( loc )
5401     );
5402   }
5403 
5404   ValueIC_t vic;
5405   if ( v.getICKind() == IntegrityConstraintDecl::foreign_key )
5406   {
5407     const ICForeignKey& ic = dynamic_cast<const ICForeignKey&>(v);
5408 
5409     const QName* fromQname = ic.getFromCollName();
5410 
5411     store::Item_t fromQnameItem;
5412     expand_function_qname(fromQnameItem, fromQname, fromQname->get_location());
5413 
5414     const QName* toQname = ic.getToCollName();
5415 
5416     store::Item_t toQnameItem;
5417     expand_function_qname(toQnameItem, toQname, toQname->get_location());
5418 
5419     vic = new ValueIC(theSctx, qnameItem, fromQnameItem, toQnameItem,
5420                       icIter, theCCB);
5421   }
5422   else
5423   {
5424     const ICColl* ic = dynamic_cast<const ICColl*>(&v);
5425 
5426     const QName* collQname = ic->getCollName();
5427     store::Item_t collQnameItem;
5428     expand_function_qname(collQnameItem, collQname, collQname->get_location());
5429 
5430     vic = new ValueIC(theSctx, qnameItem, collQnameItem, icIter, theCCB);
5431   }
5432 
5433   theSctx->bind_ic(vic, loc);
5434 
5435   // if this is a library module, register in exported module as well
5436   if (export_sctx != NULL)
5437     export_sctx->bind_ic(vic, loc);
5438 }
5439 
5440 
5441 /////////////////////////////////////////////////////////////////////////////////
5442 //                                                                             //
5443 //  QueryBody,                                                                 //
5444 //                                                                             //
5445 /////////////////////////////////////////////////////////////////////////////////
5446 
5447 
5448 /*******************************************************************************
5449   QueryBody ::= StatementsAndOptionalExpr
5450 
5451   StatementsAndOptionalExpr ::= StatementsAndExpr | Statements?
5452 
5453   StatementsAndExpr := Statements? Expr
5454 
5455   Statements ::= Statement+
5456 
5457   Expr ::=  ExprSingle ("," ExprSingle)*
5458 ********************************************************************************/
begin_visit(const QueryBody & v)5459 void* begin_visit(const QueryBody& v)
5460 {
5461   TRACE_VISIT();
5462   return no_state;
5463 }
5464 
end_visit(const QueryBody & v,void *)5465 void end_visit(const QueryBody& v, void* /*visit_state*/)
5466 {
5467   TRACE_VISIT_OUT();
5468 
5469   expr* program = pop_nodestack();
5470 
5471   // Mark the program as non-sequential if the only reason it is marked sequential
5472   // is because it contains exit exprs.
5473   program->set_not_exiting();
5474 
5475   if (program->is_updating())
5476   {
5477     theModulesInfo->theCCB->setIsUpdating(true);
5478   }
5479 
5480   if(program->is_sequential())
5481   {
5482     theModulesInfo->theCCB->setIsSequential(true);
5483   }
5484 
5485   if (program->is_updating() && !theCCB->theIsEval)
5486   {
5487     program = theExprManager->create_apply_expr(theRootSctx,
5488                              program->get_loc(),
5489                              program,
5490                              false); // don't discard XDM
5491   }
5492 
5493   push_nodestack(program);
5494 }
5495 
5496 
5497 ////////////////////////////////////////////////////////////////////////////////
5498 //                                                                            //
5499 //  Scripting Extensions                                                      //
5500 //                                                                            //
5501 ////////////////////////////////////////////////////////////////////////////////
5502 
5503 
5504 /*******************************************************************************
5505 
5506   QueryBody ::= StatementsAndOptionalExpr
5507 
5508   StatementsAndOptionalExpr ::= StatementsAndExpr | Statements?
5509 
5510   StatementsAndExpr := Statements? Expr
5511 
5512   Statements ::= Statement+
5513 
5514   Statement ::= BlockStatement |
5515                 VarDeclStatement |
5516                 AssignStatement |
5517                 ApplyStatement |
5518                 ExitStatement |
5519                 WhileExpr |
5520                 FlowCtlStatement |
5521 
5522                 FLWORStatement |
5523                 IfStatement |
5524                 TypeswitchStatement |
5525                 SwitchStatement |
5526                 TryStatement
5527 
5528   Expr ::=  ExprSingle ("," ExprSingle)*
5529 
5530   Note: In the StatementsAndOptionalExpr, StatementsAndExpr, and Statements rules,
5531   if any statements are actually present, the parser generates a subtree rooted
5532   at a BockBody parsenode. A single BlockBody parsenode (with no children) is
5533   also generated if there are no statements and no Expr either.
5534 
5535 ********************************************************************************/
5536 
5537 
5538 /*******************************************************************************
5539   A BlockBody parse node is generated as the result of the following grammar
5540   rules:
5541 
5542   1. StatementsAndOptionalExpr ::= StatementsAndExpr | Statements?
5543      If any statements are actually present or if neither statements nor an
5544      expr are present.
5545 
5546   2. StatementsAndExpr := Statements? Expr
5547      If any statements are actually present.
5548 
5549   3. Statements ::= Statement+
5550 
5551   4. EnclosedStatementsAndOptionalExpr ::= "{" StatementsAndOptionalExpr "}"
5552 
5553   5. BlockStatement ::= "{" Statements "}"
5554 
5555   6. BlockExpr ::= "{" StatementsAndOptionalExpr "}
5556 
5557 ********************************************************************************/
begin_visit(const BlockBody & v)5558 void* begin_visit(const BlockBody& v)
5559 {
5560   TRACE_VISIT();
5561 
5562   if (v.size() == 0)
5563   {
5564     push_nodestack(create_empty_seq(loc));
5565     return NULL;
5566   }
5567 
5568   if (!theSctx->is_feature_set(feature::scripting))
5569   {
5570     RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_Scripting)));
5571   }
5572 
5573   bool topLevel = v.isTopLevel();
5574   bool inEval = theCCB->theIsEval;
5575   bool allowLastUpdating = false;
5576 
5577   std::vector<expr*> stmts;
5578 
5579   // push a dummy block_expr in the node stack so that local var decls can
5580   // assert that their parent is a block expr.
5581   expr* dummyBlock = theExprManager->create_block_expr(theRootSctx, loc, false, stmts, NULL);
5582   push_nodestack(dummyBlock);
5583 
5584   push_scope();
5585 
5586   csize numScopes = theAssignedVars.size();
5587 
5588   theAssignedVars.resize(numScopes + 1);
5589 
5590   csize numExprs = v.size();
5591   bool declaresVars = false;
5592 
5593   for (csize i = 0; i < numExprs; ++i)
5594   {
5595     v[i]->accept(*this);
5596 
5597     if (dynamic_cast<const LocalVarDecl*>(v[i]) != NULL)
5598     {
5599       expr* val = pop_nodestack();
5600       var_expr* ve = static_cast<var_expr*>(pop_nodestack());
5601 
5602       GlobalBinding b(ve, val, false);
5603 
5604       declare_var(b, stmts);
5605 
5606       declaresVars = true;
5607     }
5608     else
5609     {
5610       expr* childExpr = pop_nodestack();
5611 
5612       // If the last child is an updating expr
5613       if (topLevel && i == numExprs - 1 && childExpr->is_updating())
5614       {
5615         if (inEval)
5616         {
5617           allowLastUpdating = true;
5618         }
5619         else
5620         {
5621           childExpr = theExprManager->create_apply_expr(theRootSctx, loc, childExpr, false);
5622         }
5623       }
5624 
5625       stmts.push_back(childExpr);
5626     }
5627   }
5628 
5629   // pop the dummy block expr from the stack.
5630   dummyBlock = pop_nodestack();
5631   assert(dummyBlock->get_expr_kind() == block_expr_kind);
5632 
5633   // Flatten-out a block expr if it has only one child and that child is
5634   // not a var decl expr.
5635   // hack?
5636   // this has been removed to allow for blocks containing only an expression
5637   // to be treated as JSON object constructors
5638   if (stmts.size() == 1 && !declaresVars)
5639   {
5640     push_nodestack(stmts[0]);
5641 
5642     theAssignedVars.pop_back();
5643     pop_scope();
5644 
5645     return NULL;
5646   }
5647 
5648   // Create the block expr
5649   std::vector<var_expr*>& prevAssignedVars = theAssignedVars[numScopes-1];
5650   std::vector<var_expr*>& lastAssignedVars = theAssignedVars[numScopes];
5651 
5652   expr* blockExpr = theExprManager->create_block_expr(theRootSctx,
5653                                     loc,
5654                                     allowLastUpdating,
5655                                     stmts,
5656                                     &lastAssignedVars);
5657 
5658   push_nodestack(blockExpr);
5659 
5660   prevAssignedVars.insert(prevAssignedVars.end(),
5661                           lastAssignedVars.begin(),
5662                           lastAssignedVars.end());
5663 
5664   theAssignedVars.pop_back();
5665   pop_scope();
5666 
5667   return NULL;
5668 }
5669 
5670 
end_visit(const BlockBody & v,void *)5671 void end_visit(const BlockBody& v, void* /*visit_state*/)
5672 {
5673   TRACE_VISIT_OUT();
5674 }
5675 
5676 
5677 /*******************************************************************************
5678   VarDeclStatement ::= ("local" Annotation*)? "variable"
5679                        "$" VarName TypeDeclaration? (":=" ExprSingle)?
5680                        ("," "$" VarName TypeDeclaration? (":=" ExprSingle)?)* ";"
5681 
5682   Note: the initializing ExprSingle of each var decl must be non-updating.
5683 
5684   Note: Each individual var decl in a VarDeclStatement is parsed into a VarDecl
5685   parsenode.
5686 
5687   Note: The applicable annotations are assignable vs non-assignable.
5688 
5689   Note: The parser makes sure that if a VarDeclStatement does not appear as a
5690   direct child of a BlockBody, it is wrapped by a BlockBody. Furthermore, the
5691   parser will flatten-out the VarDeclStatement parsenode by placing its children
5692   as direct children of the enclosing BlockBody. As a result, VarDeclStatement
5693   parsenodes do not appear at all in the final AST, and local var decls may
5694   appear only as direct operands of block exprs.
5695 ********************************************************************************/
begin_visit(const LocalVarDecl & v)5696 void* begin_visit(const LocalVarDecl& v)
5697 {
5698   TRACE_VISIT();
5699 
5700   store::Item_t qnameItem;
5701   expand_no_default_qname(qnameItem, v.get_var_name(), loc);
5702 
5703   if (theNodeStack.top()->get_expr_kind() != block_expr_kind)
5704   {
5705     ZORBA_ASSERT(false);
5706   }
5707 
5708   var_expr* ve = create_var(loc, qnameItem, var_expr::local_var);
5709 
5710   push_nodestack(ve);
5711 
5712   return no_state;
5713 }
5714 
5715 
end_visit(const LocalVarDecl & v,void *)5716 void end_visit(const LocalVarDecl& v, void* /*visit_state*/)
5717 {
5718   TRACE_VISIT_OUT();
5719 
5720   expr* initExpr = (v.get_binding_expr() == NULL ? NULL : pop_nodestack());
5721 
5722   var_expr* ve = dynamic_cast<var_expr*>(pop_nodestack());
5723 
5724   if (theAnnotations)
5725   {
5726     if (ZANN_CONTAINS(zann_assignable))
5727     {
5728       ve->set_mutable(true);
5729     }
5730     else if (ZANN_CONTAINS(zann_nonassignable))
5731     {
5732       ve->set_mutable(false);
5733     }
5734   }
5735 
5736   xqtref_t type;
5737   if (v.get_var_type() != NULL)
5738   {
5739     type = pop_tstack();
5740 
5741     ve->set_type(type);
5742   }
5743 
5744   // Put a mapping between the var name and the var_expr in the local sctx.
5745   // Raise error if var name exists already in local sctx obj.
5746   bind_var(ve, theSctx);
5747 
5748   // The ve and its associated intExpr will be put into var_decl_expr that
5749   // will be created by the translation of the parent block expr, immediately
5750   // after returning from this method.
5751   push_nodestack(ve);
5752 
5753 #ifdef ZORBA_WITH_DEBUGGER
5754   if (initExpr != NULL && theCCB->theDebuggerCommons != NULL)
5755   {
5756     QueryLoc lExpandedLocation =
5757     expandQueryLoc(v.get_var_name()->get_location(), initExpr->get_loc());
5758 
5759     wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true);
5760   }
5761 #endif
5762 
5763   push_nodestack(initExpr);
5764 
5765   theAnnotations = NULL;
5766 }
5767 
5768 
5769 /*******************************************************************************
5770   AssignStatement ::= "$" VarName ":=" ExprSingle ";"
5771 
5772   Note: the ExprSingle must be non-updating.
5773 ********************************************************************************/
begin_visit(const AssignExpr & v)5774 void* begin_visit(const AssignExpr& v)
5775 {
5776   TRACE_VISIT();
5777 
5778   if (!theSctx->is_feature_set(feature::scripting))
5779   {
5780     RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_Scripting)));
5781   }
5782   return no_state;
5783 }
5784 
end_visit(const AssignExpr & v,void * visit_state)5785 void end_visit(const AssignExpr& v, void* visit_state)
5786 {
5787   TRACE_VISIT_OUT();
5788 
5789   var_expr* ve = lookup_var(v.get_name(), loc, err::XPST0008);
5790 
5791   if ((ve->get_kind() != var_expr::local_var &&
5792        ve->get_kind() != var_expr::prolog_var) ||
5793       !ve->is_mutable())
5794   {
5795     RAISE_ERROR(zerr::XSST0007, loc,
5796     ERROR_PARAMS(ve->get_name()->getStringValue()));
5797   }
5798 
5799   xqtref_t varType = ve->get_type();
5800 
5801   expr* valueExpr = pop_nodestack();
5802 
5803   if (varType != NULL)
5804     valueExpr = theExprManager->create_treat_expr(theRootSctx,
5805                                                   loc,
5806                                                   valueExpr,
5807                                                   varType,
5808                                                   TreatIterator::TYPE_MATCH);
5809 
5810   push_nodestack(theExprManager->create_var_set_expr(theRootSctx, loc, ve, valueExpr));
5811 
5812   theAssignedVars.back().push_back(ve);
5813 }
5814 
5815 
5816 /*******************************************************************************
5817   ApplyStatement ::= ExprSingle ";"
5818 ********************************************************************************/
begin_visit(const ApplyExpr & v)5819 void* begin_visit(const ApplyExpr& v)
5820 {
5821   TRACE_VISIT();
5822 
5823   return no_state;
5824 }
5825 
end_visit(const ApplyExpr & v,void * visit_state)5826 void end_visit(const ApplyExpr& v, void* visit_state)
5827 {
5828   expr* param = pop_nodestack();
5829 
5830   push_nodestack(theExprManager->create_apply_expr(theRootSctx,
5831                                 param->get_loc(),
5832                                 param,
5833                                 true)); // discard XDM
5834 
5835   TRACE_VISIT_OUT();
5836 }
5837 
5838 
5839 /*******************************************************************************
5840 
5841 ********************************************************************************/
begin_visit(const ExitExpr & v)5842 void* begin_visit(const ExitExpr& v)
5843 {
5844   TRACE_VISIT();
5845 
5846   return no_state;
5847 }
5848 
5849 
end_visit(const ExitExpr & v,void * visit_state)5850 void end_visit(const ExitExpr& v, void* visit_state)
5851 {
5852   TRACE_VISIT_OUT();
5853 
5854   expr* childExpr = pop_nodestack();
5855 
5856   if (childExpr->is_updating())
5857   {
5858     theHaveUpdatingExitExprs = true;
5859 
5860     if (!inUDFBody() && !theCCB->theIsEval)
5861     {
5862       childExpr = theExprManager->create_apply_expr(theRootSctx, loc, childExpr, false);
5863     }
5864   }
5865   else if (childExpr->is_sequential())
5866   {
5867     theHaveSequentialExitExprs = true;
5868   }
5869 
5870   expr* exitExpr = theExprManager->create_exit_expr(theRootSctx, loc, childExpr);
5871 
5872   if (inUDFBody())
5873   {
5874     function* f = const_cast<function*>(theCurrentPrologVFDecl.getFunction());
5875     assert(f->isUdf());
5876     user_function* udf = static_cast<user_function*>(f);
5877 
5878     udf->setExiting(true);
5879     theExitExprs.push_back(exitExpr);
5880   }
5881 
5882   push_nodestack(exitExpr);
5883 }
5884 
5885 
5886 /*******************************************************************************
5887   WhileExpr ::= "while" "(" Expr ")" Statement
5888 ********************************************************************************/
begin_visit(const WhileExpr & v)5889 void* begin_visit(const WhileExpr& v)
5890 {
5891   TRACE_VISIT();
5892 
5893   theInWhileStack.push(true);
5894 
5895   return no_state;
5896 }
5897 
5898 
end_visit(const WhileExpr & v,void * visit_state)5899 void end_visit(const WhileExpr& v, void* visit_state)
5900 {
5901   TRACE_VISIT_OUT();
5902 
5903   expr* bodyExpr = pop_nodestack();
5904   expr* condExpr = pop_nodestack();
5905 
5906   expr* breakExpr = theExprManager->
5907   create_flowctl_expr(theRootSctx, loc, flowctl_expr::BREAK);
5908 
5909   condExpr = theExprManager->
5910   create_if_expr(theRootSctx, loc, condExpr, create_empty_seq(loc), breakExpr);
5911 
5912   block_expr* seqBody = NULL;
5913 
5914   std::vector<expr*> stmts;
5915 
5916   stmts.push_back(condExpr);
5917   stmts.push_back(bodyExpr);
5918 
5919   seqBody = theExprManager->
5920   create_block_expr(bodyExpr->get_sctx(), loc, false, stmts, NULL);
5921 
5922   push_nodestack(theExprManager->create_while_expr(theRootSctx, loc, seqBody));
5923 
5924   theInWhileStack.pop();
5925 }
5926 
5927 
5928 /*******************************************************************************
5929 
5930 ********************************************************************************/
begin_visit(const FlowCtlStatement & v)5931 void* begin_visit(const FlowCtlStatement& v)
5932 {
5933   TRACE_VISIT();
5934 
5935   return no_state;
5936 }
5937 
end_visit(const FlowCtlStatement & v,void * visit_state)5938 void end_visit(const FlowCtlStatement& v, void* visit_state)
5939 {
5940   TRACE_VISIT_OUT();
5941 
5942   enum flowctl_expr::action a;
5943 
5944   switch (v.get_action())
5945   {
5946   case FlowCtlStatement::BREAK:
5947   {
5948     if (theInWhileStack.empty())
5949     {
5950       RAISE_ERROR_NO_PARAMS(zerr::XSST0009, loc);
5951     }
5952     a = flowctl_expr::BREAK;
5953     break;
5954   }
5955   case FlowCtlStatement::CONTINUE:
5956   {
5957     if (theInWhileStack.empty())
5958     {
5959       RAISE_ERROR_NO_PARAMS(zerr::XSST0010, loc);
5960     }
5961     a = flowctl_expr::CONTINUE;
5962     break;
5963   }
5964   default:
5965     ZORBA_FATAL(false, "");
5966   }
5967 
5968   push_nodestack(theExprManager->create_flowctl_expr(theRootSctx, loc, a));
5969 }
5970 
5971 
5972 
5973 /*******************************************************************************
5974   Expr ::=  ExprSingle ("," ExprSingle)*
5975 
5976   If there is only one ExprSingle, no Expr parsenode is generated. Otherwise, an
5977   Expr parsenode is generated, whose children are the ExprSingles.
5978 ********************************************************************************/
begin_visit(const Expr & v)5979 void* begin_visit(const Expr& v)
5980 {
5981   TRACE_VISIT ();
5982   return no_state;
5983 }
5984 
end_visit(const Expr & v,void *)5985 void end_visit(const Expr& v, void* /*visit_state*/)
5986 {
5987   TRACE_VISIT_OUT();
5988 
5989   assert(v.numberOfChildren() > 1);
5990 
5991   std::vector<expr*> args;
5992 
5993   for (int i = 0; i < v.numberOfChildren(); ++i)
5994   {
5995     expr* e = pop_nodestack();
5996     args.push_back(e);
5997   }
5998 
5999   fo_expr* concatExpr = theExprManager->create_fo_expr(theRootSctx,
6000                                                         loc,
6001                                                         op_concatenate,
6002                                                         args);
6003   normalize_fo(concatExpr);
6004 
6005   push_nodestack(concatExpr);
6006 }
6007 
6008 
6009 /*******************************************************************************
6010 
6011   ExprSingle ::= ExprSimple |
6012                  FLWORExpr  |
6013                  SwitchExpr |
6014                  TypeswitchExpr |
6015                  IfExpr |
6016                  TryCatchExpr
6017 
6018   ExprSimple ::= QuantifiedExpr |
6019                  OrExpr |
6020 
6021                  InsertExpr |
6022                  DeleteExpr |
6023                  RenameExpr |
6024                  ReplaceExpr |
6025                  TransformExpr
6026 
6027 ********************************************************************************/
6028 
6029 
6030 
6031 /////////////////////////////////////////////////////////////////////////////////
6032 //                                                                             //
6033 //  FLWOR                                                                      //
6034 //                                                                             //
6035 /////////////////////////////////////////////////////////////////////////////////
6036 
6037 /*******************************************************************************
6038 
6039   FLWORExpr ::= InitialClause FLWORClauseList? ReturnClause
6040 
6041   - For the Generalized FLWOR:
6042 
6043   InitialClause ::= ForClause | LetClause | WindowClause
6044 
6045   FLWORClauseList ::= FLWORClause*
6046 
6047   FLWORClause ::= ForClause |
6048                   LetClause |
6049                   WindowClause |
6050                   WhereClause |
6051                   GroupByClause |
6052                   OrderByClause |
6053                   CountClause
6054 
6055   - For the traditional FLWOR:
6056 
6057   InitialClause ::= ForClause | LetClause
6058 
6059   FLWORClauseList ::= (ForClause | LetClause)*
6060                       WhereCluase?
6061                       GroupByClause?
6062                       OrderByClause?
6063 
6064 ********************************************************************************/
begin_visit(const FLWORExpr & v)6065 void* begin_visit(const FLWORExpr& v)
6066 {
6067   TRACE_VISIT();
6068 
6069   theFlworClausesStack.push_back(NULL);
6070 
6071   return no_state;
6072 }
6073 
6074 
end_visit(const FLWORExpr & v,void *)6075 void end_visit(const FLWORExpr& v, void* /*visit_state*/)
6076 {
6077   TRACE_VISIT_OUT();
6078 
6079   if (theSctx->xquery_version() <= StaticContextConsts::xquery_version_1_0 &&
6080       v.is_non_10())
6081   {
6082     RAISE_ERROR(err::XPST0003, loc,
6083     ERROR_PARAMS(ZED(XPST0003_XQueryVersionAtLeast30_2), theSctx->xquery_version()));
6084   }
6085 
6086   flwor_expr* flwor = theExprManager->create_flwor_expr(theRootSctx, loc, v.is_general());
6087 
6088   expr* retExpr = pop_nodestack();
6089 
6090   wrap_in_debugger_expr(retExpr, retExpr->get_loc());
6091 
6092   flwor->set_return_expr(retExpr);
6093 
6094   csize curClausePos = theFlworClausesStack.size() - 1;
6095 
6096   while (theFlworClausesStack[curClausePos] != NULL)
6097   {
6098     flwor_clause* curClause = theFlworClausesStack[curClausePos];
6099 
6100     switch (curClause->get_kind())
6101     {
6102     case flwor_clause::for_clause:
6103     case flwor_clause::let_clause:
6104     {
6105       pop_scope();
6106       break;
6107     }
6108     case flwor_clause::window_clause:
6109     {
6110       // window var + output window condition vars
6111       pop_scope();
6112       break;
6113     }
6114     case flwor_clause::group_clause:
6115     {
6116       group_clause* gc = static_cast<group_clause*>(curClause);
6117 
6118       csize numGVars = gc->getNumGroupingVars();
6119 
6120       for (csize i = 0; i < numGVars; ++i)
6121         pop_scope();
6122 
6123       pop_scope();
6124       break;
6125     }
6126     case flwor_clause::order_clause:
6127     case flwor_clause::where_clause:
6128     case flwor_clause::count_clause:
6129     {
6130       break;
6131     }
6132     default:
6133       ZORBA_ASSERT(false);
6134     }
6135 
6136     --curClausePos;
6137   }
6138 
6139   csize numClauses = theFlworClausesStack.size();
6140 
6141   for (csize i = curClausePos + 1; i < numClauses; ++i)
6142     flwor->add_clause(theFlworClausesStack[i]);
6143 
6144   theFlworClausesStack.resize(curClausePos);
6145 
6146   push_nodestack(flwor);
6147 }
6148 
6149 
6150 /*******************************************************************************
6151   - For the Generalized FLWOR:
6152 
6153   FLWORClauseList ::= FLWORClause*
6154 
6155   - For the traditional FLWOR:
6156 
6157   FLWORClauseList ::= (ForClause | LetClause)*
6158                       WhereCluase?
6159                       GroupByClause?
6160                       OrderByClause?
6161 ********************************************************************************/
begin_visit(const FLWORClauseList & v)6162 void* begin_visit(const FLWORClauseList& v)
6163 {
6164   TRACE_VISIT();
6165   return no_state;
6166 }
6167 
end_visit(const FLWORClauseList & v,void *)6168 void end_visit(const FLWORClauseList& v, void* /*visit_state*/)
6169 {
6170   TRACE_VISIT_OUT();
6171 }
6172 
6173 
6174 /*******************************************************************************
6175   ForClause ::= "outer"? "for" "$"  VarInDeclList
6176 ********************************************************************************/
begin_visit(const ForClause & v)6177 void* begin_visit(const ForClause& v)
6178 {
6179   TRACE_VISIT();
6180 
6181   if (v.has_allowing_empty())
6182   {
6183     if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
6184       RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_OuterForClause11)));
6185 
6186     theFlworClausesStack.push_back(NULL);
6187   }
6188 
6189   return no_state;
6190 }
6191 
6192 
end_visit(const ForClause & v,void *)6193 void end_visit(const ForClause& v, void* /*visit_state*/)
6194 {
6195   TRACE_VISIT_OUT();
6196 
6197   if (v.has_allowing_empty())
6198   {
6199     csize curClause = theFlworClausesStack.size() - 1;
6200     while (theFlworClausesStack[curClause] != NULL)
6201       --curClause;
6202 
6203     theFlworClausesStack.erase(theFlworClausesStack.begin() + curClause);
6204   }
6205 }
6206 
6207 
6208 /*******************************************************************************
6209   VarInDeclList ::= VarInDecl | VarInDeclList  ","  "$"  VarInDecl
6210 ********************************************************************************/
begin_visit(const VarInDeclList & v)6211 void* begin_visit(const VarInDeclList& v)
6212 {
6213   TRACE_VISIT();
6214   return no_state;
6215 }
6216 
end_visit(const VarInDeclList & v,void *)6217 void end_visit(const VarInDeclList& v, void* /*visit_state*/)
6218 {
6219   TRACE_VISIT_OUT();
6220 }
6221 
6222 
6223 /*******************************************************************************
6224   VarInDecl ::= VarName TypeDeclaration? PositionalVar? FTScoreVar? "in" ExprSingle
6225 ********************************************************************************/
begin_visit(const VarInDecl & v)6226 void* begin_visit(const VarInDecl& v)
6227 {
6228   TRACE_VISIT();
6229   return no_state;
6230 }
6231 
end_visit(const VarInDecl & v,void *)6232 void end_visit(const VarInDecl& v, void* /*visit_state*/)
6233 {
6234   TRACE_VISIT_OUT();
6235 
6236   expr* domainExpr = pop_nodestack();
6237 
6238   if (domainExpr->is_updating())
6239     throw XQUERY_EXCEPTION(err::XUST0001, ERROR_LOC(loc));
6240 
6241   // it's important to insert the debugger before the scope is pushed.
6242   // Otherwise, the variable in question would already be in scope for
6243   // the debugger but no value would be bound
6244   QueryLoc lExpandedLocation =
6245   expandQueryLoc(v.get_var_name()->get_location(), domainExpr->get_loc());
6246 
6247   wrap_in_debugger_expr(domainExpr, lExpandedLocation);
6248 
6249   push_scope();
6250 
6251   xqtref_t type = (v.get_var_type() == NULL ? NULL : pop_tstack());
6252 
6253   var_expr* varExpr = bind_var(loc, v.get_var_name(), var_expr::for_var, type);
6254   var_expr* posVarExpr = NULL;
6255 
6256   const PositionalVar* pv = v.get_posvar();
6257 
6258   if (pv != NULL)
6259   {
6260     store::Item_t pvarQName;
6261     expand_no_default_qname(pvarQName, pv->get_name(), loc);
6262 
6263     if (pvarQName->equals(varExpr->get_name()))
6264       RAISE_ERROR(err::XQST0089, loc, ERROR_PARAMS(pvarQName->getStringValue()));
6265 
6266     posVarExpr = bind_var(pv->get_location(), pvarQName, var_expr::pos_var);
6267   }
6268 
6269   for_clause* fc = theExprManager->create_for_clause(theRootSctx,
6270                                   loc,
6271                                   varExpr,
6272                                   domainExpr,
6273                                   posVarExpr,
6274                                   NULL,
6275                                   v.get_allowing_empty());
6276 
6277   theFlworClausesStack.push_back(fc);
6278 }
6279 
6280 
6281 /*******************************************************************************
6282   PositionalVar ::= "at" "$"  VarName
6283 ********************************************************************************/
begin_visit(const PositionalVar & v)6284 void* begin_visit(const PositionalVar& v)
6285 {
6286   TRACE_VISIT ();
6287   return no_state;
6288 }
6289 
end_visit(const PositionalVar & v,void *)6290 void end_visit(const PositionalVar& v, void* /*visit_state*/)
6291 {
6292   TRACE_VISIT_OUT();
6293 }
6294 
6295 
6296 /*******************************************************************************
6297   LetClause ::= "let" "$" VarGetsDeclList | "let" "score $" VarGetsDeclList
6298 ********************************************************************************/
begin_visit(const LetClause & v)6299 void* begin_visit(const LetClause& v)
6300 {
6301   TRACE_VISIT();
6302   return no_state;
6303 }
6304 
end_visit(const LetClause & v,void *)6305 void end_visit(const LetClause& v, void* /*visit_state*/)
6306 {
6307   TRACE_VISIT_OUT();
6308 }
6309 
6310 
6311 /*******************************************************************************
6312   VarGetsDeclList ::= VarGetsDecl | VarGetsDeclList ","  "$"  VarGetsDecl
6313 ********************************************************************************/
begin_visit(const VarGetsDeclList & v)6314 void* begin_visit(const VarGetsDeclList& v)
6315 {
6316   TRACE_VISIT();
6317   return no_state;
6318 }
6319 
end_visit(const VarGetsDeclList & v,void *)6320 void end_visit(const VarGetsDeclList& v, void* /*visit_state*/)
6321 {
6322   TRACE_VISIT_OUT();
6323 }
6324 
6325 
6326 /*******************************************************************************
6327   VarGetsDecl	::= VarName TypeDeclaration? ":=" ExprSingle |
6328                   VarName TypeDeclaration? FTScoreVar ":=" ExprSingle
6329 ********************************************************************************/
begin_visit(const VarGetsDecl & v)6330 void* begin_visit(const VarGetsDecl& v)
6331 {
6332   TRACE_VISIT();
6333   return no_state;
6334 }
6335 
create_let_clause(const QueryLoc loc,const QName * varName,expr * domainExpr,xqtref_t type)6336 void create_let_clause(
6337     const QueryLoc loc,
6338     const QName* varName,
6339     expr* domainExpr,
6340     xqtref_t type)
6341 {
6342   if (domainExpr->is_updating())
6343     throw XQUERY_EXCEPTION(err::XUST0001, ERROR_LOC(loc));
6344 
6345   // it's important to insert the debugger before the scope is pushed.
6346   // Otherwise, the variable in question would already be in scope for
6347   // the debugger but no value would be bound
6348   QueryLoc lExpandedLocation = expandQueryLoc(varName->get_location(),
6349                                               domainExpr->get_loc());
6350 
6351   wrap_in_debugger_expr(domainExpr, lExpandedLocation);
6352 
6353   push_scope();
6354 
6355   var_expr* varExpr = bind_var(loc, varName, var_expr::let_var, type);
6356 
6357   let_clause* clause = theExprManager->create_let_clause(theRootSctx,
6358                                       loc,
6359                                       varExpr,
6360                                       domainExpr);
6361 
6362   theFlworClausesStack.push_back(clause);
6363 }
6364 
6365 
end_visit(const VarGetsDecl & v,void *)6366 void end_visit(const VarGetsDecl& v, void* /*visit_state*/)
6367 {
6368   TRACE_VISIT_OUT();
6369 
6370   xqtref_t type = (v.get_var_type() == NULL ? NULL : pop_tstack());
6371 
6372   if (v.get_kind() == VarGetsDecl::let_var)
6373   {
6374     expr* domainExpr = pop_nodestack();
6375 
6376     create_let_clause(loc, v.get_var_name(), domainExpr, type);
6377   }
6378   else
6379   {
6380     push_scope();
6381     push_nodestack(create_var(loc, v.get_var_name(), var_expr::let_var, type));
6382   }
6383 }
6384 
6385 
6386 /*******************************************************************************
6387   WindowClause ::= "for" (TumblingWindowClause | SlidingWindowClause)
6388 
6389   TumblingWindowClause ::= "tumbling" "window" WindowVarDecl
6390                            WindowStartCondition WindowEndCondition?
6391 
6392   SlidingWindowClause ::= "sliding" "window" WindowVarDecl
6393                           WindowStartCondition WindowEndCondition
6394 
6395   Note: The accept() method of WindowClause translates the window domain expr
6396   first, then the conditions, and finally the window variable.
6397 ********************************************************************************/
begin_visit(const WindowClause & v)6398 void* begin_visit(const WindowClause& v)
6399 {
6400   TRACE_VISIT();
6401 
6402   if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
6403     RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_WindowClause11)));
6404 
6405   return no_state;
6406 }
6407 
6408 
intermediate_visit(const WindowClause & v,void *)6409 void intermediate_visit(const WindowClause& v, void* /*visit_state*/)
6410 {
6411   // This method is called after translating the window domain expr, but before
6412   // translating the window conditions and the window var.
6413 
6414   // Pop the window the domain expr.
6415   expr* windowDomainExpr = pop_nodestack();
6416 
6417   window_clause::window_t winKind = (v.get_wintype() == WindowClause::tumbling_window ?
6418                                      window_clause::tumbling_window :
6419                                      window_clause::sliding_window);
6420 
6421   window_clause* clause = theExprManager->create_window_clause(theRootSctx,
6422                                             v.get_location(),
6423                                             winKind,
6424                                             NULL,
6425                                             windowDomainExpr,
6426                                             NULL,
6427                                             NULL);
6428 
6429   theFlworClausesStack.push_back(clause);
6430 
6431   // Create scope for the input window-condition vars. These vars are visible
6432   // inside the WindowStartCondition and WindowEndCondition only, so the scope
6433   // created here will be destroyed as soon as we start processing the
6434   // WindowVarDecl (see below).
6435   push_scope();
6436 }
6437 
6438 
end_visit(const WindowClause & v,void *)6439 void end_visit(const WindowClause& v, void* /*visit_state*/)
6440 {
6441   TRACE_VISIT_OUT();
6442 
6443   window_clause* windowClause =
6444     dynamic_cast<window_clause*>(theFlworClausesStack.back());
6445   assert(windowClause != NULL);
6446 
6447   // Pop the window var and associate it with this window clause
6448   var_expr* windowVarExpr = pop_nodestack_var();
6449   windowVarExpr->set_flwor_clause(windowClause);
6450 
6451   // Create var_exprs for output window-condition vars, associate them with this
6452   // window clause, and push them to the nodestack.
6453   rchandle<FLWORWinCond> cond;
6454   for (int i = 0; i < 2; i++)
6455   {
6456     if (NULL != (cond = v[i]))
6457     {
6458       rchandle<WindowVars> vars = cond->get_winvars();
6459       if (vars != NULL)
6460         bind_wincond_vars(*vars, windowClause, false);
6461     }
6462   }
6463 
6464   // Collect the output window-condition vars from the nodestack and store
6465   // them in a flwor_wincond::vars obj.
6466   flwor_wincond::vars outputCondVarExprs[2];
6467 
6468   for (int i = 1; i >= 0; i--)
6469   {
6470     rchandle<FLWORWinCond> cond = v[i];
6471     if (cond != NULL)
6472     {
6473       rchandle<WindowVars> vars = cond->get_winvars();
6474       pop_wincond_vars(vars, outputCondVarExprs[i]);
6475     }
6476   }
6477 
6478   // Collect the input window-condition vars from the nodestack and store
6479   // them in a flwor_wincond::vars obj. Also pop the condition expr and
6480   // create a flwor_wincond obj for each condition.
6481   flwor_wincond::vars inputCondVarExprs[2];
6482   flwor_wincond* conds[2];
6483 
6484   for (int i = 1; i >= 0; i--)
6485   {
6486     rchandle<FLWORWinCond> cond = v[i];
6487     if (cond != NULL)
6488     {
6489       expr* condExpr = pop_nodestack();
6490 
6491       rchandle<WindowVars> vars = cond->get_winvars();
6492       pop_wincond_vars(vars, inputCondVarExprs[i]);
6493 
6494       conds[i] = theExprManager->create_flwor_wincond(
6495                                    theSctx,
6496                                    cond->is_only(),
6497                                    inputCondVarExprs[i],
6498                                    outputCondVarExprs[i],
6499                                    condExpr);
6500     }
6501     else
6502     {
6503       conds[i] = NULL;
6504     }
6505   }
6506 
6507   windowClause->set_var(windowVarExpr);
6508   windowClause->set_win_start(conds[0]);
6509   windowClause->set_win_stop(conds[1]);
6510 }
6511 
6512 
6513 
bind_wincond_vars(const WindowVars & v,flwor_clause * windowClause,bool input)6514 void bind_wincond_vars(const WindowVars& v, flwor_clause* windowClause, bool input)
6515 {
6516   const QueryLoc& loc = v.get_location();
6517 
6518   enum var_expr::var_kind varKind = (input ?
6519                                      var_expr::wincond_in_var :
6520                                      var_expr::wincond_out_var);
6521 
6522   enum var_expr::var_kind pvarKind = (input ?
6523                                       var_expr::wincond_in_pos_var :
6524                                       var_expr::wincond_out_pos_var);
6525 
6526   var_expr* posVarExpr = NULL;
6527   var_expr* curVarExpr = NULL;
6528   var_expr* nextVarExpr = NULL;
6529   var_expr* prevVarExpr = NULL;
6530 
6531   rchandle<PositionalVar> pv = v.get_posvar();
6532   if (pv != NULL)
6533   {
6534     posVarExpr = bind_var(pv->get_location(), pv->get_name(), pvarKind);
6535 
6536     posVarExpr->set_flwor_clause(windowClause);
6537     push_nodestack(posVarExpr);
6538   }
6539 
6540   if (v.get_curr())
6541   {
6542     curVarExpr = bind_var(loc, v.get_curr(), varKind);
6543 
6544     curVarExpr->set_flwor_clause(windowClause);
6545     push_nodestack(curVarExpr);
6546   }
6547 
6548   if (v.get_prev())
6549   {
6550     prevVarExpr = bind_var(loc, v.get_prev(), varKind);
6551 
6552     prevVarExpr->set_flwor_clause(windowClause);
6553     push_nodestack(prevVarExpr);
6554   }
6555 
6556   if (v.get_next())
6557   {
6558     nextVarExpr = bind_var(loc, v.get_next(), varKind);
6559 
6560     nextVarExpr->set_flwor_clause(windowClause);
6561     push_nodestack(nextVarExpr);
6562   }
6563 }
6564 
6565 
pop_wincond_vars(rchandle<WindowVars> node,flwor_wincond::vars & vars)6566 void pop_wincond_vars(rchandle<WindowVars> node, flwor_wincond::vars& vars)
6567 {
6568   if (node != NULL)
6569   {
6570     if (node->get_next())
6571       vars.next = pop_nodestack_var();
6572 
6573     if (node->get_prev())
6574       vars.prev = pop_nodestack_var();
6575 
6576     if (node->get_curr())
6577       vars.curr = pop_nodestack_var();
6578 
6579     if (node->get_posvar() != NULL)
6580       vars.posvar = pop_nodestack_var();
6581   }
6582 }
6583 
6584 
6585 /*******************************************************************************
6586   WindowStartCondition ::= "start" WindowVars "when" ExprSingle
6587 
6588   WindowEndCondition ::= "only"? "end" WindowVars "when" ExprSingle
6589 ********************************************************************************/
begin_visit(const FLWORWinCond & v)6590 void* begin_visit(const FLWORWinCond& v)
6591 {
6592   TRACE_VISIT();
6593   return no_state;
6594 }
6595 
end_visit(const FLWORWinCond & v,void *)6596 void end_visit(const FLWORWinCond& v, void* /*visit_state*/)
6597 {
6598   TRACE_VISIT_OUT();
6599 }
6600 
6601 
6602 /*******************************************************************************
6603   WindowVars ::= ("$" CurrentItem)? PositionalVar?
6604                  ("previous" "$" PreviousItem)?
6605                  ("next" "$" NextItem)?
6606 ********************************************************************************/
begin_visit(const WindowVars & v)6607 void* begin_visit(const WindowVars& v)
6608 {
6609   TRACE_VISIT();
6610   return no_state;
6611 }
6612 
6613 
end_visit(const WindowVars & v,void *)6614 void end_visit(const WindowVars& v, void* /*visit_state*/)
6615 {
6616   TRACE_VISIT_OUT();
6617 
6618   // Create var_exprs for the input window-condition vars, associate them with
6619   // the current window clause, and push them to the nodestack.
6620 
6621   flwor_clause* windowClause = theFlworClausesStack.back();
6622   bind_wincond_vars(v, windowClause, true);
6623 }
6624 
6625 
6626 /*******************************************************************************
6627   WindowVarDecl ::= "$" VarName TypeDeclaration? "in"  ExprSingle
6628 ********************************************************************************/
begin_visit(const WindowVarDecl & v)6629 void* begin_visit(const WindowVarDecl& v)
6630 {
6631   TRACE_VISIT();
6632 
6633   // Done with input window condition vars.
6634   pop_scope();
6635 
6636   return no_state;
6637 }
6638 
end_visit(const WindowVarDecl & v,void *)6639 void end_visit(const WindowVarDecl& v, void* /*visit_state*/)
6640 {
6641   TRACE_VISIT_OUT();
6642 
6643   // Create scope for the window var and the output window-condition vars
6644   push_scope();
6645 
6646   xqtref_t type = (v.get_var_type() == NULL ? NULL : pop_tstack());
6647 
6648   var_expr* ve = bind_var(loc, v.get_var_name(), var_expr::win_var, type);
6649 
6650   push_nodestack(ve);
6651 }
6652 
6653 
6654 /*******************************************************************************
6655   GroupByClause ::= "group" "by" GroupingSpecList
6656 
6657   GroupSpecList ::= 	GroupingSpec ("," GroupingSpec)*
6658 
6659   GroupSpec ::= "$" VarName (TypeDeclaration? ":=" ExprSingle)?
6660                 ("collation" URILiteral)?
6661 
6662   NOTE: For every group spec that has a binding expression, a let variable will
6663   be created and placed before the groupby clause.
6664 ********************************************************************************/
begin_visit(const GroupByClause & v)6665 void* begin_visit(const GroupByClause& v)
6666 {
6667   TRACE_VISIT();
6668 
6669   const FLWORExpr& flwor = *v.get_flwor ();
6670   const FLWORClauseList& clauses = *flwor.get_clause_list ();
6671 
6672   std::set<const var_expr *> all_vars;
6673   std::set<const var_expr *> group_vars;
6674   std::set<const var_expr *> non_group_vars;
6675 
6676   // Compute the set of non-grouping var_exprs. To do this, we first collect
6677   // the var_exprs for all the vars that have been defined by all clauses
6678   // before this GroupByClause. Then we collect the var_exprs for the var
6679   // names specified in the GroupByClause. The non-grouping vars are the vars
6680   // in the difference of the 2 sets above.
6681   //
6682   // NOTE: If a group spec does not have a binding expression, then a var
6683   // for the name appearing in the spec should exist already (i.e., be in
6684   // scope and have a var_expr). Otherwise, the var may or may not exist
6685   // already. In this case, if a var V exists already, it will be hidden
6686   // by the new var of the same name defined by the group spec, and so V
6687   // should not be included in the set of non-grouping vars.
6688   collect_flwor_vars(flwor, all_vars, &*clauses[0], &v, loc);
6689 
6690   GroupSpecList* speclist = v.get_spec_list();
6691 
6692   for (csize i = 0; i < speclist->size(); ++i)
6693   {
6694     GroupSpec* spec = (*speclist)[i];
6695 
6696     const QName* varname = spec->get_var_name();
6697 
6698     const var_expr* ve = NULL;
6699 
6700     if (spec->get_binding_expr() == NULL)
6701     {
6702       ve = lookup_var(varname, loc, err::XPST0008);
6703     }
6704     else
6705     {
6706       ve = lookup_var(varname, loc, zerr::ZXQP0000_NO_ERROR);
6707     }
6708 
6709     if (ve != NULL)
6710       group_vars.insert(ve);
6711   }
6712 
6713   set_difference(all_vars.begin(), all_vars.end(),
6714                  group_vars.begin(), group_vars.end(),
6715                  inserter(non_group_vars, non_group_vars.begin()));
6716 
6717   // For each var_expr X that does not appear in the group-by clause, create
6718   // a new var_exp ngX and push ngX and X in the node stack.
6719 
6720   push_nodestack(NULL);
6721 
6722   for (std::set<const var_expr *>::iterator i = non_group_vars.begin();
6723        i != non_group_vars.end();
6724        ++i)
6725   {
6726     push_nodestack(const_cast<var_expr *>(*i));
6727 
6728     var_expr* ve = create_var(loc, (*i)->get_name(), var_expr::non_groupby_var);
6729     push_nodestack(ve);
6730   }
6731 
6732   return no_state;
6733 }
6734 
6735 
end_visit(const GroupByClause & v,void *)6736 void end_visit(const GroupByClause& v, void* /*visit_state*/)
6737 {
6738   TRACE_VISIT_OUT();
6739 
6740   const GroupSpecList& groupSpecs = *v.get_spec_list();
6741   csize numGroupSpecs = groupSpecs.size();
6742 
6743   std::vector<std::string> collations;
6744   group_clause::rebind_list_t grouping_rebind;
6745   group_clause::rebind_list_t nongrouping_rebind;
6746 
6747   static_context* sctx = theSctx;
6748 
6749   for (csize i = 0; i < numGroupSpecs; ++i)
6750   {
6751     const GroupSpec& groupSpec = *groupSpecs[i];
6752 
6753     csize j;
6754     for (j = 0; j < i; ++j)
6755     {
6756       const GroupSpec& prevSpec = *groupSpecs[j];
6757 
6758       if (*groupSpec.get_var_name() == *prevSpec.get_var_name())
6759       {
6760         if (groupSpec.get_collation_spec() == NULL &&
6761             prevSpec.get_collation_spec() == NULL)
6762           break;
6763 
6764         if (groupSpec.get_collation_spec() != NULL &&
6765             prevSpec.get_collation_spec() != NULL &&
6766             groupSpec.get_collation_spec()->get_uri() ==
6767             prevSpec.get_collation_spec()->get_uri())
6768           break;
6769       }
6770     }
6771 
6772     if (j == i)
6773     {
6774       const QueryLoc& specLoc = groupSpec.get_location();
6775 
6776       // Since group specs can add let vars, and change the value of the
6777       // input_expr after the expr has been read, we delegate the actual looking
6778       // up of the variable until now, to get the most recent and correct value.
6779 
6780       store::Item_t varName;
6781       expand_no_default_qname(varName, groupSpec.get_var_name(), specLoc);
6782 
6783       VarInfo* var = sctx->lookup_var(varName.getp());
6784       if (!var)
6785       {
6786         RAISE_ERROR(err::XPST0008, specLoc,
6787         ERROR_PARAMS(varName->getStringValue(), ZED(VariabledUndeclared)));
6788       }
6789 
6790       expr* inputExpr = var->getVar();
6791 
6792       if (inputExpr->get_expr_kind() == var_expr_kind)
6793       {
6794         inputExpr = theExprManager->
6795         create_wrapper_expr(theRootSctx, specLoc, inputExpr);
6796       }
6797 
6798       inputExpr = wrap_in_atomization(inputExpr);
6799 
6800       inputExpr = wrap_in_type_match(inputExpr,
6801                                      theRTM.ANY_ATOMIC_TYPE_QUESTION,
6802                                      specLoc,
6803                                      TreatIterator::MULTI_VALUED_GROUPING_KEY);
6804 
6805       // We need to do this to handle grouping vars with same names but
6806       // different collations.
6807       push_scope();
6808 
6809       var_expr* gVar = bind_var(specLoc,
6810                                 groupSpec.get_var_name(),
6811                                 var_expr::groupby_var,
6812                                 inputExpr->get_return_type());
6813 
6814       grouping_rebind.push_back(std::pair<expr*, var_expr*>(inputExpr, gVar));
6815 
6816       if (groupSpec.get_collation_spec() != NULL)
6817       {
6818         std::string collationUri = groupSpec.get_collation_spec()->get_uri().str();
6819 
6820         if (! theSctx->is_known_collation(collationUri))
6821           RAISE_ERROR(err::XQST0076, specLoc, ERROR_PARAMS(collationUri));
6822 
6823         collations.push_back(collationUri);
6824       }
6825       else
6826       {
6827         collations.push_back ("");
6828       }
6829     }
6830   }
6831 
6832   // At this point, the nodestack contains a pair of var_exprs for each
6833   // non-grouping var. The 1stvar_expr in the pair corresponds to the
6834   // input-stream var X, and the 2nd var_expr corresponds to the associated
6835   // output-stream var.
6836 
6837   push_scope();
6838 
6839   var_expr* ngVar = NULL;
6840 
6841   while (NULL != (ngVar = pop_nodestack_var()))
6842   {
6843     var_expr* inputVar = pop_nodestack_var();
6844 
6845     bind_var(ngVar, theSctx);
6846 
6847     expr* inputExpr =
6848     theExprManager->create_wrapper_expr(theRootSctx, loc, inputVar);
6849 
6850     nongrouping_rebind.push_back(std::pair<expr*, var_expr*>(inputExpr, ngVar));
6851   }
6852 
6853   group_clause* clause = theExprManager->
6854   create_group_clause(theRootSctx,
6855                       loc,
6856                       grouping_rebind,
6857                       nongrouping_rebind,
6858                       collations);
6859 
6860   theFlworClausesStack.push_back(clause);
6861 }
6862 
6863 
6864 /*******************************************************************************
6865   GroupSpecList ::= 	GroupingSpec ("," GroupingSpec)*
6866 ********************************************************************************/
begin_visit(const GroupSpecList & v)6867 void* begin_visit(const GroupSpecList& v)
6868 {
6869   TRACE_VISIT();
6870   return no_state;
6871 }
6872 
end_visit(const GroupSpecList & v,void *)6873 void end_visit(const GroupSpecList& v, void* /*visit_state*/)
6874 {
6875   TRACE_VISIT_OUT();
6876 }
6877 
6878 
6879 /*******************************************************************************
6880   GroupSpec ::= "$" VarName (TypeDeclaration? ":=" ExprSingle)?
6881                 ("collation" URILiteral)?
6882 ********************************************************************************/
begin_visit(const GroupSpec & v)6883 void* begin_visit(const GroupSpec& v)
6884 {
6885   TRACE_VISIT();
6886   return no_state;
6887 }
6888 
end_visit(const GroupSpec & v,void *)6889 void end_visit(const GroupSpec& v, void* /*visit_state*/)
6890 {
6891   TRACE_VISIT_OUT();
6892 
6893   xqtref_t type = NULL;
6894 
6895   if (v.get_binding_expr() != NULL)
6896   {
6897     expr* domainExpr = pop_nodestack();
6898 
6899     if (v.get_var_type() != NULL)
6900       type = pop_tstack();
6901 
6902     create_let_clause(loc, v.get_var_name(), domainExpr, type);
6903   }
6904 }
6905 
6906 
6907 /*******************************************************************************
6908 
6909 ********************************************************************************/
begin_visit(const GroupCollationSpec & v)6910 void* begin_visit(const GroupCollationSpec& v)
6911 {
6912   TRACE_VISIT();
6913   return no_state;
6914 }
6915 
end_visit(const GroupCollationSpec & v,void *)6916 void end_visit(const GroupCollationSpec& v, void* /*visit_state*/)
6917 {
6918   TRACE_VISIT_OUT();
6919 }
6920 
6921 
6922 /*******************************************************************************
6923   OrderByClause ::= (("order" "by") | ("stable" "order" "by")) OrderSpecList
6924 ********************************************************************************/
begin_visit(const OrderByClause & v)6925 void* begin_visit(const OrderByClause& v)
6926 {
6927   TRACE_VISIT ();
6928   return no_state;
6929 }
6930 
6931 
end_visit(const OrderByClause & v,void *)6932 void end_visit(const OrderByClause& v, void* /*visit_state*/)
6933 {
6934   TRACE_VISIT_OUT();
6935 
6936   const OrderSpecList& orderSpecs = *v.get_spec_list();
6937   csize numOrderSpecs = orderSpecs.size();
6938 
6939   std::vector<OrderModifier> modifiers(numOrderSpecs);
6940   std::vector<expr*> orderExprs(numOrderSpecs);
6941 
6942   for (int i = numOrderSpecs - 1; i >= 0; --i)
6943   {
6944     OrderSpec* spec = orderSpecs[i];
6945     const OrderModifierPN* mod = spec->get_modifier();
6946 
6947     ParseConstants::dir_spec_t dirSpec = ParseConstants::dir_ascending;
6948     if (mod && mod->get_dir_spec() != NULL)
6949       dirSpec = mod->get_dir_spec()->getValue();
6950 
6951     StaticContextConsts::empty_order_mode_t emptySpec = theSctx->empty_order_mode();
6952     if (mod && mod->get_empty_spec() != NULL)
6953       emptySpec = mod->get_empty_spec()->getValue();
6954 
6955     std::string collationUri = theSctx->get_default_collation(loc);
6956 
6957     if (mod && mod->get_collation_spec() != NULL)
6958     {
6959       collationUri = mod->get_collation_spec()->get_uri().str();
6960 
6961       if (! theSctx->is_known_collation(collationUri))
6962         RAISE_ERROR(err::XQST0076, loc, ERROR_PARAMS(collationUri));
6963     }
6964 
6965     expr* orderExpr = pop_nodestack();
6966 
6967     if (orderExpr->is_updating())
6968       throw XQUERY_EXCEPTION(err::XUST0001, ERROR_LOC(loc));
6969 
6970     orderExpr = wrap_in_atomization(orderExpr);
6971 
6972     modifiers[i].theAscending = (dirSpec == ParseConstants::dir_ascending);
6973     modifiers[i].theEmptyLeast = (emptySpec == StaticContextConsts::empty_least);
6974     modifiers[i].theCollation = collationUri;
6975 
6976     orderExprs[i] = orderExpr;
6977   }
6978 
6979   orderby_clause* clause = theExprManager->create_orderby_clause(theRootSctx,
6980                                               loc,
6981                                               v.get_stable_bit(),
6982                                               modifiers,
6983                                               orderExprs);
6984   theFlworClausesStack.push_back(clause);
6985 }
6986 
6987 
6988 /*******************************************************************************
6989   OrderSpecList ::=	OrderSpec ("," OrderSpec)*
6990 ********************************************************************************/
begin_visit(const OrderSpecList & v)6991 void* begin_visit(const OrderSpecList& v)
6992 {
6993   TRACE_VISIT();
6994   return no_state;
6995 }
6996 
end_visit(const OrderSpecList & v,void *)6997 void end_visit(const OrderSpecList& v, void* /*visit_state*/)
6998 {
6999   TRACE_VISIT_OUT();
7000 }
7001 
7002 
7003 /*******************************************************************************
7004   OrderSpec ::= ExprSingle OrderModifier
7005 ********************************************************************************/
begin_visit(const OrderSpec & v)7006 void* begin_visit(const OrderSpec& v)
7007 {
7008   TRACE_VISIT();
7009   return no_state;
7010 }
7011 
end_visit(const OrderSpec & v,void *)7012 void end_visit(const OrderSpec& v, void* /*visit_state*/)
7013 {
7014   TRACE_VISIT_OUT();
7015 }
7016 
7017 
7018 /*******************************************************************************
7019   OrderModifier ::= OrderDirSpec? OrderEmptySpec? OrderCollationSpec?
7020 
7021   OrderCollationSpec ::= "collation" URILiteral
7022 
7023   OrderDirSpec ::= "ascending" | "descending"
7024 
7025   OrderEmptySpec ::= "empty" ("greatest" | "least")
7026 ********************************************************************************/
begin_visit(const OrderModifierPN & v)7027 void* begin_visit(const OrderModifierPN& v)
7028 {
7029   TRACE_VISIT();
7030   return no_state;
7031 }
7032 
end_visit(const OrderModifierPN & v,void *)7033 void end_visit(const OrderModifierPN& v, void* /*visit_state*/)
7034 {
7035   TRACE_VISIT_OUT();
7036 }
7037 
7038 
begin_visit(const OrderCollationSpec & v)7039 void* begin_visit(const OrderCollationSpec& v)
7040 {
7041   TRACE_VISIT ();
7042   return no_state;
7043 }
7044 
end_visit(const OrderCollationSpec & v,void *)7045 void end_visit(const OrderCollationSpec& v, void* /*visit_state*/)
7046 {
7047   TRACE_VISIT_OUT ();
7048 }
7049 
begin_visit(const OrderDirSpec & v)7050 void* begin_visit(const OrderDirSpec& v)
7051 {
7052   TRACE_VISIT ();
7053   return no_state;
7054 }
7055 
end_visit(const OrderDirSpec & v,void *)7056 void end_visit(const OrderDirSpec& v, void* /*visit_state*/)
7057 {
7058   TRACE_VISIT_OUT ();
7059 }
7060 
begin_visit(const OrderEmptySpec & v)7061 void* begin_visit(const OrderEmptySpec& v)
7062 {
7063   TRACE_VISIT ();
7064   return no_state;
7065 }
7066 
end_visit(const OrderEmptySpec & v,void *)7067 void end_visit(const OrderEmptySpec& v, void* /*visit_state*/)
7068 {
7069   TRACE_VISIT_OUT ();
7070 }
7071 
7072 
7073 /*******************************************************************************
7074   WhereClause ::= "where"  ExprSingle
7075 ********************************************************************************/
begin_visit(const WhereClause & v)7076 void* begin_visit(const WhereClause& v)
7077 {
7078   TRACE_VISIT ();
7079   return no_state;
7080 }
7081 
end_visit(const WhereClause & v,void *)7082 void end_visit(const WhereClause& v, void* /*visit_state*/)
7083 {
7084   TRACE_VISIT_OUT ();
7085 
7086   expr* whereExpr = pop_nodestack();
7087 
7088   if (whereExpr->is_updating())
7089     throw XQUERY_EXCEPTION(err::XUST0001, ERROR_LOC(loc));
7090 
7091   whereExpr = wrap_in_bev(whereExpr);
7092 
7093   wrap_in_debugger_expr(whereExpr, whereExpr->get_loc());
7094 
7095   where_clause* clause = theExprManager->create_where_clause(theRootSctx,
7096                                           loc,
7097                                           whereExpr);
7098 
7099   theFlworClausesStack.push_back(clause);
7100 }
7101 
7102 
7103 /*******************************************************************************
7104   CountClause ::= "count" "$" VarName
7105 ********************************************************************************/
begin_visit(const CountClause & v)7106 void* begin_visit(const CountClause& v)
7107 {
7108   TRACE_VISIT ();
7109 
7110   if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
7111     RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_CountClause11)));
7112 
7113   return no_state;
7114 }
7115 
end_visit(const CountClause & v,void *)7116 void end_visit(const CountClause& v, void* /*visit_state*/)
7117 {
7118   TRACE_VISIT_OUT();
7119 
7120   var_expr* varExpr = bind_var(loc, v.get_varname(), var_expr::count_var, NULL);
7121 
7122   count_clause* clause = theExprManager->create_count_clause(theRootSctx,
7123                                           loc,
7124                                           varExpr);
7125 
7126   theFlworClausesStack.push_back(clause);
7127 }
7128 
7129 
7130 /////////////////////////////////////////////////////////////////////////////////
7131 //                                                                             //
7132 //  Switch                                                                     //
7133 //                                                                             //
7134 /////////////////////////////////////////////////////////////////////////////////
7135 
7136 
7137 
7138 /*******************************************************************************
7139   SwitchExpr ::= "switch" "(" Expr ")"
7140                   SwitchCaseClause+
7141                   "default" "return" ExprSingle
7142 
7143   SwitchCaseClause ::= ("case" SwitchCaseOperand)+ "return" ExprSingle
7144 
7145   A switch expr is translated into a flwor expr. For example, a switch of
7146   the following form:
7147 
7148   switch E
7149   case $c11 return E1
7150   case $c21
7151   case $c22 return E2
7152   ......
7153   case $cn1 return En
7154   default return Ed
7155 
7156   is translated into:
7157 
7158   let $sv := E
7159   return if ($sv = $c11 or $sv = $c12 or ...) then
7160            return E1
7161          else if ($sv = $c21 or $sv = $c22 or ...) then
7162            return E2
7163          ....
7164          else if ($sv = $cn1 or $sv = $cn2 or ...) then
7165            return En
7166          else
7167            return Ed
7168 ********************************************************************************/
begin_visit(const SwitchExpr & v)7169 void* begin_visit(const SwitchExpr& v)
7170 {
7171   TRACE_VISIT();
7172 
7173   if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
7174   {
7175     RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_SwitchExpr11)));
7176   }
7177 
7178   v.get_switch_expr()->accept(*this);
7179 
7180   expr* se = pop_nodestack();
7181 
7182   se = wrap_in_atomization(se);
7183 
7184   // atomizedFlwor = [let $atomv := data(E) return NULL]
7185   var_expr* atomv = create_temp_var(v.get_switch_expr()->get_location(),
7186                                      var_expr::let_var);
7187 
7188   expr* atomizedFlwor = wrap_in_let_flwor(se, atomv, NULL);
7189 
7190   // TODO: cast as xs:string should not really be necessary
7191   // atomizedFlwor =
7192   //  [let $atomv := data(E)
7193   //   return
7194   //     let $sv :=
7195   //          if ($atomv instanceof xs:untypedAtomic)
7196   //          then $atomv cast as xs:string
7197   //          else $atomv
7198   //     return NULL]
7199   static_cast<flwor_expr*>(atomizedFlwor)->set_return_expr(
7200     theExprManager->create_if_expr(theRootSctx,
7201                 loc,
7202                 theExprManager->create_instanceof_expr(theRootSctx,
7203                                     loc,
7204                                     atomv,
7205                                     theRTM.UNTYPED_ATOMIC_TYPE_ONE),
7206                 theExprManager->create_cast_expr(theRootSctx,
7207                               loc,
7208                               atomv,
7209                               theRTM.STRING_TYPE_ONE),
7210                 atomv));
7211 
7212   // flworExpr = [let $sv := atomizedFlwor return NULL]
7213   var_expr* sv = create_temp_var(v.get_switch_expr()->get_location(), var_expr::let_var);
7214   expr* flworExpr = wrap_in_let_flwor(atomizedFlwor, sv, NULL);
7215 
7216   // retExpr = [Ed]
7217   v.get_default_expr()->accept(*this);
7218   expr* retExpr = pop_nodestack();
7219 
7220   const SwitchCaseClauseList* clauses = v.get_clause_list();
7221   std::vector<rchandle<SwitchCaseClause> >::const_reverse_iterator it;
7222 
7223   for (it = clauses->rbegin(); it != clauses->rend(); ++it)
7224   {
7225     const SwitchCaseClause* switchCaseClause = &**it;
7226     const QueryLoc& loc = switchCaseClause->get_location();
7227 
7228     const SwitchCaseOperandList* operands = switchCaseClause->get_operand_list();
7229 
7230     expr* condExpr = NULL;
7231     std::vector<expr*> condOperands;
7232     condOperands.reserve(operands->size());
7233 
7234     for (std::vector<rchandle<exprnode> >::const_iterator it = operands->begin();
7235          it != operands->end();
7236          ++it)
7237     {
7238       const exprnode* operand = &**it;
7239       operand->accept(*this);
7240 
7241       expr* operandExpr = pop_nodestack();
7242       operandExpr = wrap_in_atomization(operandExpr);
7243       operandExpr = theExprManager->create_fo_expr(theRootSctx, loc,
7244                                 GET_BUILTIN_FUNCTION(OP_ATOMIC_VALUES_EQUIVALENT_2),
7245                                 sv,
7246                                 operandExpr);
7247 
7248       condOperands.push_back(operandExpr);
7249     } // for
7250 
7251     if (condOperands.size() == 1)
7252     {
7253       condExpr = condOperands[0];
7254     }
7255     else if (condOperands.size() > 1)
7256     {
7257       condExpr = theExprManager->create_fo_expr(theRootSctx,
7258                              loc,
7259                              GET_BUILTIN_FUNCTION(OP_OR_N),
7260                              condOperands);
7261     }
7262 
7263     switchCaseClause->get_return_expr()->accept(*this);
7264     expr* caseReturnExpr = pop_nodestack();
7265 
7266     // retExpr = [if (condExpr) then caseReturnExpr else retExpr]
7267     retExpr = theExprManager->create_if_expr(theRootSctx, loc, condExpr, caseReturnExpr, retExpr);
7268 
7269   } // for
7270 
7271   static_cast<flwor_expr*>(flworExpr)->set_return_expr(retExpr);
7272   push_nodestack(flworExpr);
7273 
7274   // Return NULL so that SwitchExpr::accept() will not call accept() on the
7275   // children of the SwitchExpr parsenode.
7276   return NULL;
7277 }
7278 
end_visit(const SwitchExpr & v,void *)7279 void end_visit (const SwitchExpr& v, void* /*visit_state*/)
7280 {
7281   TRACE_VISIT_OUT ();
7282   // shouldn't get here, begin_visit() rejects visitor
7283   ZORBA_ASSERT (false);
7284 }
7285 
begin_visit(const SwitchCaseClause & v)7286 void* begin_visit(const SwitchCaseClause& v)
7287 {
7288   TRACE_VISIT();
7289 
7290   return NULL;
7291 }
7292 
end_visit(const SwitchCaseClause & v,void *)7293 void end_visit (const SwitchCaseClause& v, void* /*visit_state*/)
7294 {
7295   TRACE_VISIT_OUT ();
7296   // shouldn't get here, begin_visit() rejects visitor
7297   ZORBA_ASSERT (false);
7298 }
7299 
begin_visit(const SwitchCaseClauseList & v)7300 void* begin_visit(const SwitchCaseClauseList& v)
7301 {
7302   TRACE_VISIT();
7303   // shouldn't get here
7304   ZORBA_ASSERT(false);
7305   return no_state;
7306 }
7307 
end_visit(const SwitchCaseClauseList & v,void *)7308 void end_visit(const SwitchCaseClauseList& v, void* /*visit_state*/)
7309 {
7310   TRACE_VISIT_OUT();
7311 }
7312 
begin_visit(const SwitchCaseOperandList & v)7313 void* begin_visit(const SwitchCaseOperandList& v)
7314 {
7315   TRACE_VISIT();
7316   // shouldn't get here
7317   ZORBA_ASSERT(false);
7318   return no_state;
7319 }
7320 
end_visit(const SwitchCaseOperandList & v,void *)7321 void end_visit(const SwitchCaseOperandList& v, void* /*visit_state*/)
7322 {
7323   TRACE_VISIT_OUT();
7324 }
7325 
7326 
7327 /////////////////////////////////////////////////////////////////////////////////
7328 //                                                                             //
7329 //  TypeSwitch                                                                 //
7330 //                                                                             //
7331 /////////////////////////////////////////////////////////////////////////////////
7332 
7333 
7334 /*******************************************************************************
7335   TypeswitchExpr ::= "typeswitch" "(" Expr ")"
7336                      CaseClauseList
7337                     "default" ("$" VarName)? "return" ExprSingle
7338 
7339   CaseClauseList := CaseClause+
7340 
7341   CaseClause ::= "case" ("$" VarName "as")? SequenceType "return" ExprSingle
7342 
7343 
7344   A typeswitch expr is translated into a flwor expr. For example, a typeswitch of
7345   the following form:
7346 
7347   typeswitch E
7348   case $v1 as type1 return E1
7349   ......
7350   case $vn as typen return En
7351   default $def return Ed
7352 
7353   is translated into:
7354 
7355   let $sv := E
7356   return if (instance_of($sv, type1)) then
7357            let $v1 := treat_as($sv, type1) return E1
7358          else if (instance_of($sv, type2)) then
7359            let $v2 := treat_as($sv, type2) return E2
7360          ....
7361          else if instance_of($sv, typen)) then
7362            let $vn := treat_as($sv, typen) return En
7363          else
7364            let $def := sv return Ed
7365 ********************************************************************************/
begin_visit(const TypeswitchExpr & v)7366 void* begin_visit(const TypeswitchExpr& v)
7367 {
7368   TRACE_VISIT();
7369 
7370   var_expr* sv = create_temp_var(v.get_switch_expr()->get_location(), var_expr::let_var);
7371 
7372   v.get_switch_expr()->accept(*this);
7373 
7374   expr* se = pop_nodestack();
7375 
7376   // flworExpr = [let $sv := E return NULL]
7377   expr* retExpr = NULL;
7378   expr* flworExpr = wrap_in_let_flwor(se, sv, retExpr);
7379 
7380   const QName* defvar_name = v.get_default_varname();
7381   var_expr* defvar = NULL;
7382 
7383   if (defvar_name)
7384   {
7385     push_scope();
7386     defvar = bind_var(v.get_default_clause()->get_location(),
7387                       defvar_name,
7388                       var_expr::let_var);
7389 
7390     // retExpr = [let $def := $sv return NULL]
7391     retExpr = &*wrap_in_let_flwor(&*sv, defvar, NULL);
7392   }
7393 
7394   v.get_default_clause()->accept(*this);
7395 
7396   expr* defExpr = pop_nodestack();
7397 
7398   if (defvar_name)
7399   {
7400     pop_scope();
7401 
7402     // retExpr = [let $def := $sv return Ed]
7403     static_cast<flwor_expr*>(retExpr)->set_return_expr(defExpr);
7404   }
7405   else
7406   {
7407     // retExpr = [Ed]
7408     retExpr = defExpr;
7409   }
7410 
7411   const CaseClauseList* clauses = v.get_clause_list();
7412   for (std::vector<rchandle<CaseClause> >::const_reverse_iterator it = clauses->rbegin();
7413        it != clauses->rend();
7414        ++it)
7415   {
7416     const CaseClause* caseClause = &**it;
7417     const QueryLoc& loc = caseClause->get_location();
7418     expr* clauseExpr = NULL;
7419 
7420     caseClause->get_type()->accept(*this);
7421     xqtref_t type = pop_tstack();
7422 
7423     const QName* varname = caseClause->get_varname();
7424     var_expr* caseVar = NULL;
7425 
7426     if (varname)
7427     {
7428       push_scope();
7429 
7430       caseVar = bind_var(loc, varname, var_expr::let_var);
7431 
7432       expr* treatExpr = theExprManager->create_treat_expr(theRootSctx,
7433                                         loc,
7434                                         sv,
7435                                         type,
7436                                         TreatIterator::TREAT_EXPR);
7437 
7438       // clauseExpr = [let $caseVar := treat_as($sv, caseType) return NULL]
7439       clauseExpr = wrap_in_let_flwor(treatExpr, caseVar, NULL);
7440     }
7441 
7442     caseClause->get_expr()->accept(*this);
7443     expr* caseExpr = pop_nodestack();
7444 
7445     if (varname)
7446     {
7447       pop_scope();
7448 
7449       // clauseExpr = [let $caseVar := treat_as($sv, caseType) return NULL]
7450       static_cast<flwor_expr*>(clauseExpr)->set_return_expr(caseExpr);
7451     }
7452     else
7453     {
7454       // clauseExpr = [caseExpr]
7455       clauseExpr = caseExpr;
7456     }
7457 
7458     // retExpr = [if (instance_of($sv, type)) then clauseExpr else retExpr]
7459     retExpr = theExprManager->create_if_expr(theRootSctx,
7460                           loc,
7461                           theExprManager->create_instanceof_expr(theRootSctx, loc, &*sv, type),
7462                           clauseExpr,
7463                           retExpr);
7464   }
7465 
7466   static_cast<flwor_expr*>(flworExpr)->set_return_expr(retExpr);
7467 
7468   push_nodestack(flworExpr);
7469 
7470   // Return NULL so that TypeswitchExpr::accept() will not call accept() on the
7471   // children of the TypeswitchExpr parsenode.
7472   return NULL;
7473 }
7474 
7475 
end_visit(const TypeswitchExpr & v,void *)7476 void end_visit (const TypeswitchExpr& v, void* /*visit_state*/)
7477 {
7478   TRACE_VISIT_OUT ();
7479   // shouldn't get here, begin_visit() rejects visitor
7480   ZORBA_ASSERT (false);
7481 }
7482 
7483 
7484 /*******************************************************************************
7485   CaseClauseList := CaseClause+
7486 ********************************************************************************/
begin_visit(const CaseClauseList & v)7487 void* begin_visit(const CaseClauseList& v)
7488 {
7489   TRACE_VISIT();
7490   // shouldn't get here
7491   ZORBA_ASSERT(false);
7492   return no_state;
7493 }
7494 
7495 
end_visit(const CaseClauseList & v,void *)7496 void end_visit(const CaseClauseList& v, void* /*visit_state*/)
7497 {
7498   TRACE_VISIT_OUT();
7499 }
7500 
7501 
7502 /*******************************************************************************
7503   CaseClause ::= "case" ("$" VarName "as")? SequenceType "return" ExprSingle
7504 ********************************************************************************/
begin_visit(const CaseClause & v)7505 void* begin_visit(const CaseClause& v)
7506 {
7507   TRACE_VISIT();
7508   // shouldn't get here
7509   ZORBA_ASSERT(false);
7510   return no_state;
7511 }
7512 
7513 
end_visit(const CaseClause & v,void *)7514 void end_visit(const CaseClause& v, void* /*visit_state*/)
7515 {
7516   TRACE_VISIT_OUT();
7517 }
7518 
7519 
7520 /////////////////////////////////////////////////////////////////////////////////
7521 //                                                                             //
7522 //  If                                                                         //
7523 //                                                                             //
7524 /////////////////////////////////////////////////////////////////////////////////
7525 
7526 
7527 /*******************************************************************************
7528   IfExpr ::= "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle
7529 ********************************************************************************/
begin_visit(const IfExpr & v)7530 void* begin_visit(const IfExpr& v)
7531 {
7532   TRACE_VISIT();
7533   return no_state;
7534 }
7535 
end_visit(const IfExpr & v,void *)7536 void end_visit(const IfExpr& v, void* /*visit_state*/)
7537 {
7538   TRACE_VISIT_OUT();
7539 
7540   expr* e_h = pop_nodestack();
7541   expr* t_h = pop_nodestack();
7542   expr* c_h = pop_nodestack();
7543 
7544   wrap_in_debugger_expr(e_h, e_h->get_loc());
7545   wrap_in_debugger_expr(t_h, t_h->get_loc());
7546   wrap_in_debugger_expr(c_h, c_h->get_loc());
7547 
7548   if_expr* ifExpr = theExprManager->create_if_expr(theRootSctx, loc, c_h, t_h, e_h);
7549 
7550   push_nodestack(ifExpr);
7551 }
7552 
7553 
7554 /////////////////////////////////////////////////////////////////////////////////
7555 //                                                                             //
7556 //  TryCatch                                                                   //
7557 //                                                                             //
7558 /////////////////////////////////////////////////////////////////////////////////
7559 
7560 
7561 /*******************************************************************************
7562   [169] TryCatchExpr ::= TryClause CatchClauseList
7563 
7564   [170] TryClause ::= "try" "{" TryTargetExpr "}"
7565 
7566   [171] TryTargetExpr ::= Expr
7567 ********************************************************************************/
begin_visit(const TryExpr & v)7568 void* begin_visit(const TryExpr& v)
7569 {
7570   TRACE_VISIT();
7571 
7572   if (theSctx->xquery_version() < StaticContextConsts::xquery_version_3_0)
7573   {
7574     RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_TryCatchExpr11)));
7575   }
7576 
7577   theTryStack.push_back(&v);
7578 
7579   return no_state;
7580 }
7581 
end_visit(const TryExpr & v,void * visit_state)7582 void end_visit(const TryExpr& v, void* visit_state)
7583 {
7584   TRACE_VISIT_OUT();
7585 
7586   theTryStack.pop_back();
7587 }
7588 
7589 
7590 /*******************************************************************************
7591   CatchClauseList := CatchClause+
7592 ********************************************************************************/
begin_visit(const CatchListExpr & v)7593 void* begin_visit(const CatchListExpr& v)
7594 {
7595   TRACE_VISIT();
7596 
7597   expr* tryExpr = pop_nodestack();
7598 
7599   trycatch_expr* tce = theExprManager->create_trycatch_expr(theRootSctx, loc, tryExpr);
7600 
7601   push_nodestack(tce);
7602 
7603   return no_state;
7604 }
7605 
end_visit(const CatchListExpr & v,void * visit_state)7606 void end_visit(const CatchListExpr& v, void* visit_state)
7607 {
7608   TRACE_VISIT_OUT();
7609 
7610   trycatch_expr* tce = static_cast<trycatch_expr*>(theNodeStack.top());
7611 
7612   tce->compute_scripting_kind();
7613 }
7614 
7615 
7616 /*******************************************************************************
7617   [172] CatchClause ::= "catch" CatchErrorList "{" Expr "}"
7618 
7619   [173] CatchErrorList ::= NameTest ("|" NameTest)*
7620 ********************************************************************************/
begin_visit(const CatchExpr & v)7621 void* begin_visit(const CatchExpr& v)
7622 {
7623   TRACE_VISIT();
7624 
7625   trycatch_expr* tce = dynamic_cast<trycatch_expr *>(theNodeStack.top());
7626 
7627   catch_clause* cc = theExprManager->create_catch_clause();
7628 
7629   push_scope();
7630 
7631   store::Item_t lCode, lDesc, lValue, lModule, lLineNo, lColumnNo, lStackTrace;
7632 
7633   GENV_ITEMFACTORY->createQName(lCode, XQUERY_ERR_NS, "", "code");
7634   GENV_ITEMFACTORY->createQName(lDesc, XQUERY_ERR_NS, "", "description");
7635   GENV_ITEMFACTORY->createQName(lValue, XQUERY_ERR_NS, "", "value");
7636   GENV_ITEMFACTORY->createQName(lModule, XQUERY_ERR_NS, "", "module");
7637   GENV_ITEMFACTORY->createQName(lLineNo, XQUERY_ERR_NS, "", "line-number");
7638   GENV_ITEMFACTORY->createQName(lColumnNo, XQUERY_ERR_NS, "", "column-number");
7639   GENV_ITEMFACTORY->createQName(lStackTrace, ZORBA_ERR_NS, "", "stack-trace");
7640 
7641   cc->add_var(catch_clause::err_code,
7642       bind_var(loc, lCode, var_expr::catch_var, theRTM.QNAME_TYPE_ONE));
7643 
7644   cc->add_var(catch_clause::err_desc,
7645       bind_var(loc, lDesc, var_expr::catch_var, theRTM.STRING_TYPE_QUESTION));
7646 
7647   cc->add_var(catch_clause::err_value,
7648       bind_var(loc, lValue, var_expr::catch_var, theRTM.ITEM_TYPE_STAR));
7649 
7650   cc->add_var(catch_clause::err_module,
7651       bind_var(loc, lModule, var_expr::catch_var, theRTM.STRING_TYPE_QUESTION));
7652 
7653   cc->add_var(catch_clause::err_line_no,
7654       bind_var(loc, lLineNo, var_expr::catch_var, theRTM.INTEGER_TYPE_QUESTION));
7655 
7656   cc->add_var(catch_clause::err_column_no,
7657       bind_var(loc, lColumnNo, var_expr::catch_var, theRTM.INTEGER_TYPE_QUESTION));
7658 
7659   cc->add_var(catch_clause::zerr_stack_trace,
7660       bind_var(loc, lStackTrace, var_expr::catch_var, theRTM.ITEM_TYPE_QUESTION));
7661 
7662   tce->add_clause(cc);
7663 
7664   return no_state;
7665 }
7666 
end_visit(const CatchExpr & v,void * visit_state)7667 void end_visit(const CatchExpr& v, void* visit_state)
7668 {
7669   TRACE_VISIT_OUT();
7670 
7671   expr* ce = pop_nodestack();
7672   trycatch_expr* tce = dynamic_cast<trycatch_expr *>(theNodeStack.top());
7673 
7674   tce->add_catch_expr(ce);
7675 
7676   pop_scope();
7677 }
7678 
7679 
7680 /////////////////////////////////////////////////////////////////////////////////
7681 //                                                                             //
7682 //  Quantified                                                                 //
7683 //                                                                             //
7684 /////////////////////////////////////////////////////////////////////////////////
7685 
7686 
7687 /*******************************************************************************
7688   QuantifiedExpr ::= ("some" | "every") QVarInDeclList "satisfies" ExprSingle
7689 
7690   QVarInDeclList ::= "$" VarName TypeDeclaration? "in" ExprSingle
7691                      ("," "$" VarName TypeDeclaration? "in" ExprSingle)*
7692 
7693   A universally quantified expr is translated into a flwor expr:
7694 
7695   fn:empty(for $v1 in expr1, ... vn in exprn
7696            where not(testExpr)
7697            return true)
7698 
7699   An existentially quantified expr is translated into a flwor expr:
7700 
7701   fn:exists(for $v1 in expr1, ... vn in exprn
7702             where testExpr
7703             return true)
7704 
7705 ********************************************************************************/
begin_visit(const QuantifiedExpr & v)7706 void* begin_visit(const QuantifiedExpr& v)
7707 {
7708   TRACE_VISIT();
7709 
7710   flwor_expr* flwor(theExprManager->create_flwor_expr(theRootSctx, loc, false));
7711 
7712   flwor->set_return_expr(theExprManager->create_const_expr(theRootSctx, loc, true));
7713 
7714   push_nodestack(flwor);
7715 
7716   return no_state;
7717 }
7718 
7719 
end_visit(const QuantifiedExpr & v,void *)7720 void end_visit(const QuantifiedExpr& v, void* /*visit_state*/)
7721 {
7722   TRACE_VISIT_OUT();
7723 
7724   expr* testExpr = pop_nodestack();
7725 
7726   if (v.get_qmode() == ParseConstants::quant_every)
7727   {
7728     fo_expr* uw = theExprManager->create_fo_expr(theRootSctx,
7729                                        v.get_expr()->get_location(),
7730                                        GET_BUILTIN_FUNCTION(FN_NOT_1),
7731                                        testExpr);
7732     testExpr = uw;
7733   }
7734   else
7735   {
7736     testExpr = wrap_in_bev(testExpr);
7737   }
7738 
7739   for (int i = 0; i < (int)v.get_decl_list()->size(); ++i)
7740   {
7741     pop_scope();
7742   }
7743 
7744   flwor_expr* flworExpr = dynamic_cast<flwor_expr*>(pop_nodestack());
7745   ZORBA_ASSERT(flworExpr != NULL);
7746 
7747   flworExpr->add_where(testExpr);
7748 
7749   fo_expr* quant = theExprManager->create_fo_expr(theRootSctx,
7750                                         loc,
7751                                         v.get_qmode() == ParseConstants::quant_every ?
7752                                         GET_BUILTIN_FUNCTION(FN_EMPTY_1) :
7753                                         GET_BUILTIN_FUNCTION(FN_EXISTS_1),
7754                                         flworExpr);
7755   push_nodestack(quant);
7756 }
7757 
7758 
7759 /*******************************************************************************
7760   QVarInDeclList := QVarInDecl ("," QVarInDecl)*
7761 ********************************************************************************/
begin_visit(const QVarInDeclList & v)7762 void* begin_visit(const QVarInDeclList& v)
7763 {
7764   TRACE_VISIT();
7765   return no_state;
7766 }
7767 
end_visit(const QVarInDeclList & v,void *)7768 void end_visit(const QVarInDeclList& v, void* /*visit_state*/)
7769 {
7770   TRACE_VISIT_OUT();
7771 }
7772 
7773 
7774 /*******************************************************************************
7775   QVarInDecl := "$" VarName TypeDeclaration? "in" ExprSingle
7776 ********************************************************************************/
begin_visit(const QVarInDecl & v)7777 void* begin_visit(const QVarInDecl& v)
7778 {
7779   TRACE_VISIT();
7780   return no_state;
7781 }
7782 
end_visit(const QVarInDecl & v,void *)7783 void end_visit(const QVarInDecl& v, void* /*visit_state*/)
7784 {
7785   TRACE_VISIT_OUT();
7786 
7787   push_scope();
7788   xqtref_t type;
7789   if (v.get_typedecl() != NULL)
7790     type = pop_tstack();
7791 
7792   expr* domainExpr = pop_nodestack();
7793   var_expr* varExpr = bind_var(loc, v.get_name(), var_expr::for_var, type);
7794 
7795   flwor_expr* flworExpr = dynamic_cast<flwor_expr*>(theNodeStack.top());
7796   ZORBA_ASSERT(flworExpr != NULL);
7797 
7798   flworExpr->add_clause(wrap_in_forclause(domainExpr, varExpr, NULL));
7799 }
7800 
7801 
7802 /////////////////////////////////////////////////////////////////////////////////
7803 //                                                                             //
7804 //  OrExpr                                                                     //
7805 //                                                                             //
7806 /////////////////////////////////////////////////////////////////////////////////
7807 
7808 
7809 /*******************************************************************************
7810   OrExpr ::= AndExpr ( "or" AndExpr )*
7811 ********************************************************************************/
begin_visit(const OrExpr & v)7812 void* begin_visit(const OrExpr& v)
7813 {
7814   TRACE_VISIT ();
7815   return no_state;
7816 }
7817 
end_visit(const OrExpr & v,void *)7818 void end_visit(const OrExpr& v, void* /*visit_state*/)
7819 {
7820   TRACE_VISIT_OUT ();
7821 
7822   expr* e1 = pop_nodestack();
7823   expr* e2 = pop_nodestack();
7824 
7825   std::vector<expr*> args;
7826   args.reserve(2);
7827 
7828   if (e2->get_expr_kind() == fo_expr_kind)
7829   {
7830     fo_expr* foArg = static_cast<fo_expr*>(e2);
7831 
7832     if (foArg->get_func()->getKind() == FunctionConsts::OP_OR_N)
7833     {
7834       ulong numArgs = foArg->num_args();
7835       for (ulong i = 0; i < numArgs; ++i)
7836         args.push_back(foArg->get_arg(i));
7837     }
7838     else
7839     {
7840       args.push_back(e2);
7841     }
7842   }
7843   else
7844   {
7845     args.push_back(e2);
7846   }
7847 
7848   if (e1->get_expr_kind() == fo_expr_kind)
7849   {
7850     fo_expr* foArg = static_cast<fo_expr*>(e1);
7851 
7852     if (foArg->get_func()->getKind() == FunctionConsts::OP_OR_N)
7853     {
7854       ulong numArgs = foArg->num_args();
7855       for (ulong i = 0; i < numArgs; ++i)
7856         args.push_back(foArg->get_arg(i));
7857     }
7858     else
7859     {
7860       args.push_back(e1);
7861     }
7862   }
7863   else
7864   {
7865     args.push_back(e1);
7866   }
7867 
7868   fo_expr* fo = theExprManager->create_fo_expr(theRootSctx, loc, GET_BUILTIN_FUNCTION(OP_OR_N), args);
7869 
7870   push_nodestack(fo);
7871 }
7872 
7873 
7874 /*******************************************************************************
7875   AndExpr ::= ComparisonExpr ( "and" ComparisonExpr )*
7876 ********************************************************************************/
begin_visit(const AndExpr & v)7877 void* begin_visit(const AndExpr& v)
7878 {
7879   TRACE_VISIT ();
7880   return no_state;
7881 }
7882 
end_visit(const AndExpr & v,void *)7883 void end_visit(const AndExpr& v, void* /*visit_state*/)
7884 {
7885   TRACE_VISIT_OUT();
7886 
7887   expr* e1 = pop_nodestack();
7888   expr* e2 = pop_nodestack();
7889 
7890   std::vector<expr*> args;
7891   args.reserve(2);
7892 
7893   if (e2->get_expr_kind() == fo_expr_kind)
7894   {
7895     fo_expr* foArg = static_cast<fo_expr*>(e2);
7896 
7897     if (foArg->get_func()->getKind() == FunctionConsts::OP_AND_N)
7898     {
7899       csize numArgs = foArg->num_args();
7900       for (csize i = 0; i < numArgs; ++i)
7901         args.push_back(foArg->get_arg(i));
7902     }
7903     else
7904     {
7905       args.push_back(e2);
7906     }
7907   }
7908   else
7909   {
7910     args.push_back(e2);
7911   }
7912 
7913   if (e1->get_expr_kind() == fo_expr_kind)
7914   {
7915     fo_expr* foArg = static_cast<fo_expr*>(e1);
7916 
7917     if (foArg->get_func()->getKind() == FunctionConsts::OP_AND_N)
7918     {
7919       csize numArgs = foArg->num_args();
7920       for (csize i = 0; i < numArgs; ++i)
7921         args.push_back(foArg->get_arg(i));
7922     }
7923     else
7924     {
7925       args.push_back(e1);
7926     }
7927   }
7928   else
7929   {
7930     args.push_back(e1);
7931   }
7932 
7933   fo_expr* fo = theExprManager->create_fo_expr(theRootSctx, loc, GET_BUILTIN_FUNCTION(OP_AND_N), args);
7934 
7935   push_nodestack(fo);
7936 }
7937 
7938 
7939 /*******************************************************************************
7940   ComparisonExpr ::= RangeExpr ((ValueComp | GeneralComp | NodeComp) RangeExpr)?
7941 
7942   Note: For the full-text extension, the rule for ComparisonExpr is:
7943 
7944   ComparisonExpr ::= FTContainsExpr
7945                      ((ValueComp | GeneralComp | NodeComp) FTContainsExpr)?
7946 
7947 ********************************************************************************/
begin_visit(const ComparisonExpr & v)7948 void* begin_visit(const ComparisonExpr& v)
7949 {
7950   TRACE_VISIT();
7951   return no_state;
7952 }
7953 
end_visit(const ComparisonExpr & v,void *)7954 void end_visit(const ComparisonExpr& v, void* /*visit_state*/)
7955 {
7956   TRACE_VISIT_OUT();
7957 
7958   function* f = NULL;
7959 
7960   if (v.get_gencomp() != NULL)
7961   {
7962     switch (v.get_gencomp()->get_type())
7963     {
7964     case ParseConstants::op_eq:
7965       f = GET_BUILTIN_FUNCTION(OP_EQUAL_2);
7966       break;
7967     case ParseConstants::op_ne:
7968       f = GET_BUILTIN_FUNCTION(OP_NOT_EQUAL_2);
7969       break;
7970     case ParseConstants::op_lt:
7971       f = GET_BUILTIN_FUNCTION(OP_LESS_2);
7972       break;
7973     case ParseConstants::op_le:
7974      f = GET_BUILTIN_FUNCTION(OP_LESS_EQUAL_2);
7975      break;
7976     case ParseConstants::op_gt:
7977       f = GET_BUILTIN_FUNCTION(OP_GREATER_2);
7978       break;
7979     case ParseConstants::op_ge:
7980       f = GET_BUILTIN_FUNCTION(OP_GREATER_EQUAL_2);
7981       break;
7982     }
7983   }
7984   else if (v.get_valcomp() != NULL)
7985   {
7986     switch (v.get_valcomp()->get_type())
7987     {
7988     case ParseConstants::op_val_eq:
7989       f = GET_BUILTIN_FUNCTION(OP_VALUE_EQUAL_2);
7990       break;
7991     case ParseConstants::op_val_ne:
7992       f = GET_BUILTIN_FUNCTION(OP_VALUE_NOT_EQUAL_2);
7993       break;
7994     case ParseConstants::op_val_lt:
7995       f = GET_BUILTIN_FUNCTION(OP_VALUE_LESS_2);
7996       break;
7997     case ParseConstants::op_val_le:
7998      f = GET_BUILTIN_FUNCTION(OP_VALUE_LESS_EQUAL_2);
7999      break;
8000     case ParseConstants::op_val_gt:
8001       f = GET_BUILTIN_FUNCTION(OP_VALUE_GREATER_2);
8002       break;
8003     case ParseConstants::op_val_ge:
8004       f = GET_BUILTIN_FUNCTION(OP_VALUE_GREATER_EQUAL_2);
8005       break;
8006     }
8007   }
8008   else if (v.get_nodecomp() != NULL)
8009   {
8010     switch (v.get_nodecomp()->get_type())
8011     {
8012     case ParseConstants::op_is:
8013       f = GET_BUILTIN_FUNCTION(OP_IS_SAME_NODE_2);
8014       break;
8015     case ParseConstants::op_precedes:
8016       f = GET_BUILTIN_FUNCTION(OP_NODE_BEFORE_2);
8017       break;
8018     case ParseConstants::op_follows:
8019       f = GET_BUILTIN_FUNCTION(OP_NODE_AFTER_2);
8020       break;
8021     }
8022   }
8023 
8024   expr* e1 = pop_nodestack();
8025   expr* e2 = pop_nodestack();
8026 
8027   fo_expr* fo = theExprManager->create_fo_expr(theRootSctx, loc, f, e2, e1);
8028 
8029   normalize_fo(fo);
8030 
8031   push_nodestack(fo);
8032 
8033 #undef M
8034 }
8035 
8036 
8037 /*******************************************************************************
8038   GeneralComp ::= "=" | "!=" | "<" | "<=" | ">" | ">="
8039 ********************************************************************************/
begin_visit(const GeneralComp & v)8040 void* begin_visit(const GeneralComp& v)
8041 {
8042   TRACE_VISIT();
8043   return no_state;
8044 }
8045 
end_visit(const GeneralComp & v,void *)8046 void end_visit(const GeneralComp& v, void* /*visit_state*/)
8047 {
8048   TRACE_VISIT_OUT();
8049 }
8050 
8051 
8052 /*******************************************************************************
8053   ValueComp ::= "eq" | "ne" | "lt" | "le" | "gt" | "ge"
8054 ********************************************************************************/
begin_visit(const ValueComp & v)8055 void* begin_visit(const ValueComp& v)
8056 {
8057   TRACE_VISIT();
8058   return no_state;
8059 }
8060 
end_visit(const ValueComp & v,void *)8061 void end_visit(const ValueComp& v, void* /*visit_state*/)
8062 {
8063   TRACE_VISIT_OUT();
8064 }
8065 
8066 
8067 /*******************************************************************************
8068   NodeComp ::= "is" | "<<" | ">>"
8069 ********************************************************************************/
begin_visit(const NodeComp & v)8070 void* begin_visit(const NodeComp& v)
8071 {
8072   TRACE_VISIT();
8073   return no_state;
8074 }
8075 
end_visit(const NodeComp & v,void *)8076 void end_visit(const NodeComp& v, void* /*visit_state*/)
8077 {
8078   TRACE_VISIT_OUT();
8079 }
8080 
8081 
8082 /*******************************************************************************
8083   RangeExpr ::= AdditiveExpr ( "to" AdditiveExpr )?
8084 ********************************************************************************/
begin_visit(const RangeExpr & v)8085 void* begin_visit(const RangeExpr& v)
8086 {
8087   TRACE_VISIT();
8088   return no_state;
8089 }
8090 
end_visit(const RangeExpr & v,void *)8091 void end_visit(const RangeExpr& v, void* /*visit_state*/)
8092 {
8093   TRACE_VISIT_OUT();
8094 
8095   expr* e1 = pop_nodestack();
8096   expr* e2 = pop_nodestack();
8097 
8098   fo_expr* e = theExprManager->create_fo_expr(theRootSctx, loc, GET_BUILTIN_FUNCTION(OP_TO_2), e2, e1);
8099 
8100   normalize_fo(e);
8101 
8102   push_nodestack(e);
8103 }
8104 
8105 
8106 /*******************************************************************************
8107   AdditiveExpr ::= MultiplicativeExpr ( ("+" | "-") MultiplicativeExpr )*
8108 ********************************************************************************/
begin_visit(const AdditiveExpr & v)8109 void* begin_visit(const AdditiveExpr& v)
8110 {
8111   TRACE_VISIT();
8112   return no_state;
8113 }
8114 
end_visit(const AdditiveExpr & v,void *)8115 void end_visit(const AdditiveExpr& v, void* /*visit_state*/)
8116 {
8117   TRACE_VISIT_OUT();
8118 
8119   expr* e1 = pop_nodestack();
8120   expr* e2 = pop_nodestack();
8121 
8122   function* func = NULL;
8123 
8124   switch (v.get_add_op())
8125   {
8126   case ParseConstants::op_plus:
8127     func = GET_BUILTIN_FUNCTION(OP_ADD_2);
8128     break;
8129   case ParseConstants::op_minus:
8130     func = GET_BUILTIN_FUNCTION(OP_SUBTRACT_2);
8131     break;
8132   }
8133 
8134   fo_expr* foExpr = theExprManager->create_fo_expr(theRootSctx, loc, func, e2, e1);
8135 
8136   normalize_fo(foExpr);
8137 
8138   push_nodestack(foExpr);
8139 }
8140 
8141 
8142 /*******************************************************************************
8143   MultiplicativeExpr ::= UnionExpr (("*" | "div" | "idiv" | "mod") UnionExpr)*
8144 ********************************************************************************/
begin_visit(const MultiplicativeExpr & v)8145 void* begin_visit(const MultiplicativeExpr& v)
8146 {
8147   TRACE_VISIT();
8148   return no_state;
8149 }
8150 
end_visit(const MultiplicativeExpr & v,void *)8151 void end_visit(const MultiplicativeExpr& v, void* /*visit_state*/)
8152 {
8153   TRACE_VISIT_OUT();
8154 
8155   expr* e1 = pop_nodestack();
8156   expr* e2 = pop_nodestack();
8157 
8158   function* f = NULL;
8159   switch (v.get_mult_op())
8160   {
8161   case ParseConstants::op_mul:
8162     f = GET_BUILTIN_FUNCTION(OP_MULTIPLY_2);
8163     break;
8164   case ParseConstants::op_div:
8165     f = GET_BUILTIN_FUNCTION(OP_DIVIDE_2);
8166     break;
8167   case ParseConstants::op_idiv:
8168     f = GET_BUILTIN_FUNCTION(OP_INTEGER_DIVIDE_2);
8169     break;
8170   case ParseConstants::op_mod:
8171     f = GET_BUILTIN_FUNCTION(OP_MOD_2);
8172     break;
8173   }
8174 
8175   fo_expr* foExpr = theExprManager->create_fo_expr(theRootSctx, loc, f, e2, e1);
8176 
8177   normalize_fo(foExpr);
8178 
8179   push_nodestack(foExpr);
8180 }
8181 
8182 
8183 /*******************************************************************************
8184   UnionExpr ::= IntersectExceptExpr (("union" | "|") IntersectExceptExpr)*
8185 ********************************************************************************/
begin_visit(const UnionExpr & v)8186 void* begin_visit(const UnionExpr& v)
8187 {
8188   TRACE_VISIT();
8189   return no_state;
8190 }
8191 
end_visit(const UnionExpr & v,void *)8192 void end_visit(const UnionExpr& v, void* /*visit_state*/)
8193 {
8194   TRACE_VISIT_OUT();
8195 
8196   expr* e1 = pop_nodestack();
8197   expr* e2 = pop_nodestack();
8198 
8199   fo_expr* foExpr = theExprManager->create_fo_expr(theRootSctx,
8200                                 loc,
8201                                 GET_BUILTIN_FUNCTION(OP_UNION_2),
8202                                 e2,
8203                                 e1);
8204 
8205   normalize_fo(foExpr);
8206 
8207   // Union is implemented by a concat iterator, so we have to do node sorting
8208   // and duplicate elimi
8209   push_nodestack(theExprManager->create_fo_expr(theRootSctx,
8210                              loc,
8211                              GET_BUILTIN_FUNCTION(OP_SORT_DISTINCT_NODES_ASC_1),
8212                              foExpr));
8213 }
8214 
8215 
8216 /*******************************************************************************
8217   IntersectExceptExpr ::= InstanceofExpr
8218                           (("intersect" | "except") InstanceofExpr)*
8219 ********************************************************************************/
begin_visit(const IntersectExceptExpr & v)8220 void* begin_visit(const IntersectExceptExpr& v)
8221 {
8222   TRACE_VISIT();
8223   return no_state;
8224 }
8225 
end_visit(const IntersectExceptExpr & v,void *)8226 void end_visit(const IntersectExceptExpr& v, void* /*visit_state*/)
8227 {
8228   TRACE_VISIT_OUT();
8229 
8230   expr* e1 = pop_nodestack();
8231   expr* e2 = pop_nodestack();
8232 
8233   function* f = NULL;
8234   switch (v.get_intex_op())
8235   {
8236   case ParseConstants::op_intersect:
8237     f = GET_BUILTIN_FUNCTION(OP_INTERSECT_2);
8238     break;
8239   case ParseConstants::op_except:
8240     f = GET_BUILTIN_FUNCTION(OP_EXCEPT_2);
8241     break;
8242   }
8243 
8244   fo_expr* foExpr = theExprManager->create_fo_expr(theRootSctx, loc, f, e2, e1);
8245 
8246   normalize_fo(foExpr);
8247 
8248   push_nodestack(theExprManager->create_fo_expr(theRootSctx,
8249                              loc,
8250                              GET_BUILTIN_FUNCTION(OP_SORT_DISTINCT_NODES_ASC_1),
8251                              foExpr));
8252 }
8253 
8254 
8255 /*******************************************************************************
8256   InstanceofExpr ::= TreatExpr ( "instance" "of" SequenceType )?
8257 ********************************************************************************/
begin_visit(const InstanceofExpr & v)8258 void* begin_visit(const InstanceofExpr& v)
8259 {
8260   TRACE_VISIT();
8261   return no_state;
8262 }
8263 
end_visit(const InstanceofExpr & v,void *)8264 void end_visit (const InstanceofExpr& v, void* /*visit_state*/)
8265 {
8266   TRACE_VISIT_OUT();
8267 
8268   push_nodestack(theExprManager->create_instanceof_expr(theRootSctx,
8269                                      loc,
8270                                      pop_nodestack(),
8271                                      pop_tstack()));
8272 }
8273 
8274 
8275 /*******************************************************************************
8276   TreatExpr ::= CastableExpr ( "treat" "as" SequenceType )?
8277 ********************************************************************************/
begin_visit(const TreatExpr & v)8278 void* begin_visit(const TreatExpr& v)
8279 {
8280   TRACE_VISIT ();
8281   return no_state;
8282 }
8283 
end_visit(const TreatExpr & v,void *)8284 void end_visit(const TreatExpr& v, void* /*visit_state*/)
8285 {
8286   TRACE_VISIT_OUT();
8287 
8288   push_nodestack(theExprManager->create_treat_expr(theRootSctx,
8289                                 loc,
8290                                 pop_nodestack(),
8291                                 pop_tstack(),
8292                                 TreatIterator::TREAT_EXPR));
8293 }
8294 
8295 
8296 /*******************************************************************************
8297   CastableExpr ::= CastExpr ( "castable" "as" SingleType )?
8298 ********************************************************************************/
begin_visit(const CastableExpr & v)8299 void* begin_visit(const CastableExpr& v)
8300 {
8301   TRACE_VISIT ();
8302   return no_state;
8303 }
8304 
end_visit(const CastableExpr & v,void *)8305 void end_visit(const CastableExpr& v, void* /*visit_state*/)
8306 {
8307   TRACE_VISIT_OUT();
8308 
8309   push_nodestack(create_cast_expr(loc, pop_nodestack(), pop_tstack(), false));
8310 }
8311 
8312 
create_cast_expr(const QueryLoc & loc,expr * node,xqtref_t type,bool isCast)8313 expr* create_cast_expr(const QueryLoc& loc, expr* node, xqtref_t type, bool isCast)
8314 {
8315   TypeManager* tm = CTX_TM;
8316 
8317   if (TypeOps::is_equal(tm, *type, *GENV_TYPESYSTEM.NOTATION_TYPE_ONE, loc) ||
8318       TypeOps::is_equal(tm, *type, *GENV_TYPESYSTEM.NOTATION_TYPE_QUESTION, loc) ||
8319       TypeOps::is_equal(tm, *type, *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_ONE, loc) ||
8320       TypeOps::is_equal(tm, *type, *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_QUESTION, loc))
8321   {
8322     RAISE_ERROR(err::XPST0080, loc, ERROR_PARAMS(type->toString()));
8323   }
8324 
8325   if (TypeOps::is_subtype(tm, *type, *GENV_TYPESYSTEM.QNAME_TYPE_QUESTION, loc))
8326   {
8327     const const_expr* ce = dynamic_cast<const_expr*>(node);
8328 
8329     if (ce != NULL &&
8330         TypeOps::is_equal(tm,
8331                           *tm->create_value_type(ce->get_val()),
8332                           *GENV_TYPESYSTEM.STRING_TYPE_ONE,
8333                           loc))
8334     {
8335       store::Item_t castLiteral;
8336       try
8337       {
8338         GenericCast::instance()->castToQName(castLiteral,
8339                                              ce->get_val(),
8340                                              theNSCtx,
8341                                              false,
8342                                              CTX_TM,
8343                                              loc);
8344       }
8345       catch (ZorbaException& e)
8346       {
8347         if (isCast)
8348         {
8349           throw;
8350         }
8351         else
8352         {
8353           if (e.diagnostic() == err::FORG0001)
8354             throw;// XQUERY_EXCEPTION(err::XPST0003, ERROR_LOC(loc));
8355           else
8356             RAISE_ERROR(err::XPST0081, loc,
8357             ERROR_PARAMS(castLiteral->getStringValue()));
8358         }
8359       }
8360 
8361       assert(castLiteral != NULL || ! isCast);
8362 
8363       if (isCast)
8364         return theExprManager->create_const_expr(theRootSctx, loc, castLiteral);
8365       else
8366         return theExprManager->create_const_expr(theRootSctx, loc, castLiteral != NULL);
8367     }
8368     else
8369     {
8370       xqtref_t qnameType = (type->get_quantifier() == TypeConstants::QUANT_ONE ?
8371                             GENV_TYPESYSTEM.QNAME_TYPE_ONE :
8372                             GENV_TYPESYSTEM.QNAME_TYPE_QUESTION);
8373 
8374       // when casting to type T, where T is QName or subtype of, and the input
8375       // is not a const expr, then the input MUST be of type T or subtype of.
8376       if (isCast)
8377         // This was previously a treat_expr() with TYPE_MATCH. It was changed to
8378         // cast_expr() in order to allow dynamically computed strings to be cast
8379         // to xs:QName.
8380         return theExprManager->
8381                create_cast_expr(theRootSctx, loc, wrap_in_atomization(node), qnameType);
8382       else
8383         return theExprManager->
8384                create_instanceof_expr(theRootSctx, loc, node, qnameType);
8385     }
8386   }
8387   else
8388   {
8389     if (isCast)
8390       return theExprManager->
8391              create_cast_expr(theRootSctx, loc, wrap_in_atomization(node), type);
8392     else
8393       return theExprManager->
8394              create_castable_expr(theRootSctx, loc, wrap_in_atomization(node), type);
8395   }
8396 }
8397 
8398 
8399 /*******************************************************************************
8400   CastExpr ::= UnaryExpr ( "cast" "as" SingleType )?
8401 ********************************************************************************/
begin_visit(const CastExpr & v)8402 void* begin_visit(const CastExpr& v)
8403 {
8404   TRACE_VISIT();
8405   return no_state;
8406 }
8407 
end_visit(const CastExpr & v,void *)8408 void end_visit(const CastExpr& v, void* /*visit_state*/)
8409 {
8410   TRACE_VISIT_OUT();
8411 
8412   push_nodestack(create_cast_expr(loc, pop_nodestack(), pop_tstack(), true));
8413 }
8414 
8415 
8416 /*******************************************************************************
8417   UnaryExpr ::= ("-" | "+")* ValueExpr
8418 ********************************************************************************/
begin_visit(const UnaryExpr & v)8419 void* begin_visit(const UnaryExpr& v)
8420 {
8421   TRACE_VISIT();
8422   return no_state;
8423 }
8424 
end_visit(const UnaryExpr & v,void *)8425 void end_visit(const UnaryExpr& v, void* /*visit_state*/)
8426 {
8427   TRACE_VISIT_OUT();
8428 
8429   expr* e1 = pop_nodestack();
8430 
8431   fo_expr* foExpr = theExprManager->create_fo_expr(theRootSctx,
8432                                 loc,
8433                                 (v.get_signlist()->get_sign() ?
8434                                  GET_BUILTIN_FUNCTION(OP_UNARY_PLUS_1) :
8435                                  GET_BUILTIN_FUNCTION(OP_UNARY_MINUS_1)),
8436                                 e1);
8437   normalize_fo(foExpr);
8438 
8439   push_nodestack(foExpr);
8440 }
8441 
8442 
begin_visit(const SignList & v)8443 void* begin_visit(const SignList& v)
8444 {
8445   TRACE_VISIT();
8446   return no_state;
8447 }
8448 
end_visit(const SignList & v,void *)8449 void end_visit(const SignList& v, void* /*visit_state*/)
8450 {
8451   TRACE_VISIT_OUT();
8452 }
8453 
8454 
8455 /*******************************************************************************
8456   ValueExpr ::= ValidateExpr | PathExpr | ExtensionExpr
8457 ********************************************************************************/
8458 
8459 
8460 /*******************************************************************************
8461   ValidateExpr ::= "validate" (ValidationMode | ("as" TypeName))? "{" Expr "}"
8462   ValidationMode ::= "lax" | "strict"
8463 ********************************************************************************/
begin_visit(const ValidateExpr & v)8464 void* begin_visit(const ValidateExpr& v)
8465 {
8466   TRACE_VISIT();
8467   return no_state;
8468 }
8469 
end_visit(const ValidateExpr & v,void *)8470 void end_visit(const ValidateExpr& v, void* /*visit_state*/)
8471 {
8472   TRACE_VISIT_OUT();
8473 
8474   store::Item_t qname;
8475   if (v.get_type_name() != NULL)
8476   {
8477     const zstring& prefix = v.get_type_name()->get_prefix();
8478     zstring ns;
8479     theNSCtx->findBinding(prefix, ns);
8480 
8481     GENV_ITEMFACTORY->createQName(qname,
8482                                   ns.c_str(),
8483                                   prefix.c_str(),
8484                                   v.get_type_name()->get_localname().c_str());
8485   }
8486 
8487   push_nodestack(theExprManager->create_validate_expr(theRootSctx,
8488                                    loc,
8489                                    v.get_valmode(),
8490                                    qname,
8491                                    pop_nodestack(),
8492                                    theSctx->get_typemanager()));
8493 }
8494 
8495 
8496 /*******************************************************************************
8497   ExtensionExpr ::= PragmaList "{" Expr? "}"
8498 ********************************************************************************/
begin_visit(const ExtensionExpr & v)8499 void* begin_visit(const ExtensionExpr& v)
8500 {
8501   TRACE_VISIT();
8502 
8503   if (v.get_expr() == NULL)
8504   {
8505     throw XQUERY_EXCEPTION( err::XQST0079, ERROR_LOC(loc) );
8506   }
8507 
8508   return no_state;
8509 }
8510 
end_visit(const ExtensionExpr & v,void *)8511 void end_visit(const ExtensionExpr& v, void* /*visit_state*/)
8512 {
8513   TRACE_VISIT_OUT();
8514 
8515   size_t lNumPragmas = v.get_pragma_list()->get_pragmas().size();
8516   theScopedPragmas.resize(theScopedPragmas.size() - lNumPragmas);
8517 }
8518 
8519 
8520 /*******************************************************************************
8521   PragmaList ::= Pragma | PragmaList  Pragma
8522 ********************************************************************************/
begin_visit(const PragmaList & v)8523 void* begin_visit(const PragmaList& v)
8524 {
8525   TRACE_VISIT();
8526   return no_state;
8527 }
8528 
end_visit(const PragmaList & v,void *)8529 void end_visit(const PragmaList& v, void* /*visit_state*/)
8530 {
8531   TRACE_VISIT_OUT();
8532 }
8533 
8534 
8535 /*******************************************************************************
8536   Pragma ::= "(#" S? QName (S PragmaContents)? "#)"  // ws: explicitXQ
8537   PragmaContents ::= (Char* - (Char* '#)' Char*))
8538 ********************************************************************************/
begin_visit(const Pragma & v)8539 void* begin_visit(const Pragma& v)
8540 {
8541   TRACE_VISIT();
8542   store::Item_t lQName;
8543   expand_no_default_qname(lQName, v.get_name(), v.get_name()->get_location());
8544 
8545   if (lQName->getPrefix().empty() && lQName->getNamespace().empty())
8546   {
8547     RAISE_ERROR(err::XPST0081, loc, ERROR_PARAMS(lQName->getStringValue()));
8548   }
8549 
8550   pragma* lPragma = theExprManager->create_pragma(lQName, v.get_pragma_lit());
8551 
8552   // popped in end_visit(ExtensionExpr)
8553   theScopedPragmas.push_back(lPragma);
8554 
8555   return no_state;
8556 }
8557 
end_visit(const Pragma & v,void *)8558 void end_visit(const Pragma& v, void* /*visit_state*/)
8559 {
8560   TRACE_VISIT_OUT();
8561 }
8562 
8563 
8564 /*******************************************************************************
8565   SimpleMapExpr :: PathExpr |
8566                    SimpleMapExpr "!" PathExpr
8567 
8568   This creates a left-deep tree of SimpleMapExpr nodes: the right child of each
8569   such node is a PathExpr, and the left child is another SimpleMapExpr except
8570   from the left-most SimpleMapExpr node, whose left chils is a PathExpr.
8571 ********************************************************************************/
begin_visit(const SimpleMapExpr & v)8572 void* begin_visit(const SimpleMapExpr& v)
8573 {
8574   TRACE_VISIT();
8575 
8576   v.get_left_expr()->accept(*this);
8577 
8578   expr* left  = pop_nodestack();
8579 
8580   flwor_expr* flworExpr = wrap_expr_in_flwor(left, true);
8581 
8582   v.get_right_expr()->accept(*this);
8583 
8584   expr* right = pop_nodestack();
8585 
8586   flworExpr->set_return_expr(right);
8587 
8588   pop_scope();
8589 
8590   push_nodestack(flworExpr);
8591 
8592   return NULL;
8593 }
8594 
end_visit(const SimpleMapExpr & v,void *)8595 void end_visit(const SimpleMapExpr& v, void* /* visit_state */)
8596 {
8597   TRACE_VISIT_OUT();
8598 }
8599 
8600 
8601 /////////////////////////////////////////////////////////////////////////////////
8602 //                                                                             //
8603 //  PathExpr                                                                   //
8604 //                                                                             //
8605 /////////////////////////////////////////////////////////////////////////////////
8606 
8607 
8608 /*******************************************************************************
8609 
8610   Path Expressions
8611 
8612   PathExpr ::= ("/" RelativePathExpr?) |
8613                ("//" RelativePathExpr) |
8614                RelativePathExpr 	// gn: leading-lone-slashXQ
8615 
8616   RelativePathExpr ::= StepExpr (("/" | "//") StepExpr)*
8617 
8618   StepExpr ::= PostfixExpr | AxisStep
8619 
8620   AxisStep ::= (ReverseStep | ForwardStep) PredicateList
8621 
8622   ForwardStep ::= (ForwardAxis NodeTest) | AbbrevForwardStep
8623 
8624   ForwardAxis ::= ("child" "::") |
8625                   ("descendant" "::") |
8626                   ("attribute" "::") |
8627                   ("self" "::") |
8628                   ("descendant-or-self" "::") |
8629                   ("following-sibling" "::") |
8630                   ("following" "::")
8631 
8632   AbbrevForwardStep ::= "@"? NodeTest
8633 
8634   ReverseStep ::= (ReverseAxis NodeTest) | AbbrevReverseStep
8635 
8636   ReverseAxis ::= ("parent" "::") |
8637                   ("ancestor" "::") |
8638                   ("preceding-sibling" "::") |
8639                   ("preceding" "::") |
8640                   ("ancestor-or-self" "::")
8641 
8642   AbbrevReverseStep ::= ".."
8643 
8644   NodeTest ::= KindTest | NameTest
8645 
8646   NameTest ::= QName | Wildcard
8647 
8648   Wildcard ::= "*" | (NCName ":" "*") | ("*" ":" NCName)
8649 
8650   PostfixExpr ::= PrimaryExpr (Predicate | ArgumentList)*
8651 
8652   PredicateList ::= Predicate*
8653 
8654   Predicate ::= "[" Expr "]"
8655 
8656 
8657   If a path expr is actually a standalone filter expr, then no PathExpr parsenode
8658   (and parse subtree) is generated. Otherwise, the syntax tree for a generic
8659   PathExpr looks like this:
8660 
8661        PathExpr
8662            |
8663          rpe1
8664         /    \
8665       step1  rpe2
8666             /    \
8667           step2  rpe3
8668                 /    \
8669               step3  step4
8670 
8671   In general, rpe-i says how step-i is connected with step-(i+1), i.e. with / or //.
8672 
8673   The root PathExpr node says whether the path expr starts with a / or // or an
8674   input step expr. In particular, the type of PathExpr can be one of the following:
8675 
8676   1. path_leading_lone_slash (/)
8677   2. path_leading_slash      (/...)
8678   3. path_leading_slashslash (//...)
8679   4. path_relative           (source_expr/...)
8680 
8681   In case 1, the PathExpr node does not have any child node.
8682 
8683   In cases 2 and 3 step1 is missing, i.e., the syntax tree is like this:
8684 
8685        PathExpr
8686            |
8687          rpe1
8688         /    \
8689       NULL   rpe2
8690             /    \
8691           step2  rpe3
8692                 /    \
8693               step3  step4
8694 
8695   where, the type of PathExpr is path_relative and rpe1 designates a "/". In
8696   these cases, the translator behaves as if step1 was either
8697   fn:root(./self::node()) in case 2, or
8698   fn:root(./self::node())/descendant-or-self::node() in case 3.
8699 
8700   In general, a path expression is translated into a combination of relpath_exprs
8701   and flwor_exprs. relpath_exprs are created to represent the portions of a path
8702   expression whose steps consist of AxisSteps with no predicates. flwor_exprs
8703   are are created to represent steps that are FilterExprs or AxisSteps with
8704   predicates.
8705 
8706   For example, the expr:
8707 
8708   sourceExpr/a/b/c[predExpr]/d
8709 
8710   is translated into:
8711 
8712   (
8713   for $dot1 in sourceExpr/a/b
8714   let $temp := $dot1/c
8715   return for $dot2 at $pos in $temp
8716          return if (predExpr instance of numeric)
8717                 then if ($pos eq predExpr) then $dot2 else ()
8718                 else if (predExpr) then $dot2 else ()
8719   )/d
8720 
8721 
8722   If predExpr is a numeric constant, then during optimization the above flwor
8723   will go through the following rewrites:
8724 
8725   for $dot1 in sourceExpr/a/b
8726   let $temp := $dot1/c
8727   return for $dot2 at $pos in $temp
8728          return if ($pos eq predExpr) then $dot2 else ()
8729 
8730   for $dot1 in sourceExpr/a/b
8731   let $temp := $dot1/c
8732   return for $dot2 at $pos in $temp
8733          where ($pos eq predExpr)
8734          return $dot2
8735 
8736   for $dot1 in sourceExpr/a/b
8737   let $temp := $dot1/c
8738   return for $dot2 in subsequence($temp, predExpr, 1)
8739          return $dot2
8740 
8741   for $dot1 in sourceExpr/a/b
8742   return for $dot2 in subsequence($dot1/c, predExpr, 1)
8743          return $dot2
8744 ********************************************************************************/
begin_visit(const PathExpr & v)8745 void* begin_visit(const PathExpr& v)
8746 {
8747   TRACE_VISIT();
8748 
8749   const PathExpr& pe = v;
8750 
8751   ParseConstants::pathtype_t pe_type = pe.get_type();
8752 
8753   // terrible hack to allow for a standalone true, false or null to be
8754   // interpreted as a boolean. User must use ./true, ./false or ./null for
8755   // navigating XML elements named that way.
8756 #ifdef ZORBA_WITH_JSON
8757   if (pe_type == ParseConstants::path_relative)
8758   {
8759     RelativePathExpr* lRootRelPathExpr =
8760     dynamic_cast<RelativePathExpr*>(pe.get_relpath_expr().getp());
8761 
8762     ContextItemExpr* lStepExpr =
8763     dynamic_cast<ContextItemExpr*>(lRootRelPathExpr->get_step_expr());
8764 
8765     AxisStep* lRelPathExpr =
8766     dynamic_cast<AxisStep*>(lRootRelPathExpr->get_relpath_expr());
8767 
8768     // Only rewrites if expression consists of a context item step on the left
8769     // and of an axis step on the right,
8770     // AND if this context item was set implicitly by the parser, meaning,
8771     // the original expression was only an axis step.
8772     if (lRelPathExpr && lStepExpr && lRootRelPathExpr->is_implicit())
8773     {
8774       ForwardStep* lFwdStep =
8775       dynamic_cast<ForwardStep*>(lRelPathExpr->get_forward_step());
8776 
8777       if (lFwdStep && lFwdStep->get_axis_kind() == ParseConstants::axis_child)
8778       {
8779         AbbrevForwardStep* lAbbrFwdStep =
8780         dynamic_cast<AbbrevForwardStep*>(lFwdStep->get_abbrev_step());
8781 
8782         if (lAbbrFwdStep)
8783         {
8784           const NameTest* lNodetest =
8785           dynamic_cast<const NameTest*>(lAbbrFwdStep->get_node_test());
8786 
8787           if (lNodetest)
8788           {
8789             const rchandle<QName> lQName = lNodetest->getQName();
8790 
8791             if (lQName && lQName->get_prefix() == "")
8792             {
8793               const zstring& lLocal = lQName->get_localname();
8794 
8795               if (lLocal == "true")
8796               {
8797                 push_nodestack(theExprManager->create_const_expr(theRootSctx, loc, true));
8798                 return (void*)1;
8799               }
8800               else if (lLocal == "false")
8801               {
8802                 push_nodestack(theExprManager->create_const_expr(theRootSctx, loc, false));
8803                 return (void*)1;
8804               }
8805               else if (lLocal == "null")
8806               {
8807                 store::Item_t lNull;
8808                 GENV_ITEMFACTORY->createJSONNull(lNull);
8809                 push_nodestack(theExprManager->create_const_expr(theRootSctx, loc, lNull));
8810                 return (void*)1;
8811               }
8812             }
8813           }
8814         }
8815       }
8816     }
8817   }
8818 #endif
8819 
8820   relpath_expr* pathExpr = NULL;
8821 
8822   // Put a NULL in the stack to mark the beginning of a PathExp tree.
8823   push_nodestack(NULL);
8824 
8825   theNodeSortStack.push(NodeSortInfo());
8826 
8827   // In cases 2, 3, and 4 create a new empty relpath_expr
8828   if (pe_type != ParseConstants::path_leading_lone_slash)
8829   {
8830     pathExpr = theExprManager->create_relpath_expr(theRootSctx, loc);
8831   }
8832 
8833   // If path expr starts with / or // (cases 1, 2, or 3), create an expr
8834   // R = fn:root(./self::node()).
8835   //
8836   // In case 1, just push R to the nodestack.
8837   //
8838   // In case 2 and 3, put empty relpath_expr and R to the nodestact
8839   //
8840   // In case 4, put empty relpath_expr to the nodestack
8841 
8842   if (pe_type != ParseConstants::path_relative)
8843   {
8844     relpath_expr* ctx_path_expr = theExprManager->create_relpath_expr(theRootSctx, loc);
8845 
8846     expr* sourceExpr = theExprManager->create_treat_expr(theRootSctx,
8847                                        loc,
8848                                        DOT_REF,
8849                                        GENV_TYPESYSTEM.ANY_NODE_TYPE_ONE,
8850                                        TreatIterator::PATH_DOT);
8851 
8852     ctx_path_expr->add_back(sourceExpr);
8853 
8854     match_expr* me = theExprManager->create_match_expr(theRootSctx, loc);
8855     me->setTestKind(match_anykind_test);
8856     axis_step_expr* ase = theExprManager->create_axis_step_expr(theRootSctx, loc);
8857     ase->setAxis(axis_kind_self);
8858     ase->setTest(me);
8859 
8860     ctx_path_expr->add_back(&*ase);
8861 
8862     fo_expr* fnroot = theExprManager->create_fo_expr(theRootSctx,
8863                                    loc,
8864                                    GET_BUILTIN_FUNCTION(FN_ROOT_1),
8865                                    ctx_path_expr);
8866     normalize_fo(fnroot);
8867 
8868     if (pathExpr != NULL)
8869     {
8870       // cases 2 or 3
8871       push_nodestack(pathExpr);
8872       push_nodestack(fnroot);
8873 
8874       theNodeSortStack.top().theNumSteps++;
8875     }
8876     else
8877     {
8878       // case 1
8879       expr* result = theExprManager->create_treat_expr(theRootSctx,
8880                                      loc,
8881                                      fnroot,
8882                                      GENV_TYPESYSTEM.DOCUMENT_TYPE_ONE,
8883                                      TreatIterator::TREAT_EXPR);
8884       push_nodestack(result);
8885     }
8886   }
8887   else
8888   {
8889     // case 4
8890     push_nodestack(pathExpr);
8891   }
8892 
8893   return no_state;
8894 }
8895 
8896 
end_visit(const PathExpr & v,void *)8897 void end_visit(const PathExpr& v, void* /*visit_state*/)
8898 {
8899   TRACE_VISIT_OUT();
8900 
8901   expr* arg2 = pop_nodestack();
8902   expr* arg1 = pop_nodestack();
8903 
8904   ZORBA_ASSERT(arg1 == NULL);
8905 
8906 #ifdef NODE_SORT_OPT
8907   NodeSortInfo& nodeSortInfo = theNodeSortStack.top();
8908 
8909   if (!nodeSortInfo.theSingleInput ||
8910       nodeSortInfo.theHaveFilterSteps ||
8911       (nodeSortInfo.theNumSteps > 1 && !nodeSortInfo.theOnlyChildAxes))
8912   {
8913     // wrap in atomics_or_node_distinc_sort_asc
8914     push_nodestack(wrap_in_dos_and_dupelim(arg2, true));
8915   }
8916   else
8917   {
8918     fo_expr* checkExpr =
8919       theExprManager->create_fo_expr(theRootSctx,
8920                   arg2->get_loc(),
8921                   GET_BUILTIN_FUNCTION(OP_EITHER_NODES_OR_ATOMICS_1),
8922                   arg2);
8923 
8924     push_nodestack(checkExpr);
8925   }
8926 #else
8927   // wrap in atomics_or_node_distinc_sort_asc
8928   push_nodestack(wrap_in_dos_and_dupelim(arg2, true));
8929 #endif
8930 
8931   theNodeSortStack.pop();
8932 }
8933 
8934 
8935 /*******************************************************************************
8936 
8937   RelativePathExpr ::= StepExpr (("/" | "//") StepExpr)*
8938 
8939   Note: If a RelativePathExpr consists of a single StepExpr, a RelativePathExpr
8940   node is generated whose left child is a ContextItemExpr and its right child
8941   is the StepExpr.
8942 
8943 ********************************************************************************/
begin_visit(const RelativePathExpr & v)8944 void* begin_visit(const RelativePathExpr& v)
8945 {
8946   TRACE_VISIT();
8947 
8948   const RelativePathExpr& rpe = v;
8949 
8950   rchandle<exprnode> step = rpe.get_step_expr();
8951 
8952   if (step == NULL)
8953     return no_state;
8954 
8955   AxisStep* axisStep = step.dyn_cast<AxisStep>();
8956 
8957   // Let rpe be the i-th rpe in the Path Tree. Then pathExpr represents the
8958   // translation of step-1/.../step-(i-1)/.
8959   expr* e = pop_nodestack();
8960   relpath_expr* pathExpr = dynamic_cast<relpath_expr*>(e);
8961   ZORBA_ASSERT(pathExpr != NULL);
8962 
8963   // If case 4 and i = 1, then pathExpr is empty.
8964   if (pathExpr->size() == 0)
8965   {
8966     // If the path expr is of the form "axis::test/...." or "axis::test[pred]/...."
8967     // then the input expr to the this path expr is "treat . as node()"
8968     if (axisStep != NULL)
8969     {
8970       expr* sourceExpr = theExprManager->create_treat_expr(theRootSctx,
8971                                          loc,
8972                                          DOT_REF,
8973                                          GENV_TYPESYSTEM.ANY_NODE_TYPE_ONE,
8974                                          TreatIterator::PATH_DOT);
8975       pathExpr->add_back(sourceExpr);
8976 
8977       if (axisStep->get_predicate_list() == NULL)
8978       {
8979         // "axis::test/...." ==> push [ pathExpr(sourceExpr) ] to the nodestack.
8980         push_nodestack(pathExpr);
8981       }
8982       else
8983       {
8984         // "axis::test[pred]/...." ==> push [ for $dot at $pos in pathExpr(sourceExpr) ]
8985         // to the nodestack.
8986         flwor_expr* flworExpr = wrap_expr_in_flwor(pathExpr, false);
8987         push_nodestack(flworExpr);
8988       }
8989     }
8990     // "source_expr/...." ==> push pathExpr() to the nodestack.
8991     else
8992     {
8993       push_nodestack(pathExpr);
8994     }
8995   }
8996 
8997   // Else if step-i is an axis step with no repdicates, just put pathExpr(...)
8998   // back in the stack.
8999   else if (axisStep != NULL && axisStep->get_predicate_list() == NULL)
9000   {
9001     push_nodestack(pathExpr);
9002   }
9003 
9004   // Else, step-i is an axis step with predicates or a filter expr, and is not
9005   // the very 1st step in the path expr. In this case, pathExpr becomes the
9006   // input to a new flwor expr that will compute, once for each node in pathExpr,
9007   // the next step in the path. In particular, the following expr is pushed to
9008   // the stack:
9009   //
9010   // [ for $$dot at $$pos in node_distinc_sort_asc(pathExpr) ]
9011   else
9012   {
9013     expr* inputExpr = wrap_in_dos_and_dupelim(pathExpr, true);
9014     flwor_expr* flworExpr = wrap_expr_in_flwor(inputExpr, false);
9015     push_nodestack(flworExpr);
9016   }
9017 
9018   return no_state;
9019 }
9020 
9021 
intermediate_visit(const RelativePathExpr & rpe,void *)9022 void intermediate_visit(const RelativePathExpr& rpe, void* /*visit_state*/)
9023 {
9024   const QueryLoc& loc = rpe.get_location();
9025 
9026   // Let rpe be the i-th rpe in the Path Tree. This method is called after having
9027   // translated step-i, but before starting the translation of rpe-(i+1).
9028 
9029   // There were 2 exprs in the stack: stepExpr is the expr for step-i and curExpr
9030   // is the expr we have constructed so far for the ancestors of rpe-i. CurExpr
9031   // is either a path expr or a flwor expr.
9032   expr* stepExpr = pop_nodestack();
9033   expr* curExpr = pop_nodestack();
9034   relpath_expr* pathExpr = dynamic_cast<relpath_expr*>(curExpr);
9035   flwor_expr* flworExpr = dynamic_cast<flwor_expr*>(curExpr);
9036 
9037   // If curExpr is a path expr, step-i was an axis step with no predicates, or
9038   // the path expr is of the form "source_expr/...." and i = 1.
9039   if (pathExpr != NULL)
9040   {
9041     axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*>(stepExpr);
9042     ZORBA_ASSERT(axisExpr != NULL || pathExpr->size() == 0);
9043 
9044 #ifdef NODE_SORT_OPT
9045     if (pathExpr->size() == 0)
9046     {
9047       TreatIterator::ErrorKind errKind = TreatIterator::PATH_STEP;
9048 
9049       if (stepExpr->get_expr_kind() == wrapper_expr_kind)
9050       {
9051         wrapper_expr* tmp = static_cast<wrapper_expr*>(stepExpr);
9052         var_expr* dotVar = lookup_var(DOT_VARNAME, loc, zerr::ZXQP0000_NO_ERROR);
9053         if (tmp->get_expr() == dotVar)
9054           errKind = TreatIterator::PATH_DOT;
9055       }
9056 
9057       expr* sourceExpr = theExprManager->create_treat_expr(theRootSctx,
9058                                          stepExpr->get_loc(),
9059                                          stepExpr,
9060                                          GENV_TYPESYSTEM.ANY_NODE_TYPE_STAR,
9061                                          errKind);
9062 
9063       if (sourceExpr->get_return_type()->max_card() > 1)
9064         theNodeSortStack.top().theSingleInput = false;
9065 
9066       pathExpr->add_back(sourceExpr);
9067     }
9068     else
9069     {
9070       pathExpr->add_back(stepExpr);
9071     }
9072 #else
9073     pathExpr->add_back(stepExpr);
9074 #endif
9075   }
9076 
9077   // Else, step-i was not an axis step, or it contained predicates. In this
9078   // case, translation of step-i resulted in a flwor expr that includes step-i
9079   // and all the ancestors of rpe-i. We create a new path_expr and make the
9080   // flwor expr its 1st step (i.e. flwor/.... or flwor/descendant-or-sef/...)
9081   else
9082   {
9083     ZORBA_ASSERT(flworExpr != NULL);
9084 
9085     flworExpr->set_return_expr(stepExpr);
9086     pop_scope();
9087 
9088     pathExpr = theExprManager->create_relpath_expr(theRootSctx, loc);
9089 
9090     expr* sourceExpr = flworExpr;
9091 
9092     // If step-i was a reverse axis with predicates, we must reorder the
9093     // result of flworExpr because it is going to be produced in reverse
9094     // doc order.
9095     AxisStep* axisStep = dynamic_cast<AxisStep*>(rpe.get_step_expr());
9096 
9097     if (axisStep != NULL && axisStep->get_reverse_step() != NULL)
9098     {
9099       sourceExpr = wrap_in_dos_and_dupelim(sourceExpr, true);
9100     }
9101 
9102     if (axisStep == NULL)
9103       theNodeSortStack.top().theHaveFilterSteps = true;
9104 
9105     pathExpr->add_back(sourceExpr);
9106   }
9107 
9108   // Convert // to /descendant-or-self::node()/
9109   if (rpe.get_step_type() == ParseConstants::st_slashslash)
9110   {
9111     axis_step_expr* ase = theExprManager->create_axis_step_expr(theRootSctx, loc);
9112     match_expr* me = theExprManager->create_match_expr(theRootSctx, loc);
9113     me->setTestKind(match_anykind_test);
9114     ase->setAxis(axis_kind_descendant_or_self);
9115     ase->setTest(me);
9116     pathExpr->add_back(ase);
9117 
9118     theNodeSortStack.top().theNumSteps++;
9119     theNodeSortStack.top().theOnlyChildAxes = false;
9120   }
9121 
9122   rchandle<exprnode> child2 = rpe.get_relpath_expr();
9123   ZORBA_ASSERT(child2 != NULL);
9124   AxisStep* axisStep = child2.dyn_cast<AxisStep>();
9125 
9126   // If the second child of rpe-i is another rpe or an axis step with no
9127   // predicates, then we push the current path_expr to the stack.
9128   if (child2.dyn_cast<RelativePathExpr>() != NULL ||
9129       (axisStep != NULL && axisStep->get_predicate_list() == NULL))
9130   {
9131     push_nodestack(pathExpr);
9132   }
9133 
9134   // Else we have reached the last step of the Path Tree, and this step is a
9135   // filter step or an axis step with predicates. In this case, pathExpr
9136   // becomes the input to a new flwor expr that will compute, once for each
9137   // node in pathExpr, the next step in the path. The flwor is pushed to the
9138   // nodestack.
9139   else
9140   {
9141     expr* inputSeqExpr = wrap_in_dos_and_dupelim(pathExpr, false);
9142     flwor_expr* flworExpr = wrap_expr_in_flwor(inputSeqExpr, (axisStep == NULL));
9143     push_nodestack(flworExpr);
9144   }
9145 }
9146 
9147 
end_visit(const RelativePathExpr & v,void *)9148 void end_visit(const RelativePathExpr& v, void* /*visit_state*/)
9149 {
9150   TRACE_VISIT_OUT();
9151 
9152   const RelativePathExpr& rpe = v;
9153   rchandle<exprnode> child2 = rpe.get_relpath_expr();
9154 
9155   // If rpe-i is not the bottom rpe in the Path Tree, there is nothing to be done.
9156   if (child2.dyn_cast<RelativePathExpr>() != NULL)
9157     return;
9158 
9159   // There were 2 exprs in the stack: stepExpr is the expr for step-(i+1) and
9160   // curExpr is the expr we have constructed so far for step-i and the ancestors
9161   // of rpe-i. CurExpr is either a path expr or a flwor expr.
9162   expr* stepExpr = pop_nodestack();
9163   expr* curExpr = pop_nodestack();
9164 
9165   axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*>(stepExpr);
9166   relpath_expr* pathExpr = dynamic_cast<relpath_expr*>(curExpr);
9167   flwor_expr* flworExpr = dynamic_cast<flwor_expr*>(curExpr);
9168 
9169   // If curExpr is a path expr, step-(i+1) was an axis step with no predicates.
9170   if (pathExpr != NULL)
9171   {
9172     ZORBA_ASSERT(axisExpr != NULL);
9173 
9174     pathExpr->add_back(stepExpr);
9175     push_nodestack(pathExpr);
9176   }
9177   else
9178   {
9179     ZORBA_ASSERT(flworExpr != NULL);
9180     ZORBA_ASSERT(stepExpr != NULL);
9181 
9182     if (child2.dyn_cast<AxisStep>() == NULL)
9183       theNodeSortStack.top().theHaveFilterSteps = true;
9184 
9185     flworExpr->set_return_expr(stepExpr);
9186     pop_scope();
9187 
9188     push_nodestack(flworExpr);
9189   }
9190 }
9191 
9192 
9193 /*******************************************************************************
9194   StepExpr ::= PostfixExpr | AxisStep
9195 ********************************************************************************/
9196 
9197 
9198 /*******************************************************************************
9199   AxisStep ::= (ReverseStep | ForwardStep) PredicateList
9200 ********************************************************************************/
begin_visit(const AxisStep & v)9201 void* begin_visit(const AxisStep& v)
9202 {
9203   TRACE_VISIT();
9204 
9205   axis_step_expr* ase = theExprManager->create_axis_step_expr(theRootSctx, loc);
9206   push_nodestack(ase);
9207 
9208   theNodeSortStack.top().theNumSteps++;
9209 
9210   return no_state;
9211 }
9212 
9213 
9214 /*******************************************************************************
9215   This method is called from AxisStep::accept() after the step itself is
9216   translated, but before the associated predicate list (if any) is translated.
9217 ********************************************************************************/
post_axis_visit(const AxisStep & v,void *)9218 void post_axis_visit(const AxisStep& v, void* /*visit_state*/)
9219 {
9220   expr* e = pop_nodestack();
9221   axis_step_expr* axisExpr = dynamic_cast<axis_step_expr*>(e);
9222   ZORBA_ASSERT(axisExpr != NULL);
9223   axis_kind_t axisKind = axisExpr->getAxis();
9224 
9225   if (axisKind != axis_kind_child)
9226     theNodeSortStack.top().theOnlyChildAxes = false;
9227 
9228   PredicateList* pl = v.get_predicate_list();
9229 
9230   // Nothing to do if there are no predicates
9231   if (pl == NULL || pl->size() == 0)
9232   {
9233     push_nodestack(e);
9234     return;
9235   }
9236 
9237   const QueryLoc& loc = v.get_location();
9238 
9239   e = pop_nodestack();
9240   flwor_expr* flworExpr = dynamic_cast<flwor_expr*>(e);
9241   ZORBA_ASSERT(flworExpr != NULL);
9242 
9243   // The flworExpr was created in begin_visit(const RelativePathExpr& v), and
9244   // it is of the form:
9245   //
9246   // [ for $$dot at $$pos in node_distinc_sort_asc(pathExpr-(i-1)) ]
9247   //
9248   // Here, we add a let clause to the flworExpr:
9249   //
9250   // [ for $$dot at $$pos in node_distinc_sort_asc(pathExpr-(i-1))
9251   //   let $$predInput := $$dot/axis::test ]
9252   //
9253   // Furthermore, if it is a reverse axis, we set theReverseOrder flag of the
9254   // axist_step_expr to true
9255   //
9256   // The $$predInput var will compute and store for each $$dot, the input seq for
9257   // the preds that follow the axis step.
9258   //
9259   // The flworExpr as well as the $$predInput varExpr are pushed to the nodestack.
9260   const for_clause* fcOuterDot = static_cast<const for_clause*>(flworExpr->get_clause(0));
9261   relpath_expr* predPathExpr = theExprManager->create_relpath_expr(theRootSctx, loc);
9262   predPathExpr->add_back(theExprManager->create_wrapper_expr(theRootSctx, loc, fcOuterDot->get_var()));
9263   predPathExpr->add_back(axisExpr);
9264 
9265   expr* predInputExpr = predPathExpr;
9266 
9267   if (axisExpr->is_reverse_axis())
9268   {
9269     axisExpr->set_reverse_order();
9270   }
9271 
9272   let_clause* lcPredInput = wrap_in_letclause(predInputExpr);
9273 
9274   flworExpr->add_clause(lcPredInput);
9275 
9276   push_nodestack(flworExpr);
9277   push_nodestack(lcPredInput->get_var());
9278 }
9279 
9280 
end_visit(const AxisStep & v,void *)9281 void end_visit(const AxisStep& v, void* /*visit_state*/)
9282 {
9283   TRACE_VISIT_OUT();
9284 }
9285 
9286 
9287 /*******************************************************************************
9288   ForwardStep ::= (ForwardAxis NodeTest) | AbbrevForwardStep
9289 ********************************************************************************/
begin_visit(const ForwardStep & v)9290 void* begin_visit(const ForwardStep& v)
9291 {
9292   TRACE_VISIT ();
9293   return no_state;
9294 }
9295 
9296 
end_visit(const ForwardStep & v,void *)9297 void end_visit(const ForwardStep& v, void* /*visit_state*/)
9298 {
9299   TRACE_VISIT_OUT();
9300 }
9301 
9302 
9303 /*******************************************************************************
9304   AbbrevForwardStep ::= "@"? NodeTest
9305 ********************************************************************************/
begin_visit(const AbbrevForwardStep & v)9306 void* begin_visit(const AbbrevForwardStep& v)
9307 {
9308   TRACE_VISIT();
9309 
9310   axis_step_expr* ase = expect_axis_step_top();
9311 
9312   if (v.get_attr_bit())
9313   {
9314     ase->setAxis(axis_kind_attribute);
9315   }
9316   else
9317   {
9318     const parsenode* nodeTest = v.get_node_test();
9319 
9320     if (dynamic_cast<const AttributeTest*>(nodeTest) == NULL &&
9321         dynamic_cast<const SchemaAttributeTest*>(nodeTest) == NULL)
9322     {
9323       ase->setAxis(axis_kind_child);
9324     }
9325     else
9326     {
9327       ase->setAxis(axis_kind_attribute);
9328     }
9329   }
9330 
9331   return no_state;
9332 }
9333 
9334 
end_visit(const AbbrevForwardStep & v,void *)9335 void end_visit(const AbbrevForwardStep& v, void* /*visit_state*/)
9336 {
9337   TRACE_VISIT_OUT();
9338 }
9339 
9340 
9341 /*******************************************************************************
9342   ReverseStep ::= (ReverseAxis NodeTest) | AbbrevReverseStep
9343   AbbrevReverseStep ::= ".."
9344 ********************************************************************************/
begin_visit(const ReverseStep & v)9345 void* begin_visit(const ReverseStep& v)
9346 {
9347   TRACE_VISIT();
9348   return no_state;
9349 }
9350 
9351 
end_visit(const ReverseStep & v,void *)9352 void end_visit(const ReverseStep& v, void* /*visit_state*/)
9353 {
9354   TRACE_VISIT_OUT();
9355 }
9356 
9357 
9358 /*******************************************************************************
9359 
9360 ********************************************************************************/
begin_visit(const ForwardAxis & v)9361 void* begin_visit(const ForwardAxis& v)
9362 {
9363   TRACE_VISIT();
9364   return no_state;
9365 }
9366 
9367 
end_visit(const ForwardAxis & v,void *)9368 void end_visit(const ForwardAxis& v, void* /*visit_state*/)
9369 {
9370   TRACE_VISIT_OUT();
9371 
9372   axis_step_expr* ase = expect_axis_step_top ();
9373 
9374   switch (v.get_axis())
9375   {
9376   case ParseConstants::axis_child:
9377   {
9378     ase->setAxis(axis_kind_child);
9379     break;
9380   }
9381   case ParseConstants::axis_descendant:
9382   {
9383     ase->setAxis(axis_kind_descendant);
9384     break;
9385   }
9386   case ParseConstants::axis_attribute:
9387   {
9388     ase->setAxis(axis_kind_attribute);
9389     break;
9390   }
9391   case ParseConstants::axis_self:
9392   {
9393     ase->setAxis(axis_kind_self);
9394     break;
9395   }
9396   case ParseConstants::axis_descendant_or_self:
9397   {
9398     ase->setAxis(axis_kind_descendant_or_self);
9399     break;
9400   }
9401   case ParseConstants::axis_following_sibling:
9402   {
9403     ase->setAxis(axis_kind_following_sibling);
9404     break;
9405   }
9406   case ParseConstants::axis_following:
9407   {
9408     ase->setAxis(axis_kind_following);
9409     break;
9410   }
9411   default:
9412     ZORBA_ASSERT(false);
9413   }
9414 }
9415 
9416 
9417 /*******************************************************************************
9418 
9419 ********************************************************************************/
begin_visit(const ReverseAxis & v)9420 void* begin_visit(const ReverseAxis& v)
9421 {
9422   TRACE_VISIT();
9423   return no_state;
9424 }
9425 
9426 
end_visit(const ReverseAxis & v,void *)9427 void end_visit(const ReverseAxis& v, void* /*visit_state*/)
9428 {
9429   TRACE_VISIT_OUT();
9430 
9431   axis_step_expr* ase = expect_axis_step_top ();
9432 
9433   switch (v.get_axis())
9434   {
9435   case ParseConstants::axis_parent:
9436   {
9437     ase->setAxis(axis_kind_parent);
9438     break;
9439   }
9440   case ParseConstants::axis_ancestor:
9441   {
9442     ase->setAxis(axis_kind_ancestor);
9443     break;
9444   }
9445   case ParseConstants::axis_preceding_sibling:
9446   {
9447     ase->setAxis(axis_kind_preceding_sibling);
9448     break;
9449   }
9450   case ParseConstants::axis_preceding:
9451   {
9452     ase->setAxis(axis_kind_preceding);
9453     break;
9454   }
9455   case ParseConstants::axis_ancestor_or_self:
9456   {
9457     ase->setAxis(axis_kind_ancestor_or_self);
9458     break;
9459   }
9460   default:
9461     ZORBA_ASSERT(false);
9462   }
9463 }
9464 
9465 
9466 /*******************************************************************************
9467   NodeTest ::= KindTest | NameTest
9468 ********************************************************************************/
9469 
9470 
9471 /*******************************************************************************
9472   NameTest ::= QName | Wildcard
9473 ********************************************************************************/
begin_visit(const NameTest & v)9474 void* begin_visit (const NameTest& v)
9475 {
9476   TRACE_VISIT ();
9477   return no_state;
9478 }
9479 
9480 
end_visit(const NameTest & v,void *)9481 void end_visit(const NameTest& v, void* /*visit_state*/)
9482 {
9483   TRACE_VISIT_OUT();
9484 
9485   expr* top = theNodeStack.top();
9486 
9487   axis_step_expr* axisExpr = NULL;
9488   trycatch_expr* tce = NULL;
9489 
9490   if ((axisExpr = dynamic_cast<axis_step_expr *>(top)) != NULL)
9491   {
9492     // Construct name-test match expr
9493     match_expr* matchExpr = theExprManager->create_match_expr(theRootSctx, loc);;
9494     matchExpr->setTestKind(match_name_test);
9495 
9496     if (v.getQName() != NULL)
9497     {
9498       store::Item_t qnItem;
9499 
9500       if (axisExpr->getAxis() == axis_kind_attribute)
9501       {
9502         expand_no_default_qname(qnItem, v.getQName(), v.getQName()->get_location());
9503       }
9504       else
9505       {
9506         expand_elem_qname(qnItem, v.getQName(), v.getQName()->get_location());
9507       }
9508 
9509       matchExpr->setQName(qnItem);
9510     }
9511     else
9512     {
9513       rchandle<Wildcard> wildcard = v.getWildcard();
9514       ZORBA_ASSERT(wildcard != NULL);
9515 
9516       switch (wildcard->getKind())
9517       {
9518       case ParseConstants::wild_all:
9519       {
9520         matchExpr->setWildKind(match_all_wild);
9521         break;
9522       }
9523       case ParseConstants::wild_elem:
9524       {
9525         matchExpr->setWildKind(match_name_wild);
9526         matchExpr->setWildName(wildcard->getNsOrPrefix());
9527 
9528         zstring localname(":wildcard");
9529         store::Item_t qnItem;
9530         zstring ns;
9531         zstring prefix = wildcard->getNsOrPrefix();
9532 
9533         if (axisExpr->getAxis() != axis_kind_attribute)
9534         {
9535           ns = theSctx->default_elem_type_ns();
9536           if (wildcard->isEQnameMatch())
9537           {
9538             ns = prefix;
9539             prefix = zstring();
9540           }
9541         }
9542 
9543         theSctx->expand_qname(qnItem,
9544             ns,
9545             prefix,
9546             localname,
9547             wildcard->get_location());
9548 
9549         matchExpr->setQName(qnItem);
9550 
9551         break;
9552       }
9553       case ParseConstants::wild_prefix:
9554       {
9555         matchExpr->setWildKind(match_prefix_wild);
9556         matchExpr->setWildName(wildcard->getLocalName());
9557         break;
9558       }
9559       }
9560     }
9561 
9562     // add the match expression
9563     axisExpr->setTest(matchExpr);
9564   }
9565   else if ((tce = dynamic_cast<trycatch_expr *>(top)) != NULL)
9566   {
9567     catch_clause* cc = const_cast<catch_clause*>((*tce)[0]);
9568     if (v.getQName() != NULL)
9569     {
9570       store::Item_t qnItem;
9571       expand_elem_qname(qnItem, v.getQName(), loc);
9572 
9573       cc->add_nametest_h(new NodeNameTest(qnItem));
9574     }
9575     else
9576     {
9577       rchandle<Wildcard> wildcard = v.getWildcard();
9578       ZORBA_ASSERT(wildcard != NULL);
9579 
9580 
9581       switch (wildcard->getKind())
9582       {
9583         case ParseConstants::wild_all:
9584           cc->add_nametest_h(new NodeNameTest(zstring(), zstring()));
9585           break;
9586         case ParseConstants::wild_elem:
9587         {
9588           // bugfix #3138633; expand the qname and use the namespace instead of the prefix
9589           zstring localname(":wildcard");
9590 
9591           if (wildcard->isEQnameMatch())
9592           {
9593             cc->add_nametest_h(new NodeNameTest(wildcard->getNsOrPrefix(), zstring()));
9594           }
9595           else
9596           {
9597             store::Item_t qnItem;
9598             theSctx->expand_qname(qnItem,
9599                                   theSctx->default_elem_type_ns(),
9600                                   wildcard->getNsOrPrefix(),
9601                                   localname,
9602                                   wildcard->get_location());
9603             cc->add_nametest_h(new NodeNameTest(qnItem->getNamespace(), zstring()));
9604           }
9605           break;
9606         }
9607         case ParseConstants::wild_prefix:
9608           cc->add_nametest_h(new NodeNameTest(zstring(), wildcard->getLocalName()));
9609           break;
9610       }
9611     }
9612   }
9613   else
9614   {
9615     ZORBA_ASSERT(false);
9616   }
9617 }
9618 
9619 
9620 /*******************************************************************************
9621   Wildcard ::= "*" | (NCName ":" "*") | ("*" ":" NCName)
9622 ********************************************************************************/
begin_visit(const Wildcard & v)9623 void* begin_visit(const Wildcard& v)
9624 {
9625   TRACE_VISIT();
9626   return no_state;
9627 }
9628 
9629 
end_visit(const Wildcard & v,void *)9630 void end_visit(const Wildcard& v, void* /*visit_state*/)
9631 {
9632   TRACE_VISIT_OUT();
9633 }
9634 
9635 
9636 /*******************************************************************************
9637   PostfixExpr ::= PrimaryExpr (Predicate | ArgumentList)*
9638 ********************************************************************************/
begin_visit(const FilterExpr & v)9639 void* begin_visit(const FilterExpr& v)
9640 {
9641   TRACE_VISIT();
9642 
9643   return no_state;
9644 }
9645 
9646 
post_primary_visit(const FilterExpr & v,void *)9647 void post_primary_visit(const FilterExpr& v, void* /*visit_state*/)
9648 {
9649   // This method is called from FilterExpr::accept() after the primary expr is
9650   // translated, but before the associated predicate list, if any, is translated.
9651 
9652   // Nothing to do if this is a standalone filter expr (i.e., it does not appear
9653   // as a step of a path expr).
9654   if (!v.isPathStep())
9655     return;
9656 
9657   theNodeSortStack.top().theHaveFilterSteps = true;
9658 
9659   PredicateList* pl = v.get_pred_list();
9660 
9661   ZORBA_ASSERT(pl != NULL && pl->size() > 0);
9662 
9663   expr* primaryExpr = pop_nodestack();
9664   expr* e = pop_nodestack();
9665   flwor_expr* flworExpr = dynamic_cast<flwor_expr*>(e);
9666 
9667   // If this filter expr is not the 1st step of a path expr, ...
9668   if (flworExpr != NULL)
9669   {
9670     // for each item in the input seq compute the input seq for the pred
9671     // (= outer_dot/primaryExpr)
9672     let_clause* lcPredSeq = wrap_in_letclause(primaryExpr);
9673 
9674     flworExpr->add_clause(lcPredSeq);
9675 
9676     push_nodestack(flworExpr);
9677     push_nodestack(lcPredSeq->get_var());
9678   }
9679 
9680   // Else, this filter expr is the very first step (i.e., the source expr) of
9681   // a path expr.
9682   else
9683   {
9684      relpath_expr* pathExpr = dynamic_cast<relpath_expr*>(e);
9685      ZORBA_ASSERT(pathExpr != NULL && pathExpr->size() == 0);
9686 
9687      push_nodestack(pathExpr);
9688      push_nodestack(primaryExpr);
9689   }
9690 }
9691 
9692 
end_visit(const FilterExpr & v,void *)9693 void end_visit(const FilterExpr& v, void* /*visit_state*/)
9694 {
9695   TRACE_VISIT_OUT();
9696 }
9697 
9698 
9699 /*******************************************************************************
9700   PredicateList ::= Predicate*
9701   Predicate ::= "[" Expr "]"
9702 ********************************************************************************/
begin_visit(const PredicateList & v)9703 void* begin_visit(const PredicateList& v)
9704 {
9705   TRACE_VISIT();
9706   return no_state;
9707 }
9708 
9709 
end_visit(const PredicateList & v,void *)9710 void end_visit(const PredicateList& v, void* /*visit_state*/)
9711 {
9712   TRACE_VISIT_OUT();
9713 }
9714 
9715 
pre_predicate_visit(const PredicateList & v,void *)9716 void pre_predicate_visit(const PredicateList& v, void* /*visit_state*/)
9717 {
9718   // This method is called from PredicateList::accept(). It is called once
9719   // for each predicate in the list, before calling accept() on the predicate
9720   // expression itself.
9721 
9722 
9723   // get the predicate input seq
9724   expr* inputSeqExpr = pop_nodestack();
9725 
9726   //  let $$temp := predInputSeq
9727   //  let $$last-idx := count($$temp)
9728   //  for $$dot at $$pos in $$temp
9729   flwor_expr* flworExpr = wrap_expr_in_flwor(inputSeqExpr, true);
9730 
9731   push_nodestack(flworExpr);
9732 }
9733 
9734 
post_predicate_visit(const PredicateList & v,void *)9735 void post_predicate_visit(const PredicateList& v, void* /*visit_state*/)
9736 {
9737   // This method is called from PredicateList::accept(). It is called once
9738   // for each predicate in the list, after calling accept() on the predicate
9739   // expression itself.
9740 
9741   RootTypeManager& rtm = GENV_TYPESYSTEM;
9742   TypeManager* tm = CTX_TM;
9743 
9744   expr* predExpr = pop_nodestack();
9745 
9746   expr* f = pop_nodestack();
9747   flwor_expr* flworExpr = dynamic_cast<flwor_expr*>(f);
9748   ZORBA_ASSERT(flworExpr != NULL && flworExpr->num_clauses() == 3);
9749 
9750   const QueryLoc& loc = predExpr->get_loc();
9751 
9752   xqtref_t predType = predExpr->get_return_type();
9753 
9754   if (TypeOps::is_subtype(tm, *predType, *rtm.INTEGER_TYPE_QUESTION, loc))
9755   {
9756     flwor_clause* clause = flworExpr->get_clause(0);
9757     ZORBA_ASSERT(clause->get_kind() == flwor_clause::let_clause);
9758     let_clause* sourceClause = static_cast<let_clause*>(clause);
9759 
9760     clause = flworExpr->get_clause(1);
9761     ZORBA_ASSERT(clause->get_kind() == flwor_clause::let_clause);
9762     let_clause* sizeClause = static_cast<let_clause*>(clause);
9763 
9764     clause = flworExpr->get_clause(2);
9765     ZORBA_ASSERT(clause->get_kind() == flwor_clause::for_clause);
9766     for_clause* dotClause = static_cast<for_clause*>(clause);
9767 
9768     var_expr* sizeVar = sizeClause->get_var();
9769     var_expr* posVar = dotClause->get_pos_var();
9770     var_expr* dotVar = dotClause->get_var();
9771 
9772     if (expr_tools::count_variable_uses(predExpr, posVar, 1) == 0 &&
9773         expr_tools::count_variable_uses(predExpr, dotVar, 1) == 0)
9774     {
9775       flworExpr->remove_clause(2);
9776 
9777       if (expr_tools::count_variable_uses(predExpr, sizeVar, 1) == 0)
9778       {
9779         expr* sourceExpr = sourceClause->get_expr();
9780 
9781         fo_expr* pointExpr = theExprManager->
9782         create_fo_expr(sourceExpr->get_sctx(),
9783                        sourceExpr->get_loc(),
9784                        GET_BUILTIN_FUNCTION(OP_ZORBA_SEQUENCE_POINT_ACCESS_2),
9785                        sourceExpr,
9786                        predExpr);
9787 
9788         push_nodestack(pointExpr);
9789       }
9790       else
9791       {
9792         expr* sourceExpr = sourceClause->get_var();
9793 
9794         fo_expr* pointExpr = theExprManager->
9795         create_fo_expr(sourceExpr->get_sctx(),
9796                        sourceExpr->get_loc(),
9797                        GET_BUILTIN_FUNCTION(OP_ZORBA_SEQUENCE_POINT_ACCESS_2),
9798                        sourceExpr,
9799                        predExpr);
9800 
9801         flworExpr->set_return_expr(pointExpr);
9802 
9803         push_nodestack(flworExpr);
9804       }
9805     }
9806     else
9807     {
9808       // let $predVar := predExpr
9809       let_clause* lcPred = wrap_in_letclause(predExpr);
9810       var_expr* predvar = lcPred->get_var();
9811 
9812       flworExpr->add_clause(lcPred);
9813 
9814       // return if ($$dot eq $$predVar) then $$dot else ()
9815       fo_expr* eqExpr = theExprManager->
9816       create_fo_expr(theRootSctx,
9817                      loc,
9818                      GET_BUILTIN_FUNCTION(OP_VALUE_EQUAL_2),
9819                      lookup_ctx_var(DOT_POS_VARNAME, loc),
9820                      predvar);
9821 
9822       normalize_fo(eqExpr);
9823 
9824       expr* retExpr = theExprManager->
9825       create_if_expr(theRootSctx, loc, eqExpr, DOT_REF, create_empty_seq(loc));
9826 
9827       flworExpr->set_return_expr(retExpr);
9828 
9829       push_nodestack(flworExpr);
9830     }
9831 
9832     pop_scope();
9833 
9834     return;
9835   }
9836 
9837   // let $predVar := predExpr
9838   let_clause* lcPred = wrap_in_letclause(predExpr);
9839   var_expr* predvar = lcPred->get_var();
9840 
9841   flworExpr->add_clause(lcPred);
9842 
9843   // Construct the return expr of the flworExpr:
9844   //
9845   // if ($predVar instance-of xs:decimal or
9846   //     $predVar instance-of xs:double or
9847   //     $predVar instance-of xs:float)
9848   // then
9849   //   if (fn:boolean($dot_pos eq $predVar) then $dot else ()
9850   // else
9851   //   if (fn:boolean($predVar) then $dot else ()
9852 
9853   // Check if the pred expr returns a numeric result
9854   fo_expr* condExpr = NULL;
9855   std::vector<expr*> condOperands(3);
9856 
9857   condOperands[0] = theExprManager->
9858   create_instanceof_expr(theRootSctx, loc, predvar, rtm.DECIMAL_TYPE_QUESTION, true);
9859 
9860   condOperands[1] = theExprManager->
9861   create_instanceof_expr(theRootSctx, loc, predvar, rtm.DOUBLE_TYPE_QUESTION, true);
9862 
9863   condOperands[2] = theExprManager->
9864   create_instanceof_expr(theRootSctx, loc, predvar, rtm.FLOAT_TYPE_QUESTION, true);
9865 
9866   condExpr = theExprManager->
9867   create_fo_expr(theRootSctx, loc, GET_BUILTIN_FUNCTION(OP_OR_N), condOperands);
9868 
9869   // If so: return $dot if the value of the pred expr is equal to the value
9870   // of $dot_pos var, otherwise return the empty seq.
9871   fo_expr* eqExpr = theExprManager->
9872   create_fo_expr(theRootSctx,
9873                  loc,
9874                  GET_BUILTIN_FUNCTION(OP_VALUE_EQUAL_2),
9875                  lookup_ctx_var(DOT_POS_VARNAME, loc),
9876                  predvar);
9877 
9878   normalize_fo(eqExpr);
9879 
9880   expr* thenExpr = theExprManager->
9881   create_if_expr(theRootSctx, loc, eqExpr, DOT_REF, create_empty_seq(loc));
9882 
9883   // Else, return $dot if the the value of the pred expr is true, otherwise
9884   // return the empty seq.
9885   expr* elseExpr = theExprManager->
9886   create_if_expr(theRootSctx, loc, predvar, DOT_REF, create_empty_seq(loc));
9887 
9888   // The outer if
9889   expr* ifExpr = theExprManager->
9890   create_if_expr(theRootSctx, loc, condExpr, thenExpr, elseExpr);
9891 
9892   flworExpr->set_return_expr(ifExpr);
9893 
9894   push_nodestack(flworExpr);
9895 
9896   pop_scope();
9897 }
9898 
9899 
9900 /////////////////////////////////////////////////////////////////////////////////
9901 //                                                                             //
9902 //  Primary                                                                    //
9903 //                                                                             //
9904 /////////////////////////////////////////////////////////////////////////////////
9905 
9906 
9907 /*******************************************************************************
9908   PrimaryExpr ::= Literal |
9909                   VarRef |
9910                   ParenthesizedExpr |
9911                   ContextItemExpr |
9912                   FunctionCall |
9913                   OrderedExpr |
9914                   UnorderedExpr |
9915                   Constructor |
9916                   FunctionItemExpr
9917 ********************************************************************************/
9918 
9919 
9920 /*******************************************************************************
9921   Literal ::= NumericLiteral | StringLiteral
9922 ********************************************************************************/
begin_visit(const Literal & v)9923 void* begin_visit(const Literal& v)
9924 {
9925   TRACE_VISIT();
9926   return no_state;
9927 }
9928 
end_visit(const Literal & v,void *)9929 void end_visit(const Literal& v, void* /*visit_state*/)
9930 {
9931   TRACE_VISIT_OUT();
9932 }
9933 
9934 
9935 /*******************************************************************************
9936   NumericLiteral ::= IntegerLiteral | DecimalLiteral | DoubleLiteral
9937 
9938   IntegerLiteral ::= Digits
9939 
9940   DecimalLiteral :: ("." Digits) | (Digits "." [0-9]*)
9941 
9942   DoubleLiteral ::= (("." Digits) | (Digits ("." [0-9]*)?)) [eE] [+-]? Digits
9943 ********************************************************************************/
begin_visit(const NumericLiteral & v)9944 void* begin_visit(const NumericLiteral& v)
9945 {
9946   TRACE_VISIT();
9947   return no_state;
9948 }
9949 
end_visit(const NumericLiteral & v,void *)9950 void end_visit(const NumericLiteral& v, void* /*visit_state*/)
9951 {
9952   TRACE_VISIT_OUT();
9953 
9954   switch (v.get_type())
9955   {
9956   case ParseConstants::num_integer:
9957   {
9958     push_nodestack(theExprManager->create_const_expr(theRootSctx, loc, v.get<xs_integer>()));
9959     break;
9960   }
9961   case ParseConstants::num_decimal:
9962   {
9963     push_nodestack(theExprManager->create_const_expr(theRootSctx, loc, v.get<xs_decimal>()));
9964     break;
9965   }
9966   case ParseConstants::num_double:
9967   {
9968     push_nodestack(theExprManager->create_const_expr(theRootSctx, loc, v.get<xs_double>()));
9969     break;
9970   }
9971   }
9972 }
9973 
9974 
9975 /*******************************************************************************
9976   [181] StringLiteral ::= ('"' (PredefinedEntityRef |
9977                                 CharRef |
9978                                 EscapeQuot |
9979                                 [^"&])*
9980                            '"') |
9981                           ("'" (PredefinedEntityRef |
9982                                 CharRef |
9983                                 EscapeApos |
9984                                 [^'&])*
9985                            "'")
9986 
9987   [182] PredefinedEntityRef ::= "&" ("lt" | "gt" | "amp" | "quot" | "apos") ";"
9988 
9989   [183] EscapeQuot ::= '""'
9990 
9991   [184] EscapeApos ::= "''"
9992 
9993   [190] CharRef ::= [http://www.w3.org/TR/REC-xml#NT-CharRef]
9994 ********************************************************************************/
begin_visit(const StringLiteral & v)9995 void* begin_visit(const StringLiteral& v)
9996 {
9997   TRACE_VISIT();
9998   return no_state;
9999 }
10000 
end_visit(const StringLiteral & v,void *)10001 void end_visit(const StringLiteral& v, void* /*visit_state*/)
10002 {
10003   TRACE_VISIT_OUT();
10004 
10005   push_nodestack(theExprManager->create_const_expr(theRootSctx, loc,v.get_strval().str()));
10006 }
10007 
10008 /*******************************************************************************
10009    StringConcatExpr ::= RangeExpr ( "||" RangeExpr )*
10010 *******************************************************************************/
begin_visit(const StringConcatExpr & v)10011 void* begin_visit(const StringConcatExpr& v)
10012 {
10013   TRACE_VISIT();
10014   return no_state;
10015 }
10016 
end_visit(const StringConcatExpr & v,void *)10017 void end_visit(const StringConcatExpr& v, void* /* visit_state */)
10018 {
10019   TRACE_VISIT_OUT();
10020   std::vector<expr*> concat_args;
10021   expr* right = pop_nodestack();
10022   expr* left  = pop_nodestack();
10023   concat_args.push_back(left);
10024 
10025   //If the right leaf is the concat expr,
10026   //we add directly its leafs to the new concat expr.
10027   bool rightLeafIsConcatExpr = false;
10028   if(right->get_expr_kind() == fo_expr_kind)
10029   {
10030     fo_expr* lFoExpr = dynamic_cast<fo_expr*>(right);
10031     if(lFoExpr->get_func() == GET_BUILTIN_FUNCTION(FN_CONCAT_N))
10032     {
10033       rightLeafIsConcatExpr = true;
10034       csize i = 0;
10035       for(i = 0; i < lFoExpr->num_args(); ++i)
10036       {
10037         concat_args.push_back(lFoExpr->get_arg(i));
10038       }
10039     }
10040   }
10041 
10042   if(!rightLeafIsConcatExpr)
10043   {
10044     concat_args.push_back(right);
10045   }
10046 
10047   expr* concat =
10048   theExprManager->create_fo_expr(theRootSctx,
10049                                  loc,
10050                                  GET_BUILTIN_FUNCTION(FN_CONCAT_N),
10051                                  concat_args);
10052   push_nodestack(concat);
10053 }
10054 
10055 /*******************************************************************************
10056   VarRef ::= "$" VarName
10057   VarName ::= QName
10058 ********************************************************************************/
begin_visit(const VarRef & v)10059 void* begin_visit(const VarRef& v)
10060 {
10061   TRACE_VISIT();
10062   return no_state;
10063 }
10064 
end_visit(const VarRef & v,void *)10065 void end_visit(const VarRef& v, void* /*visit_state*/)
10066 {
10067   TRACE_VISIT_OUT();
10068 
10069   var_expr* ve = NULL;
10070 
10071   try
10072   {
10073     ve = lookup_var(v.get_name(), loc, err::XPST0008);
10074   }
10075   catch (const ZorbaException& e)
10076   {
10077     if (e.diagnostic() == err::XPST0008 && theHaveModuleImportCycle)
10078     {
10079       store::Item_t qnameItem;
10080       expand_no_default_qname(qnameItem, v.get_name(), loc);
10081 
10082       const zstring& var_ns = qnameItem->getNamespace();
10083 
10084       std::map<zstring, zstring>::const_iterator ite = theModulesStack.begin();
10085       std::map<zstring, zstring>::const_iterator end = theModulesStack.end();
10086 
10087       --end;
10088       assert((*end).second == theModuleNamespace);
10089 
10090       for (; ite != end; ++ite)
10091       {
10092         if ((*ite).second == var_ns)
10093           RAISE_ERROR(err::XQST0093, loc, ERROR_PARAMS(theModuleNamespace));
10094       }
10095     }
10096 
10097     throw;
10098   }
10099 
10100   if (ve->get_kind() == var_expr::prolog_var)
10101   {
10102     TypeManager* tm = CTX_TM;
10103 
10104     xqtref_t declaredType = ve->get_type();
10105 
10106     if (declaredType != NULL && !TypeOps::is_in_scope(tm, *declaredType))
10107     {
10108       const Error& error = (declaredType->get_manager() == tm ?
10109                             err::XPTY0004 : err::XQST0036);
10110 
10111       if (theModuleNamespace.empty())
10112       {
10113         throw XQUERY_EXCEPTION_VAR(
10114           error,
10115           ERROR_PARAMS(ZED(BadType_23o),
10116                        *declaredType,
10117                        ZED( NoTypeInMainModule_4 ),
10118                        ve->get_name()->getStringValue()),
10119           ERROR_LOC( loc )
10120         );
10121       }
10122       else
10123       {
10124         throw XQUERY_EXCEPTION_VAR(
10125           error,
10126           ERROR_PARAMS(ZED(BadType_23o),
10127                        *declaredType,
10128                        ZED( NoTypeInModule_45 ),
10129                        ve->get_name()->getStringValue(),
10130                        theModuleNamespace),
10131           ERROR_LOC( loc )
10132         );
10133       }
10134     }
10135 
10136     if (!theCurrentPrologVFDecl.isNull())
10137     {
10138       thePrologGraph.addEdge(theCurrentPrologVFDecl, ve);
10139     }
10140   }
10141 
10142   push_nodestack(theExprManager->create_wrapper_expr(theRootSctx,
10143                                                      loc,
10144                                                      ve));
10145 }
10146 
10147 
10148 /*******************************************************************************
10149   ParenthesizedExpr ::= "(" Expr? ")"
10150 ********************************************************************************/
begin_visit(const ParenthesizedExpr & v)10151 void* begin_visit(const ParenthesizedExpr& v)
10152 {
10153   TRACE_VISIT();
10154 
10155   push_nodestack(NULL);
10156   return no_state;
10157 }
10158 
end_visit(const ParenthesizedExpr & v,void *)10159 void end_visit(const ParenthesizedExpr& v, void* /*visit_state*/)
10160 {
10161   TRACE_VISIT_OUT();
10162 
10163   expr* expr = pop_nodestack();
10164 
10165   if (expr != NULL)
10166   {
10167     pop_nodestack();
10168     push_nodestack(expr);
10169   }
10170   else
10171   {
10172     fo_expr* lSeq = create_empty_seq(loc);
10173     push_nodestack(lSeq);
10174   }
10175 }
10176 
10177 
10178 /*******************************************************************************
10179   ContextItemExpr ::= "."
10180 ********************************************************************************/
begin_visit(const ContextItemExpr & v)10181 void* begin_visit(const ContextItemExpr& v)
10182 {
10183   TRACE_VISIT ();
10184   return no_state;
10185 }
10186 
end_visit(const ContextItemExpr & v,void *)10187 void end_visit (const ContextItemExpr& v, void* /*visit_state*/)
10188 {
10189   TRACE_VISIT_OUT();
10190 
10191   push_nodestack(DOT_REF);
10192 }
10193 
10194 
10195 /*******************************************************************************
10196   OrderedExpr ::= "ordered" "{" Expr "}"
10197 ********************************************************************************/
begin_visit(const OrderedExpr & v)10198 void* begin_visit(const OrderedExpr& v)
10199 {
10200   TRACE_VISIT();
10201 
10202   return no_state;
10203 }
10204 
end_visit(const OrderedExpr & v,void *)10205 void end_visit(const OrderedExpr& v, void* /*visit_state*/)
10206 {
10207   TRACE_VISIT_OUT();
10208 
10209   push_nodestack(theExprManager->create_order_expr(theRootSctx,
10210                                 loc,
10211                                 order_expr::ordered,
10212                                 pop_nodestack()));
10213 }
10214 
10215 
10216 /*******************************************************************************
10217   UnorderedExpr ::= "unordered" "{" Expr "}"
10218 ********************************************************************************/
begin_visit(const UnorderedExpr & v)10219 void* begin_visit(const UnorderedExpr& v)
10220 {
10221   TRACE_VISIT();
10222 
10223   return no_state;
10224 }
10225 
end_visit(const UnorderedExpr & v,void *)10226 void end_visit(const UnorderedExpr& v, void* /*visit_state*/)
10227 {
10228   TRACE_VISIT_OUT();
10229 
10230   push_nodestack(theExprManager->create_order_expr(theRootSctx,
10231                                 loc,
10232                                 order_expr::unordered,
10233                                 pop_nodestack()));
10234 }
10235 
10236 
10237 /*******************************************************************************
10238   FunctionCall ::= QName "(" ArgList? ")"
10239 ********************************************************************************/
begin_visit(const FunctionCall & v)10240 void* begin_visit(const FunctionCall& v)
10241 {
10242   TRACE_VISIT();
10243 
10244   rchandle<QName> qname = v.get_fname();
10245 
10246   csize numArgs = 0;
10247   if (v.get_arg_list() != NULL)
10248     numArgs = v.get_arg_list()->size();
10249 
10250   function* f = lookup_fn(qname, numArgs, loc);
10251 
10252   // Note : f maybe NULL if it is a constructor of a builtin type
10253 
10254   if (f != NULL && f->getXQueryVersion() > theSctx->xquery_version())
10255   {
10256     zstring version =
10257     (f->getXQueryVersion() == StaticContextConsts::xquery_version_1_0 ? "1.0" : "3.0");
10258 
10259     throw XQUERY_EXCEPTION(err::XPST0017,
10260                            ERROR_PARAMS(f->getName()->getStringValue(),
10261                                         ZED(FnOnlyInXQueryVersion_3),
10262                                         version),
10263                            ERROR_LOC(loc));
10264   }
10265 
10266   if (f != NULL && !theCurrentPrologVFDecl.isNull())
10267   {
10268     if (f->isUdf())
10269       thePrologGraph.addEdge(theCurrentPrologVFDecl, f);
10270   }
10271 
10272   if (f != NULL && (f->isUdf() || f->isExternal()))
10273   {
10274     TypeManager* tm = CTX_TM;
10275 
10276     const signature& sign = f->getSignature();
10277 
10278     xqtref_t retType = sign.returnType();
10279 
10280     if (!TypeOps::is_in_scope(tm, *retType))
10281     {
10282       if (theModuleNamespace.empty())
10283       {
10284         RAISE_ERROR(err::XQST0036, loc,
10285         ERROR_PARAMS(ZED(BadType_23o),
10286                      *retType,
10287                      ZED(NoTypeInMainModule_4),
10288                      f->getName()->getStringValue()));
10289       }
10290       else
10291       {
10292         RAISE_ERROR(err::XQST0036, loc,
10293         ERROR_PARAMS(ZED(BadType_23o),
10294                      *retType,
10295                      ZED(NoTypeInModule_45),
10296                      f->getName()->getStringValue(),
10297                      theModuleNamespace));
10298       }
10299     }
10300 
10301     csize numParams = f->getArity();
10302 
10303     for (csize i = 0; i < numParams; ++i)
10304     {
10305       xqtref_t type = sign[i];
10306       if (!TypeOps::is_in_scope(tm, *type))
10307       {
10308         if (theModuleNamespace.empty())
10309         {
10310           RAISE_ERROR(err::XQST0036, loc,
10311           ERROR_PARAMS(ZED(BadType_23o),
10312                        *type,
10313                        ZED(NoTypeInMainModule_4),
10314                        f->getName()->getStringValue()));
10315         }
10316         else
10317         {
10318           RAISE_ERROR(err::XQST0036, loc,
10319           ERROR_PARAMS(ZED(BadType_23o),
10320                        *retType,
10321                        ZED(NoTypeInModule_45),
10322                        f->getName()->getStringValue(),
10323                        theModuleNamespace));
10324         }
10325       }
10326     }
10327   }
10328 
10329   push_nodestack(NULL);
10330   return no_state;
10331 }
10332 
end_visit(const FunctionCall & v,void *)10333 void end_visit(const FunctionCall& v, void* /*visit_state*/)
10334 {
10335   TRACE_VISIT_OUT();
10336 
10337   TypeManager* tm = CTX_TM;
10338 
10339   // Expand the function qname
10340   rchandle<QName> qname = v.get_fname();
10341 
10342   store::Item_t qnameItem;
10343   expand_function_qname(qnameItem, qname, loc);
10344 
10345   const zstring& fn_ns = qnameItem->getNamespace();
10346 
10347   if (static_context::is_reserved_module(fn_ns))
10348   {
10349     RAISE_ERROR(zerr::ZXQP0016_RESERVED_MODULE_TARGET_NAMESPACE, loc,
10350     ERROR_PARAMS(fn_ns));
10351   }
10352 
10353   // Collect the arguments of this function in reverse order
10354   std::vector<expr*> arguments;
10355 
10356   while (true)
10357   {
10358     expr* argExpr = pop_nodestack();
10359 
10360     if (argExpr == NULL)
10361       break;
10362 
10363     arguments.push_back(argExpr);
10364   }
10365 
10366   csize numArgs = arguments.size();
10367 
10368   function* f = lookup_fn(qname, numArgs, loc);
10369 
10370   if (fn_ns == static_context::W3C_FN_NS)
10371   {
10372     // Some special processing is required for certain "fn" functions
10373     if (f == NULL)
10374     {
10375       RAISE_ERROR(err::XPST0017, loc,
10376       ERROR_PARAMS(qname->get_qname(), ZED(FunctionUndeclared_3), numArgs));
10377     }
10378 
10379     switch (f->getKind())
10380     {
10381       case FunctionConsts::FN_HEAD_1:
10382       {
10383         arguments.push_back(theExprManager->
10384                             create_const_expr(theRootSctx, loc, xs_integer::one()));
10385 
10386         arguments.push_back(theExprManager->
10387                             create_const_expr(theRootSctx, loc, xs_integer::one()));
10388 
10389         function* f = GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_3);
10390 
10391         fo_expr* foExpr = theExprManager->
10392         create_fo_expr(theRootSctx, loc, f, arguments);
10393 
10394         normalize_fo(foExpr);
10395 
10396         push_nodestack(foExpr);
10397         return;
10398       }
10399       case FunctionConsts::FN_TAIL_1:
10400       {
10401         arguments.push_back(theExprManager->
10402                             create_const_expr(theRootSctx, loc, xs_integer(2)));
10403 
10404         function* f = GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_2);
10405 
10406         fo_expr* foExpr = theExprManager->
10407         create_fo_expr(theRootSctx, loc, f, arguments);
10408 
10409         normalize_fo(foExpr);
10410 
10411         push_nodestack(foExpr);
10412         return;
10413       }
10414       case FunctionConsts::FN_SUBSEQUENCE_2:
10415       case FunctionConsts::FN_SUBSEQUENCE_3:
10416       case FunctionConsts::FN_SUBSTRING_2:
10417       case FunctionConsts::FN_SUBSTRING_3:
10418       {
10419         std::reverse(arguments.begin(), arguments.end());
10420 
10421         xqtref_t posType = arguments[1]->get_return_type();
10422 
10423         if (numArgs == 2)
10424         {
10425           if (TypeOps::is_subtype(tm, *posType, *theRTM.INTEGER_TYPE_STAR, loc))
10426           {
10427             if (f->getKind() == FunctionConsts::FN_SUBSTRING_2)
10428               f = GET_BUILTIN_FUNCTION(OP_SUBSTRING_INT_2);
10429             else
10430               f = GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_2);
10431           }
10432         }
10433         else
10434         {
10435           xqtref_t lenType = arguments[2]->get_return_type();
10436 
10437           if (TypeOps::is_subtype(tm, *posType, *theRTM.INTEGER_TYPE_STAR, loc) &&
10438               TypeOps::is_subtype(tm, *lenType, *theRTM.INTEGER_TYPE_STAR, loc))
10439           {
10440             if (f->getKind() == FunctionConsts::FN_SUBSTRING_3)
10441               f = GET_BUILTIN_FUNCTION(OP_SUBSTRING_INT_3);
10442             else
10443               f = GET_BUILTIN_FUNCTION(OP_ZORBA_SUBSEQUENCE_INT_3);
10444           }
10445         }
10446 
10447         fo_expr* foExpr = theExprManager->
10448         create_fo_expr(theRootSctx, loc, f, arguments);
10449 
10450         normalize_fo(foExpr);
10451         push_nodestack(foExpr);
10452         return;
10453       }
10454       case FunctionConsts::FN_POSITION_0:
10455       {
10456         push_nodestack(lookup_ctx_var(DOT_POS_VARNAME, loc));
10457         return;
10458       }
10459       case FunctionConsts::FN_LAST_0:
10460       {
10461         push_nodestack(lookup_ctx_var(LAST_IDX_VARNAME, loc));
10462         return;
10463       }
10464       case FunctionConsts::FN_NUMBER_0:
10465       case FunctionConsts::FN_NUMBER_1:
10466       {
10467         switch (numArgs)
10468         {
10469         case 0:
10470         {
10471           arguments.push_back(DOT_REF);
10472           f = GET_BUILTIN_FUNCTION(FN_NUMBER_1);
10473           break;
10474         }
10475         case 1:
10476           break;
10477         default:
10478           RAISE_ERROR(err::XPST0017, loc,
10479           ERROR_PARAMS("fn:number", ZED(FunctionUndeclared_3), numArgs));
10480         }
10481 
10482         var_expr* tv = create_temp_var(loc, var_expr::let_var);
10483 
10484         expr* nanExpr = theExprManager->create_const_expr(theRootSctx, loc, xs_double::nan());
10485 
10486         expr* condExpr = theExprManager->create_castable_expr(theRootSctx, loc, &*tv, theRTM.DOUBLE_TYPE_ONE);
10487 
10488         expr* castExpr = create_cast_expr(loc, tv, theRTM.DOUBLE_TYPE_ONE, true);
10489 
10490         expr* ret = theExprManager->create_if_expr(theRootSctx, loc, condExpr, castExpr, nanExpr);
10491 
10492         expr* data_expr = wrap_in_atomization(arguments[0]);
10493 
10494         push_nodestack(wrap_in_let_flwor(theExprManager->create_treat_expr(theRootSctx,
10495                                                           loc,
10496                                                           data_expr,
10497                                                           theRTM.ANY_ATOMIC_TYPE_QUESTION,
10498                                                           TreatIterator::TYPE_MATCH),
10499                                            tv,
10500                                            ret));
10501         return;
10502       }
10503       case FunctionConsts::FN_STATIC_BASE_URI_0:
10504       {
10505         if (numArgs != 0)
10506           RAISE_ERROR(err::XPST0017, loc,
10507           ERROR_PARAMS("fn:static-base-uri",
10508                        ZED(FunctionUndeclared_3),
10509                        numArgs));
10510 
10511         zstring baseuri = theSctx->get_base_uri();
10512         if (baseuri.empty())
10513           push_nodestack(create_empty_seq(loc));
10514         else
10515           push_nodestack(theExprManager->create_cast_expr(theRootSctx,
10516                                        loc,
10517                                        theExprManager->create_const_expr(theRootSctx, loc, baseuri),
10518                                        theRTM.ANY_URI_TYPE_ONE));
10519         return;
10520       }
10521       case FunctionConsts::FN_ID_1:
10522       case FunctionConsts::FN_ID_2:
10523       case FunctionConsts::FN_ELEMENT_WITH_ID_1:
10524       case FunctionConsts::FN_ELEMENT_WITH_ID_2:
10525       {
10526         if (numArgs == 1)
10527         {
10528           arguments.insert(arguments.begin(), DOT_REF);
10529           f = lookup_fn(qname, 2, loc);
10530         }
10531 
10532         expr* idsExpr = arguments[1];
10533 
10534         flwor_expr* flworExpr = wrap_expr_in_flwor(idsExpr, false);
10535 
10536         const for_clause* fc = static_cast<const for_clause*>(flworExpr->get_clause(0));
10537         expr* flworVarExpr = fc->get_var();
10538 
10539         fo_expr* normExpr = NULL;
10540         fo_expr* tokenExpr = NULL;
10541         zstring space(" ");
10542         const_expr* constExpr = theExprManager->create_const_expr(theRootSctx, loc, space);
10543 
10544         normExpr = theExprManager->create_fo_expr(theRootSctx,
10545                                loc,
10546                                GET_BUILTIN_FUNCTION(FN_NORMALIZE_SPACE_1),
10547                                flworVarExpr);
10548         normalize_fo(normExpr);
10549 
10550         tokenExpr = theExprManager->create_fo_expr(theRootSctx,
10551                                 loc,
10552                                 GET_BUILTIN_FUNCTION(FN_TOKENIZE_2),
10553                                 normExpr,
10554                                 constExpr);
10555         normalize_fo(tokenExpr);
10556 
10557         flworExpr->set_return_expr(tokenExpr);
10558 
10559         pop_scope();
10560 
10561         arguments[1] = flworExpr;
10562         break;
10563       }
10564       case FunctionConsts::FN_IDREF_1:
10565       {
10566         arguments.insert(arguments.begin(), DOT_REF);
10567         f = GET_BUILTIN_FUNCTION(FN_IDREF_2);
10568         break;
10569       }
10570       case FunctionConsts::FN_LANG_1:
10571       {
10572         arguments.insert(arguments.begin(), DOT_REF);
10573         f = GET_BUILTIN_FUNCTION(FN_LANG_2);
10574         break;
10575       }
10576       case FunctionConsts::FN_RESOLVE_URI_1:
10577       {
10578         zstring baseUri = theSctx->get_base_uri();
10579         arguments.insert(arguments.begin(), theExprManager->create_const_expr(theRootSctx, loc, baseUri));
10580         f = GET_BUILTIN_FUNCTION(FN_RESOLVE_URI_2);
10581         break;
10582       }
10583       case FunctionConsts::FN_CONCAT_N:
10584       {
10585         if (numArgs < 2)
10586           RAISE_ERROR(err::XPST0017, loc,
10587             ERROR_PARAMS("concat", ZED(FunctionUndeclared_3), numArgs));
10588         break;
10589       }
10590       case FunctionConsts::FN_DOC_1:
10591       {
10592         if (numArgs > 0)
10593         {
10594           expr*  doc_uri = arguments[0];
10595 
10596           //validate uri
10597           if(doc_uri->get_expr_kind() == const_expr_kind)
10598           {
10599             const_expr* const_uri = reinterpret_cast<const_expr*>(doc_uri);
10600             const store::Item* uri_value = const_uri->get_val();
10601             zstring uri_string = uri_value->getStringValue();
10602 
10603             try
10604             {
10605               if (uri_string.find(":/", 0, 3) != zstring::npos)
10606               {
10607                 URI docURI(uri_string, true);//with validate
10608               }
10609             }
10610             catch(XQueryException& e)
10611             {
10612               set_source(e, loc);
10613               throw;
10614             }
10615           }
10616         }
10617         break;
10618       }
10619       default: {}
10620     }
10621   }
10622 
10623   if (f != NULL && f->getKind() ==  FunctionConsts::FN_APPLY_1)
10624   {
10625     expr* applyExpr = theExprManager->
10626     create_apply_expr(theRootSctx, loc, arguments[0], false);
10627 
10628     push_nodestack(applyExpr);
10629     return;
10630   }
10631 
10632   // add context-item for functions with zero arguments which implicitly
10633   // take the context-item as argument
10634   if (f != NULL && xquery_fns_def_dot.test(f->getKind()))
10635   {
10636     arguments.push_back(DOT_REF);
10637     f = lookup_fn(qname, 1, loc);
10638   }
10639 
10640   //  Check if it is a zorba builtin function, and if so,
10641   // make sure that the module it belongs to has been imported.
10642   if (f != NULL &&
10643       f->isBuiltin() &&
10644       fn_ns != static_context::W3C_FN_NS &&
10645 #ifdef ZORBA_WITH_JSON
10646       fn_ns != static_context::JSONIQ_FN_NS &&
10647 #endif
10648       fn_ns != XQUERY_MATH_FN_NS &&
10649       fn_ns != theModuleNamespace)
10650   {
10651     if (! theSctx->is_imported_builtin_module(fn_ns))
10652     {
10653       RAISE_ERROR(err::XPST0017, loc,
10654       ERROR_PARAMS(qname->get_qname(), ZED(FunctionUndeclared_3), numArgs));
10655     }
10656   }
10657 
10658   numArgs = arguments.size();  // recompute size
10659 
10660   // Check if this is a call to a type constructor function
10661   xqtref_t type = CTX_TM->create_named_type(qnameItem,
10662                                             TypeConstants::QUANT_QUESTION,
10663                                             loc);
10664 
10665   if (type != NULL)
10666   {
10667     if (numArgs != 1 ||
10668         TypeOps::is_equal(tm, *type, *GENV_TYPESYSTEM.NOTATION_TYPE_QUESTION, loc) ||
10669         TypeOps::is_equal(tm, *type, *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_QUESTION, loc))
10670     {
10671       RAISE_ERROR(err::XPST0017, loc,
10672       ERROR_PARAMS(qname->get_qname(), ZED(FunctionUndeclared_3), numArgs));
10673     }
10674 
10675     push_nodestack(create_cast_expr(loc, arguments[0], type, true));
10676   }
10677 
10678   // It is not a builtin constructor function
10679   else
10680   {
10681     if (f == NULL)
10682     {
10683       if (theHaveModuleImportCycle)
10684       {
10685         std::map<zstring, zstring>::const_iterator ite = theModulesStack.begin();
10686         std::map<zstring, zstring>::const_iterator end = theModulesStack.end();
10687 
10688         --end;
10689         assert((*end).second == theModuleNamespace);
10690 
10691         for (; ite != end; ++ite)
10692         {
10693           if ((*ite).second == fn_ns)
10694             RAISE_ERROR(err::XQST0093, loc, ERROR_PARAMS(theModuleNamespace));
10695         }
10696       }
10697 
10698       RAISE_ERROR(err::XPST0017, loc,
10699       ERROR_PARAMS(qname->get_qname(), ZED(FunctionUndeclared_3), numArgs));
10700     }
10701 
10702     // If this is a udf that is invoked from another udf, mark that other udf
10703     // as a non-leaf function.
10704     if (f->isUdf())
10705     {
10706       if (inUDFBody())
10707       {
10708         function* f1 = const_cast<function*>(theCurrentPrologVFDecl.getFunction());
10709         user_function* udf = dynamic_cast<user_function*>(f1);
10710         ZORBA_ASSERT(udf != NULL);
10711         udf->setLeaf(false);
10712       }
10713     }
10714 
10715     // Create and normalize the fo expr
10716     std::reverse(arguments.begin(), arguments.end());
10717 
10718     fo_expr* foExpr = theExprManager->create_fo_expr(theRootSctx, loc, f, arguments);
10719 
10720     normalize_fo(foExpr);
10721 
10722     expr* resultExpr = foExpr;
10723 
10724     if (f->isExternal())
10725     {
10726       const xqtref_t& resultType = f->getSignature().returnType();
10727 
10728       resultExpr = wrap_in_type_match(foExpr,
10729                                       resultType,
10730                                       loc,
10731                                       TreatIterator::FUNC_RETURN,
10732                                       f->getName());
10733     }
10734 
10735     // Some further normalization is required for certain builtin functions
10736     FunctionConsts::FunctionKind lKind = f->getKind();
10737     switch (lKind)
10738     {
10739       case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_GENERAL_N:
10740       case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_GENERAL_N:
10741       {
10742         FunctionConsts::FunctionKind fkind = FunctionConsts::OP_SORT_DISTINCT_NODES_ASC_1;
10743 
10744         resultExpr = theExprManager->create_fo_expr(theRootSctx,
10745                                  foExpr->get_loc(),
10746                                  BuiltinFunctionLibrary::getFunction(fkind),
10747                                  foExpr);
10748 
10749         break;
10750       }
10751       case FunctionConsts::FN_ANALYZE_STRING_2:
10752       case FunctionConsts::FN_ANALYZE_STRING_3:
10753       {
10754         resultExpr = wrap_in_validate_expr_strict(
10755           foExpr,
10756           "http://www.w3.org/2005/xpath-functions");
10757 
10758         break;
10759       }
10760       case FunctionConsts::FN_SERIALIZE_2:
10761       {
10762         import_schema_auto_prefix(
10763           loc,
10764           "http://www.w3.org/2010/xslt-xquery-serialization",
10765           NULL);
10766 
10767         break;
10768       }
10769       case FunctionConsts::FN_ZORBA_EVAL_1:
10770       case FunctionConsts::FN_ZORBA_EVAL_N_1:
10771       case FunctionConsts::FN_ZORBA_EVAL_U_1:
10772       case FunctionConsts::FN_ZORBA_EVAL_S_1:
10773       {
10774         expr_script_kind_t scriptingKind;
10775 
10776         if (lKind == FunctionConsts::FN_ZORBA_EVAL_1 ||
10777             lKind == FunctionConsts::FN_ZORBA_EVAL_N_1)
10778         {
10779           scriptingKind = SIMPLE_EXPR;
10780         }
10781         else if (lKind == FunctionConsts::FN_ZORBA_EVAL_U_1)
10782         {
10783           scriptingKind = UPDATING_EXPR;
10784         }
10785         else
10786         {
10787           scriptingKind = SEQUENTIAL_FUNC_EXPR;
10788         }
10789 
10790         eval_expr* evalExpr = theExprManager->
10791         create_eval_expr(theRootSctx,
10792                          loc,
10793                          foExpr->get_arg(0),
10794                          scriptingKind,
10795                          theNSCtx);
10796 
10797         resultExpr = evalExpr;
10798 
10799         std::vector<VarInfo*> inscopeVars;
10800         theSctx->getVariables(inscopeVars);
10801 
10802         csize numVars = inscopeVars.size();
10803 
10804         for (csize i = 0; i < numVars; ++i)
10805         {
10806           evalExpr->add_var(inscopeVars[i]->getVar());
10807         }
10808 
10809         break;
10810       }
10811       case FunctionConsts::FN_ZORBA_INVOKE_N:
10812       case FunctionConsts::FN_ZORBA_INVOKE_N_N:
10813       case FunctionConsts::FN_ZORBA_INVOKE_U_N:
10814       case FunctionConsts::FN_ZORBA_INVOKE_S_N:
10815       {
10816         /*
10817            invoke(qnameExpr, arg1Expr, ...., argNExpr)
10818 
10819            is rewritten internally as:
10820 
10821            let $temp_invoke_var1   := data(qnameExpr) treat as xs:QName
10822            let $temp_invoke_var2   := arg1Expr
10823            ...
10824            let $temp_invoke_varN+1 := argNExpr
10825            let $query := concat("Q{",
10826                                 string(namespace-uri-from-QName(temp_invoke_var1)),
10827                                 "}",
10828                                 string(local-name-from-QName(temp_invoke_var1)),
10829                                 "($temp_invoke_var2, ..., $temp_invoke_varN+1)")
10830            return eval { $query }
10831         */
10832 
10833         expr_script_kind_t scriptingKind = SIMPLE_EXPR; // avoid warning
10834         zstring query_params;
10835         std::vector<var_expr*> temp_vars;
10836 
10837         if (lKind == FunctionConsts::FN_ZORBA_INVOKE_N ||
10838             lKind == FunctionConsts::FN_ZORBA_INVOKE_N_N)
10839         {
10840           scriptingKind = SIMPLE_EXPR;
10841         }
10842         else if (lKind == FunctionConsts::FN_ZORBA_INVOKE_U_N)
10843         {
10844           scriptingKind = UPDATING_EXPR;
10845         }
10846         else if (lKind == FunctionConsts::FN_ZORBA_INVOKE_S_N)
10847         {
10848           scriptingKind = SEQUENTIAL_FUNC_EXPR;
10849         }
10850 
10851         if (numArgs == 0)
10852         {
10853           RAISE_ERROR(err::XPST0017, loc,
10854           ERROR_PARAMS("invoke", ZED(FunctionUndeclared_3), numArgs));
10855         }
10856 
10857         // create a flwor with LETs to hold the parameters
10858         flwor_expr* flworExpr = theExprManager->
10859         create_flwor_expr(theRootSctx, loc, false);
10860 
10861         // wrap function's QName
10862         expr* qnameExpr = wrap_in_type_promotion(arguments[0],
10863                                                  theRTM.QNAME_TYPE_ONE,
10864                                                  PromoteIterator::TYPE_PROMOTION);
10865 
10866         for (csize i = 0; i < numArgs ; ++i)
10867         {
10868           let_clause* lc;
10869           store::Item_t qnameItem;
10870 
10871           // cannot use create_temp_var() as the variables created there are not
10872           // accessible. use a special name but check for name clashes
10873           do
10874           {
10875             std::string localName = "temp_invoke_var" +
10876                                     ztd::to_string(theTempVarCounter++);
10877             GENV_ITEMFACTORY->createQName(qnameItem, "", "", localName.c_str());
10878           }
10879           while (lookup_var(qnameItem, loc, zerr::ZXQP0000_NO_ERROR) != NULL);
10880 
10881           var_expr* var = create_var(loc, qnameItem, var_expr::let_var);
10882           temp_vars.push_back(var);
10883 
10884           if (i == 0)
10885             lc = wrap_in_letclause(qnameExpr, var);
10886           else
10887             lc = wrap_in_letclause(arguments[i], var);
10888 
10889           flworExpr->add_clause(lc);
10890 
10891           // add the parameters to the eval's query string
10892           if (i > 1)
10893             query_params += ",";
10894           if (i > 0)
10895             query_params += "$" + var->get_name()->getStringValue();
10896         }
10897 
10898         query_params = "(" + query_params + ")";
10899 
10900         // Expanded QName's namespace URI
10901         expr* namespaceExpr =
10902         theExprManager->create_fo_expr(theRootSctx,
10903                     loc,
10904                     GET_BUILTIN_FUNCTION(FN_NAMESPACE_URI_FROM_QNAME_1),
10905                     temp_vars[0]);
10906 
10907         namespaceExpr =
10908         theExprManager->create_fo_expr(theRootSctx,
10909                     loc,
10910                     GET_BUILTIN_FUNCTION(FN_STRING_1),
10911                     namespaceExpr);
10912 
10913         // Expanded QName's local name
10914         expr* localExpr =
10915         theExprManager->create_fo_expr(theRootSctx,
10916                     loc,
10917                     GET_BUILTIN_FUNCTION(FN_LOCAL_NAME_FROM_QNAME_1),
10918                     temp_vars[0]);
10919 
10920         localExpr = theExprManager->
10921         create_fo_expr(theRootSctx, loc, GET_BUILTIN_FUNCTION(FN_STRING_1), localExpr);
10922 
10923         // qnameExpr := concat("Q{",
10924         //                     namespaceExpr,
10925         //                     "}",
10926         //                     localExpr,
10927         //                     "($temp_invoke_var2, $temp_invoke_var3,...)")
10928         std::vector<expr*> concat_args;
10929         concat_args.push_back(theExprManager->create_const_expr(theRootSctx, loc, "Q{"));
10930         concat_args.push_back(namespaceExpr);
10931         concat_args.push_back(theExprManager->create_const_expr(theRootSctx, loc, "}"));
10932         concat_args.push_back(localExpr);
10933         concat_args.push_back(theExprManager->create_const_expr(theRootSctx, loc, query_params));
10934 
10935         qnameExpr = theExprManager->
10936         create_fo_expr(theRootSctx,
10937                        loc,
10938                        GET_BUILTIN_FUNCTION(FN_CONCAT_N),
10939                        concat_args);
10940 
10941         eval_expr* evalExpr = theExprManager->
10942         create_eval_expr(theRootSctx,
10943                          loc,
10944                          qnameExpr,
10945                          scriptingKind,
10946                          theNSCtx);
10947 
10948         flworExpr->set_return_expr(evalExpr);
10949         resultExpr = flworExpr;
10950 
10951         for (csize i = 0; i < temp_vars.size(); ++i)
10952         {
10953           evalExpr->add_var(temp_vars[i]);
10954         }
10955 
10956         break;
10957       }
10958 
10959       default:
10960       {
10961       }
10962     } // switch
10963 
10964     f->processPragma(resultExpr, theScopedPragmas);
10965 
10966     push_nodestack(resultExpr);
10967   }
10968 }
10969 
10970 
10971 /*******************************************************************************
10972   ArgList := ExprSingle ("," ExprSingle)*
10973 ********************************************************************************/
begin_visit(const ArgList & v)10974 void* begin_visit(const ArgList& v)
10975 {
10976   TRACE_VISIT();
10977   return no_state;
10978 }
10979 
end_visit(const ArgList & v,void *)10980 void end_visit(const ArgList& v, void* /*visit_state*/)
10981 {
10982   TRACE_VISIT_OUT();
10983 }
10984 
10985 
10986 /*******************************************************************************
10987   PostfixExpr ::= PrimaryExpr (Predicate | ArgumentList)*
10988 
10989   ArgumentList ::= "(" (Argument ("," Argument)*)? ")"
10990 
10991   Argument ::= ExprSingle
10992 
10993   As shown above, there is no grammar rule for DynamicFunctionInvocation. A
10994   PostfinExpr becomes a dynamic function invocation if the PrimaryExpr is
10995   followed by an ArgumentList, in which case, the PrimaryExpr is supposed to
10996   return a function item.
10997 ********************************************************************************/
begin_visit(const DynamicFunctionInvocation & v)10998 void* begin_visit(const DynamicFunctionInvocation& v)
10999 {
11000   TRACE_VISIT();
11001   return no_state;
11002 }
11003 
11004 
end_visit(const DynamicFunctionInvocation & v,void *)11005 void end_visit(const DynamicFunctionInvocation& v, void* /*visit_state*/)
11006 {
11007   TRACE_VISIT_OUT();
11008 
11009   // Collect the arguments of the dynamic function invocation
11010   csize numArgs = 0;
11011   std::vector<expr*> arguments;
11012   if (v.getArgList() != 0)
11013   {
11014     numArgs = v.getArgList()->size();
11015     for (csize i = numArgs; i > 0; --i)
11016     {
11017       arguments.push_back(pop_nodestack());
11018     }
11019   }
11020 
11021   // Get the function item expr
11022   expr* sourceExpr = pop_nodestack();
11023   ZORBA_ASSERT(sourceExpr != 0);
11024 
11025 #ifdef ZORBA_WITH_JSON
11026   TypeManager* tm = sourceExpr->get_type_manager();
11027   xqtref_t srcType = sourceExpr->get_return_type();
11028 
11029   if (!theSctx->is_feature_set(feature::hof) ||
11030       (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ITEM_TYPE_STAR)))
11031   {
11032     if (numArgs != 1)
11033     {
11034       RAISE_ERROR_NO_PARAMS(jerr::JNTY0018, loc);
11035     }
11036     function* func;
11037 
11038     flwor_expr* flworExpr = wrap_expr_in_flwor(sourceExpr, false);
11039     fo_expr* accessorExpr = NULL;
11040 
11041     const for_clause* fc =
11042     reinterpret_cast<const for_clause*>(flworExpr->get_clause(0));
11043 
11044     expr* flworVarExpr = fc->get_var();
11045 
11046     if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_ARRAY_TYPE_STAR))
11047     {
11048       func = GET_BUILTIN_FUNCTION(FN_JSONIQ_MEMBER_2);
11049     }
11050     else if (TypeOps::is_subtype(tm, *srcType, *theRTM.JSON_OBJECT_TYPE_STAR))
11051     {
11052       func = GET_BUILTIN_FUNCTION(FN_JSONIQ_VALUE_2);
11053     }
11054     else
11055     {
11056       func = GET_BUILTIN_FUNCTION(OP_ZORBA_JSON_ITEM_ACCESSOR_2);
11057     }
11058 
11059     accessorExpr = theExprManager->create_fo_expr(theRootSctx,
11060                                                   loc,
11061                                                   func,
11062                                                   flworVarExpr,
11063                                                   arguments[0]);
11064 
11065     normalize_fo(accessorExpr);
11066 
11067     flworExpr->set_return_expr(accessorExpr);
11068 
11069     pop_scope();
11070 
11071     push_nodestack(flworExpr);
11072 
11073     return;
11074   }
11075 #endif
11076 
11077   if (!theSctx->is_feature_set(feature::hof))
11078   {
11079     RAISE_ERROR(zerr::ZXQP0050_FEATURE_NOT_AVAILABLE, loc,
11080     ERROR_PARAMS("higher-order functions (hof)"));
11081   }
11082 
11083   expr* dynFuncInvocation =
11084   theExprManager->create_dynamic_function_invocation_expr(theRootSctx,
11085                                                           loc,
11086                                                           sourceExpr,
11087                                                           arguments);
11088   push_nodestack(dynFuncInvocation);
11089 }
11090 
11091 
11092 /*******************************************************************************
11093   LiteralFunctionItem ::= QName "#" IntegerLiteral
11094 ********************************************************************************/
begin_visit(const LiteralFunctionItem & v)11095 void* begin_visit(const LiteralFunctionItem& v)
11096 {
11097   TRACE_VISIT();
11098 
11099   if ( !theSctx->is_feature_set(feature::hof) )
11100   {
11101     RAISE_ERROR(zerr::ZXQP0050_FEATURE_NOT_AVAILABLE, v.get_location(),
11102     ERROR_PARAMS("higher-order functions (hof)"));
11103   }
11104   return no_state;
11105 }
11106 
11107 
end_visit(const LiteralFunctionItem & v,void *)11108 void end_visit(const LiteralFunctionItem& v, void* /*visit_state*/)
11109 {
11110   TRACE_VISIT_OUT();
11111 
11112   rchandle<QName> qname = v.getQName();
11113   uint32_t arity = 0;
11114 
11115   try
11116   {
11117     arity = to_xs_unsignedInt(v.getArity());
11118   }
11119   catch ( std::range_error const& )
11120   {
11121     RAISE_ERROR(err::XPST0017, loc,
11122     ERROR_PARAMS(v.getArity(), ZED(NoParseFnArity)));
11123   }
11124 
11125   // Get function implementation
11126   function* fn = lookup_fn(qname, arity, loc);
11127 
11128   // raise XPST0017 if function could not be found
11129   if (fn == 0)
11130   {
11131     RAISE_ERROR(err::XPST0017, loc,
11132     ERROR_PARAMS(qname->get_qname(), ZED(FunctionUndeclared_3), arity));
11133   }
11134 
11135   // If it is a builtin function F with signature (R, T1, ..., TN) , wrap it
11136   // in a udf UF: function UF(x1 as T1, ..., xN as TN) as R { F(x1, ... xN) }
11137   if (!fn->isUdf())
11138   {
11139     user_function* udf = new user_function(loc,
11140                                            fn->getSignature(),
11141                                            NULL, // no body for now
11142                                            fn->getScriptingKind(),
11143                                            theCCB);
11144 
11145     std::vector<expr*> foArgs(arity);
11146     std::vector<var_expr*> udfArgs(arity);
11147 
11148     for (ulong i = 0; i < arity; ++i)
11149     {
11150       var_expr* argVar = create_temp_var(loc, var_expr::arg_var);
11151 
11152       argVar->set_param_pos(i);
11153       argVar->set_udf(udf);
11154 
11155       udfArgs[i] = argVar;
11156       foArgs[i] = argVar;
11157     }
11158 
11159     expr* body = theExprManager->create_fo_expr(theRootSctx, loc, fn, foArgs);
11160 
11161     udf->setArgVars(udfArgs);
11162     udf->setBody(body);
11163 
11164     fn = udf;
11165   }
11166 
11167   expr* fiExpr = theExprManager->create_function_item_expr(theRootSctx, loc, fn->getName(), fn, arity);
11168 
11169   push_nodestack(fiExpr);
11170 }
11171 
11172 
11173 /*******************************************************************************
11174   InlineFunction ::= "function" "(" ParamList? ")"
11175                      ("as" SequenceType)? EnclosedExpr
11176 ********************************************************************************/
begin_visit(const InlineFunction & v)11177 void* begin_visit(const InlineFunction& v)
11178 {
11179   TRACE_VISIT();
11180 
11181   if ( !theSctx->is_feature_set(feature::hof) )
11182   {
11183     throw XQUERY_EXCEPTION(
11184       zerr::ZXQP0050_FEATURE_NOT_AVAILABLE,
11185       ERROR_PARAMS( "higher-order functions (hof)" ),
11186       ERROR_LOC( v.get_location() )
11187     );
11188   }
11189 
11190   // Get the in-scope vars of the scope before opening the new scope for the
11191   // function devl
11192   std::vector<VarInfo*> scopedVars;
11193   theSctx->getVariables(scopedVars);
11194 
11195   push_scope();
11196 
11197   function_item_expr* fiExpr = theExprManager->create_function_item_expr(theRootSctx, loc);
11198 
11199   push_nodestack(fiExpr);
11200 
11201   flwor_expr* flwor = NULL;
11202 
11203   // Handle function parameters. Translation of the params, if any, results to
11204   // a flwor expr with one let binding for each function parameter:
11205   //
11206   // let $x1 as T1 := _x1
11207   // .....
11208   // let $xN as TN := _xN
11209   //
11210   // where each _xi is an arg var.
11211   rchandle<ParamList> params = v.getParamList();
11212   if (params)
11213   {
11214     params->accept(*this);
11215 
11216     flwor = static_cast<flwor_expr*>(pop_nodestack());
11217   }
11218   else
11219   {
11220     flwor = theExprManager->create_flwor_expr(theRootSctx, loc, false);
11221   }
11222 
11223   // Handle inscope variables. For each inscope var, a let binding is added to
11224   // the flwor.
11225   std::vector<VarInfo*>::iterator ite = scopedVars.begin();
11226 
11227   for(; ite != scopedVars.end(); ++ite)
11228   {
11229     var_expr* varExpr = (*ite)->getVar();
11230     var_expr::var_kind kind = varExpr->get_kind();
11231 
11232     if (kind == var_expr::prolog_var || kind == var_expr::local_var)
11233     {
11234       continue;
11235     }
11236 
11237     store::Item_t qname = varExpr->get_name();
11238 
11239     var_expr* arg_var = create_var(loc, qname, var_expr::arg_var);
11240     var_expr* subst_var = bind_var(loc, qname, var_expr::let_var);
11241 
11242     let_clause* lc = wrap_in_letclause(&*arg_var, subst_var);
11243 
11244     arg_var->set_param_pos(flwor->num_clauses());
11245     arg_var->set_type(varExpr->get_return_type());
11246 
11247     // TODO: this could probably be done lazily in some cases
11248     //lc->setLazyEval(true);
11249     flwor->add_clause(lc);
11250 
11251     fiExpr->add_variable(varExpr);
11252 
11253     // ???? What about inscope vars that are hidden by param vars ???
11254   }
11255 
11256   if (flwor->num_clauses() > 0)
11257     push_nodestack(flwor);
11258   else
11259     push_nodestack(NULL);
11260 
11261   return no_state;
11262 }
11263 
11264 
end_visit(const InlineFunction & v,void * aState)11265 void end_visit(const InlineFunction& v, void* aState)
11266 {
11267   TRACE_VISIT_OUT();
11268 
11269   std::vector<var_expr*> argVars;
11270 
11271   // Get the return tyoe
11272   xqtref_t returnType = GENV_TYPESYSTEM.ITEM_TYPE_STAR;
11273   if(v.getReturnType() != 0)
11274   {
11275     returnType = pop_tstack();
11276   }
11277 
11278   // Get the inline function body and wrap it in appropriate type op.
11279   expr* body = pop_nodestack();
11280   ZORBA_ASSERT(body != 0);
11281 
11282   if (TypeOps::is_builtin_simple(CTX_TM, *returnType))
11283   {
11284     body = wrap_in_type_promotion(body, returnType, PromoteIterator::TYPE_PROMOTION);
11285   }
11286   else
11287   {
11288     body = wrap_in_type_match(body, returnType, loc, TreatIterator::TYPE_MATCH);
11289   }
11290 
11291   // Make the body be the return expr of the flwor that binds the function params.
11292   flwor_expr* flwor = static_cast<flwor_expr*>(pop_nodestack());
11293 
11294   if (flwor != NULL)
11295   {
11296     flwor->set_return_expr(body);
11297 
11298     body = flwor;
11299 
11300     // Parameters and inscope vars have been wrapped into a flwor expression (see
11301     // begin_visit). We need to add these to the udf obj so that they will bound
11302     // at runtime. We must do this here (before we optimize the inline function
11303     // body, because optimization may remove clauses from the flwor expr
11304     for (csize i = 0; i < flwor->num_clauses(); ++i)
11305     {
11306       const flwor_clause* lClause = flwor->get_clause(i);
11307       const let_clause* letClause = dynamic_cast<const let_clause*>(lClause);
11308       ZORBA_ASSERT(letClause != 0); // can only be a parameter bound using let
11309       var_expr* argVar = dynamic_cast<var_expr*>(letClause->get_expr());
11310       argVars.push_back(argVar);
11311     }
11312   }
11313 
11314   if (theCCB->theConfig.opt_level == CompilerCB::config::O1)
11315   {
11316     RewriterContext rCtx(theCCB,
11317                          body,
11318                          NULL,
11319                          "Inline function",
11320                          (theSctx->ordering_mode() == StaticContextConsts::ordered));
11321     GENV_COMPILERSUBSYS.getDefaultOptimizingRewriter()->rewrite(rCtx);
11322     body = rCtx.getRoot();
11323   }
11324 
11325   // Translate the type declarations for the function params
11326   std::vector<xqtref_t> paramTypes;
11327   rchandle<ParamList> params = v.getParamList();
11328   if (params != 0)
11329   {
11330     std::vector<rchandle<Param> >::const_iterator lIt = params->begin();
11331     for(; lIt != params->end(); ++lIt)
11332     {
11333       const Param* param = lIt->getp();
11334       const SequenceType* paramType = param->get_typedecl();
11335       if(paramType == 0)
11336       {
11337         paramTypes.push_back(GENV_TYPESYSTEM.ITEM_TYPE_STAR);
11338       }
11339       else
11340       {
11341         paramType->accept(*this);
11342         paramTypes.push_back(pop_tstack());
11343       }
11344     }
11345   }
11346 
11347   // Create the udf obj.
11348   user_function_t udf(new user_function(loc,
11349                                         signature(0, paramTypes, returnType),
11350                                         body,
11351                                         body->get_scripting_detail(),
11352                                         theCCB));
11353   udf->setArgVars(argVars);
11354   udf->setOptimized(true);
11355 
11356   // Get the function_item_expr and set its function to the udf created above.
11357   function_item_expr* fiExpr = dynamic_cast<function_item_expr*>(
11358                                theNodeStack.top());
11359   assert(fiExpr != NULL);
11360 
11361   fiExpr->set_function(udf);
11362 
11363   // pop the scope.
11364   pop_scope();
11365 }
11366 
11367 
11368 /*******************************************************************************
11369   JSONConstructor ::= ArrayConstructor |
11370                       SimpleObjectUnion |
11371                       AccumulatorObjectUnion |
11372                       DirectObjectConstructor
11373 ********************************************************************************/
11374 
11375 
11376 /*******************************************************************************
11377   ArrayConstructor ::= "[" Expr? "]"
11378 
11379   The Expr may return a sequence of zero or more items. If any of these items
11380   is a structured item, it is copied first, and the copy is inserted into the
11381   new array.
11382 ********************************************************************************/
begin_visit(const JSONArrayConstructor & v)11383 void* begin_visit(const JSONArrayConstructor& v)
11384 {
11385   TRACE_VISIT();
11386 
11387 #ifndef ZORBA_WITH_JSON
11388   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
11389 #endif
11390 
11391   return no_state;
11392 }
11393 
end_visit(const JSONArrayConstructor & v,void *)11394 void end_visit(const JSONArrayConstructor& v, void* /*visit_state*/)
11395 {
11396   TRACE_VISIT_OUT();
11397 
11398 #ifdef ZORBA_WITH_JSON
11399   expr* contentExpr = NULL;
11400 
11401   if (v.get_expr() != NULL)
11402   {
11403     contentExpr = pop_nodestack();
11404   }
11405 
11406   push_nodestack(theExprManager->create_json_array_expr(theRootSctx, loc, contentExpr));
11407 #endif
11408 }
11409 
11410 
11411 /*******************************************************************************
11412   SimpleObjectUnion ::= "{|" Expr? "|}"
11413 
11414   AccumulatorObjectUnion ::= "{[" Expr? "]}"
11415 
11416   The Expr must return a sequence of zero or more objects
11417 ********************************************************************************/
begin_visit(const JSONObjectConstructor & v)11418 void* begin_visit(const JSONObjectConstructor& v)
11419 {
11420   TRACE_VISIT();
11421 #ifndef ZORBA_WITH_JSON
11422   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
11423 #endif
11424   return no_state;
11425 }
11426 
end_visit(const JSONObjectConstructor & v,void *)11427 void end_visit(const JSONObjectConstructor& v, void* /*visit_state*/)
11428 {
11429   TRACE_VISIT_OUT();
11430 
11431 #ifdef ZORBA_WITH_JSON
11432   expr* contentExpr = NULL;
11433 
11434   if (v.get_expr() != NULL)
11435   {
11436     contentExpr = pop_nodestack();
11437 
11438     contentExpr = theExprManager->
11439     create_treat_expr(theRootSctx,
11440                       contentExpr->get_loc(),
11441                       contentExpr,
11442                       GENV_TYPESYSTEM.JSON_OBJECT_TYPE_STAR,
11443                       TreatIterator::TYPE_MATCH,
11444                       true,
11445                       NULL);
11446   }
11447 
11448   expr* jo = theExprManager->
11449   create_json_object_expr(theRootSctx, loc, contentExpr, v.get_accumulate());
11450 
11451   push_nodestack(jo);
11452 #endif
11453 }
11454 
11455 
11456 /*******************************************************************************
11457   DirectObjectConstructor ::= "{" PairConstructor ("," PairConstructor )* "}"
11458 
11459   PairConstructor ::= ExprSingle ":" ExprSingle
11460 ********************************************************************************/
begin_visit(const JSONDirectObjectConstructor & v)11461 void* begin_visit(const JSONDirectObjectConstructor& v)
11462 {
11463   TRACE_VISIT();
11464 #ifndef ZORBA_WITH_JSON
11465   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
11466 #endif
11467   return no_state;
11468 }
11469 
end_visit(const JSONDirectObjectConstructor & v,void *)11470 void end_visit(const JSONDirectObjectConstructor& v, void* /*visit_state*/)
11471 {
11472   TRACE_VISIT_OUT();
11473 
11474 #ifdef ZORBA_WITH_JSON
11475   csize numPairs = v.numPairs();
11476   std::vector<expr*> names(numPairs);
11477   std::vector<expr*> values(numPairs);
11478 
11479   for (csize i = numPairs; i > 0; --i)
11480   {
11481     names[i-1] = pop_nodestack();
11482     values[i-1] = pop_nodestack();
11483   }
11484 
11485   expr* jo = theExprManager->
11486   create_json_direct_object_expr(theRootSctx, loc, names, values);
11487 
11488   push_nodestack(jo);
11489 #endif
11490 }
11491 
11492 
11493 /*******************************************************************************
11494   PairList ::= PairConstructor | PairList COMMA PairConstructor
11495 ********************************************************************************/
begin_visit(const JSONPairList & v)11496 void* begin_visit(const JSONPairList& v)
11497 {
11498   TRACE_VISIT();
11499   return no_state;
11500 }
11501 
end_visit(const JSONPairList & v,void *)11502 void end_visit(const JSONPairList& v, void* /*visit_state*/)
11503 {
11504   TRACE_VISIT_OUT();
11505 }
11506 
11507 
11508 /*******************************************************************************
11509   PairConstructor ::= ExprSingle ":" ExprSingle
11510 
11511   The PairConstructor production can appear only on the RHS of a
11512   DirectObjectConstructor or in the source list of a JSONObjectInsertExpr
11513 
11514   The 1st ExprSingle must return exactly one item castable to string after
11515   atomization. The 2nd ExprSingle may return any kind of sequence; if the
11516   sequence is empty, it is replaced by the null item; if the sequence contains
11517   more than one item, it is boxed into an array.
11518 ********************************************************************************/
begin_visit(const JSONPairConstructor & v)11519 void* begin_visit(const JSONPairConstructor& v)
11520 {
11521   TRACE_VISIT ();
11522 #ifndef ZORBA_WITH_JSON
11523   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
11524 #else
11525 #endif
11526 
11527   return no_state;
11528 }
11529 
end_visit(const JSONPairConstructor & v,void *)11530 void end_visit(const JSONPairConstructor& v, void* /*visit_state*/)
11531 {
11532   TRACE_VISIT_OUT();
11533 
11534 #ifdef ZORBA_WITH_JSON
11535   expr* nameExpr = pop_nodestack();
11536   expr* valueExpr = pop_nodestack();
11537 
11538   nameExpr = wrap_in_atomization(nameExpr);
11539 
11540   nameExpr = theExprManager->
11541   create_cast_expr(theRootSctx,
11542                    nameExpr->get_loc(),
11543                    nameExpr,
11544                    GENV_TYPESYSTEM.STRING_TYPE_ONE);
11545 
11546   valueExpr = theExprManager->
11547   create_fo_expr(theRootSctx,
11548                  valueExpr->get_loc(),
11549                  GET_BUILTIN_FUNCTION(OP_ZORBA_JSON_BOX_1),
11550                  valueExpr);
11551 
11552   push_nodestack(valueExpr);
11553   push_nodestack(nameExpr);
11554 #endif
11555 }
11556 
11557 
11558 
11559 /*******************************************************************************
11560 
11561   Node Construction
11562 
11563   Constructor ::= DirectConstructor | ComputedConstructor
11564 
11565   DirectConstructor ::= DirElemConstructor |
11566                         DirCommentConstructor |
11567                         DirPIConstructor
11568 
11569 ********************************************************************************/
11570 
11571 
11572 /*******************************************************************************
11573   EnclosedExpr ::= "{" Expr "}"
11574 
11575   Although EnclosedExpr appears in several grammar rules, an EnclosedExpr
11576   parsenode is created only in the case of direct and computed node constructors.
11577 ********************************************************************************/
begin_visit(const EnclosedExpr & v)11578 void* begin_visit(const EnclosedExpr& v)
11579 {
11580   TRACE_VISIT();
11581   return no_state;
11582 }
11583 
end_visit(const EnclosedExpr & v,void *)11584 void end_visit (const EnclosedExpr& v, void* /*visit_state*/)
11585 {
11586   TRACE_VISIT_OUT();
11587 
11588   expr* contentExpr = pop_nodestack();
11589 
11590   fo_expr* foExpr = wrap_in_enclosed_expr(contentExpr, loc);
11591 
11592   push_nodestack(foExpr);
11593 }
11594 
11595 
11596 /*******************************************************************************
11597   DirElemConstructor ::= "<" QName DirAttributeList?
11598                          ("/>" | (">" DirElemContentList? "</" QName S? ">"))
11599 ********************************************************************************/
begin_visit(const DirElemConstructor & v)11600 void* begin_visit(const DirElemConstructor& v)
11601 {
11602   TRACE_VISIT();
11603 
11604   push_scope();
11605   push_elem_scope();
11606   return no_state;
11607 }
11608 
end_visit(const DirElemConstructor & v,void *)11609 void end_visit(const DirElemConstructor& v, void* /*visit_state*/)
11610 {
11611   TRACE_VISIT_OUT();
11612 
11613   expr* nameExpr = NULL;
11614   expr* attrExpr = NULL;
11615   expr* contentExpr = NULL;
11616 
11617   rchandle<QName> end_tag = v.get_end_name();
11618   rchandle<QName> start_tag = v.get_elem_name();
11619 
11620   if (end_tag != NULL && start_tag->get_qname() != end_tag->get_qname())
11621   {
11622     RAISE_ERROR(err::XPST0003, loc,
11623     ERROR_PARAMS(ZED(XPST0003_StartEndTagMismatch_23),
11624                  start_tag->get_qname(),
11625                  end_tag->get_qname()));
11626   }
11627 
11628   if (v.get_dir_content_list() != NULL)
11629     contentExpr = pop_nodestack();
11630 
11631   if (v.get_attr_list() != NULL)
11632     attrExpr = pop_nodestack();
11633 
11634   store::Item_t qnameItem;
11635   expand_elem_qname(qnameItem, v.get_elem_name(), loc);
11636 
11637   nameExpr = theExprManager->create_const_expr(theRootSctx, loc, qnameItem);
11638 
11639   bool copyNodes = (theCCB->theConfig.opt_level < CompilerCB::config::O1 ||
11640                     !Properties::instance()->noCopyOptim());
11641 
11642   push_nodestack(theExprManager->create_elem_expr(theRootSctx,
11643                                loc,
11644                                nameExpr,
11645                                attrExpr,
11646                                contentExpr,
11647                                theNSCtx,
11648                                copyNodes));
11649   pop_elem_scope();
11650   pop_scope();
11651 }
11652 
11653 
11654 /*******************************************************************************
11655    [120] DirAttributeList ::= DirAttr | DirAttributeList  DirAttr
11656 ********************************************************************************/
begin_visit(const DirAttributeList & v)11657 void* begin_visit(const DirAttributeList& v)
11658 {
11659   TRACE_VISIT();
11660 
11661   push_nodestack(NULL);
11662 
11663   // visit namespace declaratrion attributes first
11664   for (int visitType = 0; visitType < 2; ++visitType)
11665   {
11666     for (csize i = 0; i < v.size(); ++i)
11667     {
11668       const DirAttr* attr = v[i];
11669       const QName* qname = attr->get_name();
11670       bool isPrefix = qname->get_qname() == "xmlns" || qname->get_prefix() == "xmlns";
11671 
11672       if ((isPrefix && visitType == 0) || (! isPrefix && visitType == 1))
11673         attr->accept(*this);
11674     }
11675   }
11676 
11677   unsigned long numAttrs = 0;
11678   std::vector<attr_expr*> attributes;
11679   while(true)
11680   {
11681     expr* expr = pop_nodestack();
11682     if (expr == NULL)
11683       break;
11684 
11685     attr_expr* attrExpr = dynamic_cast<attr_expr*>(expr);
11686     const store::Item* attExprName = attrExpr->getQName();
11687 
11688     for (unsigned long i = 0; i < numAttrs; ++i)
11689     {
11690       const store::Item* attName = attributes[i]->getQName();
11691       if (attName->equals(attExprName))
11692         RAISE_ERROR(err::XQST0040, loc, ERROR_PARAMS(attName->getStringValue()));
11693     }
11694 
11695     attributes.push_back(attrExpr);
11696     ++numAttrs;
11697   }
11698 
11699   if (attributes.size() == 1)
11700   {
11701     push_nodestack(attributes[0]);
11702   }
11703   else
11704   {
11705     std::vector<expr*> args;
11706     for (std::vector<attr_expr*>::reverse_iterator it = attributes.rbegin();
11707          it != attributes.rend();
11708          ++it)
11709     {
11710       args.push_back((*it));
11711     }
11712 
11713     fo_expr* expr_list =
11714     theExprManager->create_fo_expr(theRootSctx, loc, op_concatenate, args);
11715 
11716     normalize_fo(expr_list);
11717 
11718     push_nodestack(expr_list);
11719   }
11720 
11721   return NULL;  // reject visitor -- everything done
11722 }
11723 
end_visit(const DirAttributeList & v,void *)11724 void end_visit(const DirAttributeList& v, void* /*visit_state*/)
11725 {
11726   // begin_visit() rejects visitor
11727   ZORBA_ASSERT(false);
11728 }
11729 
11730 
11731 /*******************************************************************************
11732   DirAttr ::= (S (QName S? "=" S? DirAttributeValue)
11733 ********************************************************************************/
begin_visit(const DirAttr & v)11734 void* begin_visit(const DirAttr& v)
11735 {
11736   TRACE_VISIT();
11737   // boundary is needed because the value of an attribute might be empty
11738   push_nodestack(NULL);
11739   return no_state;
11740 }
11741 
end_visit(const DirAttr & v,void *)11742 void end_visit(const DirAttr& v, void* /*visit_state*/)
11743 {
11744   TRACE_VISIT_OUT();
11745 
11746   expr* valueExpr = pop_nodestack();
11747 
11748   if (valueExpr != NULL)
11749   {
11750     // delete boundary
11751     pop_nodestack();
11752   }
11753 
11754   QName* qname = v.get_name();
11755 
11756   // Namespace direct attribute
11757   if (qname->get_qname() == "xmlns" || qname->get_prefix() == "xmlns")
11758   {
11759     zstring prefix;
11760     zstring uri;
11761     bool have_uri = false;
11762 
11763     if (qname->get_qname() != "xmlns")
11764     {
11765       prefix = qname->get_localname();
11766 
11767       if (ZSTREQ(prefix, "xmlns"))
11768         throw XQUERY_EXCEPTION(
11769           err::XQST0070,
11770           ERROR_PARAMS( prefix, ZED( NoRebindPrefix ) ),
11771           ERROR_LOC( loc )
11772         );
11773     }
11774 
11775     const_expr* constValueExpr = dynamic_cast<const_expr*>(valueExpr);
11776     fo_expr* foExpr = dynamic_cast<fo_expr*>(valueExpr);
11777     if (foExpr != NULL && foExpr->get_func() != op_concatenate)
11778       foExpr = NULL;
11779 
11780     if (constValueExpr != NULL)
11781     {
11782       constValueExpr->get_val()->getStringValue2(uri);
11783       have_uri = true;
11784     }
11785     else if (foExpr != NULL)
11786     {
11787       for (unsigned int i=0; i<foExpr->num_args(); i++)
11788       {
11789         const_expr* constValueExpr = dynamic_cast<const_expr*>(foExpr->get_arg(i));
11790         if (constValueExpr != NULL)
11791         {
11792           constValueExpr->get_val()->appendStringValue(uri);
11793         }
11794         else
11795         {
11796           fo_expr* foExpr2 = dynamic_cast<fo_expr*>(foExpr->get_arg(i));
11797           if (foExpr2 != NULL &&
11798               foExpr2->get_func()->getKind() == FunctionConsts::OP_ENCLOSED_1 &&
11799               (qname->get_qname() == "xmlns" || qname->get_prefix() == "xmlns"))
11800           {
11801             throw XQUERY_EXCEPTION(err::XQST0022, ERROR_LOC(loc));
11802           }
11803         }
11804       }
11805       have_uri = true;
11806     }
11807 
11808     if (have_uri)
11809     {
11810       if ((ZSTREQ(prefix, "xml") && !ZSTREQ(uri, XML_NS)))
11811       {
11812         RAISE_ERROR(err::XQST0070, loc,
11813         ERROR_PARAMS(prefix, ZED(NoRebindPrefix)));
11814       }
11815 
11816       if ((ZSTREQ(uri, XML_NS) && !ZSTREQ(prefix, "xml")) ||
11817            ZSTREQ(uri, XMLNS_NS))
11818       {
11819         RAISE_ERROR(err::XQST0070, loc, ERROR_PARAMS(uri, ZED(NoBindURI)));
11820       }
11821 
11822       theSctx->bind_ns(prefix, uri, loc, err::XQST0071);
11823       theNSCtx->bind_ns(prefix, uri);
11824 
11825       if (prefix.empty())
11826         theSctx->set_default_elem_type_ns(uri, true, loc);
11827     }
11828     else if (valueExpr == NULL)
11829     {
11830       if (ZSTREQ(prefix, "xml"))
11831       {
11832         RAISE_ERROR(err::XQST0070, loc,
11833         ERROR_PARAMS(prefix, ZED(NoRebindPrefix)));
11834       }
11835 
11836       // unbind the prefix
11837       zstring empty;
11838       theSctx->bind_ns(prefix, empty, loc, err::XQST0071);
11839       theNSCtx->bind_ns(prefix, empty);
11840 
11841       if (prefix.empty())
11842         theSctx->set_default_elem_type_ns(empty, true, loc);
11843     }
11844     else
11845     {
11846       throw XQUERY_EXCEPTION(err::XQST0022, ERROR_LOC(loc));
11847     }
11848   }
11849   else
11850   // Plain direct attribute
11851   {
11852     store::Item_t qnameItem;
11853     expand_no_default_qname(qnameItem, qname, qname->get_location());
11854 
11855     expr* nameExpr = theExprManager->create_const_expr(theRootSctx, loc, qnameItem);
11856 
11857     fo_expr* foExpr = NULL;
11858     if ((foExpr = dynamic_cast<fo_expr*>(valueExpr)) != NULL &&
11859         foExpr->get_func()->getKind() == FunctionConsts::OP_ENCLOSED_1)
11860     {
11861       foExpr->set_arg(0, wrap_in_atomization(foExpr->get_arg(0)));
11862     }
11863     else if (valueExpr != NULL)
11864     {
11865       valueExpr = wrap_in_atomization(valueExpr);
11866     }
11867 
11868     expr* attrExpr = theExprManager->create_attr_expr(theRootSctx, loc, nameExpr, valueExpr);
11869 
11870     push_nodestack(attrExpr);
11871   }
11872 }
11873 
11874 
11875 /*******************************************************************************
11876   DirElemContentList ::= DirElemContent | DirElemContentList DirElemContent
11877 ********************************************************************************/
begin_visit(const DirElemContentList & v)11878 void* begin_visit(const DirElemContentList& v)
11879 {
11880   TRACE_VISIT();
11881 
11882   push_nodestack(NULL);
11883   return no_state;
11884 }
11885 
end_visit(const DirElemContentList & v,void *)11886 void end_visit(const DirElemContentList& v, void* /*visit_state*/)
11887 {
11888   TRACE_VISIT_OUT();
11889 
11890   std::vector<expr*> args;
11891   while (true)
11892   {
11893     expr* e = pop_nodestack();
11894     if (e == NULL)
11895       break;
11896 
11897     args.push_back(e);
11898   }
11899 
11900   if (args.size() == 1)
11901   {
11902     push_nodestack(args[0]);
11903   }
11904   else
11905   {
11906     fo_expr* expr_list = theExprManager->
11907     create_fo_expr(theRootSctx, loc, op_concatenate, args);
11908 
11909     normalize_fo(expr_list);
11910 
11911     push_nodestack(expr_list);
11912   }
11913 }
11914 
11915 
begin_visit(const DirElemContent & v)11916 void* begin_visit(const DirElemContent& v)
11917 {
11918   TRACE_VISIT();
11919 
11920   return no_state;
11921 }
11922 
end_visit(const DirElemContent & v,void *)11923 void end_visit(const DirElemContent& v, void* /*visit_state*/)
11924 {
11925   TRACE_VISIT_OUT();
11926 
11927   if (v.get_direct_cons() != NULL)
11928   {
11929     // nothing to be done, the content expression is already on the stack
11930   }
11931   else if (v.get_cdata() != NULL)
11932   {
11933   }
11934   else if (v.get_common_content() != NULL)
11935   {
11936   }
11937   else
11938   {
11939     if (!v.isStripped())
11940     {
11941       expr* content = theExprManager->create_const_expr(theRootSctx, loc, v.get_elem_content().str());
11942 
11943       push_nodestack(theExprManager->create_text_expr(theRootSctx, loc,
11944                                    text_expr::text_constructor,
11945                                    content));
11946     }
11947   }
11948 }
11949 
11950 
11951 /**
11952  * Inserts an entry in theIsWSBoundaryStack and thePossibleWSContentStack to save
11953  * information during boundary whitespace checking.
11954  */
begin_check_boundary_whitespace()11955 void begin_check_boundary_whitespace()
11956 {
11957   if (theSctx->boundary_space_mode() == StaticContextConsts::strip_space)
11958 {
11959     theIsWSBoundaryStack.push(true);
11960     thePossibleWSContentStack.push(0);
11961   }
11962 }
11963 
11964 
11965 /*******************************************************************************
11966   Whitespace checking. Checks if v might be a whitespace (check of the following
11967   boundary can only be checked during the next invocation), and if the items
11968   saved in thePossibleWSContentStack is really boundary whitespace.
11969 ********************************************************************************/
check_boundary_whitespace(const DirElemContent & v)11970 void check_boundary_whitespace(const DirElemContent& v)
11971 {
11972   v.setIsStripped(false);
11973   if (theSctx->boundary_space_mode() == StaticContextConsts::strip_space)
11974   {
11975     bool lPrevIsBoundary = translator_ns::pop_stack (theIsWSBoundaryStack);
11976     const DirElemContent* lPrev = translator_ns::peek_stack(thePossibleWSContentStack);
11977     thePossibleWSContentStack.pop();
11978 
11979     if (v.get_direct_cons() != 0 ||
11980         (v.get_common_content() != 0 && v.get_common_content()->get_expr() != 0))
11981     {
11982       thePossibleWSContentStack.push(0);
11983       theIsWSBoundaryStack.push(true);
11984       if (lPrev != 0) {
11985         lPrev->setIsStripped(true);
11986       }
11987     }
11988     else if (v.get_common_content() != 0 || v.get_cdata() != 0)
11989     {
11990       thePossibleWSContentStack.push(0);
11991       theIsWSBoundaryStack.push(false);
11992     }
11993     else
11994     {
11995       bool lCouldBe = false;
11996       if (lPrevIsBoundary) {
11997         zstring content = v.get_elem_content().str();
11998         utf8::trim_whitespace(content);
11999 
12000         // Filtering out of whitespaces
12001         if (content.empty()) {
12002           lCouldBe = true;
12003         }
12004       }
12005       if (lCouldBe) {
12006         thePossibleWSContentStack.push(&v);
12007       } else {
12008         thePossibleWSContentStack.push(0);
12009       }
12010       theIsWSBoundaryStack.push(false);
12011     }
12012   }
12013 }
12014 
12015 /**
12016  * Deletes the entries in theIsWSBoundaryStack and thePossibleWSContentStack. If thePossibleWSContentStack
12017  * contains an item, this item is boundary whitespace because end of content is a boundary.
12018  */
end_check_boundary_whitespace()12019 void end_check_boundary_whitespace()
12020 {
12021   if (theSctx->boundary_space_mode() == StaticContextConsts::strip_space)
12022   {
12023     const DirElemContent* lPrev = translator_ns::pop_stack (thePossibleWSContentStack);
12024     if (lPrev != 0)
12025     {
12026       lPrev->setIsStripped(true);
12027     }
12028     theIsWSBoundaryStack.pop();
12029   }
12030 }
12031 
12032 
12033 
begin_visit(const CDataSection & v)12034 void* begin_visit(const CDataSection& v)
12035 {
12036   TRACE_VISIT();
12037   return no_state;
12038 }
12039 
end_visit(const CDataSection & v,void *)12040 void end_visit(const CDataSection& v, void* /*visit_state*/)
12041 {
12042   TRACE_VISIT_OUT();
12043   std::string lCDATA_content = v.get_cdata_content().str();
12044   // Skip empty CDATA sections
12045   if(!lCDATA_content.empty())
12046   {
12047     expr* content = theExprManager->create_const_expr(theRootSctx, loc, lCDATA_content);
12048     push_nodestack(theExprManager->create_text_expr(theRootSctx, loc, text_expr::text_constructor, content));
12049   }
12050 }
12051 
12052 
begin_visit(const DirAttributeValue & v)12053 void* begin_visit(const DirAttributeValue& v)
12054 {
12055   TRACE_VISIT();
12056   return no_state;
12057 }
12058 
end_visit(const DirAttributeValue & v,void *)12059 void end_visit(const DirAttributeValue& v, void* /*visit_state*/)
12060 {
12061   TRACE_VISIT_OUT();
12062 }
12063 
12064 
attr_content_list(const QueryLoc & loc,void *)12065 void attr_content_list(const QueryLoc& loc, void* /*visit_state*/)
12066 {
12067   std::vector<expr*> args;
12068   while(true)
12069   {
12070     expr* e = pop_nodestack();
12071     if (e == NULL)
12072       break;
12073 
12074     args.push_back(e);
12075   }
12076 
12077   if (args.size() == 1)
12078   {
12079     push_nodestack(args[0]);
12080   }
12081   else if (args.size() > 1)
12082   {
12083     fo_expr* expr_list = theExprManager->
12084     create_fo_expr(theRootSctx, loc, op_concatenate, args);
12085 
12086     normalize_fo(expr_list);
12087 
12088     push_nodestack(expr_list);
12089   }
12090 }
12091 
12092 
begin_visit(const QuoteAttrContentList & v)12093 void* begin_visit(const QuoteAttrContentList& v)
12094 {
12095   TRACE_VISIT();
12096 
12097   push_nodestack(NULL);
12098   return no_state;
12099 }
12100 
end_visit(const QuoteAttrContentList & v,void * visit_state)12101 void end_visit(const QuoteAttrContentList& v, void* visit_state)
12102 {
12103   TRACE_VISIT_OUT();
12104   attr_content_list(loc, visit_state);
12105 }
12106 
12107 
begin_visit(const AposAttrContentList & v)12108 void* begin_visit(const AposAttrContentList& v)
12109 {
12110   TRACE_VISIT();
12111 
12112   push_nodestack(NULL);
12113   return no_state;
12114 }
12115 
end_visit(const AposAttrContentList & v,void * visit_state)12116 void end_visit(const AposAttrContentList& v, void* visit_state)
12117 {
12118   TRACE_VISIT_OUT();
12119   attr_content_list (loc, visit_state);
12120 }
12121 
12122 
attr_val_content(const QueryLoc & loc,const CommonContent * cc,zstring content)12123 void attr_val_content(const QueryLoc& loc, const CommonContent *cc, zstring content)
12124 {
12125   if (cc == NULL)
12126   {
12127     push_nodestack(theExprManager->create_const_expr (theRootSctx, loc, content));
12128   }
12129   else
12130   {
12131     // nothing to be done because when common content != NULL,
12132     // the corresponding expr is already on the stack
12133   }
12134 }
12135 
12136 
begin_visit(const QuoteAttrValueContent & v)12137 void* begin_visit(const QuoteAttrValueContent& v)
12138 {
12139   TRACE_VISIT();
12140   return no_state;
12141 }
12142 
end_visit(const QuoteAttrValueContent & v,void *)12143 void end_visit(const QuoteAttrValueContent& v, void* /*visit_state*/)
12144 {
12145   TRACE_VISIT_OUT();
12146   attr_val_content(loc, v.get_common_content(), v.get_quot_atcontent().str());
12147 }
12148 
12149 
begin_visit(const AposAttrValueContent & v)12150 void* begin_visit(const AposAttrValueContent& v)
12151 {
12152   TRACE_VISIT();
12153   return no_state;
12154 }
12155 
end_visit(const AposAttrValueContent & v,void *)12156 void end_visit(const AposAttrValueContent& v, void* /*visit_state*/)
12157 {
12158   TRACE_VISIT_OUT();
12159   attr_val_content(loc, v.get_common_content(), v.get_apos_atcontent().str());
12160 }
12161 
12162 
begin_visit(const CommonContent & v)12163 void* begin_visit(const CommonContent& v)
12164 {
12165   TRACE_VISIT();
12166 
12167   return no_state;
12168 }
12169 
end_visit(const CommonContent & v,void *)12170 void end_visit(const CommonContent& v, void* /*visit_state*/)
12171 {
12172   TRACE_VISIT_OUT();
12173 
12174   switch (v.get_type())
12175   {
12176   case ParseConstants::cont_entity:
12177   {
12178     ZORBA_ASSERT (false);
12179     break;
12180   }
12181   case ParseConstants::cont_charref:
12182   {
12183     std::string content;
12184     std::string charrefs = v.get_ref().str();
12185 
12186     const char* curRef = charrefs.c_str();
12187     const char* end = curRef + charrefs.size();
12188 
12189     while (curRef < end)
12190     {
12191       int d = xml::parse_entity(curRef, &content);
12192       if (d < 0)
12193       {
12194         RAISE_ERROR(err::XQST0090, loc,
12195         ERROR_PARAMS(curRef, theSctx->xquery_version()));
12196       }
12197       curRef += d;
12198 
12199       if (curRef >= end)
12200         break;
12201 
12202       if (*curRef == '&')
12203         curRef++;
12204     }
12205 
12206     expr* lConstExpr = theExprManager->create_const_expr(theRootSctx, loc, content);
12207     push_nodestack(lConstExpr);
12208     break;
12209   }
12210   case ParseConstants::cont_escape_lbrace:
12211   {
12212     // we always create a text node here because if we are in an attribute, we atomice
12213     // the text node into its string value
12214     zstring content("{");
12215     expr* lConstExpr = theExprManager->create_const_expr(theRootSctx, loc, content);
12216     push_nodestack ( lConstExpr );
12217     break;
12218   }
12219   case ParseConstants::cont_escape_rbrace:
12220   {
12221     // we always create a text node here because if we are in an attribute, we atomice
12222     // the text node into its string value
12223     zstring content("}");
12224     expr* lConstExpr = theExprManager->create_const_expr(theRootSctx, loc, content);
12225     push_nodestack ( lConstExpr );
12226     break;
12227   }
12228   case ParseConstants::cont_expr:
12229   {
12230     break;
12231   }
12232   }
12233 }
12234 
12235 
begin_visit(const DirCommentConstructor & v)12236 void* begin_visit(const DirCommentConstructor& v)
12237 {
12238   TRACE_VISIT();
12239   return no_state;
12240 }
12241 
end_visit(const DirCommentConstructor & v,void *)12242 void end_visit(const DirCommentConstructor& v, void* /*visit_state*/)
12243 {
12244   TRACE_VISIT_OUT();
12245 
12246   zstring str = v.get_comment().str();
12247   expr* content = theExprManager->create_const_expr (theRootSctx, loc, str);
12248   push_nodestack (theExprManager->create_text_expr(theRootSctx, loc,
12249                                 text_expr::comment_constructor,
12250                                 content));
12251 }
12252 
12253 
begin_visit(const DirPIConstructor & v)12254 void* begin_visit(const DirPIConstructor& v)
12255 {
12256   TRACE_VISIT();
12257   return no_state;
12258 }
12259 
end_visit(const DirPIConstructor & v,void *)12260 void end_visit(const DirPIConstructor& v, void* /*visit_state*/)
12261 {
12262   TRACE_VISIT_OUT();
12263 
12264   zstring target_str = v.get_pi_target().str();
12265   zstring target_upper;
12266   utf8::to_upper(target_str, &target_upper);
12267 
12268   if (target_upper == "XML")
12269     RAISE_ERROR(err::XPST0003, loc, ERROR_PARAMS(ZED(XPST0003_PiTarget)));
12270 
12271   expr* target = theExprManager->create_const_expr(theRootSctx, loc, target_str);
12272   expr* content = theExprManager->create_const_expr(theRootSctx, loc, v.get_pi_content().str());
12273 
12274   push_nodestack(theExprManager->create_pi_expr(theRootSctx, loc, target,  content));
12275 }
12276 
12277 
begin_visit(const CompDocConstructor & v)12278 void* begin_visit(const CompDocConstructor& v)
12279 {
12280   TRACE_VISIT();
12281   return no_state;
12282 }
12283 
end_visit(const CompDocConstructor & v,void *)12284 void end_visit(const CompDocConstructor& v, void* /*visit_state*/)
12285 {
12286   TRACE_VISIT_OUT();
12287 
12288   expr* lContent = pop_nodestack();
12289 
12290   fo_expr* lEnclosed = wrap_in_enclosed_expr(lContent, loc);
12291 
12292   bool copyNodes = (theCCB->theConfig.opt_level < CompilerCB::config::O1 ||
12293                     !Properties::instance()->noCopyOptim());
12294 
12295   push_nodestack(theExprManager->create_doc_expr(theRootSctx, loc, lEnclosed, copyNodes));
12296 }
12297 
12298 
begin_visit(const CompElemConstructor & v)12299 void* begin_visit(const CompElemConstructor& v)
12300 {
12301   TRACE_VISIT();
12302   return no_state;
12303 }
12304 
end_visit(const CompElemConstructor & v,void *)12305 void end_visit(const CompElemConstructor& v, void* /*visit_state*/)
12306 {
12307   TRACE_VISIT_OUT();
12308 
12309   expr* nameExpr = NULL;
12310   expr* contentExpr = NULL;
12311 
12312   if (v.get_content_expr() != 0)
12313   {
12314     contentExpr = pop_nodestack();
12315 
12316     fo_expr* lEnclosed = wrap_in_enclosed_expr(contentExpr, loc);
12317 
12318     contentExpr = lEnclosed;
12319   }
12320 
12321   QName* constQName = v.get_qname_expr().dyn_cast<QName>();
12322 
12323   if (constQName != NULL)
12324   {
12325     store::Item_t qnameItem;
12326     expand_elem_qname(qnameItem, constQName, loc);
12327 
12328     nameExpr = theExprManager->create_const_expr(theRootSctx, loc, qnameItem);
12329   }
12330   else
12331   {
12332     nameExpr = pop_nodestack();
12333 
12334     expr* atomExpr = wrap_in_atomization(nameExpr);
12335     nameExpr = theExprManager->create_name_cast_expr(theRootSctx,
12336                                                      loc,
12337                                                      atomExpr,
12338                                                      theNSCtx,
12339                                                      false);
12340   }
12341 
12342   bool copyNodes = (theCCB->theConfig.opt_level < CompilerCB::config::O1 ||
12343                     !Properties::instance()->noCopyOptim());
12344 
12345   push_nodestack(theExprManager->create_elem_expr(theRootSctx,
12346                                                   loc,
12347                                                   nameExpr,
12348                                                   contentExpr,
12349                                                   theNSCtx,
12350                                                   copyNodes));
12351 }
12352 
12353 
begin_visit(const CompAttrConstructor & v)12354 void* begin_visit(const CompAttrConstructor& v)
12355 {
12356   TRACE_VISIT();
12357   return no_state;
12358 }
12359 
end_visit(const CompAttrConstructor & v,void *)12360 void end_visit(const CompAttrConstructor& v, void* /*visit_state*/)
12361 {
12362   TRACE_VISIT_OUT();
12363 
12364   expr* nameExpr = NULL;
12365   expr* valueExpr = NULL;
12366   expr* attrExpr = NULL;
12367 
12368   if (v.get_val_expr() != 0)
12369   {
12370     valueExpr = pop_nodestack();
12371 
12372     valueExpr = wrap_in_enclosed_expr(valueExpr, loc);
12373   }
12374 
12375   QName* constQName = v.get_qname_expr().dyn_cast<QName>();
12376 
12377   if (constQName != NULL)
12378   {
12379     store::Item_t qnameItem;
12380     expand_no_default_qname(qnameItem, constQName, constQName->get_location());
12381 
12382     nameExpr = theExprManager->create_const_expr(theRootSctx, loc, qnameItem);
12383   }
12384   else
12385   {
12386     nameExpr = pop_nodestack();
12387     expr* atomExpr = wrap_in_atomization(nameExpr);
12388     nameExpr = theExprManager->create_name_cast_expr(theRootSctx,
12389                                                      loc,
12390                                                      atomExpr,
12391                                                      theNSCtx,
12392                                                      true);
12393   }
12394 
12395   attrExpr = theExprManager->create_attr_expr(theRootSctx, loc, nameExpr, valueExpr);
12396 
12397   push_nodestack(attrExpr);
12398 }
12399 
12400 
begin_visit(const CompCommentConstructor & v)12401 void* begin_visit(const CompCommentConstructor& v)
12402 {
12403   TRACE_VISIT();
12404   return no_state;
12405 }
12406 
end_visit(const CompCommentConstructor & v,void *)12407 void end_visit(const CompCommentConstructor& v, void* /*visit_state*/)
12408 {
12409   TRACE_VISIT_OUT();
12410 
12411   expr* inputExpr = pop_nodestack();
12412 
12413   fo_expr* enclosedExpr = wrap_in_enclosed_expr(inputExpr, loc);
12414 
12415   expr* textExpr = theExprManager->create_text_expr(theRootSctx, loc,
12416                                                      text_expr::comment_constructor,
12417                                                      enclosedExpr);
12418 
12419   push_nodestack(textExpr);
12420 }
12421 
12422 
begin_visit(const CompPIConstructor & v)12423 void* begin_visit(const CompPIConstructor& v)
12424 {
12425   TRACE_VISIT();
12426   return no_state;
12427 }
12428 
end_visit(const CompPIConstructor & v,void *)12429 void end_visit(const CompPIConstructor& v, void* /*visit_state*/)
12430 {
12431   TRACE_VISIT_OUT();
12432 
12433   expr* target = NULL;
12434   expr* content = NULL;
12435 
12436   if (v.get_content_expr() == NULL)
12437   {
12438     content = create_empty_seq(loc);
12439   }
12440   else
12441   {
12442     content = pop_nodestack();
12443 
12444     content = wrap_in_enclosed_expr(content, loc);
12445   }
12446 
12447   if (v.get_target_expr() != NULL)
12448   {
12449     target = pop_nodestack();
12450 
12451     expr* castExpr = create_cast_expr(loc, target, theRTM.NCNAME_TYPE_ONE, true);
12452 
12453     target = wrap_in_enclosed_expr(castExpr, loc);
12454   }
12455 
12456   expr* e = (v.get_target_expr () != NULL ?
12457               theExprManager->create_pi_expr(theRootSctx, loc, target, content) :
12458               theExprManager->create_pi_expr(theRootSctx, loc, theExprManager->create_const_expr(theRootSctx, loc, v.get_target().str()), content));
12459 
12460   push_nodestack (e);
12461 }
12462 
12463 
begin_visit(const CompTextConstructor & v)12464 void* begin_visit(const CompTextConstructor& v)
12465 {
12466   TRACE_VISIT();
12467   return no_state;
12468 }
12469 
end_visit(const CompTextConstructor & v,void *)12470 void end_visit(const CompTextConstructor& v, void* /*visit_state*/)
12471 {
12472   TRACE_VISIT_OUT();
12473 
12474   expr* inputExpr = pop_nodestack();
12475 
12476   fo_expr* enclosedExpr = wrap_in_enclosed_expr(inputExpr, loc);
12477 
12478   expr* textExpr = theExprManager->create_text_expr(theRootSctx,
12479                                                      loc,
12480                                                      text_expr::text_constructor,
12481                                                      enclosedExpr);
12482 
12483   push_nodestack(textExpr);
12484 }
12485 
12486 
12487 /*******************************************************************************
12488 
12489 ********************************************************************************/
12490 
begin_visit(const SingleType & v)12491 void* begin_visit(const SingleType& v)
12492 {
12493   TRACE_VISIT();
12494   return no_state;
12495 }
12496 
end_visit(const SingleType & v,void *)12497 void end_visit(const SingleType& v, void* /*visit_state*/)
12498 {
12499   TRACE_VISIT_OUT();
12500   if (v.get_hook_bit())
12501     theTypeStack.push(CTX_TM->create_type(*pop_tstack(), TypeConstants::QUANT_QUESTION));
12502   // else leave type as it is on tstack
12503 }
12504 
12505 
begin_visit(const TypeName & v)12506 void* begin_visit(const TypeName& v)
12507 {
12508   TRACE_VISIT();
12509   return no_state;
12510 }
12511 
end_visit(const TypeName & v,void *)12512 void end_visit(const TypeName& v, void* /*visit_state*/)
12513 {
12514   TRACE_VISIT_OUT();
12515 }
12516 
12517 
12518 /////////////////////////////////////////////////////////////////////////////////
12519 //                                                                             //
12520 //  Sequence Type Matching                                                     //
12521 //                                                                             //
12522 /////////////////////////////////////////////////////////////////////////////////
12523 
12524 
12525 /*******************************************************************************
12526 
12527   A SequenceType parsenode has 2 children: The right child is always an
12528   OccurrenceIndicator node. The left child may be either an AtomicType node,
12529   or one of the 9 kind-test nodes (elementTest, documentTest, ... etc), or
12530   an ItemType node. ItemType respesents the expression item().
12531 
12532 ********************************************************************************/
12533 
begin_visit(const SequenceType & v)12534 void* begin_visit(const SequenceType& v)
12535 {
12536   TRACE_VISIT();
12537 
12538   if (v.get_itemtype() == NULL && v.get_occur() == NULL)
12539   {
12540     theTypeStack.push(GENV_TYPESYSTEM.EMPTY_TYPE);
12541     return NULL;
12542   }
12543 
12544   return no_state;
12545 }
12546 
end_visit(const SequenceType & v,void *)12547 void end_visit(const SequenceType& v, void* /*visit_state*/)
12548 {
12549   TRACE_VISIT_OUT();
12550 }
12551 
12552 
begin_visit(const OccurrenceIndicator & v)12553 void* begin_visit(const OccurrenceIndicator& v)
12554 {
12555   TRACE_VISIT();
12556 
12557   TypeConstants::quantifier_t q = TypeConstants::QUANT_STAR;
12558   switch(v.get_type())
12559   {
12560   case ParseConstants::occurs_exactly_one:
12561     q = TypeConstants::QUANT_ONE; break;
12562   case ParseConstants::occurs_one_or_more:
12563     q = TypeConstants::QUANT_PLUS; break;
12564   case ParseConstants::occurs_optionally:
12565     q = TypeConstants::QUANT_QUESTION; break;
12566   case ParseConstants::occurs_zero_or_more:
12567     q = TypeConstants::QUANT_STAR; break;
12568   case ParseConstants::occurs_never:
12569     ZORBA_ASSERT(false);
12570   }
12571 
12572   if (q != TypeConstants::QUANT_ONE)
12573     theTypeStack.push(CTX_TM->create_type(*pop_tstack(), q));
12574 
12575   return no_state;
12576 }
12577 
end_visit(const OccurrenceIndicator & v,void *)12578 void end_visit(const OccurrenceIndicator& v, void* /*visit_state*/)
12579 {
12580   TRACE_VISIT_OUT();
12581 }
12582 
12583 
begin_visit(const AtomicType & v)12584 void* begin_visit(const AtomicType& v)
12585 {
12586   TRACE_VISIT();
12587   return no_state;
12588 }
12589 
end_visit(const AtomicType & v,void *)12590 void end_visit(const AtomicType& v, void* /*visit_state*/)
12591 {
12592   TRACE_VISIT_OUT();
12593 
12594   rchandle<QName> qname = v.get_qname();
12595   store::Item_t qnameItem;
12596   expand_elem_qname(qnameItem, qname, loc);
12597 
12598   xqtref_t t = CTX_TM->create_named_atomic_type(qnameItem,
12599                                                 TypeConstants::QUANT_ONE,
12600                                                 loc);
12601 
12602   // some types that should never be parsed, like xs:untyped, are;
12603   // we catch them with is_simple()
12604   if (t == NULL)
12605   {
12606     RAISE_ERROR(err::XPST0051, loc, ERROR_PARAMS(qname->get_qname()));
12607   }
12608   else
12609   {
12610     theTypeStack.push (t);
12611   }
12612 }
12613 
12614 
begin_visit(const ItemType & v)12615 void* begin_visit(const ItemType& v)
12616 {
12617   TRACE_VISIT();
12618   return no_state;
12619 }
12620 
end_visit(const ItemType & v,void *)12621 void end_visit(const ItemType& v, void* /*visit_state*/)
12622 {
12623   TRACE_VISIT_OUT();
12624   theTypeStack.push(GENV_TYPESYSTEM.ITEM_TYPE_ONE);
12625 }
12626 
12627 
begin_visit(const StructuredItemType & v)12628 void* begin_visit(const StructuredItemType& v)
12629 {
12630   TRACE_VISIT();
12631 #ifndef ZORBA_WITH_JSON
12632   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
12633 #endif
12634   return no_state;
12635 }
12636 
end_visit(const StructuredItemType & v,void *)12637 void end_visit(const StructuredItemType& v, void* /*visit_state*/)
12638 {
12639   TRACE_VISIT_OUT();
12640 #ifdef ZORBA_WITH_JSON
12641   theTypeStack.push(GENV_TYPESYSTEM.STRUCTURED_ITEM_TYPE_ONE);
12642 #endif
12643 }
12644 
12645 
12646 /*******************************************************************************
12647 
12648   JSONTest
12649 
12650   JSONTest ::= JSONItemTest | JSONObjectTest | JSONArrayTest
12651 
12652   JSONItemTest ::= "json-item" "(" ")"
12653   JSONObjectTest ::= "object" "(" ")"
12654   JSONArrayTest ::= "array" "(" ")"
12655 
12656 ********************************************************************************/
12657 
begin_visit(const JSON_Test & v)12658 void* begin_visit(const JSON_Test& v)
12659 {
12660   TRACE_VISIT();
12661 #ifndef ZORBA_WITH_JSON
12662   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
12663 #endif
12664   return no_state;
12665 }
12666 
end_visit(const JSON_Test & v,void *)12667 void end_visit(const JSON_Test& v, void* /*visit_state*/)
12668 {
12669   TRACE_VISIT_OUT();
12670 #ifdef ZORBA_WITH_JSON
12671   RootTypeManager& rtm = GENV_TYPESYSTEM;
12672 
12673   switch (v.get_kind())
12674   {
12675   case store::StoreConsts::jsonObject:
12676   {
12677     theTypeStack.push(rtm.JSON_OBJECT_TYPE_ONE);
12678     break;
12679   }
12680   case store::StoreConsts::jsonArray:
12681   {
12682     theTypeStack.push(rtm.JSON_ARRAY_TYPE_ONE);
12683 
12684     break;
12685   }
12686   case store::StoreConsts::jsonItem:
12687   {
12688     theTypeStack.push(rtm.JSON_ITEM_TYPE_ONE);
12689     break;
12690   }
12691   default:
12692     ZORBA_ASSERT(false);
12693   }
12694 #endif /* ZORBA_WITH_JSON */
12695 }
12696 
12697 
12698 /*******************************************************************************
12699 
12700    KindTest
12701 
12702 ********************************************************************************/
12703 
12704 
begin_visit(const QName & v)12705 void* begin_visit(const QName& v)
12706 {
12707   TRACE_VISIT();
12708   return no_state;
12709 }
12710 
12711 
end_visit(const QName & v,void *)12712 void end_visit(const QName& v, void* /*visit_state*/)
12713 {
12714   TRACE_VISIT_OUT();
12715 }
12716 
12717 
begin_visit(const AnyKindTest & v)12718 void* begin_visit(const AnyKindTest& v)
12719 {
12720   TRACE_VISIT();
12721   // no action needed here
12722   return no_state;
12723 }
12724 
12725 
end_visit(const AnyKindTest & v,void *)12726 void end_visit(const AnyKindTest& v, void* /*visit_state*/)
12727 {
12728   TRACE_VISIT_OUT();
12729 
12730   // if the top of the stack is an axis step expr, add a node test expr to it.
12731   axis_step_expr* axisExpr =
12732     dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
12733   if (axisExpr != NULL)
12734   {
12735     match_expr* me = theExprManager->create_match_expr(theRootSctx, loc);
12736     me->setTestKind(match_anykind_test);
12737     axisExpr->setTest(me);
12738   }
12739   else
12740   {
12741     theTypeStack.push(GENV_TYPESYSTEM.ANY_NODE_TYPE_ONE);
12742   }
12743 }
12744 
12745 
12746 /*******************************************************************************
12747 
12748   DocumentTest ::= "document-node" "(" (ElementTest | SchemaElementTest)? ")"
12749 
12750 ********************************************************************************/
begin_visit(const DocumentTest & v)12751 void* begin_visit(const DocumentTest& v)
12752 {
12753   TRACE_VISIT();
12754   return no_state;
12755 }
12756 
12757 
end_visit(const DocumentTest & v,void *)12758 void end_visit(const DocumentTest& v, void* /*visit_state*/)
12759 {
12760   TRACE_VISIT_OUT();
12761 
12762   ElementTest* elemTest = v.get_elem_test();
12763   SchemaElementTest* schemaTest = v.get_schema_elem_test();
12764   axis_step_expr* axisExpr =
12765     dynamic_cast<axis_step_expr*>(peek_nodestk_or_null());
12766   match_expr* match = NULL;
12767 
12768   if (elemTest == NULL && schemaTest == NULL)
12769   {
12770     if (axisExpr != NULL)
12771     {
12772       match = theExprManager->create_match_expr(theRootSctx, loc);
12773       match->setTestKind(match_doc_test);
12774 
12775       axisExpr->setTest(match);
12776     }
12777     else
12778     {
12779       theTypeStack.push(GENV_TYPESYSTEM.DOCUMENT_TYPE_ONE);
12780     }
12781   }
12782   else if (axisExpr != NULL)
12783   {
12784     match = axisExpr->getTest();
12785     match->setDocTestKind(match->getTestKind());
12786     match->setTestKind(match_doc_test);
12787   }
12788   else
12789   {
12790     xqtref_t elementOrSchemaTest = pop_tstack();
12791 
12792     xqtref_t docTest = CTX_TM->create_node_type(store::StoreConsts::documentNode,
12793                                                 NULL,
12794                                                 elementOrSchemaTest,
12795                                                 TypeConstants::QUANT_ONE,
12796                                                 false,
12797                                                 false);
12798     theTypeStack.push(docTest);
12799   }
12800 }
12801 
12802 
12803 /*******************************************************************************
12804 
12805 	ElementTest ::= "element" "("
12806                      (ElementNameOrWildcard ("," TypeName "?"?)?)?
12807                   ")"
12808 
12809   ElementNameOrWildcard ::= ElementName | "*"
12810 
12811 ********************************************************************************/
begin_visit(const ElementTest & v)12812 void* begin_visit(const ElementTest& v)
12813 {
12814   TRACE_VISIT();
12815   return no_state;
12816 }
12817 
12818 
end_visit(const ElementTest & v,void *)12819 void end_visit(const ElementTest& v, void* /*visit_state*/)
12820 {
12821   TRACE_VISIT_OUT ();
12822 
12823   bool nillable =  v.isNilledAllowed();
12824   rchandle<QName> elemName = v.getElementName();
12825   rchandle<TypeName> typeName = v.getTypeName();
12826   store::Item_t elemNameItem;
12827   store::Item_t typeNameItem;
12828 
12829   if (elemName != NULL)
12830     expand_elem_qname(elemNameItem, elemName, loc);
12831 
12832   if (typeName != NULL)
12833     expand_elem_qname(typeNameItem, typeName->get_name(), loc);
12834 
12835   // if the top of the stack is an axis step expr, add a node test expr to it.
12836   axis_step_expr* axisExpr =
12837     dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
12838 
12839   xqtref_t contentType;
12840 
12841   if (typeName != NULL)
12842   {
12843     contentType = CTX_TM->create_named_type(typeNameItem,
12844                                             TypeConstants::QUANT_ONE,
12845                                             loc);
12846 
12847     if (contentType == NULL)
12848     {
12849       RAISE_ERROR(err::XPST0008, loc,
12850       ERROR_PARAMS(typeNameItem->getStringValue(), ZED(ElementName)));
12851     }
12852   }
12853 
12854   if (axisExpr != NULL)
12855   {
12856     match_expr* me = theExprManager->create_match_expr(theRootSctx, loc);
12857     me->setTestKind(match_elem_test);
12858     me->setQName(elemNameItem);
12859     me->setTypeName(typeNameItem);
12860     me->setNilledAllowed(nillable);
12861 
12862     axisExpr->setTest(me);
12863   }
12864 
12865   // Else, create a sequence-type match
12866   else
12867   {
12868     xqtref_t seqmatch = CTX_TM->create_node_type(store::StoreConsts::elementNode,
12869                                                  elemNameItem,
12870                                                  contentType,
12871                                                  TypeConstants::QUANT_ONE,
12872                                                  nillable,
12873                                                  false);
12874     theTypeStack.push(seqmatch);
12875   }
12876 }
12877 
12878 
12879 /*******************************************************************************
12880 
12881   SchemaElementTest ::= "schema-element" "(" ElementDeclaration ")"
12882 
12883   ElementDeclaration ::= ElementName
12884 
12885 ********************************************************************************/
begin_visit(const SchemaElementTest & v)12886 void* begin_visit(const SchemaElementTest& v)
12887 {
12888   TRACE_VISIT();
12889 
12890 #ifndef ZORBA_NO_XMLSCHEMA
12891   axis_step_expr* axisExpr =
12892     dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
12893   rchandle<QName> elemName = v.get_elem();
12894   ZORBA_ASSERT(elemName != NULL);
12895 
12896   store::Item_t elemQNameItem;
12897   expand_elem_qname(elemQNameItem, elemName, loc);
12898 
12899   if (axisExpr != NULL)
12900   {
12901     store::Item_t typeQNameItem;
12902     CTX_TM->get_schema_element_typename(elemQNameItem, typeQNameItem, loc);
12903 
12904     match_expr* match = theExprManager->create_match_expr(theRootSctx, loc);
12905     match->setTestKind(match_xs_elem_test);
12906     match->setQName(elemQNameItem);
12907     match->setTypeName(typeQNameItem);
12908 
12909     axisExpr->setTest(match);
12910   }
12911   else
12912   {
12913     xqtref_t seqmatch = CTX_TM->create_schema_element_type(elemQNameItem,
12914                                                            TypeConstants::QUANT_ONE,
12915                                                            loc);
12916     theTypeStack.push(seqmatch);
12917   }
12918 #else /* ZORBA_NO_XMLSCHEMA */
12919   RAISE_ERROR(zerr::ZXQP0005_NOT_ENABLED, loc,
12920   ERROR_PARAMS(ZED(XMLSchema)));
12921 #endif /* ZORBA_NO_XMLSCHEMA */
12922   return no_state;
12923 }
12924 
12925 
end_visit(const SchemaElementTest & v,void *)12926 void end_visit(const SchemaElementTest& v, void* /*visit_state*/)
12927 {
12928   TRACE_VISIT_OUT();
12929 }
12930 
12931 
begin_visit(const AttributeTest & v)12932 void* begin_visit(const AttributeTest& v)
12933 {
12934   TRACE_VISIT();
12935   return no_state;
12936 }
12937 
12938 
end_visit(const AttributeTest & v,void *)12939 void end_visit(const AttributeTest& v, void* /*visit_state*/)
12940 {
12941   TRACE_VISIT_OUT();
12942 
12943   rchandle<QName> attrName = v.get_attr_name();
12944   rchandle<TypeName> typeName = v.get_type_name();
12945 
12946   store::Item_t attrNameItem;
12947   store::Item_t typeNameItem;
12948   xqtref_t contentType;
12949 
12950   if (attrName != NULL)
12951   {
12952     expand_no_default_qname(attrNameItem, attrName,  attrName->get_location());
12953   }
12954 
12955   if (typeName != NULL)
12956   {
12957     expand_elem_qname(typeNameItem, typeName->get_name(), typeName->get_location());
12958 
12959     contentType = CTX_TM->create_named_type(typeNameItem,
12960                                             TypeConstants::QUANT_ONE,
12961                                             loc);
12962 
12963     if (contentType == NULL)
12964     {
12965       throw XQUERY_EXCEPTION(
12966         err::XPST0008,
12967         ERROR_PARAMS( typeNameItem->getStringValue(), ZED( AttributeName ) ),
12968         ERROR_LOC( loc )
12969       );
12970     }
12971   }
12972 
12973   // if the top of the stack is an axis step expr, add a node test expr to it.
12974   axis_step_expr* axisExpr =
12975     dynamic_cast<axis_step_expr*> (peek_nodestk_or_null());
12976   if (axisExpr != NULL)
12977   {
12978     match_expr* match = theExprManager->create_match_expr(theRootSctx, loc);
12979     match->setTestKind(match_attr_test);
12980 
12981     if (attrName != NULL)
12982       match->setQName(attrNameItem);
12983 
12984     if (typeName != NULL)
12985       match->setTypeName(typeNameItem);
12986 
12987     axisExpr->setTest(match);
12988   }
12989   else
12990   {
12991     xqtref_t seqmatch = CTX_TM->create_node_type(store::StoreConsts::attributeNode,
12992                                                  attrNameItem,
12993                                                  contentType,
12994                                                  TypeConstants::QUANT_ONE,
12995                                                  false,
12996                                                  false);
12997 
12998     theTypeStack.push(seqmatch);
12999   }
13000 }
13001 
13002 
begin_visit(const SchemaAttributeTest & v)13003 void* begin_visit(const SchemaAttributeTest& v)
13004 {
13005   TRACE_VISIT();
13006 
13007 #ifndef ZORBA_NO_XMLSCHEMA
13008   axis_step_expr* axisExpr =
13009     dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
13010   rchandle<QName> attrName = v.get_attr();
13011   ZORBA_ASSERT(attrName != NULL);
13012 
13013   store::Item_t attrQNameItem;
13014   expand_no_default_qname(attrQNameItem, attrName, attrName->get_location());
13015 
13016   if (axisExpr != NULL)
13017   {
13018     store::Item_t typeQNameItem;
13019     CTX_TM->get_schema_attribute_typename(attrQNameItem, typeQNameItem, loc);
13020 
13021     match_expr* match = theExprManager->create_match_expr(theRootSctx, loc);
13022     match->setTestKind(match_xs_attr_test);
13023     match->setQName(attrQNameItem);
13024     match->setTypeName(typeQNameItem);
13025 
13026     axisExpr->setTest(match);
13027   }
13028   else
13029   {
13030     xqtref_t seqmatch = CTX_TM->create_schema_attribute_type(attrQNameItem,
13031                                                              TypeConstants::QUANT_ONE,
13032                                                              loc);
13033 
13034     theTypeStack.push(seqmatch);
13035   }
13036 
13037 #else /* ZORBA_NO_XMLSCHEMA */
13038   throw XQUERY_EXCEPTION(
13039     zerr::ZXQP0005_NOT_ENABLED,
13040     ERROR_PARAMS( ZED( XMLSchema ) ),
13041     ERROR_LOC( loc )
13042   );
13043 #endif /* ZORBA_NO_XMLSCHEMA */
13044   return no_state;
13045 }
13046 
13047 
end_visit(const SchemaAttributeTest & v,void *)13048 void end_visit(const SchemaAttributeTest& v, void* /*visit_state*/)
13049 {
13050   TRACE_VISIT_OUT();
13051 }
13052 
13053 
begin_visit(const TextTest & v)13054 void* begin_visit(const TextTest& v)
13055 {
13056   TRACE_VISIT();
13057   // no action needed here
13058   return no_state;
13059 }
13060 
13061 
end_visit(const TextTest & v,void *)13062 void end_visit(const TextTest& v, void* /*visit_state*/)
13063 {
13064   TRACE_VISIT_OUT();
13065 
13066   axis_step_expr* axisExpr =
13067     dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
13068   if (axisExpr != NULL)
13069   {
13070     match_expr* match = theExprManager->create_match_expr(theRootSctx, loc);
13071     match->setTestKind(match_text_test);
13072     axisExpr->setTest(match);
13073   }
13074   else
13075   {
13076     theTypeStack.push(GENV_TYPESYSTEM.TEXT_TYPE_ONE);
13077   }
13078 }
13079 
13080 
begin_visit(const CommentTest & v)13081 void* begin_visit(const CommentTest& v)
13082 {
13083   TRACE_VISIT();
13084   // no action needed here
13085   return no_state;
13086 }
13087 
13088 
end_visit(const CommentTest & v,void *)13089 void end_visit(const CommentTest& v, void* /*visit_state*/)
13090 {
13091   TRACE_VISIT_OUT();
13092 
13093   axis_step_expr* axisExpr =
13094     dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
13095   if (axisExpr != NULL)
13096   {
13097     match_expr* match = theExprManager->create_match_expr(theRootSctx, loc);
13098     match->setTestKind(match_comment_test);
13099     axisExpr->setTest(match);
13100   }
13101   else
13102   {
13103     theTypeStack.push(GENV_TYPESYSTEM.COMMENT_TYPE_ONE);
13104   }
13105 }
13106 
13107 
begin_visit(const PITest & v)13108 void* begin_visit(const PITest& v)
13109 {
13110   TRACE_VISIT();
13111   return no_state;
13112 }
13113 
13114 
end_visit(const PITest & v,void *)13115 void end_visit(const PITest& v, void* /*visit_state*/)
13116 {
13117   TRACE_VISIT_OUT();
13118 
13119   axis_step_expr* axisExpr =
13120     dynamic_cast<axis_step_expr*> (peek_nodestk_or_null ());
13121   std::string target = v.get_target().str();
13122 
13123   store::Item_t qname = NULL;
13124   if (target != "")
13125   {
13126     // bugfix for XQuery 1.1 (fixes test K2-NameTest-22)
13127     // see W3C bug http://www.w3.org/Bugs/Public/show_bug.cgi?id=6559
13128     // processing-instruction( N ) matches any processing-instruction node
13129     // whose PITarget is equal to fn:normalize-space(N). If fn:normalize-space(N)
13130     // is not in the lexical space of NCName, a type error is raised [err:XPTY0004]
13131 
13132     zstring lNormalizedTarget;
13133     ascii::normalize_whitespace( target, &lNormalizedTarget );
13134 
13135     if (!GenericCast::instance()->castableToNCName(lNormalizedTarget))
13136     {
13137       throw XQUERY_EXCEPTION(err::XPTY0004,
13138         ERROR_PARAMS(ZED(BadType_23o), lNormalizedTarget,
13139           ZED( NoCastTo_45o ), "NCName"
13140         ),
13141         ERROR_LOC( loc )
13142       );
13143     }
13144 
13145     // bugfix (see above); pass normalized string instead of original target
13146     GENV_ITEMFACTORY->createQName(qname, NULL, NULL, lNormalizedTarget.c_str());
13147   }
13148 
13149   if (axisExpr != NULL)
13150   {
13151     match_expr* match = theExprManager->create_match_expr(theRootSctx, loc);
13152     match->setTestKind(match_pi_test);
13153     if (target != "")
13154       match->setQName(qname);
13155     axisExpr->setTest(match);
13156   }
13157   else
13158   {
13159     if (target == "")
13160     {
13161       theTypeStack.push(GENV_TYPESYSTEM.PI_TYPE_ONE);
13162     }
13163     else
13164     {
13165       xqtref_t t = GENV_TYPESYSTEM.create_node_type(store::StoreConsts::piNode,
13166                                                     qname,
13167                                                     NULL,
13168                                                     TypeConstants::QUANT_ONE,
13169                                                     false,
13170                                                     false);
13171       theTypeStack.push (t);
13172     }
13173   }
13174 }
13175 
13176 
begin_visit(const AnyFunctionTest & v)13177 void* begin_visit(const AnyFunctionTest& v)
13178 {
13179   TRACE_VISIT();
13180   //Nothing to do here
13181   return no_state;
13182 }
13183 
end_visit(const AnyFunctionTest & v,void *)13184 void end_visit(const AnyFunctionTest& v, void* /*visit_state*/)
13185 {
13186   TRACE_VISIT_OUT();
13187   theTypeStack.push(GENV_TYPESYSTEM.ANY_FUNCTION_TYPE_STAR);
13188 }
13189 
begin_visit(const TypeList & v)13190 void* begin_visit(const TypeList& v)
13191 {
13192   TRACE_VISIT ();
13193   return no_state;
13194 }
13195 
end_visit(const TypeList & v,void *)13196 void end_visit(const TypeList& v, void* /*visit_state*/)
13197 {
13198   TRACE_VISIT_OUT();
13199 }
13200 
begin_visit(const TypedFunctionTest & v)13201 void* begin_visit(const TypedFunctionTest& v)
13202 {
13203   TRACE_VISIT();
13204   return no_state;
13205 }
13206 
end_visit(const TypedFunctionTest & v,void *)13207 void end_visit(const TypedFunctionTest& v, void* /*visit_state*/)
13208 {
13209   TRACE_VISIT_OUT ();
13210   const rchandle<TypeList>& lParamTypes = v.getArgumentTypes();
13211   const rchandle<SequenceType>& lRetType = v.getReturnType();
13212 
13213   std::vector<xqtref_t> lParamXQTypes;
13214   xqtref_t              lRetXQType;
13215 
13216   if (lParamTypes)
13217   {
13218     for (int i = 0; i < (int)lParamTypes->size(); ++i)
13219     {
13220       const SequenceType* lParamType = (*lParamTypes)[i];
13221 
13222       if (lParamType == 0)
13223       {
13224         lParamXQTypes.push_back(GENV_TYPESYSTEM.ITEM_TYPE_STAR);
13225       }
13226       else
13227       {
13228         lParamType->accept(*this);
13229         lParamXQTypes.push_back(pop_tstack());
13230       }
13231     }
13232   }
13233 
13234   if (lRetType != 0)
13235   {
13236     lRetType->accept(*this);
13237     lRetXQType = pop_tstack();
13238   }
13239 
13240   TypeConstants::quantifier_t lQuant = TypeConstants::QUANT_STAR;
13241   theTypeStack.push (GENV_TYPESYSTEM.create_function_type(
13242     lParamXQTypes, lRetXQType, lQuant));
13243 }
13244 
13245 
13246 ////////////////////////////////////////////////////////////////////////////////
13247 //                                                                            //
13248 //  Update Expressions                                                        //
13249 //                                                                            //
13250 ////////////////////////////////////////////////////////////////////////////////
13251 
13252 
13253 
13254 /*******************************************************************************
13255   JSONObjectInsertExpr ::=
13256   "insert" "json" "{" PairConstructor ("," PairConstructor)* "}"
13257 ********************************************************************************/
begin_visit(const JSONObjectInsertExpr & v)13258 void* begin_visit(const JSONObjectInsertExpr& v)
13259 {
13260   TRACE_VISIT();
13261 #ifndef ZORBA_WITH_JSON
13262   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
13263 #endif
13264   return no_state;
13265 }
13266 
13267 
end_visit(const JSONObjectInsertExpr & v,void *)13268 void end_visit(const JSONObjectInsertExpr& v, void* /*visit_state*/)
13269 {
13270   TRACE_VISIT_OUT();
13271 
13272 #ifdef ZORBA_WITH_JSON
13273   RootTypeManager& rtm = GENV_TYPESYSTEM;
13274 
13275   expr* targetExpr = pop_nodestack();
13276   expr* contentExpr = pop_nodestack();
13277 
13278   targetExpr = wrap_in_type_match(targetExpr,
13279                                   rtm.JSON_OBJECT_TYPE_ONE,
13280                                   loc,
13281                                   TreatIterator::JSONIQ_OBJECT_UPDATE_TARGET, // JNUP0008
13282                                   NULL);
13283 
13284   contentExpr = wrap_in_type_match(contentExpr,
13285                                   rtm.JSON_OBJECT_TYPE_STAR,
13286                                   loc,
13287                                   TreatIterator::JSONIQ_OBJECT_UPDATE_CONTENT, // JNUP0019
13288                                   NULL);
13289 
13290   std::vector<expr*> args(2);
13291   args[0] = targetExpr;
13292   args[1] = theExprManager->create_json_object_expr(
13293       theRootSctx,
13294       loc,
13295       contentExpr,
13296       false);
13297 
13298   expr* updExpr = theExprManager->
13299   create_fo_expr(theRootSctx,
13300                  loc,
13301                  GET_BUILTIN_FUNCTION(OP_ZORBA_JSON_OBJECT_INSERT_2),
13302                  args);
13303 
13304   push_nodestack(updExpr);
13305 #endif
13306 }
13307 
13308 
13309 /*******************************************************************************
13310   JSONArrayInsertExpr ::=
13311   "insert" "json" "[" ExprSingle "]" "into" ExprSingle "at" "position" ExprSingle
13312 ********************************************************************************/
begin_visit(const JSONArrayInsertExpr & v)13313 void* begin_visit(const JSONArrayInsertExpr& v)
13314 {
13315   TRACE_VISIT();
13316 #ifndef ZORBA_WITH_JSON
13317   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
13318 #endif
13319   return no_state;
13320 }
13321 
13322 
end_visit(const JSONArrayInsertExpr & v,void *)13323 void end_visit(const JSONArrayInsertExpr& v, void* /*visit_state*/)
13324 {
13325   TRACE_VISIT_OUT();
13326 
13327 #ifdef ZORBA_WITH_JSON
13328   RootTypeManager& rtm = GENV_TYPESYSTEM;
13329 
13330   expr* posExpr = pop_nodestack();
13331   expr* targetExpr = pop_nodestack();
13332   expr* sourceExpr = pop_nodestack();
13333 
13334   posExpr = wrap_in_type_promotion(posExpr,
13335                                    rtm.INTEGER_TYPE_ONE,
13336                                    PromoteIterator::JSONIQ_ARRAY_SELECTOR); // JNUP0007
13337 
13338   targetExpr = wrap_in_type_match(targetExpr,
13339                                   rtm.JSON_ARRAY_TYPE_ONE,
13340                                   loc,
13341                                   TreatIterator::JSONIQ_ARRAY_UPDATE_TARGET, // JNUP0008
13342                                   NULL);
13343 
13344   std::vector<expr*> args(3);
13345   args[0] = targetExpr;
13346   args[1] = posExpr;
13347   args[2] = sourceExpr;
13348 
13349   fo_expr* updExpr = theExprManager->
13350   create_fo_expr(theRootSctx,
13351                  loc,
13352                  GET_BUILTIN_FUNCTION(OP_ZORBA_JSON_ARRAY_INSERT_3),
13353                  args);
13354 
13355   normalize_fo(updExpr);
13356 
13357   push_nodestack(updExpr);
13358 #endif
13359 }
13360 
13361 
13362 /*******************************************************************************
13363 
13364 ********************************************************************************/
begin_visit(const JSONArrayAppendExpr & v)13365 void* begin_visit(const JSONArrayAppendExpr& v)
13366 {
13367   TRACE_VISIT();
13368 #ifndef ZORBA_WITH_JSON
13369   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
13370 #endif
13371   return no_state;
13372 }
13373 
13374 
end_visit(const JSONArrayAppendExpr & v,void *)13375 void end_visit(const JSONArrayAppendExpr& v, void* /*visit_state*/)
13376 {
13377   TRACE_VISIT_OUT();
13378 
13379 #ifdef ZORBA_WITH_JSON
13380   expr* targetExpr = pop_nodestack();
13381   expr* contentExpr = pop_nodestack();
13382 
13383   targetExpr = wrap_in_type_match(targetExpr,
13384                                   theRTM.JSON_ARRAY_TYPE_ONE,
13385                                   loc,
13386                                   TreatIterator::JSONIQ_ARRAY_UPDATE_TARGET, // JNUP0008
13387                                   NULL);
13388 
13389   fo_expr* updExpr = theExprManager->
13390   create_fo_expr(theRootSctx,
13391                  loc,
13392                  GET_BUILTIN_FUNCTION(OP_ZORBA_JSON_ARRAY_APPEND_2),
13393                  targetExpr,
13394                  contentExpr);
13395 
13396   normalize_fo(updExpr);
13397 
13398   push_nodestack(updExpr);
13399 #endif
13400 }
13401 
13402 
13403 /*******************************************************************************
13404   JSONDeleteExpr ::= "delete" "json" FilterExpr
13405 
13406   The parser makes sure that the FileterExpr is actually a dynamic  function
13407   invocation, i.e., :
13408 
13409   FilterExpr := PrimaryExpr ("(" ArgList ")")+
13410 
13411   The parser also makes sure that each ArgList contains exactly one arg.
13412 
13413   If there are N ArgLists, the last one is considered to be the selector expr
13414   and the PrimaryExpr together with the N-1 ArgLists constitute the target expr.
13415 ********************************************************************************/
begin_visit(const JSONDeleteExpr & v)13416 void* begin_visit(const JSONDeleteExpr& v)
13417 {
13418   TRACE_VISIT();
13419 #ifndef ZORBA_WITH_JSON
13420   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
13421 #endif
13422   return no_state;
13423 }
13424 
13425 
end_visit(const JSONDeleteExpr & v,void *)13426 void end_visit(const JSONDeleteExpr& v, void* /*visit_state*/)
13427 {
13428   TRACE_VISIT_OUT();
13429 
13430 #ifdef ZORBA_WITH_JSON
13431   expr* selExpr = pop_nodestack();
13432   expr* targetExpr = pop_nodestack();
13433 
13434   selExpr = wrap_in_type_promotion(selExpr,
13435                                    theRTM.ANY_ATOMIC_TYPE_ONE,
13436                                    PromoteIterator::JSONIQ_SELECTOR, // JNUP0007
13437                                    NULL);
13438 
13439   targetExpr = wrap_in_type_match(targetExpr,
13440                                   theRTM.JSON_ITEM_TYPE_ONE,
13441                                   loc,
13442                                   TreatIterator::JSONIQ_UPDATE_TARGET, // JNUP0008
13443                                   NULL);
13444 
13445   fo_expr* updExpr = theExprManager->
13446   create_fo_expr(theRootSctx,
13447                  loc,
13448                  GET_BUILTIN_FUNCTION(OP_ZORBA_JSON_DELETE_2),
13449                  targetExpr,
13450                  selExpr);
13451 
13452   push_nodestack(updExpr);
13453 #endif
13454 }
13455 
13456 
13457 /*******************************************************************************
13458   JSONReplaceExpr ::= "replace" "json" "value" "of" FilterExpr "with" ExprSingle
13459 ********************************************************************************/
begin_visit(const JSONReplaceExpr & v)13460 void* begin_visit(const JSONReplaceExpr& v)
13461 {
13462   TRACE_VISIT();
13463 #ifndef ZORBA_WITH_JSON
13464   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
13465 #endif
13466   return no_state;
13467 }
13468 
13469 
end_visit(const JSONReplaceExpr & v,void *)13470 void end_visit(const JSONReplaceExpr& v, void* /*visit_state*/)
13471 {
13472   TRACE_VISIT_OUT();
13473 
13474 #ifdef ZORBA_WITH_JSON
13475   expr* valueExpr = pop_nodestack();
13476   expr* selExpr = pop_nodestack();
13477   expr* targetExpr = pop_nodestack();
13478 
13479   std::vector<expr*> args(3);
13480 
13481   args[0] = wrap_in_type_match(targetExpr,
13482                                theRTM.JSON_ITEM_TYPE_ONE,
13483                                loc,
13484                                TreatIterator::JSONIQ_UPDATE_TARGET, // JNUP0008
13485                                NULL);
13486 
13487   args[1] = wrap_in_type_promotion(selExpr,
13488                                    theRTM.ANY_ATOMIC_TYPE_ONE,
13489                                    PromoteIterator::JSONIQ_SELECTOR, // JNUP0007
13490                                    NULL);
13491 
13492   args[2] = theExprManager->create_fo_expr(theRootSctx,
13493                                            valueExpr->get_loc(),
13494                                            GET_BUILTIN_FUNCTION(OP_ZORBA_JSON_BOX_1),
13495                                            valueExpr);
13496 
13497   fo_expr* updExpr = theExprManager->
13498   create_fo_expr(theRootSctx,
13499                  loc,
13500                  GET_BUILTIN_FUNCTION(OP_ZORBA_JSON_REPLACE_VALUE_3),
13501                  args);
13502 
13503   push_nodestack(updExpr);
13504 #endif
13505 }
13506 
13507 
13508 /*******************************************************************************
13509   JSONRenameExpr ::= "rename" "json" FilterExpr "as" ExprSingle
13510 ********************************************************************************/
begin_visit(const JSONRenameExpr & v)13511 void* begin_visit(const JSONRenameExpr& v)
13512 {
13513   TRACE_VISIT();
13514 #ifndef ZORBA_WITH_JSON
13515   RAISE_ERROR_NO_PARAMS(err::XPST0003, loc);
13516 #endif
13517   return no_state;
13518 }
13519 
13520 
end_visit(const JSONRenameExpr & v,void *)13521 void end_visit(const JSONRenameExpr& v, void* /*visit_state*/)
13522 {
13523   TRACE_VISIT_OUT();
13524 
13525 #ifdef ZORBA_WITH_JSON
13526   expr* newNameExpr = pop_nodestack();
13527   expr* nameExpr = pop_nodestack();
13528   expr* targetExpr = pop_nodestack();
13529 
13530   std::vector<expr*> args(3);
13531 
13532   args[0] = wrap_in_type_match(targetExpr,
13533                                theRTM.JSON_OBJECT_TYPE_ONE,
13534                                loc,
13535                                TreatIterator::JSONIQ_OBJECT_UPDATE_TARGET, // JNUP0008
13536                                NULL);
13537 
13538   args[1] = wrap_in_type_promotion(nameExpr,
13539                                    theRTM.STRING_TYPE_ONE,
13540                                    PromoteIterator::JSONIQ_OBJECT_SELECTOR); // JNUP0007
13541 
13542   args[2] = wrap_in_type_promotion(newNameExpr,
13543                                    theRTM.STRING_TYPE_ONE,
13544                                    PromoteIterator::JSONIQ_OBJECT_SELECTOR); // JNUP0007
13545 
13546   fo_expr* updExpr = theExprManager->
13547   create_fo_expr(theRootSctx,
13548                  loc,
13549                  GET_BUILTIN_FUNCTION(OP_ZORBA_JSON_RENAME_3),
13550                  args);
13551 
13552   push_nodestack(updExpr);
13553 #endif
13554 }
13555 
13556 
13557 /*******************************************************************************
13558 
13559 ********************************************************************************/
begin_visit(const DeleteExpr & v)13560 void* begin_visit(const DeleteExpr& v)
13561 {
13562   TRACE_VISIT ();
13563   return no_state;
13564 }
13565 
end_visit(const DeleteExpr & v,void *)13566 void end_visit(const DeleteExpr& v, void* /*visit_state*/)
13567 {
13568   TRACE_VISIT_OUT();
13569 
13570   expr* lTarget = pop_nodestack();
13571 
13572   expr* aDelete = theExprManager->create_delete_expr(theRootSctx, loc, lTarget);
13573   push_nodestack(aDelete);
13574 }
13575 
13576 
begin_visit(const InsertExpr & v)13577 void* begin_visit(const InsertExpr& v)
13578 {
13579   TRACE_VISIT();
13580   return no_state;
13581 }
13582 
end_visit(const InsertExpr & v,void *)13583 void end_visit(const InsertExpr& v, void* /*visit_state*/)
13584 {
13585   TRACE_VISIT_OUT();
13586   expr* lTarget = pop_nodestack();
13587   expr* lSource = pop_nodestack();
13588 
13589   lSource = wrap_in_enclosed_expr(lSource, loc);
13590 
13591   expr* lInsert = theExprManager->
13592   create_insert_expr(theRootSctx, loc, v.getType(), lSource, lTarget);
13593 
13594   push_nodestack(lInsert);
13595 }
13596 
13597 
begin_visit(const RenameExpr & v)13598 void* begin_visit(const RenameExpr& v)
13599 {
13600   TRACE_VISIT();
13601   return no_state;
13602 }
13603 
end_visit(const RenameExpr & v,void *)13604 void end_visit(const RenameExpr& v, void* /*visit_state*/)
13605 {
13606   TRACE_VISIT_OUT();
13607 
13608   expr* nameExpr = pop_nodestack();
13609   expr* targetExpr = pop_nodestack();
13610 
13611   nameExpr = wrap_in_atomization(nameExpr);
13612 
13613   // We use a name_cast_expr here for static typing reasons. However, during codegen,
13614   // we are not going to generate a NameCastIterator, because we don't always know at
13615   // compile time whether the target will an element or an attribute node.
13616   nameExpr = theExprManager->
13617   create_name_cast_expr(theRootSctx, loc, nameExpr, theNSCtx, false);
13618 
13619   expr* renameExpr = theExprManager->
13620   create_rename_expr(theRootSctx, loc, targetExpr, nameExpr);
13621 
13622   push_nodestack(renameExpr);
13623 }
13624 
13625 
begin_visit(const ReplaceExpr & v)13626 void* begin_visit (const ReplaceExpr& v)
13627 {
13628   TRACE_VISIT();
13629   return no_state;
13630 }
13631 
end_visit(const ReplaceExpr & v,void *)13632 void end_visit(const ReplaceExpr& v, void* /*visit_state*/)
13633 {
13634   TRACE_VISIT_OUT();
13635 
13636   expr* lReplacement = pop_nodestack();
13637   expr* lTarget = pop_nodestack();
13638 
13639   if (v.getType() == store::UpdateConsts::NODE)
13640   {
13641     lReplacement = wrap_in_enclosed_expr(lReplacement, loc);
13642   }
13643 
13644   expr* lReplace = theExprManager->
13645   create_replace_expr(theRootSctx, loc, v.getType(), lTarget, lReplacement);
13646 
13647   push_nodestack(lReplace);
13648 }
13649 
13650 
begin_visit(const TransformExpr & v)13651 void* begin_visit(const TransformExpr& v)
13652 {
13653   TRACE_VISIT();
13654 
13655   transform_expr* transformExpr =
13656   theExprManager->create_transform_expr(theRootSctx, loc);
13657 
13658   push_nodestack(transformExpr);
13659 
13660   return no_state;
13661 }
13662 
end_visit(const TransformExpr & v,void *)13663 void end_visit(const TransformExpr& v, void* /*visit_state*/)
13664 {
13665   TRACE_VISIT_OUT();
13666 
13667   expr* returnExpr = pop_nodestack();
13668   expr* modifyExpr = pop_nodestack();
13669 
13670   transform_expr* transformExpr =
13671   dynamic_cast<transform_expr*>(theNodeStack.top());
13672   assert(transformExpr != NULL);
13673 
13674   transformExpr->setModifyExpr(modifyExpr);
13675   transformExpr->setReturnExpr(returnExpr);
13676 
13677   const csize lSize = v.get_var_list()->size();
13678   for (csize i = 0; i < lSize; ++i)
13679   {
13680     pop_scope();
13681   }
13682 }
13683 
13684 
begin_visit(const CopyVarList & v)13685 void* begin_visit(const CopyVarList& v)
13686 {
13687   TRACE_VISIT();
13688   return no_state;
13689 }
13690 
end_visit(const CopyVarList & v,void *)13691 void end_visit(const CopyVarList& v, void* /*visit_state*/)
13692 {
13693   TRACE_VISIT_OUT();
13694 }
13695 
13696 
begin_visit(const VarBinding & v)13697 void* begin_visit(const VarBinding& v)
13698 {
13699   TRACE_VISIT();
13700 
13701   return no_state;
13702 }
13703 
end_visit(const VarBinding & v,void *)13704 void end_visit(const VarBinding& v, void*)
13705 {
13706   TRACE_VISIT_OUT();
13707 
13708   expr* sourceExpr = pop_nodestack();
13709 
13710   if (sourceExpr->is_updating())
13711     throw XQUERY_EXCEPTION(err::XUST0001, ERROR_LOC(loc));
13712 
13713   push_scope();
13714 
13715   var_expr* varExpr = bind_var(loc, v.get_varname(), var_expr::copy_var);
13716 
13717   transform_expr* transformExpr =
13718   dynamic_cast<transform_expr*>(theNodeStack.top());
13719   assert(transformExpr != NULL);
13720 
13721   copy_clause* copyClause = theExprManager->create_copy_clause(varExpr, sourceExpr);
13722 
13723   transformExpr->add_back(copyClause);
13724 }
13725 
13726 
13727 
13728 ////////////////////////////////////////////////////////////////////////////////
13729 //                                                                            //
13730 //  Full-Text                                                                 //
13731 //                                                                            //
13732 ////////////////////////////////////////////////////////////////////////////////
13733 
13734 
13735 #ifndef ZORBA_NO_FULL_TEXT
flatten(ftnode * n)13736 template<typename FTNodeType> bool flatten( ftnode *n )
13737 {
13738   if ( FTNodeType *const n2 = dynamic_cast<FTNodeType*>( n ) )
13739   {
13740     typename FTNodeType::ftnode_list_t &list = n2->get_node_list();
13741     typename FTNodeType::ftnode_list_t::iterator i = list.begin();
13742     while ( i != list.end() )
13743     {
13744       push_ftstack( *i );
13745       i = list.erase( i );
13746     }
13747     delete n;
13748     return true;
13749   }
13750   return false;
13751 }
13752 #endif /* ZORBA_NO_FULL_TEXT */
13753 
begin_visit(const FTAnd & v)13754 void* begin_visit (const FTAnd& v)
13755 {
13756   TRACE_VISIT ();
13757 #ifndef ZORBA_NO_FULL_TEXT
13758   push_ftstack( nullptr ); // sentinel
13759 #endif /* ZORBA_NO_FULL_TEXT */
13760   return no_state;
13761 }
13762 
end_visit(const FTAnd & v,void *)13763 void end_visit (const FTAnd& v, void* /*visit_state*/)
13764 {
13765   TRACE_VISIT_OUT ();
13766 #ifndef ZORBA_NO_FULL_TEXT
13767   ftand::ftnode_list_t list;
13768   while ( true )
13769   {
13770     ftnode *const n = pop_ftstack();
13771     if ( !n )
13772       break;
13773     if ( !flatten<ftand>( n ) )
13774     {
13775       //
13776       // We must use push_front() to maintain the original left-to-right order
13777       // of the query.
13778       //
13779       list.push_front( n );
13780     }
13781   }
13782   push_ftstack( new ftand( loc, list ) );
13783 #endif /* ZORBA_NO_FULL_TEXT */
13784 }
13785 
13786 
begin_visit(const FTAnyallOption & v)13787 void *begin_visit (const FTAnyallOption& v)
13788 {
13789   TRACE_VISIT ();
13790   // nothing to do
13791   return no_state;
13792 }
13793 
13794 
end_visit(const FTAnyallOption & v,void *)13795 void end_visit (const FTAnyallOption& v, void* /*visit_state*/)
13796 {
13797   TRACE_VISIT_OUT ();
13798   // nothing to do
13799 }
13800 
13801 
begin_visit(const FTBigUnit & v)13802 void *begin_visit (const FTBigUnit& v)
13803 {
13804   TRACE_VISIT ();
13805   // nothing to do
13806   return no_state;
13807 }
13808 
13809 
end_visit(const FTBigUnit & v,void *)13810 void end_visit (const FTBigUnit& v, void* /*visit_state*/)
13811 {
13812   TRACE_VISIT_OUT ();
13813   // nothing to do
13814 }
13815 
begin_visit(const FTCaseOption & v)13816 void *begin_visit (const FTCaseOption& v)
13817 {
13818   TRACE_VISIT ();
13819   // nothing to do
13820   return no_state;
13821 }
13822 
13823 
end_visit(const FTCaseOption & v,void *)13824 void end_visit (const FTCaseOption& v, void* /*visit_state*/)
13825 {
13826   TRACE_VISIT_OUT ();
13827 #ifndef ZORBA_NO_FULL_TEXT
13828   ftmatch_options *const mo = dynamic_cast<ftmatch_options*>( top_ftstack() );
13829   ZORBA_ASSERT( mo );
13830   if ( mo->get_case_option() )
13831     throw XQUERY_EXCEPTION(
13832       err::FTST0019, ERROR_PARAMS( "case" ), ERROR_LOC( loc )
13833     );
13834   mo->set_case_option( new ftcase_option( loc, v.get_mode() ) );
13835 #endif /* ZORBA_NO_FULL_TEXT */
13836 }
13837 
13838 
begin_visit(const FTContainsExpr & v)13839 void *begin_visit (const FTContainsExpr& v)
13840 {
13841   TRACE_VISIT ();
13842 #ifdef ZORBA_NO_FULL_TEXT
13843   throw XQUERY_EXCEPTION(
13844     err::XPST0003, ERROR_PARAMS( ZED( FullTextNotEnabled ) ), ERROR_LOC( loc )
13845   );
13846 #endif /* ZORBA_NO_FULL_TEXT */
13847   return no_state;
13848 }
13849 
end_visit(const FTContainsExpr & v,void *)13850 void end_visit (const FTContainsExpr& v, void* /*visit_state*/)
13851 {
13852   TRACE_VISIT_OUT ();
13853 #ifndef ZORBA_NO_FULL_TEXT
13854   expr* ftignore = NULL;
13855   if ( v.get_ignore() )
13856     ftignore = pop_nodestack();
13857 
13858   ftselection *const selection = dynamic_cast<ftselection*>( pop_ftstack() );
13859   ZORBA_ASSERT( selection );
13860 
13861   expr* range = pop_nodestack();
13862   ZORBA_ASSERT( range );
13863 
13864   ftcontains_expr *const e =
13865     theExprManager->create_ftcontains_expr( theRootSctx, loc, range, selection, ftignore );
13866   push_nodestack( e );
13867 #endif /* ZORBA_NO_FULL_TEXT */
13868 }
13869 
begin_visit(const FTContent & v)13870 void *begin_visit (const FTContent& v) {
13871   TRACE_VISIT ();
13872   // nothing to do
13873   return no_state;
13874 }
13875 
end_visit(const FTContent & v,void *)13876 void end_visit (const FTContent& v, void* /*visit_state*/) {
13877   TRACE_VISIT_OUT ();
13878 #ifndef ZORBA_NO_FULL_TEXT
13879   push_ftstack( new ftcontent_filter( loc, v.get_mode() ) );
13880 #endif /* ZORBA_NO_FULL_TEXT */
13881 }
13882 
begin_visit(const FTDiacriticsOption & v)13883 void *begin_visit (const FTDiacriticsOption& v) {
13884   TRACE_VISIT ();
13885   // nothing to do
13886   return no_state;
13887 }
13888 
end_visit(const FTDiacriticsOption & v,void *)13889 void end_visit (const FTDiacriticsOption& v, void* /*visit_state*/) {
13890   TRACE_VISIT_OUT ();
13891 #ifndef ZORBA_NO_FULL_TEXT
13892   ftmatch_options *const mo = dynamic_cast<ftmatch_options*>( top_ftstack() );
13893   ZORBA_ASSERT( mo );
13894   if ( mo->get_diacritics_option() )
13895     throw XQUERY_EXCEPTION(
13896       err::FTST0019, ERROR_PARAMS( "diacriticics" ), ERROR_LOC( loc )
13897     );
13898   mo->set_diacritics_option( new ftdiacritics_option( loc, v.get_mode() ) );
13899 #endif /* ZORBA_NO_FULL_TEXT */
13900 }
13901 
begin_visit(const FTDistance & v)13902 void *begin_visit (const FTDistance& v) {
13903   TRACE_VISIT ();
13904   // nothing to do
13905   return no_state;
13906 }
13907 
end_visit(const FTDistance & v,void *)13908 void end_visit (const FTDistance& v, void* /*visit_state*/) {
13909   TRACE_VISIT_OUT ();
13910 #ifndef ZORBA_NO_FULL_TEXT
13911   ftdistance_filter *const df = new ftdistance_filter(
13912     loc, dynamic_cast<ftrange*>( pop_ftstack() ), v.get_unit()->get_unit()
13913   );
13914   push_ftstack( df );
13915 #endif /* ZORBA_NO_FULL_TEXT */
13916 }
13917 
begin_visit(const FTExtensionOption & v)13918 void *begin_visit (const FTExtensionOption& v) {
13919   TRACE_VISIT ();
13920   // nothing to do
13921   return no_state;
13922 }
13923 
end_visit(const FTExtensionOption & v,void *)13924 void end_visit (const FTExtensionOption& v, void* /*visit_state*/) {
13925   TRACE_VISIT_OUT ();
13926 #ifndef ZORBA_NO_FULL_TEXT
13927   rchandle<QName> const &qname = v.get_qname();
13928   zstring ns;
13929   theSctx->lookup_ns( ns, qname->get_prefix(), loc );
13930 
13931   ftmatch_options *const mo = dynamic_cast<ftmatch_options*>( top_ftstack() );
13932   ZORBA_ASSERT( mo );
13933   mo->add_extension_option( new ftextension_option( loc, qname, v.get_val() ) );
13934 #endif /* ZORBA_NO_FULL_TEXT */
13935 }
13936 
begin_visit(const FTExtensionSelection & v)13937 void *begin_visit (const FTExtensionSelection& v) {
13938   TRACE_VISIT ();
13939   // TODO
13940   return no_state;
13941 }
13942 
end_visit(const FTExtensionSelection & v,void *)13943 void end_visit (const FTExtensionSelection& v, void* /*visit_state*/) {
13944   TRACE_VISIT_OUT ();
13945 #ifndef ZORBA_NO_FULL_TEXT
13946   ftselection *const s = dynamic_cast<ftselection*>( top_ftstack() );
13947   if ( s )
13948     pop_ftstack();
13949   else
13950     throw XQUERY_EXCEPTION( err::XQST0079, ERROR_LOC( loc ) );
13951   push_ftstack( new ftextension_selection( loc, v.get_pragma_list(), s ) );
13952 #endif /* ZORBA_NO_FULL_TEXT */
13953 }
13954 
begin_visit(const FTIgnoreOption & v)13955 void *begin_visit (const FTIgnoreOption& v) {
13956   TRACE_VISIT ();
13957   // nothing to do
13958   return no_state;
13959 }
13960 
end_visit(const FTIgnoreOption & v,void *)13961 void end_visit (const FTIgnoreOption& v, void* /*visit_state*/) {
13962   TRACE_VISIT_OUT ();
13963 #ifndef ZORBA_NO_FULL_TEXT
13964   expr* e( pop_nodestack() );
13965   push_nodestack( wrap_in_type_match(e,
13966                                      theRTM.ANY_NODE_TYPE_STAR,
13967                                      e->get_loc(),
13968                                      TreatIterator::TYPE_MATCH));
13969 #endif /* ZORBA_NO_FULL_TEXT */
13970 }
13971 
begin_visit(const FTLanguageOption & v)13972 void *begin_visit (const FTLanguageOption& v) {
13973   TRACE_VISIT ();
13974   // nothing to do
13975   return no_state;
13976 }
13977 
end_visit(const FTLanguageOption & v,void *)13978 void end_visit (const FTLanguageOption& v, void* /*visit_state*/) {
13979   TRACE_VISIT_OUT ();
13980 #ifndef ZORBA_NO_FULL_TEXT
13981   ftmatch_options *const mo = dynamic_cast<ftmatch_options*>( top_ftstack() );
13982   ZORBA_ASSERT( mo );
13983   if ( mo->get_language_option() )
13984     throw XQUERY_EXCEPTION(
13985       err::FTST0019, ERROR_PARAMS( "language" ), ERROR_LOC( loc )
13986     );
13987   mo->set_language_option( new ftlanguage_option( loc, v.get_language() ) );
13988 #endif /* ZORBA_NO_FULL_TEXT */
13989 }
13990 
begin_visit(const FTMatchOptions & v)13991 void *begin_visit (const FTMatchOptions& v) {
13992   TRACE_VISIT ();
13993 #ifndef ZORBA_NO_FULL_TEXT
13994   push_ftstack( new ftmatch_options( loc ) );
13995 #endif /* ZORBA_NO_FULL_TEXT */
13996   return no_state;
13997 }
13998 
end_visit(const FTMatchOptions & v,void *)13999 void end_visit (const FTMatchOptions& v, void* /*visit_state*/) {
14000   TRACE_VISIT_OUT ();
14001   // nothing to do
14002 }
14003 
begin_visit(const FTMildNot & v)14004 void *begin_visit (const FTMildNot& v) {
14005   TRACE_VISIT ();
14006 #ifndef ZORBA_NO_FULL_TEXT
14007   push_ftstack( nullptr ); // sentinel
14008 #endif /* ZORBA_NO_FULL_TEXT */
14009   return no_state;
14010 }
14011 
end_visit(const FTMildNot & v,void *)14012 void end_visit (const FTMildNot& v, void* /*visit_state*/) {
14013   TRACE_VISIT_OUT ();
14014 #ifndef ZORBA_NO_FULL_TEXT
14015   ftmild_not::ftnode_list_t list;
14016   while ( true ) {
14017     ftnode *const n = pop_ftstack();
14018     if ( !n )
14019       break;
14020     if ( !flatten<ftmild_not>( n ) ) {
14021       //
14022       // We must use push_front() to maintain the original left-to-right order
14023       // of the query.
14024       //
14025       list.push_front( n );
14026     }
14027   }
14028   push_ftstack( new ftmild_not( loc, list ) );
14029 #endif /* ZORBA_NO_FULL_TEXT */
14030 }
14031 
begin_visit(const FTOptionDecl & v)14032 void *begin_visit (const FTOptionDecl& v) {
14033   TRACE_VISIT ();
14034   // nothing to do
14035   return no_state;
14036 }
14037 
end_visit(const FTOptionDecl & v,void *)14038 void end_visit (const FTOptionDecl& v, void* /*visit_state*/) {
14039   TRACE_VISIT_OUT ();
14040 #ifndef ZORBA_NO_FULL_TEXT
14041   ftmatch_options *const mo = dynamic_cast<ftmatch_options*>( pop_ftstack() );
14042   ZORBA_ASSERT( mo );
14043   theSctx->set_match_options( mo );
14044 #endif /* ZORBA_NO_FULL_TEXT */
14045 }
14046 
begin_visit(const FTOr & v)14047 void *begin_visit (const FTOr& v) {
14048   TRACE_VISIT ();
14049 #ifndef ZORBA_NO_FULL_TEXT
14050   push_ftstack( nullptr ); // sentinel
14051 #endif /* ZORBA_NO_FULL_TEXT */
14052   return no_state;
14053 }
14054 
end_visit(const FTOr & v,void *)14055 void end_visit (const FTOr& v, void* /*visit_state*/) {
14056   TRACE_VISIT_OUT ();
14057 #ifndef ZORBA_NO_FULL_TEXT
14058   ftor::ftnode_list_t list;
14059   while ( true ) {
14060     ftnode *const n = pop_ftstack();
14061     if ( !n )
14062       break;
14063     if ( !flatten<ftor>( n ) ) {
14064       //
14065       // We must use push_front() to maintain the original left-to-right order
14066       // of the query.
14067       //
14068       list.push_front( n );
14069     }
14070   }
14071   push_ftstack( new ftor( loc, list ) );
14072 #endif /* ZORBA_NO_FULL_TEXT */
14073 }
14074 
begin_visit(const FTOrder & v)14075 void *begin_visit (const FTOrder& v) {
14076   TRACE_VISIT ();
14077   // nothing to do
14078   return no_state;
14079 }
14080 
end_visit(const FTOrder & v,void *)14081 void end_visit (const FTOrder& v, void* /*visit_state*/) {
14082   TRACE_VISIT_OUT ();
14083 #ifndef ZORBA_NO_FULL_TEXT
14084   push_ftstack( new ftorder_filter( loc ) );
14085 #endif /* ZORBA_NO_FULL_TEXT */
14086 }
14087 
begin_visit(const FTPrimaryWithOptions & v)14088 void *begin_visit (const FTPrimaryWithOptions& v) {
14089   TRACE_VISIT ();
14090 #ifndef ZORBA_NO_FULL_TEXT
14091   push_ftstack( new ftprimary_with_options( loc ) );
14092 #endif /* ZORBA_NO_FULL_TEXT */
14093   return no_state;
14094 }
14095 
end_visit(const FTPrimaryWithOptions & v,void *)14096 void end_visit (const FTPrimaryWithOptions& v, void* /*visit_state*/) {
14097   TRACE_VISIT_OUT ();
14098 #ifndef ZORBA_NO_FULL_TEXT
14099   ftweight *const w = dynamic_cast<ftweight*>( top_ftstack() );
14100   if ( w )
14101     pop_ftstack();
14102 
14103   ftmatch_options *const mo = dynamic_cast<ftmatch_options*>( top_ftstack() );
14104   if ( mo )
14105     pop_ftstack();
14106 
14107   ftprimary *const p = dynamic_cast<ftprimary*>( pop_ftstack() );
14108   ZORBA_ASSERT( p );
14109 
14110   ftprimary_with_options *const pwo =
14111     dynamic_cast<ftprimary_with_options*>( top_ftstack() );
14112   ZORBA_ASSERT( pwo );
14113 
14114   pwo->set_primary( p );
14115   if ( mo )
14116     pwo->set_match_options( mo );
14117   if ( w )
14118     pwo->set_weight( w );
14119 #endif /* ZORBA_NO_FULL_TEXT */
14120 }
14121 
begin_visit(const FTRange & v)14122 void *begin_visit (const FTRange& v) {
14123   TRACE_VISIT ();
14124 #ifndef ZORBA_NO_FULL_TEXT
14125   push_nodestack( NULL ); // sentinel
14126 #endif /* ZORBA_NO_FULL_TEXT */
14127   return no_state;
14128 }
14129 
end_visit(const FTRange & v,void *)14130 void end_visit (const FTRange& v, void* /*visit_state*/) {
14131   TRACE_VISIT_OUT ();
14132 #ifndef ZORBA_NO_FULL_TEXT
14133   expr* e2 = pop_nodestack();
14134   expr* e1 = pop_nodestack();
14135   if ( e1 )
14136     pop_nodestack(); // pop the sentinel
14137   else {
14138     e1 = e2;
14139     e2 = NULL;
14140   }
14141 
14142   if ( e1 ) {
14143     e1 = wrap_in_type_promotion(e1,
14144                                 theRTM.INTEGER_TYPE_ONE,
14145                                 PromoteIterator::TYPE_PROMOTION);
14146   }
14147   if ( e2 ) {
14148     e2 = wrap_in_type_promotion(e2,
14149                                 theRTM.INTEGER_TYPE_ONE,
14150                                 PromoteIterator::TYPE_PROMOTION);
14151   }
14152 
14153   ftrange *const r = new ftrange( loc, v.get_mode(), e1, e2 );
14154   push_ftstack( r );
14155 #endif /* ZORBA_NO_FULL_TEXT */
14156 }
14157 
begin_visit(const FTScope & v)14158 void *begin_visit (const FTScope& v) {
14159   TRACE_VISIT ();
14160   // nothing to do
14161   return no_state;
14162 }
14163 
end_visit(const FTScope & v,void *)14164 void end_visit (const FTScope& v, void* /*visit_state*/) {
14165   TRACE_VISIT_OUT ();
14166 #ifndef ZORBA_NO_FULL_TEXT
14167   ftscope_filter *const sf =
14168     new ftscope_filter( loc, v.get_scope(), v.get_big_unit()->get_unit() );
14169   push_ftstack( sf );
14170 #endif /* ZORBA_NO_FULL_TEXT */
14171 }
14172 
begin_visit(const FTScoreVar & v)14173 void *begin_visit (const FTScoreVar& v) {
14174   TRACE_VISIT ();
14175   throw XQUERY_EXCEPTION(
14176     zerr::ZXQP0004_NOT_IMPLEMENTED, ERROR_PARAMS( "score" ), ERROR_LOC( loc )
14177   );
14178 }
14179 
end_visit(const FTScoreVar & v,void *)14180 void end_visit (const FTScoreVar& v, void* /*visit_state*/) {
14181   TRACE_VISIT_OUT ();
14182   // TODO
14183 }
14184 
begin_visit(const FTSelection & v)14185 void *begin_visit (const FTSelection& v) {
14186   TRACE_VISIT ();
14187   // nothing to do
14188   return no_state;
14189 }
14190 
end_visit(const FTSelection & v,void *)14191 void end_visit (const FTSelection& v, void* /*visit_state*/) {
14192   TRACE_VISIT_OUT ();
14193 #ifndef ZORBA_NO_FULL_TEXT
14194   ftselection::ftpos_filter_list_t list;
14195   while ( true ) {
14196     ftnode *const n = pop_ftstack();
14197     if ( ftpos_filter *const pf = dynamic_cast<ftpos_filter*>( n ) ) {
14198       //
14199       // We must use push_front() to maintain the original left-to-right order
14200       // of the query.
14201       //
14202       list.push_front( pf );
14203     } else {
14204       push_ftstack( new ftselection( loc, n, list ) );
14205       break;
14206     }
14207   }
14208 #endif /* ZORBA_NO_FULL_TEXT */
14209 }
14210 
begin_visit(const FTStemOption & v)14211 void *begin_visit (const FTStemOption& v) {
14212   TRACE_VISIT ();
14213   // nothing to do
14214   return no_state;
14215 }
14216 
end_visit(const FTStemOption & v,void *)14217 void end_visit (const FTStemOption& v, void* /*visit_state*/) {
14218   TRACE_VISIT_OUT ();
14219 #ifndef ZORBA_NO_FULL_TEXT
14220   ftmatch_options *const mo = dynamic_cast<ftmatch_options*>( top_ftstack() );
14221   ZORBA_ASSERT( mo );
14222   if ( mo->get_stem_option() )
14223     throw XQUERY_EXCEPTION(
14224       err::FTST0019, ERROR_PARAMS( "stem" ), ERROR_LOC( loc )
14225     );
14226   mo->set_stem_option( new ftstem_option( loc, v.get_mode() ) );
14227 #endif /* ZORBA_NO_FULL_TEXT */
14228 }
14229 
begin_visit(const FTStopWords & v)14230 void *begin_visit (const FTStopWords& v) {
14231   TRACE_VISIT ();
14232   // nothing to do
14233   return no_state;
14234 }
14235 
end_visit(const FTStopWords & v,void *)14236 void end_visit (const FTStopWords& v, void* /*visit_state*/) {
14237   TRACE_VISIT_OUT ();
14238 #ifndef ZORBA_NO_FULL_TEXT
14239   ftstop_words *const sw = new ftstop_words(
14240     loc, v.get_uri(), v.get_stop_words()
14241   );
14242   push_ftstack( sw );
14243 #endif /* ZORBA_NO_FULL_TEXT */
14244 }
14245 
begin_visit(const FTStopWordsInclExcl & v)14246 void *begin_visit (const FTStopWordsInclExcl& v) {
14247   TRACE_VISIT ();
14248   // nothing to do
14249   return no_state;
14250 }
14251 
end_visit(const FTStopWordsInclExcl & v,void *)14252 void end_visit (const FTStopWordsInclExcl& v, void* /*visit_state*/) {
14253   TRACE_VISIT_OUT ();
14254 #ifndef ZORBA_NO_FULL_TEXT
14255   ftstop_words *const sw = dynamic_cast<ftstop_words*>( top_ftstack() );
14256   ZORBA_ASSERT( sw );
14257   sw->set_mode( v.get_mode() );
14258 #endif /* ZORBA_NO_FULL_TEXT */
14259 }
14260 
begin_visit(const FTStopWordOption & v)14261 void *begin_visit (const FTStopWordOption& v) {
14262   TRACE_VISIT ();
14263   // nothing to do
14264   return no_state;
14265 }
14266 
end_visit(const FTStopWordOption & v,void *)14267 void end_visit (const FTStopWordOption& v, void* /*visit_state*/) {
14268   TRACE_VISIT_OUT ();
14269 #ifndef ZORBA_NO_FULL_TEXT
14270   if ( v.get_mode() == ft_stop_words_mode::without )
14271     return;
14272   ftstop_word_option::list_t stop_words;
14273   while ( true ) {
14274     ftnode *const n = top_ftstack();
14275     if ( ftstop_words *const sw = dynamic_cast<ftstop_words*>( n ) ) {
14276       //
14277       // We must use push_front() to maintain the original left-to-right order
14278       // of the query.
14279       //
14280       stop_words.push_front( sw );
14281       pop_ftstack();
14282     } else
14283       break;
14284   }
14285   ftmatch_options *const mo = dynamic_cast<ftmatch_options*>( top_ftstack() );
14286   ZORBA_ASSERT( mo );
14287   if ( mo->get_stop_word_option() )
14288     throw XQUERY_EXCEPTION(
14289       err::FTST0019, ERROR_PARAMS( "stop words" ), ERROR_LOC( loc )
14290     );
14291   ftstop_word_option *const sw =
14292     new ftstop_word_option( loc, stop_words, v.get_mode() );
14293   mo->set_stop_word_option( sw );
14294 #endif /* ZORBA_NO_FULL_TEXT */
14295 }
14296 
begin_visit(const FTThesaurusID & v)14297 void *begin_visit (const FTThesaurusID& v) {
14298   TRACE_VISIT ();
14299   // nothing to do
14300   return no_state;
14301 }
14302 
end_visit(const FTThesaurusID & v,void *)14303 void end_visit (const FTThesaurusID& v, void* /*visit_state*/) {
14304   TRACE_VISIT_OUT ();
14305 #ifndef ZORBA_NO_FULL_TEXT
14306   zstring const &uri = v.get_uri();
14307   zstring error_msg;
14308   std::auto_ptr<internal::Resource> rsrc(
14309     theSctx->resolve_uri( uri, internal::EntityData::THESAURUS, error_msg )
14310   );
14311   if ( !rsrc.get() )
14312     throw XQUERY_EXCEPTION(
14313       err::FTST0018, ERROR_PARAMS( uri ), ERROR_LOC( loc )
14314     );
14315 
14316   ftrange *levels;
14317   if ( v.get_levels() ) {
14318     levels = dynamic_cast<ftrange*>( pop_ftstack() );
14319     ZORBA_ASSERT( levels );
14320   } else
14321     levels = nullptr;
14322 
14323   ftthesaurus_id *const tid =
14324     new ftthesaurus_id( loc, uri, v.get_relationship(), levels );
14325   push_ftstack( tid );
14326 #endif /* ZORBA_NO_FULL_TEXT */
14327 }
14328 
begin_visit(const FTThesaurusOption & v)14329 void *begin_visit (const FTThesaurusOption& v) {
14330   TRACE_VISIT ();
14331 #ifndef ZORBA_NO_FULL_TEXT
14332   push_ftstack( nullptr ); // sentinel
14333 #endif /* ZORBA_NO_FULL_TEXT */
14334   return no_state;
14335 }
14336 
end_visit(const FTThesaurusOption & v,void *)14337 void end_visit (const FTThesaurusOption& v, void* /*visit_state*/) {
14338   TRACE_VISIT_OUT ();
14339 #ifndef ZORBA_NO_FULL_TEXT
14340   ftthesaurus_id *const default_tid = v.includes_default() ?
14341     new ftthesaurus_id( loc, "##default" ) : nullptr;
14342 
14343   ftthesaurus_option::thesaurus_id_list_t list;
14344   while ( true ) {
14345     ftthesaurus_id *const tid = dynamic_cast<ftthesaurus_id*>( pop_ftstack() );
14346     if ( tid )
14347       list.push_back( tid );
14348     else
14349       break;
14350   }
14351   ftmatch_options *const mo = dynamic_cast<ftmatch_options*>( top_ftstack() );
14352   ZORBA_ASSERT( mo );
14353   if ( mo->get_thesaurus_option() )
14354     throw XQUERY_EXCEPTION(
14355       err::FTST0019, ERROR_PARAMS( "thesaurus" ), ERROR_LOC( loc )
14356     );
14357   ftthesaurus_option *const t =
14358     new ftthesaurus_option( loc, default_tid, list, v.no_thesaurus() );
14359   mo->set_thesaurus_option( t );
14360 #endif /* ZORBA_NO_FULL_TEXT */
14361 }
14362 
begin_visit(const FTTimes & v)14363 void *begin_visit (const FTTimes& v) {
14364   TRACE_VISIT ();
14365   // nothing to do
14366   return no_state;
14367 }
14368 
end_visit(const FTTimes & v,void *)14369 void end_visit (const FTTimes& v, void* /*visit_state*/) {
14370   TRACE_VISIT_OUT ();
14371   // nothing to do
14372 }
14373 
begin_visit(const FTUnaryNot & v)14374 void *begin_visit (const FTUnaryNot& v) {
14375   TRACE_VISIT ();
14376   // nothing to do
14377   return no_state;
14378 }
14379 
end_visit(const FTUnaryNot & v,void *)14380 void end_visit (const FTUnaryNot& v, void* /*visit_state*/) {
14381   TRACE_VISIT_OUT ();
14382 #ifndef ZORBA_NO_FULL_TEXT
14383   push_ftstack( new ftunary_not( loc, pop_ftstack() ) );
14384 #endif /* ZORBA_NO_FULL_TEXT */
14385 }
14386 
begin_visit(const FTUnit & v)14387 void *begin_visit (const FTUnit& v) {
14388   TRACE_VISIT ();
14389   // nothing to do
14390   return no_state;
14391 }
14392 
end_visit(const FTUnit & v,void *)14393 void end_visit (const FTUnit& v, void* /*visit_state*/) {
14394   TRACE_VISIT_OUT ();
14395   // nothing to do
14396 }
14397 
begin_visit(const FTWeight & v)14398 void *begin_visit (const FTWeight& v) {
14399   TRACE_VISIT ();
14400   // nothing to do
14401   return no_state;
14402 }
14403 
end_visit(const FTWeight & v,void *)14404 void end_visit (const FTWeight& v, void* /*visit_state*/) {
14405   TRACE_VISIT_OUT ();
14406 #ifndef ZORBA_NO_FULL_TEXT
14407   expr* e( pop_nodestack() );
14408   e = wrap_in_type_promotion(e,
14409                              theRTM.DOUBLE_TYPE_ONE,
14410                              PromoteIterator::TYPE_PROMOTION);
14411   push_ftstack( new ftweight( loc, e ) );
14412 #endif /* ZORBA_NO_FULL_TEXT */
14413 }
14414 
begin_visit(const FTWildCardOption & v)14415 void *begin_visit (const FTWildCardOption& v) {
14416   TRACE_VISIT ();
14417   // nothing to do
14418   return no_state;
14419 }
14420 
end_visit(const FTWildCardOption & v,void *)14421 void end_visit (const FTWildCardOption& v, void* /*visit_state*/) {
14422   TRACE_VISIT_OUT ();
14423 #ifndef ZORBA_NO_FULL_TEXT
14424   ftmatch_options *const mo = dynamic_cast<ftmatch_options*>( top_ftstack() );
14425   ZORBA_ASSERT( mo );
14426   if ( mo->get_wild_card_option() )
14427     throw XQUERY_EXCEPTION(
14428       err::FTST0019, ERROR_PARAMS( "wildcards" ), ERROR_LOC( loc )
14429     );
14430   mo->set_wild_card_option( new ftwild_card_option( loc, v.get_mode() ) );
14431 #endif /* ZORBA_NO_FULL_TEXT */
14432 }
14433 
begin_visit(const FTWindow & v)14434 void *begin_visit (const FTWindow& v) {
14435   TRACE_VISIT ();
14436   // nothing to do
14437   return no_state;
14438 }
14439 
end_visit(const FTWindow & v,void *)14440 void end_visit (const FTWindow& v, void* /*visit_state*/) {
14441   TRACE_VISIT_OUT ();
14442 #ifndef ZORBA_NO_FULL_TEXT
14443   expr* e( pop_nodestack() );
14444   e = wrap_in_type_promotion(e,
14445                              theRTM.INTEGER_TYPE_ONE,
14446                              PromoteIterator::TYPE_PROMOTION);
14447   push_ftstack( new ftwindow_filter( loc, e, v.get_unit()->get_unit() ) );
14448 #endif /* ZORBA_NO_FULL_TEXT */
14449 }
14450 
begin_visit(const FTWords & v)14451 void *begin_visit (const FTWords& v) {
14452   TRACE_VISIT ();
14453   // nothing to do
14454   return no_state;
14455 }
14456 
end_visit(const FTWords & v,void *)14457 void end_visit (const FTWords& v, void* /*visit_state*/) {
14458   TRACE_VISIT_OUT ();
14459 #ifndef ZORBA_NO_FULL_TEXT
14460   expr* e( pop_nodestack() );
14461   e = wrap_in_type_promotion(e,
14462                              theRTM.STRING_TYPE_STAR,
14463                              PromoteIterator::TYPE_PROMOTION);
14464   push_ftstack( new ftwords( loc, e, v.get_any_all_option()->get_option() ) );
14465 #endif /* ZORBA_NO_FULL_TEXT */
14466 }
14467 
begin_visit(const FTWordsTimes & v)14468 void *begin_visit (const FTWordsTimes& v)
14469 {
14470   TRACE_VISIT ();
14471   // nothing to do
14472   return no_state;
14473 }
14474 
end_visit(const FTWordsTimes & v,void *)14475 void end_visit (const FTWordsTimes& v, void* /*visit_state*/)
14476 {
14477   TRACE_VISIT_OUT ();
14478 #ifndef ZORBA_NO_FULL_TEXT
14479   ftrange *const times = dynamic_cast<ftrange*>( top_ftstack() );
14480   if ( times )
14481     pop_ftstack();
14482   ftwords *const words = dynamic_cast<ftwords*>( pop_ftstack() );
14483   push_ftstack( new ftwords_times( loc, words, times ) );
14484 #endif /* ZORBA_NO_FULL_TEXT */
14485 }
14486 
begin_visit(const FTWordsValue & v)14487 void *begin_visit (const FTWordsValue& v)
14488 {
14489   TRACE_VISIT ();
14490   // nothing to do
14491   return no_state;
14492 }
14493 
end_visit(const FTWordsValue & v,void *)14494 void end_visit (const FTWordsValue& v, void* /*visit_state*/)
14495 {
14496   TRACE_VISIT_OUT ();
14497   // nothing to do
14498 }
14499 
14500 
14501 /*******************************************************************************
14502 
14503 ********************************************************************************/
begin_visit(const ParseErrorNode & v)14504 void* begin_visit(const ParseErrorNode& v)
14505 {
14506   TRACE_VISIT();
14507   return no_state;
14508 }
14509 
end_visit(const ParseErrorNode & v,void *)14510 void end_visit(const ParseErrorNode& v, void* /*visit_state*/)
14511 {
14512   TRACE_VISIT_OUT();
14513 }
14514 
14515 
14516 /*******************************************************************************
14517 
14518 ********************************************************************************/
begin_visit(const exprnode & v)14519 void* begin_visit(const exprnode& v)
14520 {
14521   TRACE_VISIT();
14522   return no_state;
14523 }
14524 
end_visit(const exprnode & v,void *)14525 void end_visit(const exprnode& v, void* /*visit_state*/)
14526 {
14527   TRACE_VISIT_OUT();
14528 }
14529 
14530 
14531 public:
14532 
14533 /*******************************************************************************
14534 
14535 ********************************************************************************/
result()14536 expr* result()
14537 {
14538   if (theNodeStack.size() != 1)
14539   {
14540     std::cout << "Error: extra nodes on translator stack:\n";
14541     while (! theNodeStack.empty())
14542     {
14543 #ifndef NDEBUG
14544       expr* e_h = pop_nodestack();
14545 
14546       if (! Properties::instance()->traceTranslator())
14547       {
14548         if (e_h != NULL)
14549           e_h->put(std::cout) << std::endl;
14550         else
14551           std::cout << "NULL" << std::endl;
14552       }
14553 #else
14554       (void)pop_nodestack();
14555 #endif
14556     }
14557     ZORBA_ASSERT (false);
14558   }
14559 
14560   ZORBA_ASSERT(theTypeStack.size() == 0);
14561 
14562   if (theScopeDepth != 0)
14563   {
14564     std::cout << "Error: scope depth " << theScopeDepth << std::endl;
14565     ZORBA_ASSERT(false);
14566   }
14567 
14568   return pop_nodestack();
14569 }
14570 
14571 };
14572 
14573 
14574 /*******************************************************************************
14575   Translate a module.
14576 ********************************************************************************/
translate_aux(TranslatorImpl * rootTranslator,const parsenode & root,static_context * rootSctx,csize rootSctxId,ModulesInfo * minfo,const std::map<zstring,zstring> & modulesStack,bool isLibModule,StaticContextConsts::xquery_version_t maxLibModuleVersion)14577 expr* translate_aux(
14578     TranslatorImpl* rootTranslator,
14579     const parsenode& root,
14580     static_context* rootSctx,
14581     csize rootSctxId,
14582     ModulesInfo* minfo,
14583     const std::map<zstring, zstring>& modulesStack,
14584     bool isLibModule,
14585     StaticContextConsts::xquery_version_t maxLibModuleVersion)
14586 {
14587   std::auto_ptr<TranslatorImpl> t(new TranslatorImpl(rootTranslator,
14588                                                      rootSctx,
14589                                                      rootSctxId,
14590                                                      minfo,
14591                                                      modulesStack,
14592                                                      isLibModule,
14593                                                      maxLibModuleVersion));
14594 
14595   root.accept(*t);
14596 
14597   expr* result = t->result();
14598 
14599   CompilerCB* ccb = minfo->theCCB;
14600   if (ccb->theConfig.translate_cb != NULL)
14601     ccb->theConfig.translate_cb(&*result, "XQuery program");
14602 
14603   return result;
14604 }
14605 
14606 
14607 
14608 /*******************************************************************************
14609   Translate a main module.
14610 ********************************************************************************/
translate(const parsenode & root,CompilerCB * ccb)14611 expr* translate(const parsenode& root, CompilerCB* ccb)
14612 {
14613   std::map<zstring, zstring> modulesStack;
14614 
14615   if (typeid(root) != typeid(MainModule))
14616     RAISE_ERROR(err::XPST0003, root.get_location(),
14617     ERROR_PARAMS(ZED(XPST0003_ModuleDeclNotInMain)));
14618 
14619   ModulesInfo minfo(ccb);
14620 
14621   return translate_aux(NULL,
14622                        root,
14623                        ccb->theRootSctx,
14624                        (int)ccb->theSctxMap.size(),
14625                        &minfo,
14626                        modulesStack,
14627                        false);
14628 }
14629 
14630 } // namespace zorba
14631 /* vim:set et sw=2 ts=2: */
14632