#[test]
fn gql_inline_property_map_large_integer_binds_exact_i64_not_lossy_float() {
let q = parse(
QueryLanguage::Gql,
"MATCH (n:artifact {number: 9007199254740993}) RETURN n",
)
.unwrap();
let compiled = compile(&q, &opts()).unwrap();
assert!(
compiled
.params
.iter()
.any(|p| matches!(p, QueryValue::Integer(9007199254740993))),
"large integer literal must bind as the exact i64, not a rounded f64; params: {:?}",
compiled.params
);
}
#[test]
fn gql_inline_property_map_i64_max_binds_exact() {
let q = parse(
QueryLanguage::Gql,
&format!("MATCH (n:artifact {{number: {}}}) RETURN n", i64::MAX),
)
.unwrap();
let compiled = compile(&q, &opts()).unwrap();
assert!(compiled
.params
.iter()
.any(|p| matches!(p, QueryValue::Integer(n) if *n == i64::MAX)));
}
#[test]
fn gql_inline_property_map_i64_min_binds_exact() {
let q = parse(
QueryLanguage::Gql,
&format!("MATCH (n:artifact {{number: {}}}) RETURN n", i64::MIN),
)
.unwrap();
let compiled = compile(&q, &opts()).unwrap();
assert!(compiled
.params
.iter()
.any(|p| matches!(p, QueryValue::Integer(n) if *n == i64::MIN)));
}
#[test]
fn gql_where_equality_large_integer_binds_exact_i64_not_lossy_float() {
let q = parse(
QueryLanguage::Gql,
"MATCH (n:artifact) WHERE n.properties.number = 9007199254740993 RETURN n",
)
.unwrap();
let compiled = compile(&q, &opts()).unwrap();
assert!(
compiled
.params
.iter()
.any(|p| matches!(p, QueryValue::Integer(9007199254740993))),
"WHERE equality with a large integer literal must bind exact i64; params: {:?}",
compiled.params
);
}
#[test]
fn gql_where_equality_i64_bounds_bind_exact() {
for bound in [i64::MIN, i64::MAX] {
let q = parse(
QueryLanguage::Gql,
&format!("MATCH (n:artifact) WHERE n.properties.number = {bound} RETURN n"),
)
.unwrap();
let compiled = compile(&q, &opts()).unwrap();
assert!(
compiled
.params
.iter()
.any(|p| matches!(p, QueryValue::Integer(n) if *n == bound)),
"bound {bound} must bind exact; params: {:?}",
compiled.params
);
}
}
#[test]
fn variable_length_where_i64_bounds_bind_exact() {
for bound in [i64::MIN, i64::MAX] {
let q = parse(
QueryLanguage::Gql,
&format!(
"MATCH (a)-[:extends*1..3]->(b) \
WHERE b.properties.number = {bound} RETURN b"
),
)
.unwrap();
let compiled = compile(&q, &opts()).unwrap();
assert!(
compiled
.params
.iter()
.any(|p| matches!(p, QueryValue::Integer(n) if *n == bound)),
"variable-length WHERE bound {bound} must bind exact i64; params: {:?}",
compiled.params
);
}
}
#[test]
fn variable_length_end_node_inline_property_map_i64_bounds_bind_exact() {
for bound in [i64::MIN, i64::MAX] {
let q = parse(
QueryLanguage::Gql,
&format!("MATCH (a)-[:extends*1..3]->(b:artifact {{number: {bound}}}) RETURN b"),
)
.unwrap();
let compiled = compile(&q, &opts()).unwrap();
assert!(
compiled
.params
.iter()
.any(|p| matches!(p, QueryValue::Integer(n) if *n == bound)),
"end-node inline-map bound {bound} must bind exact i64; params: {:?}",
compiled.params
);
}
}
#[test]
fn gql_inline_property_map_integer_overflow_rejected_at_parse_time() {
let overflow = "9223372036854775808";
let err = parse(
QueryLanguage::Gql,
&format!("MATCH (n:artifact {{number: {overflow}}}) RETURN n"),
)
.unwrap_err();
assert!(
matches!(err, QueryError::Parse { .. }),
"out-of-range integer literal must be rejected at parse time, not silently \
truncated or coerced to float; got: {err:?}"
);
}
#[test]
fn gql_where_equality_integer_overflow_rejected_at_parse_time() {
let overflow = "9223372036854775808";
let err = parse(
QueryLanguage::Gql,
&format!("MATCH (n:artifact) WHERE n.properties.number = {overflow} RETURN n"),
)
.unwrap_err();
assert!(matches!(err, QueryError::Parse { .. }));
}
#[test]
fn gql_inline_property_map_float_overflow_rejected() {
let huge = format!("{}.0", "9".repeat(400));
let err = parse(
QueryLanguage::Gql,
&format!("MATCH (n:document {{score: {huge}}}) RETURN n"),
)
.unwrap_err();
assert!(
matches!(err, QueryError::Parse { .. }),
"non-finite float literal must be rejected, not silently bound as Infinity; got: {err:?}"
);
}