← 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.

Commit message:
runtime optimization for LET vars whose domain expr returns 0 or 1 items

Requested reviews:
  Markos Zaharioudakis (markos-za)

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

runtime optimization for LET vars whose domain expr returns 0 or 1 items
-- 
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/148915
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/compiler/codegen/plan_visitor.cpp'
--- src/compiler/codegen/plan_visitor.cpp	2013-02-07 04:37:24 +0000
+++ src/compiler/codegen/plan_visitor.cpp	2013-02-17 00:07:26 +0000
@@ -198,9 +198,10 @@
   PlanIter_t               theInputVar;
   std::vector<PlanIter_t>  theOutputVarRefs;
   bool                     theIsFakeLetVar;
+  bool                     theIsSingleItemLetVar;
 
 public:
-  VarRebind() : theIsFakeLetVar(false) {}
+  VarRebind() : theIsFakeLetVar(false), theIsSingleItemLetVar(false) {}
 };
 
 
@@ -717,7 +718,7 @@
 }
 
 
-PlanIter_t create_var_iter(const var_expr& var, bool forvar)
+PlanIter_t create_var_iter(const var_expr& var, bool forvar, bool singleItemLetVar)
 {
   PlanIter_t iter;
   if (forvar)
@@ -727,6 +728,9 @@
   else
   {
     iter = new LetVarIterator(var.get_sctx(), var.get_loc(), var.get_name());
+    
+    if (singleItemLetVar)
+      static_cast<LetVarIterator*>(iter.getp())->setSingleItem();
   }
   return iter;
 }
@@ -771,7 +775,7 @@
     // or materialize clause the comes after D_C and rebinds the var to its
     // output.
     long i = stackSize - 1;
-    while(true)
+    while (true)
     {
       if ((varPos = theClauseStack[i]->find_var(&var)) >= 0)
         break;
@@ -782,13 +786,15 @@
 
     FlworClauseVarMap* clauseVarMap = theClauseStack[i];
     flwor_expr* flworExpr = clauseVarMap->theClause->get_flwor_expr();
-    bool isFakeLetVar = clauseVarMap->theVarRebinds[varPos]->theIsFakeLetVar;
+    bool fakeLetVar = clauseVarMap->theVarRebinds[varPos]->theIsFakeLetVar;
+    bool singleItemLetVar = clauseVarMap->theVarRebinds[varPos]->theIsSingleItemLetVar;
 
-    if (isFakeLetVar)
+    if (fakeLetVar)
       isForVar = true;
 
     // Create a var ref iter in the output of C.
-    varIter = create_var_iter(var, isForVar);
+    varIter = create_var_iter(var, isForVar, singleItemLetVar);
+
 
     clauseVarMap->theVarRebinds[varPos]->theOutputVarRefs.push_back(varIter);
 
@@ -814,9 +820,10 @@
           clauseVarMap->theVarRebinds.push_back(varRebind);
 
           varRebind->theInputVar = varIter;
-          varRebind->theIsFakeLetVar = isFakeLetVar;
+          varRebind->theIsFakeLetVar = fakeLetVar;
+          //varRebind->theIsSingleItemLetVar = singleItemLetVar;
 
-          varIter = create_var_iter(var, isForVar);
+          varIter = create_var_iter(var, isForVar, varRebind->theIsSingleItemLetVar);
 
           varRebind->theOutputVarRefs.push_back(varIter);
         }
@@ -989,10 +996,6 @@
                 k == flwor_clause::window_clause ||
                 numForClauses > 0)
             {
-              theCCB->theXQueryDiagnostics->add_warning(
-              NEW_XQUERY_WARNING(zwarn::ZWST0004_AMBIGUOUS_SEQUENTIAL_FLWOR,
-                                 WARN_LOC(c->get_loc())));
-
               if (i > 0 &&
                   v.get_clause(i-1)->get_kind() != flwor_clause::order_clause &&
                   v.get_clause(i-1)->get_kind() != flwor_clause::groupby_clause)
@@ -1224,6 +1227,8 @@
 
     if (domType->get_quantifier() == TypeConstants::QUANT_ONE)
       varRebind->theIsFakeLetVar = true;
+    else if (domType->get_quantifier() == TypeConstants::QUANT_QUESTION)
+      varRebind->theIsSingleItemLetVar = true;
 
     break;
   }
