← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/bug1123016 into lp:zorba

 

Juan Zacarias has proposed merging lp:~zorba-coders/zorba/bug1123016 into lp:zorba.

Commit message:
Implmentation of two new functions for xqxq module xqxq:query-plan and xqxq:load-from-query-plan

Requested reviews:
  Matthias Brantner (matthias-brantner)
  Chris Hillery (ceejatec)
Related bugs:
  Bug #1123016 in Zorba: "FOTS driver does not run the tests thorugh the plan serializer"
  https://bugs.launchpad.net/zorba/+bug/1123016

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug1123016/+merge/155082

Implmentation of two new functions for xqxq module xqxq:query-plan and xqxq:load-from-query-plan
-- 
https://code.launchpad.net/~zorba-coders/zorba/bug1123016/+merge/155082
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'modules/xqxq/xqxq.xq'
--- modules/xqxq/xqxq.xq	2013-03-15 18:25:44 +0000
+++ modules/xqxq/xqxq.xq	2013-03-22 23:43:21 +0000
@@ -387,6 +387,15 @@
   xs:QName) as item()* external;
 
 
+declare function xqxq:query-plan($query-key as xs:anyURI) 
+  as xs:base64Binary external;
+  
+declare function xqxq:load-from-query-plan($plan as xs:base64Binary)
+  as xs:anyURI external;
+  
+declare function xqxq:load-from-query-plan($plan as xs:base64Binary,
+  $resolver as item()?, $mapper as item()?) as xs:anyURI external;
+
 (:~
  : Internal helper function. Only necessary because of incomplete HOF
  : support in Zorba.

=== modified file 'modules/xqxq/xqxq.xq.src/xqxq.cpp'
--- modules/xqxq/xqxq.xq.src/xqxq.cpp	2013-03-13 16:17:38 +0000
+++ modules/xqxq/xqxq.xq.src/xqxq.cpp	2013-03-22 23:43:21 +0000
@@ -85,6 +85,14 @@
     {
       lFunc = new VariableValueFunction(this);
     }
+    else if (localName == "query-plan")
+    {
+      lFunc = new QueryPlanFunction(this);
+    }
+    else if (localName == "load-from-query-plan")
+    {
+      lFunc = new LoadFromQueryPlanFunction(this);
+    }
   }
   
   return lFunc;
