← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~markos-za/zorba/markos-bugs into lp:zorba

 

Markos Zaharioudakis has proposed merging lp:~markos-za/zorba/markos-bugs into lp:zorba.

Requested reviews:
  Matthias Brantner (matthias-brantner)

For more details, see:
https://code.launchpad.net/~markos-za/zorba/markos-bugs/+merge/78812
-- 
https://code.launchpad.net/~markos-za/zorba/markos-bugs/+merge/78812
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2011-10-05 22:39:18 +0000
+++ ChangeLog	2011-10-10 10:08:22 +0000
@@ -41,6 +41,7 @@
   * Fixed bug #863730 (static delete-node* functions don't raise ZDDY0012)
   * Implemented the probe-index-range-value for general indexes
   * Fixed bug #867662 ("nullptr" warning)
+  * Fixed bug #867262 (allow reuse of iterator over ExtFuncArgItemSequence)
 
 version 2.0.1
 

=== modified file 'include/zorba/item_sequence.h'
--- include/zorba/item_sequence.h	2011-06-14 17:26:33 +0000
+++ include/zorba/item_sequence.h	2011-10-10 10:08:22 +0000
@@ -21,19 +21,26 @@
 
 namespace zorba { 
 
-  /** \brief This interface represents an instance of the XQuery 1.0 and XPath 2.0 Data Model (XDM).
+  /** 
+   * \brief This interface represents an instance of the XQuery 1.0 and XPath 2.0
+   * Data Model (XDM).
    *
    * See http://www.w3.org/TR/xpath-datamodel/.
    */
   class ZORBA_DLL_PUBLIC ItemSequence : virtual public SmartObject
   {
     public:
-      /** \brief Destructor
+      /**
+       * \brief Destructor
        */
       virtual ~ItemSequence() { }
 
-      /** \brief get the Iterator over the items
+      /**
+       * \brief get the Iterator over the items
+       *
        * @return an iterator over the items
+       * @throw Throws zerr::ZAPI0039 if the implementation of the associated
+       *        ItemSequence does not allow more than one iterator to be created. 
       */
       virtual Iterator_t  getIterator() = 0;
 

=== modified file 'include/zorba/iterator.h'
--- include/zorba/iterator.h	2011-06-14 17:26:33 +0000
+++ include/zorba/iterator.h	2011-10-10 10:08:22 +0000
@@ -73,6 +73,8 @@
    * The purpose of this method is to release resources that were allocated
    * during open. After calling close(), neither close() nor next() may be
    * called again. However, the iterator may be re-opened (by calling open()).
+   *
+   * @throw  ZorbaException if an error occurs, or the Iterator has not been opened.
    */
   virtual void 
   close() = 0;

=== modified file 'src/runtime/core/fncall_iterator.cpp'
--- src/runtime/core/fncall_iterator.cpp	2011-08-16 11:25:55 +0000
+++ src/runtime/core/fncall_iterator.cpp	2011-10-10 10:08:22 +0000
@@ -399,29 +399,35 @@
   {
   private:
     ExtFuncArgItemSequence * theItemSequence;
-    bool is_open;
-    int open_count;
+    bool                     theIsOpen;
+    bool                     theFirstOpen;
 
   public:
-    InternalIterator(ExtFuncArgItemSequence* item_sequence) 
+    InternalIterator(ExtFuncArgItemSequence* seq) 
       : 
-      theItemSequence(item_sequence),
-      is_open(false),
-      open_count(0)
+      theItemSequence(seq),
+      theIsOpen(false),
+      theFirstOpen(true)
     {
     }
 
-    virtual void open()
+    void open()
     {
-      is_open = true;
-      //if(open_count)
-      //  theItemSequence->theChild->reset(theItemSequence->thePlanState);
-      open_count++;
+      if (theIsOpen)
+        throw ZORBA_EXCEPTION(zerr::ZAPI0041_ITERATOR_ALREADY_OPEN);
+
+      if (!theFirstOpen)
+        theItemSequence->theChild->reset(theItemSequence->thePlanState);
+
+      theIsOpen = true;
+      theFirstOpen = false;
     }
 
     bool next(Item& item)
     {
-      ZORBA_ASSERT(is_open);
+      if (!theIsOpen)  
+        throw ZORBA_EXCEPTION(zerr::ZAPI0040_ITERATOR_NOT_OPEN);
+
       store::Item_t result;
       bool status = theItemSequence->theChild->
                     consumeNext(result,
@@ -431,28 +437,38 @@
       return status;
     }
 
-    virtual void close()
+    void close()
     {
-      is_open = false;
-      // theItemSequence->theChild->close(theItemSequence->thePlanState);
+      if (!theIsOpen)  
+        throw ZORBA_EXCEPTION(zerr::ZAPI0040_ITERATOR_NOT_OPEN);
+
+      theIsOpen = false;
     }
 
-    virtual bool isOpen() const {return is_open;}
+    bool isOpen() const { return theIsOpen; }
   };
 
 private:
   PlanIter_t   theChild;
   PlanState  & thePlanState;
+  bool         theHasIterator;
 
 public:
   ExtFuncArgItemSequence(PlanIter_t& child, PlanState& state)
     :
     theChild(child),
-    thePlanState(state)
-  {
-  }
-
-  virtual Iterator_t getIterator() {return new InternalIterator(this);}
+    thePlanState(state),
+    theHasIterator(false)
+  {
+  }
+
+  virtual Iterator_t getIterator() 
+  {
+    if (theHasIterator)
+      throw ZORBA_EXCEPTION(zerr::ZAPI0039_XQUERY_HAS_ITERATOR_ALREADY);
+
+    return new InternalIterator(this);
+  }
 };
 
 
@@ -468,9 +484,9 @@
 {
   theResultIter = NULL;
 
-  ulong n = (ulong)m_extArgs.size();
+  csize n = m_extArgs.size();
 
-  for (ulong i = 0; i < n; ++i)
+  for (csize i = 0; i < n; ++i)
   {
     delete m_extArgs[i];
   }

=== modified file 'test/unit/CMakeLists.txt'
--- test/unit/CMakeLists.txt	2011-08-31 13:17:59 +0000
+++ test/unit/CMakeLists.txt	2011-10-10 10:08:22 +0000
@@ -19,6 +19,7 @@
 #belongs to test external_function.cpp
 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/ext_mod.xq ${CMAKE_CURRENT_BINARY_DIR}/ext_mod.xq)
 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/ext_main.xq ${CMAKE_CURRENT_BINARY_DIR}/ext_main.xq)
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/ext_main2.xq ${CMAKE_CURRENT_BINARY_DIR}/ext_main2.xq)
 
 #belongs to test no_folding.cpp
 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/fold_mod1.xq ${CMAKE_CURRENT_BINARY_DIR}/fold_mod1.xq)

