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