diff options
author | Alexander Barkov <bar@mariadb.com> | 2021-12-29 14:54:34 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2021-12-29 14:54:34 +0400 |
commit | 189bf300cae5bbf147b780d6191f7fef6ad58678 (patch) | |
tree | 1e645398a0dab3ebbf6c4da75d5c629d0dfaf294 | |
parent | fad1d15326651a92895c799829ff66edc37fc20f (diff) | |
download | mariadb-git-189bf300cae5bbf147b780d6191f7fef6ad58678.tar.gz |
MDEV-21639 DEFAULT(col) evaluates to a bad value in WHERE clausebb-10.2-bar-MDEV-21639
The problem happened because Item_default_value did not overload
properly the val_xxx_result() family methods.
This change backports the patch for:
MDEV-24958 Server crashes in my_strtod / Value_source::Converter_strntod::Converter_strntod with DEFAULT(blob)
which earlier fixed the problem in 10.3.
-rw-r--r-- | mysql-test/r/func_default.result | 121 | ||||
-rw-r--r-- | mysql-test/t/func_default.test | 102 | ||||
-rw-r--r-- | sql/item.cc | 42 | ||||
-rw-r--r-- | sql/item.h | 10 |
4 files changed, 272 insertions, 3 deletions
diff --git a/mysql-test/r/func_default.result b/mysql-test/r/func_default.result index 9699f0795e3..8721270ca1c 100644 --- a/mysql-test/r/func_default.result +++ b/mysql-test/r/func_default.result @@ -29,6 +29,9 @@ INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three'); SELECT s, 32 AS mi FROM t1 GROUP BY s HAVING DEFAULT(mi) IS NULL; ERROR HY000: Field 'mi' doesn't have a default value DROP TABLE t1; +# +# Start of 10.2 tests +# set timestamp=unix_timestamp('2001-01-01 10:20:30.123456'); create table t1 (a int default 1, b int default (a+1), c varchar(100) default 'foo', d text default 'bar', @@ -40,3 +43,121 @@ default(a) default(b) default(c) default(d) default(e) default(f) 1 2 foo bar 2001-01-01 10:20:30 2001-01-01 10:20:30.120000 1 11 foo bar 2001-01-01 10:20:30 2001-01-01 10:20:30.120000 drop table t1; +# +# MDEV-21639 DEFAULT(col) evaluates to a bad value in WHERE clause +# +CREATE TABLE t1 (a BIGINT NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10))); +INSERT INTO t1 VALUES (10000); +SELECT +a, +DEFAULT(a), +CASE WHEN a THEN DEFAULT(a) END AS c, +CASE WHEN a THEN DEFAULT(a) END = 10 AS ce +FROM t1; +a DEFAULT(a) c ce +10000 10 10 1 +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10; +a +10000 +DROP TABLE t1; +CREATE TABLE t1 (a DOUBLE NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10))); +INSERT INTO t1 VALUES (10000); +SELECT +a, +DEFAULT(a), +CASE WHEN a THEN DEFAULT(a) END AS c, +CASE WHEN a THEN DEFAULT(a) END = 10 AS ce +FROM t1; +a DEFAULT(a) c ce +10000 10 10 1 +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10; +a +10000 +DROP TABLE t1; +CREATE TABLE t1 (a DECIMAL(10,0) NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10))); +INSERT INTO t1 VALUES (10000); +SELECT +a, +DEFAULT(a), +CASE WHEN a THEN DEFAULT(a) END AS c, +CASE WHEN a THEN DEFAULT(a) END = 10 AS ce +FROM t1; +a DEFAULT(a) c ce +10000 10 10 1 +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10; +a +10000 +DROP TABLE t1; +CREATE TABLE t1 (a VARCHAR(32) NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10))); +INSERT INTO t1 VALUES (10000); +SELECT +a, +DEFAULT(a), +CASE WHEN a THEN DEFAULT(a) END AS c, +CASE WHEN a THEN DEFAULT(a) END = '10' AS ce +FROM t1; +a DEFAULT(a) c ce +10000 10 10 1 +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='10'; +a +10000 +DROP TABLE t1; +CREATE TABLE t1 (a DATE NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP()%10,DATE'2001-01-01'))); +INSERT INTO t1 VALUES ('2000-01-01'); +SELECT +a, +DEFAULT(a), +CASE WHEN a THEN DEFAULT(a) END AS c, +CASE WHEN a THEN DEFAULT(a) END = '2001-01-01' AS ce +FROM t1; +a DEFAULT(a) c ce +2000-01-01 2001-01-01 2001-01-01 1 +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='2001-01-01'; +a +2000-01-01 +DROP TABLE t1; +CREATE TABLE t1 (a TIME NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP()%10,TIME'10:20:30'))); +INSERT INTO t1 VALUES ('10:00:00'); +SELECT +a, +DEFAULT(a), +CASE WHEN a THEN DEFAULT(a) END AS c, +CASE WHEN a THEN DEFAULT(a) END = '10:20:30' AS ce +FROM t1; +a DEFAULT(a) c ce +10:00:00 10:20:30 10:20:30 1 +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='10:20:30'; +a +10:00:00 +DROP TABLE t1; +CREATE TABLE t1 (a DATETIME NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),TIMESTAMP'2001-01-01 10:20:30'))); +INSERT INTO t1 VALUES ('2000-01-01 10:00:00'); +SELECT +a, +DEFAULT(a), +CASE WHEN a THEN DEFAULT(a) END AS c, +CASE WHEN a THEN DEFAULT(a) END = '2001-01-01 10:20:30' AS ce +FROM t1; +a DEFAULT(a) c ce +2000-01-01 10:00:00 2001-01-01 10:20:30 2001-01-01 10:20:30 1 +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='2001-01-01 10:20:30'; +a +2000-01-01 10:00:00 +DROP TABLE t1; +CREATE TABLE t1 (a INT NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),FALSE))); +INSERT INTO t1 VALUES (10); +SELECT +a, +DEFAULT(a), +CASE WHEN a THEN DEFAULT(a) END AS c, +CASE WHEN a THEN DEFAULT(a) END IS FALSE AS ce +FROM t1; +a DEFAULT(a) c ce +10 0 0 1 +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END IS FALSE; +a +10 +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/t/func_default.test b/mysql-test/t/func_default.test index 332bfca021f..cba7842c68f 100644 --- a/mysql-test/t/func_default.test +++ b/mysql-test/t/func_default.test @@ -34,9 +34,9 @@ INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three'); SELECT s, 32 AS mi FROM t1 GROUP BY s HAVING DEFAULT(mi) IS NULL; DROP TABLE t1; -# -# 10.2 tests -# +--echo # +--echo # Start of 10.2 tests +--echo # set timestamp=unix_timestamp('2001-01-01 10:20:30.123456'); create table t1 (a int default 1, b int default (a+1), @@ -46,3 +46,99 @@ insert t1 () values (); insert t1 (a) values (10); select default(a),default(b),default(c),default(d),default(e),default(f) from t1; drop table t1; + +--echo # +--echo # MDEV-21639 DEFAULT(col) evaluates to a bad value in WHERE clause +--echo # + +CREATE TABLE t1 (a BIGINT NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10))); +INSERT INTO t1 VALUES (10000); +SELECT + a, + DEFAULT(a), + CASE WHEN a THEN DEFAULT(a) END AS c, + CASE WHEN a THEN DEFAULT(a) END = 10 AS ce +FROM t1; +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10; +DROP TABLE t1; + +CREATE TABLE t1 (a DOUBLE NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10))); +INSERT INTO t1 VALUES (10000); +SELECT + a, + DEFAULT(a), + CASE WHEN a THEN DEFAULT(a) END AS c, + CASE WHEN a THEN DEFAULT(a) END = 10 AS ce +FROM t1; +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10; +DROP TABLE t1; + +CREATE TABLE t1 (a DECIMAL(10,0) NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10))); +INSERT INTO t1 VALUES (10000); +SELECT + a, + DEFAULT(a), + CASE WHEN a THEN DEFAULT(a) END AS c, + CASE WHEN a THEN DEFAULT(a) END = 10 AS ce +FROM t1; +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10; +DROP TABLE t1; + +CREATE TABLE t1 (a VARCHAR(32) NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10))); +INSERT INTO t1 VALUES (10000); +SELECT + a, + DEFAULT(a), + CASE WHEN a THEN DEFAULT(a) END AS c, + CASE WHEN a THEN DEFAULT(a) END = '10' AS ce +FROM t1; +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='10'; +DROP TABLE t1; + +CREATE TABLE t1 (a DATE NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP()%10,DATE'2001-01-01'))); +INSERT INTO t1 VALUES ('2000-01-01'); +SELECT + a, + DEFAULT(a), + CASE WHEN a THEN DEFAULT(a) END AS c, + CASE WHEN a THEN DEFAULT(a) END = '2001-01-01' AS ce +FROM t1; +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='2001-01-01'; +DROP TABLE t1; + +CREATE TABLE t1 (a TIME NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP()%10,TIME'10:20:30'))); +INSERT INTO t1 VALUES ('10:00:00'); +SELECT + a, + DEFAULT(a), + CASE WHEN a THEN DEFAULT(a) END AS c, + CASE WHEN a THEN DEFAULT(a) END = '10:20:30' AS ce +FROM t1; +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='10:20:30'; +DROP TABLE t1; + +CREATE TABLE t1 (a DATETIME NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),TIMESTAMP'2001-01-01 10:20:30'))); +INSERT INTO t1 VALUES ('2000-01-01 10:00:00'); +SELECT + a, + DEFAULT(a), + CASE WHEN a THEN DEFAULT(a) END AS c, + CASE WHEN a THEN DEFAULT(a) END = '2001-01-01 10:20:30' AS ce +FROM t1; +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='2001-01-01 10:20:30'; +DROP TABLE t1; + +CREATE TABLE t1 (a INT NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),FALSE))); +INSERT INTO t1 VALUES (10); +SELECT + a, + DEFAULT(a), + CASE WHEN a THEN DEFAULT(a) END AS c, + CASE WHEN a THEN DEFAULT(a) END IS FALSE AS ce +FROM t1; +SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END IS FALSE; +DROP TABLE t1; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/sql/item.cc b/sql/item.cc index 3ff0219c3b3..a5b313b786d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9165,6 +9165,48 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions) &view_error_processor); } +double Item_default_value::val_result() +{ + calculate(); + return Item_field::val_result(); +} + +longlong Item_default_value::val_int_result() +{ + calculate(); + return Item_field::val_int_result(); +} + +String *Item_default_value::str_result(String* tmp) +{ + calculate(); + return Item_field::str_result(tmp); +} + +bool Item_default_value::val_bool_result() +{ + calculate(); + return Item_field::val_bool_result(); +} + +bool Item_default_value::is_null_result() +{ + calculate(); + return Item_field::is_null_result(); +} + +my_decimal *Item_default_value::val_decimal_result(my_decimal *decimal_value) +{ + calculate(); + return Item_field::val_decimal_result(decimal_value); +} + +bool Item_default_value::get_date_result(MYSQL_TIME *ltime,ulonglong fuzzydate) +{ + calculate(); + return Item_field::get_date_result(ltime, fuzzydate); +} + table_map Item_default_value::used_tables() const { if (!field || !field->default_value) diff --git a/sql/item.h b/sql/item.h index 2a904c1691a..997352ef27a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5478,6 +5478,16 @@ public: longlong val_int(); my_decimal *val_decimal(my_decimal *decimal_value); bool get_date(MYSQL_TIME *ltime,ulonglong fuzzydate); + + /* Result variants */ + double val_result(); + longlong val_int_result(); + String *str_result(String* tmp); + my_decimal *val_decimal_result(my_decimal *val); + bool val_bool_result(); + bool is_null_result(); + bool get_date_result(MYSQL_TIME *ltime,ulonglong fuzzydate); + bool send(Protocol *protocol, String *buffer); int save_in_field(Field *field_arg, bool no_conversions); bool save_in_param(THD *thd, Item_param *param) |