From 43ac94a85da8810b4478cd38c01d0a4e47b02b40 Mon Sep 17 00:00:00 2001 From: li-qinlang Date: Mon, 25 Sep 2023 10:21:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=95=B0=E5=AD=97=E8=BD=ACda?= =?UTF-8?q?te=E8=A1=A8=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../expected/b_compatibility_time_type.out | 9 +- contrib/dolphin/expected/conv_cast_test.out | 98 +++++++++++++++++++ contrib/dolphin/plugin_utils/adt/date.cpp | 17 +++- contrib/dolphin/sql/conv_cast_test.sql | 24 +++++ 4 files changed, 142 insertions(+), 6 deletions(-) diff --git a/contrib/dolphin/expected/b_compatibility_time_type.out b/contrib/dolphin/expected/b_compatibility_time_type.out index 73b373ed9..c491945f4 100644 --- a/contrib/dolphin/expected/b_compatibility_time_type.out +++ b/contrib/dolphin/expected/b_compatibility_time_type.out @@ -287,9 +287,11 @@ SELECT 990101::date; (1 row) SELECT 100::date; +WARNING: Out of range value for date +CONTEXT: referenced column: date date ------------ - 1999-12-31 + 0000-00-00 (1 row) SELECT 101::date; @@ -2042,8 +2044,6 @@ CREATE TABLE t_NO_ZERO_DATE_date(v date); CREATE TABLE t_NO_ZERO_DATE_datetime(v datetime); CREATE TABLE t_NO_ZERO_DATE_timestamp(v timestamp); INSERT INTO t_NO_ZERO_DATE_date(v) VALUES(0); -ERROR: Out of range value for date -CONTEXT: referenced column: v INSERT INTO t_NO_ZERO_DATE_date(v) VALUES('0000-00-00'); INSERT INTO t_NO_ZERO_DATE_date(v) VALUES('0000-00-01'); WARNING: date/time field value out of range: "0000-00-01" @@ -2151,7 +2151,8 @@ SELECT * FROM t_NO_ZERO_DATE_date order by v; 0000-00-00 0000-00-00 0000-00-00 -(6 rows) + 0000-00-00 +(7 rows) SELECT * FROM t_NO_ZERO_DATE_datetime order by v; v diff --git a/contrib/dolphin/expected/conv_cast_test.out b/contrib/dolphin/expected/conv_cast_test.out index 61c595759..e7081e394 100644 --- a/contrib/dolphin/expected/conv_cast_test.out +++ b/contrib/dolphin/expected/conv_cast_test.out @@ -766,5 +766,103 @@ select 'false'::bool::float8; (1 row) +create table test_date(a date); +set dolphin.sql_mode = sql_mode_strict,sql_mode_full_group,pipes_as_concat,ansi_quotes,no_zero_date,pad_char_to_full_length,auto_recompile_function; +select 0::date; +WARNING: Out of range value for date +CONTEXT: referenced column: date + date +------------ + 0000-00-00 +(1 row) + +insert into test_date values(0); +ERROR: Out of range value for date +CONTEXT: referenced column: a +select 1::date; +WARNING: Out of range value for date +CONTEXT: referenced column: date + date +------------ + 0000-00-00 +(1 row) + +insert into test_date values(1); +ERROR: Out of range value for date +CONTEXT: referenced column: a +set dolphin.sql_mode = sql_mode_strict,sql_mode_full_group,pipes_as_concat,ansi_quotes,pad_char_to_full_length,auto_recompile_function; +select 0::date; + date +------------ + 0000-00-00 +(1 row) + +insert into test_date values(0); +select 1::date; +WARNING: Out of range value for date +CONTEXT: referenced column: date + date +------------ + 0000-00-00 +(1 row) + +insert into test_date values(1); +ERROR: Out of range value for date +CONTEXT: referenced column: a +set dolphin.sql_mode = sql_mode_full_group,pipes_as_concat,ansi_quotes,no_zero_date,pad_char_to_full_length,auto_recompile_function; +select 0::date; +WARNING: Out of range value for date +CONTEXT: referenced column: date + date +------------ + 0000-00-00 +(1 row) + +insert into test_date values(0); +WARNING: Out of range value for date +CONTEXT: referenced column: a +select 1::date; +WARNING: Out of range value for date +CONTEXT: referenced column: date + date +------------ + 0000-00-00 +(1 row) + +insert into test_date values(1); +WARNING: Out of range value for date +CONTEXT: referenced column: a +set dolphin.sql_mode = sql_mode_full_group,pipes_as_concat,ansi_quotes,pad_char_to_full_length,auto_recompile_function; +select 0::date; + date +------------ + 0000-00-00 +(1 row) + +insert into test_date values(0); +select 1::date; +WARNING: Out of range value for date +CONTEXT: referenced column: date + date +------------ + 0000-00-00 +(1 row) + +insert into test_date values(1); +WARNING: Out of range value for date +CONTEXT: referenced column: a +reset dolphin.sql_mode; +select * from test_date; + a +------------ + 0000-00-00 + 0000-00-00 + 0000-00-00 + 0000-00-00 + 0000-00-00 +(5 rows) + + drop schema conv_cast_test cascade; +NOTICE: drop cascades to table test_date reset current_schema; diff --git a/contrib/dolphin/plugin_utils/adt/date.cpp b/contrib/dolphin/plugin_utils/adt/date.cpp index 811bd4b90..b5c27cf06 100644 --- a/contrib/dolphin/plugin_utils/adt/date.cpp +++ b/contrib/dolphin/plugin_utils/adt/date.cpp @@ -632,6 +632,7 @@ int NumberDate(char *str, pg_tm *tm, unsigned int date_flag) int int32_b_format_date_internal(struct pg_tm *tm, int4 date, bool mayBe2Digit, unsigned int date_flag) { int dterr; + int errlevel = SQL_MODE_STRICT() ? ERROR : WARNING; /* YYYYMMDD or YYMMDD*/ tm->tm_mday = date % 100; /* DD */ tm->tm_mon = date / 100 % 100; /* MM */ @@ -640,7 +641,15 @@ int int32_b_format_date_internal(struct pg_tm *tm, int4 date, bool mayBe2Digit, /* validate b format date */ if (tm->tm_year > B_FORMAT_MAX_YEAR_OF_DATE) { dterr = DTERR_FIELD_OVERFLOW; - } else if (is2digits && !date_flag && date == 0 && (!SQL_MODE_NO_ZERO_DATE() && SQL_MODE_STRICT())) { + } else if (is2digits && !date_flag && date == 0 && !(SQL_MODE_NO_ZERO_DATE() && SQL_MODE_STRICT())) { + return 0; + } else if (is2digits && !date_flag && date > 0 && date < B_FORMAT_DATE_INT_MIN) { + ereport(errlevel, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("Out of range value for date"))); + tm->tm_year = 0; + tm->tm_mon = 0; + tm->tm_mday = 0; return 0; } else { dterr = ValidateDateForBDatabase(is2digits, tm, date_flag); @@ -669,7 +678,11 @@ Datum int32_b_format_date(PG_FUNCTION_ARGS) (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("Out of range value for date"))); } - + if (date == 0 && !SQL_MODE_STRICT() && SQL_MODE_NO_ZERO_DATE()) { + ereport(WARNING, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("Out of range value for date"))); + } if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday)) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("date out of range: \"%d\"", date))); diff --git a/contrib/dolphin/sql/conv_cast_test.sql b/contrib/dolphin/sql/conv_cast_test.sql index 091f0cf96..22d9a00c3 100755 --- a/contrib/dolphin/sql/conv_cast_test.sql +++ b/contrib/dolphin/sql/conv_cast_test.sql @@ -137,5 +137,29 @@ select 'false'::bool::bit(64); select 'false'::bool::float4; select 'false'::bool::float8; +create table test_date(a date); +set dolphin.sql_mode = sql_mode_strict,sql_mode_full_group,pipes_as_concat,ansi_quotes,no_zero_date,pad_char_to_full_length,auto_recompile_function; +select 0::date; +insert into test_date values(0); +select 1::date; +insert into test_date values(1); +set dolphin.sql_mode = sql_mode_strict,sql_mode_full_group,pipes_as_concat,ansi_quotes,pad_char_to_full_length,auto_recompile_function; +select 0::date; +insert into test_date values(0); +select 1::date; +insert into test_date values(1); +set dolphin.sql_mode = sql_mode_full_group,pipes_as_concat,ansi_quotes,no_zero_date,pad_char_to_full_length,auto_recompile_function; +select 0::date; +insert into test_date values(0); +select 1::date; +insert into test_date values(1); +set dolphin.sql_mode = sql_mode_full_group,pipes_as_concat,ansi_quotes,pad_char_to_full_length,auto_recompile_function; +select 0::date; +insert into test_date values(0); +select 1::date; +insert into test_date values(1); +reset dolphin.sql_mode; +select * from test_date; + drop schema conv_cast_test cascade; reset current_schema; -- Gitee