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 #pragma once
17 #ifndef ZORBA_RUNTIME_VAR_ITERATORS
18 #define ZORBA_RUNTIME_VAR_ITERATORS
19 
20 #include "common/shared_types.h"
21 
22 #include "runtime/base/noarybase.h"
23 #include "runtime/base/unarybase.h"
24 #include "runtime/base/narybase.h"
25 
26 #include "zorbatypes/schema_types.h"
27 
28 
29 namespace zorba
30 {
31 
32 /*******************************************************************************
33   This iterator implements the var_decl expression. Its purpose is to "declare"
34   a block-local or prolog var (including the context item, if it is declared in
35   the prolog) and to initialize its value, if an init expr is provided.
36 
37   Specifically, for each prolog and block-local variable, the dynamic context
38   maps a numeric variable id (assigned to the varExpr during codegen) to an
39   entry that stores the current value of the variable, either as a single item
40   or as an iterator that produces an item sequence. Each such entry has a
41   state as well, which can be one of undeclared, declared, having a single-item
42   value, or having an iterator value.
43 
44   The iterator adds such an entry for the variable in the dynamic context and
45   initializes its state to "declared". It is possible that an entry for the
46   variable exists already (and the entry may even have a value already), in
47   which case, the iterator will set its state to "declared" only if it was
48   previously "undeclared". Then, if an init expr is porvided, the init subplan
49   will be evaluated, the resulting value will be stored in the dctx entry,
50   and the state of the entry will be set to single-item or iterator value.
51 
52   The iterator has 0 or 1 children. It has a single child if there is an
53   init expr, in which case, the child is the root of the subplan that computes
54   the init value.
55 
56   Note: this iterator is a NOOP if the variable being declared is an external
57   one, which has been set already, either during a previous execution of the
58   same XQuery obj, or via the c++ API.
59 ********************************************************************************/
60 class CtxVarDeclareIterator : public NaryBaseIterator<CtxVarDeclareIterator,
61                                                       PlanIteratorState>
62 {
63 private:
64   ulong         theVarId;
65   store::Item_t theVarName;
66   bool          theIsExternal;
67   bool          theSingleItem;
68 
69 public:
70   SERIALIZABLE_CLASS(CtxVarDeclareIterator);
71 
72   SERIALIZABLE_CLASS_CONSTRUCTOR2T(
73   CtxVarDeclareIterator,
74   NaryBaseIterator<CtxVarDeclareIterator, PlanIteratorState>);
75 
76   void serialize(::zorba::serialization::Archiver& ar);
77 
78 public:
79   CtxVarDeclareIterator(
80         static_context* sctx,
81         const QueryLoc& loc,
82         std::vector<PlanIter_t>& args,
83         ulong varid,
84         const store::Item_t& varName,
85         bool isExtern,
86         bool singleItem);
87 
getVarId()88   ulong getVarId() const { return theVarId; }
89 
getVarName()90   const store::Item* getVarName() const { return theVarName.getp(); }
91 
92   void accept(PlanIterVisitor& v) const;
93 
94   bool nextImpl(store::Item_t& result, PlanState& planState) const;
95 };
96 
97 
98 /*******************************************************************************
99   This iterator implements the ctxvar-assign(varName, initExpr) function. Its
100   purpose is to initialize prolog vars that do have an initializing expr, or
101   in xquery-scripting, to assign a value to a prolog or block-local variable.
102 
103   For the context item var, the iterator creates a binding in the dynamic ctx
104   between the varName (".") and the actual context item returned by the initExpr.
105   For a regular prolog var, the iterator creates a binding in the dynamic ctx
106   between the varName and an iterator plan that computes the initExpr.
107 ********************************************************************************/
108 class CtxVarAssignIterator : public UnaryBaseIterator<CtxVarAssignIterator,
109                                                       PlanIteratorState>
110 {
111 private:
112   ulong         theVarId;
113   store::Item_t theVarName;
114   bool          theIsLocal;
115   bool          theSingleItem;
116 
117 public:
118   SERIALIZABLE_CLASS(CtxVarAssignIterator);
119 
120   SERIALIZABLE_CLASS_CONSTRUCTOR2T(
121   CtxVarAssignIterator,
122   UnaryBaseIterator<CtxVarAssignIterator, PlanIteratorState>);
123 
124   void serialize(::zorba::serialization::Archiver& ar);
125 
126 public:
CtxVarAssignIterator(static_context * sctx,const QueryLoc & loc,ulong varid,const store::Item_t & varName,bool isLocal,PlanIter_t & arg)127   CtxVarAssignIterator(
128         static_context* sctx,
129         const QueryLoc& loc,
130         ulong varid,
131         const store::Item_t& varName,
132         bool isLocal,
133         PlanIter_t& arg)
134     :
135     UnaryBaseIterator<CtxVarAssignIterator, PlanIteratorState>(sctx, loc, arg),
136     theVarId(varid),
137     theVarName(varName),
138     theIsLocal(isLocal),
139     theSingleItem(false)
140   {
141   }
142 
getVarId()143   ulong getVarId() const { return theVarId; }
144 
getVarName()145   const store::Item* getVarName() const { return theVarName.getp(); }
146 
isLocal()147   bool isLocal() const { return theIsLocal; }
148 
setSingleItem()149   void setSingleItem() { theSingleItem = true; }
150 
151   void accept(PlanIterVisitor& v) const;
152 
153   bool nextImpl(store::Item_t& result, PlanState& planState) const;
154 };
155 
156 
157 /*******************************************************************************
158   This iterator implements the ctxvar-is-set(varName) function. Its purpose is
159   to check if an external prolog variable has been set. It does so by checking
160   whether an entry exists for variable in the global dynamic ctx.
161 ********************************************************************************/
162 class CtxVarIsSetIterator : public NoaryBaseIterator<CtxVarIsSetIterator,
163                                                        PlanIteratorState>
164 {
165 private:
166   ulong         theVarId;
167   store::Item_t theVarName;
168 
169 public:
170   SERIALIZABLE_CLASS(CtxVarIsSetIterator);
171 
172   SERIALIZABLE_CLASS_CONSTRUCTOR2T(
173   CtxVarIsSetIterator,
174   NoaryBaseIterator<CtxVarIsSetIterator, PlanIteratorState>);
175 
176   void serialize(::zorba::serialization::Archiver& ar);
177 
178 public:
CtxVarIsSetIterator(static_context * sctx,const QueryLoc & loc,ulong varid,const store::Item_t & varName)179   CtxVarIsSetIterator(
180         static_context* sctx,
181         const QueryLoc& loc,
182         ulong varid,
183         const store::Item_t& varName)
184     :
185     NoaryBaseIterator<CtxVarIsSetIterator, PlanIteratorState>(sctx, loc),
186     theVarId(varid),
187     theVarName(varName)
188   {
189   }
190 
getVarId()191   ulong getVarId() const { return theVarId; }
192 
getVarName()193   const store::Item* getVarName() const { return theVarName.getp(); }
194 
195   void accept(PlanIterVisitor& v) const;
196 
197   bool nextImpl(store::Item_t& result, PlanState& planState) const;
198 };
199 
200 
201 
202 /*******************************************************************************
203   This iterator implements a reference to a prolog or block-local variable.
204 
205   For each prolog variable, the dynamic context maps the name of the variable
206   to an iterator that computes the variable's value. CtxVariableIterator has
207   one child only, which produces the name of a prolog variabe. Using this name,
208   CtxVariableIterator extracts the associated iterator from the dynamic context
209   and just returns the items that it produces, one-at-a-time.
210 
211   The global context item is also considered a prolog variable whose name is
212   ".". Since the value of the context item is always a single item (or the empty
213   seq), the dynamic context maps "." to an Item (instead of an Iterator). So,
214   a CtxVariableIterator that represents the context item, returns just the item
215   associated with "." in the dynamic context.
216 
217   Note: the binding in the dynamic context between a var name and an iterator
218   plan (or single item) can be created in one of the following ways:
219   (a) The CtxVarAssignIterator described above, or
220   (b) Through the user API provided by DynamicContextImpl class (see methods
221       setVariable, setContextItem, etc).
222 ********************************************************************************/
223 class CtxVarState : public  PlanIteratorState
224 {
225 public:
226   store::TempSeq_t         theTempSeq;
227 
228   store::TempSeqIterator_t theSourceIter;
229   store::Item_t            theItem;
230 
231   xs_integer               thePos;
232   xs_integer               theLastPos;
233 
234 public:
235   CtxVarState();
236 
237   ~CtxVarState();
238 
239   void reset(PlanState& planState);
240 };
241 
242 
243 class CtxVarIterator : public NoaryBaseIterator<CtxVarIterator, CtxVarState>
244 {
245 protected:
246   ulong          theVarId;
247   store::Item_t  theVarName;
248   bool           theIsLocal;
249 
250   xs_integer     theTargetPos;
251   PlanIter_t     theTargetPosIter;
252   PlanIter_t     theTargetLenIter;
253   bool           theInfLen;
254 
255 public:
256   SERIALIZABLE_CLASS(CtxVarIterator);
257 
258   SERIALIZABLE_CLASS_CONSTRUCTOR2T(
259   CtxVarIterator,
260   NoaryBaseIterator<CtxVarIterator, CtxVarState>);
261 
262   void serialize(::zorba::serialization::Archiver& ar);
263 
264 public:
265   CtxVarIterator(
266       static_context* sctx,
267       const QueryLoc& loc,
268       ulong varid,
269       const store::Item_t& varName,
270       bool local);
271 
~CtxVarIterator()272   virtual ~CtxVarIterator() {}
273 
getVarId()274   ulong getVarId() const { return theVarId; }
275 
getVarName()276   const store::Item* getVarName() const { return theVarName.getp(); }
277 
isLocal()278   bool isLocal() const { return theIsLocal; }
279 
280   bool setTargetPos(xs_integer v);
281 
282   bool setTargetPosIter(const PlanIter_t& v);
283 
284   bool setTargetLenIter(const PlanIter_t& v);
285 
getTargetPos()286   xs_integer getTargetPos() const { return theTargetPos; }
287 
getTargetPosIter()288   PlanIterator* getTargetPosIter() const { return theTargetPosIter.getp(); }
289 
getTargetLenIter()290   PlanIterator* getTargetLenIter() const { return theTargetLenIter.getp(); }
291 
292   uint32_t getStateSizeOfSubtree() const;
293 
294   void accept(PlanIterVisitor& v) const;
295 
296   void openImpl(PlanState& planState, uint32_t& offset);
297 
298   void resetImpl(PlanState& planState) const;
299 
300   void closeImpl(PlanState& planState);
301 
302   bool nextImpl(store::Item_t& result, PlanState& planState) const;
303 };
304 
305 
306 /*******************************************************************************
307 
308   FOR variables. A ForVarIterator represents a reference to a for variable V.
309 
310   theValue stores the current value of V.
311 
312 ********************************************************************************/
313 class ForVarState : public PlanIteratorState
314 {
315 public:
316   store::Item_t theValue;
317 
init(PlanState & planState)318   void init(PlanState& planState)
319   {
320     PlanIteratorState::init(planState);
321   }
322 
reset(PlanState & planState)323   void reset(PlanState& planState)
324   {
325     PlanIteratorState::reset(planState);
326   }
327 };
328 
329 
330 class ForVarIterator : public NoaryBaseIterator<ForVarIterator, ForVarState>
331 {
332 protected:
333   store::Item_t  theVarName;
334 
335 public:
336   SERIALIZABLE_CLASS(ForVarIterator);
337 
338   SERIALIZABLE_CLASS_CONSTRUCTOR2T(
339   ForVarIterator,
340   NoaryBaseIterator<ForVarIterator, ForVarState>);
341 
342   void serialize(::zorba::serialization::Archiver& ar);
343 
344 public:
345   ForVarIterator(
346         static_context* sctx,
347         const QueryLoc& loc,
348         store::Item* name);
349 
~ForVarIterator()350   ~ForVarIterator() { }
351 
getVarName()352   store::Item* getVarName() const { return theVarName.getp(); }
353 
354   void accept(PlanIterVisitor& v) const;
355 
356   bool nextImpl(store::Item_t& result, PlanState& planState) const;
357 
358   void bind(store::Item* value, PlanState& planState);
359 };
360 
361 
362 /*******************************************************************************
363 
364   LET variables. A LetVarIterator represents a reference to a let variable V.
365 
366   If the var is materialized, then its value is stored in a temp sequence, and a
367   (smart) pointer to that temp seq is stored in the state of the LetVarIterator.
368   Otherwise, it's value is a PlanIteratorWraper that may wrap the actual domain
369   expression that defines the var.
370 
371   theSourceIter:
372   --------------
373   Stores the current "value" of V, if the variable is not materialized.
374 
375   theTempSeq:
376   -----------
377   The temp seq storing the value of tha variable.
378 
379   theTempSeqIter:
380   ---------------
381   A pre-allocated iterator over the temp seq.
382 
383 ********************************************************************************/
384 class LetVarState : public PlanIteratorState
385 {
386 public:
387   store::Iterator_t        theSourceIter;
388 
389   store::TempSeq_t         theTempSeq;
390   store::TempSeqIterator_t theTempSeqIter;
391   store::Item_t            theItem;
392   xs_integer               theWindowStart;
393   xs_integer               theWindowEnd;
394 
395   xs_integer               thePos;
396   xs_integer               theLastPos;
397 
398 public:
399   LetVarState();
400 
401   ~LetVarState();
402 
403   void reset(PlanState& planState);
404 };
405 
406 
407 class LetVarIterator : public NoaryBaseIterator<LetVarIterator, LetVarState>
408 {
409 private:
410   store::Item_t  theVarName;
411   xs_integer     theTargetPos;
412   PlanIter_t     theTargetPosIter;
413   PlanIter_t     theTargetLenIter;
414   bool           theInfLen;
415 
416 public:
417   SERIALIZABLE_CLASS(LetVarIterator);
418 
419   SERIALIZABLE_CLASS_CONSTRUCTOR2T(
420   LetVarIterator,
421   NoaryBaseIterator<LetVarIterator, LetVarState>);
422 
423   void serialize(::zorba::serialization::Archiver& ar);
424 
425 public:
426   LetVarIterator(
427       static_context* sctx,
428       const QueryLoc& loc,
429       store::Item* name);
430 
~LetVarIterator()431   ~LetVarIterator() {}
432 
433   bool setTargetPos(xs_integer v);
434 
435   bool setTargetPosIter(const PlanIter_t& v);
436 
437   bool setTargetLenIter(const PlanIter_t& v);
438 
getTargetPos()439   xs_integer getTargetPos() const { return theTargetPos; }
440 
getTargetPosIter()441   PlanIterator* getTargetPosIter() const { return theTargetPosIter.getp(); }
442 
getTargetLenIter()443   PlanIterator* getTargetLenIter() const { return theTargetLenIter.getp(); }
444 
getVarName()445   store::Item* getVarName() const { return theVarName.getp(); }
446 
447   void bind(const store::TempSeq_t& value, PlanState& planState);
448 
449   void bind(
450       store::TempSeq_t& value,
451       PlanState& planState,
452       xs_integer startPos,
453       xs_integer endPos);
454 
455   void bind(store::Iterator_t& it, PlanState& planState);
456 
457   void accept(PlanIterVisitor& v) const;
458 
459   uint32_t getStateSizeOfSubtree() const;
460 
461   void openImpl(PlanState& planState, uint32_t& offset);
462 
463   void resetImpl(PlanState& planState) const;
464 
465   void closeImpl(PlanState& planState);
466 
467   bool nextImpl(store::Item_t& result, PlanState& planState) const;
468 };
469 
470 
471 }
472 #endif
473 
474 /*
475  * Local variables:
476  * mode: c++
477  * End:
478  */
479 /* vim:set et sw=2 ts=2: */
480