@@ -684,32 +684,30 @@ Query make_diacritic_insensitive_constraint(NSPredicateOperatorType operatorType
684
684
}
685
685
}
686
686
687
+ // static_assert is always evaluated even if it's inside a if constexpr
688
+ // unless the value is derived from the template argument, in which case it's
689
+ // only evaluated if that branch is active
690
+ template <typename > struct AlwaysFalse : std::false_type {};
691
+
687
692
template <typename C, typename T>
688
- void QueryBuilder::do_add_diacritic_sensitive_string_constraint (NSPredicateOperatorType operatorType,
689
- NSComparisonPredicateOptions predicateOptions,
690
- C&& column, T&& value) {
691
- bool caseSensitive = !(predicateOptions & NSCaseInsensitivePredicateOption);
693
+ Query make_diacritic_sensitive_constraint (NSPredicateOperatorType operatorType,
694
+ bool caseSensitive, C& column, T const & value)
695
+ {
692
696
switch (operatorType) {
693
697
case NSBeginsWithPredicateOperatorType:
694
- add_substring_constraint (value, column.begins_with (value, caseSensitive));
695
- break ;
698
+ return column.begins_with (value, caseSensitive);
696
699
case NSEndsWithPredicateOperatorType:
697
- add_substring_constraint (value, column.ends_with (value, caseSensitive));
698
- break ;
700
+ return column.ends_with (value, caseSensitive);
699
701
case NSContainsPredicateOperatorType:
700
- add_substring_constraint (value, column.contains (value, caseSensitive));
701
- break ;
702
+ return column.contains (value, caseSensitive);
702
703
case NSEqualToPredicateOperatorType:
703
- m_query.and_query (column.equal (value, caseSensitive));
704
- break ;
704
+ return column.equal (value, caseSensitive);
705
705
case NSNotEqualToPredicateOperatorType:
706
- m_query.and_query (column.not_equal (value, caseSensitive));
707
- break ;
706
+ return column.not_equal (value, caseSensitive);
708
707
case NSLikePredicateOperatorType:
709
- m_query.and_query (column.like (value, caseSensitive));
710
- break ;
708
+ return column.like (value, caseSensitive);
711
709
default : {
712
- if constexpr (is_any_v<C, Columns<String>, Columns<Lst<String>>, Columns<Set<String>>>) {
710
+ if constexpr (is_any_v<C, Columns<String>, Columns<Lst<String>>, Columns<Set<String>>, ColumnDictionaryKeys >) {
713
711
unsupportedOperator (RLMPropertyTypeString, operatorType);
714
712
}
715
713
else if constexpr (is_any_v<C, Columns<Binary>, Columns<Lst<Binary>>, Columns<Set<Binary>>>) {
@@ -726,10 +724,56 @@ Query make_diacritic_insensitive_constraint(NSPredicateOperatorType operatorType
726
724
@" Operator '%@ ' not supported for string queries on Dictionary." ,
727
725
operatorName (operatorType));
728
726
}
727
+ else {
728
+ static_assert (AlwaysFalse<C>::value, " unsupported column type" );
729
+ }
729
730
}
730
731
}
731
732
}
732
733
734
+ template <typename C, typename T>
735
+ void QueryBuilder::do_add_diacritic_sensitive_string_constraint (NSPredicateOperatorType operatorType,
736
+ NSComparisonPredicateOptions predicateOptions,
737
+ C&& column, T&& value) {
738
+ bool caseSensitive = !(predicateOptions & NSCaseInsensitivePredicateOption);
739
+ Query condition = make_diacritic_sensitive_constraint (operatorType, caseSensitive, column, value);
740
+
741
+ // Queries on Mixed used to coerce Strings to Binary and vice-versa. Core
742
+ // no longer does this, but we can maintain compatibility by doing the
743
+ // coercion and checking both
744
+ // NEXT-MAJOR: we should remove this and realign with core's behavior
745
+ if constexpr (is_any_v<C, Columns<Mixed>, Columns<Lst<Mixed>>, Columns<Set<Mixed>>, Columns<Dictionary>>) {
746
+ Mixed m = value;
747
+ if (!m.is_null ()) {
748
+ if (m.get_type () == type_String) {
749
+ m = m.export_to_type <BinaryData>();
750
+ }
751
+ else {
752
+ m = m.export_to_type <StringData>();
753
+ }
754
+
755
+ // Equality and substring operations need (col == strValue OR col == binValue),
756
+ // but not equals needs (col != strValue AND col != binValue)
757
+ if (operatorType != NSNotEqualToPredicateOperatorType) {
758
+ condition.Or ();
759
+ }
760
+
761
+ condition.and_query (make_diacritic_sensitive_constraint (operatorType, caseSensitive, column, m));
762
+ }
763
+ }
764
+ switch (operatorType) {
765
+ case NSBeginsWithPredicateOperatorType:
766
+ case NSEndsWithPredicateOperatorType:
767
+ case NSContainsPredicateOperatorType:
768
+ add_substring_constraint (value, std::move (condition));
769
+ break ;
770
+
771
+ default :
772
+ m_query.and_query (std::move (condition));
773
+ break ;
774
+ }
775
+ }
776
+
733
777
template <typename C, typename T>
734
778
void QueryBuilder::add_diacritic_sensitive_string_constraint (NSPredicateOperatorType operatorType,
735
779
NSComparisonPredicateOptions predicateOptions,
@@ -1297,11 +1341,6 @@ KeyPath key_path_from_string(RLMSchema *schema, RLMObjectSchema *objectSchema, N
1297
1341
1298
1342
#pragma mark Collection Operations
1299
1343
1300
- // static_assert is always evaluated even if it's inside a if constexpr
1301
- // unless the value is derived from the template argument, in which case it's
1302
- // only evaluated if that branch is active
1303
- template <CollectionOperation::Type> struct AlwaysFalse : std::false_type {};
1304
-
1305
1344
template <CollectionOperation::Type OperationType, typename Column>
1306
1345
auto collection_operation_expr_2 (Column&& column) {
1307
1346
if constexpr (OperationType == CollectionOperation::Minimum) {
@@ -1317,7 +1356,8 @@ auto collection_operation_expr_2(Column&& column) {
1317
1356
return column.average ();
1318
1357
}
1319
1358
else {
1320
- static_assert (AlwaysFalse<OperationType>::value, " invalid operation type" );
1359
+ static_assert (AlwaysFalse<std::integral_constant<CollectionOperation::Type, OperationType>>::value,
1360
+ " invalid operation type" );
1321
1361
}
1322
1362
}
1323
1363
@@ -1660,7 +1700,7 @@ bool is_self_value_for_key_path_function_expression(NSExpression *expression)
1660
1700
ColumnReference collectionColumn = column_reference_from_key_path (key_path_from_string (m_schema, objectSchema, keyPath), true );
1661
1701
RLMPrecondition (collectionColumn.property ().dictionary , @" Invalid predicate" ,
1662
1702
@" Invalid keypath '%@ ': only dictionaries support subscript predicates." , functionExpression);
1663
- add_mixed_constraint (operatorType, options, collectionColumn.resolve <Dictionary>().key (mapKey.UTF8String ), right.constantValue );
1703
+ add_mixed_constraint (operatorType, options, std::move ( collectionColumn.resolve <Dictionary>().key (mapKey.UTF8String ) ), right.constantValue );
1664
1704
}
1665
1705
1666
1706
void QueryBuilder::apply_function_expression (RLMObjectSchema *objectSchema, NSExpression *functionExpression,
0 commit comments