bool deepEqual( const QueryLoc& loc, static_context* sctx, store::Item_t& item1, store::Item_t& item2, XQPCollator* collator, int timezone, bool raiseError) { if (item1->isFunction() || item2->isFunction()) { if (raiseError) { RAISE_ERROR(err::FOTY0015, loc, ERROR_PARAMS((item1->isFunction() ? item1 : item2)->getFunctionName()->getStringValue())); } else return false; } if (item1->getKind() != item2->getKind()) return false; switch (item1->getKind()) { case store::Item::ATOMIC: { assert(item2->isAtomic()); store::SchemaTypeCode type1 = item1->getTypeCode(); store::SchemaTypeCode type2 = item2->getTypeCode(); // check if both 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; } if (raiseError) { try { TypeManager* tm = sctx->get_typemanager(); return CompareIterator::valueEqual(loc, item1, item2, tm, timezone, collator, raiseError); } catch (ZorbaException const& e) { if (e.diagnostic() == err::XPTY0004) return false; throw; } } else { TypeManager* tm = sctx->get_typemanager(); return CompareIterator::valueEqual(loc, item1, item2, tm, timezone, collator, raiseError); } break; } case store::Item::NODE: { return deepEqualNodes(loc, sctx, item1, item2, collator, timezone, raiseError); } case store::Item::OBJECT: { return deepEqualObjects(loc, sctx, item1, item2, collator, timezone, raiseError); } case store::Item::ARRAY: { return deepEqualArrays(loc, sctx, item1, item2, collator, timezone, raiseError); } default: { ZORBA_ASSERT(false); // should never reach here } } return false; }