Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/bug-archiver 
into lp:zorba.

Commit message:
1. Fixed plan serializer bug: no more only_for_eval fields
2. invoke() can also be used to invoke function items. 


Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-archiver/+merge/187699

1. Fixed plan serializer bug: no more only_for_eval fields
2. invoke() can also be used to invoke function items. 
-- 
https://code.launchpad.net/~zorba-coders/zorba/bug-archiver/+merge/187699
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'modules/zorba-query/zorba-query.xq'
--- modules/zorba-query/zorba-query.xq	2013-08-14 06:22:00 +0000
+++ modules/zorba-query/zorba-query.xq	2013-09-26 09:43:49 +0000
@@ -456,12 +456,3 @@
 declare function zq:load-from-query-plan($plan as xs:base64Binary,
   $resolver as item()?, $mapper as item()?) as xs:anyURI external;
 
-(:~
- : <p>Internal helper function. Only necessary because of incomplete HOF
- : support in Zorba.</p>
- :)
-declare %private function zq:hof-invoker($hof as item(),
-  $ns as xs:string, $entity as xs:string) as item()*
-{
-   $hof($ns, $entity)
-};

=== modified file 'modules/zorba-query/zorba-query.xq.src/zorba-query.cpp'
--- modules/zorba-query/zorba-query.xq.src/zorba-query.cpp	2013-09-19 20:47:26 +0000
+++ modules/zorba-query/zorba-query.xq.src/zorba-query.cpp	2013-09-26 09:43:49 +0000
@@ -22,8 +22,8 @@
 /*******************************************************************************
 
 ********************************************************************************/