@@ -1461,7 +1466,7 @@
   if (c.get_kind() != flwor_clause::where_clause)
   {
     ZORBA_ASSERT(!theClauseStack.empty());
-    ulong stackSize = (ulong)theClauseStack.size();
+    csize stackSize = theClauseStack.size();
 
     clauseVarMap = theClauseStack[stackSize-1];
     theClauseStack.resize(stackSize - 1);
@@ -1534,9 +1539,15 @@
     }
     else
     {
-      return new flwor::LetIterator(sctx, var->get_loc(), var->get_name(),
-                                    PREV_ITER, domainIter, varRefs,
-                                    lc->lazyEval(), true);  // materialize
+      flwor::LetIterator* letIter =
+      new flwor::LetIterator(sctx, var->get_loc(), var->get_name(),
+                             PREV_ITER, domainIter, varRefs,
+                             lc->lazyEval(), true);  // materialize
+
+      if (clauseVarMap->theVarRebinds[0]->theIsSingleItemLetVar)
+        letIter->setSingleItem();
+
+      return letIter;
     }
   }
 
@@ -1616,16 +1627,16 @@
   //
   else if (c.get_kind() == flwor_clause::order_clause)
   {
-    ulong numVars = (ulong)clauseVarMap->theVarRebinds.size();
-    ulong numForVars = 0;
-    ulong numLetVars = 0;
+    csize numVars = clauseVarMap->theVarRebinds.size();
+    csize numForVars = 0;
+    csize numLetVars = 0;
 
     std::vector<ForVarIter_t> inputForVars(numVars);
     std::vector<LetVarIter_t> inputLetVars(numVars);
     std::vector<std::vector<PlanIter_t> > outputForVarsRefs(numVars);
     std::vector<std::vector<PlanIter_t> > outputLetVarsRefs(numVars);
 
-    for (ulong i = 0; i < numVars; ++i)
+    for (csize i = 0; i < numVars; ++i)
     {
       VarRebind* varRebind = clauseVarMap->theVarRebinds[i].getp();
 
@@ -1924,6 +1935,9 @@
                                                     domainIter,
                                                     lc->lazyEval(),
                                                     true)); // materialize
+
+        if (clauseVarMap->theVarRebinds[0]->theIsSingleItemLetVar)
+          forletClauses.back().setSingleItem();
       }
       break;
     }

=== modified file 'src/runtime/core/flwor_iterator.cpp'
--- src/runtime/core/flwor_iterator.cpp	2012-10-08 12:09:36 +0000
+++ src/runtime/core/flwor_iterator.cpp	2013-02-17 00:07:26 +0000
@@ -84,6 +84,7 @@
   theType(FOR),
   theInput(input),
   theVarRefs(varRefs),
+  theSingleItemLETVar(false),
   theDoLazyEval(true)
 {
 }
@@ -109,6 +110,7 @@
   theInput(input),
   theVarRefs(varRefs),
   thePosVarRefs(posVarRefs),
+  theSingleItemLETVar(false),
   theDoLazyEval(true)
 {
 }
@@ -133,6 +135,7 @@
   theType(LET),
   theInput(input),
   theVarRefs(varRefs),
+  theSingleItemLETVar(false),
   theDoLazyEval(lazyEval)
 {
 }
@@ -160,6 +163,7 @@
   ar & theVarRefs;
   ar & thePosVarRefs;
   ar & theInput;
+  ar & theSingleItemLETVar;
   ar & theDoLazyEval;
 }
 
@@ -745,7 +749,7 @@
   {
     const ForLetClause& flc = *iter;
 
-    if (flc.theType == ForLetClause::LET)
+    if (flc.theType == ForLetClause::LET && !flc.theSingleItemLETVar)
     {
       (*domiter) = new PlanIteratorWrapper(flc.theInput, planState);
       (*seqiter) = GENV_STORE.createTempSeq(flc.lazyEval());
@@ -1221,12 +1225,11 @@
     // We increase the position counter
     ++bindingState;
 
-    std::vector<PlanIter_t>::const_iterator viter = flc.theVarRefs.begin();
+    std::vector<PlanIter_t>::const_iterator ite = flc.theVarRefs.begin();
     std::vector<PlanIter_t>::const_iterator end = flc.theVarRefs.end();
-    for (; viter != end; ++viter)
+    for (; ite != end; ++ite)
     {
-      static_cast<ForVarIterator*>
-      ((*viter).getp())->bind(item.getp(), planState);
+      static_cast<ForVarIterator*>((*ite).getp())->bind(item.getp(), planState);
     }
 
     if (!flc.thePosVarRefs.empty())
@@ -1234,12 +1237,11 @@
       store::Item_t posItem;
       GENV_ITEMFACTORY->createInteger(posItem, xs_integer(bindingState));
 
-      std::vector<PlanIter_t>::const_iterator viter = flc.thePosVarRefs.begin();
+      std::vector<PlanIter_t>::const_iterator ite = flc.thePosVarRefs.begin();
       std::vector<PlanIter_t>::const_iterator end = flc.thePosVarRefs.end();
-      for (; viter != end; ++viter)
+      for (; ite != end; ++ite)
       {
-        static_cast<ForVarIterator*>
-        ((*viter).getp())->bind(posItem.getp(), planState);
+        static_cast<ForVarIterator*>((*ite).getp())->bind(posItem.getp(), planState);
       }
     }
 
@@ -1253,15 +1255,36 @@
       return false;
     }
 
