expression: fix handling of zero month/day in DATE function (#65150)

close pingcap/tidb#59417
This commit is contained in:
cryo
2025-12-30 21:09:38 +08:00
committed by GitHub
parent 8c3f0a502a
commit 9ce91e4518
6 changed files with 89 additions and 7 deletions

View File

@ -310,6 +310,10 @@ func (b *builtinDateSig) evalTime(ctx EvalContext, row chunk.Row) (types.Time, b
if expr.IsZero() && sqlMode(ctx).HasNoZeroDateMode() {
return types.ZeroTime, true, handleInvalidTimeError(ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, expr.String()))
}
// for issue 59417, should return NULL when month or day is zero and sql_mode contains NO_ZERO_IN_DATE
if !expr.IsZero() && expr.InvalidZero() && sqlMode(ctx).HasNoZeroInDateMode() {
return types.ZeroTime, true, handleInvalidTimeError(ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, expr.String()))
}
expr.SetCoreTime(types.FromDate(expr.Year(), expr.Month(), expr.Day(), 0, 0, 0, 0))
expr.SetType(mysql.TypeDate)

View File

@ -99,10 +99,19 @@ func (b *builtinDateSig) vecEvalTime(ctx EvalContext, input *chunk.Chunk, result
return err
}
result.SetNull(i, true)
} else {
times[i].SetCoreTime(types.FromDate(times[i].Year(), times[i].Month(), times[i].Day(), 0, 0, 0, 0))
times[i].SetType(mysql.TypeDate)
continue
}
// for issue 59417, should return NULL when month or day is zero and sql_mode contains NO_ZERO_IN_DATE
if !times[i].IsZero() && times[i].InvalidZero() && sqlMode(ctx).HasNoZeroInDateMode() {
if err := handleInvalidTimeError(ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, times[i].String())); err != nil {
return err
}
result.SetNull(i, true)
continue
}
times[i].SetCoreTime(types.FromDate(times[i].Year(), times[i].Month(), times[i].Day(), 0, 0, 0, 0))
times[i].SetType(mysql.TypeDate)
}
return nil
}

View File

@ -2832,7 +2832,7 @@ func TestTimeBuiltin(t *testing.T) {
result = tk.MustQuery(`select date("2019-09-12"), date("2019-09-12 12:12:09"), date("2019-09-12 12:12:09.121212");`)
result.Check(testkit.Rows("2019-09-12 2019-09-12 2019-09-12"))
result = tk.MustQuery(`select date("0000-00-00"), date("0000-00-00 12:12:09"), date("0000-00-00 00:00:00.121212"), date("0000-00-00 00:00:00.000000");`)
result.Check(testkit.Rows("<nil> 0000-00-00 0000-00-00 <nil>"))
result.Check(testkit.Rows("<nil> <nil> <nil> <nil>"))
result = tk.MustQuery(`select date("aa"), date(12.1), date("");`)
result.Check(testkit.Rows("<nil> <nil> <nil>"))

View File

@ -3418,3 +3418,53 @@ SELECT UTC_TIMESTAMP(2147483647);
Error 1426 (42000): Too-big precision 2147483647 specified for 'utc_timestamp'. Maximum is 6.
SELECT UTC_TIMESTAMP(2147483648);
Error 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use
set sql_mode = 'NO_ZERO_IN_DATE';
select date(0), date('0000-00-00');
date(0) date('0000-00-00')
0000-00-00 0000-00-00
show warnings;
Level Code Message
select date('0000-00-01'), date('0000-12-00'), date('2024-00-00');
date('0000-00-01') date('0000-12-00') date('2024-00-00')
NULL NULL NULL
show warnings;
Level Code Message
Warning 1292 Incorrect datetime value: '0000-00-01 00:00:00.000000'
Warning 1292 Incorrect datetime value: '0000-12-00 00:00:00.000000'
Warning 1292 Incorrect datetime value: '2024-00-00 00:00:00.000000'
select date('0000-12-01'), date('2024-00-01'), date('2024-12-00');
date('0000-12-01') date('2024-00-01') date('2024-12-00')
0000-12-01 NULL NULL
show warnings;
Level Code Message
Warning 1292 Incorrect datetime value: '2024-00-01 00:00:00.000000'
Warning 1292 Incorrect datetime value: '2024-12-00 00:00:00.000000'
select date('2024-12-01');
date('2024-12-01')
2024-12-01
show warnings;
Level Code Message
drop table if exists t;
create table t(test_date DATETIME);
SET sql_mode = '';
INSERT INTO t VALUES (0),('0000-00-00'),('0000-00-01'),('0000-12-00'),('2024-00-00'),('0000-12-01'),('2024-00-01'),('2024-12-00'),('2024-12-01');
SET sql_mode = 'NO_ZERO_IN_DATE';
SELECT DATE(test_date) FROM t;
DATE(test_date)
0000-00-00
0000-00-00
NULL
NULL
NULL
0000-12-01
NULL
NULL
2024-12-01
show warnings;
Level Code Message
Warning 1292 Incorrect datetime value: '0000-00-01 00:00:00'
Warning 1292 Incorrect datetime value: '0000-12-00 00:00:00'
Warning 1292 Incorrect datetime value: '2024-00-00 00:00:00'
Warning 1292 Incorrect datetime value: '2024-00-01 00:00:00'
Warning 1292 Incorrect datetime value: '2024-12-00 00:00:00'
drop table if exists t;

View File

@ -1649,3 +1649,22 @@ SELECT UTC_TIMESTAMP(-1);
SELECT UTC_TIMESTAMP(2147483647);
-- error 1064
SELECT UTC_TIMESTAMP(2147483648);
# Issue 59417
set sql_mode = 'NO_ZERO_IN_DATE';
select date(0), date('0000-00-00');
show warnings;
select date('0000-00-01'), date('0000-12-00'), date('2024-00-00');
show warnings;
select date('0000-12-01'), date('2024-00-01'), date('2024-12-00');
show warnings;
select date('2024-12-01');
show warnings;
drop table if exists t;
create table t(test_date DATETIME);
SET sql_mode = '';
INSERT INTO t VALUES (0),('0000-00-00'),('0000-00-01'),('0000-12-00'),('2024-00-00'),('0000-12-01'),('2024-00-01'),('2024-12-00'),('2024-12-01');
SET sql_mode = 'NO_ZERO_IN_DATE';
SELECT DATE(test_date) FROM t;
show warnings;
drop table if exists t;

View File

@ -12401,9 +12401,9 @@
{
"sql": "SELECT DATE('2024-00-15')",
"args": null,
"pass": false,
"known": true,
"comment": "https://github.com/pingcap/tidb/issues/59417"
"pass": true,
"known": false,
"comment": ""
},
{
"sql": "SELECT DATE('2023-02-29')",