← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/markos-scratch into lp:zorba

 

Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/markos-scratch into lp:zorba.

Commit message:
Fixed and optimized deep-equal (bug #1180023)

Requested reviews:
  Markos Zaharioudakis (markos-za)

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/164981

Fixed and optimized deep-equal (bug #1180023)
-- 
https://code.launchpad.net/~zorba-coders/zorba/markos-scratch/+merge/164981
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog'
--- ChangeLog	2013-05-16 09:21:28 +0000
+++ ChangeLog	2013-05-21 21:50:31 +0000
@@ -7,9 +7,11 @@
 
 Optimizations:
   * Implemented hoisting optimization for general FLWOR.
+  * Optimized implementation of fn:deep-equal
 
 Bug Fixes/Other Changes:
   * Fixed bug in hoisting through try-catch expr
+  * Fixed implementation of fn:deep-equal according to latest W3C spec.
 
 
 version 2.9

=== modified file 'src/runtime/sequences/sequences_impl.cpp'
--- src/runtime/sequences/sequences_impl.cpp	2013-05-08 20:40:49 +0000
+++ src/runtime/sequences/sequences_impl.cpp	2013-05-21 21:50:31 +0000
@@ -829,25 +829,23 @@
 /*******************************************************************************
   15.3.1 fn:deep-equal
 ********************************************************************************/
-// Forward declaration
+
 static bool DeepEqual(
     const QueryLoc& loc,
     static_context* sctx,
-    dynamic_context* dctx,
     store::Item_t& item1,
     store::Item_t& item2,
-    XQPCollator* collator);
-
-
-static bool DeepEqual(
+    XQPCollator* collator,
+    int timezone);
+
+
+static bool DeepEqualChildren(
     const QueryLoc& loc,
     static_context* sctx,
-    dynamic_context* dctx,
-    store::Iterator_t it1,
-    store::Iterator_t it2,
+    const store::Iterator_t& it1,
+    const store::Iterator_t& it2,
     XQPCollator* collator,
-    bool skip_pi_nodes,
-    bool skip_comment_nodes)
+    int timezone)
 {
   store::Item_t child1, child2;
   bool c1Valid, c2Valid;
@@ -857,38 +855,35 @@
 
   while (1)
   {
-    while ((c1Valid = it1->next(child1))
-            &&
-            ((skip_pi_nodes && child1->getNodeKind() == store::StoreConsts::piNode)
-              ||
-            (skip_comment_nodes && child1->getNodeKind() == store::StoreConsts::commentNode)))
+    while ((c1Valid = it1->next(child1)) &&
+           (child1->getNodeKind() == store::StoreConsts::piNode ||
+            child1->getNodeKind() == store::StoreConsts::commentNode))
       ;
 
-    while ((c2Valid = it2->next(child2))
-            &&
-            ((skip_pi_nodes && child2->getNodeKind() == store::StoreConsts::piNode)
-              ||
-            (skip_comment_nodes && child2->getNodeKind() == store::StoreConsts::commentNode)))
+    while ((c2Valid = it2->next(child2)) &&
+            (child2->getNodeKind() == store::StoreConsts::piNode ||
+             child2->getNodeKind() == store::StoreConsts::commentNode))
       ;
 
     if (!c1Valid && !c2Valid)
       return true;
     else if (!c1Valid || !c2Valid)
       return false;
-    else if (!DeepEqual(loc, sctx, dctx, child1, child2, collator))
+    else if (!DeepEqual(loc, sctx, child1, child2, collator, timezone))
       return false;
   }
 
   return true;
 }
 
+
 static bool DeepEqualAttributes(
   const QueryLoc& loc,
   static_context* sctx,
-  dynamic_context* dctx,
-  store::Iterator_t it1,
-  store::Iterator_t it2,
-  XQPCollator* collator)
+  const store::Iterator_t& it1,
+  const store::Iterator_t& it2,
+  XQPCollator* collator,
+  int timezone)
 {
   store::Item_t child1, child2;
   int c1count = 0, c2count = 0;
@@ -899,14 +894,18 @@
   while (it1->next(child1))
   {
     c1count++;
+
     it2->reset();
+
     bool found = false;
     while (it2->next(child2))
-      if (DeepEqual(loc, sctx, dctx, child1, child2, collator))
+    {
+      if (DeepEqual(loc, sctx, child1, child2, collator, timezone))
       {
         found = true;
         break;
       }
+    }
 
     if (!found)
       return false;
@@ -922,128 +921,196 @@
   return true;
 }
 
+
 static bool DeepEqualNodes(
     const QueryLoc& loc,
     static_context* sctx,
-    dynamic_context* dctx,
     const store::Item_t& item1,
     const store::Item_t& item2,
-    XQPCollator* collator)
+    XQPCollator* collator,
+    int timezone)
 {
   if (item1->getNodeKind() != item2->getNodeKind())
     return false;
 
   switch (item1->getNodeKind())
   {
-    case store::StoreConsts::anyNode:
-      ZORBA_ASSERT(false);  // case not treated
-      break;
-
-    case store::StoreConsts::documentNode:
-    {
-      return DeepEqual(loc,
-                       sctx,
-                       dctx,
-                       item1->getChildren(),
-                       item2->getChildren(),
-                       collator,
-                       true,
-                       false);
-      break;
-    }
-    case store::StoreConsts::elementNode:
-    {
-      if (! item1->getNodeName()->equals(item2->getNodeName()))
-        return false;
-
-      TypeManager* tm = sctx->get_typemanager();
-
-      xqtref_t type1 = tm->create_value_type(item1.getp());
-      xqtref_t type2 = tm->create_value_type(item2.getp());
-
-      const NodeXQType* nodeType1 = static_cast<const NodeXQType *>(type1.getp());
-      const NodeXQType* nodeType2 = static_cast<const NodeXQType *>(type2.getp());
-
-      if ( nodeType1->get_content_type()->content_kind() != nodeType2->get_content_type()->content_kind() )
-        return false;
-
-      return (DeepEqualAttributes(loc,
-                                  sctx,
-                                  dctx,
-                                  item1->getAttributes(),
-                                  item2->getAttributes(),
-                                  collator)
-              &&
-              DeepEqual(loc,
-                        sctx,
-                        dctx,
-                        item1->getChildren(),
-                        item2->getChildren(),
-                        collator,
-                        true,
-                        true));
-      break;
-    }
-    case store::StoreConsts::attributeNode:
-    {
-      if (! item1->getNodeName()->equals(item2->getNodeName()))
-        return false;
-
-      store::Item_t tvalue1, tvalue2;
-      store::Iterator_t tvalue1Iter, tvalue2Iter;
-      item1->getTypedValue(tvalue1, tvalue1Iter);
-      item2->getTypedValue(tvalue2, tvalue2Iter);
-
-      if (tvalue1Iter == NULL && tvalue2Iter == NULL)
-        return DeepEqual(loc, sctx, dctx, tvalue1, tvalue2, collator);
-      else if (tvalue1Iter != NULL && tvalue2Iter != NULL)
-        return DeepEqual(loc, sctx, dctx, tvalue1Iter, tvalue2Iter, collator, false, false);
-      else
-        return false;
-
-      break;
-    }
-    case store::StoreConsts::textNode:
-    case store::StoreConsts::commentNode:
-    {
-      return (0 == utf8::compare(item1->getStringValue(),
-                                 item2->getStringValue(),
-                                 collator));
-      break;
-    }
-
-    case store::StoreConsts::piNode:
-    {
-      int lCmpRes = utf8::compare(item1->getNodeName()->getStringValue(),
-                                  item2->getNodeName()->getStringValue(),
-                                  collator);
-      if (0 != lCmpRes)
-        return false;
-
-      lCmpRes = utf8::compare(item1->getStringValue(),
-                              item2->getStringValue(),
-                              collator);
-
-      return (0 == lCmpRes);
-      break;
-    }
-
-    case store::StoreConsts::namespaceNode:
-    {
-      int lCmpRes = utf8::compare(item1->getNamespacePrefix(),
-                                  item2->getNamespacePrefix(),
-                                  collator);
-      if (0 != lCmpRes)
-        return false;
-
-      lCmpRes = utf8::compare(item1->getStringValue(),
-                              item2->getStringValue(),
-                              collator);
-
-      return (0 == lCmpRes);
-      break;
-    }
-  }
+  case store::StoreConsts::documentNode:
+  {
+    return DeepEqualChildren(loc,
+                             sctx,
+                             item1->getChildren(),
+                             item2->getChildren(),
+                             collator,
+                             timezone);
+    break;
+  }
+  case store::StoreConsts::elementNode:
+  {
+    if (! item1->getNodeName()->equals(item2->getNodeName()))
+      return false;
+
+    if (!DeepEqualAttributes(loc,
+                             sctx,
+                             item1->getAttributes(),
+                             item2->getAttributes(),
+                             collator,
+                             timezone))
+      return false;
+
+    if (item1->haveSimpleContent())
+    {
+      if (!item2->haveSimpleContent())
+        return false;
+
+      store::Item_t value1, value2;
+      store::Iterator_t ite1, ite2;
+      item1->getTypedValue(value1, ite1);
+      item2->getTypedValue(value2, ite2);
+
+      if (ite1 == NULL && ite2 == NULL)
+      {
+        return DeepEqual(loc, sctx, value1, value2, collator, timezone);
+      }
+      else if (ite1 != NULL && ite2 != NULL)
+      {
+        ite1->open();
+        ite2->open();
+        
+        while (1)
+        {
+          bool c1Valid = ite1->next(value1);
+          bool c2Valid = ite2->next(value2);
+          
+          if (!c1Valid && !c2Valid)
+            return true;
+          else if (!c1Valid || !c2Valid)
+            return false;
+          else if (!DeepEqual(loc, sctx, value1, value2, collator, timezone))
+            return false;
+        }
+      }
+      else
+      {
+        return false;
+      }
+    }
+    else if (item2->haveSimpleContent())
+    {
+      return false;
+    }
+    else
+    {
+      store::Item* typename1 = item1->getType();
+      store::Item* typename2 = item2->getType();
+
+      if (typename1->equals(typename2))
+      {
+        return DeepEqualChildren(loc,
+                                 sctx,
+                                 item1->getChildren(),
+                                 item2->getChildren(),
+                                 collator,
+                                 timezone);
+      }
+      else
+      {
+        TypeManager* tm = sctx->get_typemanager();
+
+        xqtref_t type1 = 
+        tm->create_named_type(typename1, TypeConstants::QUANT_ONE, loc, true);
+
+        xqtref_t type2 = 
+        tm->create_named_type(typename2, TypeConstants::QUANT_ONE, loc, true);
+
+        ZORBA_ASSERT(type1->isComplex() && type2->isComplex());
+
+        if (type1->contentKind() != type2->contentKind())
+          return false;
+
+        return DeepEqualChildren(loc,
+                                 sctx,
+                                 item1->getChildren(),
+                                 item2->getChildren(),
+                                 collator,
+                                 timezone);
+      }
+    }
+  }
+  case store::StoreConsts::attributeNode:
+  {
+    if (! item1->getNodeName()->equals(item2->getNodeName()))
+      return false;
+
+    store::Item_t value1, value2;
+    store::Iterator_t ite1, ite2;
+    item1->getTypedValue(value1, ite1);
+    item2->getTypedValue(value2, ite2);
+
+    if (ite1 == NULL && ite2 == NULL)
+    {
+      return DeepEqual(loc, sctx, value1, value2, collator, timezone);
+    }
+    else if (ite1 != NULL && ite2 != NULL)
+    {
+      ite1->open();
+      ite2->open();
+
+      while (1)
+      {
+        bool c1Valid = ite1->next(value1);
+        bool c2Valid = ite2->next(value2);
+        
+        if (!c1Valid && !c2Valid)
+          return true;
+        else if (!c1Valid || !c2Valid)
+          return false;
+        else if (!DeepEqual(loc, sctx, value1, value2, collator, timezone))
+          return false;
+      }
+    }
+    else
+    {
+      return false;
+    }
+
+    break;
+  }
+  case store::StoreConsts::textNode:
+  case store::StoreConsts::commentNode:
+  {
+    return (0 == utf8::compare(item1->getStringValue(),
+                               item2->getStringValue(),
+                               collator));
+  }
+
+  case store::StoreConsts::piNode:
+  {
+    if (utf8::compare(item1->getNodeName()->getStringValue(),
+                      item2->getNodeName()->getStringValue(),
+                      collator))
+      return false;
+
+    return (0 == utf8::compare(item1->getStringValue(),
+                               item2->getStringValue(),
+                               collator));
+  }
+
+  case store::StoreConsts::namespaceNode:
+  {
+    if (utf8::compare(item1->getNamespacePrefix(),
+                      item2->getNamespacePrefix(),
+                      collator))
+      return false;
+    
+    return (0 == utf8::compare(item1->getStringValue(),
+                               item2->getStringValue(),
+                               collator));
+  }
+  default:
+    ZORBA_ASSERT(false);
+  }
+
   return true;
 }
 
