Merge lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba

Proposed by Federico Cavalieri on 2014-04-15
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
Reviewer Review Type Date Requested Status
Federico Cavalieri Approve on 2014-04-15
Matthias Brantner 2014-04-15 Approve on 2014-04-15
Review via email: mp+215934@code.launchpad.net

Commit message

Fixed external functions skip iterator

Description of the change

Fixed external functions skip iterator

To post a comment you must log in.
Federico Cavalieri (fcavalieri) wrote :

I found a regression, investigating

11714. By Federico Cavalieri on 2014-04-15

Fixed external functions skip iterator

review: Approve
Zorba Build Bot (zorba-buildbot) wrote :
Zorba Build Bot (zorba-buildbot) wrote :

Voting criteria failed for the following merge proposals:

https://code.launchpad.net/~zorba-coders/zorba/fix-fncall-iterator/+merge/215934 :
Votes: {'Approve': 1}

Zorba Build Bot (zorba-buildbot) wrote :

Validation queue result for https://code.launchpad.net/~zorba-coders/zorba/fix-fncall-iterator/+merge/215934

Stage "CommitZorba" failed.

Check console output at http://jenkins.lambda.nu:8180/job/CommitZorba/316/console to view the results.

Zorba Build Bot (zorba-buildbot) wrote :
Zorba Build Bot (zorba-buildbot) wrote :

Voting criteria failed for the following merge proposals:

https://code.launchpad.net/~zorba-coders/zorba/fix-fncall-iterator/+merge/215934 :
Votes: {'Approve': 1}

Zorba Build Bot (zorba-buildbot) wrote :

Validation queue result for https://code.launchpad.net/~zorba-coders/zorba/fix-fncall-iterator/+merge/215934

Stage "CommitZorba" failed.

Check console output at http://jenkins.lambda.nu:8180/job/CommitZorba/317/console to view the results.

review: Approve
Zorba Build Bot (zorba-buildbot) wrote :
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue succeeded - proposal merged!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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+&lt;products&gt; &lt;product&gt;
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]

Subscribers

People subscribed via source and target branches