Federico Cavalieri has proposed merging lp:~fcavalieri/zorba/updrevalidate into 
lp:zorba.

Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~fcavalieri/zorba/updrevalidate/+merge/79187

Reimplemented validate-in-place through a new update primitive UpdRevalidate.
This also fixes bugs 872796 and 872799
-- 
https://code.launchpad.net/~fcavalieri/zorba/updrevalidate/+merge/79187
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2011-10-12 09:58:12 +0000
+++ ChangeLog	2011-10-12 21:33:26 +0000
@@ -50,6 +50,8 @@
 	different nodes cannot have the same identifier.
   * Fixed bug #872697  (segmentation fault with validation of NMTOKENS)
   * Added undo for node revalidation
+  * Fixed bug #872796  (validate-in-place can interfere with other update primitives)
+  * Fixed bug #872799 (validate-in-place can set incorrect types)
 
 version 2.0.1
 

=== modified file 'src/runtime/schema/schema_impl.cpp'
--- src/runtime/schema/schema_impl.cpp	2011-06-14 17:26:33 +0000
+++ src/runtime/schema/schema_impl.cpp	2011-10-12 21:33:26 +0000
@@ -84,27 +84,25 @@
 bool
 ZorbaValidateInPlaceIterator::nextImpl(store::Item_t& result, PlanState& planState) const
 {
-  store::Item_t item;
+  store::Item_t node;
 
   PlanIteratorState *state;
   std::auto_ptr<store::PUL> pul;
-  std::set<store::Item*> nodes;
-  SchemaValidatorImpl validator(loc, theSctx);
 
   DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
-      
-  if (consumeNext(item, theChild.getp(), planState))
+
+  if (consumeNext(node, theChild.getp(), planState))
   {
     pul.reset(GENV_ITEMFACTORY->createPendingUpdateList());
 
-    nodes.insert(item.getp());
-    
-    validator.validate(nodes, *pul);    
+    pul->addRevalidate(&loc,node);
+
     result = pul.release();
     STACK_PUSH(true, state);
   }
 
   STACK_END (state);
+
 }
 
 

=== modified file 'src/store/api/pul.h'
--- src/store/api/pul.h	2011-09-12 22:42:28 +0000
+++ src/store/api/pul.h	2011-10-12 21:33:26 +0000
@@ -141,6 +141,9 @@
         Item_t& typeName,
         std::vector<Item_t>& typedValue) = 0;
 
+  virtual void addRevalidate(
+          const QueryLoc* aQueryLoc,
+          Item_t& target) = 0;
 
   virtual void addPut(
         const QueryLoc* aQueryLoc,

=== modified file 'src/store/api/update_consts.h'
--- src/store/api/update_consts.h	2011-10-06 12:32:10 +0000
+++ src/store/api/update_consts.h	2011-10-12 21:33:26 +0000
@@ -66,6 +66,7 @@
     UP_RENAME_PI,
     UP_SET_ATTRIBUTE_TYPE,
     UP_SET_ELEMENT_TYPE,
+    UP_REVALIDATE,
     UP_PUT,
 
     // collection primitives
@@ -206,6 +207,8 @@
       return "setAttributeType";
     case UP_SET_ELEMENT_TYPE:
       return "setElementType";
+    case UP_REVALIDATE:
+      return "revalidate";
     default:
       return "unknownUpdatePrimitive";
   }

=== modified file 'src/store/naive/pul_primitive_factory.cpp'
--- src/store/naive/pul_primitive_factory.cpp	2011-09-12 22:42:28 +0000
+++ src/store/naive/pul_primitive_factory.cpp	2011-10-12 21:33:26 +0000
@@ -230,7 +230,18 @@
 {
   return new UpdSetAttributeType(pul, aLoc, target, typeName, typedValue, haveListValue);
 }
-    
+
+/***************************************************************************
+
+***************************************************************************/
+UpdRevalidate*
+PULPrimitiveFactory::createUpdRevalidate(
+    PULImpl*       pul,
+    const QueryLoc* aLoc,
+    store::Item_t& target)
+{
+  return new UpdRevalidate(pul, aLoc, target);
+}
 
 /***************************************************************************
 

=== modified file 'src/store/naive/pul_primitive_factory.h'
--- src/store/naive/pul_primitive_factory.h	2011-09-12 22:42:28 +0000
+++ src/store/naive/pul_primitive_factory.h	2011-10-12 21:33:26 +0000
@@ -40,6 +40,7 @@
   class UpdReplaceCommentValue;
   class UpdSetElementType;
   class UpdSetAttributeType;
+  class UpdRevalidate;
   class UpdPut;
   class UpdCreateCollection;
   class UpdDeleteCollection;
@@ -214,6 +215,14 @@
         bool           haveListValue);
   
   /***************************************************************************
+     ***************************************************************************/
+  virtual UpdRevalidate*
+  createUpdRevalidate(
+        PULImpl*       pul,
+        const QueryLoc*,
+        store::Item_t& target);
+
+  /***************************************************************************
    ***************************************************************************/
   virtual UpdPut*
   createUpdPut(PULImpl* pul, const QueryLoc*, store::Item_t& target, store::Item_t& uri);