@@ -1051,10 +1118,10 @@
 static bool DeepEqualObjects(
     const QueryLoc& loc,
     static_context* sctx,
-    dynamic_context* dctx,
     const store::Item_t& item1,
     const store::Item_t& item2,
-    XQPCollator* collator)
+    XQPCollator* collator,
+    int timezone)
 {
   assert(item1->isJSONObject());
   assert(item2->isJSONObject());
@@ -1070,24 +1137,27 @@
   while (lKeys->next(lKey))
   {
     lValue2 = item2->getObjectValue(lKey);
-    if (lValue2 == NULL) return false;
+
+    if (lValue2 == NULL)
+      return false;
 
     lValue1 = item1->getObjectValue(lKey);
 
-    if (!DeepEqual(loc, sctx, dctx, lValue1, lValue2, collator))
+    if (!DeepEqual(loc, sctx, lValue1, lValue2, collator, timezone))
       return false;
   }
 
   return true;
 }
 
+
 static bool DeepEqualArrays(
     const QueryLoc& loc,
     static_context* sctx,
-    dynamic_context* dctx,
     const store::Item_t& item1,
     const store::Item_t& item2,
-    XQPCollator* collator)
+    XQPCollator* collator,
+    int timezone)
 {
   assert(item1->isJSONArray());
   assert(item2->isJSONArray());
@@ -1104,7 +1174,7 @@
 
   while (lValues1->next(lValue1) && lValues2->next(lValue2))
   {
-    if (!DeepEqual(loc, sctx, dctx, lValue1, lValue2, collator))
+    if (!DeepEqual(loc, sctx, lValue1, lValue2, collator, timezone))
       return false;
   }
 
@@ -1115,60 +1185,37 @@
 static bool DeepEqual(
     const QueryLoc& loc,
     static_context* sctx,
-    dynamic_context* dctx,
     store::Item_t& item1,
     store::Item_t& item2,
-    XQPCollator* collator)
+    XQPCollator* collator,
+    int timezone)
 {
-  const RootTypeManager& rtm = GENV_TYPESYSTEM;
-  TypeManager* tm = sctx->get_typemanager();
-
-  if (item1.isNull() && item2.isNull())
-    return true;
-
-  if (item1 == NULL || item2 == NULL)
-    return false;
-
-  if (item1->isNode() != item2->isNode() ||
-      item1->isJSONObject() != item2->isJSONObject() ||
-      item1->isJSONArray() != item2->isJSONArray())
-    return false;
-
-
-  xqtref_t type1 = tm->create_value_type(item1.getp());
-  xqtref_t type2 = tm->create_value_type(item2.getp());
-
-  if ( type1->content_kind() != type2->content_kind() )
-    return false;
-
-  if (item1->isAtomic())
+  if (item1->getKind() != item2->getKind())
+    return false;
+
+  switch (item1->getKind())
+  {
+  case store::Item::ATOMIC:
   {
     assert(item2->isAtomic());
-    long timezone = dctx->get_implicit_timezone();
-
-    if (collator == NULL)
-      collator = sctx->get_default_collator(QueryLoc::null);
-
-    // check NaN
-    if (((TypeOps::is_subtype(tm, *type1, *rtm.FLOAT_TYPE_ONE)
-          &&
-          item1->getFloatValue().isNaN())
-          ||
-         (TypeOps::is_subtype(tm, *type1, *rtm.DOUBLE_TYPE_ONE)
-          &&
-          item1->getDoubleValue().isNaN()))
-          &&
-        ((TypeOps::is_subtype(tm, *type2, *rtm.FLOAT_TYPE_ONE)
-          &&
-          item2->getFloatValue().isNaN())
-          ||
-         (TypeOps::is_subtype(tm, *type2, *rtm.DOUBLE_TYPE_ONE)
-          &&
-          item2->getDoubleValue().isNaN())))
+
+    store::SchemaTypeCode type1 = item1->getTypeCode();
+    store::SchemaTypeCode type2 = item2->getTypeCode();
+
+    // check if bot items are NaN
+    if (((type1 == store::XS_FLOAT && item1->getFloatValue().isNaN()) ||
+         (type1 == store::XS_DOUBLE && item1->getDoubleValue().isNaN()))
+        &&
+        ((type2 == store::XS_FLOAT && item2->getFloatValue().isNaN()) ||
+         (type2 == store::XS_DOUBLE && item2->getDoubleValue().isNaN())))
+    {
       return true;
+    }
 
     try
     {
+      TypeManager* tm = sctx->get_typemanager();
+
       return CompareIterator::valueEqual(loc, item1, item2, tm, timezone, collator);
     }
     catch (ZorbaException const& e)
@@ -1177,25 +1224,31 @@
         return false;
       throw;
     }
-  }
-  else
-  {
-    if (item1->isNode())
-    {
-      return DeepEqualNodes(loc, sctx, dctx, item1, item2, collator);
-    }
-    else if (item1->isJSONObject())
-    {
-      return DeepEqualObjects(loc, sctx, dctx, item1, item2, collator);
+
+    break;
+  }
+  case store::Item::NODE:
+  {
+    return DeepEqualNodes(loc, sctx, item1, item2, collator, timezone);
+  }
+  case store::Item::JSONIQ:
+  {
+    if (item1->isJSONObject())
+    {
+      return DeepEqualObjects(loc, sctx, item1, item2, collator, timezone);
     }
     else
     {
-      return DeepEqualArrays(loc, sctx, dctx, item1, item2, collator);
+      return DeepEqualArrays(loc, sctx, item1, item2, collator, timezone);
     }
-
+  }
+  default:
+  {
     ZORBA_ASSERT(false);  // should never reach here
-    return false;
-  }
+  }
+  }
+
+  return false;
 }
 
 
