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_FNCALL_ITERATOR 18 #define ZORBA_RUNTIME_FNCALL_ITERATOR 19 20 #include <zorba/api_shared_types.h> 21 #include <zorba/function.h> 22 23 #include "common/shared_types.h" 24 25 // TODO remove the next three includes 26 #include "api/unmarshaller.h" 27 #include "context/static_context.h" 28 29 #include "runtime/base/narybase.h" 30 31 32 namespace zorba { 33 34 class StaticContextImpl; 35 36 37 /******************************************************************************* 38 thePlan: 39 -------- 40 The runtime plan for the function body. This is created during 41 UDFunctionCallIterator::openImpl(), if it has not not been created already 42 (during the openImpl() method of another UDFunctionCallIterator on the same 43 udf). A pointer to this plan is also stored in the udf obj itself, and that's 44 how we know if it has been created already or not. 45 46 thePlanState: 47 ------------- 48 The plan state to run thePlan with. The PlanState obj is created during 49 UDFunctionCallIterator::openImpl(), but the actual state block is created and 50 initialized the 1st time that UDFunctionCallIterator::nextImpl() is called 51 (at that time open() is invoked on thePlan). 52 53 thePlanStateSize: 54 ----------------- 55 The size of the plan state block. 56 57 theLocalDCtx: 58 ------------- 59 The dynamic context for this udf call. It is where the values of the udf's 60 local block-variables are stored. It is created during 61 UDFunctionCallIterator::openImpl(), 62 63 thePlanOpen: 64 ------------ 65 Whether thePlan has been opened already or not. 66 67 theArgWrappers: 68 --------------- 69 For each argument of this function call, theArgWrappers stores a plan iterator 70 wrapper over the sub plan that computes the arg expr. This wrapping is needed 71 because the udf-body plan and the arg sub plans operate in different plan states. 72 Note: Withinh the function body, there may exist more than one references to 73 an arg var V, but these references are "mutually exclusive", ie, at most one 74 of the references will actually be reached during each particular execution of 75 the body. So, it is never the case that the arg expr will have more than one 76 consumers, and as a result we can bind all those V references to the same arg 77 wrapper. 78 79 theCache: 80 --------- 81 Is an Index which is set in the state if caching for the invoked function 82 should be done. The cache is owned by the UDF itself and shared across 83 all function invocations. 84 85 theArgValues: 86 ------------- 87 If caching is used, this vector contains the results of all arguments 88 of the function evaluation. It's used to bind the arg variables if the 89 cache didn't give a result in order to avoid duplicate evaluation of 90 the arguments. 91 ********************************************************************************/ 92 class UDFunctionCallIteratorState : public PlanIteratorState 93 { 94 public: 95 PlanIter_t thePlan; 96 PlanState * thePlanState; 97 uint32_t thePlanStateSize; 98 dynamic_context * theLocalDCtx; 99 bool thePlanOpen; 100 std::vector<store::Iterator_t> theArgWrappers; 101 store::Index * theCache; 102 std::vector<store::TempSeq_t> theArgValues; 103 104 UDFunctionCallIteratorState(); 105 106 ~UDFunctionCallIteratorState(); 107 108 void open(PlanState& planState, user_function* udf); 109 110 void reset(PlanState& planState); 111 }; 112 113 114 /******************************************************************************* 115 theUDF: 116 ------- 117 Pointer to the udf object. 118 119 theIsDynamic: 120 ------------- 121 122 ********************************************************************************/ 123 class UDFunctionCallIterator : public NaryBaseIterator<UDFunctionCallIterator, 124 UDFunctionCallIteratorState> 125 { 126 typedef std::vector<LetVarIter_t> ArgVarRefs; 127 128 protected: 129 user_function * theUDF; 130 bool theIsDynamic; 131 132 public: 133 SERIALIZABLE_CLASS(UDFunctionCallIterator); 134 135 SERIALIZABLE_CLASS_CONSTRUCTOR2T( 136 UDFunctionCallIterator, 137 NaryBaseIterator<UDFunctionCallIterator, UDFunctionCallIteratorState>); 138 139 void serialize(::zorba::serialization::Archiver& ar); 140 141 public: 142 UDFunctionCallIterator( 143 static_context* sctx, 144 const QueryLoc& loc, 145 std::vector<PlanIter_t>& args, 146 const user_function* aUDF); 147 ~UDFunctionCallIterator()148 ~UDFunctionCallIterator() {} 149 150 bool isUpdating() const; 151 setDynamic()152 void setDynamic() { theIsDynamic = true; } 153 154 bool isCached() const; 155 156 void accept(PlanIterVisitor& v) const; 157 158 void openImpl(PlanState& planState, uint32_t& offset); 159 160 void resetImpl(PlanState& planState) const; 161 162 void closeImpl(PlanState& planState); 163 164 bool nextImpl(store::Item_t& result, PlanState& planState) const; 165 166 protected: 167 void createCache( 168 PlanState& planState, 169 UDFunctionCallIteratorState* state); 170 171 bool probeCache( 172 PlanState& planState, 173 UDFunctionCallIteratorState* state, 174 store::Item_t& result, 175 std::vector<store::Item_t>& argValues) const; 176 177 void insertCacheEntry( 178 UDFunctionCallIteratorState* state, 179 std::vector<store::Item_t>& argValues, 180 store::Item_t& udfValue) const; 181 }; 182 183 184 /******************************************************************************* 185 186 ********************************************************************************/ 187 class ExtFunctionCallIteratorState : public PlanIteratorState 188 { 189 public: 190 std::vector<ItemSequence*> m_extArgs; 191 ItemSequence_t theResult; 192 Iterator_t theResultIter; 193 194 ExtFunctionCallIteratorState(); 195 196 ~ExtFunctionCallIteratorState(); 197 198 void reset(PlanState&); 199 }; 200 201 202 class ExtFunctionCallIterator : public NaryBaseIterator<ExtFunctionCallIterator, 203 ExtFunctionCallIteratorState> 204 { 205 protected: 206 const ExternalFunction * theFunction; 207 bool theIsUpdating; 208 zstring theNamespace; 209 static_context * theModuleSctx; 210 211 public: 212 SERIALIZABLE_CLASS(ExtFunctionCallIterator); 213 214 SERIALIZABLE_CLASS_CONSTRUCTOR2T( 215 ExtFunctionCallIterator, 216 NaryBaseIterator<ExtFunctionCallIterator, ExtFunctionCallIteratorState>); 217 218 void serialize(serialization::Archiver& ar); 219 220 public: 221 ExtFunctionCallIterator( 222 static_context* sctx, 223 const QueryLoc& loc, 224 std::vector<PlanIter_t>& args, 225 const ExternalFunction* function, 226 bool isUpdating, 227 const zstring& ns, 228 static_context* moduleSctx); 229 230 virtual ~ExtFunctionCallIterator(); 231 isUpdating()232 virtual bool isUpdating() const { return theIsUpdating; } 233 234 void accept(PlanIterVisitor& v) const; 235 236 void openImpl(PlanState& planState, uint32_t& offset); 237 238 bool nextImpl(store::Item_t& result, PlanState& planState) const; 239 }; 240 241 } 242 243 #endif /* ZORBA_FNCALL_ITERATOR_H */ 244 245 /* 246 * Local variables: 247 * mode: c++ 248 * End: 249 */ 250 /* vim:set et sw=2 ts=2: */ 251