=== modified file 'test/unit/ext_mod.xq'
--- test/unit/ext_mod.xq	2011-08-05 02:21:55 +0000
+++ test/unit/ext_mod.xq	2011-10-10 10:08:22 +0000
@@ -31,3 +31,7 @@
 };
 
 declare function ext:bar2() as xs:string? external;
+
+
+declare function ext:bar3($seq as xs:integer*) external;
+

=== modified file 'test/unit/external_function.cpp'
--- test/unit/external_function.cpp	2011-09-28 21:02:54 +0000
+++ test/unit/external_function.cpp	2011-10-10 10:08:22 +0000
@@ -72,6 +72,7 @@
   }
 };
 
+
 class MySimpleExternalFunction2 : public ContextualExternalFunction
 {
 public:
@@ -88,11 +89,49 @@
   }
 };
 
+
+class MySimpleExternalFunction3 : public NonContextualExternalFunction
+{
+public:
+  String getURI() const { return "http://www.zorba-xquery.com/m";; }
+
+  String getLocalName() const { return "bar3"; }
+
+  ItemSequence_t evaluate(const ExternalFunction::Arguments_t& args) const
+  {
+    Item item;
+    int64_t sum1 = 0;
+    int64_t sum2 = 0;
+
+    Iterator_t iter = args[0]->getIterator();
+    iter->open();
+    while (iter->next(item))
+      sum1 += item.getLongValue();
+    iter->close();
+
+    //iter = args[0]->getIterator();
+    iter->open();
+    while (iter->next(item))
+      sum2 += item.getLongValue();
+    iter->close();
+
+    if (sum1 != sum2)
+    {
+      std::cerr << "sum1 = " << sum1 << "  sum2 = " << sum2 << std::endl;
+      throw std::exception();
+    }
+
+    return ItemSequence_t(new EmptySequence());
+  }
+};
+
+
 class MyExternalModule : public ExternalModule
 {
 protected:
   MySimpleExternalFunction           bar;
   MySimpleExternalFunction2          bar2;
+  MySimpleExternalFunction3          bar3;
 
 public:
   String getURI() const { return "http://www.zorba-xquery.com/m";; }
@@ -101,11 +140,14 @@
   {
     if (aLocalname == "bar")
         return const_cast<MySimpleExternalFunction*>(&bar);
+    if (aLocalname == "bar3")
+        return const_cast<MySimpleExternalFunction3*>(&bar3);
     else
         return const_cast<MySimpleExternalFunction2*>(&bar2);
   }
 };
 