=== modified file 'src/store/naive/pul_primitives.cpp'
--- src/store/naive/pul_primitives.cpp	2011-10-12 09:58:12 +0000
+++ src/store/naive/pul_primitives.cpp	2011-10-12 21:33:26 +0000
@@ -25,12 +25,14 @@
 #include "store/naive/node_items.h"
 #include "store/naive/atomic_items.h"
 #include "store/naive/simple_collection.h"
+#include "store/naive/simple_item_factory.h"
 #include "store/naive/node_factory.h"
 #include "store/naive/simple_index.h"
 #include "store/naive/simple_index_value.h"
 
 #include "store/api/iterator.h"
 #include "store/api/copymode.h"
+#include "store/api/validator.h"
 
 #include "diagnostics/xquery_diagnostics.h"
 
@@ -662,6 +664,35 @@
 /*******************************************************************************
 
 ********************************************************************************/
+void UpdRevalidate::apply()
+{
+  std::set<store::Item*> nodes;
+
+  theRevalidationPul=GET_STORE().getItemFactory()->createPendingUpdateList();
+  nodes.insert(theTarget.getp());
+  thePul->theValidator->validate(nodes,*theRevalidationPul.getp());
+  try
+  {
+    theRevalidationPul->applyUpdates(false);
+  }
+  catch (...)
+  {
+    ZORBA_FATAL(0, "Error during the in-place validation");
+  }
+
+  theIsApplied = true;
+}
+
+
+void UpdRevalidate::undo()
+{
+  static_cast<PULImpl *>(theRevalidationPul.getp())->undoUpdates();
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 UpdReplaceTextValue::~UpdReplaceTextValue()
 {
   if (theIsTyped)

=== modified file 'src/store/naive/pul_primitives.h'
--- src/store/naive/pul_primitives.h	2011-10-12 08:43:16 +0000
+++ src/store/naive/pul_primitives.h	2011-10-12 21:33:26 +0000
@@ -24,11 +24,11 @@
 #include "store/api/collection.h"
 #include "store/api/iterator.h"
 #include "store/api/annotation.h"
+#include "store/api/pul.h"
 
 #include "store/api/index.h" // for index spec obj
 #include "store/api/ic.h" // for index spec obj
 
-
 namespace zorba { namespace simplestore {
 
 
@@ -807,6 +807,34 @@
 };
 
 
+/*******************************************************************************
+
+********************************************************************************/
+class UpdRevalidate : public UpdatePrimitive
+{
+  friend class PULImpl;
+  friend class PULPrimitiveFactory;
+
+protected:
+  store::PUL_t theRevalidationPul;
+
+  UpdRevalidate(PULImpl* pul, const QueryLoc* aLoc, store::Item_t& target)
+    :
+    UpdatePrimitive(pul, aLoc, target){}
+
+
+public:
+
+  store::UpdateConsts::UpdPrimKind getKind() const
+  {
+    return store::UpdateConsts::UP_REVALIDATE;
+  }
+
+  void apply();
+  void undo();
+};
+
+
 /////////////////////////////////////////////////////////////////////////////////
 //                                                                             //
 //  fn:put primitive                                                           //

=== modified file 'src/store/naive/simple_pul.cpp'
--- src/store/naive/simple_pul.cpp	2011-10-12 08:43:16 +0000
+++ src/store/naive/simple_pul.cpp	2011-10-12 21:33:26 +0000
@@ -798,6 +798,35 @@
   theValidationList.push_back(upd);
 }
 
+void PULImpl::addRevalidate(
+    const QueryLoc* aQueryLoc,
+    store::Item_t& target)
+{
+  CollectionPul* pul = getCollectionPul(target.getp());
+
+  XmlNode* n = BASE_NODE(target);
+
+  NodeUpdates* updates = 0;
+  bool found = pul->theNodeToUpdatesMap.get(n, updates);
+
+  UpdRevalidate* upd = GET_STORE().getPULFactory().
+      createUpdRevalidate(this, aQueryLoc, target);
+
+
+  pul->theRevalidateList.push_back(upd);
+
+  if (!found)
+  {
+    updates = new NodeUpdates(1);
+    (*updates)[0] = upd;
+    pul->theNodeToUpdatesMap.insert(n, updates);
+  }
+  else
+  {
+    updates->push_back(upd);
+  }
+}
+
 
 /*******************************************************************************
  Collection primitives
@@ -1104,6 +1133,11 @@
                       thisPul->theDeleteList,
                       otherPul->theDeleteList,
                       UP_LIST_DELETE);
+      // Merge revalidation primitives
+      mergeUpdateList(thisPul,
+                      thisPul->theRevalidateList,
+                      otherPul->theRevalidateList,
+                      UP_LIST_NONE);
 
       // Merge collection primitives
       mergeUpdateList(thisPul,
@@ -1762,6 +1796,7 @@
   cleanList(theReplaceNodeList);
   cleanList(theReplaceContentList);
   cleanList(theDeleteList);
+  cleanList(theRevalidateList);
 
   cleanList(theCreateCollectionList);
   cleanList(theInsertIntoCollectionList);
@@ -1787,6 +1822,8 @@
   switchPulInPrimitivesList(theReplaceNodeList);
   switchPulInPrimitivesList(theReplaceContentList);
   switchPulInPrimitivesList(theDeleteList);
+  switchPulInPrimitivesList(theRevalidateList);
+
   switchPulInPrimitivesList(theCreateCollectionList);
   switchPulInPrimitivesList(theInsertIntoCollectionList);
   switchPulInPrimitivesList(theDeleteFromCollectionList);
@@ -2040,38 +2077,38 @@
     {
       InternalNode* node = (*it);
 
-    	for (csize i = 0; i < node->numChildren()-1; ++i)
-    	{
-    		if (node->getChild(i)->getNodeKind() == store::StoreConsts::textNode &&
+      for (csize i = 0; i < node->numChildren()-1; ++i)
+      {
+        if (node->getChild(i)->getNodeKind() == store::StoreConsts::textNode &&
             node->getChild(i+1)->getNodeKind() == store::StoreConsts::textNode)
-    		{
+        {
           TextNode* mergedNode = reinterpret_cast<TextNode*>(node->getChild(i));
 
-    			TextNodeMerge mergeInfo(node, i);
+          TextNodeMerge mergeInfo(node, i);
           mergeInfo.theMergedNodes.push_back(mergedNode);
           node->removeChild(i);
 
-    			zstring newContent = mergedNode->getText();
+          zstring newContent = mergedNode->getText();
           csize j = i;
 
-    			while (j < node->numChildren() &&
-                 node->getChild(j)->getNodeKind() == store::StoreConsts::textNode)
-    			{
-    			  TextNode* mergedNode = reinterpret_cast<TextNode*>(node->getChild(j));
-    				newContent += mergedNode->getText();
-    				node->removeChild(j);
-    				mergeInfo.theMergedNodes.push_back(mergedNode);
-    			}
+          while (j < node->numChildren() &&
+              node->getChild(j)->getNodeKind() == store::StoreConsts::textNode)
+          {
+            TextNode* mergedNode = reinterpret_cast<TextNode*>(node->getChild(j));
+            newContent += mergedNode->getText();
+            node->removeChild(j);
+            mergeInfo.theMergedNodes.push_back(mergedNode);
+          }
 
-    			theMergeList.push_back(mergeInfo);
+          theMergeList.push_back(mergeInfo);
 
           (void)GET_NODE_FACTORY().createTextNode(node->getTree(),
-                                                  node,
-                                                  false,
-                                                  i,
-                                                  newContent);
-    		}
-    	}
+              node,
+              false,
+              i,
+              newContent);
+        }
+      }
     }
 
 #ifndef ZORBA_NO_XMLSCHEMA
@@ -2091,6 +2128,11 @@
         ZORBA_FATAL(0, "Error during the application of the validation PUL");
       }
     }
+
+    if (thePul->theValidator != NULL)
+    {
+      applyList(theRevalidateList);
+    }
 #endif
 
     // Apply collection primitives, except delete primitives
@@ -2233,7 +2275,10 @@
     undoList(theInsertIntoCollectionList);
     undoList(theCreateCollectionList);
 
-    // Undo validation
+    // Undo validate-in-place validation
+    undoList(theRevalidateList);
+
+    // Undo apply-updates caused validation
     if (theValidationPul)
     {
       undoList(static_cast<PULImpl *>(theValidationPul.getp())->theValidationList);

=== modified file 'src/store/naive/simple_pul.h'
--- src/store/naive/simple_pul.h	2011-10-12 08:43:16 +0000
+++ src/store/naive/simple_pul.h	2011-10-12 21:33:26 +0000
@@ -185,6 +185,9 @@
   std::vector<UpdatePrimitive*>      theDeleteFromCollectionList;
   std::vector<UpdatePrimitive*>      theDeleteCollectionList;
 
+  // Validate in place primitives
+  std::vector<UpdatePrimitive*>      theRevalidateList;
+
   // Index Maintenance
   std::set<XmlNode*>                 theModifiedDocs;
   std::vector<XmlNode*>              theInsertedDocs;
@@ -253,6 +256,7 @@
 class PULImpl : public store::PUL
 {
   friend class CollectionPul;
+  friend class UpdRevalidate;
 
 public:
   enum UpdListKind
@@ -405,6 +409,10 @@
         store::Item_t&              typeName,
         std::vector<store::Item_t>& typedValue);
 
+  void addRevalidate(
+          const QueryLoc* aQueryLoc,
+          store::Item_t&              target);
+
   // Collection primitives
   void addCreateCollection(
         const QueryLoc* aQueryLoc,

=== added file 'test/rbkt/Queries/zorba/schemas/val-inplace3.xq'
--- test/rbkt/Queries/zorba/schemas/val-inplace3.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/schemas/val-inplace3.xq	2011-10-12 21:33:26 +0000
@@ -0,0 +1,22 @@
+import module namespace schema = "http://www.zorba-xquery.com/modules/schema";;
+import schema namespace d="http://www.example.com/doc"; at "val-inplace3.xsd";
+import module namespace file = "http://expath.org/ns/file";;
+declare revalidation lax;
+
+variable $doc:=<item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xmlns="http://www.zorba-xquery.org/schema";>
+    <a>old</a>
+</item>;
+
+(
+  schema:validate-in-place($doc),
+  replace value of node $doc//*:a with "new"
+);
+
+variable $res1:=string($doc//*:a);
+
+(
+  replace value of node $doc//*:a with "new"
+);
+
+($res1,string($doc//*:a))
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/schemas/val-inplace3.xsd'
--- test/rbkt/Queries/zorba/schemas/val-inplace3.xsd	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/schemas/val-inplace3.xsd	2011-10-12 21:33:26 +0000
@@ -0,0 +1,13 @@
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
+	targetNamespace="http://www.zorba-xquery.org/schema"; xmlns="http://www.zorba-xquery.org/schema";
+	elementFormDefault="qualified">
+
+	<xs:element name="item">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="a" type="xs:string" />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+
+</xs:schema>
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/schemas/val-inplace4.xq'
--- test/rbkt/Queries/zorba/schemas/val-inplace4.xq	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/schemas/val-inplace4.xq	2011-10-12 21:33:26 +0000
@@ -0,0 +1,40 @@
+import module namespace schema = "http://www.zorba-xquery.com/modules/schema";;
+import schema namespace d="http://www.example.com/doc"; at "val-inplace4.xsd";
+import module namespace file = "http://expath.org/ns/file";;
+declare revalidation lax;
+
+variable $doc:=<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xmlns="http://www.zorba-xquery.org/schema";>
+  <bigEl>
+    <a>old</a>
+  </bigEl>
+</items>;
+
+variable $doc-2:=<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xmlns="http://www.zorba-xquery.org/schema";>
+  <bigEl>
+    <a>old</a>
+  </bigEl>
+</items>;
+
+(
+  schema:validate-in-place($doc),
+  rename node $doc/*:bigEl as QName("http://www.zorba-xquery.org/schema","smallEl";)
+);
+
+
+schema:validate-in-place($doc-2);
+(
+<doc>
+{
+for $x in ($doc//*)
+return (<node name="{node-name($x)}" type="{schema:schema-type($x)}"/>)
+}
+</doc>,
+<doc2>
+{
+for $x in ($doc-2//*)
+return (<node name="{node-name($x)}" type="{schema:schema-type($x)}"/>)
+}
+</doc2>
+)
\ No newline at end of file

=== added file 'test/rbkt/Queries/zorba/schemas/val-inplace4.xsd'
--- test/rbkt/Queries/zorba/schemas/val-inplace4.xsd	1970-01-01 00:00:00 +0000
+++ test/rbkt/Queries/zorba/schemas/val-inplace4.xsd	2011-10-12 21:33:26 +0000
@@ -0,0 +1,26 @@
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
+	targetNamespace="http://www.zorba-xquery.org/schema"; xmlns="http://www.zorba-xquery.org/schema";
+	elementFormDefault="qualified">
+
+	<xs:element name="items">
+		<xs:complexType>
+			<xs:choice maxOccurs="unbounded">
+				<xs:element name="bigEl" type="bigEl" />
+				<xs:element name="smallEl" type="smallEl" />
+			</xs:choice>
+		</xs:complexType>
+	</xs:element>
+
+	<xs:complexType name="bigEl">
+		<xs:sequence>
+			<xs:element name="a" type="xs:string" />
+		</xs:sequence>
+	</xs:complexType>
+
+	<xs:complexType name="smallEl">
+		<xs:sequence>
+			<xs:element name="a" type="xs:string" />
+		</xs:sequence>
+	</xs:complexType>
+
+</xs:schema>
\ No newline at end of file

-- 
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