@@ -750,13 +750,16 @@ namespace {
750
750
bool attributesEqual (VPackSlice first, VPackSlice second,
751
751
std::vector<arangodb::basics::AttributeName>::const_iterator begin,
752
752
std::vector<arangodb::basics::AttributeName>::const_iterator end) {
753
+ TRI_ASSERT (first.isObject ());
754
+ TRI_ASSERT (second.isObject ());
755
+
753
756
for (; begin != end; ++begin) {
754
757
// fetch subattribute
755
758
first = first.get (begin->name );
756
- second = second.get (begin->name );
757
759
if (first.isExternal ()) {
758
760
first = first.resolveExternal ();
759
761
}
762
+ second = second.get (begin->name );
760
763
if (second.isExternal ()) {
761
764
second = second.resolveExternal ();
762
765
}
@@ -784,6 +787,17 @@ namespace {
784
787
if (notF1 || notF2) { // one of the paths was not found
785
788
break ;
786
789
}
790
+
791
+ // check if, after fetching the subattribute, we are point to a non-object.
792
+ // e.g. if the index is on field ["a.b"], the first iteration of this loop
793
+ // will look for subattribute "a" in the original document. this will always
794
+ // work. however, when looking for "b", we have to make sure that "a" was
795
+ // an object. otherwise we must not call Slice::get() on it. In case one of
796
+ // the subattributes we found so far is not an object, we fall back to the
797
+ // regular comparison
798
+ if (!first.isObject () || !second.isObject ()) {
799
+ break ;
800
+ }
787
801
}
788
802
789
803
return basics::VelocyPackHelper::equal (first, second, true );
0 commit comments