Matthias Brantner has proposed merging lp:~zorba-coders/zorba/bug-938934 into 
lp:zorba.

Requested reviews:
  Matthias Brantner (matthias-brantner)
  Markos Zaharioudakis (markos-za)
  Till Westmann (tillw)
Related bugs:
  Bug #938934 in Zorba: "collection dml:truncate function missing"
  https://bugs.launchpad.net/zorba/+bug/938934

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

- fix bug #938934 "collection dml:truncate function missing"
- fixes documentation bug: raise zerr:ZDDY0003 instead of zerr:ZDDY0009
-- 
https://code.launchpad.net/~zorba-coders/zorba/bug-938934/+merge/96501
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2012-03-07 15:49:25 +0000
+++ ChangeLog	2012-03-08 01:45:27 +0000
@@ -10,6 +10,7 @@
     %ann:must-copy-input-nodes to be used by the no-copy optimization.
   * Caching of results for recursive functions with atomic parameter and return types.
   * Added %ann:cache and %ann:no-cache to enable or disable caching of results of functions with atomic parameter and return types.
+  * Added truncate function to the collection modules for efficient deletion of all nodes in a collection.
   * Fixed bug 917923 (bug in copying outer var values into the eval dynamic context)
   * Fixed bug 867509 (Can not handle largest xs:unsignedLong values)
   * Fixed bug 924063 (sentence is incorrectly incremented when token characters end without sentence terminator)

=== modified file 'modules/com/zorba-xquery/www/modules/store/dynamic/collections/dml.xq'
--- modules/com/zorba-xquery/www/modules/store/dynamic/collections/dml.xq	2011-08-26 23:36:24 +0000
+++ modules/com/zorba-xquery/www/modules/store/dynamic/collections/dml.xq	2012-03-08 01:45:27 +0000
@@ -260,7 +260,7 @@
  : @return The result of this function is an empty XDM instance and a pending update
  :         list which, once applied, deletes the last node from the collection.
  :
- : @error zerr:ZDDY0009 If available collections does not provide a mapping
+ : @error zerr:ZDDY0003 If available collections does not provide a mapping
  :        for the expanded QName $name.
  : @error zerr:ZDDY0011 if the collection doesn't contain any node.
  :
@@ -278,7 +278,7 @@
  : @return The result of this function is an empty XDM instance and a pending update
  :         list which, once applied, deletes the last n nodes.
  :
- : @error zerr:ZDDY0009 If available collections does not provide a mapping
+ : @error zerr:ZDDY0003 If available collections does not provide a mapping
  :        for the expanded QName $name.
  : @error zerr:ZDDY0011 if the collection doesn't contain the given number of nodes.
  :
@@ -288,6 +288,19 @@
   $number as xs:integer) external;
 
 (:~
+ : The truncate function is an updating function that deletes the
+ : entire contents of collection.
+ :
+ : @param $name The name of the collection whose content to delete
+ :
+ : @return The result of this function is an empty XDM instance and a pending update
+ :         list which, once applied, deletes the nodes.
+ :
+ : @error zerr:ZDDY0003 if the collection identified by $name is not available.
+ :)
+declare updating function dml:truncate($name as xs:QName) external;
+
+(:~
  : The index-of function return the index of the given node in the collection.
  :
  : @param $node The node to retrieve the index from.
@@ -307,7 +320,7 @@
  :
  : @return The sequence contained in the given collection.
  :
- : @error zerr:ZDDY0009 If available collections does not provide a mapping
+ : @error zerr:ZDDY0003 If available collections does not provide a mapping
  :        for the expanded QName $name.
  :
  :)