-    store::TempSeq_t tmpSeq = iterState->theTempSeqs[varNo].getp();
-    tmpSeq->init(iterState->theTempSeqIters[varNo]);
-
-    std::vector<PlanIter_t>::const_iterator viter = flc.theVarRefs.begin();
-    std::vector<PlanIter_t>::const_iterator end = flc.theVarRefs.end();
-    for (; viter != end; ++viter)
-    {
-      static_cast<LetVarIterator*>
-      ((*viter).getp())->bind(tmpSeq, planState);
+    if (!flc.theSingleItemLETVar)
+    {
+      store::TempSeq_t tmpSeq = iterState->theTempSeqs[varNo].getp();
+      tmpSeq->init(iterState->theTempSeqIters[varNo]);
+
+      std::vector<PlanIter_t>::const_iterator ite = flc.theVarRefs.begin();
+      std::vector<PlanIter_t>::const_iterator end = flc.theVarRefs.end();
+      for (; ite != end; ++ite)
+      {
+        static_cast<LetVarIterator*>((*ite).getp())->bind(tmpSeq, planState);
+      }
+    }
+    else
+    {
+      store::Item_t item;
+      if (!consumeNext(item, flc.theInput, planState))
+      {
+        item = NULL;
+      }
+      else
+      {
+        flc.theInput->reset(planState);
+      }
+
+      std::vector<PlanIter_t>::const_iterator ite = flc.theVarRefs.begin();
+      std::vector<PlanIter_t>::const_iterator end = flc.theVarRefs.end();
+      for (; ite != end; ++ite)
+      {
+        static_cast<LetVarIterator*>((*ite).getp())->bind(item, planState);
+      }
     }
 
     bindingState = 1;

=== modified file 'src/runtime/core/flwor_iterator.h'
--- src/runtime/core/flwor_iterator.h	2012-09-19 21:16:15 +0000
+++ src/runtime/core/flwor_iterator.h	2013-02-17 00:07:26 +0000
@@ -84,10 +84,17 @@
   enum ForLetType { FOR, LET };
 
   zstring                    theVarName;
+
   ForLetType                 theType;
+
   PlanIter_t                 theInput;
+
   std::vector<PlanIter_t>    theVarRefs;
+
   std::vector<PlanIter_t>    thePosVarRefs;
+
+  bool                       theSingleItemLETVar;
+
   bool                       theDoLazyEval;
     
 public:
@@ -122,6 +129,8 @@
 
   zstring getVarName() const;
 
+  void setSingleItem() { theSingleItemLETVar = true; }
+
   bool lazyEval() const { return theDoLazyEval; }
 };
 
@@ -363,7 +372,7 @@
   typedef std::vector<StreamTuple> TuplesTable;
 
 protected:
-  checked_vector<long>           theVarBindingState;
+  std::vector<long>              theVarBindingState;
 
   std::vector<store::TempSeq_t>  theTempSeqs;
 

=== modified file 'src/runtime/core/gflwor/common.h'
--- src/runtime/core/gflwor/common.h	2013-01-19 20:47:55 +0000
+++ src/runtime/core/gflwor/common.h	2013-02-17 00:07:26 +0000
@@ -39,7 +39,7 @@
 inline void createTempSeq(
     store::TempSeq_t& aTempSeqResult,
     const PlanIter_t& aInput,
-    PlanState& aPlanState,
+    PlanState& planState,
     const bool aLazyEval);
 
 
@@ -61,15 +61,6 @@
   
 public:
   StreamTuple() {}
-
-  StreamTuple(
-        std::vector<store::Item_t >& items,
-        std::vector<store::TempSeq_t >& sequences)
-    :
-    theItems(items),
-    theSequences(sequences) 
-  {
-  }
 };
 
 
