Merge lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
- fix-fncall-iterator
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 11714 |
Proposed branch: | lp:~zorba-coders/zorba/fix-fncall-iterator |
Merge into: | lp:zorba |
Diff against target: |
336 lines (+136/-122) 4 files modified
src/runtime/core/fncall_iterator.cpp (+126/-122) src/runtime/core/fncall_iterator.h (+5/-0) test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines-2.xml.res (+1/-0) test/rbkt/Queries/zorba/file/file_read_text_lines-2.xq (+4/-0) |
To merge this branch: | bzr merge lp:~zorba-coders/zorba/fix-fncall-iterator |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Federico Cavalieri | Approve | ||
Matthias Brantner | Approve | ||
Review via email: mp+215934@code.launchpad.net |
Commit message
Fixed external functions skip iterator
Description of the change
Fixed external functions skip iterator
Federico Cavalieri (fcavalieri) wrote : | # |
- 11714. By Federico Cavalieri
-
Fixed external functions skip iterator
Matthias Brantner (matthias-brantner) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for the following merge proposals:
https:/
Progress dashboard at http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Voting criteria failed for the following merge proposals:
https:/
Votes: {'Approve': 1}
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue result for https:/
Stage "CommitZorba" failed.
Check console output at http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for the following merge proposals:
https:/
Progress dashboard at http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Voting criteria failed for the following merge proposals:
https:/
Votes: {'Approve': 1}
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue result for https:/
Stage "CommitZorba" failed.
Check console output at http://
Federico Cavalieri (fcavalieri) : | # |
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for the following merge proposals:
https:/
Progress dashboard at http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue succeeded - proposal merged!
Preview Diff
1 | === modified file 'src/runtime/core/fncall_iterator.cpp' |
2 | --- src/runtime/core/fncall_iterator.cpp 2014-02-25 03:58:17 +0000 |
3 | +++ src/runtime/core/fncall_iterator.cpp 2014-04-15 19:36:22 +0000 |
4 | @@ -773,7 +773,8 @@ |
5 | /******************************************************************************* |
6 | |
7 | ********************************************************************************/ |
8 | -ExtFunctionCallIteratorState::ExtFunctionCallIteratorState() |
9 | +ExtFunctionCallIteratorState::ExtFunctionCallIteratorState(): |
10 | + theIsEvaluated(false) |
11 | { |
12 | } |
13 | |
14 | @@ -796,6 +797,7 @@ |
15 | PlanIteratorState::reset(planState); |
16 | theResultIter = NULL; |
17 | theResult = NULL; |
18 | + theIsEvaluated = false; |
19 | } |
20 | |
21 | |
22 | @@ -951,48 +953,43 @@ |
23 | STACK_END( state ); |
24 | } |
25 | |
26 | -bool ExtFunctionCallIterator::skip( int64_t count, |
27 | - PlanState &planState ) const { |
28 | +bool ExtFunctionCallIterator::skip(int64_t count, PlanState &planState) const |
29 | +{ |
30 | + if (count == 0) |
31 | + return true; |
32 | + |
33 | ItemSequence_t api_seq; |
34 | bool more_items; |
35 | - |
36 | - ExtFunctionCallIteratorState *state; |
37 | - DEFAULT_STACK_INIT( ExtFunctionCallIteratorState, state, planState ); |
38 | - |
39 | - try { |
40 | - if ( theFunction->isContextual() ) { |
41 | - ContextualExternalFunction const *const f = |
42 | - dynamic_cast<ContextualExternalFunction const*>( theFunction ); |
43 | - ZORBA_ASSERT( f ); |
44 | - StaticContextImpl sctx( |
45 | - theModuleSctx, |
46 | - planState.theQuery ? |
47 | - planState.theQuery->getRegisteredDiagnosticHandlerNoSync() : |
48 | - nullptr |
49 | - ); |
50 | - DynamicContextImpl dctx( |
51 | - nullptr, planState.theGlobalDynCtx, theModuleSctx |
52 | - ); |
53 | - api_seq = f->evaluate( state->m_extArgs, &sctx, &dctx ); |
54 | - } else { |
55 | - NonContextualExternalFunction const *const f = |
56 | - dynamic_cast<NonContextualExternalFunction const*>( theFunction ); |
57 | - ZORBA_ASSERT( f ); |
58 | - api_seq = f->evaluate( state->m_extArgs ); |
59 | - } |
60 | - if ( !!api_seq ) { |
61 | - Iterator_t api_iter( api_seq->getIterator() ); |
62 | - api_iter->open(); |
63 | - more_items = api_iter->skip( count ); |
64 | - api_iter->close(); |
65 | + ExtFunctionCallIteratorState *state = |
66 | + StateTraitsImpl<ExtFunctionCallIteratorState>::getState(planState, this->theStateOffset); |
67 | + |
68 | + try |
69 | + { |
70 | + ZORBA_ASSERT(!state->theIsEvaluated); |
71 | + evaluate(state, planState); |
72 | + |
73 | + if ( !state->theResult.isNull() ) |
74 | + { |
75 | + state->theResultIter = state->theResult->getIterator(); |
76 | + state->theResultIter->open(); |
77 | + more_items = state->theResultIter->skip( count ); |
78 | + if (!more_items) |
79 | + state->theResultIter->close(); |
80 | } |
81 | } |
82 | - catch ( ZorbaException &e ) { |
83 | + catch ( ZorbaException &e ) |
84 | + { |
85 | set_source( e, loc ); |
86 | throw; |
87 | } |
88 | - STACK_PUSH( more_items, state ); |
89 | - STACK_END( state ); |
90 | + catch (std::exception const& e) |
91 | + { |
92 | + throw XQUERY_EXCEPTION( |
93 | + zerr::ZXQP0001_DYNAMIC_RUNTIME_ERROR, |
94 | + ERROR_PARAMS(e.what()), |
95 | + ERROR_LOC(loc)); |
96 | + } |
97 | + return more_items; |
98 | } |
99 | |
100 | bool ExtFunctionCallIterator::nextImpl( |
101 | @@ -1000,102 +997,109 @@ |
102 | PlanState& planState) const |
103 | { |
104 | Item lOutsideItem; |
105 | - const NonContextualExternalFunction* lPureFct = 0; |
106 | - const ContextualExternalFunction* lNonePureFct = 0; |
107 | |
108 | ExtFunctionCallIteratorState* state; |
109 | DEFAULT_STACK_INIT(ExtFunctionCallIteratorState, state, planState); |
110 | |
111 | - try |
112 | - { |
113 | - if (!theFunction->isContextual()) |
114 | - { |
115 | - lPureFct = dynamic_cast<const NonContextualExternalFunction*>(theFunction); |
116 | - ZORBA_ASSERT(lPureFct); |
117 | - |
118 | - state->theResult = lPureFct->evaluate(state->m_extArgs); |
119 | - if(state->theResult.get() != NULL) |
120 | - state->theResultIter = state->theResult->getIterator(); |
121 | - } |
122 | - else |
123 | - { |
124 | - lNonePureFct = dynamic_cast<const ContextualExternalFunction*>(theFunction); |
125 | - ZORBA_ASSERT(lNonePureFct); |
126 | - |
127 | - // The planState.theQuery maybe null, e.g. in the case of constant-folding |
128 | - // of global variable expressions |
129 | - StaticContextImpl theSctxWrapper(theModuleSctx, |
130 | - (planState.theQuery == NULL? |
131 | - NULL : |
132 | - planState.theQuery->getRegisteredDiagnosticHandlerNoSync())); |
133 | - |
134 | - DynamicContextImpl theDctxWrapper(NULL, |
135 | - planState.theGlobalDynCtx, |
136 | - theModuleSctx); |
137 | - |
138 | - state->theResult = lNonePureFct->evaluate(state->m_extArgs, |
139 | - &theSctxWrapper, |
140 | - &theDctxWrapper); |
141 | - |
142 | - if(state->theResult.get() != NULL) |
143 | - state->theResultIter = state->theResult->getIterator(); |
144 | - } // if (!theFunction->isContextual()) |
145 | - } |
146 | - catch (ZorbaException& e) |
147 | - { |
148 | - set_source( e, loc ); |
149 | - throw; |
150 | - } |
151 | - catch (std::exception const& e) |
152 | - { |
153 | - throw XQUERY_EXCEPTION( |
154 | - zerr::ZXQP0001_DYNAMIC_RUNTIME_ERROR, |
155 | - ERROR_PARAMS(e.what()), |
156 | - ERROR_LOC(loc)); |
157 | - } |
158 | - |
159 | - |
160 | - if(state->theResult.get() != NULL) |
161 | - { |
162 | - state->theResultIter->open(); |
163 | - } |
164 | - while (true) |
165 | + if (!state->theIsEvaluated) |
166 | { |
167 | try |
168 | { |
169 | - if (state->theResult.get() == NULL) // This will happen if the user's external function returns a zorba::ItemSequence_t(NULL) |
170 | - break; |
171 | - |
172 | - if (!state->theResultIter->next(lOutsideItem)) |
173 | - { |
174 | - state->theResultIter->close(); |
175 | - break; |
176 | - } |
177 | - } |
178 | - catch (XQueryException& e) |
179 | - { |
180 | - set_source( e, loc ); |
181 | - throw; |
182 | - } |
183 | - |
184 | - result = Unmarshaller::getInternalItem(lOutsideItem); |
185 | - |
186 | - if (theIsUpdating) |
187 | - { |
188 | - if (!result->isPul()) |
189 | - throw XQUERY_EXCEPTION(err::XUDY0019, ERROR_LOC(loc)); |
190 | - } |
191 | - else |
192 | - { |
193 | - if (result->isPul()) |
194 | - throw XQUERY_EXCEPTION(err::XUDY0018, ERROR_LOC(loc)); |
195 | - } |
196 | - STACK_PUSH(true, state); |
197 | - } |
198 | - |
199 | + evaluate(state, planState); |
200 | + |
201 | + if (state->theResult.get() != NULL) |
202 | + { |
203 | + state->theResultIter = state->theResult->getIterator(); |
204 | + state->theResultIter->open(); |
205 | + } |
206 | + } |
207 | + catch (ZorbaException& e) |
208 | + { |
209 | + set_source( e, loc ); |
210 | + throw; |
211 | + } |
212 | + catch (std::exception const& e) |
213 | + { |
214 | + throw XQUERY_EXCEPTION( |
215 | + zerr::ZXQP0001_DYNAMIC_RUNTIME_ERROR, |
216 | + ERROR_PARAMS(e.what()), |
217 | + ERROR_LOC(loc)); |
218 | + } |
219 | + } |
220 | + |
221 | + if (!state->theResult.isNull() && //The external function returns zorba::ItemSequence_t(NULL) |
222 | + state->theResultIter->isOpen()) //The iterator has not been skipped past its end |
223 | + { |
224 | + while (true) |
225 | + { |
226 | + try |
227 | + { |
228 | + if (!state->theResultIter->next(lOutsideItem)) |
229 | + { |
230 | + state->theResultIter->close(); |
231 | + break; |
232 | + } |
233 | + } |
234 | + catch (XQueryException& e) |
235 | + { |
236 | + set_source( e, loc ); |
237 | + throw; |
238 | + } |
239 | + catch (std::exception const& e) |
240 | + { |
241 | + throw XQUERY_EXCEPTION( |
242 | + zerr::ZXQP0001_DYNAMIC_RUNTIME_ERROR, |
243 | + ERROR_PARAMS(e.what()), |
244 | + ERROR_LOC(loc)); |
245 | + } |
246 | + |
247 | + result = Unmarshaller::getInternalItem(lOutsideItem); |
248 | + |
249 | + if (theIsUpdating) |
250 | + { |
251 | + if (!result->isPul()) |
252 | + throw XQUERY_EXCEPTION(err::XUDY0019, ERROR_LOC(loc)); |
253 | + } |
254 | + else |
255 | + { |
256 | + if (result->isPul()) |
257 | + throw XQUERY_EXCEPTION(err::XUDY0018, ERROR_LOC(loc)); |
258 | + } |
259 | + STACK_PUSH(true, state); |
260 | + } |
261 | + } |
262 | STACK_END (state); |
263 | } |
264 | |
265 | +void ExtFunctionCallIterator::evaluate(ExtFunctionCallIteratorState* state, PlanState& planState) const |
266 | +{ |
267 | + if ( theFunction->isContextual() ) |
268 | + { |
269 | + ContextualExternalFunction const *const lFunction = |
270 | + dynamic_cast<ContextualExternalFunction const*>( theFunction ); |
271 | + ZORBA_ASSERT( lFunction ); |
272 | + |
273 | + StaticContextImpl lSctx(theModuleSctx, |
274 | + planState.theQuery ? |
275 | + planState.theQuery->getRegisteredDiagnosticHandlerNoSync(): |
276 | + nullptr); |
277 | + |
278 | + DynamicContextImpl lDctx(nullptr, |
279 | + planState.theGlobalDynCtx, |
280 | + theModuleSctx); |
281 | + |
282 | + state->theResult = lFunction->evaluate( state->m_extArgs, &lSctx, &lDctx ); |
283 | + } |
284 | + else |
285 | + { |
286 | + NonContextualExternalFunction const *const lFunction = |
287 | + dynamic_cast<NonContextualExternalFunction const*>( theFunction ); |
288 | + ZORBA_ASSERT( lFunction ); |
289 | + |
290 | + state->theResult = lFunction->evaluate( state->m_extArgs ); |
291 | + } |
292 | + state->theIsEvaluated = true; |
293 | +} |
294 | |
295 | NARY_ACCEPT(ExtFunctionCallIterator); |
296 | |
297 | |
298 | === modified file 'src/runtime/core/fncall_iterator.h' |
299 | --- src/runtime/core/fncall_iterator.h 2014-02-12 02:25:45 +0000 |
300 | +++ src/runtime/core/fncall_iterator.h 2014-04-15 19:36:22 +0000 |
301 | @@ -215,6 +215,7 @@ |
302 | std::vector<ItemSequence*> m_extArgs; |
303 | ItemSequence_t theResult; |
304 | Iterator_t theResultIter; |
305 | + bool theIsEvaluated; |
306 | |
307 | ExtFunctionCallIteratorState(); |
308 | |
309 | @@ -265,7 +266,11 @@ |
310 | bool nextImpl(store::Item_t& result, PlanState& planState) const; |
311 | |
312 | bool count(store::Item_t& result, PlanState& planState) const; |
313 | + |
314 | bool skip(int64_t count, PlanState &planState) const; |
315 | + |
316 | +private: |
317 | + void evaluate(ExtFunctionCallIteratorState* state, PlanState& planState) const; |
318 | }; |
319 | |
320 | } |
321 | |
322 | === added file 'test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines-2.xml.res' |
323 | --- test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines-2.xml.res 1970-01-01 00:00:00 +0000 |
324 | +++ test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines-2.xml.res 2014-04-15 19:36:22 +0000 |
325 | @@ -0,0 +1,1 @@ |
326 | +<products> <product> |
327 | \ No newline at end of file |
328 | |
329 | === added file 'test/rbkt/Queries/zorba/file/file_read_text_lines-2.xq' |
330 | --- test/rbkt/Queries/zorba/file/file_read_text_lines-2.xq 1970-01-01 00:00:00 +0000 |
331 | +++ test/rbkt/Queries/zorba/file/file_read_text_lines-2.xq 2014-04-15 19:36:22 +0000 |
332 | @@ -0,0 +1,4 @@ |
333 | +import module namespace file = "http://expath.org/ns/file"; |
334 | + |
335 | +file:read-text-lines(fn:resolve-uri("mydata.xml"))[1], |
336 | +file:read-text-lines(fn:resolve-uri("mydata.xml"))[2] |
I found a regression, investigating