=== modified file 'modules/com/zorba-xquery/www/modules/store/static/collections/dml.xq'
--- modules/com/zorba-xquery/www/modules/store/static/collections/dml.xq	2011-10-03 09:18:49 +0000
+++ modules/com/zorba-xquery/www/modules/store/static/collections/dml.xq	2012-03-08 01:45:27 +0000
@@ -409,6 +409,21 @@
   $number as xs:integer)  external;
 
 (:~
+ : The truncate function is an updating function that deletes the
+ : entire contents of collection.
+ :
+ : @param $name The name of the collection whose content to delete
+ :
+ : @return The result of this function is an empty XDM instance and a pending update
+ :         list which, once applied, deletes the nodes.
+ :
+ : @error zerr:ZDDY0001 if the collection identified by $name is not declared.
+ : @error zerr:ZDDY0003 if the collection identified by $name is not available.
+ :
+ :)
+declare updating function cdml:truncate($name as xs:QName) external;
+
+(:~
  : The index-of function that returns the position of the node in its collection.
  :
  : @param $node The node to retrieve the index for.

=== modified file 'src/functions/func_collections_impl.cpp'
--- src/functions/func_collections_impl.cpp	2012-02-16 12:48:17 +0000
+++ src/functions/func_collections_impl.cpp	2012-03-08 01:45:27 +0000
@@ -293,6 +293,21 @@
 /*******************************************************************************
 
 ********************************************************************************/
+PlanIter_t zorba_store_collections_static_dml_truncate::codegen(
+  CompilerCB*,
+  static_context* sctx,
+  const QueryLoc& loc,
+  std::vector<PlanIter_t>& argv,
+  expr& ann) const
+{
+  return new ZorbaTruncateCollectionIterator(sctx, loc, argv,
+      getName()->getNamespace() == static_context::ZORBA_STORE_DYNAMIC_COLLECTIONS_DML_FN_NS);
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 PlanIter_t zorba_store_collections_static_dml_delete_node_first::codegen(
   CompilerCB*,
   static_context* sctx,

=== modified file 'src/functions/pregenerated/func_collections.cpp'
--- src/functions/pregenerated/func_collections.cpp	2012-02-16 12:48:17 +0000
+++ src/functions/pregenerated/func_collections.cpp	2012-03-08 01:45:27 +0000
@@ -58,6 +58,7 @@
 
 
 
+
 PlanIter_t zorba_store_collections_static_dml_collection_name::codegen(
   CompilerCB*,
   static_context* sctx,
@@ -686,6 +687,30 @@
   {
     
 
+    DECL_WITH_KIND(sctx, zorba_store_collections_static_dml_truncate,
+        (createQName("http://www.zorba-xquery.com/modules/store/static/collections/dml","","truncate";), 
+        GENV_TYPESYSTEM.QNAME_TYPE_ONE, 
+        GENV_TYPESYSTEM.EMPTY_TYPE),
+        FunctionConsts::ZORBA_STORE_COLLECTIONS_STATIC_DML_TRUNCATE_1);
+
+  }
+
+
+  {
+    
+
+    DECL_WITH_KIND(sctx, zorba_store_collections_static_dml_truncate,
+        (createQName("http://www.zorba-xquery.com/modules/store/dynamic/collections/dml","","truncate";), 
+        GENV_TYPESYSTEM.QNAME_TYPE_ONE, 
+        GENV_TYPESYSTEM.EMPTY_TYPE),
+        FunctionConsts::ZORBA_STORE_DYNAMIC_COLLECTIONS_DML_TRUNCATE_1);
+
+  }
+
+
+  {
+    
+
     DECL_WITH_KIND(sctx, zorba_store_collections_static_dml_collection_name,
         (createQName("http://www.zorba-xquery.com/modules/store/static/collections/dml","","collection-name";), 
         GENV_TYPESYSTEM.ANY_NODE_TYPE_ONE, 

=== modified file 'src/functions/pregenerated/func_collections.h'
--- src/functions/pregenerated/func_collections.h	2012-01-11 17:30:25 +0000
+++ src/functions/pregenerated/func_collections.h	2012-03-08 01:45:27 +0000
@@ -434,6 +434,25 @@
 };
 
 
+//zorba-store-collections-static-dml:truncate
+class zorba_store_collections_static_dml_truncate : public function
+{
+public:
+  zorba_store_collections_static_dml_truncate(const signature& sig, FunctionConsts::FunctionKind kind)
+    : 
+    function(sig, kind)
+  {
+
+  }
+
+  short getScriptingKind() const { return UPDATING_EXPR; }
+
+  bool accessesDynCtx() const { return true; }
+
+  CODEGEN_DECL();
+};
+
+
 //zorba-store-collections-static-dml:collection-name
 class zorba_store_collections_static_dml_collection_name : public function
 {

=== modified file 'src/functions/pregenerated/function_enum.h'
--- src/functions/pregenerated/function_enum.h	2012-03-07 15:49:25 +0000
+++ src/functions/pregenerated/function_enum.h	2012-03-08 01:45:27 +0000
@@ -79,6 +79,8 @@
   ZORBA_STORE_COLLECTIONS_STATIC_DML_DELETE_NODES_LAST_2,
   ZORBA_STORE_DYNAMIC_COLLECTIONS_DML_DELETE_NODE_LAST_1,
   ZORBA_STORE_DYNAMIC_COLLECTIONS_DML_DELETE_NODES_LAST_2,
+  ZORBA_STORE_COLLECTIONS_STATIC_DML_TRUNCATE_1,
+  ZORBA_STORE_DYNAMIC_COLLECTIONS_DML_TRUNCATE_1,
   ZORBA_STORE_COLLECTIONS_STATIC_DML_COLLECTION_NAME_1,
   ZORBA_STORE_DYNAMIC_COLLECTIONS_DML_COLLECTION_NAME_1,
   ZORBA_STORE_COLLECTIONS_STATIC_DDL_IS_AVAILABLE_COLLECTION_1,

=== modified file 'src/runtime/collections/collections_impl.cpp'
--- src/runtime/collections/collections_impl.cpp	2012-02-16 12:48:17 +0000
+++ src/runtime/collections/collections_impl.cpp	2012-03-08 01:45:27 +0000
@@ -1796,6 +1796,93 @@
 /*******************************************************************************
 
 ********************************************************************************/
+bool ZorbaTruncateCollectionIterator::nextImpl(
+    store::Item_t& result,
+    PlanState& planState) const
+{
+  store::Collection_t              collection;
+  store::Item_t                    collectionName;
+  std::auto_ptr<store::PUL>        pul;
+
+  PlanIteratorState* state;
+  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
+
+  consumeNext(collectionName, theChildren[0].getp(), planState);
+
+  (void)getCollection(
+      theSctx, collectionName, loc, theDynamicCollection, collection);
+
+  // create the pul and add the primitive
+  pul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
+
+  pul->addTruncateCollection(&loc, collectionName, theDynamicCollection);
+
+  result = pul.release();
+  STACK_PUSH( result != NULL, state);
+
+  STACK_END (state);
+}
+
+/*******************************************************************************
+
+********************************************************************************/
+const StaticallyKnownCollection*
+ZorbaTruncateCollectionIterator::getCollection(
+    const static_context* aSctx,
+    const store::Item_t& aName,
+    const QueryLoc& aLoc,
+    bool aDynamicCollection,
+    store::Collection_t& coll) const
+{
+  const StaticallyKnownCollection* collectionDecl = aSctx->lookup_collection(aName);
+  if (collectionDecl == 0  && !aDynamicCollection)
+  {
+    throw XQUERY_EXCEPTION(
+      zerr::ZDDY0001_COLLECTION_NOT_DECLARED,
+      ERROR_PARAMS( aName->getStringValue() ),
+      ERROR_LOC( aLoc )
+    );
+  }
+
+  if (!aDynamicCollection)
+  {
+    // checking collection update mode
+    switch(collectionDecl->getUpdateProperty())
+    {
+      case StaticContextConsts::decl_const:
+        throw XQUERY_EXCEPTION(
+          zerr::ZDDY0004_COLLECTION_CONST_UPDATE,
+          ERROR_PARAMS( aName->getStringValue() ),
+          ERROR_LOC( loc )
+        );
+
+      case StaticContextConsts::decl_append_only:
+        throw XQUERY_EXCEPTION(
+          zerr::ZDDY0005_COLLECTION_APPEND_BAD_INSERT,
+          ERROR_PARAMS( aName->getStringValue() ),
+          ERROR_LOC( loc )
+        );
+      default: break;
+    }
+  }
+
+  coll = GENV_STORE.getCollection(aName, aDynamicCollection);
+
+  if (coll == NULL)
+  {
+    throw XQUERY_EXCEPTION(
+      zerr::ZDDY0003_COLLECTION_DOES_NOT_EXIST,
+      ERROR_PARAMS( aName->getStringValue() ),
+      ERROR_LOC( aLoc )
+    );
+  }
+
+  return collectionDecl;
+}
+
+/*******************************************************************************
+
+********************************************************************************/
 bool ZorbaCollectionNameIterator::nextImpl(
     store::Item_t& result,
     PlanState& planState) const

=== modified file 'src/runtime/collections/pregenerated/collections.cpp'
--- src/runtime/collections/pregenerated/collections.cpp	2011-11-01 14:26:48 +0000
+++ src/runtime/collections/pregenerated/collections.cpp	2012-03-08 01:45:27 +0000
@@ -551,6 +551,34 @@
 // </ZorbaDeleteNodesLastIterator>
 
 
+// <ZorbaTruncateCollectionIterator>
+const char* ZorbaTruncateCollectionIterator::class_name_str = "ZorbaTruncateCollectionIterator";
+ZorbaTruncateCollectionIterator::class_factory<ZorbaTruncateCollectionIterator>
+ZorbaTruncateCollectionIterator::g_class_factory;
+
+const serialization::ClassVersion 
+ZorbaTruncateCollectionIterator::class_versions[] ={{ 1, 0x000905, false}};
+
+const int ZorbaTruncateCollectionIterator::class_versions_count =
+sizeof(ZorbaTruncateCollectionIterator::class_versions)/sizeof(struct serialization::ClassVersion);
+
+void ZorbaTruncateCollectionIterator::accept(PlanIterVisitor& v) const {
+  v.beginVisit(*this);
+
+  std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
+  std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
+  for ( ; lIter != lEnd; ++lIter ){
+    (*lIter)->accept(v);
+  }
+
+  v.endVisit(*this);
+}
+
+ZorbaTruncateCollectionIterator::~ZorbaTruncateCollectionIterator() {}
+
+// </ZorbaTruncateCollectionIterator>
+
+
 // <ZorbaCollectionNameIterator>
 const char* ZorbaCollectionNameIterator::class_name_str = "ZorbaCollectionNameIterator";
 ZorbaCollectionNameIterator::class_factory<ZorbaCollectionNameIterator>

=== modified file 'src/runtime/collections/pregenerated/collections.h'
--- src/runtime/collections/pregenerated/collections.h	2011-11-01 14:26:48 +0000
+++ src/runtime/collections/pregenerated/collections.h	2012-03-08 01:45:27 +0000
@@ -865,6 +865,50 @@
 
 /**
  * 
+ *      zorba:truncate
+ *    
+ * Author: Zorba Team
+ */
+class ZorbaTruncateCollectionIterator : public NaryBaseIterator<ZorbaTruncateCollectionIterator, PlanIteratorState>
+{ 
+protected:
+  bool theDynamicCollection; //whether it's the function of the dynamic or the static collection module
+public:
+  SERIALIZABLE_CLASS(ZorbaTruncateCollectionIterator);
+
+  SERIALIZABLE_CLASS_CONSTRUCTOR2T(ZorbaTruncateCollectionIterator,
+    NaryBaseIterator<ZorbaTruncateCollectionIterator, PlanIteratorState>);
+
+  void serialize( ::zorba::serialization::Archiver& ar)
+  {
+    serialize_baseclass(ar,
+    (NaryBaseIterator<ZorbaTruncateCollectionIterator, PlanIteratorState>*)this);
+
+    ar & theDynamicCollection;
+  }
+
+  ZorbaTruncateCollectionIterator(
+    static_context* sctx,
+    const QueryLoc& loc,
+    std::vector<PlanIter_t>& children,
+    bool aDynamicCollection)
+    : 
+    NaryBaseIterator<ZorbaTruncateCollectionIterator, PlanIteratorState>(sctx, loc, children),
+    theDynamicCollection(aDynamicCollection)
+  {}
+
+  virtual ~ZorbaTruncateCollectionIterator();
+
+public:
+  const StaticallyKnownCollection* getCollection(const static_context* sctx, const store::Item_t& name, const QueryLoc& loc, bool dyn_coll, store::Collection_t& coll) const;
+  void accept(PlanIterVisitor& v) const;
+
+  bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
+};
+
+
+/**
+ * 
  *      zorba:collection-name
  *    
  * Author: Zorba Team

=== modified file 'src/runtime/core/apply_updates.cpp'
--- src/runtime/core/apply_updates.cpp	2011-08-17 18:55:07 +0000
+++ src/runtime/core/apply_updates.cpp	2012-03-08 01:45:27 +0000
@@ -141,12 +141,13 @@
   SchemaValidatorImpl validator(loc, sctx);
   ICCheckerImpl icChecker(sctx, gdctx);
   std::vector<store::Index*> indexes;
+  std::vector<store::Index*> truncate_indexes;
   store::ItemHandle<store::PUL> indexPul;
 
   // Get all the indexes that are associated with any of the collections that
   // are going to be updated by this pul. Check which of those indices can be
   // maintained incrementally, and pass this info back to the pul.
-  pul->getIndicesToRefresh(indexes);
+  pul->getIndicesToRefresh(indexes, truncate_indexes);
 
   ulong numIndices = (ulong)indexes.size();
 
@@ -178,6 +179,17 @@
     zorbaIndexes[i] = indexDecl;
   }
 
+  numIndices = (ulong)truncate_indexes.size();
+  for (ulong i = 0; i < numIndices; ++i)
+  {
+    IndexDecl* indexDecl = sctx->lookup_index(indexes[i]->getName());
+
+    if (indexDecl->getMaintenanceMode() == IndexDecl::DOC_MAP)
+    {
+      pul->addIndexTruncator(indexDecl->getSourceName(0), indexes[i]);
+    }
+  }
+
   try 
   {
     // Apply updates

=== modified file 'src/runtime/spec/collections/collections.xml'
--- src/runtime/spec/collections/collections.xml	2012-01-11 17:30:25 +0000
+++ src/runtime/spec/collections/collections.xml	2012-03-08 01:45:27 +0000
@@ -924,6 +924,52 @@
 /*******************************************************************************
 ********************************************************************************/
 -->
+<zorba:iterator name="ZorbaTruncateCollectionIterator" >
+
+    <zorba:description author="Zorba Team">
+      zorba:truncate
+    </zorba:description>
+
+    <zorba:function generateCodegen="false">
+
+      <zorba:signature localname="truncate" prefix="zorba-store-collections-static-dml">
+        <zorba:param>xs:QName</zorba:param>
+        <zorba:output>empty-sequence()</zorba:output>
+      </zorba:signature>
+
+      <zorba:signature localname="truncate" prefix="zorba-store-dynamic-collections-dml">
+        <zorba:param>xs:QName</zorba:param>
+        <zorba:output>empty-sequence()</zorba:output>
+      </zorba:signature>
+
+      <zorba:methods>
+        <zorba:getScriptingKind returnValue="UPDATING_EXPR"/>
+        <zorba:accessesDynCtx returnValue="true"/>
+      </zorba:methods>
+
+    </zorba:function>
+
+    <zorba:constructor>
+      <zorba:parameter type="bool" name="aDynamicCollection" />
+    </zorba:constructor>
+
+    <zorba:member type="bool" name="theDynamicCollection"
+      brief="whether it's the function of the dynamic or the static collection module"/>
+
+    <zorba:method const="true" name="getCollection" return="const StaticallyKnownCollection*">
+      <zorba:param type="const static_context*" name="sctx"/>
+      <zorba:param type="const store::Item_t&amp;" name="name"/>
+      <zorba:param type="const QueryLoc&amp;" name="loc"/>
+      <zorba:param type="bool" name="dyn_coll"/>
+      <zorba:param type="store::Collection_t&amp;" name="coll"/>
+    </zorba:method>
+</zorba:iterator>
+
+
+<!--
+/*******************************************************************************
+********************************************************************************/
+-->
 <zorba:iterator name="ZorbaCollectionNameIterator" >
 
     <zorba:description author="Zorba Team">

=== modified file 'src/runtime/visitors/pregenerated/planiter_visitor.h'
--- src/runtime/visitors/pregenerated/planiter_visitor.h	2012-03-07 15:49:25 +0000
+++ src/runtime/visitors/pregenerated/planiter_visitor.h	2012-03-08 01:45:27 +0000
@@ -92,6 +92,8 @@
 
     class ZorbaDeleteNodesLastIterator;
 
+    class ZorbaTruncateCollectionIterator;
+
     class ZorbaCollectionNameIterator;
 
     class IsAvailableCollectionIterator;
@@ -697,6 +699,9 @@
     virtual void beginVisit ( const ZorbaDeleteNodesLastIterator& ) = 0;
     virtual void endVisit   ( const ZorbaDeleteNodesLastIterator& ) = 0;
 
+    virtual void beginVisit ( const ZorbaTruncateCollectionIterator& ) = 0;
+    virtual void endVisit   ( const ZorbaTruncateCollectionIterator& ) = 0;
+
     virtual void beginVisit ( const ZorbaCollectionNameIterator& ) = 0;
     virtual void endVisit   ( const ZorbaCollectionNameIterator& ) = 0;
 

=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.cpp'
--- src/runtime/visitors/pregenerated/printer_visitor.cpp	2012-03-07 15:49:25 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.cpp	2012-03-08 01:45:27 +0000
@@ -545,6 +545,20 @@
 // </ZorbaDeleteNodesLastIterator>
 
 
+// <ZorbaTruncateCollectionIterator>
+void PrinterVisitor::beginVisit ( const ZorbaTruncateCollectionIterator& a) {
+  thePrinter.startBeginVisit("ZorbaTruncateCollectionIterator", ++theId);
+  printCommons( &a, theId );
+  thePrinter.endBeginVisit( theId );
+}
+
+void PrinterVisitor::endVisit ( const ZorbaTruncateCollectionIterator& ) {
+  thePrinter.startEndVisit();
+  thePrinter.endEndVisit();
+}
+// </ZorbaTruncateCollectionIterator>
+
+
 // <ZorbaCollectionNameIterator>
 void PrinterVisitor::beginVisit ( const ZorbaCollectionNameIterator& a) {
   thePrinter.startBeginVisit("ZorbaCollectionNameIterator", ++theId);

=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.h'
--- src/runtime/visitors/pregenerated/printer_visitor.h	2012-03-07 15:49:25 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.h	2012-03-08 01:45:27 +0000
@@ -140,6 +140,9 @@
     void beginVisit( const ZorbaDeleteNodesLastIterator& );
     void endVisit  ( const ZorbaDeleteNodesLastIterator& );
 
+    void beginVisit( const ZorbaTruncateCollectionIterator& );
+    void endVisit  ( const ZorbaTruncateCollectionIterator& );
+
     void beginVisit( const ZorbaCollectionNameIterator& );
     void endVisit  ( const ZorbaCollectionNameIterator& );
 

=== modified file 'src/store/api/pul.h'
--- src/store/api/pul.h	2011-10-12 20:59:49 +0000
+++ src/store/api/pul.h	2012-03-08 01:45:27 +0000
@@ -203,6 +203,11 @@
         bool isLast,
         bool dyn_collection = false) = 0;
 
+  virtual void addTruncateCollection(
+        const QueryLoc* aQueryLoc,
+        Item_t& name,
+        bool dyn_collection = false) = 0;
+
   // functions to add primitives for indexes
 
   virtual void addCreateIndex(
@@ -281,13 +286,18 @@
 
   // utils
   virtual void getIndicesToRefresh(
-        std::vector<Index*>& indices) = 0;
+        std::vector<Index*>& indices,
+        std::vector<Index*>& truncate_indices) = 0;
 
   virtual void addIndexEntryCreator(
         const Item* collectionName, 
         Index* idx,
         IndexEntryCreator* creator) = 0;
 
+  virtual void addIndexTruncator(
+      const store::Item* collectionName,
+      Index* idx) = 0;
+
   virtual void setValidator(
         SchemaValidator* validator) = 0;
 

=== modified file 'src/store/api/update_consts.h'
--- src/store/api/update_consts.h	2012-01-11 17:30:25 +0000
+++ src/store/api/update_consts.h	2012-03-08 01:45:27 +0000
@@ -81,6 +81,7 @@
     UP_INSERT_AT_INTO_COLLECTION,
     UP_REMOVE_FROM_COLLECTION,
     UP_REMOVE_AT_FROM_COLLECTION,
+    UP_TRUNCATE_COLLECTION,
 
     // index primitives
     UP_CREATE_INDEX,
@@ -177,6 +178,8 @@
       return "insertAtIntoCollection";
     case UP_REMOVE_FROM_COLLECTION:
       return "removeFromCollection";
+    case UP_TRUNCATE_COLLECTION:
+      return "truncateCollection";
     case UP_REMOVE_AT_FROM_COLLECTION:
       return "removeAtFromCollection";
     case UP_CREATE_INDEX:

=== modified file 'src/store/naive/pul_primitive_factory.cpp'
--- src/store/naive/pul_primitive_factory.cpp	2012-03-07 14:22:29 +0000
+++ src/store/naive/pul_primitive_factory.cpp	2012-03-08 01:45:27 +0000
@@ -376,6 +376,18 @@
       return new UpdDeleteNodesFromCollection(pul, aLoc, name, nodes, isLast, dyn_collection);
     }
 
+
+    /***************************************************************************
+    ***************************************************************************/
+    UpdTruncateCollection*
+    PULPrimitiveFactory::createUpdTruncateCollection(
+          CollectionPul* pul,
+          const QueryLoc* aLoc,
+          store::Item_t& name,
+          bool dyn_collection)
+    {
+      return new UpdTruncateCollection(pul, aLoc, name, dyn_collection);
+    }
     
     /***************************************************************************
     ***************************************************************************/

=== modified file 'src/store/naive/pul_primitive_factory.h'
--- src/store/naive/pul_primitive_factory.h	2012-02-28 20:45:43 +0000
+++ src/store/naive/pul_primitive_factory.h	2012-03-08 01:45:27 +0000
@@ -50,6 +50,7 @@
   class UpdInsertBeforeIntoCollection;
   class UpdInsertAfterIntoCollection;
   class UpdDeleteNodesFromCollection;
+  class UpdTruncateCollection;
   class UpdCreateIndex;
   class UpdDeleteIndex;
   class UpdRefreshIndex;
@@ -311,6 +312,15 @@
         std::vector<store::Item_t>& nodes,
         bool isLast,
         bool dyn_collection = false);
+
+  /***************************************************************************
+   ***************************************************************************/
+  virtual UpdTruncateCollection*
+  createUpdTruncateCollection(
+        CollectionPul* pul,
+        const QueryLoc*,
+        store::Item_t& name,
+        bool dyn_collection = false);
     
   /***************************************************************************
    ***************************************************************************/

=== modified file 'src/store/naive/pul_primitives.cpp'
--- src/store/naive/pul_primitives.cpp	2012-03-07 14:22:29 +0000
+++ src/store/naive/pul_primitives.cpp	2012-03-08 01:45:27 +0000
@@ -1276,6 +1276,36 @@
 }
 
 
+/*******************************************************************************
+  UpdTruncateCollection
+********************************************************************************/
+void UpdTruncateCollection::apply()
+{
+  SimpleCollection* lColl = static_cast<SimpleCollection*>
+                            (GET_STORE().getCollection(theName, theDynamicCollection).getp());
+  assert(lColl);
+
+  lColl->theXmlTrees.swap(theTrees);
+
+  theIsApplied = true;
+
+}
+
+void UpdTruncateCollection::undo()
+{
+  if (!theIsApplied) return;
+
+  SimpleCollection* lColl = static_cast<SimpleCollection*>
+                            (GET_STORE().getCollection(theName, theDynamicCollection).getp());
+  assert(lColl);
+
+  lColl->theXmlTrees.clear();
+
+  theTrees.swap(lColl->theXmlTrees);
+
+  theIsApplied = false;
+}
+
 
 /////////////////////////////////////////////////////////////////////////////////
 //                                                                             //

=== modified file 'src/store/naive/pul_primitives.h'
--- src/store/naive/pul_primitives.h	2012-02-28 20:45:43 +0000
+++ src/store/naive/pul_primitives.h	2012-03-08 01:45:27 +0000
@@ -1210,6 +1210,37 @@
 };
 
 
+/*******************************************************************************
+
+********************************************************************************/
+class UpdTruncateCollection: public  UpdCollection
+{
+  friend class PULPrimitiveFactory;
+
+protected:
+  std::vector<store::Item_t> theTrees; // needed for undo only
+
+  UpdTruncateCollection(
+        CollectionPul* pul,
+        const QueryLoc* aLoc,
+        store::Item_t& name,
+        bool dyn_collection)
+    :
+    UpdCollection(pul, aLoc, name, dyn_collection)
+  {
+  }
+
+public:
+  store::UpdateConsts::UpdPrimKind getKind() const
+  { 
+    return store::UpdateConsts::UP_TRUNCATE_COLLECTION;
+  }
+
+  void apply();
+  void undo();
+};
+
+
 /////////////////////////////////////////////////////////////////////////////////
 //                                                                             //
 //  Index Primitives                                                           //

=== modified file 'src/store/naive/simple_collection.h'
--- src/store/naive/simple_collection.h	2012-03-07 14:22:29 +0000
+++ src/store/naive/simple_collection.h	2012-03-08 01:45:27 +0000
@@ -41,6 +41,7 @@
 class SimpleCollection : public Collection
 {
   friend class CollectionIter;
+  friend class UpdTruncateCollection;
 
 public:
   class CollectionIter : public store::Iterator

=== modified file 'src/store/naive/simple_index.h'
--- src/store/naive/simple_index.h	2012-01-11 17:30:25 +0000
+++ src/store/naive/simple_index.h	2012-03-08 01:45:27 +0000
@@ -69,6 +69,8 @@
 
   virtual KeyIterator_t keys() const = 0;
 
+  virtual void clear() = 0;
+
   store::IndexCondition_t createCondition(store::IndexCondition::Kind k);
 
   //

=== modified file 'src/store/naive/simple_index_general.cpp'
--- src/store/naive/simple_index_general.cpp	2012-02-15 10:25:02 +0000
+++ src/store/naive/simple_index_general.cpp	2012-03-08 01:45:27 +0000
@@ -755,6 +755,26 @@
 }
 
 
+/******************************************************************************
+
+*******************************************************************************/
+void GeneralHashIndex::clear()
+{
+  for (ulong i = 0; i < store::XS_LAST; ++i)
+  {
+    if (theMaps[i] == NULL)
+      continue;
+
+    theMaps[i]->clear();
+  }
+
+  if (isTyped())
+  {
+    theSingleMap->clear();
+  }
+}
+
+
 /////////////////////////////////////////////////////////////////////////////////
 //                                                                             //
 //  GeneralHashIndex::KeyIterator                                              //
@@ -912,6 +932,26 @@
 /******************************************************************************
 
 *******************************************************************************/
+void GeneralTreeIndex::clear()
+{
+  for (ulong i = 0; i < store::XS_LAST; ++i)
+  {
+    if (theMaps[i] == NULL)
+      continue;
+
+    theMaps[i]->clear();
+  }
+
+  if (isTyped())
+  {
+    theSingleMap->clear();
+  }
+}
+
+
+/******************************************************************************
+
+*******************************************************************************/
 store::Index::KeyIterator_t GeneralTreeIndex::keys() const
 {
   return 0;

=== modified file 'src/store/naive/simple_index_general.h'
--- src/store/naive/simple_index_general.h	2012-02-28 20:45:43 +0000
+++ src/store/naive/simple_index_general.h	2012-03-08 01:45:27 +0000
@@ -238,6 +238,8 @@
   Index::KeyIterator_t keys() const;
 
   bool remove(const store::Item_t& key, store::Item_t& item, bool);
+
+  void clear();
 };
 
 
@@ -291,6 +293,8 @@
   Index::KeyIterator_t keys() const;
 
   bool remove(const store::Item_t& key, store::Item_t& item, bool all);
+
+  void clear();
 };
 
 

=== modified file 'src/store/naive/simple_pul.cpp'
--- src/store/naive/simple_pul.cpp	2012-03-07 14:22:29 +0000
+++ src/store/naive/simple_pul.cpp	2012-03-08 01:45:27 +0000
@@ -944,6 +944,17 @@
 }
 
 
+void PULImpl::addTruncateCollection(
+        const QueryLoc* aQueryLoc,
+        store::Item_t& name,
+        bool dyn_collection)
+{
+  CollectionPul* pul = getCollectionPulByName(name.getp(),dyn_collection);
+
+  pul->theTruncateCollectionList.push_back(
+  GET_PUL_FACTORY().createUpdTruncateCollection(pul, aQueryLoc, name, dyn_collection));
+}
+
 /*******************************************************************************
   Index primitives
 ********************************************************************************/
@@ -1157,6 +1168,11 @@
                       UP_LIST_NONE);
 
       mergeUpdateList(thisPul,
+                      thisPul->theTruncateCollectionList,
+                      otherPul->theTruncateCollectionList,
+                      UP_LIST_NONE);
+
+      mergeUpdateList(thisPul,
                       thisPul->theDeleteCollectionList,
                       otherPul->theDeleteCollectionList,
                       UP_LIST_NONE);
