← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba

 

Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/markos-scratch into lp:zorba.

Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/114657

Streaming execution for tumbling windows (also fixes bug #1010051)
-- 
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/114657
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2012-07-11 10:57:01 +0000
+++ ChangeLog	2012-07-12 14:52:27 +0000
@@ -26,6 +26,7 @@
   * Big rewrite of plan serializer internals, resulting in big performance improvement.
   * Avoid (if possible) treat expr for checking that the value of a non-external
     global variable conforms to the type declaration of the vatiable.
+  * Streaming execution for tumbling windows (also fixes bug #1010051).
 
 Bug Fixes/Other Changes:
   * Fixed bug #1002993 (bug during revalidation after update; improper condition

=== modified file 'src/compiler/expression/flwor_expr.cpp'
--- src/compiler/expression/flwor_expr.cpp	2012-07-11 04:46:41 +0000
+++ src/compiler/expression/flwor_expr.cpp	2012-07-12 14:52:27 +0000
@@ -340,6 +340,9 @@
   if (theWinStopCond != NULL)
     theWinStopCond->set_flwor_clause(this);
 
+  if (winKind == tumbling_window)
+    theLazyEval = true;
+
   if (varExpr != NULL && sctx != NULL)
   {
     RootTypeManager& rtm = GENV_TYPESYSTEM;

=== modified file 'src/runtime/core/gflwor/window_iterator.cpp'
--- src/runtime/core/gflwor/window_iterator.cpp	2012-07-11 05:28:20 +0000
+++ src/runtime/core/gflwor/window_iterator.cpp	2012-07-12 14:52:27 +0000
@@ -59,23 +59,23 @@
   Constructor
 ********************************************************************************/
 WindowVars::WindowVars (
-    const std::vector<PlanIter_t >& aCurVars,
-    const std::vector<PlanIter_t >& aPrevVars,
-    const std::vector<PlanIter_t >& aNextVars,
-    const std::vector<PlanIter_t >& aPosVars,
-    const std::vector<PlanIter_t >& aCurOutVars,
-    const std::vector<PlanIter_t >& aPrevOutVars,
-    const std::vector<PlanIter_t >& aNextOutVars,
-    const std::vector<PlanIter_t >& aPosOutVars)
+    const std::vector<PlanIter_t >& curVars,
+    const std::vector<PlanIter_t >& prevVars,
+    const std::vector<PlanIter_t >& nextVars,
+    const std::vector<PlanIter_t >& posVars,
+    const std::vector<PlanIter_t >& curOutVars,
+    const std::vector<PlanIter_t >& prevOutVars,
+    const std::vector<PlanIter_t >& nextOutVars,
+    const std::vector<PlanIter_t >& posOutVars)
 :
-  theCurVars(aCurVars),
-  thePrevVars(aPrevVars),
-  theNextVars(aNextVars),
-  thePosVars(aPosVars),
-  theCurOuterVars(aCurOutVars),
-  thePrevOuterVars(aPrevOutVars),
-  theNextOuterVars(aNextOutVars),
-  thePosOuterVars(aPosOutVars)
+  theCurVars(curVars),
+  thePrevVars(prevVars),
+  theNextVars(nextVars),
+  thePosVars(posVars),
+  theCurOuterVars(curOutVars),
+  thePrevOuterVars(prevOutVars),
+  theNextOuterVars(nextOutVars),
+  thePosOuterVars(posOutVars)
 {
 }
 
@@ -136,57 +136,47 @@
 /*******************************************************************************
   Binds the variables inside the window clause.
 
-  @param aPlanState The PlanState
+  @param planState The PlanState
   @param aInputSeq The underlying input sequence
   @param aPosition The position of the current item within the input sequence
                    (counting starts with 1).
 ********************************************************************************/
 void WindowVars::bindIntern(
-    PlanState& aPlanState,
-    const store::TempSeq_t& aInputSeq,
-    const ulong aPosition) const
+    PlanState& planState,
+    const store::TempSeq_t& inputSeq,
+    const ulong pos) const
 {
-  store::Item_t lItem;
+  store::Item_t item;
 
   if (!theCurVars.empty())
   {
-    aInputSeq->getItem(xs_integer(aPosition), lItem);
-    bindVariables(lItem, theCurVars, aPlanState);
+    inputSeq->getItem(xs_integer(pos), item);
+
+    bindVariables(item, theCurVars, planState);
   }
 
   if (!thePrevVars.empty())
   {
-    if (aPosition > 1)
-    {
-      aInputSeq->getItem(xs_integer(aPosition - 1), lItem);
-    }
+    if (pos > 1)
+      inputSeq->getItem(xs_integer(pos - 1), item);
     else
-    {
-      lItem = 0;
-    }
+      item = NULL;
 
-    bindVariables(lItem, thePrevVars, aPlanState);
+    bindVariables(item, thePrevVars, planState);
   }
 
   if (!theNextVars.empty())
   {
-    if (aInputSeq->containsItem(xs_integer(aPosition + 1)))
-    {
-      aInputSeq->getItem(xs_integer(aPosition + 1), lItem);
-    }
-    else
-    {
-      lItem = 0;
-    }
+    inputSeq->getItem(xs_integer(pos + 1), item);
 
-    bindVariables(lItem, theNextVars, aPlanState);
+    bindVariables(item, theNextVars, planState);
   }
 
   if (!thePosVars.empty())
   {
-    store::Item_t lPosItem;
-    GENV_ITEMFACTORY->createInteger(lPosItem, xs_integer(aPosition));
-    bindVariables(lPosItem, thePosVars, aPlanState);
+    GENV_ITEMFACTORY->createInteger(item, xs_integer(pos));
+
+    bindVariables(item, thePosVars, planState);
   }
 }
 
@@ -194,56 +184,47 @@
 /*******************************************************************************
   Binds the variables outside the window clause.
 
-  @param aPlanState The PlanState
-  @param aInputSeq The underlying input sequence
-  @param aPosition The position of the current item within the input sequence
+  @param planState The PlanState
+  @param inputSeq The underlying input sequence
+  @param pos The position of the current item within the input sequence
                    (counting starts with 1).
 ********************************************************************************/
 void WindowVars::bindExtern(
-    PlanState& aPlanState,
-    const store::TempSeq_t& aInputSeq,
-    const ulong aPosition) const
+    PlanState& planState,
+    const store::TempSeq_t& inputSeq,
+    const ulong pos) const
 {
-  store::Item_t lItem;
+  store::Item_t item;
 
   if (!theCurOuterVars.empty())
   {
-    aInputSeq->getItem(xs_integer(aPosition), lItem);
-    bindVariables(lItem, theCurOuterVars, aPlanState);
+    inputSeq->getItem(xs_integer(pos), item);
+
+    bindVariables(item, theCurOuterVars, planState);
   }
 
   if (!thePrevOuterVars.empty())
   {
-    if (aPosition > 1)
-    {
-      aInputSeq->getItem(xs_integer(aPosition - 1), lItem);
-    }
+    if (pos > 1)
+      inputSeq->getItem(xs_integer(pos - 1), item);
     else
-    {
-      lItem = 0;
-    }
+      item = NULL;
 
-    bindVariables(lItem, thePrevOuterVars, aPlanState);
+    bindVariables(item, thePrevOuterVars, planState);
   }
 
   if (!theNextOuterVars.empty())
   {
-    if (aInputSeq->containsItem(xs_integer(aPosition + 1)))
-    {
-      aInputSeq->getItem(xs_integer(aPosition + 1), lItem);
-    }
-    else
-    {
-      lItem = 0;
-    }
+    inputSeq->getItem(xs_integer(pos + 1), item);
 
-    bindVariables(lItem, theNextOuterVars, aPlanState);
+    bindVariables(item, theNextOuterVars, planState);
   }
 
   if (!thePosOuterVars.empty())
   {
-    GENV_ITEMFACTORY->createInteger(lItem, Integer(aPosition));
-    bindVariables(lItem, thePosOuterVars, aPlanState);
+    GENV_ITEMFACTORY->createInteger(item, Integer(pos));
+
+    bindVariables(item, thePosOuterVars, planState);
   }
 }
 