@@ -1207,6 +1260,7 @@
   store::Item_t arg1, arg2;
   XQPCollator* collator = NULL;
   bool equal = true;
+  int timezone;
 
   DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
 
@@ -1215,13 +1269,20 @@
     collator = getCollator(theSctx, loc, planState, theChildren[2].getp());
   }
 
+  if (collator == NULL)
+    collator = theSctx->get_default_collator(QueryLoc::null);
+
+  timezone = planState.theGlobalDynCtx->get_implicit_timezone();
+
   while (1)
   {
     bool a1 = consumeNext(arg1, theChildren[0].getp(), planState);
     bool a2 = consumeNext(arg2, theChildren[1].getp(), planState);
 
     if (!a1 && !a2)
+    {
       break;
+    }
     else if (!a1 || !a2)
     {
       equal = false;
@@ -1230,29 +1291,19 @@
 
     if (arg1->isFunction() || arg2->isFunction())
     {
-			throw XQUERY_EXCEPTION(
-          err::FOTY0015,
-          ERROR_PARAMS ( (arg1->isFunction()
-                            ? arg1
-                            : arg2
-                         )->getFunctionName()->getStringValue() ),
-          ERROR_LOC( loc )
-        );
+			RAISE_ERROR(err::FOTY0015, loc,
+      ERROR_PARAMS((arg1->isFunction() ? arg1 : arg2)->getFunctionName()->getStringValue()));
     }
 
-    equal = equal && DeepEqual(loc,
-                               theSctx,
-                               planState.theLocalDynCtx,
-                               arg1,
-                               arg2,
-                               collator);
+    equal = equal && DeepEqual(loc, theSctx, arg1, arg2, collator, timezone);
   }
 
   STACK_PUSH(GENV_ITEMFACTORY->createBoolean(result, equal), state);
 
-  STACK_END (state);
+  STACK_END(state);
 }
 
