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