@@ -1502,7 +1518,9 @@
   This method is invoked by the ApplyIterator before any of the pul primitives
   is applied.
 ********************************************************************************/
-void PULImpl::getIndicesToRefresh(std::vector<store::Index*>& indices)
+void PULImpl::getIndicesToRefresh(
+    std::vector<store::Index*>& indices,
+    std::vector<store::Index*>& truncate_indices)
 {
   SimpleStore* store = &GET_STORE();
 
@@ -1513,6 +1531,7 @@
   // modified/inserted/deleted collection docs, because they will be need later
   // to maintain indices.
   std::set<store::Collection*> collections;
+  std::set<store::Collection*> truncated_collections;
 
   CollectionPulMap::iterator collIte = theCollectionPuls.begin();
   CollectionPulMap::iterator collEnd = theCollectionPuls.end();
@@ -1529,6 +1548,12 @@
 
     CollectionPul* pul = collIte->second;
 
+    if (pul->theTruncateCollectionList.size() > 0)
+    {
+      truncated_collections.insert(collection);
+      continue;
+    }
+
     NodeToUpdatesMap::iterator ite = pul->theNodeToUpdatesMap.begin();
     NodeToUpdatesMap::iterator end = pul->theNodeToUpdatesMap.end();
     for (; ite != end; ++ite)
@@ -1595,6 +1620,21 @@
       if (colIte != colEnd)
         break;
     }