-zorba::ExternalFunction*
-ZorbaQueryModule::getExternalFunction(const zorba::String& localName)
+zorba::ExternalFunction* ZorbaQueryModule::getExternalFunction(
+    const zorba::String& localName)
 {
   FuncMap_t::iterator lIte = theFunctions.find(localName);
     
@@ -102,7 +102,7 @@
     
 
 /*******************************************************************************
-
+  Invoked from static_context::~static_context()
 ********************************************************************************/
 void ZorbaQueryModule::destroy() 
 {
@@ -231,7 +231,9 @@
 /*******************************************************************************
 
 ********************************************************************************/
-void ZorbaQueryFunction::throwError(const char *err_localname, const std::string& aErrorMessage)
+void ZorbaQueryFunction::throwError(
+    const char *err_localname,
+    const std::string& aErrorMessage)
 {
   String errNS(ZORBA_QUERY_MODULE_NAMESPACE);
   String errName(err_localname);
@@ -356,18 +358,12 @@
   
   //construct the arguments for the url resolver
   std::vector<ItemSequence_t> lArgs;
-  ItemSequence_t lSeq0 = new SingletonItemSequence(theFunction);
   ItemSequence_t lSeq1 = new SingletonItemSequence(ZorbaQueryModule::getItemFactory()->createString(aUri));
   ItemSequence_t lSeq2 = new SingletonItemSequence(ZorbaQueryModule::getItemFactory()->createString(lDataKind));
-  lArgs.push_back(lSeq0);
   lArgs.push_back(lSeq1);
   lArgs.push_back(lSeq2);
 
-  //invoke the HOF helper function using the arguments generated
-  Item lHofHelper = ZorbaQueryModule::getItemFactory()->
-  createQName("http://zorba.io/modules/zorba-query";, "zq", "hof-invoker");
-
-  ItemSequence_t lResult = theCtx->invoke(lHofHelper, lArgs);
+  ItemSequence_t lResult = theCtx->invoke(theFunction, lArgs);
   
   //Check if the result is an empty sequence by creating an Iterator, this is
   // cheaper than serializing the result and then checking if it was empty.
@@ -406,18 +402,12 @@
 
   //construct the arguments for the url resolver
   std::vector<ItemSequence_t> lArgs;
-  ItemSequence_t lSeq0 = new SingletonItemSequence(theFunction);
   ItemSequence_t lSeq1 = new SingletonItemSequence(ZorbaQueryModule::getItemFactory()->createString(aUrl));
   ItemSequence_t lSeq2 = new SingletonItemSequence(ZorbaQueryModule::getItemFactory()->createString(lDataKind));
-  lArgs.push_back(lSeq0);
   lArgs.push_back(lSeq1);
   lArgs.push_back(lSeq2);
   
-  //invoke the HOF helper function using the arguments generated
-  Item lHofHelper = ZorbaQueryModule::getItemFactory()->
-  createQName("http://zorba.io/modules/zorba-query";, "zq", "hof-invoker");
-
-  ItemSequence_t lResult = theCtx->invoke(lHofHelper, lArgs);
+  ItemSequence_t lResult = theCtx->invoke(theFunction, lArgs);
 
   // Check if the result is an empty sequence by creating an Iterator, this is
   // cheaper than serializing the result and then checking if it was empty.
@@ -460,8 +450,10 @@
   DynamicContext* lDynCtx = const_cast<DynamicContext*>(aDctx);
   StaticContext_t lSctxChild = aSctx->createChildContext();
    
-  QueryMap* lQueryMap;
-  if (!(lQueryMap = dynamic_cast<QueryMap*>(lDynCtx->getExternalFunctionParameter("zqQueryMap"))))
+  QueryMap* lQueryMap =
+  dynamic_cast<QueryMap*>(lDynCtx->getExternalFunctionParameter("zqQueryMap"));
+
+  if (!lQueryMap)
   {
     lQueryMap = new QueryMap();
     lDynCtx->addExternalFunctionParameter("zqQueryMap", lQueryMap);     

=== modified file 'modules/zorba-query/zorba-query.xq.src/zorba-query.h'
--- modules/zorba-query/zorba-query.xq.src/zorba-query.h	2013-08-13 19:19:44 +0000
+++ modules/zorba-query/zorba-query.xq.src/zorba-query.h	2013-09-26 09:43:49 +0000
@@ -75,6 +75,10 @@
 };
   
 
+
+/*******************************************************************************
+
+********************************************************************************/
 class ZorbaQueryURIMapper : public URIMapper
 {
 protected:
@@ -97,6 +101,8 @@
     EntityData const* aEntityData,
     std::vector<zorba::String>& oUris);
 };
+
+
 /*******************************************************************************
   Bag class for objects associated with a prepared query
 ********************************************************************************/
@@ -120,7 +126,16 @@
 
 
 /*******************************************************************************
+  There is one instance of QueryMap per outer query. The instance is created
+  on the fly (if it does not exist already) inside the 
+  PrepareMainModuleFunction::evaluate() or LoadFromQueryPlanFunction::evaluate()
+  methods (when those methods are invoked by the outer query). The instance
+  is registered in (and owned by) the dctx of the outer query as an 
+  ExternalFunctionParameter with the name "zqQueryMap". 
 
+  For each inner query prepared or loaded by the outer query, the QueryMap
+  instance maps the symbolic id of the inner query to its associated XQuery
+  obj and URIMapper and URLResolver objs (if any).
 ********************************************************************************/
 class QueryMap : public ExternalFunctionParameter
 {
@@ -240,7 +255,11 @@
 class IsBoundVariableFunction : public ZorbaQueryFunction
 {
 public:
-  IsBoundVariableFunction(const ZorbaQueryModule* aModule) : ZorbaQueryFunction(aModule) {}
+  IsBoundVariableFunction(const ZorbaQueryModule* aModule)
+    :
+    ZorbaQueryFunction(aModule)
+  {
+  }
 
   virtual ~IsBoundVariableFunction(){}
 
@@ -260,7 +279,11 @@
 class GetExternalVariablesFunction : public ZorbaQueryFunction
 {
 public:
-  GetExternalVariablesFunction(const ZorbaQueryModule* aModule) : ZorbaQueryFunction(aModule) {}
+  GetExternalVariablesFunction(const ZorbaQueryModule* aModule)
+    :
+    ZorbaQueryFunction(aModule)
+  {
+  }
 
   virtual ~GetExternalVariablesFunction() {}
 
@@ -531,39 +554,41 @@
            const zorba::DynamicContext*) const;
 };
 
-  class VariableValueFunction : public ZorbaQueryFunction{
-    protected:
-      class ValueItemSequence : public ItemSequence
-      {
-        protected:
-          Iterator_t theIterator;
-
-        public:
-          ValueItemSequence(Iterator_t& aIter)
-            : theIterator(aIter)
-          {
-          }
-
-          virtual ~ValueItemSequence(){}
-
-          Iterator_t
-          getIterator() { return theIterator; }
-
-      };
-    public:
-      VariableValueFunction(const ZorbaQueryModule* aModule) : ZorbaQueryFunction(aModule) {}
-
-      virtual ~VariableValueFunction() {}
-
-      virtual zorba::String
-        getLocalName() const {return "variable-value"; }
-
-      virtual zorba::ItemSequence_t
-        evaluate(const Arguments_t&,
-                 const zorba::StaticContext*,
-                 const zorba::DynamicContext*) const;
+    
+class VariableValueFunction : public ZorbaQueryFunction
+{
+protected:
+  class ValueItemSequence : public ItemSequence
+  {
+  protected:
+    Iterator_t theIterator;
+
+  public:
+    ValueItemSequence(Iterator_t& aIter) : theIterator(aIter)
+    {
+    }
+    
+    virtual ~ValueItemSequence(){}
+
+    Iterator_t
+    getIterator() { return theIterator; }
+    
   };
 
+public:
+  VariableValueFunction(const ZorbaQueryModule* aModule) : ZorbaQueryFunction(aModule) {}
+
+  virtual ~VariableValueFunction() {}
+
+  virtual zorba::String getLocalName() const {return "variable-value"; }
+
+  virtual zorba::ItemSequence_t
+  evaluate(const Arguments_t&,
+           const zorba::StaticContext*,
+           const zorba::DynamicContext*) const;
+};
+
+
 /*******************************************************************************
 
 ********************************************************************************/

=== modified file 'src/api/staticcontextimpl.cpp'
--- src/api/staticcontextimpl.cpp	2013-09-16 09:08:27 +0000
+++ src/api/staticcontextimpl.cpp	2013-09-26 09:43:49 +0000
@@ -1527,13 +1527,28 @@
 
 ********************************************************************************/
 ItemSequence_t StaticContextImpl::invoke(
-    const Item& aQName,
+    const Item& aItem,
+    const std::vector<ItemSequence_t>& aArgs) const
+{
+  store::Item_t item = Unmarshaller::getInternalItem(aItem);
+
+  if (item->isAtomic())
+    return invokeFunc(aItem, item, aArgs);
+  else
+    return invokeFuncItem(aItem, item, aArgs);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+ItemSequence_t StaticContextImpl::invokeFunc(
+    const Item& aItem,
+    const store::Item_t& qname,
     const std::vector<ItemSequence_t>& aArgs) const
 {
   try
   {
-    store::Item_t qname = Unmarshaller::getInternalItem(aQName);
-
     if (qname->getTypeCode() != store::XS_QNAME)
     {
       throw XQUERY_EXCEPTION(err::XPTY0004, ERROR_PARAMS(ZED(BadType_23o), "xs:QName"));
@@ -1563,7 +1578,7 @@
     // bind qname and params
     DynamicContext* queryDctx = query->getDynamicContext();
 
-    queryDctx->setVariable("", "xxx-func-name", aQName);
+    queryDctx->setVariable("", "xxx-func-name", aItem);
 
     for (csize i = 0; i < numArgs; ++i)
     {
@@ -1598,8 +1613,9 @@
   // prolog
   lOut
     << "import module namespace ref = 'http://www.zorba-xquery.com/modules/reflection';"
-    << std::endl
-    << "declare variable $xxx-func-name as xs:QName" << " external;" << std::endl;
+    << std::endl;
+
+  lOut << "declare variable $xxx-func-name as xs:QName external;" << std::endl;
 
   for (csize i = 0; i < arity; ++i)
   {
@@ -1620,6 +1636,7 @@
 
   // args
   lOut << "($xxx-func-name";
+
   for (csize i = 0; i < arity; ++i)
   {
     lOut << ", $arg" << i;
@@ -1629,6 +1646,92 @@
 }
 
 
+/*******************************************************************************
+
+********************************************************************************/
+ItemSequence_t StaticContextImpl::invokeFuncItem(
+    const Item& aItem,
+    const store::Item_t& funcItem,
+    const std::vector<ItemSequence_t>& aArgs) const
+{
+  try
+  {
+    if (!funcItem->isFunction())
+    {
+      throw XQUERY_EXCEPTION(err::XPTY0004,
+      ERROR_PARAMS(ZED(BadType_23o), "xs:function()"));
+    }
+
+    csize numArgs = aArgs.size();
+
+    String queryStr = createHOFQuery(numArgs);
+
+    XQuery_t query(new XQueryImpl());
+
+    // compile without any hints
+    Zorba_CompilerHints_t lHints;
+    StaticContext_t querySctx = new StaticContextImpl(*this);
+
+    query->compile(queryStr, querySctx, lHints);
+
+    // bind func item and params
+    DynamicContext* queryDctx = query->getDynamicContext();
+
+    queryDctx->setVariable("", "xxx-func-item", aItem);
+
+    for (csize i = 0; i < numArgs; ++i)
+    {
+      std::ostringstream argName;
+      argName << "arg" << i;
+      queryDctx->setVariable("", argName.str(), aArgs[i]->getIterator());
+    }
+
+    // the XQueryImpl object needs to live as long as its iterator
+    // because the iterator returned as a result of the query
+    // contains a reference to the query in order to do cleanup work.
+    // The same is true for this sctx
+    return new InvokeItemSequence(query, const_cast<StaticContextImpl*>(this));
+  }
+  catch (ZorbaException const& e)
+  {
+    ZorbaImpl::notifyError(theDiagnosticHandler, e);
+    return 0;
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+std::string StaticContextImpl::createHOFQuery(csize arity)
+{
+  std::ostringstream lOut;
+
+  // prolog
+  lOut << "declare variable $xxx-func-item external;" << std::endl;
+
+  for (csize i = 0; i < arity; ++i)
+  {
+    lOut << "declare variable $arg" << i << " external;" << std::endl;
+  }
+
+  // body
+  lOut << "$xxx-func-item(";
+
+  for (csize i = 0; i < arity; ++i)
+  {
+    lOut << "$arg" << i;
+
+    if (i < arity-1)
+      lOut << ",";
+  }
+  lOut << ")";
+
+  return lOut.str();
+}
+
+
+
 StaticCollectionManager*
 StaticContextImpl::getStaticCollectionManager() const
 {

=== modified file 'src/api/staticcontextimpl.h'
--- src/api/staticcontextimpl.h	2013-09-16 09:08:27 +0000
+++ src/api/staticcontextimpl.h	2013-09-26 09:43:49 +0000
@@ -76,9 +76,23 @@
 protected:
   static std::string createInvokeQuery(const function*, size_t aArity);
 
+  static std::string createHOFQuery(size_t aArity);
+
 private:
   StaticContextImpl(const StaticContextImpl&);
 
+  ItemSequence_t
+  invokeFunc(
+      const Item& aItem,
+      const store::Item_t& qname,
+      const std::vector<ItemSequence_t>& aArgs) const;
+
+  ItemSequence_t
+  invokeFuncItem(
+      const Item& aItem,
+      const store::Item_t& funItem,
+      const std::vector<ItemSequence_t>& aArgs) const;
+
 public:
   StaticContextImpl(DiagnosticHandler* = 0);
 
@@ -261,22 +275,25 @@
   resolve(const String& aRelativeUri, const String& aBaseUri) const;
 
   virtual bool
-  validate(const Item& rootElement, Item& validatedResult,
-           validation_mode_t validationMode = validate_strict) const;
-
-  virtual bool
-  validate(const Item& rootElement, Item& validatedResult,
-           const String& targetNamespace,
-           validation_mode_t validationMode = validate_strict) const;
-
-  virtual bool
-  validateSimpleContent(const String& stringValue,
-          const Item& typeQName,
-          std::vector<Item>& resultList) const;
+  validate(
+      const Item& rootElement,
+      Item& validatedResult,
+      validation_mode_t validationMode = validate_strict) const;
+
+  virtual bool
+  validate(
+      const Item& rootElement, Item& validatedResult,
+      const String& targetNamespace,
+      validation_mode_t validationMode = validate_strict) const;
+
+  virtual bool
+  validateSimpleContent(
+      const String& stringValue,
+      const Item& typeQName,
+      std::vector<Item>& resultList) const;
 
   ItemSequence_t
-  invoke(const Item& aQName,
-         const std::vector<ItemSequence_t>& aArgs) const;
+  invoke(const Item& item, const std::vector<ItemSequence_t>& aArgs) const;
 
   virtual StaticCollectionManager*
   getStaticCollectionManager() const;

=== modified file 'src/context/static_context.cpp'
--- src/context/static_context.cpp	2013-09-17 23:05:29 +0000
+++ src/context/static_context.cpp	2013-09-26 09:43:49 +0000
@@ -37,6 +37,7 @@
 #include "context/decimal_format.h"
 #include "context/sctx_map_iterator.h"
 
+#include "compiler/api/compilercb.h"
 #include "compiler/expression/expr_base.h"
 #include "compiler/expression/var_expr.h"
 #ifndef ZORBA_NO_FULL_TEXT
@@ -1132,10 +1133,11 @@
   ar & theVariablesMap;
   ar & theImportedPrivateVariablesMap;
 
-  ar.set_serialize_only_for_eval(true);
-  ar & theFunctionMap;
-  ar & theFunctionArityMap;
-  ar.set_serialize_only_for_eval(false);
+  if (ar.get_ccb()->theHasEval)
+  {
+    ar & theFunctionMap;
+    ar & theFunctionArityMap;
+  }
 
   ar & theCollectionMap;
 

=== modified file 'src/functions/external_function.cpp'
--- src/functions/external_function.cpp	2013-07-02 21:32:23 +0000
+++ src/functions/external_function.cpp	2013-09-26 09:43:49 +0000
@@ -77,7 +77,7 @@
 
   // if loaded, theImpl needs to be set immediately
   // this is covered by test/unit/external_function.cpp
-  if(!ar.is_serializing_out()) 
+  if (!ar.is_serializing_out()) 
   {
     try
     {

=== modified file 'src/functions/function.cpp'
--- src/functions/function.cpp	2013-09-23 09:11:02 +0000
+++ src/functions/function.cpp	2013-09-26 09:43:49 +0000
@@ -65,6 +65,18 @@
     }
 #endif
   }
+#if 0
+  else
+  {
+    std::cout << "Allocated function ";
+    if (getName())
+    {
+      zstring qname = getName()->getStringValue();
+      std::cout << qname;
+    }
+    std::cout << " ( " << this << " )" << std::endl;
+  }
+#endif
 
   setFlag(FunctionConsts::isDeterministic);
 }
@@ -76,6 +88,16 @@
 function::~function()
 {
   delete theAnnotationList;
+
+#if 0
+  if (!isBuiltin())
+  {
+    std::cout << "Deallocated function ";
+    if (getName())
+      std::cout << getName()->getStringValue();
+    std::cout << " ( " << this << " )" << std::endl;
+  }
+#endif
 }
 
 

=== modified file 'src/functions/function.h'
--- src/functions/function.h	2013-09-19 16:36:16 +0000
+++ src/functions/function.h	2013-09-26 09:43:49 +0000
@@ -98,8 +98,6 @@
 
   static_context* getStaticContext() const { return theModuleSctx; }
 
-  void setStaticContext(static_context* sctx) { theModuleSctx = sctx; }
-
   void setFlag(FunctionConsts::AnnotationFlags flag)
   {
     theFlags |= flag;

=== modified file 'src/runtime/core/fncall_iterator.cpp'
--- src/runtime/core/fncall_iterator.cpp	2013-09-20 20:37:55 +0000
+++ src/runtime/core/fncall_iterator.cpp	2013-09-26 09:43:49 +0000
@@ -221,6 +221,21 @@
 
   ar & theUDF;
   ar & theIsDynamic;
+
+  // If the query does not have eval, theFunctionMap and theFunctionArityMap
+  // members of static_context are not serialized. This can cause a memory leak
+  // if theUDF deserialization occuring above allocates a udf obj that is only
+  // pointed to (via a raw pointer) by this UDFunctionCallIterator. To fix the
+  // leak, we register the udf in theSctx.
+  if (!ar.is_serializing_out() &&
+      !ar.get_ccb()->theHasEval &&
+      !theUDF->isBuiltin())
+  {
+    function* f = theSctx->lookup_fn(theUDF->getName(), theUDF->getArity(), false);
+
+    if (!f)
+      theSctx->bind_fn(theUDF, theUDF->getArity(), loc);
+  }
 }
 
 

=== modified file 'src/runtime/core/fncall_iterator.h'
--- src/runtime/core/fncall_iterator.h	2013-06-15 22:44:20 +0000
+++ src/runtime/core/fncall_iterator.h	2013-09-26 09:43:49 +0000
@@ -24,11 +24,10 @@
 
 #include "runtime/hof/function_item.h"
 #include "runtime/util/single_item_iterator.h"
+#include "runtime/base/narybase.h"
 
 #include "context/static_context.h"
 
-#include "runtime/base/narybase.h"
-
 
 namespace zorba {
 

=== modified file 'src/zorbaserialization/archiver.cpp'
--- src/zorbaserialization/archiver.cpp	2013-02-28 17:33:05 +0000
+++ src/zorbaserialization/archiver.cpp	2013-09-26 09:43:49 +0000
@@ -47,7 +47,6 @@
     TypeCode type,
     const void* ptr,
     ArchiveFieldKind kind,
-    int only_for_eval,
     ENUM_ALLOW_DELAY allow_delay,
     unsigned int level)
   :
@@ -64,7 +63,6 @@
   theFirstChild(NULL),
   theLastChild(NULL),
   theParent(NULL),
-  theOnlyForEval(only_for_eval),
   theAllowDelay2(allow_delay)
 {
   assert(theKind == ARCHIVE_FIELD_NORMAL || 
@@ -163,7 +161,6 @@
     const void* ptr,
     ArchiveFieldKind kind,
     archive_field* refered,
-    int only_for_eval,
     ENUM_ALLOW_DELAY allow_delay,
     unsigned int level)
   :
@@ -180,7 +177,6 @@
   theFirstChild(NULL),
   theLastChild(NULL),
   theParent(NULL),
-  theOnlyForEval(only_for_eval),
   theAllowDelay2(allow_delay)
 {
   assert(type != TYPE_ENUM);
@@ -228,7 +224,6 @@
   theCurrentLevel(0),
   theNonClassFieldsMap(0),
   theClassFieldsMap(0),
-  theOnlyForEval(0),
   all_reference_list(0),
   internal_archive(internal_archive),
   theSerializeEverything(false),
@@ -246,7 +241,6 @@
                                      NULL,  // ptr
                                      ARCHIVE_FIELD_NORMAL,
                                      NULL,  // referred
-                                     false, // only for eval
                                      ALLOW_DELAY,
                                      0);    // level
 
@@ -344,7 +338,6 @@
   new_field = new archive_field(type,
                                 ptr,
                                 ARCHIVE_FIELD_NORMAL,
-                                get_serialize_only_for_eval(),
                                 theAllowDelay2,
                                 theCurrentLevel);
 
@@ -400,7 +393,6 @@
                                   NULL,       // ptr
                                   ARCHIVE_FIELD_REFERENCING,
                                   ref_field,
-                                  get_serialize_only_for_eval(),
                                   theAllowDelay2,
                                   theCurrentLevel);
   }
@@ -409,7 +401,6 @@
     new_field = new archive_field(type,
                                   ptr,
                                   ARCHIVE_FIELD_PTR,
-                                  get_serialize_only_for_eval(),
                                   theAllowDelay2,
                                   theCurrentLevel);
   }
@@ -421,7 +412,6 @@
                                   NULL,       // ptr
                                   ARCHIVE_FIELD_NULL,
                                   NULL,
-                                  get_serialize_only_for_eval(),
                                   theAllowDelay2,
                                   theCurrentLevel);
   }
@@ -511,7 +501,6 @@
                                 ptr,
                                 field_kind,
                                 ref_field,
-                                get_serialize_only_for_eval(), 
                                 theAllowDelay2,
                                 theCurrentLevel);
 
@@ -656,39 +645,10 @@
 
 
 /*******************************************************************************
-  Return the left sibling of a given field (NULL if there is no left sibling).
-********************************************************************************/
-archive_field* Archiver::get_prev(archive_field* field)
-{
-  archive_field* temp;
-  temp = field->theParent->theFirstChild;
-
-  if (temp == field)
-    return NULL;
-
-  while (temp)
-  {
-    if (temp->theNextSibling == field)
-      return temp;
-
-    temp = temp->theNextSibling;
-  }
-
-  assert(false);
-  return NULL;
-}
-
-
-/*******************************************************************************
 
 ********************************************************************************/
 void Archiver::prepare_serialize_out()
 {
-  if (!is_serialize_everything())
-  {
-    check_compound_fields(theRootField);
-  }
-
   while(check_allowed_delays(theRootField))
   {
   }
@@ -698,255 +658,6 @@
 /*******************************************************************************
 
 ********************************************************************************/
-void Archiver::check_compound_fields(archive_field* parent_field)
-{
-  //resolve all references first
-  //iterate: find the reference to the top most eval_only field and resolve it
-  archive_field* refering_field;
-
-  while (1)
-  {
-    refering_field = find_top_most_eval_only_field(parent_field);
-
-    if(!refering_field)
-      break;
-
-    if((refering_field->theReferredField->theAllowDelay2 != ALLOW_DELAY) ||
-      (refering_field->theReferredField->theKind == ARCHIVE_FIELD_NORMAL) ||
-      !refering_field->theReferredField->theOnlyForEval)
-    {
-      //must preserve this serialization
-      archive_field* temp_field = refering_field->theReferredField->theParent;
-      while(temp_field)
-      {
-        temp_field->theOnlyForEval = 0;
-        temp_field = temp_field->theParent;
-      }
-    }
-    else
-    {
-      exchange_mature_fields(refering_field, refering_field->theReferredField);
-      refering_field->theOnlyForEval = refering_field->theReferredField->theOnlyForEval;
-    }
-
-    clean_only_for_eval(refering_field->theReferredField,
-                        get_only_for_eval(refering_field->theReferredField));
-  }
-
-  while (check_only_for_eval_nondelay_referencing(parent_field))
-  {
-  }
-
-  replace_only_for_eval_with_null(parent_field);
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-archive_field* Archiver::find_top_most_eval_only_field(archive_field* parent_field)
-{
-  int ref_depth = -1;
-  archive_field* refering_field = NULL;
-
-  archive_field* child = parent_field->theFirstChild;
-  
-  while (child)
-  {
-    if (child->theOnlyForEval)
-    {
-    }
-    else if (child->theKind == ARCHIVE_FIELD_REFERENCING &&
-             get_only_for_eval(child->theReferredField))
-    {
-      int new_depth = compute_field_depth(child->theReferredField);
-      if(!refering_field || (ref_depth > new_depth))
-      {
-        ref_depth = new_depth;
-        refering_field = child;
-      }
-    }
-    else if (!child->theIsSimple && !child->theReferredField)
-    {
-      archive_field* new_refering = find_top_most_eval_only_field(child);
-
-      if (new_refering)
-      {
-        int new_depth = compute_field_depth(new_refering->theReferredField);
-        if (!refering_field || (ref_depth > new_depth))
-        {
-          ref_depth = new_depth;
-          refering_field = new_refering;
-        }
-      }
-    }
-
-    child = child->theNextSibling;
-  }
-
-  return refering_field;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-int Archiver::compute_field_depth(archive_field* field)
-{
-  archive_field* temp;
-  int i = 0;
-  temp = field->theParent;
-  while(temp)
-  {
-    temp = temp->theParent;
-    i++;
-  }
-  return i;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-int Archiver::get_only_for_eval(archive_field* field)
-{
-  if (field->theOnlyForEval)
-    return field->theOnlyForEval;
-
-  archive_field* child;
-  for (child = field->theFirstChild; child; child = child->theNextSibling)
-  {
-    if (child->theOnlyForEval)
-      return child->theOnlyForEval;
-  }
-
-  return 0;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-void Archiver::clean_only_for_eval(archive_field* field, int substract_value)
-{
-  if (field->theOnlyForEval >= substract_value)
-    field->theOnlyForEval -= substract_value;
-  else
-    field->theOnlyForEval = 0;
-
-  if (!field->theIsSimple)
-  {
-    archive_field* child = field->theFirstChild;
-    while (child)
-    {
-      clean_only_for_eval(child, substract_value);
-      child = child->theNextSibling;
-    }
-  }
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-bool Archiver::check_only_for_eval_nondelay_referencing(archive_field* parent_field)
-{
-  archive_field* current_field = parent_field->theFirstChild;
-
-  while (current_field)
-  {
-    if (current_field->theOnlyForEval && current_field->theKind != ARCHIVE_FIELD_NORMAL)
-    {
-      if (current_field->theKind == ARCHIVE_FIELD_REFERENCING &&
-          current_field->theAllowDelay2 != ALLOW_DELAY &&
-          !current_field->theReferredField->theOnlyForEval)
-      {
-        //must preserve this serialization
-        archive_field* temp_field = current_field->theParent;
-        while (temp_field)
-        {
-          temp_field->theOnlyForEval = 0;
-          temp_field = temp_field->theParent;
-        }
-        clean_only_for_eval(current_field, current_field->theOnlyForEval);
-        return true;
-      }
-    }
-
-    if (!current_field->theIsSimple)
-    {
-      if (check_only_for_eval_nondelay_referencing(current_field))
-        return true;
-    }
-
-    current_field = current_field->theNextSibling;
-  }
-  return false;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-void Archiver::replace_only_for_eval_with_null(archive_field* parent_field)
-{
-  archive_field* current_field = parent_field->theFirstChild;
-
-  while (current_field)
-  {
-    if (current_field->theOnlyForEval &&
-        (current_field->theKind != ARCHIVE_FIELD_NORMAL) &&
-        (current_field->theKind != ARCHIVE_FIELD_BASECLASS))
-    {
-      //don't save it, replace it with NULL if possible
-      archive_field* null_field = replace_with_null(current_field);
-
-      orphan_fields.push_back(current_field);
-      current_field = null_field;
-    }
-
-    if (!current_field->theIsSimple)
-    {
-      replace_only_for_eval_with_null(current_field);
-    }
-
-    current_field = current_field->theNextSibling;
-  }
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-archive_field* Archiver::replace_with_null(archive_field* current_field)
-{
-  if (current_field->theParent)
-  {
-    archive_field* null_field = new archive_field(TYPE_NULL,
-                                                  current_field->theIsSimple,
-                                                  current_field->theIsClass,
-                                                  NULL,
-                                                  ARCHIVE_FIELD_NULL,
-                                                  NULL,
-                                                  false,
-                                                  ALLOW_DELAY,
-                                                  current_field->theLevel);
-    null_field->theId = 0;
-    replace_field(null_field, current_field);
-    current_field->theParent = NULL;
-    current_field->theNextSibling = NULL;
-
-    return null_field;
-  }
-
-  //otherwise it is orphan
-  return NULL;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
 bool Archiver::check_allowed_delays(archive_field* parent_field)
 {
   //check all fields with dont_allow_delay and see if they are delayed
@@ -962,9 +673,9 @@
     }
 
     if (child->theKind == ARCHIVE_FIELD_REFERENCING &&
-       ((child->theAllowDelay2 == DONT_ALLOW_DELAY &&
-         check_order(child, child->theReferredField) < 1) ||
-        child->theAllowDelay2 == SERIALIZE_NOW))
+        ((child->theAllowDelay2 == DONT_ALLOW_DELAY &&
+          check_order(child, child->theReferredField) < 1) ||
+         child->theAllowDelay2 == SERIALIZE_NOW))
     {
       if (child->theReferredField->theKind == ARCHIVE_FIELD_NORMAL ||
           child->theReferredField->theAllowDelay2 == SERIALIZE_NOW)
@@ -1058,6 +769,30 @@
 }
 
 
+/*******************************************************************************
+  Return the left sibling of a given field (NULL if there is no left sibling).
+********************************************************************************/
+archive_field* Archiver::get_prev(archive_field* field)
+{
+  archive_field* temp;
+  temp = field->theParent->theFirstChild;
+
+  if (temp == field)
+    return NULL;
+
+  while (temp)
+  {
+    if (temp->theNextSibling == field)
+      return temp;
+
+    temp = temp->theNextSibling;
+  }
+
+  assert(false);
+  return NULL;
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 //                                                                            //
 //  De-Serialization only                                                     //

=== modified file 'src/zorbaserialization/archiver.h'
--- src/zorbaserialization/archiver.h	2013-02-07 17:24:36 +0000
+++ src/zorbaserialization/archiver.h	2013-09-26 09:43:49 +0000
@@ -172,8 +172,6 @@
 
   FieldMap                    * theClassFieldsMap;
 
-  int                           theOnlyForEval;
-
 
   void                       ** all_reference_list;
 
@@ -322,24 +320,8 @@
 
   void replace_field(archive_field* new_field, archive_field* ref_field);
 
-  archive_field* replace_with_null(archive_field* current_field);
-
   void register_pointers_internal(archive_field* fields);
 
-  int compute_field_depth(archive_field* field);
-
-  int get_only_for_eval(archive_field* field);
-
-  archive_field* find_top_most_eval_only_field(archive_field* parent_field);
-
-  bool check_only_for_eval_nondelay_referencing(archive_field* parent_field);
-
-  void replace_only_for_eval_with_null(archive_field* parent_field);
-
-  void clean_only_for_eval(archive_field* field, int substract_value);
-
-  void check_compound_fields(archive_field* parent_field);
-
   bool check_allowed_delays(archive_field* parent_field);
 
   int check_order(archive_field* field1, archive_field* field2);
@@ -370,18 +352,6 @@
 public:
   void register_item(store::Item* i);
 
-  int get_serialize_only_for_eval() { return theOnlyForEval; }
-
-  void set_serialize_only_for_eval(bool evalonly)
-  {
-    if (evalonly)
-      theOnlyForEval++;
-    else
-      theOnlyForEval--;
-
-    assert(theOnlyForEval >= 0);
-  }
-
   void dont_allow_delay(ENUM_ALLOW_DELAY d = DONT_ALLOW_DELAY)
   {
     theAllowDelay2 = d;

=== modified file 'src/zorbaserialization/archiver_field.h'
--- src/zorbaserialization/archiver_field.h	2012-05-25 13:57:00 +0000
+++ src/zorbaserialization/archiver_field.h	2013-09-26 09:43:49 +0000
@@ -125,9 +125,6 @@
   ----------
   The parent field in the fields tree.
 
-  theOnlyForEval:
-  ---------------
-
   theAllowDelay2:
   ---------------
 
@@ -174,8 +171,6 @@
   class archive_field        * theLastChild;
   class archive_field        * theParent;
 
-  int                          theOnlyForEval;
-
   ENUM_ALLOW_DELAY             theAllowDelay2;
 
 #ifdef ZORBA_PLAN_SERIALIZER_STATISTICS
@@ -191,7 +186,6 @@
       const void* ptr,
       ArchiveFieldKind kind,
       archive_field* refered,
-      int only_for_eval,
       ENUM_ALLOW_DELAY allow_delay,
       unsigned int level);
 
@@ -199,7 +193,6 @@
       TypeCode type,
       const void* ptr,
       ArchiveFieldKind kind,
-      int only_for_eval,
       ENUM_ALLOW_DELAY allow_delay,
       unsigned int level);
 

=== modified file 'src/zorbaserialization/mem_archiver.h'
--- src/zorbaserialization/mem_archiver.h	2013-02-07 17:24:36 +0000
+++ src/zorbaserialization/mem_archiver.h	2013-09-26 09:43:49 +0000
@@ -39,7 +39,7 @@
     : 
     Archiver(is_serializing_out, internal_archive),
     temp_field(TYPE_LAST, false, false, NULL,
-               ARCHIVE_FIELD_NORMAL, NULL, false, ALLOW_DELAY, 0)
+               ARCHIVE_FIELD_NORMAL, NULL, ALLOW_DELAY, 0)
   {
     current_field = NULL;
     is_after_last = false;

=== modified file 'test/rbkt/Queries/zorba/file/copy.xqlib'
--- test/rbkt/Queries/zorba/file/copy.xqlib	2013-08-09 08:27:30 +0000
+++ test/rbkt/Queries/zorba/file/copy.xqlib	2013-09-26 09:43:49 +0000
@@ -4,8 +4,9 @@
 
 declare namespace ann = "http://zorba.io/annotations";;
 
-declare %ann:nondeterministic %ann:sequential function fct:test-copy($rbktPath as xs:string, $file as xs:string) {
-
+declare %ann:nondeterministic %ann:sequential
+function fct:test-copy($rbktPath as xs:string, $file as xs:string)
+{
   variable $fileSrc := fn:concat($rbktPath, "/Queries/zorba/file/copy_files/", $file);
   variable $fileDest := fn:concat($rbktPath, "/Queries/zorba/file/copy_files/", $file, ".out");
 
@@ -21,7 +22,8 @@
   (: read both files back and compare :)
   let $src := file:read-binary($fileSrc)
   let $dest := file:read-binary($fileDest)
-  return {
+  return
+  {
     variable $result := $src eq $dest;
 
     (: delete the file before we terminate :)

=== modified file 'test/rbkt/Queries/zorba/zorba-query/query-plan2.xq'
--- test/rbkt/Queries/zorba/zorba-query/query-plan2.xq	2013-08-13 19:19:44 +0000
+++ test/rbkt/Queries/zorba/zorba-query/query-plan2.xq	2013-09-26 09:43:49 +0000
@@ -4,7 +4,8 @@
 declare namespace op = "http://zorba.io/options/features";;
 declare namespace f = "http://zorba.io/features";;
 
-declare function resolver:url-resolver($namespace as xs:string, $entity as xs:string) {
+declare function resolver:url-resolver($namespace as xs:string, $entity as xs:string)
+{
   if($namespace = 'http://test')
   then "module namespace test = 'http://test'; declare function test:foo(){'foo'};"
   else ()
@@ -16,5 +17,7 @@
 
 
 variable $query-plan := zq:query-plan($queryID); 
+
 variable $queryID2 := zq:load-from-query-plan($query-plan, resolver:url-resolver#2, ());
+
 zq:evaluate ($queryID2)

=== modified file 'test/rbkt/Queries/zorba/zorba-query/uri-mapper.xq'
--- test/rbkt/Queries/zorba/zorba-query/uri-mapper.xq	2013-08-13 19:19:44 +0000
+++ test/rbkt/Queries/zorba/zorba-query/uri-mapper.xq	2013-09-26 09:43:49 +0000
@@ -5,7 +5,8 @@
 declare namespace op = "http://zorba.io/options/features";;
 declare namespace f = "http://zorba.io/features";;
 
-declare function resolver:url-resolver($namespace as xs:string, $entity as xs:string) {
+declare function resolver:url-resolver($namespace as xs:string, $entity as xs:string)
+{
   if($namespace = 'http://foo')
   then "module namespace test = 'http://test'; declare function test:foo(){'foo'};"
   else ()
@@ -23,4 +24,5 @@
   "import module namespace test = 'http://test'; test:foo()", 
   resolver:url-resolver#2, mapper:uri-mapper#2
 );
+
 zq:evaluate($queryID)

-- 
Mailing list: https://launchpad.net/~zorba-coders
Post to     : zorba-coders@lists.launchpad.net
Unsubscribe : https://launchpad.net/~zorba-coders
More help   : https://help.launchpad.net/ListHelp

Reply via email to