+
 /*******************************************************************************
 
   15.3.3 op:intersect : implemented by the HashSemiJoinIterator below

=== modified file 'src/store/api/item.h'
--- src/store/api/item.h	2013-04-09 13:08:21 +0000
+++ src/store/api/item.h	2013-05-21 21:50:31 +0000
@@ -233,6 +233,13 @@
   getType() const;
 
   /**
+   * @return true if the type of this element node is a simple type or a complex
+   * type with simple content.
+   */
+  virtual bool
+  haveSimpleContent() const;
+
+  /**
    * Get a hash value computed from the value of this item.
    *
    * @param RuntimeCB the runtime control block that contains the
@@ -319,7 +326,8 @@
   virtual void
   getTypedValue(Item_t& val, Iterator_t& iter) const;
 
-  /** Method to print to content of the Item
+  /**
+   * Method to print to content of the Item
    */
   virtual zstring
   show() const;

=== modified file 'src/store/naive/item.cpp'
--- src/store/naive/item.cpp	2013-04-09 13:08:21 +0000
+++ src/store/naive/item.cpp	2013-05-21 21:50:31 +0000
@@ -296,6 +296,14 @@
   );
 }
 
+bool Item::haveSimpleContent() const
+{
+  throw ZORBA_EXCEPTION(
+    zerr::ZSTR0050_FUNCTION_NOT_IMPLEMENTED_FOR_ITEMTYPE,
+    ERROR_PARAMS( __FUNCTION__, typeid(*this).name() )
+  );
+}
+
 
 uint32_t Item::hash(long timezone, const XQPCollator* coll) const
 {

=== modified file 'src/store/naive/node_items.h'
--- src/store/naive/node_items.h	2013-04-09 12:13:33 +0000
+++ src/store/naive/node_items.h	2013-05-21 21:50:31 +0000
@@ -1056,6 +1056,12 @@
 
   void getTypedValue(store::Item_t& val, store::Iterator_t& iter) const;
 
+  bool haveSimpleContent() const 
+  {
+    TextNode* node;
+    return haveTypedTypedValue(node);
+  }
+
   bool isId() const;
 
   bool isIdRefs() const;

=== modified file 'src/types/schema/revalidateUtils.cpp'
--- src/types/schema/revalidateUtils.cpp	2013-05-16 17:38:41 +0000
+++ src/types/schema/revalidateUtils.cpp	2013-05-21 21:50:31 +0000
@@ -524,7 +524,7 @@
         //  - if invalid there will be a validation exception thrown before this code
         //  - if xmlspace or mixed content it's fine to have the same node
 
-        if ( udXQType.content_kind()==XQType::SIMPLE_CONTENT_KIND )
+        if ( udXQType.contentKind()==XQType::SIMPLE_CONTENT_KIND )
         {
           typeManager->getSchema()->parseUserSimpleTypes(textValue,
                                                          type,
@@ -604,7 +604,7 @@
 bool SchemaValidatorImpl::isPossibleSimpleContentRevalImpl(
     xqtref_t schemaType)
 {
-  if ( schemaType->content_kind() == XQType::SIMPLE_CONTENT_KIND )
+  if ( schemaType->contentKind() == XQType::SIMPLE_CONTENT_KIND )
   {
     if (schemaType->type_kind() == XQType::ATOMIC_TYPE_KIND)
     {

=== modified file 'src/types/schema/validate.cpp'
--- src/types/schema/validate.cpp	2013-05-16 17:38:41 +0000
+++ src/types/schema/validate.cpp	2013-05-21 21:50:31 +0000
@@ -691,7 +691,7 @@
     cout << "     - text: '" << textNodeValue << "' T: " <<
       typeQName->getLocalName() << "\n"; cout.flush();
     cout << "        xqT: " << xqType->toString() << "  content_kind: " <<
-      (long)xqType->content_kind() << " tKind:" << (long)xqType->type_kind() << " \n";
+      (long)xqType->contentKind() << " tKind:" << (long)xqType->type_kind() << " \n";
     cout.flush();
   }
   else
@@ -702,7 +702,7 @@
 #endif
 
   if ( xqType != NULL &&
-       xqType->content_kind() == XQType::SIMPLE_CONTENT_KIND )
+       xqType->contentKind() == XQType::SIMPLE_CONTENT_KIND )
   {
     store::NsBindings nsBindings;
     parent->getNamespaceBindings(nsBindings);
@@ -724,8 +724,8 @@
                                        typedValues);
   }
   else if ( xqType!=NULL &&
-            (xqType->content_kind()==XQType::ELEMENT_ONLY_CONTENT_KIND ||
-             xqType->content_kind()==XQType::EMPTY_CONTENT_KIND ))
+            (xqType->contentKind()==XQType::ELEMENT_ONLY_CONTENT_KIND ||
+             xqType->contentKind()==XQType::EMPTY_CONTENT_KIND ))
   {
     // if text not valid the schemaValidator should have already
     // thrown an error
@@ -819,7 +819,7 @@
         resultList.push_back(result);
       }
       else if (udt.isComplex() &&
-               udt.content_kind() == XQType::SIMPLE_CONTENT_KIND)
+               udt.contentKind() == XQType::SIMPLE_CONTENT_KIND)
       {
         try
         {

=== modified file 'src/types/schema/validate.h'
--- src/types/schema/validate.h	2013-02-07 17:24:36 +0000
+++ src/types/schema/validate.h	2013-05-21 21:50:31 +0000
@@ -70,9 +70,9 @@
    */
   static bool typeHasValue(xqtref_t t)
   {
-    return (t->content_kind() == XQType::MIXED_CONTENT_KIND ||
-            t->content_kind() == XQType::SIMPLE_CONTENT_KIND ||
-            t->content_kind() == XQType::EMPTY_CONTENT_KIND);
+    return (t->contentKind() == XQType::MIXED_CONTENT_KIND ||
+            t->contentKind() == XQType::SIMPLE_CONTENT_KIND ||
+            t->contentKind() == XQType::EMPTY_CONTENT_KIND);
   }
   
   /**
@@ -87,7 +87,7 @@
       const xqtref_t& t,
       const QueryLoc& loc)
   {
-    return (t->content_kind() == XQType::SIMPLE_CONTENT_KIND &&
+    return (t->contentKind() == XQType::SIMPLE_CONTENT_KIND &&
             !TypeOps::is_equal(tm, *t, *GENV_TYPESYSTEM.UNTYPED_ATOMIC_TYPE_ONE, loc));
   }
   
@@ -98,7 +98,7 @@
    */
   static bool typeHasEmptyValue(xqtref_t t)
   {
-    return t->content_kind() == XQType::EMPTY_CONTENT_KIND;
+    return t->contentKind() == XQType::EMPTY_CONTENT_KIND;
   }
 
 private:

=== modified file 'src/types/typeimpl.cpp'
--- src/types/typeimpl.cpp	2013-04-17 16:18:23 +0000
+++ src/types/typeimpl.cpp	2013-05-21 21:50:31 +0000
@@ -246,12 +246,22 @@
 ********************************************************************************/
 bool XQType::isComplex() const
 {
-  if (type_kind() == XQType::USER_DEFINED_KIND)
+  switch (type_kind())
+  {
+  case XQType::USER_DEFINED_KIND:
   {
     return static_cast<const UserDefinedXQType*>(this)->theUDTKind == COMPLEX_UDT; 
   }
-
-  return false;
+  case XQType::ANY_TYPE_KIND:
+  case XQType::UNTYPED_KIND:
+  {
+    return true;
+  }
+  default:
+  {
+    return false;
+  }
+  }
 }
 
 
@@ -381,6 +391,54 @@
 /*******************************************************************************
 
 ********************************************************************************/
+XQType::content_kind_t XQType::contentKind() const
+{
+  switch (type_kind())
+  {
+  case XQType::USER_DEFINED_KIND:
+  {
+    return static_cast<const UserDefinedXQType*>(this)->theContentKind; 
+  }
+  case XQType::NONE_KIND:
+  case XQType::EMPTY_KIND:
+  {
+    return EMPTY_CONTENT_KIND;
+  }
+  case XQType::ATOMIC_TYPE_KIND:
+  case XQType::ANY_SIMPLE_TYPE_KIND:
+  {
+    return SIMPLE_CONTENT_KIND; 
+  }
+  default:
+  {
+    return MIXED_CONTENT_KIND;
+  }
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+bool XQType::isAnonymous() const
+{
+  switch (type_kind())
+  {
+  case XQType::USER_DEFINED_KIND:
+  {
+    return static_cast<const UserDefinedXQType*>(this)->theIsAnonymous; 
+  }
+  default:
+  {
+    return false;
+  }
+  }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
 store::Item_t XQType::getQName() const
 {
   switch (type_kind())
@@ -1338,7 +1396,7 @@
   theQName(qname),
   theBaseType(baseType),
   theUDTKind(udtKind),
-  m_contentKind(contentKind)
+  theContentKind(contentKind)
 {
   assert(udtKind == ATOMIC_UDT || udtKind == COMPLEX_UDT);
 
@@ -1347,7 +1405,7 @@
 
   TRACE("UserDefinedXQType c2: " << theQName->getLocalName() << "@"
         << theQName->getNamespace() << " " << decodeUDTKind(theUDTKind)
-        << " " << contentKindStr(m_contentKind));
+        << " " << contentKindStr(theContentKind));
 }
 
 
@@ -1367,7 +1425,7 @@
   theQName(qname),
   theBaseType(baseType),
   theUDTKind(LIST_UDT),
-  m_contentKind(SIMPLE_CONTENT_KIND),
+  theContentKind(SIMPLE_CONTENT_KIND),
   m_listItemType(listItemType)
 {
   ZORBA_ASSERT(listItemType);
@@ -1391,7 +1449,7 @@
   theQName(qname),
   theBaseType(baseType),
   theUDTKind(UNION_UDT),
-  m_contentKind(SIMPLE_CONTENT_KIND),
+  theContentKind(SIMPLE_CONTENT_KIND),
   m_unionItemTypes(unionItemTypes)
 {
   std::vector<xqtref_t>::const_iterator ite = unionItemTypes.begin();
@@ -1412,7 +1470,7 @@
   ar & theQName;
   ar & theBaseType;
   SERIALIZE_ENUM(UDTKind, theUDTKind);
-  SERIALIZE_ENUM(content_kind_t, m_contentKind);
+  SERIALIZE_ENUM(content_kind_t, theContentKind);
   ar & m_listItemType;
   ar & m_unionItemTypes;
 }
@@ -1586,7 +1644,7 @@
     ZORBA_ASSERT(false);
   }
 
-  info << " " << contentKindStr(m_contentKind);
+  info << " " << contentKindStr(theContentKind);
 
   return os << "[UserDefinedXQType "
             << TypeOps::decode_quantifier(get_quantifier()) << " "

=== modified file 'src/types/typeimpl.h'
--- src/types/typeimpl.h	2013-04-11 22:29:26 +0000
+++ src/types/typeimpl.h	2013-05-21 21:50:31 +0000
@@ -375,7 +375,9 @@
 
   int card() const;
 
-  virtual bool isAnonymous() const {  return false; }
+  store::Item_t getQName() const;
+
+  bool isAnonymous() const;
 
   bool isComplex() const;
 
@@ -395,9 +397,7 @@
 
   bool isBuiltinAtomicOne() const;
 
-  store::Item_t getQName() const;
-
-  virtual content_kind_t content_kind() const { return MIXED_CONTENT_KIND; };
+  content_kind_t contentKind() const;
 
   virtual xqtref_t getBaseBuiltinType() const { return this; }
 
@@ -429,8 +429,6 @@
 public:
   NoneXQType(const TypeManager* manager, bool builtin = false);
 
-  content_kind_t content_kind() const { return EMPTY_CONTENT_KIND; };
-
  public:
   SERIALIZABLE_CLASS(NoneXQType)
   SERIALIZABLE_CLASS_CONSTRUCTOR2(NoneXQType, XQType)
@@ -446,8 +444,6 @@
 public:
   EmptyXQType(const TypeManager* manager, bool builtin = false);
 
-  content_kind_t content_kind() const { return EMPTY_CONTENT_KIND; };
-
  public:
   SERIALIZABLE_CLASS(EmptyXQType)
   SERIALIZABLE_CLASS_CONSTRUCTOR2(EmptyXQType, XQType)
@@ -506,8 +502,6 @@
 
   store::SchemaTypeCode get_type_code() const { return theAtomicCode; }
 
-  content_kind_t content_kind() const { return SIMPLE_CONTENT_KIND; };
-
   virtual std::ostream& serialize_ostream(std::ostream& os) const;
 };
 
@@ -605,8 +599,6 @@
 
   bool is_untyped() const;
 
-  content_kind_t content_kind() const { return MIXED_CONTENT_KIND; };
-
   bool is_equal(const TypeManager* tm, const NodeXQType& supertype) const;
 
   bool is_subtype(
@@ -708,22 +700,22 @@
   defined atomic types, the associated quantifier can be anything. For all
   other user-defined types, associated quantifier must be ONE.
  
-  m_qname:
+  teQName:
   --------
   The name of this user-defined type. The actual type definition is stored in
   the TypeManger that created this type (and is pointed to my theManager). The
   TypeManager also stores the mapping from the type name to the type definition.
 
-  m_base_type:
+  theBaseType:
   ------------
   The baseType of this type. NULL for list or union types.
 
   theUDTKind:
-  ---------------
+  -----------
   Whether this is an atomic, list, union, or complex type.
 
-  m_contentKind:
-  --------------
+  theContentKind:
+  ---------------
   This type's content kind, if this is a complex type. One of empty, simple,
   element-only, or mixed.
 
@@ -751,7 +743,7 @@
 
   UDTKind                 theUDTKind;
 
-  content_kind_t          m_contentKind;
+  content_kind_t          theContentKind;
 
   std::vector<xqtref_t>   m_unionItemTypes;
 
@@ -798,10 +790,6 @@
 
   virtual ~UserDefinedXQType() {}
 
-  virtual bool isAnonymous() const {  return theIsAnonymous; }
-
-  virtual content_kind_t content_kind() const { return m_contentKind; };
-
   UDTKind getUDTKind() const { return theUDTKind; }
 
   xqtref_t getBaseType() const { return theBaseType; }
@@ -873,8 +861,6 @@
   {
   }
 
-  content_kind_t content_kind() const { return SIMPLE_CONTENT_KIND; };
-
 public:
   SERIALIZABLE_CLASS(AnySimpleXQType)
   SERIALIZABLE_CLASS_CONSTRUCTOR2(AnySimpleXQType, XQType)

=== modified file 'src/types/typemanagerimpl.cpp'
--- src/types/typemanagerimpl.cpp	2013-04-23 20:38:23 +0000
+++ src/types/typemanagerimpl.cpp	2013-05-21 21:50:31 +0000
@@ -1087,7 +1087,7 @@
                                    udt.getBaseType(),
                                    quantifier,
                                    udt.getUDTKind(),
-                                   udt.content_kind());
+                                   udt.contentKind());
     }
   }
   default:

=== modified file 'test/fots/CMakeLists.txt'
--- test/fots/CMakeLists.txt	2013-05-17 23:57:15 +0000
+++ test/fots/CMakeLists.txt	2013-05-21 21:50:31 +0000
@@ -139,7 +139,6 @@
 EXPECTED_FOTS_FAILURE (app-CatalogCheck Catalog010 1172273)
 EXPECTED_FOTS_FAILURE (app-CatalogCheck Catalog011 1172273)
 EXPECTED_FOTS_FAILURE (fn-available-environment-variables fn-available-environment-variables-011 0)
-EXPECTED_FOTS_FAILURE (fn-deep-equal K2-SeqDeepEqualFunc-36 0)
 EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-005 0)
 EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-006 0)
 EXPECTED_FOTS_FAILURE (fn-environment-variable environment-variable-007 0)


Follow ups