@@ -325,7 +333,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-void  PrepareMainModuleFunction::XQXQURIMapper::mapURI(
+void  XQXQURIMapper::mapURI(
     String aUri,
     EntityData const* aEntityData,
     std::vector<String>& oUris)
@@ -376,7 +384,7 @@
 /*******************************************************************************
 
 ********************************************************************************/
-Resource* PrepareMainModuleFunction::XQXQURLResolver::resolveURL(
+Resource* XQXQURLResolver::resolveURL(
     const String& aUrl,
     EntityData const* aEntityData)
 { 
@@ -964,7 +972,126 @@
   }
 }
 
+/*******************************************************************************
+
+********************************************************************************/
+zorba::ItemSequence_t QueryPlanFunction::evaluate(
+    const Arguments_t& aArgs,
+    const zorba::StaticContext* aSctx,
+    const zorba::DynamicContext* aDctx) const 
+{
+  String lQueryID = XQXQFunction::getOneStringArgument(aArgs,0);
+
+  QueryMap* lQueryMap;
+  if (!(lQueryMap= dynamic_cast<QueryMap*>(aDctx->getExternalFunctionParameter("xqxqQueryMap"))))
+  {
+    throwError("NoQueryMatch", "String identifying query does not exists.");
+  }
+
+  XQuery_t lQuery = getQuery(aDctx, lQueryID);
+
+  std::stringstream* lExcPlan = new std::stringstream();
+  if (!lQuery->saveExecutionPlan(*lExcPlan, ZORBA_USE_BINARY_ARCHIVE))
+  {
+    throwError("QueryPlanError", "FAILED getting query execution plan.");
+  }
+  
+  return ItemSequence_t(new SingletonItemSequence(XQXQModule::getItemFactory()->createStreamableBase64Binary(*lExcPlan, &streamReleaser)));
+}
  
+
+/*******************************************************************************
+
+********************************************************************************/
+zorba::ItemSequence_t LoadFromQueryPlanFunction::evaluate(
+    const Arguments_t& aArgs,
+    const zorba::StaticContext* aSctx,
+    const zorba::DynamicContext* aDctx) const 
+{
+  Item lQueryPlanItem = XQXQFunction::getItemArgument(aArgs,0);
+  std::istream& lQueryPlanStream = lQueryPlanItem.getStream();
+
+  DynamicContext* lDynCtx = const_cast<DynamicContext*>(aDctx);
+  StaticContext_t lSctxChild = aSctx->createChildContext();
+   
+  QueryMap* lQueryMap;
+  if (!(lQueryMap = dynamic_cast<QueryMap*>(lDynCtx->getExternalFunctionParameter("xqxqQueryMap"))))
+  {
+    lQueryMap = new QueryMap();
+    lDynCtx->addExternalFunctionParameter("xqxqQueryMap", lQueryMap);     
+  }
+
+  Zorba* lZorba = Zorba::getInstance(0);
+  XQuery_t lQuery;
+  
+  std::auto_ptr<XQXQURLResolver> lResolver;
+  std::auto_ptr<XQXQURIMapper> lMapper;
+  try
+  {
+    lQuery = lZorba->createQuery();
+    if ( aArgs.size() > 2)
+    {
+      QueryPlanSerializationCallback lPlanSer;
+
+      Item lMapperFunctionItem = getItemArgument(aArgs, 2);
+      if (!lMapperFunctionItem.isNull())
+      {
+        lMapper.reset(new XQXQURIMapper(lMapperFunctionItem, lSctxChild));
+        lPlanSer.add_URIMapper(lMapper.get());
+      }
+
+      Item lResolverFunctionItem = getItemArgument(aArgs, 1);
+      if (!lResolverFunctionItem.isNull())
+      {
+        lResolver.reset(new XQXQURLResolver(lResolverFunctionItem, lSctxChild));
+        lPlanSer.add_URLResolver(lResolver.get());
+      }
+
+      lQuery->loadExecutionPlan(lQueryPlanStream, &lPlanSer);
+    }
+    else
+    { 
+      lQuery->loadExecutionPlan(lQueryPlanStream);
+    }
+  }
+  catch (XQueryException& xe)
+  {
+    lQuery = NULL;
+    std::ostringstream err;
+    err << "The query loaded from the query plan raised an error at"
+      << " file" << xe.source_uri() << " line" << xe.source_line()
+      << " column" << xe.source_column() << ": " << xe.what();
+    Item errQName = XQXQModule::getItemFactory()->createQName(
+      xe.diagnostic().qname().ns(),
+      xe.diagnostic().qname().localname());
+    throw USER_EXCEPTION(errQName, err.str());
+  }
+  catch (ZorbaException& ze)
+  {
+    lQuery = NULL;
+    std::ostringstream err;
+    if (ze.diagnostic() == zerr::ZCSE0013_UNABLE_TO_LOAD_QUERY)
+      err << "The query loaded from the query plan raised an error: failed to load pre-compiled query: document, collection, or module resolver required but not given.";
+    else
+      err << "The query loaded from the query plan raised an error: "<< ze.what();
+    Item errQName = XQXQModule::getItemFactory()->createQName(
+      ze.diagnostic().qname().ns(),
+      ze.diagnostic().qname().localname());
+    throw USER_EXCEPTION(errQName, err.str());
+  }
+
+  uuid lUUID;
+  uuid::create(&lUUID);
+
+  std::stringstream lStream;
+  lStream << lUUID;
+
+  String lStrUUID = lStream.str();
+
+  lQueryMap->storeQuery(lStrUUID, lQuery, lMapper.release(), lResolver.release());
+  return ItemSequence_t(new SingletonItemSequence(XQXQModule::getItemFactory()->createAnyURI(lStrUUID)));
+}
+
 }/*namespace xqxq*/ }/*namespace zorba*/
 
 #ifdef WIN32

