summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2021-06-21 04:00:16 +0300
committerNikita Malyavin <nikitamalyavin@gmail.com>2021-07-12 22:00:39 +0300
commit0e9ba176bf2ad4d44e62b8f6e4e1916b39c5bf33 (patch)
treead9d40799528b18d472bb371751fb2b66f7cb5d3 /sql
parentb082716892071fdc3c961e9afaa011e0f6beb102 (diff)
downloadmariadb-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.cc10
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 */