@@ -317,35 +308,35 @@
     
 template <class T> inline void resetVector(
     const std::vector<T >& aVector,
-    PlanState& aPlanState)
+    PlanState& planState)
 {
   typename std::vector<T >::const_iterator lIter;
   for ( lIter = aVector.begin();
         lIter != aVector.end();
         ++lIter )
   {
-    lIter->reset(aPlanState);
+    lIter->reset(planState);
   }
 }
   
 
 template <class T> inline void closeVector(
     std::vector<T >& aVector,
-    PlanState& aPlanState)
+    PlanState& planState)
 {
   typename std::vector<T >::const_iterator lIter;
   for (lIter = aVector.begin();
        lIter != aVector.end();
        ++lIter )
   {
-    lIter->close(aPlanState);
+    lIter->close(planState);
   }
 }
   
   
 template <class T> inline void openVector(
     std::vector<T >& aVector,
-    PlanState& aPlanState,
+    PlanState& planState,
     uint32_t& aOffset)
 {
   typename std::vector<T >::iterator lIter;
@@ -353,7 +344,7 @@
        lIter != aVector.end();
        ++lIter)
   {
-    lIter->open(aPlanState, aOffset);
+    lIter->open(planState, aOffset);
   }
 }
   
@@ -372,38 +363,38 @@
 }
   
   
-template <class T> void resetVectorPtr(const std::vector<T >& aVector, PlanState& aPlanState)
+template <class T> void resetVectorPtr(const std::vector<T >& aVector, PlanState& planState)
 {
   typename std::vector<T >::const_iterator lIter;
   for ( lIter = aVector.begin();
         lIter != aVector.end();
         ++lIter )
   {
-    (*lIter)->reset(aPlanState);
+    (*lIter)->reset(planState);
   }
 }
   
   
-template <class T> void closeVectorPtr(std::vector<T >& aVector, PlanState& aPlanState)
+template <class T> void closeVectorPtr(std::vector<T >& aVector, PlanState& planState)
 {
   typename std::vector<T >::const_iterator lIter;
   for (lIter = aVector.begin();
        lIter != aVector.end();
        ++lIter )
   {
-    (*lIter)->close(aPlanState);
+    (*lIter)->close(planState);
   }
 }
   
   
-template <class T> inline void openVectorPtr(std::vector<T >& aVector, PlanState& aPlanState, uint32_t& aOffset)
+template <class T> inline void openVectorPtr(std::vector<T >& aVector, PlanState& planState, uint32_t& aOffset)
 {
   typename std::vector<T >::iterator lIter;
   for (lIter = aVector.begin();
        lIter != aVector.end();
        ++lIter )
   {
-    (*lIter)->open(aPlanState, aOffset);
+    (*lIter)->open(planState, aOffset);
   }
 }
   