=== modified file 'modules/xqxq/xqxq.xq.src/xqxq.h'
--- modules/xqxq/xqxq.xq.src/xqxq.h	2013-02-15 06:11:20 +0000
+++ modules/xqxq/xqxq.xq.src/xqxq.h	2013-03-22 23:43:21 +0000
@@ -7,6 +7,7 @@
 #include <zorba/external_module.h>
 #include <zorba/function.h>
 #include <zorba/dynamic_context.h>
+#include <zorba/serialization_callback.h>
 
 #define XQXQ_MODULE_NAMESPACE "http://www.zorba-xquery.com/modules/xqxq";
 
@@ -51,6 +52,52 @@
 
 
 /*******************************************************************************
+
+********************************************************************************/
+class XQXQURLResolver : public URLResolver
+{
+protected:
+  Item             theFunction;
+  StaticContext_t  theCtx;
+
+public:
+  XQXQURLResolver(Item& aFunction, StaticContext_t& aSctx)
+    :
+    URLResolver(),
+    theFunction(aFunction),
+    theCtx(aSctx)
+  {
+  }
+        
+  virtual ~XQXQURLResolver() { }
+      
+  virtual Resource* resolveURL(const String& url, EntityData const* entityData);
+};
+  
+
+class XQXQURIMapper : public URIMapper
+{
+protected:
+  Item            theFunction;
+  StaticContext_t theCtx;
+    
+public:
+  XQXQURIMapper(Item& aFunction, StaticContext_t& aSctx)
+    :
+    URIMapper(),
+    theFunction(aFunction),
+    theCtx(aSctx)
+  {
+  }
+    
+  virtual ~XQXQURIMapper(){ }
+    
+  virtual void mapURI(
+    const zorba::String aUri,
+    EntityData const* aEntityData,
+    std::vector<zorba::String>& oUris);
+};
+/*******************************************************************************
   Bag class for objects associated with a prepared query
 ********************************************************************************/
 class QueryData : public SmartObject
@@ -144,52 +191,6 @@
   evaluate(const Arguments_t&,
            const zorba::StaticContext*,
            const zorba::DynamicContext*) const;
-  
-protected:
-  
-  class XQXQURLResolver : public URLResolver
-  {
-  protected:
-    Item             theFunction;
-    StaticContext_t  theCtx;
-
-  public:
-    XQXQURLResolver(Item& aFunction, StaticContext_t& aSctx)
-      :
-      URLResolver(),
-      theFunction(aFunction),
-      theCtx(aSctx)
-    {
-    }
-        
-    virtual ~XQXQURLResolver() { }
-      
-    virtual Resource* resolveURL(const String& url, EntityData const* entityData);
-  };
-  
-
-  class XQXQURIMapper : public URIMapper
-  {
-  protected:
-    Item            theFunction;
-    StaticContext_t theCtx;
-    
-  public:
-    XQXQURIMapper(Item& aFunction, StaticContext_t& aSctx)
-      :
-      URIMapper(),
-      theFunction(aFunction),
-      theCtx(aSctx)
-    {
-    }
-    
-    virtual ~XQXQURIMapper(){ }
-    
-    virtual void mapURI(
-      const zorba::String aUri,
-      EntityData const* aEntityData,
-      std::vector<zorba::String>& oUris);
-  };
 };
 
 
@@ -561,7 +562,87 @@
                  const zorba::DynamicContext*) const;
   };
 
