zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #25904
[Merge] lp:~zorba-coders/zorba/bug-archiver into lp:zorba
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)
Follow ups