@@ -434,69 +425,87 @@
 inline void createTempSeq(
     store::TempSeq_t& aTempSeqResult,
     const PlanIter_t& aInput,
-    PlanState& aPlanState,
+    PlanState& planState,
     const bool aLazyEval)
 {
-  store::Iterator_t iterWrapper = new PlanIteratorWrapper(aInput, aPlanState);
+  store::Iterator_t iterWrapper = new PlanIteratorWrapper(aInput, planState);
   aTempSeqResult = GENV_STORE.createTempSeq(iterWrapper, aLazyEval);
 }
   
 
 inline void bindVariables(
-    store::TempSeq_t& aTmpSeq,
-    const std::vector<PlanIter_t>& aLetVariables,
-    PlanState& aPlanState) 
+    store::TempSeq_t& tmpSeq,
+    const std::vector<PlanIter_t>& letVariables,
+    PlanState& planState) 
 {
-  std::vector<PlanIter_t>::const_iterator letIter = aLetVariables.begin();
-  std::vector<PlanIter_t>::const_iterator letEnd = aLetVariables.end();
-  for (; letIter != letEnd; ++letIter) 
+  std::vector<PlanIter_t>::const_iterator ite = letVariables.begin();
+  std::vector<PlanIter_t>::const_iterator end = letVariables.end();
+  for (; ite != end; ++ite) 
   {
-    static_cast<LetVarIterator*>
-    ((*letIter).getp())->bind(aTmpSeq, aPlanState);
+    static_cast<LetVarIterator*>((*ite).getp())->bind(tmpSeq, planState);
   }
 }
   
 
 inline void bindVariables(
-    const PlanIter_t& aInput,
-    const std::vector<PlanIter_t>& aLetVariables,
-    PlanState& aPlanState,
+    const PlanIter_t& input,
+    const std::vector<PlanIter_t>& letVariables,
+    PlanState& planState,
     bool lazyEval,
-    bool aNeedsMaterialization) 
+    bool needsMaterialization,
+    bool singleItem) 
 {
-  if (aNeedsMaterialization) 
-  {
-    store::TempSeq_t lTempSeq;
-    createTempSeq(lTempSeq, aInput, aPlanState, lazyEval);
-
-    bindVariables(lTempSeq, aLetVariables, aPlanState);
+  if (singleItem)
+  {
+    store::Item_t item;
+    if (!PlanIterator::consumeNext(item, input, planState))
+    {
+      item = NULL;
+    }
+    else
+    {
+      input->reset(planState);
+    }
+
+    std::vector<PlanIter_t>::const_iterator ite = letVariables.begin();
+    std::vector<PlanIter_t>::const_iterator end = letVariables.end();
+    for (; ite != end; ++ite)
+    {
+      static_cast<LetVarIterator*>((*ite).getp())->bind(item, planState);
+    }
+  }
+  else if (needsMaterialization) 
+  {
+    store::TempSeq_t tempSeq;
+    createTempSeq(tempSeq, input, planState, lazyEval);
+
+    bindVariables(tempSeq, letVariables, planState);
   }
   else
   {
-    store::Iterator_t iterWrapper = new PlanIteratorWrapper(aInput, aPlanState);
+    store::Iterator_t iterWrapper = new PlanIteratorWrapper(input, planState);
 
-    std::vector<PlanIter_t>::const_iterator letIter = aLetVariables.begin();
-    std::vector<PlanIter_t>::const_iterator letEnd = aLetVariables.begin();
-    for (; letIter != letEnd; ++letIter) 
+    std::vector<PlanIter_t>::const_iterator ite = letVariables.begin();
+    std::vector<PlanIter_t>::const_iterator end = letVariables.end();
+    for (; ite != end; ++ite)
     {
-      static_cast<LetVarIterator*>
-      ((*letIter).getp())->bind(iterWrapper, aPlanState);
+      static_cast<LetVarIterator*>((*ite).getp())->bind(iterWrapper, planState);
     }
   }
 }
 
 
 inline void bindVariables(
-    const store::Item_t& aItem,
-    const std::vector<PlanIter_t>& aForVariables,
-    PlanState& aPlanState) 
+    const store::Item_t& item,
+    const std::vector<PlanIter_t>& forVariables,
+    PlanState& planState) 
 {
-  std::vector<PlanIter_t>::const_iterator forIter = aForVariables.begin();
-  std::vector<PlanIter_t>::const_iterator forEnd = aForVariables.end();
-  for (; forIter != forEnd; ++forIter) 
+  std::vector<PlanIter_t>::const_iterator ite = forVariables.begin();
+  std::vector<PlanIter_t>::const_iterator end = forVariables.end();
+  for (; ite != end; ++ite) 
   {
-    ForVarIterator* varRef = static_cast<ForVarIterator*>((*forIter).getp());
-    varRef->bind(aItem.getp(), aPlanState);
+    ForVarIterator* varRef = static_cast<ForVarIterator*>((*ite).getp());
+    varRef->bind(item.getp(), planState);
   }
 }
 

=== removed file 'src/runtime/core/gflwor/common_binding.h'
--- src/runtime/core/gflwor/common_binding.h	2012-09-19 21:16:15 +0000
+++ src/runtime/core/gflwor/common_binding.h	1970-01-01 00:00:00 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright 2006-2008 The FLWOR Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef ZORBA_RUNTIME_GFLWOR_COMMON_BINDING
-#define ZORBA_RUNTIME_GFLWOR_COMMON_BINDING
-
-#include "zorba/api_shared_types.h"
-#include "zorbautils/checked_vector.h"
-#include "runtime/core/var_iterators.h"
-#include "system/globalenv.h"
-#include "store/api/store.h"
-#include "runtime/api/plan_iterator_wrapper.h"
-#include "store/api/temp_seq.h"
-
-//using namespace zorba;
-
-namespace zorba 
-{
-
-namespace flwor 
-{
-
-/////////////////////////////////////////////////////////////////////////////////
-//                                                                             //
-//  Static Binding Functions                                                   //
-//                                                                             //
-/////////////////////////////////////////////////////////////////////////////////
-
-inline void bindVariables(
-    store::TempSeq_t& aTmpSeq,
-    const std::vector<LetVarIter_t>& aLetVariables,
-    PlanState& aPlanState) 
-{
-  std::vector<LetVarIter_t>::const_iterator letIter;
-
-  for (letIter = aLetVariables.begin();
-       letIter != aLetVariables.end();
-       ++letIter) 
-  {
-    store::Iterator_t iter = aTmpSeq->getIterator();
-    iter->open();
-    (*letIter)->bind(iter, aPlanState);
-  }
-}
-
-
-}/* namespace gflwor */
-} /* namespace zorba */
-#endif  /* ZORBA_RUNTIME_GFLWOR_COMMON_BINDING */
-
-/*
- * Local variables:
- * mode: c++
- * End:
- */
-/* vim:set et sw=2 ts=2: */