-
+/*******************************************************************************
+
+********************************************************************************/
+class QueryPlanFunction : public XQXQFunction
+{
+public:
+  QueryPlanFunction(const XQXQModule* aModule) : XQXQFunction(aModule) {}
+
+  virtual ~QueryPlanFunction() {}
+
+  virtual zorba::String
+  getLocalName() const {return "query-plan"; }
+
+  virtual zorba::ItemSequence_t
+  evaluate(const Arguments_t&,
+           const zorba::StaticContext*,
+           const zorba::DynamicContext*) const;
+  
+  virtual String getURI() const {
+    return theModule->getURI();
+  }
+  
+protected:
+  const XQXQModule* theModule;
+};
+
+
+/*******************************************************************************
+
+********************************************************************************/
+class LoadFromQueryPlanFunction : public XQXQFunction
+{
+public:
+  LoadFromQueryPlanFunction(const XQXQModule* aModule) : XQXQFunction(aModule) {}
+
+  virtual ~LoadFromQueryPlanFunction() {}
+
+  virtual zorba::String
+  getLocalName() const {return "load-from-query-plan"; }
+
+  virtual zorba::ItemSequence_t
+  evaluate(const Arguments_t&,
+           const zorba::StaticContext*,
+           const zorba::DynamicContext*) const;
+  
+  virtual String getURI() const {
+    return theModule->getURI();
+  }
+  
+protected:
+  const XQXQModule* theModule;
+
+  class QueryPlanSerializationCallback : public zorba::SerializationCallback
+  {
+    std::vector<URIMapper*> theUriMappers;
+    std::vector<URLResolver*>theUrlResolvers;
+
+  public:
+    QueryPlanSerializationCallback()
+    {
+    }
+
+    virtual ~QueryPlanSerializationCallback() {}
+
+    void add_URIMapper(URIMapper* aMapper)
+    {
+      theUriMappers.push_back(aMapper);
+    }
+
+    void add_URLResolver(URLResolver* aResolver)
+    {
+      theUrlResolvers.push_back(aResolver);
+    }
+
+    virtual URIMapper*
+      getURIMapper(size_t  i ) const { return theUriMappers.size() < i? NULL : theUriMappers[i]; }
+
+    virtual URLResolver*
+    getURLResolver(size_t i) const { return theUrlResolvers.size() < i? NULL : theUrlResolvers[i]; }
+  };
+};
 }/*xqxq namespace*/}/*zorba namespace*/
 
 

=== modified file 'src/compiler/api/compilercb.cpp'
--- src/compiler/api/compilercb.cpp	2013-03-20 23:33:11 +0000
+++ src/compiler/api/compilercb.cpp	2013-03-22 23:43:21 +0000
@@ -201,6 +201,7 @@
   ar & theIsEval;
   ar & theIsLoadProlog;
   ar & theIsUpdating;
+  ar & theIsSequential;
   ar & theSctxMap;
   ar & theRootSctx;
 #ifdef ZORBA_WITH_DEBUGGER

=== added file 'test/rbkt/ExpQueryResults/zorba/xqxq/query-plan.xml.res'
--- test/rbkt/ExpQueryResults/zorba/xqxq/query-plan.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/xqxq/query-plan.xml.res	2013-03-22 23:43:21 +0000
@@ -0,0 +1,1 @@
+2
\ No newline at end of file

=== added file 'test/rbkt/ExpQueryResults/zorba/xqxq/query-plan2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/xqxq/query-plan2.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/xqxq/query-plan2.xml.res	2013-03-22 23:43:21 +0000
@@ -0,0 +1,1 @@
+foo
\ No newline at end of file

=== added file 'test/rbkt/ExpQueryResults/zorba/xqxq/query-plan3.xml.res'
--- test/rbkt/ExpQueryResults/zorba/xqxq/query-plan3.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/xqxq/query-plan3.xml.res	2013-03-22 23:43:21 +0000
@@ -0,0 +1,1 @@
+foo
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/xqxq/query-plan.xq'
--- test/rbkt/Queries/zorba/xqxq/query-plan.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/xqxq/query-plan.xq	2013-03-22 23:43:21 +0000
@@ -0,0 +1,6 @@
+import module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq';
+
+variable $queryID := xqxq:prepare-main-module("1+1");
+variable $query-plan := xqxq:query-plan($queryID); 
+variable $queryID2 := xqxq:load-from-query-plan($query-plan);
+xqxq:evaluate ($queryID2)