@@ -305,27 +286,27 @@
 /***************************************************************************//**
 
 ********************************************************************************/
-void StartClause::open(PlanState& aPlanState, uint32_t& aOffset) const
-{
-  theStartClauseIter->open(aPlanState, aOffset);
-}
-
-
-/***************************************************************************//**
-
-********************************************************************************/
-void StartClause::reset(PlanState& aPlanState) const
-{
-  theStartClauseIter->reset(aPlanState);
-}
-
-
-/***************************************************************************//**
-
-********************************************************************************/
-void StartClause::close(PlanState& aPlanState) const
-{
-  theStartClauseIter->close(aPlanState);
+void StartClause::open(PlanState& planState, uint32_t& aOffset) const
+{
+  theStartClauseIter->open(planState, aOffset);
+}
+
+
+/***************************************************************************//**
+
+********************************************************************************/
+void StartClause::reset(PlanState& planState) const
+{
+  theStartClauseIter->reset(planState);
+}
+
+
+/***************************************************************************//**
+
+********************************************************************************/
+void StartClause::close(PlanState& planState) const
+{
+  theStartClauseIter->close(planState);
 }
 
 
@@ -335,13 +316,13 @@
   expr.
 ********************************************************************************/
 bool StartClause::evaluate(
-    PlanState& aPlanState,
-    const store::TempSeq_t& aInputSeq,
-    const ulong aPosition) const
+    PlanState& planState,
+    const store::TempSeq_t& inputSeq,
+    const ulong pos) const
 {
-  theWindowVars.bindIntern(aPlanState, aInputSeq, aPosition);
+  theWindowVars.bindIntern(planState, inputSeq, pos);
 
-  return evalToBool(theStartClauseIter, aPlanState);
+  return evalToBool(theStartClauseIter, planState);
 }
 
 
@@ -351,11 +332,11 @@
   the temp sequence that materializes the result of the domain expr.
 ********************************************************************************/
 void StartClause::bindExtern(
-    PlanState& aPlanState,
-    const store::TempSeq_t& aInputSeq,
-    const ulong aPosition) const
+    PlanState& planState,
+    const store::TempSeq_t& inputSeq,
+    const ulong pos) const
 {
-  theWindowVars.bindExtern(aPlanState, aInputSeq, aPosition);
+  theWindowVars.bindExtern(planState, inputSeq, pos);
 }
 
 
@@ -363,11 +344,11 @@
 
 ********************************************************************************/
 void StartClause::bindIntern(
-    PlanState& aPlanState,
-    const store::TempSeq_t& aInputSeq,
-    const ulong aPosition) const
+    PlanState& planState,
+    const store::TempSeq_t& inputSeq,
+    const ulong pos) const
 {
-  theWindowVars.bindIntern(aPlanState, aInputSeq, aPosition);
+  theWindowVars.bindIntern(planState, inputSeq, pos);
 }
 
 
@@ -456,30 +437,30 @@
 /***************************************************************************//**
 
 ********************************************************************************/
-void EndClause::open(PlanState& aPlanState, uint32_t& aOffset) const
-{
-  if (theHasEndClause)
-    theEndClauseIter->open(aPlanState, aOffset);
-}
-
-
-/***************************************************************************//**
-
-********************************************************************************/
-void EndClause::reset(PlanState& aPlanState) const
-{
-  if (theHasEndClause)
-    theEndClauseIter->reset(aPlanState);
-}
-
-
-/***************************************************************************//**
-
-********************************************************************************/
-void EndClause::close(PlanState& aPlanState) const
-{
-  if (theHasEndClause)
-    theEndClauseIter->close(aPlanState);
+void EndClause::open(PlanState& planState, uint32_t& aOffset) const
+{
+  if (theHasEndClause)
+    theEndClauseIter->open(planState, aOffset);
+}
+
+
+/***************************************************************************//**
+
+********************************************************************************/
+void EndClause::reset(PlanState& planState) const
+{
+  if (theHasEndClause)
+    theEndClauseIter->reset(planState);
+}
+
+
+/***************************************************************************//**
+
+********************************************************************************/
+void EndClause::close(PlanState& planState) const
+{
+  if (theHasEndClause)
+    theEndClauseIter->close(planState);
 }
 
 
@@ -487,13 +468,13 @@
 
 ********************************************************************************/
 bool EndClause::evaluate(
-    PlanState& aPlanState,
-    const store::TempSeq_t& aInputSeq,
-    const ulong aPosition) const
+    PlanState& planState,
+    const store::TempSeq_t& inputSeq,
+    const ulong pos) const
 {
-  theWindowVars.bindIntern(aPlanState, aInputSeq, aPosition);
+  theWindowVars.bindIntern(planState, inputSeq, pos);
 
-  return evalToBool(theEndClauseIter, aPlanState);
+  return evalToBool(theEndClauseIter, planState);
 }
 
 
@@ -501,11 +482,11 @@
 
 ********************************************************************************/
 void EndClause::bindIntern(
-    PlanState& aPlanState,
-    const store::TempSeq_t& aInputSeq,
-    const ulong aPosition) const
+    PlanState& planState,
+    const store::TempSeq_t& inputSeq,
+    const ulong pos) const
 {
-  theWindowVars.bindIntern(aPlanState, aInputSeq, aPosition);
+  theWindowVars.bindIntern(planState, inputSeq, pos);
 }
 
 
@@ -513,11 +494,11 @@
 
 ********************************************************************************/
 void EndClause::bindExtern(
-    PlanState& aPlanState,
-    const store::TempSeq_t& aInputSeq,
-    const ulong aPosition) const
+    PlanState& planState,
+    const store::TempSeq_t& inputSeq,
+    const ulong pos) const
 {
-  theWindowVars.bindExtern(aPlanState, aInputSeq, aPosition);
+  theWindowVars.bindExtern(planState, inputSeq, pos);
 }
 
 
@@ -561,9 +542,9 @@
 }
 
 