=== modified file 'src/runtime/core/gflwor/let_iterator.cpp'
--- src/runtime/core/gflwor/let_iterator.cpp	2012-09-19 21:16:15 +0000
+++ src/runtime/core/gflwor/let_iterator.cpp	2013-02-17 00:07:26 +0000
@@ -44,7 +44,8 @@
   theVarName(aVarName),
   theLetVars(aLetVars),
   theLazyEval(lazyEval), 
-  theNeedsMat(aNeedsMaterialization) 
+  theNeedsMat(aNeedsMaterialization),
+  theSingleItemLETVar(false)
 {
 }
 
@@ -63,6 +64,7 @@
   ar & theLetVars;
   ar & theLazyEval;
   ar & theNeedsMat;
+  ar & theSingleItemLETVar;
 }
 
 
@@ -83,20 +85,25 @@
 
 
 
-bool LetIterator::nextImpl(store::Item_t& aResult, PlanState& aPlanState) const 
+bool LetIterator::nextImpl(store::Item_t& result, PlanState& planState) const 
 {
-  PlanIteratorState* lState;
-  DEFAULT_STACK_INIT(PlanIteratorState, lState, aPlanState);
+  PlanIteratorState* state;
+  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
 
-  while (consumeNext(aResult, theChild0, aPlanState)) 
+  while (consumeNext(result, theChild0, planState)) 
   {
-    bindVariables(theChild1, theLetVars, aPlanState, theLazyEval, theNeedsMat);
-
-    STACK_PUSH(true, lState);
-
-    theChild1->reset(aPlanState);
+    bindVariables(theChild1,
+                  theLetVars,
+                  planState,
+                  theLazyEval,
+                  theNeedsMat,
+                  theSingleItemLETVar);
+
+    STACK_PUSH(true, state);
+
+    theChild1->reset(planState);
   }
-  STACK_END(lState);
+  STACK_END(state);
 }
 
 

=== modified file 'src/runtime/core/gflwor/let_iterator.h'
--- src/runtime/core/gflwor/let_iterator.h	2012-09-19 21:16:15 +0000
+++ src/runtime/core/gflwor/let_iterator.h	2013-02-17 00:07:26 +0000
@@ -48,14 +48,12 @@
   std::vector<PlanIter_t> theLetVars;
   bool                    theLazyEval;
   bool                    theNeedsMat;
-  
+  bool                    theSingleItemLETVar;
+
 public:
   SERIALIZABLE_CLASS(LetIterator);
-
   SERIALIZABLE_CLASS_CONSTRUCTOR2T(
-  LetIterator,
-  BinaryBaseIterator<LetIterator, PlanIteratorState>);
-
+  LetIterator, BinaryBaseIterator<LetIterator, PlanIteratorState>);
   void serialize(::zorba::serialization::Archiver& ar);
 
 public:
@@ -73,6 +71,8 @@
 
   store::Item* getVarName() const { return theVarName.getp(); }
 
+  void setSingleItem() { theSingleItemLETVar = true; }
+
   void accept(PlanIterVisitor& v) const;
 
   bool nextImpl(store::Item_t& result, PlanState& planState) const;

=== modified file 'src/runtime/core/gflwor/orderby_iterator.cpp'
--- src/runtime/core/gflwor/orderby_iterator.cpp	2012-09-19 21:16:15 +0000
+++ src/runtime/core/gflwor/orderby_iterator.cpp	2013-02-17 00:07:26 +0000
@@ -450,14 +450,14 @@
   StreamTuple& streamTuple = 
   iterState->theDataTable[iterState->theSortTable[iterState->theCurTuplePos].theDataPos];
 
-  ulong numForVarsRefs = (ulong)theOutputForVarsRefs.size();
-  for (ulong i = 0; i < numForVarsRefs; ++i)
+  csize numForVarsRefs = theOutputForVarsRefs.size();
+  for (csize i = 0; i < numForVarsRefs; ++i)
   {
     bindVariables(streamTuple.theItems[i], theOutputForVarsRefs[i], planState);
   }
 