+
 class MySerializationCallback : public SerializationCallback
 {
   protected:
@@ -119,10 +161,12 @@
     }
 };
 
+
 bool
 external_function_test_1(Zorba* aZorba)
 {
-  try {
+  try 
+  {
     // test the sausalito use case
     // serialize a query and afterwards execute it
     // by calling a dynamic function (i.e. using eval) 
@@ -152,7 +196,6 @@
         if (!lCalled) {
           return 2;
         }
-
       }
 
       {
@@ -175,20 +218,26 @@
         std::cout << lQuery << std::endl;
       }
     }
-  } catch (XQueryException& qe) {
+  }
+  catch (XQueryException& qe)
+  {
     std::cerr << qe << std::endl;
     return false;
-  } catch (ZorbaException& e) {
+  }
+  catch (ZorbaException& e)
+  {
     std::cerr << e << std::endl;
     return false;
   }
   return true;
 }
 
+
 bool
 external_function_test_2(Zorba* aZorba)
 {
-  try {
+  try 
+  {
     std::ifstream lIn("ext_main.xq");
     assert(lIn.good());
     std::ostringstream lOut;
@@ -218,7 +267,6 @@
         lDestroyedParam = false;
       }
 
-
       lDynContext->setVariable("local:foo",
                                aZorba->getItemFactory()->createString("foo")); 
 
@@ -228,15 +276,57 @@
     // destroy is called if the XQuery object is destroyed
     return lGotParam && lDestroyedParam;
 
-  } catch (XQueryException& qe) {
-    std::cerr << qe << std::endl;
-    return false;
-  } catch (ZorbaException& e) {
-    std::cerr << e << std::endl;
-    return false;
-  }
-  return true;
-}
+  } 
+  catch (XQueryException& qe) 
+  {
+    std::cerr << qe << std::endl;
+    return false;
+  }
+  catch (ZorbaException& e)
+  {
+    std::cerr << e << std::endl;
+    return false;
+  }
+  return true;
+}
+
+
+bool
+external_function_test_3(Zorba* aZorba)
+{
+  try 
+  {
+    std::ifstream lIn("ext_main2.xq");
+    assert(lIn.good());
+    std::ostringstream lOut;
+    MyExternalModule lMod;
+
+    StaticContext_t lSctx = aZorba->createStaticContext();
+    lSctx->registerModule(&lMod);
+
+    {
+      XQuery_t lQuery = aZorba->compileQuery(lIn, lSctx);
+
+      std::cout << lQuery << std::endl;
+    }
+  } 
+  catch (XQueryException& qe) 
+  {
+    std::cerr << qe << std::endl;
+    return false;
+  }
+  catch (ZorbaException& e)
+  {
+    std::cerr << e << std::endl;
+    return false;
+  }
+  catch (...)
+  {
+    return false;
+  }
+  return true;
+}
+
 
 int
 external_function(int argc, char* argv[]) 
@@ -256,6 +346,12 @@
     return 2;
   }
 
+  std::cout << "executing external_function_test_3" << std::endl;
+  if (!external_function_test_3(lZorba))
+  {
+    return 3;
+  }
+
   lZorba->shutdown();
   zorba::StoreManager::shutdownStore(lStore);
   return 0;


Follow ups