Skip to content

Commit

Permalink
Support querying with @type on nested collections
Browse files Browse the repository at this point in the history
  • Loading branch information
jedelbo committed Jan 25, 2024
1 parent f9b432e commit 68fd450
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 17 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
* Queries on dictionaries in Mixed with @keys did not return correct result ([#7255](https://github.com/realm/realm-core/issues/7255), since 14.0.0-beta.0)
* Changes to inner collections will not be reported by notifier on owning collection ([#7270](https://github.com/realm/realm-core/issues/7270), since 14.0.0-beta.0)
* @count/@size not supported for mixed properties ([#7280](https://github.com/realm/realm-core/issues/7280), since v10.0.0)
* Query with @type does not support filtering on collections ([#7281](https://github.com/realm/realm-core/issues/7281), since 14.0.0-beta.0)

### Breaking changes
* None.
* If you want to query using @type operation, you must use 'objectlink' to match links to objects. 'object' is reserved for dictionary types.

### Compatibility
* Fileformat: Generates files with format v24. Reads and automatically upgrade from fileformat v10. If you want to upgrade from an earlier file format version you will have to use RealmCore v13.x.y or earlier.
Expand Down
16 changes: 14 additions & 2 deletions src/realm/query_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,17 @@ static const std::vector<std::pair<std::string, TypeOfValue::Attribute>> attribu
{"double", TypeOfValue::Double},
{"decimal128", TypeOfValue::Decimal128},
{"decimal", TypeOfValue::Decimal128},
{"object", TypeOfValue::ObjectLink},
{"objectlink", TypeOfValue::ObjectLink},
{"link", TypeOfValue::ObjectLink},
{"objectid", TypeOfValue::ObjectId},
{"uuid", TypeOfValue::UUID},
{"guid", TypeOfValue::UUID},
{"numeric", TypeOfValue::Numeric},
{"bindata", TypeOfValue::Binary}};
{"bindata", TypeOfValue::Binary},
{"object", TypeOfValue::Object},
{"array", TypeOfValue::Array},
{"collection", TypeOfValue::Collection},
};

TypeOfValue::Attribute get_single_from(std::string str)
{
Expand Down Expand Up @@ -112,6 +116,14 @@ TypeOfValue::Attribute attribute_from(DataType type)
return TypeOfValue::Attribute::ObjectLink;
case DataType::Type::UUID:
return TypeOfValue::Attribute::UUID;
default:
if (type == type_Dictionary) {
return TypeOfValue::Attribute::Object;
}
if (type == type_List) {
return TypeOfValue::Attribute::Array;
}
break;
}
throw query_parser::InvalidQueryArgError(
util::format("Invalid value '%1' cannot be converted to 'TypeOfValue'", type));
Expand Down
27 changes: 15 additions & 12 deletions src/realm/query_value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,22 @@ namespace realm {
class TypeOfValue {
public:
enum Attribute {
Null = 1,
Int = 2,
Double = 4,
Float = 8,
Bool = 16,
Timestamp = 32,
String = 64,
Binary = 128,
UUID = 256,
ObjectId = 512,
Decimal128 = 1024,
ObjectLink = 2048,
Null = 0x0001,
Int = 0x0002,
Double = 0x0004,
Float = 0x0008,
Bool = 0x0010,
Timestamp = 0x0020,
String = 0x0040,
Binary = 0x0080,
UUID = 0x0100,
ObjectId = 0x0200,
Decimal128 = 0x0400,
ObjectLink = 0x0800,
Object = 0x1000,
Array = 0x2000,
Numeric = Int + Double + Float + Decimal128,
Collection = Array + Object
};
explicit TypeOfValue(int64_t attributes);
explicit TypeOfValue(const std::string& attribute_tags);
Expand Down
12 changes: 10 additions & 2 deletions test/test_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4812,6 +4812,7 @@ TEST(Parser_TypeOfValue)
}
std::string bin_data("String2Binary");
table->get_object(15).set(col_any, Mixed());
table->get_object(17).set_collection(col_any, CollectionType::Dictionary);
table->get_object(75).set(col_any, Mixed(75.));
table->get_object(28).set(col_any, Mixed(BinaryData(bin_data)));
nb_strings--;
Expand All @@ -4837,7 +4838,7 @@ TEST(Parser_TypeOfValue)
++it;
}
}
size_t nb_ints = 71;
size_t nb_ints = 70;
verify_query(test_context, table, "mixed.@type == 'string'", nb_strings);
verify_query(test_context, table, "mixed.@type == 'double'", 2);
verify_query(test_context, table, "mixed.@type == 'float'", 0);
Expand All @@ -4861,7 +4862,7 @@ TEST(Parser_TypeOfValue)
verify_query(test_context, table, "mixed.@type == 'char'", nb_ints);
verify_query(test_context, table, "mixed.@type == 'timestamp'", 0);
verify_query(test_context, table, "mixed.@type == 'datetimeoffset'", 0);
verify_query(test_context, table, "mixed.@type == 'object'", 0);
verify_query(test_context, table, "mixed.@type == 'object'", 1);

verify_query(test_context, table,
"mixed.@type == 'binary' || mixed.@type == 'DECIMAL' || mixed.@type == 'Double'", 4);
Expand Down Expand Up @@ -5284,6 +5285,10 @@ TEST(Parser_NestedMixedDictionaryList)
snake->insert("age", 20);
}

Obj george = persons->create_object_with_primary_key("George");
george.set(col_self, george.get_key());
george.set_collection(col, CollectionType::List);

auto q = persons->column<Mixed>(col).path({"instruments", 0, "strings"}) == 6;
CHECK_EQUAL(q.count(), 1);

Expand All @@ -5300,6 +5305,9 @@ TEST(Parser_NestedMixedDictionaryList)
verify_query(test_context, persons, "properties.@keys == 'tickets'", 1);
verify_query(test_context, persons, "properties.@size == 3", 1);
verify_query(test_context, persons, "properties.instruments.@size == 2", 1);
verify_query(test_context, persons, "properties.@type == 'object'", 2);
verify_query(test_context, persons, "properties.@type == 'array'", 1);
verify_query(test_context, persons, "properties.@type == 'collection'", 3);
}

TEST(Parser_NestedDictionaryDeep)
Expand Down

0 comments on commit 68fd450

Please sign in to comment.