diff --git a/src/query/sql/src/planner/semantic/type_check/scalar_function.rs b/src/query/sql/src/planner/semantic/type_check/scalar_function.rs index 9e93d8f671a..a16f54a526b 100644 --- a/src/query/sql/src/planner/semantic/type_check/scalar_function.rs +++ b/src/query/sql/src/planner/semantic/type_check/scalar_function.rs @@ -643,12 +643,27 @@ where A: TypeCheckAdapter // will be folded from `timestamp > to_timestamp('2001-01-01')` to `timestamp > 978307200000000` // Note: check function may reorder the args + let checked_func_name = BUILTIN_FUNCTIONS + .aliases + .get(func_name) + .map_or(func_name, String::as_str); + + // `check_function` may eliminate an identity conversion and return its argument. + // In that case, the checked root arguments no longer correspond to the original call. + let checked_root_matches = match &expr { + expr::Expr::FunctionCall(expr::FunctionCall { + function, + args: checked_args, + .. + }) => function.signature.name == checked_func_name && checked_args.len() == args.len(), + _ => false, + }; let mut folded_args = match &expr { expr::Expr::FunctionCall(expr::FunctionCall { function, args: checked_args, .. - }) => checked_args + }) if checked_root_matches => checked_args .iter() .zip( function diff --git a/src/query/sql/tests/it/semantic/type_check/scalar_function.rs b/src/query/sql/tests/it/semantic/type_check/scalar_function.rs index 16615e9000e..b606afdf453 100644 --- a/src/query/sql/tests/it/semantic/type_check/scalar_function.rs +++ b/src/query/sql/tests/it/semantic/type_check/scalar_function.rs @@ -15,6 +15,12 @@ async fn test_type_check_scalar_function_rules() -> Result<()> { setup_sqls: &[], sql: "to_decimal(number, number)", }, + SqlTestCase { + name: "identity_cast_preserves_complete_argument", + description: "An eliminated identity cast must not remap an inner function argument onto the original call.", + setup_sqls: &[], + sql: "to_int64(100000000 + ((854435761::UInt64 * number + 123456789) % 900000000))", + }, ]; run_type_check_cases("scalar_function.txt", &cases).await diff --git a/src/query/sql/tests/it/semantic/type_check/scalar_function.txt b/src/query/sql/tests/it/semantic/type_check/scalar_function.txt index c2f31f86d02..e23bf53d1ba 100644 --- a/src/query/sql/tests/it/semantic/type_check/scalar_function.txt +++ b/src/query/sql/tests/it/semantic/type_check/scalar_function.txt @@ -11,3 +11,10 @@ sql: to_decimal(number, number) status: error code: 1065 message: Invalid arguments for `to_decimal`, precision is only allowed to be a constant + +=== identity_cast_preserves_complete_argument === +description: An eliminated identity cast must not remap an inner function argument onto the original call. +sql: to_int64(100000000 + ((854435761::UInt64 * number + 123456789) % 900000000)) +status: ok +scalar: to_int64(plus(100000000, modulo(plus(multiply(854435761, number (#0)), 123456789), 900000000))) +type: Int64 NULL