Skip to content

Commit 69f4ebc

Browse files
graph: Don't generate nocase filters for non-String list types
Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
1 parent 5525bcd commit 69f4ebc

File tree

1 file changed

+40
-21
lines changed

1 file changed

+40
-21
lines changed

graph/src/schema/api.rs

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,26 @@ fn field_enum_filter_input_values(
965965
.collect()
966966
}
967967

968+
/// Returns true if the given type supports case-insensitive filter
969+
/// operations (`_nocase` variants) when used as a list element type.
970+
/// Only `String` scalar types and object/interface types with `String`
971+
/// IDs support case-insensitive matching; types like `Bytes`, `BigInt`,
972+
/// etc. don't have a concept of case.
973+
fn field_list_supports_nocase(schema: &Schema, typedef: &s::TypeDefinition) -> bool {
974+
match typedef {
975+
s::TypeDefinition::Scalar(t) => t.name == "String",
976+
s::TypeDefinition::Object(obj_type) => {
977+
matches!(IdType::try_from(obj_type), Ok(IdType::String))
978+
}
979+
s::TypeDefinition::Interface(intf_type) => schema
980+
.types_for_interface
981+
.get(&intf_type.name)
982+
.and_then(|types| types.first())
983+
.is_none_or(|obj_type| matches!(IdType::try_from(obj_type), Ok(IdType::String))),
984+
_ => false,
985+
}
986+
}
987+
968988
/// Generates `*_filter` input values for the given list field.
969989
fn field_list_filter_input_values(
970990
schema: &Schema,
@@ -1000,25 +1020,26 @@ fn field_list_filter_input_values(
10001020
None => {
10011021
vec![]
10021022
}
1003-
Some(input_field_type) => vec![
1004-
"",
1005-
"not",
1006-
"contains",
1007-
"contains_nocase",
1008-
"not_contains",
1009-
"not_contains_nocase",
1010-
]
1011-
.into_iter()
1012-
.map(|filter_type| {
1013-
input_value(
1014-
&field.name,
1015-
filter_type,
1016-
s::Type::ListType(Box::new(s::Type::NonNullType(Box::new(
1017-
input_field_type.clone(),
1018-
)))),
1019-
)
1020-
})
1021-
.collect(),
1023+
Some(input_field_type) => {
1024+
let ops: &[&str] = if field_list_supports_nocase(schema, typedef) {
1025+
&[
1026+
"",
1027+
"not",
1028+
"contains",
1029+
"contains_nocase",
1030+
"not_contains",
1031+
"not_contains_nocase",
1032+
]
1033+
} else {
1034+
&["", "not", "contains", "not_contains"]
1035+
};
1036+
let value_type = s::Type::ListType(Box::new(s::Type::NonNullType(Box::new(
1037+
input_field_type.clone(),
1038+
))));
1039+
ops.iter()
1040+
.map(|filter_type| input_value(&field.name, filter_type, value_type.clone()))
1041+
.collect()
1042+
}
10221043
};
10231044

10241045
if let Some(parent) = parent_type_name {
@@ -2346,10 +2367,8 @@ type Gravatar @entity {
23462367
"pools",
23472368
"pools_",
23482369
"pools_contains",
2349-
"pools_contains_nocase",
23502370
"pools_not",
23512371
"pools_not_contains",
2352-
"pools_not_contains_nocase",
23532372
],
23542373
pools_fields.as_slice(),
23552374
"Field {protos} has the wrong pools filters"

0 commit comments

Comments
 (0)