From 2f08393e7d1fdde23454f11397dba19df6136cbc Mon Sep 17 00:00:00 2001 From: James Stone Date: Tue, 2 Mar 2021 09:31:32 -0800 Subject: [PATCH] fix null queries over links to an indexed property (#4460) --- CHANGELOG.md | 1 + src/realm/query_expression.hpp | 10 +++++++++- test/test_parser.cpp | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 474ffccb9a8..0a92047f566 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixed * ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?) +* Fixed queries for constant null across links to an indexed property not returning matches when the link was null. ([#4460]https://github.com/realm/realm-core/pull/4460), since 5.23.6). * Support upgrading from file format 5. ([#7089](https://github.com/realm/realm-cocoa/issues/7089), since v6.0.0) * On 32bit devices you may get exception with "No such object" when upgrading to v10.* ([#7314](https://github.com/realm/realm-java/issues/7314), since v10.0.0) * The notification worker thread would rerun queries after every commit rather than only commits which modified tables which could effect the query results if the table had any outgoing links to tables not used in the query (since v6.0.0). diff --git a/src/realm/query_expression.hpp b/src/realm/query_expression.hpp index 25e9b1a3077..b7e9ba97282 100644 --- a/src/realm/query_expression.hpp +++ b/src/realm/query_expression.hpp @@ -4319,7 +4319,15 @@ class Compare : public Expression { if (std::is_same_v && m_left_is_const && m_right->has_search_index() && m_right->get_comparison_type() == ExpressionComparisonType::Any) { if (m_left_value.is_null()) { - m_matches = m_right->find_all(Mixed()); + const ObjPropertyBase* prop = dynamic_cast(m_right.get()); + // when checking for null across links, null links are considered matches, + // so we must compute the slow matching even if there is an index. + if (!prop || prop->links_exist()) { + return dT; + } + else { + m_matches = m_right->find_all(Mixed()); + } } else { if (m_right->get_type() != m_left_value.get_type()) { diff --git a/test/test_parser.cpp b/test/test_parser.cpp index 3210c27f8a9..08d35b6588e 100644 --- a/test/test_parser.cpp +++ b/test/test_parser.cpp @@ -497,6 +497,8 @@ TEST(Parser_basic_serialisation) verify_query(test_context, t, "buddy == nil", 4); verify_query(test_context, t, "buddy != NULL", 1); verify_query(test_context, t, "buddy <> NULL", 1); + verify_query(test_context, t, "buddy.name == NULL", 4); // matches null links + verify_query(test_context, t, "buddy.age == NULL", 4); verify_query(test_context, t, "age > 2", 2); verify_query(test_context, t, "!(age >= 2)", 2); verify_query(test_context, t, "!(age => 2)", 2);