zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #13243
[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba
Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/markos-scratch into lp:zorba.
Requested reviews:
Markos Zaharioudakis (markos-za)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/119482
Fixed bug #1033407 (do not store var_expr rchandles in the static context)
--
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/119482
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/api/dynamiccontextimpl.cpp'
--- src/api/dynamiccontextimpl.cpp 2012-07-24 08:48:48 +0000
+++ src/api/dynamiccontextimpl.cpp 2012-08-14 08:22:22 +0000
@@ -38,7 +38,6 @@
#include "compiler/parser/query_loc.h"
#include "compiler/parsetree/parsenodes.h"
#include "compiler/api/compilercb.h"
-#include "compiler/expression/var_expr.h"
#include "runtime/util/item_iterator.h"
@@ -98,9 +97,9 @@
tree. The var_expr can be found within the static context that the variable
belongs to. In the case of a lexical QName, this method will only attempt to
look up the namespace prefix in the main module's static context. For a clark
- name, it will call to the other form of get_var_expr().
+ name, it will call to the other form of get_var_info().
********************************************************************************/
-var_expr* DynamicContextImpl::get_var_expr(const zstring& inVarName)
+VarInfo* DynamicContextImpl::get_var_info(const zstring& inVarName)
{
// First check for universal name.
zstring nsUri;
@@ -109,7 +108,7 @@
// Looks like it is a universal name; jump over to other form.
zstring localname;
xml::clark_localname(inVarName, &localname);
- return get_var_expr(nsUri, localname);
+ return get_var_info(nsUri, localname);
}
ZORBA_ASSERT(theStaticContext);
@@ -125,11 +124,9 @@
QueryLoc::null);
// Note: lookup_var will return NULL if the variable is not known.
- var_expr* var = theStaticContext->lookup_var(qnameItem,
- QueryLoc::null,
- zerr::ZXQP0000_NO_ERROR);
+ VarInfo* var = theStaticContext->lookup_var(qnameItem);
- if (var == NULL)
+ if (!var)
{
throw XQUERY_EXCEPTION(err::XPST0008,
ERROR_PARAMS(BUILD_STRING('{',
@@ -150,33 +147,34 @@
the variable belongs to. This method will search through all static contexts,
including library modules, for a matching variable declaration.
********************************************************************************/
-var_expr* DynamicContextImpl::get_var_expr(
+VarInfo* DynamicContextImpl::get_var_info(
const zstring& inVarUri,
const zstring& inVarLocalName) const
{
- var_expr* var = NULL;
-
store::Item_t qname;
GENV_ITEMFACTORY->createQName(qname, inVarUri, zstring(), inVarLocalName);
+ VarInfo* var = NULL;
+
if (theQuery != NULL)
{
CompilerCB::SctxMap& lMap = theQuery->theCompilerCB->theSctxMap;
CompilerCB::SctxMap::const_iterator ite;
+
for (ite = lMap.begin(); ite != lMap.end(); ++ite)
{
- var = ite->second->lookup_var(qname, QueryLoc::null, zerr::ZXQP0000_NO_ERROR);
+ var = ite->second->lookup_var(qname);
if (var)
- break;
+ return var;
}
}
else
{
- var = theStaticContext->lookup_var(qname, QueryLoc::null, zerr::ZXQP0000_NO_ERROR);
+ var = theStaticContext->lookup_var(qname);
}
- if (var == NULL)
+ if (!var)
{
throw XQUERY_EXCEPTION(err::XPST0008,
ERROR_PARAMS(BUILD_STRING('{', inVarUri, '}', inVarLocalName ), ZED(Variable)));
@@ -200,13 +198,14 @@
const zstring& nameSpace = Unmarshaller::getInternalString(inNamespace);
const zstring& localName = Unmarshaller::getInternalString(inLocalname);
- var_expr* var = get_var_expr(nameSpace, localName);
- ulong varId = var->get_unique_id();
+ VarInfo* var = get_var_info(nameSpace, localName);
+
+ ulong varId = var->getId();
store::Item_t item;
store::TempSeq_t tempseq;
- theCtx->get_variable(varId, var->get_name(), QueryLoc::null, item, tempseq);
+ theCtx->get_variable(varId, var->getName(), QueryLoc::null, item, tempseq);
if (! item.isNull())
{
@@ -248,11 +247,11 @@
const zstring& localName = Unmarshaller::getInternalString(inLocalname);
store::Iterator_t value = Unmarshaller::getInternalIterator(inValue.get());
- var_expr* var;
+ VarInfo* var = NULL;
try
{
- var = get_var_expr(nameSpace, localName);
+ var = get_var_info(nameSpace, localName);
}
catch (ZorbaException const& e)
{
@@ -266,7 +265,7 @@
throw;
}
- ulong varId = var->get_unique_id();
+ ulong varId = var->getId();
theCtx->add_variable(varId, value);
@@ -292,7 +291,6 @@
const zstring& varName = Unmarshaller::getInternalString(inVarName);
store::Item_t value(Unmarshaller::getInternalItem(inValue));
ZorbaImpl::checkItem(value);
- var_expr* var;
// For string items, check that the value is a valid Unicode codepoint sequence
const char* invalid_char;
@@ -311,9 +309,11 @@
<< (static_cast<unsigned int>(*invalid_char) & 0xFF)) ));
}
+ VarInfo* var = NULL;
+
try
{
- var = get_var_expr(varName);
+ var = get_var_info(varName);
}
catch (ZorbaException const& e)
{
@@ -327,7 +327,7 @@
throw;
}
- ulong varId = var->get_unique_id();
+ ulong varId = var->getId();
// add it to the internal context
theCtx->add_variable(varId, value);
@@ -358,11 +358,12 @@
const zstring& varName = Unmarshaller::getInternalString(inVarName);
store::Iterator_t value = Unmarshaller::getInternalIterator(inValue.get());
- var_expr* var;
+
+ VarInfo* var = NULL;
try
{
- var = get_var_expr(varName);
+ var = get_var_info(varName);
}
catch (ZorbaException const& e)
{
@@ -376,7 +377,7 @@
throw;
}
- ulong varId = var->get_unique_id();
+ ulong varId = var->getId();
theCtx->add_variable(varId, value);
=== modified file 'src/api/dynamiccontextimpl.h'
--- src/api/dynamiccontextimpl.h 2012-07-24 08:48:48 +0000
+++ src/api/dynamiccontextimpl.h 2012-08-14 08:22:22 +0000
@@ -26,6 +26,7 @@
class DiagnosticHandler;
class XQueryImpl;
+class VarInfo;
/*******************************************************************************
@@ -138,10 +139,10 @@
getExternalFunctionParam(const String& aName, void*&) const;
virtual bool
- addExternalFunctionParameter ( const String& aName, ExternalFunctionParameter* aParam );
+ addExternalFunctionParameter(const String& aName, ExternalFunctionParameter* aParam);
virtual ExternalFunctionParameter*
- getExternalFunctionParameter ( const String& aName ) const;
+ getExternalFunctionParameter(const String& aName) const;
virtual bool
isBoundExternalVariable(const String& aNamespace, const String& aLocalname) const;
@@ -153,9 +154,9 @@
void checkNoIterators() const;
private:
- var_expr* get_var_expr(const zstring& inVarName);
+ VarInfo* get_var_info(const zstring& varName);
- var_expr* get_var_expr(const zstring& inVarUri, const zstring& inVarLocalName) const;
+ VarInfo* get_var_info(const zstring& varUri, const zstring& varLocalName) const;
};
} /* namespace zorba */
=== modified file 'src/api/staticcontextimpl.cpp'
--- src/api/staticcontextimpl.cpp 2012-07-24 08:48:48 +0000
+++ src/api/staticcontextimpl.cpp 2012-08-14 08:22:22 +0000
@@ -1531,29 +1531,31 @@
StaticContextImpl::getExternalVariables(Iterator_t& aVarsIter) const
{
ZORBA_TRY
- std::vector<var_expr_t> lVars;
- theCtx->getVariables(lVars, true, false, true);
-
- std::vector<var_expr_t>::const_iterator lIte = lVars.begin();
- std::vector<var_expr_t>::const_iterator lEnd = lVars.end();
- std::vector<store::Item_t> lExVars;
-
- for (; lIte != lEnd; ++lIte)
+ std::vector<VarInfo*> vars;
+ theCtx->getVariables(vars, true, false, true);
+
+ std::vector<VarInfo*>::const_iterator ite = vars.begin();
+ std::vector<VarInfo*>::const_iterator end = vars.end();
+ std::vector<store::Item_t> extVars;
+
+ for (; ite != end; ++ite)
{
- lExVars.push_back(lIte->getp()->get_name());
+ extVars.push_back((*ite)->getName());
}
- Iterator_t vIter = new VectorIterator(lExVars, theDiagnosticHandler);
+ Iterator_t vIter = new VectorIterator(extVars, theDiagnosticHandler);
aVarsIter = vIter;
ZORBA_CATCH
}
+
Item
StaticContextImpl::fetch(const String& aURI) const
{
return fetch(aURI, "SOME_CONTENT", "UTF-8");
}
+
Item
StaticContextImpl::fetch(
const String& aURI,
=== modified file 'src/api/xqueryimpl.cpp'
--- src/api/xqueryimpl.cpp 2012-07-24 08:48:48 +0000
+++ src/api/xqueryimpl.cpp 2012-08-14 08:22:22 +0000
@@ -55,7 +55,6 @@
#include "compiler/api/compiler_api.h"
#include "compiler/api/compilercb.h"
-#include "compiler/expression/var_expr.h"
#include "runtime/base/plan_iterator.h"
#include "runtime/api/plan_wrapper.h"
@@ -762,26 +761,26 @@
checkNotClosed();
checkCompiled();
- std::vector<var_expr_t> lVars;
-
- CompilerCB::SctxMap::const_iterator lIte = theCompilerCB->theSctxMap.begin();
- CompilerCB::SctxMap::const_iterator lEnd = theCompilerCB->theSctxMap.end();
-
- for(; lIte != lEnd; ++lIte)
+ std::vector<VarInfo*> vars;
+
+ CompilerCB::SctxMap::const_iterator ite = theCompilerCB->theSctxMap.begin();
+ CompilerCB::SctxMap::const_iterator end = theCompilerCB->theSctxMap.end();
+
+ for(; ite != end; ++ite)
{
- lIte->second.getp()->getVariables(lVars, false, false, true);
+ ite->second.getp()->getVariables(vars, false, false, true);
}
- std::vector<var_expr_t>::const_iterator lVarIte = lVars.begin();
- std::vector<var_expr_t>::const_iterator lVarEnd = lVars.end();
- std::vector<store::Item_t> lExVars;
+ std::vector<VarInfo*>::const_iterator lVarIte = vars.begin();
+ std::vector<VarInfo*>::const_iterator lVarEnd = vars.end();
+ std::vector<store::Item_t> extVars;
for(; lVarIte != lVarEnd; ++lVarIte)
{
- lExVars.push_back((*lVarIte)->get_name());
+ extVars.push_back((*lVarIte)->getName());
}
- Iterator_t vIter = new VectorIterator(lExVars, theDiagnosticHandler);
+ Iterator_t vIter = new VectorIterator(extVars, theDiagnosticHandler);
aVarsIter = vIter;
@@ -801,34 +800,40 @@
checkNotClosed();
checkCompiled();
- var_expr* var = NULL;
-
zstring& nameSpace = Unmarshaller::getInternalString(aNamespace);
zstring& localName = Unmarshaller::getInternalString(aLocalname);
store::Item_t qname;
GENV_ITEMFACTORY->createQName(qname, nameSpace, zstring(), localName);
+ VarInfo* var = NULL;
+
CompilerCB::SctxMap& lMap = theCompilerCB->theSctxMap;
- CompilerCB::SctxMap::const_iterator lIte = lMap.begin();
- CompilerCB::SctxMap::const_iterator lEnd = lMap.end();
+ CompilerCB::SctxMap::const_iterator ite = lMap.begin();
+ CompilerCB::SctxMap::const_iterator end = lMap.end();
- for (; lIte != lEnd; ++lIte)
+ for (; ite != end; ++ite)
{
- var = lIte->second->lookup_var(qname, QueryLoc::null, zerr::ZXQP0000_NO_ERROR);
+ var = ite->second->lookup_var(qname);
- if(var)
+ if (var)
break;
}
- if(var == NULL)
+ if (!var)
+ {
throw XQUERY_EXCEPTION(zerr::ZAPI0011_ELEMENT_NOT_DECLARED,
- ERROR_PARAMS(BUILD_STRING('{', qname->getNamespace(), '}', qname->getLocalName()), ZED(Variable)));
+ ERROR_PARAMS(BUILD_STRING('{',
+ qname->getNamespace(),
+ '}',
+ qname->getLocalName()),
+ ZED(Variable)));
+ }
if (var->hasInitializer())
return true;
- ulong varId = var->get_unique_id();
+ ulong varId = var->getId();
if (theDynamicContext->is_set_variable(varId))
return true;
=== modified file 'src/compiler/codegen/plan_visitor.cpp'
--- src/compiler/codegen/plan_visitor.cpp 2012-07-24 08:48:48 +0000
+++ src/compiler/codegen/plan_visitor.cpp 2012-08-14 08:22:22 +0000
@@ -2075,18 +2075,24 @@
csize numVars = v.var_count();
- checked_vector<PlanIter_t> args(numVars+1);
- checked_vector<store::Item_t> varnames(numVars);
- checked_vector<xqtref_t> vartypes(numVars);
+ checked_vector<PlanIter_t> args;
+ args.reserve(numVars+1);
+
+ std::vector<store::Item_t> varNames(numVars);
+ std::vector<xqtref_t> varTypes(numVars);
+ std::vector<int> isGlobalVar(numVars);
for (csize i = 0; i < numVars; ++i)
{
- varnames[i] = v.get_var(i)->get_name();
- vartypes[i] = v.get_var(i)->get_type();
- args[i] = pop_itstack();
+ varNames[i] = v.get_var(i)->get_name();
+ varTypes[i] = v.get_var(i)->get_type();
+ isGlobalVar[i] = (v.get_arg_expr(i) == NULL);
+
+ if (!isGlobalVar[i])
+ args.push_back(pop_itstack());
}
- args[numVars] = pop_itstack();
+ args.push_back(pop_itstack());
reverse(args.begin(), args.end());
store::NsBindings localBindings;
@@ -2095,8 +2101,9 @@
push_itstack(new EvalIterator(sctx,
qloc,
args,
- varnames,
- vartypes,
+ varNames,
+ varTypes,
+ isGlobalVar,
v.get_inner_scripting_kind(),
localBindings,
v.getNodeCopy(),
@@ -2127,14 +2134,17 @@
std::vector<PlanIter_t> argvEvalIter;
csize numVars = v.var_count();
- std::vector<store::Item_t> varnames(numVars);
- std::vector<xqtref_t> vartypes(numVars);
+ std::vector<store::Item_t> varNames(numVars);
+ std::vector<xqtref_t> varTypes(numVars);
+ std::vector<int> isGlobalVar(numVars);
//create the eval iterator children
for (csize i = 0; i < numVars; i++)
{
- varnames[i] = v.get_var(i)->get_name();
- vartypes[i] = v.get_var(i)->get_type();
+ varNames[i] = v.get_var(i)->get_name();
+ varTypes[i] = v.get_var(i)->get_type();
+ isGlobalVar[i] = (v.get_var(i)->get_kind() == var_expr::prolog_var);
+
argvEvalIter.push_back(pop_itstack());
}
@@ -2167,15 +2177,16 @@
argv.push_back(new EvalIterator(sctx,
qloc,
argvEvalIter,
- varnames,
- vartypes,
+ varNames,
+ varTypes,
+ isGlobalVar,
SEQUENTIAL_FUNC_EXPR,
localBindings,
true,
true));
lDebugIterator->setChildren(&argv);
- lDebugIterator->setVariables(varnames, vartypes);
+ lDebugIterator->setVariables(varNames, varTypes);
// link all debugger iterators in the tree
if (!theDebuggerStack.empty())
=== modified file 'src/compiler/expression/expr.cpp'
--- src/compiler/expression/expr.cpp 2012-07-24 08:48:48 +0000
+++ src/compiler/expression/expr.cpp 2012-08-14 08:22:22 +0000
@@ -1210,7 +1210,7 @@
{
var_expr_t cloneVar = dynamic_cast<var_expr*>(theVars[i]->clone(s).getp());
assert(cloneVar != NULL);
- new_eval->add_var(cloneVar, theArgs[i]->clone(s));
+ new_eval->add_var(cloneVar, (theArgs[i] ? theArgs[i]->clone(s) : NULL));
}
return new_eval.getp();
=== modified file 'src/compiler/expression/expr.h'
--- src/compiler/expression/expr.h 2012-07-24 08:48:48 +0000
+++ src/compiler/expression/expr.h 2012-08-14 08:22:22 +0000
@@ -1041,8 +1041,8 @@
theVars:
--------
- There is one "eval" var for each non-global var that is in scope where the call
- to the eval function appears at.
+ There is one "eval" var (of kind var_expr::eval_var) for each var that is in
+ scope where the call to the eval function appears at.
theArgs:
--------
=== modified file 'src/compiler/expression/var_expr.cpp'
--- src/compiler/expression/var_expr.cpp 2012-07-24 08:48:48 +0000
+++ src/compiler/expression/var_expr.cpp 2012-08-14 08:22:22 +0000
@@ -26,17 +26,12 @@
#include "context/static_context.h"
-#include "zorbaserialization/serialize_zorba_types.h"
-#include "zorbaserialization/serialize_template_types.h"
-
#include "diagnostics/assert.h"
namespace zorba
{
-SERIALIZABLE_CLASS_VERSIONS(var_expr)
-
/*******************************************************************************
@@ -86,6 +81,7 @@
theCopyClause(NULL),
theParamPos(0),
theUDF(NULL),
+ theVarInfo(NULL),
theIsExternal(false),
theIsPrivate(false),
theIsMutable(true),
@@ -111,6 +107,7 @@
theCopyClause(NULL),
theParamPos(source.theParamPos),
theUDF(source.theUDF),
+ theVarInfo(NULL),
theIsExternal(source.theIsExternal),
theIsPrivate(source.theIsPrivate),
theIsMutable(source.theIsMutable),
@@ -119,42 +116,26 @@
}
-var_expr::var_expr(::zorba::serialization::Archiver& ar)
- :
- theFlworClause(NULL),
- theCopyClause(NULL),
- theUDF(NULL)
+/*******************************************************************************
+
+********************************************************************************/
+var_expr::~var_expr()
{
+ if (theVarInfo)
+ {
+ assert(theVarKind == prolog_var);
+ theVarInfo->clearVar();
+ }
}
/*******************************************************************************
********************************************************************************/
-void var_expr::serialize(::zorba::serialization::Archiver& ar)
+void var_expr::set_var_info(VarInfo* v)
{
- ar & theSctx;
- ar & theLoc;
- ar & theType;
- theKind = var_expr_kind;
- ar & theScriptingKind;
- ar & theFlags1;
-
- SERIALIZE_ENUM(var_kind, theVarKind);
-
- ar & theUniqueId;
-
- ar & theName;
- ar & theDeclaredType;
- //ar & theFlworClause;
- //ar & theCopyClause;
- //ar & theParamPos;
- //ar & theUDF;
- //ar & theSetExprs;
- ar & theIsPrivate;
- ar & theIsExternal;
- ar & theIsMutable;
- ar & theHasInitializer;
+ assert(theVarInfo == NULL);
+ theVarInfo = v;
}
@@ -170,6 +151,69 @@
/*******************************************************************************
********************************************************************************/
+void var_expr::set_unique_id(ulong v)
+{
+ assert(theUniqueId == 0);
+
+ theUniqueId = v;
+
+ if (theVarInfo)
+ {
+ assert(theVarKind == prolog_var);
+ theVarInfo->setId(v);
+ }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void var_expr::set_external(bool v)
+{
+ assert(theVarKind == prolog_var);
+ theIsExternal = v;
+
+ if (theVarInfo)
+ {
+ assert(theVarKind == prolog_var);
+ theVarInfo->setIsExternal(v);
+ }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void var_expr::set_has_initializer(bool v)
+{
+ theHasInitializer = v;
+
+ if (theVarInfo)
+ {
+ assert(theVarKind == prolog_var);
+ theVarInfo->setHasInitializer(v);
+ }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+void var_expr::set_type(xqtref_t t)
+{
+ theDeclaredType = t;
+
+ if (theVarInfo)
+ {
+ assert(theVarKind == prolog_var);
+ theVarInfo->setType(t);
+ }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
xqtref_t var_expr::get_type() const
{
return theDeclaredType;
@@ -179,15 +223,6 @@
/*******************************************************************************
********************************************************************************/
-void var_expr::set_type(xqtref_t t)
-{
- theDeclaredType = t;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
const var_expr* var_expr::get_pos_var() const
{
if (theVarKind == for_var)
=== modified file 'src/compiler/expression/var_expr.h'
--- src/compiler/expression/var_expr.h 2012-07-24 08:48:48 +0000
+++ src/compiler/expression/var_expr.h 2012-08-14 08:22:22 +0000
@@ -27,6 +27,7 @@
class for_clause;
class copy_clause;
class var_expr;
+class VarInfo;
typedef rchandle<var_expr> var_expr_t;
@@ -123,7 +124,9 @@
public:
enum var_kind
{
- eval_var = 0,
+ unknown_var = 0,
+
+ eval_var,
for_var,
let_var,
@@ -146,9 +149,7 @@
local_var,
- arg_var,
-
- unknown_var // TODO: get rid
+ arg_var
};
protected:
@@ -170,6 +171,8 @@
std::vector<expr*> theSetExprs;
+ VarInfo * theVarInfo;
+
bool theIsExternal;
bool theIsPrivate;
@@ -179,11 +182,6 @@
bool theHasInitializer;
public:
- SERIALIZABLE_CLASS(var_expr)
- var_expr(::zorba::serialization::Archiver& ar);
- void serialize(::zorba::serialization::Archiver& ar);
-
-public:
static std::string decode_var_kind(enum var_kind);
public:
@@ -195,9 +193,15 @@
var_expr(const var_expr& source);
+ virtual ~var_expr();
+
+ void set_var_info(VarInfo* v);
+
+ VarInfo* get_var_info() const { return theVarInfo; }
+
ulong get_unique_id() const { return theUniqueId; }
- void set_unique_id(ulong v) { assert(theUniqueId == 0); theUniqueId = v; }
+ void set_unique_id(ulong v);
store::Item* get_name() const;
@@ -211,11 +215,11 @@
bool is_external() const { return theIsExternal; }
- void set_external(bool v) { theIsExternal = v; }
-
- bool hasInitializer() const { return theHasInitializer; }
-
- void setHasInitializer(bool v) { theHasInitializer = v; }
+ void set_external(bool v);
+
+ bool has_initializer() const { return theHasInitializer; }
+
+ void set_has_initializer(bool v);
bool is_mutable() const { return theIsMutable; }
=== modified file 'src/compiler/rewriter/rules/nodeid_rules.cpp'
--- src/compiler/rewriter/rules/nodeid_rules.cpp 2012-07-24 08:48:48 +0000
+++ src/compiler/rewriter/rules/nodeid_rules.cpp 2012-08-14 08:22:22 +0000
@@ -932,17 +932,23 @@
{
expr* arg = e->get_arg_expr(i);
+ if (arg == NULL)
+ continue;
+
std::vector<expr*> sources;
theSourceFinder->findNodeSources(arg, &udfCaller, sources);
markSources(sources);
}
- std::vector<var_expr_t> globalVars;
+ std::vector<VarInfo*> globalVars;
node->get_sctx()->getVariables(globalVars, false, true);
- FOR_EACH(std::vector<var_expr_t>, ite, globalVars)
+ FOR_EACH(std::vector<VarInfo*>, ite, globalVars)
{
- var_expr* globalVar = (*ite).getp();
+ var_expr* globalVar = (*ite)->getVar();
+
+ if (globalVar == NULL)
+ continue;
std::vector<expr*> sources;
theSourceFinder->findNodeSources(globalVar, &udfCaller, sources);
@@ -1315,12 +1321,12 @@
markForSerialization(e->get_arg_expr(i));
}
- std::vector<var_expr_t> globalVars;
+ std::vector<VarInfo*> globalVars;
e->get_sctx()->getVariables(globalVars, true, true);
- FOR_EACH(std::vector<var_expr_t>, ite, globalVars)
+ FOR_EACH(std::vector<VarInfo*>, ite, globalVars)
{
- var_expr* globalVar = (*ite).getp();
+ var_expr* globalVar = (*ite)->getVar();
markForSerialization(globalVar);
}
=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp 2012-07-31 22:06:33 +0000
+++ src/compiler/translator/translator.cpp 2012-08-14 08:22:22 +0000
@@ -583,6 +583,8 @@
PrologGraph thePrologGraph;
PrologGraphVertex theCurrentPrologVFDecl;
+ std::vector<var_expr_t> theVars;
+
std::vector<expr*> theExitExprs;
bool theHaveUpdatingExitExprs;
@@ -1128,7 +1130,7 @@
{
assert(sctx != NULL);
- if(e->get_kind() == var_expr::let_var)
+ if (e->get_kind() == var_expr::let_var)
{
sctx->bind_var(e, e->get_loc(), err::XQST0039);
}
@@ -1136,6 +1138,8 @@
{
sctx->bind_var(e, e->get_loc(), err::XQST0049);
}
+
+ theVars.push_back(e);
}
@@ -1226,7 +1230,22 @@
store::Item_t qnameItem;
expand_no_default_qname(qnameItem, qname, loc);
- return theSctx->lookup_var(qnameItem.getp(), loc, err);
+ VarInfo* var = theSctx->lookup_var(qnameItem.getp());
+
+ if (!var)
+ {
+ if (err != zerr::ZXQP0000_NO_ERROR)
+ {
+ zstring varName = static_context::var_name(qnameItem);
+ throw XQUERY_EXCEPTION_VAR(err,
+ ERROR_PARAMS(varName, ZED(VariabledUndeclared)),
+ ERROR_LOC(loc));
+ }
+
+ return NULL;
+ }
+
+ return var->getVar();
}
@@ -1238,12 +1257,24 @@
If var is not found, the method raises the given error, unless the given error
is MAX_ZORBA_ERROR_CODE, in which case it returns NULL.
********************************************************************************/
-var_expr* lookup_var(
- const store::Item* qname,
- const QueryLoc& loc,
- const Error& err)
+var_expr* lookup_var(const store::Item* qname, const QueryLoc& loc, const Error& err)
{
- return theSctx->lookup_var(qname, loc, err);
+ VarInfo* var = theSctx->lookup_var(qname);
+
+ if (!var)
+ {
+ if (err != zerr::ZXQP0000_NO_ERROR)
+ {
+ zstring varName = static_context::var_name(qname);
+ throw XQUERY_EXCEPTION_VAR(err,
+ ERROR_PARAMS(varName, ZED(VariabledUndeclared)),
+ ERROR_LOC(loc));
+ }
+
+ return NULL;
+ }
+
+ return var->getVar();
}
@@ -1714,7 +1745,7 @@
theCCB->theDebuggerCommons->addBreakable(lBreakable, aIsMainModuleBreakable);
// retrieve all variables that are in the current scope
- typedef std::vector<var_expr_t> VarExprVector;
+ typedef std::vector<VarInfo*> VarExprVector;
VarExprVector lAllInScopeVars;
theSctx->getVariables(lAllInScopeVars);
@@ -1724,7 +1755,7 @@
lIter != lAllInScopeVars.end();
++lIter)
{
- var_expr* argVar = *lIter;
+ var_expr* argVar = (*lIter)->getVar();
store::Item* lVarname = argVar->get_name();
@@ -3835,7 +3866,7 @@
if (initExpr != NULL)
{
expr::checkSimpleExpr(initExpr);
- ve->setHasInitializer(true);
+ ve->set_has_initializer(true);
}
// If this is a library module, register the var in the exported sctx as well.
@@ -6527,7 +6558,7 @@
{
if (groupSpec.get_collation_spec() == NULL &&
prevSpec.get_collation_spec() == NULL)
- break;
+ break;
if (groupSpec.get_collation_spec() != NULL &&
prevSpec.get_collation_spec() != NULL &&
@@ -6546,7 +6577,15 @@
store::Item_t varName;
expand_no_default_qname(varName, groupSpec.get_var_name(), loc);
- expr_t inputExpr = sctx->lookup_var(varName.getp(), loc, err::XPST0008);
+ VarInfo* var = sctx->lookup_var(varName.getp());
+
+ if (!var)
+ {
+ RAISE_ERROR(err::XPST0008, loc,
+ ERROR_PARAMS(varName->getStringValue(), ZED(VariabledUndeclared)));
+ }
+
+ expr_t inputExpr = var->getVar();
if (inputExpr->get_expr_kind() == var_expr_kind)
{
@@ -10387,24 +10426,27 @@
theNSCtx);
resultExpr = evalExpr;
- std::vector<var_expr_t> inscopeVars;
+ std::vector<VarInfo*> inscopeVars;
theSctx->getVariables(inscopeVars);
+
csize numVars = inscopeVars.size();
for (csize i = 0; i < numVars; ++i)
{
- if (inscopeVars[i]->get_kind() == var_expr::prolog_var)
- continue;
+ var_expr* ve = inscopeVars[i]->getVar();
var_expr_t evalVar = create_var(loc,
- inscopeVars[i]->get_name(),
+ ve->get_name(),
var_expr::eval_var,
- inscopeVars[i]->get_return_type());
+ ve->get_return_type());
// At thgis point, the domain expr of an eval var is always another var.
// However, that other var may be later inlined, so in general, the domain
// expr of an eval var may be any expr.
- expr_t valueExpr = inscopeVars[i].getp();
+ expr_t valueExpr;
+
+ if (ve->get_kind() != var_expr::prolog_var)
+ valueExpr = ve;
evalExpr->add_var(evalVar, valueExpr);
}
@@ -10471,11 +10513,12 @@
let_clause_t lc;
store::Item_t qnameItem;
- // cannot use create_temp_var() as the variables created there are not accessible
- // use a special name but check for name clashes
+ // cannot use create_temp_var() as the variables created there are not
+ // accessible. use a special name but check for name clashes
do
{
- std::string localName = "temp_invoke_var" + ztd::to_string(theTempVarCounter++);
+ std::string localName = "temp_invoke_var" +
+ ztd::to_string(theTempVarCounter++);
GENV_ITEMFACTORY->createQName(qnameItem, "", "", localName.c_str());
}
while (lookup_var(qnameItem.getp(), loc, zerr::ZXQP0000_NO_ERROR) != NULL);
@@ -10522,7 +10565,11 @@
localExpr =
new fo_expr(theRootSctx, loc, GET_BUILTIN_FUNCTION(FN_STRING_1), localExpr);
- // qnameExpr := concat("Q{", namespaceExpr, "}", localExpr, "$temp_invoke_var2,$temp_invoke_var3,...)")
+ // qnameExpr := concat("Q{",
+ // namespaceExpr,
+ // "}",
+ // localExpr,
+ // "($temp_invoke_var2, $temp_invoke_var3,...)")
std::vector<expr_t> concat_args;
concat_args.push_back(new const_expr(theRootSctx, loc, "Q{"));
concat_args.push_back(namespaceExpr);
@@ -10545,23 +10592,28 @@
flworExpr->set_return_expr(evalExpr.getp());
resultExpr = flworExpr;
- std::vector<var_expr_t> inscopeVars;
+#if 0
+ std::vector<VarInfo*> inscopeVars;
theSctx->getVariables(inscopeVars);
+
csize numVars = inscopeVars.size();
for (csize i = 0; i < numVars; ++i)
{
- if (inscopeVars[i]->get_kind() == var_expr::prolog_var)
+ var_expr* ve = inscopeVars[i]->getVar();
+
+ if (ve->get_kind() == var_expr::prolog_var)
continue;
var_expr_t evalVar = create_var(loc,
- inscopeVars[i]->get_name(),
+ ve->get_name(),
var_expr::eval_var,
- inscopeVars[i]->get_return_type());
+ ve->get_return_type());
- expr_t valueExpr = inscopeVars[i].getp();
+ expr_t valueExpr = ve;
evalExpr->add_var(evalVar, valueExpr);
}
+#endif
for (csize i = 0; i < temp_vars.size(); ++i)
{
@@ -10807,7 +10859,7 @@
// Get the in-scope vars of the scope before opening the new scope for the
// function devl
- std::vector<var_expr_t> scopedVars;
+ std::vector<VarInfo*> scopedVars;
theSctx->getVariables(scopedVars);
push_scope();
@@ -10840,10 +10892,10 @@
// Handle inscope variables. For each inscope var, a let binding is added to
// the flwor.
- std::vector<var_expr_t>::iterator ite = scopedVars.begin();
+ std::vector<VarInfo*>::iterator ite = scopedVars.begin();
for(; ite != scopedVars.end(); ++ite)
{
- var_expr* varExpr = (*ite);
+ var_expr* varExpr = (*ite)->getVar();
var_expr::var_kind kind = varExpr->get_kind();
if (kind == var_expr::prolog_var || kind == var_expr::local_var)
=== modified file 'src/compiler/xqddf/value_index.cpp'
--- src/compiler/xqddf/value_index.cpp 2012-07-24 08:48:48 +0000
+++ src/compiler/xqddf/value_index.cpp 2012-08-14 08:22:22 +0000
@@ -265,17 +265,10 @@
expr* dotVar = NULL;
// Get the var_expr representing the context item, if it is defined
- try
- {
- dotVar = theSctx->lookup_var(dotQName, QueryLoc::null, err::XPST0008);
- }
- catch (ZorbaException const& e)
- {
- if (e.diagnostic() != err::XPST0008)
- {
- throw;
- }
- }
+ VarInfo* var = theSctx->lookup_var(dotQName);
+
+ if (var)
+ dotVar = var->getVar();
std::vector<var_expr*> varExprs;
=== modified file 'src/context/static_context.cpp'
--- src/context/static_context.cpp 2012-07-24 08:48:48 +0000
+++ src/context/static_context.cpp 2012-08-14 08:22:22 +0000
@@ -94,6 +94,8 @@
SERIALIZABLE_CLASS_VERSIONS(FunctionInfo)
+SERIALIZABLE_CLASS_VERSIONS(VarInfo)
+
SERIALIZABLE_CLASS_VERSIONS(PrologOption)
SERIALIZABLE_CLASS_VERSIONS_2(static_context::ctx_module_t, TYPE_sctx_module)
@@ -168,6 +170,77 @@
/**************************************************************************//**
*******************************************************************************/
+VarInfo::VarInfo()
+ :
+ theId(0),
+ theKind(var_expr::unknown_var),
+ theVarExpr(NULL)
+{
+}
+
+
+/**************************************************************************//**
+
+*******************************************************************************/
+VarInfo::VarInfo(::zorba::serialization::Archiver& ar)
+ :
+ SimpleRCObject(ar)
+{
+}
+
+
+/**************************************************************************//**
+
+*******************************************************************************/
+VarInfo::~VarInfo()
+{
+}
+
+
+/**************************************************************************//**
+
+*******************************************************************************/
+VarInfo::VarInfo(const var_expr_t& v)
+ :
+ theName(v->get_name()),
+ theId(v->get_unique_id()),
+ theKind(v->get_kind()),
+ theType(v->get_type()),
+ theIsExternal(v->is_external()),
+ theHasInitializer(v->has_initializer()),
+ theVarExpr(v.getp())
+{
+ if (theKind == var_expr::prolog_var)
+ v->set_var_info(this);
+}
+
+
+/**************************************************************************//**
+
+*******************************************************************************/
+void VarInfo::serialize(::zorba::serialization::Archiver& ar)
+{
+ ar & theName;
+ ar & theId;
+ ar & theKind;
+ ar & theType;
+ ar & theIsExternal;
+ ar & theHasInitializer;
+}
+
+
+/**************************************************************************//**
+
+*******************************************************************************/
+void VarInfo::setType(const xqtref_t& t)
+{
+ theType = t;
+}
+
+
+/**************************************************************************//**
+
+*******************************************************************************/
void PrologOption::serialize(::zorba::serialization::Archiver& ar)
{
ar & theName;
@@ -491,11 +564,7 @@
return (ns == ZORBA_SCRIPTING_FN_NS ||
ns == ZORBA_UTIL_FN_NS);
}
- else if (ns == W3C_FN_NS || ns == XQUERY_MATH_FN_NS
-//#ifdef ZORBA_WITH_JSON
-// || ns == JSONIQ_FN_NS
-//#endif
- )
+ else if (ns == W3C_FN_NS || ns == XQUERY_MATH_FN_NS)
{
return true;
}
@@ -739,27 +808,6 @@
delete theExternalModulesMap;
}
- if (theVariablesMap)
- delete theVariablesMap;
-
- if (theImportedPrivateVariablesMap)
- delete theImportedPrivateVariablesMap;
-
- if (theFunctionMap)
- delete theFunctionMap;
-
- if (theFunctionArityMap)
- {
- FunctionArityMap::iterator ite = theFunctionArityMap->begin();
- FunctionArityMap::iterator end = theFunctionArityMap->end();
- for (; ite != end; ++ite)
- {
- delete (*ite).second;
- }
-
- delete theFunctionArityMap;
- }
-
if (theW3CCollectionMap)
delete theW3CCollectionMap;
@@ -772,6 +820,33 @@
if (theICMap)
delete theICMap;
+ if (theFunctionMap)
+ delete theFunctionMap;
+
+ if (theFunctionArityMap)
+ {
+ FunctionArityMap::iterator ite = theFunctionArityMap->begin();
+ FunctionArityMap::iterator end = theFunctionArityMap->end();
+ for (; ite != end; ++ite)
+ {
+ delete (*ite).second;
+ }
+
+ delete theFunctionArityMap;
+ }
+
+ if (theVariablesMap)
+ {
+ delete theVariablesMap;
+ theVariablesMap = NULL;
+ }
+
+ if (theImportedPrivateVariablesMap)
+ {
+ delete theImportedPrivateVariablesMap;
+ theImportedPrivateVariablesMap = NULL;
+ }
+
if (theNamespaceBindings)
delete theNamespaceBindings;
@@ -2109,22 +2184,26 @@
********************************************************************************/
void static_context::bind_var(
- var_expr_t& varExpr,
+ const var_expr_t& varExpr,
const QueryLoc& loc,
const Error& err)
{
if (theVariablesMap == NULL)
{
- theVariablesMap = new VariableMap(HashMapItemPointerCmp(0, NULL), 8, false);
+ theVariablesMap = new VariableMap(HashMapItemPointerCmp(0, NULL), 16, false);
}
store::Item* qname = varExpr->get_name();
- if (!theVariablesMap->insert(qname, varExpr))
+ VarInfo_t vi = varExpr->get_var_info();
+
+ if (vi == NULL)
+ vi = new VarInfo(varExpr);
+
+ if (!theVariablesMap->insert(qname, vi))
{
- throw XQUERY_EXCEPTION_VAR(
- err, ERROR_PARAMS( qname->getStringValue() ), ERROR_LOC( loc )
- );
+ throw XQUERY_EXCEPTION_VAR(err,
+ ERROR_PARAMS(qname->getStringValue()), ERROR_LOC(loc));
}
}
@@ -2137,37 +2216,25 @@
If var is not found, the method raises the given error, unless the given error
is ZXQP0000_NO_ERROR, in which case it returns NULL.
********************************************************************************/
-var_expr* static_context::lookup_var(
- const store::Item* qname,
- const QueryLoc& loc,
- const Error& error) const
+VarInfo* static_context::lookup_var(const store::Item* qname) const
{
store::Item* qname2 = const_cast<store::Item*>(qname);
+ VarInfo_t var;
+
const static_context* sctx = this;
- var_expr_t varExpr;
while (sctx != NULL)
{
if (sctx->theVariablesMap != NULL &&
- sctx->theVariablesMap->get(qname2, varExpr))
+ sctx->theVariablesMap->get(qname2, var))
{
- return varExpr.getp();
+ return var.getp();
}
sctx = sctx->theParent;
}
- if (error != zerr::ZXQP0000_NO_ERROR)
- {
- zstring lVarName = var_name(qname);
- throw XQUERY_EXCEPTION_VAR(
- error,
- ERROR_PARAMS( lVarName, ZED( VariabledUndeclared ) ),
- ERROR_LOC( loc )
- );
- }
-
return NULL;
}
@@ -2176,8 +2243,8 @@
This method is used by introspection and debugger
********************************************************************************/
void static_context::getVariables(
- std::vector<var_expr_t>& vars,
- bool aLocalsOnly,
+ std::vector<VarInfo*>& vars,
+ bool localsOnly,
bool returnPrivateVars,
bool externalVarsOnly) const
{
@@ -2196,7 +2263,7 @@
csize i = 0;
for (; i < numVars; ++i)
{
- if (vars[i]->get_name()->equals((*ite).first))
+ if (vars[i]->getName()->equals((*ite).first))
break;
}
@@ -2204,12 +2271,12 @@
{
if (externalVarsOnly)
{
- if((*ite).second->is_external())
- vars.push_back((*ite).second);
+ if ((*ite).second->isExternal())
+ vars.push_back((*ite).second.getp());
}
else
{
- vars.push_back((*ite).second);
+ vars.push_back((*ite).second.getp());
}
}
}
@@ -2226,24 +2293,24 @@
csize i = 0;
for (; i < numVars; ++i)
{
- if (vars[i]->get_name()->equals((*ite).first))
+ if (vars[i]->getName()->equals((*ite).first))
break;
}
if (i == numVars)
{
- if(externalVarsOnly)
+ if (externalVarsOnly)
{
- if((*ite).second->is_external())
- vars.push_back((*ite).second);
+ if((*ite).second->isExternal())
+ vars.push_back((*ite).second.getp());
}
else
- vars.push_back((*ite).second);
+ vars.push_back((*ite).second.getp());
}
}
}
- if (aLocalsOnly)
+ if (localsOnly)
{
break;
}
@@ -2342,8 +2409,8 @@
if (theFunctionArityMap->get(qname, fv))
{
- ulong numFunctions = (ulong)fv->size();
- for (ulong i = 0; i < numFunctions; ++i)
+ csize numFunctions = fv->size();
+ for (csize i = 0; i < numFunctions; ++i)
{
if ((*fv)[i].theFunction == f)
{
@@ -4003,7 +4070,7 @@
if (theVariablesMap == NULL)
{
theVariablesMap = new VariableMap(HashMapItemPointerCmp(0, NULL),
- (ulong)module->theVariablesMap->capacity(),
+ module->theVariablesMap->capacity(),
false);
}
@@ -4011,7 +4078,8 @@
VariableMap::iterator end = module->theVariablesMap->end();
for (; ite != end; ++ite)
{
- var_expr_t ve = ite.getValue();
+ var_expr* ve = (*ite).second->getVar();
+
if (!ve->is_private())
{
bind_var(ve, loc, err::XQST0049);
@@ -4024,7 +4092,11 @@
new VariableMap(HashMapItemPointerCmp(0, NULL), 8, false);
}
- if (!theImportedPrivateVariablesMap->insert(ve->get_name(), ve))
+ VarInfo_t vi = ve->get_var_info();
+
+ assert (vi != NULL);
+
+ if (!theImportedPrivateVariablesMap->insert(ve->get_name(), vi))
{
RAISE_ERROR(err::XQST0049, loc,
ERROR_PARAMS(ve->get_name()->getStringValue()));
=== modified file 'src/context/static_context.h'
--- src/context/static_context.h 2012-07-24 08:48:48 +0000
+++ src/context/static_context.h 2012-08-14 08:22:22 +0000
@@ -44,6 +44,7 @@
#include "zorbautils/hashmap_itemp.h"
#include "common/shared_types.h"
+
#include "util/stl_util.h"
#include "util/auto_vector.h"
@@ -137,9 +138,7 @@
public:
SERIALIZABLE_CLASS(FunctionInfo)
-
FunctionInfo(::zorba::serialization::Archiver& ar);
-
void serialize(::zorba::serialization::Archiver& ar);
public:
@@ -151,13 +150,75 @@
};
+
+/*******************************************************************************
+
+********************************************************************************/
+class VarInfo : public SimpleRCObject
+{
+protected:
+ store::Item_t theName;
+
+ ulong theId;
+
+ int theKind;
+
+ xqtref_t theType;
+
+ bool theIsExternal;
+
+ bool theHasInitializer;
+
+ var_expr * theVarExpr;
+
+public:
+ SERIALIZABLE_CLASS(VarInfo)
+ VarInfo(::zorba::serialization::Archiver& ar);
+ void serialize(::zorba::serialization::Archiver& ar);
+
+public:
+ VarInfo();
+
+ VarInfo(const var_expr_t& v);
+
+ ~VarInfo();
+
+ const store::Item_t& getName() const { return theName; }
+
+ ulong getId() const { return theId; }
+
+ void setId(ulong id) { theId = id; }
+
+ int getKind() const { return theKind; }
+
+ const XQType* getType() const { return theType.getp(); }
+
+ void setType(const xqtref_t& t);
+
+ bool isExternal() const { return theIsExternal; }
+
+ void setIsExternal(bool v) { theIsExternal = v; }
+
+ bool hasInitializer() const { return theHasInitializer; }
+
+ void setHasInitializer(bool v) { theHasInitializer = v; }
+
+ var_expr* getVar() const { return theVarExpr; }
+
+ void clearVar() { theVarExpr = NULL; }
+};
+
+
+typedef rchandle<VarInfo> VarInfo_t;
+
+
/*******************************************************************************
********************************************************************************/
struct PrologOption : public ::zorba::serialization::SerializeBaseClass
{
- store::Item_t theName;
- zstring theValue;
+ store::Item_t theName;
+ zstring theValue;
public:
SERIALIZABLE_CLASS(PrologOption)
@@ -389,7 +450,7 @@
ITEM_PTR_HASH_MAP(ValueIC_t, ICMap);
- ITEM_PTR_HASH_MAP(var_expr_t, VariableMap);
+ ITEM_PTR_HASH_MAP(VarInfo_t, VariableMap);
ITEM_PTR_HASH_MAP(FunctionInfo, FunctionMap);
@@ -618,8 +679,6 @@
void serialize(serialization::Archiver& ar);
- void prepare_for_serialize(CompilerCB *compiler_cb);
-
public:
static_context(::zorba::serialization::Archiver& ar);
@@ -810,21 +869,15 @@
//
// Variables
//
- void bind_var(
- var_expr_t& expr,
- const QueryLoc& loc,
- const Error& err);
+ void bind_var(const var_expr_t& expr, const QueryLoc& loc, const Error& err);
- var_expr* lookup_var(
- const store::Item* qname,
- const QueryLoc& loc,
- const Error& err) const;
+ VarInfo* lookup_var(const store::Item* qname) const;
void getVariables(
- std::vector<var_expr_t>& variableList,
- bool localsOnly = false,
- bool returnPrivateVars = false,
- bool externalVarsOnly = false) const;
+ std::vector<VarInfo*>& variableList,
+ bool localsOnly = false,
+ bool returnPrivateVars = false,
+ bool externalVarsOnly = false) const;
void set_context_item_type(const xqtref_t& t, const QueryLoc& loc);
=== modified file 'src/debugger/debugger_runtime.cpp'
--- src/debugger/debugger_runtime.cpp 2012-07-24 08:48:48 +0000
+++ src/debugger/debugger_runtime.cpp 2012-08-14 08:22:22 +0000
@@ -376,17 +376,19 @@
static_context* lContext = lCommons->getCurrentStaticContext();
// get all visible variables and filter below
- std::vector<var_expr_t> lVars;
+ std::vector<VarInfo*> lVars;
lContext->getVariables(lVars, false);
std::vector<std::pair<std::string, std::string> > lVarList;
- std::vector<var_expr_t>::iterator lIte = lVars.begin();
- std::vector<var_expr_t>::iterator lEnd = lVars.end();
+ std::vector<VarInfo*>::iterator lIte = lVars.begin();
+ std::vector<VarInfo*>::iterator lEnd = lVars.end();
- for (; lIte != lEnd; ++lIte) {
+ for (; lIte != lEnd; ++lIte)
+ {
// non-global to locals and globals to globals
- if ((aLocals && (*lIte)->get_kind() == var_expr::prolog_var) ||
- (!aLocals && (*lIte)->get_kind() != var_expr::prolog_var)) {
+ if ((aLocals && (*lIte)->getKind() == var_expr::prolog_var) ||
+ (!aLocals && (*lIte)->getKind() != var_expr::prolog_var))
+ {
continue;
}
@@ -395,11 +397,12 @@
// read the name ****************************
- store::Item* lNameItem = (*lIte)->get_name();
+ const store::Item_t& lNameItem = (*lIte)->getName();
zstring lLocalName = lNameItem->getLocalName();
// correct the name of the context item
- if (!aLocals && lLocalName == "$$dot") {
+ if (!aLocals && lLocalName == "$$dot")
+ {
lVarList.push_back(std::pair<std::string, std::string>(".", "item()*"));
continue;
}
@@ -417,19 +420,23 @@
lNameSs << "\\" << lNameItem->getNamespace().str();
}
-
// read the type ****************************
- xqtref_t lType = (*lIte)->get_type();
+ xqtref_t lType = (*lIte)->getType();
- if (lType == NULL || lType->get_qname() == NULL) {
+ if (lType == NULL || lType->get_qname() == NULL)
+ {
lTypeSs << "item()*";
- } else {
+ }
+ else
+ {
TypeConstants::quantifier_t lQuantifier = lType->get_quantifier();
- store::Item_t lQname = (*lIte)->get_type()->get_qname();
+ store::Item_t lQname = (*lIte)->getType()->get_qname();
lTypeSs << lQname->getPrefix().str()
<< ":"
<< lQname->getLocalName().str();
- switch (lQuantifier) {
+
+ switch (lQuantifier)
+ {
case TypeConstants::QUANT_QUESTION:
lTypeSs << "?";
break;
=== modified file 'src/runtime/eval/eval.cpp'
--- src/runtime/eval/eval.cpp 2012-07-24 08:48:48 +0000
+++ src/runtime/eval/eval.cpp 2012-08-14 08:22:22 +0000
@@ -70,16 +70,18 @@
static_context* sctx,
const QueryLoc& loc,
std::vector<PlanIter_t>& children,
- const std::vector<store::Item_t>& aVarNames,
- const std::vector<xqtref_t>& aVarTypes,
+ const std::vector<store::Item_t>& varNames,
+ const std::vector<xqtref_t>& varTypes,
+ const std::vector<int>& isGlobalVar,
expr_script_kind_t scriptingKind,
const store::NsBindings& localBindings,
bool doNodeCopy,
bool forDebugger)
:
NaryBaseIterator<EvalIterator, EvalIteratorState>(sctx, loc, children),
- theVarNames(aVarNames),
- theVarTypes(aVarTypes),
+ theOuterVarNames(varNames),
+ theOuterVarTypes(varTypes),
+ theIsGlobalVar(isGlobalVar),
theScriptingKind(scriptingKind),
theLocalBindings(localBindings),
theDoNodeCopy(doNodeCopy),
@@ -106,8 +108,9 @@
serialize_baseclass(ar,
(NaryBaseIterator<EvalIterator, EvalIteratorState>*)this);
- ar & theVarNames;
- ar & theVarTypes;
+ ar & theOuterVarNames;
+ ar & theOuterVarTypes;
+ ar & theIsGlobalVar;
SERIALIZE_ENUM(enum expr_script_kind_t, theScriptingKind);
ar & theLocalBindings;
ar & theDoNodeCopy;
@@ -128,35 +131,14 @@
CONSUME(item, 0);
{
- csize numEvalVars = theVarNames.size();
-
- // Create an "outer" sctx and register into it (a) global vars corresponding
- // to the eval vars and (b) the expression-level ns bindings at the place
- // where the eval call appears at.
- static_context* outerSctx = theSctx->create_child_context();
-
- for (csize i = 0; i < numEvalVars; ++i)
- {
- var_expr_t ve = new var_expr(outerSctx,
- loc,
- var_expr::prolog_var,
- theVarNames[i].getp());
-
- ve->set_type(theVarTypes[i]);
-
- outerSctx->bind_var(ve, loc, err::XQST0049);
- }
-
- store::NsBindings::const_iterator ite = theLocalBindings.begin();
- store::NsBindings::const_iterator end = theLocalBindings.end();
-
- for (; ite != end; ++ite)
- {
- outerSctx->bind_ns(ite->first, ite->second, loc);
- }
+ // Create the "import" sctx. The importOuterEnv() method (called below) will
+ // register into the importSctx (a) the outer vars of the eval query and (b)
+ // the expression-level ns bindings of the outer query at the place where
+ // the eval call appears at.
+ static_context* importSctx = theSctx->create_child_context();
// Create the root sctx for the eval query
- static_context* evalSctx = outerSctx->create_child_context();
+ static_context* evalSctx = importSctx->create_child_context();
// Create the ccb for the eval query
CompilerCB* evalCCB = new CompilerCB(*planState.theCompilerCB);
@@ -171,9 +153,10 @@
dynamic_context* evalDctx = new dynamic_context(planState.theGlobalDynCtx);
state->dctx.reset(evalDctx);
- // Copy the values of outer vars into the evalDctx
+ // Import the outer environment.
+ std::vector<var_expr_t> outerVars;
ulong maxOuterVarId;
- copyOuterVariables(planState, outerSctx, evalDctx, maxOuterVarId);
+ importOuterEnv(planState, importSctx, evalDctx, outerVars, maxOuterVarId);
// If we are here after a reet, we must set state->thePlanWrapper to NULL
// before reseting the state->thePlan. Otherwise, the current state->thePlan
@@ -182,12 +165,10 @@
state->thePlanWrapper = NULL;
// Compile
- state->thePlan = compile(evalCCB,
- item->getStringValue(),
- maxOuterVarId);
+ state->thePlan = compile(evalCCB, item->getStringValue(), maxOuterVarId);
- // Set external vars
- setExternalVariables(evalCCB, outerSctx, evalSctx, evalDctx);
+ // Set the values for the (explicit) external vars of the eval query
+ setExternalVariables(evalCCB, importSctx, evalSctx, evalDctx);
// Execute
state->thePlanWrapper = new PlanWrapper(state->thePlan,
@@ -215,27 +196,49 @@
/****************************************************************************//**
- Copy the values of all the "outer" vars (i.e., global and eval vars) to the
- evalDctx. Also, compute the max varid of all these vars and pass this max varid
- to the compiler of the eval query so that the varids that will be generated for
- the eval query will not conflict with the varids of the global and eval vars.
+ This method imports a static and dynamic environment from the quter query into
+ the eval query. In particular:
+
+ (a) imports into the importSctx all the outer vars of the eval query
+ (b) imports into the importSctx all the ns bindings of the outer query at the
+ place where the eval call appears at
+ (c) Copies all the var values from the outer-query global dctx into the eval-
+ query dctx.
+ (d) For each of the non-global outer vars, places its value into the eval dctx.
+ The var value is represented as a PlanIteratorWrapper over the subplan that
+ evaluates the domain expr of the eval var.
+ (e) Computes the max var id of all the var values set in steps (c) and (d).
+ This max varid will be passed to the compiler of the eval query so that
+ the varids that will be generated for the eval query will not conflict with
+ the varids of the outer vars and the outer-query global vars.
********************************************************************************/
-void EvalIterator::copyOuterVariables(
+void EvalIterator::importOuterEnv(
PlanState& planState,
- static_context* outerSctx,
+ static_context* importSctx,
dynamic_context* evalDctx,
+ std::vector<var_expr_t>& outerVars,
ulong& maxOuterVarId) const
{
maxOuterVarId = 1;
+ // Copy all the var values from the outer-query global dctx into the eval-query
+ // dctx. This is need to handle the following scenario: (a) $x is an outer-query
+ // global var that is not among the outer vars of the eval query (because $x was
+ // hidden at the point where the eval call is made inside the outer query), and
+ // (b) foo() is a function decalred in the outer query that accessed $x and is
+ // invoked by the eval query. The copying must be done using the same positions
+ // (i.e., var ids) in the eval dctx as in the outer-query dctx.
+
dynamic_context* outerDctx = evalDctx->getParent();
- const std::vector<dynamic_context::VarValue>& outerVars = outerDctx->get_variables();
- csize numOuterVars = outerVars.size();
-
- for (csize i = 0; i < numOuterVars; ++i)
+ const std::vector<dynamic_context::VarValue>& outerGlobalValues =
+ outerDctx->get_variables();
+
+ csize numOuterGlobalVars = outerGlobalValues.size();
+
+ for (csize i = 0; i < numOuterGlobalVars; ++i)
{
- const dynamic_context::VarValue& outerVar = outerVars[i];
+ const dynamic_context::VarValue& outerVar = outerGlobalValues[i];
if (!outerVar.isSet())
continue;
@@ -262,23 +265,63 @@
++maxOuterVarId;
- // For each of the eval vars, place its value into the evalDctx. The var
- // value is represented as a PlanIteratorWrapper over the subplan that
- // evaluates the domain expr of the eval var.
- for (csize i = 0; i < theChildren.size() - 1; ++i)
- {
- var_expr* evalVar = outerSctx->lookup_var(theVarNames[i],
- loc,
- zerr::ZXQP0000_NO_ERROR);
- ZORBA_ASSERT(evalVar);
-
- evalVar->set_unique_id(maxOuterVarId);
-
- store::Iterator_t iter = new PlanIteratorWrapper(theChildren[i + 1], planState);
-
- evalDctx->add_variable(maxOuterVarId, iter);
-
- ++maxOuterVarId;
+ // Import the outer vars. Specifically, for each outer var:
+ // (a) create a declaration inside the importSctx.
+ // (b) Set its var id
+ // (c) If it is not a global one, set its value within the eval dctx.
+
+ csize curChild = 0;
+
+ csize numOuterVars = theOuterVarNames.size();
+
+ outerVars.resize(numOuterVars);
+
+ for (csize i = 0; i < numOuterVars; ++i)
+ {
+ var_expr_t ve = new var_expr(importSctx,
+ loc,
+ var_expr::prolog_var,
+ theOuterVarNames[i].getp());
+
+ ve->set_type(theOuterVarTypes[i]);
+
+ outerVars[i] = ve;
+
+ if (!theIsGlobalVar[i])
+ {
+ ++curChild;
+
+ store::Iterator_t iter = new PlanIteratorWrapper(theChildren[curChild], planState);
+
+ evalDctx->add_variable(maxOuterVarId, iter);
+
+ ve->set_unique_id(maxOuterVarId);
+
+ ++maxOuterVarId;
+ }
+ else
+ {
+ static_context* outerSctx = importSctx->get_parent();
+
+ VarInfo* outerGlobalVar = outerSctx->lookup_var(theOuterVarNames[i]);
+ ZORBA_ASSERT(outerGlobalVar);
+
+ ulong outerGlobalVarId = outerGlobalVar->getId();
+
+ ve->set_unique_id(outerGlobalVarId);
+ }
+
+ importSctx->bind_var(ve, loc, err::XQST0049);
+ }
+
+ // Import the outer-query ns bindings
+
+ store::NsBindings::const_iterator ite = theLocalBindings.begin();
+ store::NsBindings::const_iterator end = theLocalBindings.end();
+
+ for (; ite != end; ++ite)
+ {
+ importSctx->bind_ns(ite->first, ite->second, loc);
}
}
@@ -288,11 +331,11 @@
********************************************************************************/
void EvalIterator::setExternalVariables(
CompilerCB* ccb,
- static_context* outerSctx,
+ static_context* importSctx,
static_context* evalSctx,
dynamic_context* evalDctx) const
{
- std::vector<var_expr_t> innerVars;
+ std::vector<VarInfo*> innerVars;
CompilerCB::SctxMap::const_iterator sctxIte = ccb->theSctxMap.begin();
CompilerCB::SctxMap::const_iterator sctxEnd = ccb->theSctxMap.end();
@@ -302,27 +345,25 @@
sctxIte->second->getVariables(innerVars, true, false, true);
}
- FOR_EACH(std::vector<var_expr_t>, ite, innerVars)
+ FOR_EACH(std::vector<VarInfo*>, ite, innerVars)
{
- var_expr* innerVar = (*ite).getp();
+ VarInfo* innerVar = (*ite);
- if (!innerVar->is_external())
+ if (!innerVar->isExternal())
continue;
- ulong innerVarId = innerVar->get_unique_id();
-
- var_expr* globalVar = outerSctx->lookup_var(innerVar->get_name(),
- loc,
- zerr::ZXQP0000_NO_ERROR);
-
- if (globalVar == NULL)
+ ulong innerVarId = innerVar->getId();
+
+ VarInfo* outerVar = importSctx->lookup_var(innerVar->getName());
+
+ if (!outerVar)
continue;
store::Item_t itemValue;
store::TempSeq_t seqValue;
- evalDctx->get_variable(globalVar->get_unique_id(),
- globalVar->get_name(),
+ evalDctx->get_variable(outerVar->getId(),
+ outerVar->getName(),
loc,
itemValue,
seqValue);
=== modified file 'src/runtime/eval/eval.h'
--- src/runtime/eval/eval.h 2012-07-24 08:48:48 +0000
+++ src/runtime/eval/eval.h 2012-08-14 08:22:22 +0000
@@ -43,43 +43,74 @@
/****************************************************************************//**
The 1st child iterator computes the query string, and the next N child
- iterators compute the domain expression of each of the "eval" variables.
+ iterators compute the value of each of the non-global outer variables
+ (see below).
theVarNames:
------------
- The names of the "eval" vars. These will be added to the prolog of the eval
- query as external var declarations. If the prolog of the eval query declares
- or imports any variable with the same name as the name of an eval variable,
- then the inner var will hide the eval var. Furthermore, if the inner
+ The names of all the outer-query vars that are in scope at the place where the
+ eval expr appears. These will be "imported" to the prolog of the eval query as
+ global external var declarations. From the viewpoint of the eval query, we call
+ these vars the "outer vars" of the eval query. If the prolog of the eval query
+ declares or imports any variable with the same name as the name of an outer
+ var, then the explicit eval var will hide the implicit outer var.
theVarTypes:
------------
- The data types of the "eval" vars.
+ The data types of the outer vars.
+
+ theIsGlobalVar:
+ ----------------
+ For each of the outer vars, this bool vector says whether the var corresponds
+ to a global outer-query var. If yes, then its value should appear in the global
+ dcx of the outer query, and will be copied from there into the global dctx of
+ the inner query (using the same var id as the corresponding outer query var).
+
+ theScriptingKind:
+ -----------------
+
+ Tells whether the eval query is going to be sequential, updating, or simple.
+
+ theLocalBindings:
+ -----------------
+
+ theDoNodeCopy:
+ --------------
+
+ theForDebugger:
+ ---------------
+
********************************************************************************/
class EvalIterator : public NaryBaseIterator<EvalIterator, EvalIteratorState>
{
protected:
- std::vector<store::Item_t> theVarNames;
- std::vector<xqtref_t> theVarTypes;
+ std::vector<store::Item_t> theOuterVarNames;
+
+ std::vector<xqtref_t> theOuterVarTypes;
+
+ std::vector<int> theIsGlobalVar;
+
expr_script_kind_t theScriptingKind;
+
store::NsBindings theLocalBindings;
+
bool theDoNodeCopy;
+
bool theForDebugger;
public:
SERIALIZABLE_CLASS(EvalIterator);
-
SERIALIZABLE_CLASS_CONSTRUCTOR2T(EvalIterator,
NaryBaseIterator<EvalIterator, EvalIteratorState>);
-
void serialize(::zorba::serialization::Archiver& ar);
EvalIterator(
static_context* sctx,
const QueryLoc& loc,
std::vector<PlanIter_t>& children,
- const std::vector<store::Item_t>& aVarNames,
- const std::vector<xqtref_t>& aVarTypes,
+ const std::vector<store::Item_t>& varNames,
+ const std::vector<xqtref_t>& varTypes,
+ const std::vector<int>& isGlobalVar,
expr_script_kind_t scriptingKind,
const store::NsBindings& localBindings,
bool doNodeCopy,
@@ -92,15 +123,16 @@
bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
private:
- void copyOuterVariables(
+ void importOuterEnv(
PlanState& planState,
- static_context* outerSctx,
+ static_context* importSctx,
dynamic_context* evalDctx,
+ std::vector<var_expr_t>& outerVars,
ulong& maxOuterVarId) const;
-void setExternalVariables(
+ void setExternalVariables(
CompilerCB* ccb,
- static_context* outerSctx,
+ static_context* importSctx,
static_context* evalSctx,
dynamic_context* evalDctx) const;
=== modified file 'src/runtime/introspection/pregenerated/sctx.cpp'
--- src/runtime/introspection/pregenerated/sctx.cpp 2012-07-24 08:48:48 +0000
+++ src/runtime/introspection/pregenerated/sctx.cpp 2012-08-14 08:22:22 +0000
@@ -30,7 +30,6 @@
#include "store/api/iterator.h"
-#include "compiler/expression/var_expr.h"
namespace zorba {
=== modified file 'src/runtime/introspection/pregenerated/sctx.h'
--- src/runtime/introspection/pregenerated/sctx.h 2012-07-24 08:48:48 +0000
+++ src/runtime/introspection/pregenerated/sctx.h 2012-08-14 08:22:22 +0000
@@ -29,6 +29,7 @@
#include "runtime/base/narybase.h"
+#include "context/static_context.h"
namespace zorba {
@@ -216,8 +217,8 @@
class InscopeVariablesIteratorState : public PlanIteratorState
{
public:
- std::vector<var_expr_t> theVariables; //vector of variables
- ulong thePosition; //current position
+ std::vector<VarInfo*> theVariables; //vector of variables
+ csize thePosition; //current position
InscopeVariablesIteratorState();
=== modified file 'src/runtime/introspection/sctx_impl.cpp'
--- src/runtime/introspection/sctx_impl.cpp 2012-07-24 08:48:48 +0000
+++ src/runtime/introspection/sctx_impl.cpp 2012-08-14 08:22:22 +0000
@@ -28,8 +28,6 @@
#include "context/dynamic_context.h"
#include "context/static_context_consts.h"
-#include "compiler/expression/var_expr.h"
-
#include "runtime/introspection/sctx.h"
#include "functions/function.h"
@@ -141,7 +139,7 @@
while (state->thePosition < state->theVariables.size())
{
- aResult = state->theVariables[state->thePosition]->get_name();
+ aResult = state->theVariables[state->thePosition]->getName();
STACK_PUSH(true, state);
++state->thePosition;
}
=== modified file 'src/runtime/spec/introspection/sctx.xml'
--- src/runtime/spec/introspection/sctx.xml 2012-07-24 08:48:48 +0000
+++ src/runtime/spec/introspection/sctx.xml 2012-08-14 08:22:22 +0000
@@ -10,9 +10,12 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.zorba-xquery.com ../runtime.xsd">
+<zorba:header>
+ <zorba:include form="Quoted">context/static_context.h</zorba:include>
+</zorba:header>
+
<zorba:source>
- <zorba:include form="Quoted">store/api/iterator.h</zorba:include>
- <zorba:include form="Quoted">compiler/expression/var_expr.h</zorba:include>
+ <zorba:include form="Quoted">store/api/iterator.h</zorba:include>
</zorba:source>
<!--
@@ -126,9 +129,9 @@
</zorba:function>
<zorba:state generateReset="false" generateDestructor="false">
- <zorba:member type="std::vector<var_expr_t>" name="theVariables"
+ <zorba:member type="std::vector<VarInfo*>" name="theVariables"
brief="vector of variables"/>
- <zorba:member type="ulong" name="thePosition" brief="current position"/>
+ <zorba:member type="csize" name="thePosition" brief="current position"/>
</zorba:state>
</zorba:iterator>
=== modified file 'src/zorbaserialization/archiver_consts.h'
--- src/zorbaserialization/archiver_consts.h 2012-07-11 15:38:39 +0000
+++ src/zorbaserialization/archiver_consts.h 2012-08-14 08:22:22 +0000
@@ -363,6 +363,7 @@
TYPE_DecimalFormat,
TYPE_BaseUriInfo,
+ TYPE_VarInfo,
TYPE_FunctionInfo,
TYPE_PrologOption,
TYPE_sctx_module,
=== modified file 'src/zorbautils/hashmap.h'
--- src/zorbautils/hashmap.h 2012-07-24 08:48:48 +0000
+++ src/zorbautils/hashmap.h 2012-08-14 08:22:22 +0000
@@ -427,6 +427,9 @@
SYNC_CODE(AutoMutex lock(theMutexp);)
+ if (empty())
+ return false;
+
const HashEntry<T, V>* entry = bucket(hval);
if (entry->isFree())
@@ -455,6 +458,9 @@
SYNC_CODE(AutoMutex lock(theMutexp);)
+ if (empty())
+ return end();
+
const HashEntry<T, V>* entry = bucket(hval);
if (entry->isFree())
@@ -482,6 +488,9 @@
SYNC_CODE(AutoMutex lock(theMutexp);)
+ if (empty())
+ return false;
+
const HashEntry<T, V>* entry = bucket(hval);
if (entry->isFree())
=== modified file 'test/rbkt/Queries/zorba/modules/extvarModule-A.xqlib'
--- test/rbkt/Queries/zorba/modules/extvarModule-A.xqlib 2012-07-24 08:48:48 +0000
+++ test/rbkt/Queries/zorba/modules/extvarModule-A.xqlib 2012-08-14 08:22:22 +0000
@@ -9,6 +9,7 @@
import module namespace zm-B = "http://zorbatest.lambda.nu/modules-B"
at "extvarModule-B.xqlib";
+
declare function zm-A:getVar()
{
zm-B:getVar()
=== modified file 'test/rbkt/Queries/zorba/reflection/client.xqlib'
--- test/rbkt/Queries/zorba/reflection/client.xqlib 2012-07-24 08:48:48 +0000
+++ test/rbkt/Queries/zorba/reflection/client.xqlib 2012-08-14 08:22:22 +0000
@@ -1,20 +1,25 @@
module namespace client = "http://pilman.ch/ns/blubb";
declare variable $client:public as xs:string := "public";
+
declare %private variable $client:oauth-token1 as xs:string := "private token1";
+
declare %private variable $client:oauth-token2 as xs:string := "private token2";
+
declare function client:public()
{
- $client:public
+ $client:public
};
+
declare function client:tweets1()
{
- $client:oauth-token1
+ $client:oauth-token1
};
+
declare function client:tweets2()
{
- $client:oauth-token2
+ $client:oauth-token2
};
=== added file 'test/rbkt/Queries/zorba/reflection/reflection-eval-04.spec'
--- test/rbkt/Queries/zorba/reflection/reflection-eval-04.spec 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/reflection/reflection-eval-04.spec 2012-08-14 08:22:22 +0000
@@ -0,0 +1,1 @@
+Error: http://www.w3.org/2005/xqt-errors:XPST0008
=== added file 'test/rbkt/Queries/zorba/reflection/reflection-eval-04.xq'
--- test/rbkt/Queries/zorba/reflection/reflection-eval-04.xq 1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/reflection/reflection-eval-04.xq 2012-08-14 08:22:22 +0000
@@ -0,0 +1,5 @@
+import module namespace reflection = "http://www.zorba-xquery.com/modules/reflection";
+import module namespace client = "http://pilman.ch/ns/blubb" at "client.xqlib";
+
+for $i in (1 to 2)
+return reflection:eval-s("$i, $client:oauth-token1")
=== modified file 'test/rbkt/Queries/zorba/xqddf/test1_mod2.xqlib'
--- test/rbkt/Queries/zorba/xqddf/test1_mod2.xqlib 2012-07-24 08:48:48 +0000
+++ test/rbkt/Queries/zorba/xqddf/test1_mod2.xqlib 2012-08-14 08:22:22 +0000
@@ -5,12 +5,15 @@
import module namespace ddl = "http://www.zorba-xquery.com/modules/store/static/collections/ddl";
import module namespace dml = "http://www.zorba-xquery.com/modules/store/static/collections/dml";
+
import module namespace module1 = "http://www.zorba-xquery.com/module1" at "test1_mod1.xqlib";
declare namespace ann = "http://www.zorba-xquery.com/annotations";
+
declare collection module2:coll as node()*;
+
declare variable $module2:coll as xs:QName := xs:QName("module2:coll");
=== modified file 'test/rbkt/Queries/zorba/xqddf/test4.xqlib'
--- test/rbkt/Queries/zorba/xqddf/test4.xqlib 2012-07-24 08:48:48 +0000
+++ test/rbkt/Queries/zorba/xqddf/test4.xqlib 2012-08-14 08:22:22 +0000
@@ -10,11 +10,16 @@
declare namespace ann = "http://www.zorba-xquery.com/annotations";
+
declare collection n:foo as node();
+
declare %ann:automatic %ann:nonunique %ann:value-equality index n:index
on nodes dml:collection(xs:QName("n:foo"))
- by (if (fn:data(d:userrecord/d:company)) then d:userrecord/d:company else "none") as xs:string;
+ by (if (fn:data(d:userrecord/d:company))
+ then d:userrecord/d:company
+ else "none") as xs:string;
+
declare %ann:sequential function n:foo()
{
Follow ups