-void WindowState::reset(PlanState& aPlanState)
+void WindowState::reset(PlanState& planState)
 {
-  PlanIteratorState::reset(aPlanState);
+  PlanIteratorState::reset(planState);
   theCurInputPos = 1;
   theDomainSeq = NULL;
   theOpenWindows.clear();
@@ -607,6 +588,9 @@
   theMaxNeededHistory(maxNeededHistory)
 {
   castIterVector<LetVarIterator>(theVarRefs, varRefs);
+
+  if (theWindowType == TUMBLING)
+    theMaxNeededHistory = 1;
 }
 
 
@@ -685,44 +669,44 @@
 /***************************************************************************//**
 
 ********************************************************************************/
-void WindowIterator::openImpl(PlanState& aPlanState, uint32_t& aOffset)
+void WindowIterator::openImpl(PlanState& planState, uint32_t& aOffset)
 {
-  StateTraitsImpl<WindowState>::createState(aPlanState, theStateOffset, aOffset);
-
-  theTupleIter->open(aPlanState, aOffset);
-  theInputIter->open(aPlanState, aOffset);
-
-  theStartClause.open(aPlanState, aOffset);
-  theEndClause.open(aPlanState, aOffset);
+  StateTraitsImpl<WindowState>::createState(planState, theStateOffset, aOffset);
+
+  theTupleIter->open(planState, aOffset);
+  theInputIter->open(planState, aOffset);
+
+  theStartClause.open(planState, aOffset);
+  theEndClause.open(planState, aOffset);
 }
 
 
 /***************************************************************************//**
 
 ********************************************************************************/
-void WindowIterator::resetImpl(PlanState& aPlanState) const
+void WindowIterator::resetImpl(PlanState& planState) const
 {
-  WindowState* lState = StateTraitsImpl<WindowState>::getState(aPlanState,
+  WindowState* lState = StateTraitsImpl<WindowState>::getState(planState,
                                                                theStateOffset);
-  lState->reset(aPlanState);
+  lState->reset(planState);
 
-  theTupleIter->reset(aPlanState);
-  theInputIter->reset(aPlanState);
-  theStartClause.reset(aPlanState);
-  theEndClause.reset(aPlanState);
+  theTupleIter->reset(planState);
+  theInputIter->reset(planState);
+  theStartClause.reset(planState);
+  theEndClause.reset(planState);
 }
 
 
 /***************************************************************************//**
 
 ********************************************************************************/
-void WindowIterator::closeImpl(PlanState& aPlanState)
+void WindowIterator::closeImpl(PlanState& planState)
 {
-  theTupleIter->close(aPlanState);
-  theInputIter->close(aPlanState);
-  theStartClause.close(aPlanState);
-  theEndClause.close(aPlanState);
-  StateTraitsImpl<WindowState>::destroyState(aPlanState, theStateOffset);
+  theTupleIter->close(planState);
+  theInputIter->close(planState);
+  theStartClause.close(planState);
+  theEndClause.close(planState);
+  StateTraitsImpl<WindowState>::destroyState(planState, theStateOffset);
 }
 
 
@@ -731,8 +715,8 @@
   of the domain sequence.
 ********************************************************************************/
 void WindowIterator::bindVariable(
-    PlanState& aPlanState,
-    store::TempSeq_t& aInputSeq,
+    PlanState& planState,
+    store::TempSeq_t& inputSeq,
     ulong aStartPos,
     ulong aEndPos) const
 {
@@ -743,7 +727,7 @@
        lVarIter != theVarRefs.end();
        ++lVarIter)
   {
-    (*lVarIter)->bind(aInputSeq, aPlanState, lStartPos, lEndPos);
+    (*lVarIter)->bind(inputSeq, planState, lStartPos, lEndPos);
   }
 }
 
@@ -759,11 +743,14 @@
     if (lState->theOpenWindows.empty())
     {
       if (lState->theCurInputPos > theMaxNeededHistory)
-        lState->theDomainSeq->purgeUpTo(xs_integer(lState->theCurInputPos - theMaxNeededHistory));
+        lState->theDomainSeq->
+        purgeUpTo(xs_integer(lState->theCurInputPos - theMaxNeededHistory));
     }
     else
     {
-      int32_t lPurgeTo = lState->theOpenWindows.front().theStartPos - theMaxNeededHistory;
+      int64_t lPurgeTo =
+      lState->theOpenWindows.front().theStartPos - theMaxNeededHistory;
+
       if (lPurgeTo > 0)
         lState->theDomainSeq->purgeUpTo(xs_integer(lPurgeTo));
     }
@@ -774,71 +761,72 @@
 /***************************************************************************//**
 
 ********************************************************************************/
-bool WindowIterator::nextImpl(store::Item_t& aResult, PlanState& aPlanState) const
+bool WindowIterator::nextImpl(store::Item_t& aResult, PlanState& planState) const
 {
   store::Iterator_t iterator;
-  WindowState* lState;
-  DEFAULT_STACK_INIT(WindowState, lState, aPlanState);
+
+  WindowState* state;
+  DEFAULT_STACK_INIT(WindowState, state, planState);
 
   // Pull the next tuple from the input stream
-  while (consumeNext(aResult, theTupleIter, aPlanState))
+  while (consumeNext(aResult, theTupleIter, planState))
   {
     // Create the temp sequence where to materialize the result of the domain
     // expr (lazily if theLazyEval flag is true).
-    iterator = new PlanIteratorWrapper(theInputIter, aPlanState);
-    lState->theDomainSeq = GENV_STORE.createTempSeq(iterator, theLazyEval);
+    iterator = new PlanIteratorWrapper(theInputIter, planState);
+    state->theDomainSeq = GENV_STORE.createTempSeq(iterator, theLazyEval);
 
     // Its clever to switch quite early to avoid a lot of if-else statements
     if (theWindowType == WindowIterator::SLIDING)
     {
       // Get the next item from the domain sequence
       // TODO: can the xs_integer be hoisted?
-      while (lState->theDomainSeq->containsItem(xs_integer(lState->theCurInputPos)))
+      while (state->theDomainSeq->containsItem(xs_integer(state->theCurInputPos)))
       {
         // If the current item satisfies the start condition, create a candidate
         // window starting at the current domain item.
-        if (theStartClause.evaluate(aPlanState,
-                                    lState->theDomainSeq,
-                                    lState->theCurInputPos))
+        if (theStartClause.evaluate(planState,
+                                    state->theDomainSeq,
+                                    state->theCurInputPos))
         {
-          lState->theOpenWindows.push_back(WindowDef(lState->theCurInputPos));
+          state->theOpenWindows.push_back(WindowDef(state->theCurInputPos));
         }
 
         // For each candidate window, check if the current domain item satisfies
         // the end condition. Notice that before evaluating the end condition
         // expr, we must rebind the internal vars of the start condition, because
         // those varaibles may be refrenced in the end cond expr.
-        lState->theCurWindow = lState->theOpenWindows.begin();
+        state->theCurWindow = state->theOpenWindows.begin();
 
-        while ( lState->theCurWindow != lState->theOpenWindows.end() )
+        while ( state->theCurWindow != state->theOpenWindows.end() )
         {
-          if (lState->theCurWindow->theEndPos == 0)
+          if (state->theCurWindow->theEndPos == 0)
           {
-            theStartClause.bindIntern(aPlanState,
-                                      lState->theDomainSeq,
-                                      lState->theCurWindow->theStartPos);
+            theStartClause.bindIntern(planState,
+                                      state->theDomainSeq,
+                                      state->theCurWindow->theStartPos);
 
-            ulong lCurPos = lState->theCurInputPos;
-            if ( theEndClause.evaluate(aPlanState,
-                                       lState->theDomainSeq,
+            ulong lCurPos = state->theCurInputPos;
+            if ( theEndClause.evaluate(planState,
+                                       state->theDomainSeq,
                                        lCurPos))
             {
-              lState->theCurWindow->theEndPos = lCurPos;
+              state->theCurWindow->theEndPos = lCurPos;
             }
           }
 
-          ++lState->theCurWindow;
+          ++state->theCurWindow;
         }
 
         // Try to return closed windows to the consumer iterator. Notice that
         // windows must be sorted according to the position of their starting
         // items in the domain sequence. So, we can return a closed window only
-        // if it appears as the first window in lState->theOpenWindows.
-        lState->theCurWindow = lState->theOpenWindows.begin();
+        // if it appears as the first window in state->theOpenWindows.
+        state->theCurWindow = state->theOpenWindows.begin();
 
-        while (!lState->theOpenWindows.empty())
+        while (!state->theOpenWindows.empty())
         {
-          if (lState->theCurWindow->theEndPos != 0)
+          if (state->theCurWindow->theEndPos != 0)
           {
             // The current window is closed and its starting item is before the
             // stating items of all other windows (open or closed) in the domain
@@ -849,23 +837,24 @@
             // evaluations of the start and/or end conditions, and (d) return to
             // the caller a new tuple that consists of the current input tuple
             // augmented with one column per variable that was bound in this step.
-            theStartClause.bindExtern(aPlanState,
-                                      lState->theDomainSeq,
-                                      lState->theCurWindow->theStartPos);
-
-            theEndClause.bindExtern(aPlanState,
-                                    lState->theDomainSeq,
-                                    lState->theCurWindow->theEndPos);
-
-            bindVariable(aPlanState,
-                         lState->theDomainSeq,
-                         lState->theCurWindow->theStartPos,
-                         lState->theCurWindow->theEndPos);
-
-            lState->theCurWindow = lState->theOpenWindows.erase(lState->theCurWindow);
-            doGarbageCollection(lState);
-
-            STACK_PUSH(true, lState);
+            theStartClause.bindExtern(planState,
+                                      state->theDomainSeq,
+                                      state->theCurWindow->theStartPos);
+
+            theEndClause.bindExtern(planState,
+                                    state->theDomainSeq,
+                                    state->theCurWindow->theEndPos);
+
+            bindVariable(planState,
+                         state->theDomainSeq,
+                         state->theCurWindow->theStartPos,
+                         state->theCurWindow->theEndPos);
+
+            state->theCurWindow = state->theOpenWindows.erase(state->theCurWindow);
+
+            //doGarbageCollection(state);
+
+            STACK_PUSH(true, state);
           }
           else
           {
@@ -873,7 +862,7 @@
           }
         }
 
-        ++lState->theCurInputPos;
+        ++state->theCurInputPos;
       }
     }
     else //Tumpling window
@@ -881,123 +870,126 @@
       // Doing this switch now also avoids further overhad
       if (theEndClause.theHasEndClause)
       {
-        // TODO: can the xs_integer be hoisted?
-        while (lState->theDomainSeq->containsItem(xs_integer(lState->theCurInputPos)))
+        while (state->theDomainSeq->containsItem(xs_integer(state->theCurInputPos)))
         {
-          if (lState->theOpenWindows.empty() &&
-              theStartClause.evaluate(aPlanState,
-                                      lState->theDomainSeq,
-                                      lState->theCurInputPos))
-          {
-            theStartClause.bindExtern(aPlanState,
-                                      lState->theDomainSeq,
-                                      lState->theCurInputPos);
-
-            lState->theOpenWindows.push_back(lState->theCurInputPos);
-          }
-
-          if ( !lState->theOpenWindows.empty() &&
-               theEndClause.evaluate(aPlanState,
-                                     lState->theDomainSeq,
-                                     lState->theCurInputPos))
-          {
-            theEndClause.bindExtern(aPlanState,
-                                    lState->theDomainSeq,
-                                    lState->theCurInputPos);
-
-            bindVariable(aPlanState,
-                         lState->theDomainSeq,
-                         lState->theOpenWindows[0].theStartPos,
-                         lState->theCurInputPos);
-
-            lState->theOpenWindows.pop_back();
-
-            assert(lState->theOpenWindows.empty());
-
-            doGarbageCollection(lState);
-
-            STACK_PUSH(true, lState);
-          }
-          ++lState->theCurInputPos;
+          if (state->theOpenWindows.empty() &&
+              theStartClause.evaluate(planState,
+                                      state->theDomainSeq,
+                                      state->theCurInputPos))
+          {
+            theStartClause.bindExtern(planState,
+                                      state->theDomainSeq,
+                                      state->theCurInputPos);
+
+            state->theOpenWindows.push_back(state->theCurInputPos);
+          }
+
+          if ( !state->theOpenWindows.empty() &&
+               theEndClause.evaluate(planState,
+                                     state->theDomainSeq,
+                                     state->theCurInputPos))
+          {
+            theEndClause.bindExtern(planState,
+                                    state->theDomainSeq,
+                                    state->theCurInputPos);
+
+            bindVariable(planState,
+                         state->theDomainSeq,
+                         state->theOpenWindows[0].theStartPos,
+                         state->theCurInputPos);
+
+            state->theOpenWindows.pop_back();
+
+            assert(state->theOpenWindows.empty());
+
+            STACK_PUSH(true, state);
+
+            doGarbageCollection(state);
+          }
+
+          ++state->theCurInputPos;
         }
       }
       else
       {
-        // TODO: can the xs_integer be hoisted?
-        while (lState->theDomainSeq->containsItem(xs_integer(lState->theCurInputPos)))
+        while (state->theDomainSeq->containsItem(xs_integer(state->theCurInputPos)))
         {
-          if (theStartClause.evaluate(aPlanState,
-                                      lState->theDomainSeq,
-                                      lState->theCurInputPos))
+          if (theStartClause.evaluate(planState,
+                                      state->theDomainSeq,
+                                      state->theCurInputPos))
           {
-            if (!lState->theOpenWindows.empty())
+            if (!state->theOpenWindows.empty())
             {
               //In no case there should be more than 1 position inside
-              assert(lState->theOpenWindows.size() == 1);
-
-              theStartClause.bindExtern(aPlanState,
-                                        lState->theDomainSeq,
-                                        lState->theOpenWindows[0].theStartPos);
-
-              bindVariable(aPlanState,
-                           lState->theDomainSeq,
-                           lState->theOpenWindows[0].theStartPos,
-                           lState->theCurInputPos  -1);
-
-              lState->theOpenWindows.pop_back();
-
-              doGarbageCollection(lState);
-
-              STACK_PUSH(true, lState);
+              assert(state->theOpenWindows.size() == 1);
+
+              theStartClause.bindExtern(planState,
+                                        state->theDomainSeq,
+                                        state->theOpenWindows[0].theStartPos);
+
+              bindVariable(planState,
+                           state->theDomainSeq,
+                           state->theOpenWindows[0].theStartPos,
+                           state->theCurInputPos  - 1);
+
+              state->theOpenWindows.pop_back();
+
+              assert(state->theOpenWindows.empty());
+
+              STACK_PUSH(true, state);
+
+              --state->theCurInputPos;
+              doGarbageCollection(state);
+              ++state->theCurInputPos;
             }
 
-            lState->theOpenWindows.push_back(lState->theCurInputPos);
+            state->theOpenWindows.push_back(state->theCurInputPos);
           }
 
-          ++lState->theCurInputPos;
+          ++state->theCurInputPos;
         }
       }
     }
 
     // Check if we have open and/or closed windows
-    lState->theCurWindow = lState->theOpenWindows.begin();
+    state->theCurWindow = state->theOpenWindows.begin();
 
-    while (lState->theCurWindow != lState->theOpenWindows.end())
+    while (state->theCurWindow != state->theOpenWindows.end())
     {
-      if (!theEndClause.theOnlyEnd || lState->theCurWindow->theEndPos != 0)
+      if (!theEndClause.theOnlyEnd || state->theCurWindow->theEndPos != 0)
       {
-        if (lState->theCurWindow->theEndPos == 0)
-          lState->theCurWindow->theEndPos = lState->theCurInputPos - 1;
-
-        bindVariable(aPlanState,
-                     lState->theDomainSeq,
-                     lState->theOpenWindows[0].theStartPos,
-                     lState->theCurWindow->theEndPos);
-
-        theStartClause.bindExtern(aPlanState,
-                                  lState->theDomainSeq,
-                                  lState->theOpenWindows[0].theStartPos);
-
-        theEndClause.bindExtern(aPlanState,
-                                lState->theDomainSeq,
-                                lState->theCurWindow->theEndPos);
-
-        lState->theCurWindow = lState->theOpenWindows.erase(lState->theCurWindow);
-
-        STACK_PUSH(true, lState);
+        if (state->theCurWindow->theEndPos == 0)
+          state->theCurWindow->theEndPos = state->theCurInputPos - 1;
+
+        bindVariable(planState,
+                     state->theDomainSeq,
+                     state->theOpenWindows[0].theStartPos,
+                     state->theCurWindow->theEndPos);
+
+        theStartClause.bindExtern(planState,
+                                  state->theDomainSeq,
+                                  state->theOpenWindows[0].theStartPos);
+
+        theEndClause.bindExtern(planState,
+                                state->theDomainSeq,
+                                state->theCurWindow->theEndPos);
+
+        state->theCurWindow = state->theOpenWindows.erase(state->theCurWindow);
+
+        STACK_PUSH(true, state);
       }
       else
       {
-        ++lState->theCurWindow;
+        ++state->theCurWindow;
       }
     }
 
-    theInputIter->reset(aPlanState);
-    lState->reset(aPlanState);
+    theInputIter->reset(planState);
+    state->reset(planState);
   }
 
-  STACK_PUSH(false, lState);
-  STACK_END(lState);
+  STACK_PUSH(false, state);
+  STACK_END(state);
 }
 
   } //Namespace flwor

=== modified file 'src/runtime/core/trycatch.cpp'
--- src/runtime/core/trycatch.cpp	2012-07-11 04:46:41 +0000
+++ src/runtime/core/trycatch.cpp	2012-07-12 14:52:27 +0000
@@ -77,17 +77,22 @@
 TryCatchIteratorState::reset(PlanState& planState) 
 {
   PlanIteratorState::reset(planState);
+
   if ( theTargetSequence )
     theTargetSequence->purge(); // release the target sequence
-  if (theTempIterator != NULL) {
+
+  if (theTempIterator != NULL)
+  {
     theTempIterator->close();
     theTempIterator = NULL;
   }
+
   theCatchIterator = NULL;
 
   std::vector<store::Iterator_t>::iterator lIters = theErrorIters.begin();
   std::vector<store::Iterator_t>::iterator lItersEnd = theErrorIters.end();
-  for (; lIters != lItersEnd; ++lIters) {
+  for (; lIters != lItersEnd; ++lIters)
+  {
     (*lIters)->close();
   }
 
@@ -521,6 +526,7 @@
   }
 }
 
+
 bool
 TryCatchIterator::nextImpl(store::Item_t& result, PlanState& planState) const
 {
@@ -579,15 +585,20 @@
 
   theChild->reset(planState);
 
-  std::vector<TryCatchIterator::CatchClause>::const_iterator lIter = theCatchClauses.begin();
-  std::vector<TryCatchIterator::CatchClause>::const_iterator lEnd = theCatchClauses.end();
-
-  for ( ; lIter != lEnd; ++lIter ) {
+  std::vector<TryCatchIterator::CatchClause>::const_iterator lIter =
+  theCatchClauses.begin();
+
+  std::vector<TryCatchIterator::CatchClause>::const_iterator lEnd =
+  theCatchClauses.end();
+
+  for ( ; lIter != lEnd; ++lIter )
+  {
     ( *lIter ).catch_expr->reset(planState);
   }
 
 }
 
+
 void
 TryCatchIterator::closeImpl(PlanState& planState)
 {
@@ -603,7 +614,9 @@
   StateTraitsImpl<TryCatchIteratorState>::destroyState(planState, theStateOffset);
 }
 
-void TryCatchIterator::accept(PlanIterVisitor &v) const {
+
+void TryCatchIterator::accept(PlanIterVisitor &v) const
+{
   v.beginVisit(*this);
   theChild->accept ( v );
   std::vector<TryCatchIterator::CatchClause>::const_iterator lIter = theCatchClauses.begin();

=== modified file 'src/runtime/core/trycatch.h'
--- src/runtime/core/trycatch.h	2012-07-11 04:46:41 +0000
+++ src/runtime/core/trycatch.h	2012-07-12 14:52:27 +0000
@@ -36,9 +36,11 @@
   void reset(PlanState&);
 
   // used for evaluating the target expression eagerly
-  store::TempSeq_t  theTargetSequence;
-  store::Iterator_t theTempIterator;
-  PlanIter_t theCatchIterator;
+  store::TempSeq_t               theTargetSequence;
+
+  store::Iterator_t              theTempIterator;
+
+  PlanIter_t                     theCatchIterator;
 
   std::vector<store::Iterator_t> theErrorIters;
 };
@@ -119,8 +121,9 @@
   void resetImpl(PlanState& planState) const;
   void closeImpl(PlanState& planState);
 
-  virtual void accept(PlanIterVisitor& v) const;
-  virtual uint32_t getStateSizeOfSubtree() const;
+  void accept(PlanIterVisitor& v) const;
+
+  uint32_t getStateSizeOfSubtree() const;
 
 protected:
   bool matchedCatch(

=== modified file 'src/runtime/core/var_iterators.cpp'
--- src/runtime/core/var_iterators.cpp	2012-07-11 04:46:41 +0000
+++ src/runtime/core/var_iterators.cpp	2012-07-12 14:52:27 +0000
@@ -578,7 +578,8 @@
     else if (state->theTempSeq != NULL)
     {
       if (state->theSourceIter == NULL)
-        state->theSourceIter = GENV_STORE.getIteratorFactory()->createTempSeqIterator();
+        state->theSourceIter = GENV_STORE.getIteratorFactory()->
+        createTempSeqIterator(false);
 
       state->theSourceIter->init(state->theTempSeq);
       state->theSourceIter->open();
@@ -800,7 +801,8 @@
     else
     {
       if (state->theTempSeqIter == NULL)
-        state->theTempSeqIter = GENV_STORE.getIteratorFactory()->createTempSeqIterator();
+        state->theTempSeqIter = GENV_STORE.getIteratorFactory()->
+                                createTempSeqIterator(false);
 
       state->theTempSeqIter->init(value);
       state->theTempSeqIter->open();
@@ -832,7 +834,8 @@
     else
     {
       if (state->theTempSeqIter == NULL)
-        state->theTempSeqIter = GENV_STORE.getIteratorFactory()->createTempSeqIterator();
+        state->theTempSeqIter = GENV_STORE.getIteratorFactory()->
+        createTempSeqIterator(value->isLazy());
 
       state->theTempSeqIter->init(value, startPos, endPos);
       state->theTempSeqIter->open();

=== modified file 'src/store/api/iterator.h'
--- src/store/api/iterator.h	2012-07-11 04:46:41 +0000
+++ src/store/api/iterator.h	2012-07-12 14:52:27 +0000
@@ -207,8 +207,6 @@
 
   virtual void open() = 0;
   
-  virtual Item* next() = 0;
-  
   virtual bool next(Item_t& result) = 0;
   
   virtual void reset() = 0;

=== modified file 'src/store/api/iterator_factory.h'
--- src/store/api/iterator_factory.h	2012-07-11 04:46:41 +0000
+++ src/store/api/iterator_factory.h	2012-07-12 14:52:27 +0000
@@ -62,7 +62,7 @@
    * Create an iterator to iterate over the items of a temp sequence.
    */
   virtual TempSeqIterator*
-  createTempSeqIterator() = 0;
+  createTempSeqIterator(bool lazy) = 0;
 };
 
 

=== modified file 'src/store/api/temp_seq.h'
--- src/store/api/temp_seq.h	2012-07-11 04:46:41 +0000
+++ src/store/api/temp_seq.h	2012-07-12 14:52:27 +0000
@@ -36,6 +36,18 @@
 public:
   virtual ~TempSeq(){}
 
+  virtual bool isLazy() const = 0;
+
+  /**
+   * @return Does this TempSeq save an empty sequence? 
+   */
+  virtual bool empty() = 0;
+
+  /**
+   *
+   */
+  virtual xs_integer getSize() const = 0;
+
   /**
    * Initializes a temp sequence with the given input iterator
    */
@@ -63,12 +75,7 @@
    * 
    * @param upTo boundary for garbage collector
    */
-  virtual void purgeUpTo(xs_integer upTo) = 0;
-
-  /**
-   * @return Does this TempSeq save an empty sequence? 
-   */
-  virtual bool empty() = 0;
+  virtual void purgeUpTo(xs_integer pos) = 0;
 
   /**
    * Gets an item at a certain position.
@@ -78,7 +85,7 @@
    * @param position (first position in XQuery is 1 and not 0!)
    * @return item
    */
-  virtual void getItem(xs_integer position, Item_t& result) = 0;
+  virtual void getItem(xs_integer pos, Item_t& result) = 0;
 		
   /**
    * Returns true if the item at the passed position is available.
@@ -88,12 +95,7 @@
    * @param position 
    * @return 
    */
-  virtual bool containsItem(xs_integer position) = 0;
-
-  /**
-   *
-   */
-  virtual xs_integer getSize() const = 0;
+  virtual bool containsItem(xs_integer pos) = 0;
 
   /**
    * Reads the whole Sequence from beginning to end; it is allowed to have several 
@@ -104,18 +106,6 @@
    */
   virtual Iterator_t getIterator() const = 0;
 	
-  /**
-   * Returns an iterator which reads just a part of the underlying TempSeq
-   * Starts counting with 1.
-   *
-   * @param startPos The first item which the iterator returns. Starts counting with 1.
-   * @param endPos The last item which the iterator returns 
-   * @return Iterator
-   */
-  virtual Iterator_t getIterator(
-      xs_integer startPos,
-      xs_integer endPos,
-      bool streaming = false) const = 0;
 };
 
 } // namespace store

=== modified file 'src/store/naive/simple_iterator_factory.cpp'
--- src/store/naive/simple_iterator_factory.cpp	2012-07-11 04:46:41 +0000
+++ src/store/naive/simple_iterator_factory.cpp	2012-07-12 14:52:27 +0000
@@ -19,6 +19,7 @@
 #include "simple_iterator_factory.h"
 #include "node_iterators.h"
 #include "simple_temp_seq.h"
+#include "simple_lazy_temp_seq.h"
 #include "simple_index.h"
 #include "simple_index_value.h"
 #include "simple_index_general.h"
@@ -83,9 +84,12 @@
 /*******************************************************************************
 
 ********************************************************************************/
-store::TempSeqIterator* SimpleIteratorFactory::createTempSeqIterator()
+store::TempSeqIterator* SimpleIteratorFactory::createTempSeqIterator(bool lazy)
 {
-  return new SimpleTempSeqIter();
+  if (lazy)
+    return new SimpleLazyTempSeqIter();
+  else
+     return new SimpleTempSeqIter();
 }
 
 

=== modified file 'src/store/naive/simple_iterator_factory.h'
--- src/store/naive/simple_iterator_factory.h	2012-07-11 04:46:41 +0000
+++ src/store/naive/simple_iterator_factory.h	2012-07-12 14:52:27 +0000
@@ -39,7 +39,7 @@
 
   store::IndexProbeIterator* createIndexProbeIterator(const store::Index_t& index);
 
-  store::TempSeqIterator* createTempSeqIterator();
+  store::TempSeqIterator* createTempSeqIterator(bool lazy);
 };
 
 }

=== modified file 'src/store/naive/simple_lazy_temp_seq.cpp'
--- src/store/naive/simple_lazy_temp_seq.cpp	2012-07-11 04:46:41 +0000
+++ src/store/naive/simple_lazy_temp_seq.cpp	2012-07-12 14:52:27 +0000
@@ -33,9 +33,9 @@
 /*******************************************************************************
 
 ********************************************************************************/
-SimpleLazyTempSeq::SimpleLazyTempSeq(const store::Iterator_t& aIter)
+SimpleLazyTempSeq::SimpleLazyTempSeq(const store::Iterator_t& iter)
 {
-  init(aIter);
+  init(iter);
 }
 
 
@@ -44,66 +44,42 @@
 ********************************************************************************/
 SimpleLazyTempSeq::~SimpleLazyTempSeq()
 {
+  clear();
 }
 
 
 /*******************************************************************************
 
 ********************************************************************************/
-void SimpleLazyTempSeq::init(const store::Iterator_t& aIter)
+void SimpleLazyTempSeq::clear()
 {
-  theIterator = aIter;
-  theMatFinished = false;
-  thePurgedUpTo = 0;
+  std::vector<store::Item*>::iterator ite = theItems.begin();
+  std::vector<store::Item*>::iterator end = theItems.end();
+  for (; ite != end; ++ite)
+  {
+    (*ite)->removeReference();
+  }
+
   theItems.clear();
 }
 
 
 /*******************************************************************************
-
-********************************************************************************/
-void SimpleLazyTempSeq::append(const store::Iterator_t& iter)
-{
-  while (!theMatFinished)
-  {
-    matNextItem();
-  }
-
-  theMatFinished = false;
-  theIterator = iter;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-void SimpleLazyTempSeq::purge()
-{
-  //Not supported
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-void SimpleLazyTempSeq::purgeUpTo(xs_integer upTo)
-{
-  xs_long lUpTo;
-  try 
-  {
-    lUpTo = to_xs_long(upTo);
-  }
-  catch (std::range_error& e)
-  {
-    throw ZORBA_EXCEPTION(zerr::ZSTR0060_RANGE_EXCEPTION,
-    ERROR_PARAMS(BUILD_STRING("sequence too big (" << e.what() << ")")));
-  }
-
-  ZORBA_ASSERT(lUpTo >= thePurgedUpTo);
-  ZORBA_ASSERT(lUpTo - thePurgedUpTo <= theItems.size());
-
-  theItems.erase(theItems.begin(), (theItems.begin() + (lUpTo - thePurgedUpTo)));
-  thePurgedUpTo = lUpTo;
+  Get the next item (if any) from the input iterator and put it at the end of 
+  the queue.  
+********************************************************************************/
+void SimpleLazyTempSeq::matNextItem() 
+{
+  store::Item_t item;
+
+  if (! theIterator->next(item)) 
+  {
+    theMatFinished = true;
+  }
+  else
+  {
+    theItems.push_back(item.release());
+  }
 }
 
 
@@ -134,12 +110,97 @@
 /*******************************************************************************
 
 ********************************************************************************/
+xs_integer SimpleLazyTempSeq::getSize() const
+{
+  ZORBA_ASSERT(false);
+  return xs_integer(thePurgedUpTo + theItems.size());
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void SimpleLazyTempSeq::init(const store::Iterator_t& iter)
+{
+  theIterator = iter;
+
+  theMatFinished = false;
+  thePurgedUpTo = 0;
+
+  clear();
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void SimpleLazyTempSeq::append(const store::Iterator_t& iter)
+{
+  while (!theMatFinished)
+  {
+    matNextItem();
+  }
+
+  theMatFinished = false;
+  theIterator = iter;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void SimpleLazyTempSeq::purge()
+{
+  theIterator = NULL;
+
+  theMatFinished = false;
+  thePurgedUpTo = 0;
+
+  clear();
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void SimpleLazyTempSeq::purgeUpTo(xs_integer position)
+{
+  xs_long pos;
+  try 
+  {
+    pos = to_xs_long(position);
+  }
+  catch (std::range_error& e)
+  {
+    throw ZORBA_EXCEPTION(zerr::ZSTR0060_RANGE_EXCEPTION,
+    ERROR_PARAMS(BUILD_STRING("sequence too big (" << e.what() << ")")));
+  }
+
+  ZORBA_ASSERT(pos >= thePurgedUpTo);
+  ZORBA_ASSERT(pos - thePurgedUpTo <= theItems.size());
+
+  std::vector<store::Item*>::iterator ite = theItems.begin();
+  std::vector<store::Item*>::iterator end = theItems.begin() + (pos - thePurgedUpTo);
+  for (; ite != end; ++ite)
+  {
+    (*ite)->removeReference();
+  }
+
+  theItems.erase(theItems.begin(), end);
+
+  thePurgedUpTo = pos;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 void SimpleLazyTempSeq::getItem(xs_integer position, store::Item_t& result)
 {
-  xs_long lPos;
+  xs_long pos;
   try 
   {
-    lPos = to_xs_long(position);
+    pos = to_xs_long(position);
   }
   catch (std::range_error& e)
   {
@@ -147,9 +208,18 @@
     ERROR_PARAMS(BUILD_STRING("access out of bounds " << e.what() << ")")));
   }
 
-  if (this->containsItem(position)) 
-  {
-    result = theItems[lPos - thePurgedUpTo - 1];
+  ZORBA_ASSERT(pos > thePurgedUpTo);
+
+  xs_long numItemsToBuffer = pos - thePurgedUpTo;
+
+  while (!theMatFinished && theItems.size() <  numItemsToBuffer) 
+  {
+    matNextItem();
+  }
+
+  if (theItems.size() >= numItemsToBuffer)
+  {
+    result = theItems[pos - thePurgedUpTo - 1];
   }
   else 
   {
@@ -180,10 +250,10 @@
 ********************************************************************************/
 inline bool SimpleLazyTempSeq::containsItem(xs_integer position) 
 {
-  xs_long lPos;
+  xs_long pos;
   try 
   {
-    lPos = to_xs_long(position);
+    pos = to_xs_long(position);
   }
   catch (std::range_error& e)
   {
@@ -191,9 +261,9 @@
     ERROR_PARAMS(BUILD_STRING("access out of bounds " << e.what() << ")")));
   }
 
-  assert(lPos > thePurgedUpTo);
+  ZORBA_ASSERT(pos > thePurgedUpTo);
 
-  xs_long numItemsToBuffer = lPos - thePurgedUpTo;
+  xs_long numItemsToBuffer = pos - thePurgedUpTo;
 
   while (!theMatFinished && theItems.size() <  numItemsToBuffer) 
   {
@@ -205,44 +275,6 @@
 
 
 /*******************************************************************************
-  Get the next item (if any) from the input iterator and put it at the end of 
-  the queue.  
-********************************************************************************/
-void SimpleLazyTempSeq::matNextItem() 
-{
-  theItems.push_back(NULL);
-
-  store::Item_t& lLocation = theItems.back();
-
-  if (theIterator->next(lLocation)) 
-  {
-    if (theCopy && lLocation->isNode()) 
-    {
-      store::CopyMode lCopyMode;
-      lLocation = lLocation->copy(NULL, lCopyMode);
-    }
-  }
-  else 
-  {
-    // We do not want to have an empty item materialized.
-    theItems.pop_back();
-    theMatFinished = true;
-    theIterator->close();
-  }
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-xs_integer SimpleLazyTempSeq::getSize() const
-{
-  ZORBA_ASSERT(false);
-  return xs_integer(0);
-}
-
-
-/*******************************************************************************
   Reads the whole Sequence from beginning to end; it is allowed to have several
   concurrent iterators on the same TempSeq.
 
@@ -250,23 +282,28 @@
 ********************************************************************************/
 store::Iterator_t SimpleLazyTempSeq::getIterator() const
 {
-  return new SimpleLazyTempSeqIter(this, xs_integer(1), xs_integer(std::numeric_limits<long>::max()));
+  return new SimpleLazyTempSeqIter(this,
+                                   xs_integer(1),
+                                   xs_integer(std::numeric_limits<long>::max()));
 }
 
 
+/////////////////////////////////////////////////////////////////////////////////
+//                                                                             //
+//  SimpleLazyTempSeqIter                                                      //
+//                                                                             //
+/////////////////////////////////////////////////////////////////////////////////
+
+
 /*******************************************************************************
-  Returns an iterator which reads just a part of the underlying TempSeq
 
-  @param startPos The first item which the iterator returns
-  @param endPos The last item which the iterator returns
-  @return Iterator
 ********************************************************************************/
-store::Iterator_t SimpleLazyTempSeq::getIterator(
-    xs_integer startPos,
-    xs_integer endPos,
-    bool streaming) const
+SimpleLazyTempSeqIter::SimpleLazyTempSeqIter()
+  :
+  theCurPos(0),
+  theStartPos(0),
+  theEndPos(0)
 {
-  return new SimpleLazyTempSeqIter(this, startPos, endPos);
 }
 
 
@@ -274,17 +311,17 @@
 
 ********************************************************************************/
 SimpleLazyTempSeqIter::SimpleLazyTempSeqIter(
-    const SimpleLazyTempSeq* aTempSeq,
-    xs_integer aStartPos,
-    xs_integer aEndPos)
+    const SimpleLazyTempSeq* tempSeq,
+    xs_integer startPos,
+    xs_integer endPos)
   :
-  theTempSeq(const_cast<SimpleLazyTempSeq*>(aTempSeq))
+  theTempSeq(const_cast<SimpleLazyTempSeq*>(tempSeq))
 {
   try 
   {
-    theCurPos = to_xs_long(aStartPos) - 1;
-    theStartPos = to_xs_long(aStartPos);
-    theEndPos = to_xs_long(aEndPos);
+    theStartPos = to_xs_long(startPos);
+    theEndPos = to_xs_long(endPos);
+    theCurPos = theStartPos - 1;
   }
   catch (std::range_error& e)
   {
@@ -294,17 +331,61 @@
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
 SimpleLazyTempSeqIter::~SimpleLazyTempSeqIter()
 {
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
+void SimpleLazyTempSeqIter::init(const store::TempSeq_t& seq)
+{
+  ZORBA_ASSERT(false);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void SimpleLazyTempSeqIter::init(
+    const store::TempSeq_t& seq,
+    xs_integer startPos,
+    xs_integer endPos)
+{
+  assert(seq->isLazy());
+
+  theTempSeq = static_cast<SimpleLazyTempSeq*>(seq.getp());
+
+  try 
+  {
+    theStartPos = to_xs_long(startPos);
+    theEndPos = to_xs_long(endPos);
+    theCurPos = theStartPos - 1;
+  }
+  catch (std::range_error& e)
+  {
+    RAISE_ERROR_NO_LOC(zerr::ZSTR0060_RANGE_EXCEPTION,
+    ERROR_PARAMS(BUILD_STRING("sequence too big (" << e.what() << ")")));
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 void SimpleLazyTempSeqIter::open()
 {
   theCurPos = theStartPos - 1;
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
 bool SimpleLazyTempSeqIter::next(store::Item_t& result)
 {
   if (theCurPos < theEndPos && theTempSeq->containsItem(xs_integer(theCurPos+1)))
@@ -320,12 +401,18 @@
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
 void SimpleLazyTempSeqIter::reset()
 {
   theCurPos = theStartPos - 1;
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
 void SimpleLazyTempSeqIter::close()
 {
 }

=== modified file 'src/store/naive/simple_lazy_temp_seq.h'
--- src/store/naive/simple_lazy_temp_seq.h	2012-07-11 04:46:41 +0000
+++ src/store/naive/simple_lazy_temp_seq.h	2012-07-12 14:52:27 +0000
@@ -35,25 +35,38 @@
 
 
 /*******************************************************************************
-  theIterator    : The input iterator that produces the items to be buffered by
-                   "this" temp sequence.
-  theCopy        : Whether or not to copy the items returned by theIterator 
-                   before buffering them in "this" temp sequence.
-  theMatFinished : Set to true when theIterator returns its last item.
-  thePurgedUpTo  : The number of items that have been purged from the buffer so
-                   far.
-
-  theItems       : Vector storing the buffered items.
+
+  theIterator :
+  -------------
+  The input iterator that produces the items to be cached by "this" temp sequence.
+
+  theMatFinished :
+  ----------------
+  Set to true when theIterator returns its last item.
+
+  thePurgedUpTo :
+  ---------------
+  The number of items that have been purged from the buffer so far.
+
+  theItems :
+  ----------
+  Vector storing the cached items.
 ********************************************************************************/
 class SimpleLazyTempSeq : public store::TempSeq 
 {
  private:
   store::Iterator_t          theIterator;
-  bool                       theCopy;
+
   bool                       theMatFinished;
+
   xs_long                    thePurgedUpTo;
   
-  std::vector<store::Item_t> theItems;
+  std::vector<store::Item*>  theItems; // ref-counting is done manually
+
+ private:
+  void clear();
+
+  void matNextItem();
 
  public:
   SimpleLazyTempSeq() { }
@@ -62,38 +75,34 @@
 
   virtual ~SimpleLazyTempSeq();
 
+  // Store API
+
+  bool isLazy() const { return true; }
+
+  bool empty();
+
+  xs_integer getSize() const;
+
   void init(const store::Iterator_t& iter);
 
   void append(const store::Iterator_t& iter);
 
   void purge();
 
-  void purgeUpTo(xs_integer upTo);
-
-  bool empty();
-
-  void getItem(xs_integer position, store::Item_t& result);
-
-  bool containsItem(xs_integer position);
-
-  xs_integer getSize() const;
+  void purgeUpTo(xs_integer pos);
+
+  void getItem(xs_integer pos, store::Item_t& result);
+
+  bool containsItem(xs_integer pos);
 
   store::Iterator_t getIterator() const;
-
-  store::Iterator_t getIterator(
-      xs_integer startPos,
-      xs_integer endPos,
-      bool streaming = false) const;
-
- private:
-  void matNextItem();
 };
  
  
 /*******************************************************************************
 
 ********************************************************************************/
-class SimpleLazyTempSeqIter : public store::Iterator 
+class SimpleLazyTempSeqIter : public store::TempSeqIterator
 {
  private:
   SimpleLazyTempSeq_t  theTempSeq;
@@ -103,16 +112,27 @@
   xs_long              theEndPos;
 
  public:
+  SimpleLazyTempSeqIter();
+
   SimpleLazyTempSeqIter(
-      const SimpleLazyTempSeq* aTempSeq,
-      xs_integer aStartPos,
-      xs_integer aEndPos);
+      const SimpleLazyTempSeq* tempSeq,
+      xs_integer startPos,
+      xs_integer endPos);
 
   virtual ~SimpleLazyTempSeqIter();
 
+  // Store API
+
+  void init(const store::TempSeq_t& seq);
+
+  void init(const store::TempSeq_t& seq, xs_integer startPos, xs_integer endPos);
+
   void open();
+
   bool next(store::Item_t& result);
+
   void reset();
+
   void close();
 };
 

=== modified file 'src/store/naive/simple_temp_seq.cpp'
--- src/store/naive/simple_temp_seq.cpp	2012-07-11 04:46:41 +0000
+++ src/store/naive/simple_temp_seq.cpp	2012-07-12 14:52:27 +0000
@@ -30,6 +30,16 @@
 /*******************************************************************************
 
 ********************************************************************************/
+SimpleTempSeq::SimpleTempSeq(store::Item_t& item) 
+{
+  theItems.push_back(NULL);
+  theItems[0] = item.release();
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 SimpleTempSeq::SimpleTempSeq(std::vector<store::Item_t>& items)
 {
   theItems.resize(items.size());
@@ -47,6 +57,15 @@
 /*******************************************************************************
 
 ********************************************************************************/
+SimpleTempSeq::SimpleTempSeq(const store::Iterator_t& iter)
+{
+  init(iter);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 SimpleTempSeq::~SimpleTempSeq()
 {
   clear();
@@ -108,13 +127,14 @@
 ********************************************************************************/
 void SimpleTempSeq::purge()
 {
+  clear();
 }
 
 
 /*******************************************************************************
 
 ********************************************************************************/
-void SimpleTempSeq::purgeUpTo(xs_integer upTo)
+void SimpleTempSeq::purgeUpTo(xs_integer pos)
 {
 }
 
@@ -196,51 +216,46 @@
 }
 
 
-/*******************************************************************************
-  Returns an iterator which reads just a part of the underlying TempSeq
-
-  @param startPos The first item which the iterator returns
-  @param endPos The last item which the iterator returns 
-  @return Iterator
-********************************************************************************/
-store::Iterator_t SimpleTempSeq::getIterator(
-    xs_integer startPos,
-    xs_integer endPos,
-    bool streaming) const
-{
-  return new SimpleTempSeqIter(this, startPos, endPos);
-}
+/////////////////////////////////////////////////////////////////////////////////
+//                                                                             //
+//  SimpleTempSeqIter                                                          //
+//                                                                             //
+/////////////////////////////////////////////////////////////////////////////////
 
 
 /*******************************************************************************
 
 ********************************************************************************/	
-SimpleTempSeqIter::SimpleTempSeqIter(const SimpleTempSeq* aTempSeq)
+SimpleTempSeqIter::SimpleTempSeqIter(const SimpleTempSeq* tempSeq)
 	:
-  theTempSeq(const_cast<SimpleTempSeq*>(aTempSeq)),
-  theBorderType(none)
-{
-  theBegin = theTempSeq->theItems.begin();
-  theEnd = theTempSeq->theItems.end();
-}
-
-
-SimpleTempSeqIter::SimpleTempSeqIter(
-    const SimpleTempSeq* seq,
-    xs_integer startPos,
-    xs_integer endPos)
-{
-  init(const_cast<SimpleTempSeq*>(seq), startPos, endPos);
-}
-
-
+  theTempSeq(const_cast<SimpleTempSeq*>(tempSeq))
+{
+  theBegin = theTempSeq->theItems.begin();
+  theEnd = theTempSeq->theItems.end();
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/	
+void SimpleTempSeqIter::init(const store::TempSeq_t& tempSeq)
+{
+  theTempSeq = tempSeq;
+
+  theBegin = theTempSeq->theItems.begin();
+  theEnd = theTempSeq->theItems.end();
+}
+
+
+/*******************************************************************************
+  Return the items in the subrange [startPos, endPos]
+********************************************************************************/	
 void SimpleTempSeqIter::init(
-    const store::TempSeq_t& aTempSeq,
+    const store::TempSeq_t& tempSeq,
     xs_integer startPos,
     xs_integer endPos)
 {
-  theTempSeq = aTempSeq;
-  theBorderType = startEnd;
+  theTempSeq = tempSeq;
 
   xs_long start;
   xs_long end;
@@ -269,22 +284,18 @@
 }
 
 
-void SimpleTempSeqIter::init(const store::TempSeq_t& aTempSeq)
-{
-  theTempSeq = aTempSeq;
-  theBorderType = none;
-
-  theBegin = theTempSeq->theItems.begin();
-  theEnd = theTempSeq->theItems.end();
-}
-
-
+/*******************************************************************************
+
+********************************************************************************/	
 void SimpleTempSeqIter::open()
 {
   theIte = theBegin;
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/	
 bool SimpleTempSeqIter::next(store::Item_t& result)
 {
   if (theIte != theEnd)
@@ -299,29 +310,23 @@
 }
 
 
-store::Item* SimpleTempSeqIter::next()
-{
-  if (theIte != theEnd)
-  {
-    store::Item* result = *theIte;
-    ++theIte;
-    return result;
-  }
-
-  return NULL;
-}
-
-
+/*******************************************************************************
+
+********************************************************************************/	
 void SimpleTempSeqIter::reset()
 {
   theIte = theBegin;
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/	
 void SimpleTempSeqIter::close()
 {
 }
 
+
 } // namespace store
 } // namespace zorba
 /* vim:set et sw=2 ts=2: */

=== modified file 'src/store/naive/simple_temp_seq.h'
--- src/store/naive/simple_temp_seq.h	2012-07-11 04:46:41 +0000
+++ src/store/naive/simple_temp_seq.h	2012-07-12 14:52:27 +0000
@@ -23,9 +23,7 @@
 
 namespace zorba { namespace simplestore {
 
-/**
- * 
- */
+
 typedef rchandle<class SimpleTempSeq> SimpleTempSeq_t;
 
 
@@ -46,21 +44,22 @@
 public:
   SimpleTempSeq() { }
 
-  SimpleTempSeq(store::Item_t& item) 
-  {
-    theItems.push_back(NULL);
-    theItems[0] = item.release();
-  }
+  SimpleTempSeq(store::Item_t& item);
 
   SimpleTempSeq(std::vector<store::Item_t>& items);
 
-  SimpleTempSeq(const store::Iterator_t& iter)
-  {
-    init(iter);
-  }
+  SimpleTempSeq(const store::Iterator_t& iter);
 
   virtual ~SimpleTempSeq();
 
+  // Store API
+
+  bool isLazy() const { return false; }
+
+  bool empty();
+  
+  xs_integer getSize() const;
+
   void init(const store::Iterator_t& iter);
 
   void append(const store::Iterator_t& iter);
@@ -69,20 +68,11 @@
 
   void purgeUpTo(xs_integer upTo);
 
-  bool empty();
-  
-  xs_integer getSize() const;
-
   void getItem(xs_integer position, store::Item_t& res);
 
   bool containsItem(xs_integer position);
 
   store::Iterator_t getIterator() const;
-
-  store::Iterator_t getIterator(
-      xs_integer startPos,
-      xs_integer endPos,
-      bool streaming = false) const;
 };
 
 
@@ -92,14 +82,7 @@
 class SimpleTempSeqIter : public store::TempSeqIterator
 {
  private:
-  enum BorderType
-  {
-    none,
-    startEnd
-  };
-
   SimpleTempSeq_t                      theTempSeq;
-  BorderType                           theBorderType;
 
   std::vector<store::Item*>::iterator  theIte;
   std::vector<store::Item*>::iterator  theBegin;
@@ -110,19 +93,20 @@
 
   SimpleTempSeqIter(const SimpleTempSeq* seq);
 
-  SimpleTempSeqIter(const SimpleTempSeq* seq, xs_integer startPos, xs_integer endPos);
-
   ~SimpleTempSeqIter() {}
 
+  // Store API
+
   void init(const store::TempSeq_t& seq);
 
   void init(const store::TempSeq_t& seq, xs_integer startPos, xs_integer endPos);
 
-  store::Item* next();
-
   void open();
+
   bool next(store::Item_t& result);
+
   void reset();
+
   void close();
  };
 


Follow ups