=== added file 'test/rbkt/Queries/zorba/xqxq/query-plan2.xq'
--- test/rbkt/Queries/zorba/xqxq/query-plan2.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/xqxq/query-plan2.xq	2013-03-22 23:43:21 +0000
@@ -0,0 +1,20 @@
+import module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq';
+
+declare namespace resolver = 'http://www.zorba-xquery.com/modules/xqxq/url-resolver';
+declare namespace op = "http://www.zorba-xquery.com/options/features";;
+declare namespace f = "http://www.zorba-xquery.com/features";;
+
+declare function resolver:url-resolver($namespace as xs:string, $entity as xs:string) {
+  if($namespace = 'http://test.xq')
+  then "module namespace test = 'http://test'; declare function test:foo(){'foo'};"
+  else ()
+};
+
+variable $queryID := xqxq:prepare-main-module(
+  "import module namespace test = 'http://test'; test:foo()",
+  resolver:url-resolver#2, ());
+
+
+variable $query-plan := xqxq:query-plan($queryID); 
+variable $queryID2 := xqxq:load-from-query-plan($query-plan, resolver:url-resolver#2, ());
+xqxq:evaluate ($queryID2)

=== added file 'test/rbkt/Queries/zorba/xqxq/query-plan3.xq'
--- test/rbkt/Queries/zorba/xqxq/query-plan3.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/xqxq/query-plan3.xq	2013-03-22 23:43:21 +0000
@@ -0,0 +1,28 @@
+import module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq';
+
+declare namespace resolver = 'http://www.zorba-xquery.com/modules/xqxq/url-resolver';
+declare namespace mapper = 'http://www.zorba-xquery.com/modules/xqxq/uri-mapper';
+declare namespace op = "http://www.zorba-xquery.com/options/features";;
+declare namespace f = "http://www.zorba-xquery.com/features";;
+
+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 ()
+};
+
+declare function mapper:uri-mapper($namespace as xs:string, $entity as xs:string)
+{
+   if($namespace = 'http://test')
+   then 'http://foo'
+   else ()
+};
+
+variable $queryID := xqxq:prepare-main-module
+(
+  "import module namespace test = 'http://test'; test:foo()", 
+  resolver:url-resolver#2, mapper:uri-mapper#2
+);
+variable $query-plan := xqxq:query-plan($queryID); 
+variable $queryID2 := xqxq:load-from-query-plan($query-plan, resolver:url-resolver#2, mapper:uri-mapper#2);
+xqxq:evaluate ($queryID2)

=== added file 'test/rbkt/Queries/zorba/xqxq/query-plan4.spec'
--- test/rbkt/Queries/zorba/xqxq/query-plan4.spec	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/xqxq/query-plan4.spec	2013-03-22 23:43:21 +0000
@@ -0,0 +1,1 @@
+Error: http://www.zorba-xquery.com/errors:ZCSE0013

=== added file 'test/rbkt/Queries/zorba/xqxq/query-plan4.xq'
--- test/rbkt/Queries/zorba/xqxq/query-plan4.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/xqxq/query-plan4.xq	2013-03-22 23:43:21 +0000
@@ -0,0 +1,28 @@
+import module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq';
+
+declare namespace resolver = 'http://www.zorba-xquery.com/modules/xqxq/url-resolver';
+declare namespace mapper = 'http://www.zorba-xquery.com/modules/xqxq/uri-mapper';
+declare namespace op = "http://www.zorba-xquery.com/options/features";;
+declare namespace f = "http://www.zorba-xquery.com/features";;
+
+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 ()
+};
+
+declare function mapper:uri-mapper($namespace as xs:string, $entity as xs:string)
+{
+   if($namespace = 'http://test')
+   then 'http://foo'
+   else ()
+};
+
+variable $queryID := xqxq:prepare-main-module
+(
+  "import module namespace test = 'http://test'; test:foo()", 
+  resolver:url-resolver#2, mapper:uri-mapper#2
+);
+variable $query-plan := xqxq:query-plan($queryID); 
+variable $queryID2 := xqxq:load-from-query-plan($query-plan);
+xqxq:evaluate ($queryID2)


Follow ups