zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #26917
[Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
Federico Cavalieri has proposed merging lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba.
Commit message:
Fixed external functions skip iterator
Requested reviews:
Matthias Brantner (matthias-brantner)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/fix-fncall-iterator/+merge/215934
Fixed external functions skip iterator
--
https://code.launchpad.net/~zorba-coders/zorba/fix-fncall-iterator/+merge/215934
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/runtime/core/fncall_iterator.cpp'
--- src/runtime/core/fncall_iterator.cpp 2014-02-25 03:58:17 +0000
+++ src/runtime/core/fncall_iterator.cpp 2014-04-15 18:58:26 +0000
@@ -773,7 +773,8 @@
/*******************************************************************************
********************************************************************************/
-ExtFunctionCallIteratorState::ExtFunctionCallIteratorState()
+ExtFunctionCallIteratorState::ExtFunctionCallIteratorState():
+ theIsEvaluated(false)
{
}
@@ -951,48 +952,40 @@
STACK_END( state );
}
-bool ExtFunctionCallIterator::skip( int64_t count,
- PlanState &planState ) const {
+bool ExtFunctionCallIterator::skip(int64_t count, PlanState &planState) const
+{
ItemSequence_t api_seq;
bool more_items;
-
- ExtFunctionCallIteratorState *state;
- DEFAULT_STACK_INIT( ExtFunctionCallIteratorState, state, planState );
-
- try {
- if ( theFunction->isContextual() ) {
- ContextualExternalFunction const *const f =
- dynamic_cast<ContextualExternalFunction const*>( theFunction );
- ZORBA_ASSERT( f );
- StaticContextImpl sctx(
- theModuleSctx,
- planState.theQuery ?
- planState.theQuery->getRegisteredDiagnosticHandlerNoSync() :
- nullptr
- );
- DynamicContextImpl dctx(
- nullptr, planState.theGlobalDynCtx, theModuleSctx
- );
- api_seq = f->evaluate( state->m_extArgs, &sctx, &dctx );
- } else {
- NonContextualExternalFunction const *const f =
- dynamic_cast<NonContextualExternalFunction const*>( theFunction );
- ZORBA_ASSERT( f );
- api_seq = f->evaluate( state->m_extArgs );
- }
- if ( !!api_seq ) {
- Iterator_t api_iter( api_seq->getIterator() );
- api_iter->open();
- more_items = api_iter->skip( count );
- api_iter->close();
+ ExtFunctionCallIteratorState *state =
+ StateTraitsImpl<ExtFunctionCallIteratorState>::getState(planState, this->theStateOffset);
+
+ try
+ {
+ ZORBA_ASSERT(!state->theIsEvaluated);
+ evaluate(state, planState);
+
+ if ( !state->theResult.isNull() )
+ {
+ state->theResultIter = state->theResult->getIterator();
+ state->theResultIter->open();
+ more_items = state->theResultIter->skip( count );
+ if (!more_items)
+ state->theResultIter->close();
}
}
- catch ( ZorbaException &e ) {
+ catch ( ZorbaException &e )
+ {
set_source( e, loc );
throw;
}
- STACK_PUSH( more_items, state );
- STACK_END( state );
+ catch (std::exception const& e)
+ {
+ throw XQUERY_EXCEPTION(
+ zerr::ZXQP0001_DYNAMIC_RUNTIME_ERROR,
+ ERROR_PARAMS(e.what()),
+ ERROR_LOC(loc));
+ }
+ return more_items;
}
bool ExtFunctionCallIterator::nextImpl(
@@ -1000,102 +993,110 @@
PlanState& planState) const
{
Item lOutsideItem;
- const NonContextualExternalFunction* lPureFct = 0;
- const ContextualExternalFunction* lNonePureFct = 0;
ExtFunctionCallIteratorState* state;
DEFAULT_STACK_INIT(ExtFunctionCallIteratorState, state, planState);
- try
- {
- if (!theFunction->isContextual())
- {
- lPureFct = dynamic_cast<const NonContextualExternalFunction*>(theFunction);
- ZORBA_ASSERT(lPureFct);
-
- state->theResult = lPureFct->evaluate(state->m_extArgs);
- if(state->theResult.get() != NULL)
- state->theResultIter = state->theResult->getIterator();
- }
- else
- {
- lNonePureFct = dynamic_cast<const ContextualExternalFunction*>(theFunction);
- ZORBA_ASSERT(lNonePureFct);
-
- // The planState.theQuery maybe null, e.g. in the case of constant-folding
- // of global variable expressions
- StaticContextImpl theSctxWrapper(theModuleSctx,
- (planState.theQuery == NULL?
- NULL :
- planState.theQuery->getRegisteredDiagnosticHandlerNoSync()));
-
- DynamicContextImpl theDctxWrapper(NULL,
- planState.theGlobalDynCtx,
- theModuleSctx);
-
- state->theResult = lNonePureFct->evaluate(state->m_extArgs,
- &theSctxWrapper,
- &theDctxWrapper);
-
- if(state->theResult.get() != NULL)
- state->theResultIter = state->theResult->getIterator();
- } // if (!theFunction->isContextual())
- }
- catch (ZorbaException& e)
- {
- set_source( e, loc );
- throw;
- }
- catch (std::exception const& e)
- {
- throw XQUERY_EXCEPTION(
- zerr::ZXQP0001_DYNAMIC_RUNTIME_ERROR,
- ERROR_PARAMS(e.what()),
- ERROR_LOC(loc));
- }
-
-
- if(state->theResult.get() != NULL)
- {
- state->theResultIter->open();
- }
- while (true)
+ if (!state->theIsEvaluated)
{
try
{
- if (state->theResult.get() == NULL) // This will happen if the user's external function returns a zorba::ItemSequence_t(NULL)
- break;
-
- if (!state->theResultIter->next(lOutsideItem))
- {
- state->theResultIter->close();
- break;
- }
- }
- catch (XQueryException& e)
- {
- set_source( e, loc );
- throw;
- }
-
- result = Unmarshaller::getInternalItem(lOutsideItem);
-
- if (theIsUpdating)
- {
- if (!result->isPul())
- throw XQUERY_EXCEPTION(err::XUDY0019, ERROR_LOC(loc));
- }
- else
- {
- if (result->isPul())
- throw XQUERY_EXCEPTION(err::XUDY0018, ERROR_LOC(loc));
- }
- STACK_PUSH(true, state);
- }
-
+ evaluate(state, planState);
+
+ if (state->theResult.get() != NULL)
+ {
+ state->theResultIter = state->theResult->getIterator();
+ state->theResultIter->open();
+ }
+ }
+ catch (ZorbaException& e)
+ {
+ set_source( e, loc );
+ throw;
+ }
+ catch (std::exception const& e)
+ {
+ throw XQUERY_EXCEPTION(
+ zerr::ZXQP0001_DYNAMIC_RUNTIME_ERROR,
+ ERROR_PARAMS(e.what()),
+ ERROR_LOC(loc));
+ }
+ }
+
+ if (!state->theResult.isNull() && //The external function returns zorba::ItemSequence_t(NULL)
+ state->theResultIter->isOpen()) //The iterator has not been skipped past its end
+ {
+ while (true)
+ {
+ try
+ {
+ if (!state->theResultIter->next(lOutsideItem))
+ {
+ state->theResultIter->close();
+ break;
+ }
+ }
+ catch (XQueryException& e)
+ {
+ set_source( e, loc );
+ throw;
+ }
+ catch (std::exception const& e)
+ {
+ throw XQUERY_EXCEPTION(
+ zerr::ZXQP0001_DYNAMIC_RUNTIME_ERROR,
+ ERROR_PARAMS(e.what()),
+ ERROR_LOC(loc));
+ }
+
+ result = Unmarshaller::getInternalItem(lOutsideItem);
+
+ if (theIsUpdating)
+ {
+ if (!result->isPul())
+ throw XQUERY_EXCEPTION(err::XUDY0019, ERROR_LOC(loc));
+ }
+ else
+ {
+ if (result->isPul())
+ throw XQUERY_EXCEPTION(err::XUDY0018, ERROR_LOC(loc));
+ }
+ STACK_PUSH(true, state);
+ }
+ }
STACK_END (state);
}
+void ExtFunctionCallIterator::evaluate(ExtFunctionCallIteratorState* state, PlanState& planState) const
+{
+ if ( theFunction->isContextual() )
+ {
+ ContextualExternalFunction const *const lFunction =
+ dynamic_cast<ContextualExternalFunction const*>( theFunction );
+ ZORBA_ASSERT( lFunction );
+
+ StaticContextImpl lSctx(theModuleSctx,
+ planState.theQuery ?
+ planState.theQuery->getRegisteredDiagnosticHandlerNoSync():
+ nullptr);
+
+ DynamicContextImpl lDctx(nullptr,
+ planState.theGlobalDynCtx,
+ theModuleSctx);
+
+ state->theResult = lFunction->evaluate( state->m_extArgs, &lSctx, &lDctx );
+ }
+ else
+ {
+ NonContextualExternalFunction const *const lFunction =
+ dynamic_cast<NonContextualExternalFunction const*>( theFunction );
+ ZORBA_ASSERT( lFunction );
+
+ state->theResult = lFunction->evaluate( state->m_extArgs );
+ }
+
+ state->theIsEvaluated = true;
+}
NARY_ACCEPT(ExtFunctionCallIterator);
=== modified file 'src/runtime/core/fncall_iterator.h'
--- src/runtime/core/fncall_iterator.h 2014-02-12 02:25:45 +0000
+++ src/runtime/core/fncall_iterator.h 2014-04-15 18:58:26 +0000
@@ -215,6 +215,7 @@
std::vector<ItemSequence*> m_extArgs;
ItemSequence_t theResult;
Iterator_t theResultIter;
+ bool theIsEvaluated;
ExtFunctionCallIteratorState();
@@ -265,7 +266,11 @@
bool nextImpl(store::Item_t& result, PlanState& planState) const;
bool count(store::Item_t& result, PlanState& planState) const;
+
bool skip(int64_t count, PlanState &planState) const;
+
+private:
+ void evaluate(ExtFunctionCallIteratorState* state, PlanState& planState) const;
};
}
=== added file 'test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines-2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines-2.xml.res 1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines-2.xml.res 2014-04-15 18:58:26 +0000
@@ -0,0 +1,1 @@
+<products> <product>
\ No newline at end of file
=== added file 'test/rbkt/Queries/zorba/file/file_read_text_lines-2.xq'
--- test/rbkt/Queries/zorba/file/file_read_text_lines-2.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/file/file_read_text_lines-2.xq 2014-04-15 18:58:26 +0000
@@ -0,0 +1,4 @@
+import module namespace file = "http://expath.org/ns/file";
+
+file:read-text-lines(fn:resolve-uri("mydata.xml"))[1],
+file:read-text-lines(fn:resolve-uri("mydata.xml"))[2]
Follow ups
-
[Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: noreply, 2014-04-15
-
[Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: Zorba Build Bot, 2014-04-15
-
[Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: Zorba Build Bot, 2014-04-15
-
Re: [Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: Federico Cavalieri, 2014-04-15
-
[Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: Zorba Build Bot, 2014-04-15
-
[Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: Zorba Build Bot, 2014-04-15
-
[Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: Zorba Build Bot, 2014-04-15
-
[Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: Zorba Build Bot, 2014-04-15
-
[Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: Zorba Build Bot, 2014-04-15
-
Re: [Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: Matthias Brantner, 2014-04-15
-
Re: [Merge] lp:~zorba-coders/zorba/fix-fncall-iterator into lp:zorba
From: Federico Cavalieri, 2014-04-15