diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-06-21 04:00:16 +0300 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-07-12 22:00:39 +0300 |
commit | 0e9ba176bf2ad4d44e62b8f6e4e1916b39c5bf33 (patch) | |
tree | ad9d40799528b18d472bb371751fb2b66f7cb5d3 /sql | |
parent | b082716892071fdc3c961e9afaa011e0f6beb102 (diff) | |
download | mariadb-git-0e9ba176bf2ad4d44e62b8f6e4e1916b39c5bf33.tar.gz |
MDEV-17890 Server crash on DELETE with YEAR field with truncated expr
The failing reason was inconsistent truncation rules: the value of virtual
column could have been evaluated to '2000' sometimes instead of '0000' for
value 'a'.
The reason why `c YEAR AS ('aaaa')` was not evaluated same is that len=4 is
a special case insidew Field_year::store.
The correct fix is: always evaluate a bad value to 0000 instead 2000.
The truncated values should be evaluated as usual.
$support_virtual_index is finally changed to 1 in gcol.gcol_ins_upd_innodb,
which is also enough for testing.
The test from original bug report is also added.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/sql/field.cc b/sql/field.cc index 652228beceb..074de35e0cf 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6373,6 +6373,7 @@ bool Field_timef::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; + THD *thd= get_thd(); char *end; int error; longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); @@ -6384,7 +6385,14 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1); return 1; } - if (get_thd()->count_cuted_fields && + + if (!thd->count_cuted_fields && error == MY_ERRNO_EDOM) + { + *ptr= 0; + return 1; + } + + if (thd->count_cuted_fields && (error= check_int(cs, from, len, end, error))) { if (error == 1) /* empty or incorrect string */ |