Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions pkg/types/field_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,14 @@ func InferParamTypeFromDatum(d *Datum, tp *FieldType) {
func InferParamTypeFromUnderlyingValue(value any, tp *FieldType) {
switch value.(type) {
case nil:
tp.SetType(mysql.TypeVarString)
tp.SetFlen(UnspecifiedLength)
tp.SetDecimal(UnspecifiedLength)
// Also set the `charset` and `collation` for it, because some function (e.g. `json_object`) will return error
// if the argument collation is `binary`.
// For NULL parameters, use TypeNull to ensure consistent behavior with literal NULL values
// in control flow functions like CASE WHEN. Previously using TypeVarString caused incorrect
// type inference in prepared statements (issue #62564).
tp.SetType(mysql.TypeNull)
tp.SetFlen(0)
tp.SetDecimal(0)
// Set default charset and collation instead of binary charset to avoid breaking JSON functions
// (see PR #54145 which fixed JSON function argument verification issues).
tp.SetCharset(mysql.DefaultCharset)
tp.SetCollate(mysql.DefaultCollationName)
default:
Expand Down
10 changes: 10 additions & 0 deletions tests/integrationtest/r/planner/core/casetest/integration.result
Original file line number Diff line number Diff line change
Expand Up @@ -1838,3 +1838,13 @@ Update N/A root N/A
└─TableReader(Probe) 0.00 root data:Selection
└─Selection 0.00 cop[tikv] or(or(and(eq(test.tt.c, 11), eq(test.tt.d, 111)), and(eq(test.tt.c, 22), eq(test.tt.d, 222))), or(and(eq(test.tt.c, 33), eq(test.tt.d, 333)), and(eq(test.tt.c, 44), eq(test.tt.d, 444)))), or(or(eq(test.tt.c, 11), eq(test.tt.c, 22)), or(eq(test.tt.c, 33), eq(test.tt.c, 44))), or(or(eq(test.tt.d, 111), eq(test.tt.d, 222)), or(eq(test.tt.d, 333), eq(test.tt.d, 444)))
└─TableRangeScan 0.00 cop[tikv] table:tt range: decided by [eq(test.tt.c, Column#20) eq(test.tt.d, Column#21)], keep order:false, stats:pseudo
CREATE TABLE test_62564(c0 DECIMAL);
INSERT INTO test_62564 VALUES (0);
SELECT * FROM test_62564 WHERE CAST((CASE test_62564.c0 WHEN test_62564.c0 THEN CAST(test_62564.c0 AS TIME) ELSE NULL END ) AS DATE);
c0
0
SET @b = NULL;
PREPARE prepare_query FROM 'SELECT * FROM test_62564 WHERE CAST((CASE test_62564.c0 WHEN test_62564.c0 THEN CAST(test_62564.c0 AS TIME) ELSE ? END ) AS DATE)';
EXECUTE prepare_query USING @b;
c0
0
Original file line number Diff line number Diff line change
Expand Up @@ -732,3 +732,11 @@ use test;
drop table if exists tt;
create table tt(a bigint, b bigint, c bigint, d bigint, e bigint, primary key(c,d));
explain format = brief update tt, (select 1 as c1 ,2 as c2 ,3 as c3, 4 as c4 union all select 2,3,4,5 union all select 3,4,5,6) tmp set tt.a=tmp.c1, tt.b=tmp.c2 where tt.c=tmp.c3 and tt.d=tmp.c4 and (tt.c,tt.d) in ((11,111),(22,222),(33,333),(44,444));

# TestIssue62564
CREATE TABLE test_62564(c0 DECIMAL);
INSERT INTO test_62564 VALUES (0);
SELECT * FROM test_62564 WHERE CAST((CASE test_62564.c0 WHEN test_62564.c0 THEN CAST(test_62564.c0 AS TIME) ELSE NULL END ) AS DATE);
SET @b = NULL;
PREPARE prepare_query FROM 'SELECT * FROM test_62564 WHERE CAST((CASE test_62564.c0 WHEN test_62564.c0 THEN CAST(test_62564.c0 AS TIME) ELSE ? END ) AS DATE)';
EXECUTE prepare_query USING @b;