+
+    for (csize i = 0; i < numIndexSources; ++i)
+    {
+      std::set<store::Collection*>::const_iterator colIte = truncated_collections.begin();
+      std::set<store::Collection*>::const_iterator colEnd = truncated_collections.end();
+
+      for (; colIte != colEnd; ++colIte)
+      {
+        if (indexSources[i]->equals((*colIte)->getName()))
+        {
+          truncate_indices.push_back(index);
+          break;
+        }
+      }
+    }
   }
 }
 
@@ -1617,6 +1657,18 @@
 /*******************************************************************************
 
 ********************************************************************************/
+void PULImpl::addIndexTruncator(
+    const store::Item* collectionName,
+    store::Index* idx)
+{
+  CollectionPul* pul = getCollectionPulByName(collectionName,false);
+  pul->theTruncatedIndices.push_back(static_cast<IndexImpl*>(idx));
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 void PULImpl::setICChecker(store::ICChecker* icChecker)
 {
   theICChecker = icChecker;
@@ -1796,6 +1848,7 @@
   cleanList(theCreateCollectionList);
   cleanList(theInsertIntoCollectionList);
   cleanList(theDeleteFromCollectionList);
+  cleanList(theTruncateCollectionList);
   cleanList(theDeleteCollectionList);
 
   cleanIndexDeltas(theBeforeIndexDeltas);
@@ -1822,6 +1875,7 @@
   switchPulInPrimitivesList(theCreateCollectionList);
   switchPulInPrimitivesList(theInsertIntoCollectionList);
   switchPulInPrimitivesList(theDeleteFromCollectionList);
+  switchPulInPrimitivesList(theTruncateCollectionList);
   switchPulInPrimitivesList(theDeleteCollectionList);
 }
 
@@ -1946,7 +2000,14 @@
 ********************************************************************************/
 void CollectionPul::refreshIndices()
 {
-  csize numIncrementalIndices = theIncrementalIndices.size();
+  csize numIncrementalIndices = theTruncatedIndices.size();
+  for (csize idx = 0; idx < numIncrementalIndices; ++idx)
+  {
+    ValueIndex* index = static_cast<ValueIndex*>(theTruncatedIndices[idx]);
+    index->clear();
+  }
+
+  numIncrementalIndices = theIncrementalIndices.size();
 
   for (csize idx = 0; idx < numIncrementalIndices; ++idx)
   {
@@ -2134,6 +2195,7 @@
     applyList(theCreateCollectionList);
     applyList(theInsertIntoCollectionList);
     applyList(theDeleteFromCollectionList);
+    applyList(theTruncateCollectionList);
 
     // Compute the after-delta for each incrementally maintained index.
     computeIndexAfterDeltas();
@@ -2266,6 +2328,7 @@
 
   try
   {
+    undoList(theTruncateCollectionList);
     undoList(theDeleteFromCollectionList);
     undoList(theInsertIntoCollectionList);
     undoList(theCreateCollectionList);

=== modified file 'src/store/naive/simple_pul.h'
--- src/store/naive/simple_pul.h	2012-03-07 14:22:29 +0000
+++ src/store/naive/simple_pul.h	2012-03-08 01:45:27 +0000
@@ -183,6 +183,7 @@
   std::vector<UpdatePrimitive*>      theCreateCollectionList;
   std::vector<UpdatePrimitive*>      theInsertIntoCollectionList;
   std::vector<UpdatePrimitive*>      theDeleteFromCollectionList;
+  std::vector<UpdatePrimitive*>      theTruncateCollectionList;
   std::vector<UpdatePrimitive*>      theDeleteCollectionList;
 
   // Validate in place primitives
@@ -194,6 +195,7 @@
   std::vector<XmlNode*>              theDeletedDocs;
 
   std::vector<IndexImpl*>            theIncrementalIndices;
+  std::vector<IndexImpl*>            theTruncatedIndices;
 
   std::vector<IndexEntryCreator_t>   theIndexEntryCreators;
 
@@ -465,6 +467,11 @@
         bool isLast,
         bool dyn_collection = false);
 
+  void addTruncateCollection(
+        const QueryLoc* aQueryLoc,
+        store::Item_t& name,
+        bool dyn_collection = false);
+
   // Index primitives
   void addCreateIndex(
         const QueryLoc* aQueryLoc,
@@ -539,13 +546,19 @@
   // utils
   void checkTransformUpdates(const std::vector<store::Item*>& rootNodes) const;
 
-  void getIndicesToRefresh(std::vector<store::Index*>& indices);
+  void getIndicesToRefresh(
+      std::vector<store::Index*>& indices,
+      std::vector<store::Index*>& truncate_indices);
 
   void addIndexEntryCreator(
         const store::Item* collectionName,
         store::Index* idx,
         store::IndexEntryCreator* creator);
 
+  void addIndexTruncator(
+      const store::Item* collectionName,
+      store::Index* idx);
+
   void setValidator(store::SchemaValidator* validator);
   store::SchemaValidator* getValidator() const { return theValidator; }
 

=== added file 'test/rbkt/ExpQueryResults/zorba/collections/delete_nodes/truncate_001.xml.res'
--- test/rbkt/ExpQueryResults/zorba/collections/delete_nodes/truncate_001.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/collections/delete_nodes/truncate_001.xml.res	2012-03-08 01:45:27 +0000
@@ -0,0 +1,1 @@
+<a>1</a><a>2</a><a>3</a><a>4</a><a>5</a><a>6</a><a>7</a><a>8</a><a>9</a><a>10</a><b>1</b><b>2</b><b>3</b><b>4</b><b>5</b><b>6</b><b>7</b><b>8</b><b>9</b><b>10</b>

=== added file 'test/rbkt/ExpQueryResults/zorba/collections/dynamic6.xml.res'
--- test/rbkt/ExpQueryResults/zorba/collections/dynamic6.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/collections/dynamic6.xml.res	2012-03-08 01:45:27 +0000
@@ -0,0 +1,1 @@
+0

=== added file 'test/rbkt/ExpQueryResults/zorba/index/auctions2.xml.res'
--- test/rbkt/ExpQueryResults/zorba/index/auctions2.xml.res	1970-01-01 00:00:00 +0000
+++ test/rbkt/ExpQueryResults/zorba/index/auctions2.xml.res	2012-03-08 01:45:27 +0000
@@ -0,0 +1,1 @@
+<person id="person0"><city>Macon</city></person>

=== modified file 'test/rbkt/Queries/zorba/collections/collection_002.xqdata'
--- test/rbkt/Queries/zorba/collections/collection_002.xqdata	2011-06-24 19:58:33 +0000
+++ test/rbkt/Queries/zorba/collections/collection_002.xqdata	2012-03-08 01:45:27 +0000
@@ -2,4 +2,6 @@
 
 declare collection ns:collection as node()*;
 
-declare function ns:test2() { () };
\ No newline at end of file
+declare collection ns:collection2 as node()*;
+
+declare function ns:test2() { () };

=== added file 'test/rbkt/Queries/zorba/collections/delete_nodes/truncate_001.xq'
--- test/rbkt/Queries/zorba/collections/delete_nodes/truncate_001.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/collections/delete_nodes/truncate_001.xq	2012-03-08 01:45:27 +0000
@@ -0,0 +1,27 @@
+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 ns = "http://www.example.com/example"; at "../collection_002.xqdata";
+
+variable $contents;
+
+ddl:create(xs:QName("ns:collection"));
+ddl:create(xs:QName("ns:collection2"));
+
+dml:insert-nodes(
+  xs:QName("ns:collection"),
+  for $i in 1 to 10 return <a>{$i}</a>
+);
+
+dml:insert-nodes(
+  xs:QName("ns:collection2"),
+  for $i in 1 to 10 return <b>{$i}</b>
+);
+
+$contents := (dml:collection(xs:QName("ns:collection")), dml:collection(xs:QName("ns:collection2")));
+
+(dml:truncate(xs:QName("ns:collection")), dml:truncate(xs:QName("ns:collection2")));
+
+$contents := ($contents, dml:collection(xs:QName("ns:collection")), dml:collection(xs:QName("ns:collection")));
+
+$contents

=== added file 'test/rbkt/Queries/zorba/collections/dynamic6.xq'
--- test/rbkt/Queries/zorba/collections/dynamic6.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/collections/dynamic6.xq	2012-03-08 01:45:27 +0000
@@ -0,0 +1,10 @@
+import module namespace ddl = "http://www.zorba-xquery.com/modules/store/dynamic/collections/ddl";;
+import module namespace dml = "http://www.zorba-xquery.com/modules/store/dynamic/collections/dml";;
+
+ddl:create(xs:QName("ddl:test2"),(<center1/>,<oldlast/>));
+
+dml:insert-nodes-first(xs:QName("ddl:test2"), (<c1/>,<c2/>));
+
+dml:truncate(xs:QName("ddl:test2"));
+
+count(dml:collection(xs:QName("ddl:test2")))

=== added file 'test/rbkt/Queries/zorba/index/auctions2.xq'
--- test/rbkt/Queries/zorba/index/auctions2.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/index/auctions2.xq	2012-03-08 01:45:27 +0000
@@ -0,0 +1,25 @@
+import module namespace auctions = "http://www.w3.org/TestModules/auctions"; at
+                                   "auctions_module1.xqlib";
+
+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 index_ddl = "http://www.zorba-xquery.com/modules/store/static/indexes/ddl";;
+import module namespace index_dml = "http://www.zorba-xquery.com/modules/store/static/indexes/dml";;
+
+declare namespace err = "http://www.w3.org/2005/xqt-errors";;
+
+auctions:create-db();
+
+variable $cities := ();
+
+$cities := for $x in auctions:probe-point-city(xs:QName("auctions:PersonCity"), "Macon")
+           return <person id = "{$x/@id}">{$x//city}</person>;
+
+dml:truncate(xs:QName("auctions:auctions"));
+
+$cities := ($cities, 
+            for $x in auctions:probe-point-city(xs:QName("auctions:PersonCity"), "Macon")
+            return <person id = "{$x/@id}">{$x//city}</person>);
+
+$cities
+

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

Reply via email to