-  ulong numLetVarsRefs = (ulong)theOutputLetVarsRefs.size();
-  for(ulong i = 0; i < numLetVarsRefs; ++i)
+  csize numLetVarsRefs = theOutputLetVarsRefs.size();
+  for(csize i = 0; i < numLetVarsRefs; ++i)
   {
     bindVariables(streamTuple.theSequences[i], theOutputLetVarsRefs[i], planState);
   }

=== modified file 'src/runtime/core/gflwor/orderby_iterator.h'
--- src/runtime/core/gflwor/orderby_iterator.h	2012-09-19 21:16:15 +0000
+++ src/runtime/core/gflwor/orderby_iterator.h	2013-02-17 00:07:26 +0000
@@ -125,8 +125,8 @@
 
   void clear()
   {
-    ulong numColumns = (ulong)theKeyValues.size();
-    for (ulong i = 0; i < numColumns; ++i)
+    csize numColumns = theKeyValues.size();
+    for (csize i = 0; i < numColumns; ++i)
     {
       if (theKeyValues[i] != NULL)
       {

=== modified file 'src/runtime/core/var_iterators.cpp'
--- src/runtime/core/var_iterators.cpp	2013-01-08 08:34:08 +0000
+++ src/runtime/core/var_iterators.cpp	2013-02-17 00:07:26 +0000
@@ -714,7 +714,8 @@
   NoaryBaseIterator<LetVarIterator, LetVarState>(sctx, loc),
   theVarName(name),
   theTargetPos(0),
-  theInfLen(false)
+  theInfLen(false),
+  theSingleItem(false)
 {
 }
 
@@ -727,6 +728,17 @@
   ar & theTargetPosIter;
   ar & theTargetLenIter;
   ar & theInfLen;
+  ar & theSingleItem;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void LetVarIterator::setSingleItem()
+{
+  theSingleItem = true;
+  assert(theTargetPosIter == NULL && theTargetLenIter == NULL && theTargetPos == 0);
 }
 
 
@@ -735,7 +747,7 @@
 ********************************************************************************/
 bool LetVarIterator::setTargetPos(xs_integer v)
 {
-  if (theTargetPos == Integer(0) && theTargetPosIter == NULL)
+  if (!theSingleItem && theTargetPos == 0 && theTargetPosIter == NULL)
   {
     theTargetPos = v;
     return true;
@@ -746,7 +758,7 @@
 
 bool LetVarIterator::setTargetPosIter(const PlanIter_t& v)
 {
-  if (theTargetPos == Integer(0) && theTargetPosIter == NULL)
+  if (!theSingleItem && theTargetPos == 0 && theTargetPosIter == NULL)
   {
     theTargetPosIter = v;
     return true;
@@ -757,7 +769,8 @@
 
 bool LetVarIterator::setTargetLenIter(const PlanIter_t& v)
 {
-  if (theTargetPos == Integer(0) &&
+  if (!theSingleItem &&
+      theTargetPos == 0 &&
       theTargetLenIter == NULL && 
       theInfLen == false)
   {
@@ -787,6 +800,20 @@
 /*******************************************************************************
 
 ********************************************************************************/
+void LetVarIterator::bind(store::Item_t& value, PlanState& planState)
+{
+  assert(theSingleItem);
+
+  LetVarState* state;
+  state = StateTraitsImpl<LetVarState>::getState(planState, theStateOffset);
+
+  state->theItem = value;
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 void LetVarIterator::bind(const store::TempSeq_t& value, PlanState& planState)
 {
   LetVarState* state;
@@ -803,8 +830,10 @@
     else
     {
       if (state->theTempSeqIter == NULL)
-        state->theTempSeqIter = GENV_STORE.getIteratorFactory()->
-                                createTempSeqIterator(false);
+      {
+        state->theTempSeqIter = 
+        GENV_STORE.getIteratorFactory()->createTempSeqIterator(false);
+      }
 
       state->theTempSeqIter->init(value);
       state->theTempSeqIter->open();
@@ -918,7 +947,15 @@
   LetVarState* state;
   DEFAULT_STACK_INIT(LetVarState, state, planState);
 
-  if (theTargetPosIter != NULL)
+  if (theSingleItem)
+  {
+    if (state->theItem != NULL)
+    {
+      result = state->theItem;
+      STACK_PUSH(true, state);
+    }
+  }
+  else if (theTargetPosIter != NULL)
   {
     result = NULL;
 

=== modified file 'src/runtime/core/var_iterators.h'
--- src/runtime/core/var_iterators.h	2012-09-19 21:16:15 +0000
+++ src/runtime/core/var_iterators.h	2013-02-17 00:07:26 +0000
@@ -408,18 +408,18 @@
 {
 private:
   store::Item_t  theVarName;
+
   xs_integer     theTargetPos;
   PlanIter_t     theTargetPosIter;
   PlanIter_t     theTargetLenIter;
   bool           theInfLen;
 
+  bool           theSingleItem;
+
 public:
   SERIALIZABLE_CLASS(LetVarIterator);
-
   SERIALIZABLE_CLASS_CONSTRUCTOR2T(
-  LetVarIterator, 
-  NoaryBaseIterator<LetVarIterator, LetVarState>);
-
+  LetVarIterator, NoaryBaseIterator<LetVarIterator, LetVarState>);
   void serialize(::zorba::serialization::Archiver& ar);
 
 public:
@@ -430,6 +430,10 @@
 
   ~LetVarIterator() {}
 
+  void setSingleItem();
+
+  bool isSingleItemLETVar() const { return theSingleItem; }
+
   bool setTargetPos(xs_integer v);
 
   bool setTargetPosIter(const PlanIter_t& v);
@@ -444,6 +448,8 @@
 
   store::Item* getVarName() const { return theVarName.getp(); }
 
+  void bind(store::Item_t& value, PlanState& planState);
+
   void bind(const store::TempSeq_t& value, PlanState& planState);
 
   void bind(

=== modified file 'src/store/naive/json_items.cpp'
--- src/store/naive/json_items.cpp	2013-02-05 04:08:51 +0000
+++ src/store/naive/json_items.cpp	2013-02-17 00:07:26 +0000
@@ -710,6 +710,18 @@
 /******************************************************************************
 
 *******************************************************************************/
+zstring SimpleJSONObject::show() const
+{
+  std::stringstream str;
+  str << "{ }";
+
+  return str.str();
+}
+
+
+/******************************************************************************
+
+*******************************************************************************/
 SimpleJSONObject::KeyIterator::~KeyIterator() 
 {
 }
@@ -1240,6 +1252,18 @@
 /******************************************************************************
 
 *******************************************************************************/
+zstring SimpleJSONArray::show() const
+{
+  std::stringstream str;
+  str << "[ ]";
+
+  return str.str();
+}
+
+
+/******************************************************************************
+
+*******************************************************************************/
 SimpleJSONArray::ValuesIterator::~ValuesIterator() 
 {
 }

=== modified file 'src/store/naive/json_items.h'
--- src/store/naive/json_items.h	2013-02-05 04:08:51 +0000
+++ src/store/naive/json_items.h	2013-02-17 00:07:26 +0000
@@ -301,8 +301,7 @@
   Pairs  thePairs;
 
 public:
-  SimpleJSONObject()
-  {}
+  SimpleJSONObject() {}
 
   virtual ~SimpleJSONObject();
 
@@ -327,6 +326,8 @@
 
   virtual void getTypedValue(store::Item_t& val, store::Iterator_t& iter) const;
 
+  zstring show() const;
+
   // updates
   
   virtual bool add(
@@ -477,6 +478,8 @@
 
   void getTypedValue(store::Item_t& val, store::Iterator_t& iter) const;
 
+  zstring show() const;
+
   // updates
   
   virtual void

=== modified file 'test/rbkt/Queries/zorba/index/match_veq_02.xqlib'
--- test/rbkt/Queries/zorba/index/match_veq_02.xqlib	2013-01-29 06:01:31 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_02.xqlib	2013-02-17 00:07:26 +0000
@@ -14,7 +14,7 @@
 declare namespace an = "http://www.zorba-xquery.com/annotations";;
 
 
-declare %an:ordered collection sessions:sessions as element();
+declare %an:ordered collection sessions:sessions as element()*;
 
 declare variable $sessions:sessions as xs:QName := xs:QName("sessions:sessions");
 

=== modified file 'test/rbkt/Queries/zorba/index/match_veq_03.xqlib'
--- test/rbkt/Queries/zorba/index/match_veq_03.xqlib	2013-01-29 06:01:31 +0000
+++ test/rbkt/Queries/zorba/index/match_veq_03.xqlib	2013-02-17 00:07:26 +0000
@@ -13,7 +13,7 @@
 declare namespace an = "http://www.zorba-xquery.com/annotations";;
 
 
-declare %an:ordered collection sessions:sessions as element();
+declare %an:ordered collection sessions:sessions as element()*;
 
 declare variable $sessions:sessions := xs:QName("sessions:sessions");
 


Follow ups