Skip to content

Commit 189bf30

Browse files
committed
MDEV-21639 DEFAULT(col) evaluates to a bad value in WHERE clause
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.
1 parent fad1d15 commit 189bf30

File tree

4 files changed

+272
-3
lines changed

4 files changed

+272
-3
lines changed

mysql-test/r/func_default.result

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three');
2929
SELECT s, 32 AS mi FROM t1 GROUP BY s HAVING DEFAULT(mi) IS NULL;
3030
ERROR HY000: Field 'mi' doesn't have a default value
3131
DROP TABLE t1;
32+
#
33+
# Start of 10.2 tests
34+
#
3235
set timestamp=unix_timestamp('2001-01-01 10:20:30.123456');
3336
create table t1 (a int default 1, b int default (a+1),
3437
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)
4043
1 2 foo bar 2001-01-01 10:20:30 2001-01-01 10:20:30.120000
4144
1 11 foo bar 2001-01-01 10:20:30 2001-01-01 10:20:30.120000
4245
drop table t1;
46+
#
47+
# MDEV-21639 DEFAULT(col) evaluates to a bad value in WHERE clause
48+
#
49+
CREATE TABLE t1 (a BIGINT NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10)));
50+
INSERT INTO t1 VALUES (10000);
51+
SELECT
52+
a,
53+
DEFAULT(a),
54+
CASE WHEN a THEN DEFAULT(a) END AS c,
55+
CASE WHEN a THEN DEFAULT(a) END = 10 AS ce
56+
FROM t1;
57+
a DEFAULT(a) c ce
58+
10000 10 10 1
59+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10;
60+
a
61+
10000
62+
DROP TABLE t1;
63+
CREATE TABLE t1 (a DOUBLE NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10)));
64+
INSERT INTO t1 VALUES (10000);
65+
SELECT
66+
a,
67+
DEFAULT(a),
68+
CASE WHEN a THEN DEFAULT(a) END AS c,
69+
CASE WHEN a THEN DEFAULT(a) END = 10 AS ce
70+
FROM t1;
71+
a DEFAULT(a) c ce
72+
10000 10 10 1
73+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10;
74+
a
75+
10000
76+
DROP TABLE t1;
77+
CREATE TABLE t1 (a DECIMAL(10,0) NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10)));
78+
INSERT INTO t1 VALUES (10000);
79+
SELECT
80+
a,
81+
DEFAULT(a),
82+
CASE WHEN a THEN DEFAULT(a) END AS c,
83+
CASE WHEN a THEN DEFAULT(a) END = 10 AS ce
84+
FROM t1;
85+
a DEFAULT(a) c ce
86+
10000 10 10 1
87+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10;
88+
a
89+
10000
90+
DROP TABLE t1;
91+
CREATE TABLE t1 (a VARCHAR(32) NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10)));
92+
INSERT INTO t1 VALUES (10000);
93+
SELECT
94+
a,
95+
DEFAULT(a),
96+
CASE WHEN a THEN DEFAULT(a) END AS c,
97+
CASE WHEN a THEN DEFAULT(a) END = '10' AS ce
98+
FROM t1;
99+
a DEFAULT(a) c ce
100+
10000 10 10 1
101+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='10';
102+
a
103+
10000
104+
DROP TABLE t1;
105+
CREATE TABLE t1 (a DATE NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP()%10,DATE'2001-01-01')));
106+
INSERT INTO t1 VALUES ('2000-01-01');
107+
SELECT
108+
a,
109+
DEFAULT(a),
110+
CASE WHEN a THEN DEFAULT(a) END AS c,
111+
CASE WHEN a THEN DEFAULT(a) END = '2001-01-01' AS ce
112+
FROM t1;
113+
a DEFAULT(a) c ce
114+
2000-01-01 2001-01-01 2001-01-01 1
115+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='2001-01-01';
116+
a
117+
2000-01-01
118+
DROP TABLE t1;
119+
CREATE TABLE t1 (a TIME NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP()%10,TIME'10:20:30')));
120+
INSERT INTO t1 VALUES ('10:00:00');
121+
SELECT
122+
a,
123+
DEFAULT(a),
124+
CASE WHEN a THEN DEFAULT(a) END AS c,
125+
CASE WHEN a THEN DEFAULT(a) END = '10:20:30' AS ce
126+
FROM t1;
127+
a DEFAULT(a) c ce
128+
10:00:00 10:20:30 10:20:30 1
129+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='10:20:30';
130+
a
131+
10:00:00
132+
DROP TABLE t1;
133+
CREATE TABLE t1 (a DATETIME NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),TIMESTAMP'2001-01-01 10:20:30')));
134+
INSERT INTO t1 VALUES ('2000-01-01 10:00:00');
135+
SELECT
136+
a,
137+
DEFAULT(a),
138+
CASE WHEN a THEN DEFAULT(a) END AS c,
139+
CASE WHEN a THEN DEFAULT(a) END = '2001-01-01 10:20:30' AS ce
140+
FROM t1;
141+
a DEFAULT(a) c ce
142+
2000-01-01 10:00:00 2001-01-01 10:20:30 2001-01-01 10:20:30 1
143+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='2001-01-01 10:20:30';
144+
a
145+
2000-01-01 10:00:00
146+
DROP TABLE t1;
147+
CREATE TABLE t1 (a INT NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),FALSE)));
148+
INSERT INTO t1 VALUES (10);
149+
SELECT
150+
a,
151+
DEFAULT(a),
152+
CASE WHEN a THEN DEFAULT(a) END AS c,
153+
CASE WHEN a THEN DEFAULT(a) END IS FALSE AS ce
154+
FROM t1;
155+
a DEFAULT(a) c ce
156+
10 0 0 1
157+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END IS FALSE;
158+
a
159+
10
160+
DROP TABLE t1;
161+
#
162+
# End of 10.2 tests
163+
#

mysql-test/t/func_default.test

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three');
3434
SELECT s, 32 AS mi FROM t1 GROUP BY s HAVING DEFAULT(mi) IS NULL;
3535
DROP TABLE t1;
3636

37-
#
38-
# 10.2 tests
39-
#
37+
--echo #
38+
--echo # Start of 10.2 tests
39+
--echo #
4040

4141
set timestamp=unix_timestamp('2001-01-01 10:20:30.123456');
4242
create table t1 (a int default 1, b int default (a+1),
@@ -46,3 +46,99 @@ insert t1 () values ();
4646
insert t1 (a) values (10);
4747
select default(a),default(b),default(c),default(d),default(e),default(f) from t1;
4848
drop table t1;
49+
50+
--echo #
51+
--echo # MDEV-21639 DEFAULT(col) evaluates to a bad value in WHERE clause
52+
--echo #
53+
54+
CREATE TABLE t1 (a BIGINT NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10)));
55+
INSERT INTO t1 VALUES (10000);
56+
SELECT
57+
a,
58+
DEFAULT(a),
59+
CASE WHEN a THEN DEFAULT(a) END AS c,
60+
CASE WHEN a THEN DEFAULT(a) END = 10 AS ce
61+
FROM t1;
62+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10;
63+
DROP TABLE t1;
64+
65+
CREATE TABLE t1 (a DOUBLE NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10)));
66+
INSERT INTO t1 VALUES (10000);
67+
SELECT
68+
a,
69+
DEFAULT(a),
70+
CASE WHEN a THEN DEFAULT(a) END AS c,
71+
CASE WHEN a THEN DEFAULT(a) END = 10 AS ce
72+
FROM t1;
73+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10;
74+
DROP TABLE t1;
75+
76+
CREATE TABLE t1 (a DECIMAL(10,0) NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10)));
77+
INSERT INTO t1 VALUES (10000);
78+
SELECT
79+
a,
80+
DEFAULT(a),
81+
CASE WHEN a THEN DEFAULT(a) END AS c,
82+
CASE WHEN a THEN DEFAULT(a) END = 10 AS ce
83+
FROM t1;
84+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END=10;
85+
DROP TABLE t1;
86+
87+
CREATE TABLE t1 (a VARCHAR(32) NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),10)));
88+
INSERT INTO t1 VALUES (10000);
89+
SELECT
90+
a,
91+
DEFAULT(a),
92+
CASE WHEN a THEN DEFAULT(a) END AS c,
93+
CASE WHEN a THEN DEFAULT(a) END = '10' AS ce
94+
FROM t1;
95+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='10';
96+
DROP TABLE t1;
97+
98+
CREATE TABLE t1 (a DATE NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP()%10,DATE'2001-01-01')));
99+
INSERT INTO t1 VALUES ('2000-01-01');
100+
SELECT
101+
a,
102+
DEFAULT(a),
103+
CASE WHEN a THEN DEFAULT(a) END AS c,
104+
CASE WHEN a THEN DEFAULT(a) END = '2001-01-01' AS ce
105+
FROM t1;
106+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='2001-01-01';
107+
DROP TABLE t1;
108+
109+
CREATE TABLE t1 (a TIME NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP()%10,TIME'10:20:30')));
110+
INSERT INTO t1 VALUES ('10:00:00');
111+
SELECT
112+
a,
113+
DEFAULT(a),
114+
CASE WHEN a THEN DEFAULT(a) END AS c,
115+
CASE WHEN a THEN DEFAULT(a) END = '10:20:30' AS ce
116+
FROM t1;
117+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='10:20:30';
118+
DROP TABLE t1;
119+
120+
CREATE TABLE t1 (a DATETIME NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),TIMESTAMP'2001-01-01 10:20:30')));
121+
INSERT INTO t1 VALUES ('2000-01-01 10:00:00');
122+
SELECT
123+
a,
124+
DEFAULT(a),
125+
CASE WHEN a THEN DEFAULT(a) END AS c,
126+
CASE WHEN a THEN DEFAULT(a) END = '2001-01-01 10:20:30' AS ce
127+
FROM t1;
128+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END='2001-01-01 10:20:30';
129+
DROP TABLE t1;
130+
131+
CREATE TABLE t1 (a INT NOT NULL DEFAULT (IF(false,UNIX_TIMESTAMP(),FALSE)));
132+
INSERT INTO t1 VALUES (10);
133+
SELECT
134+
a,
135+
DEFAULT(a),
136+
CASE WHEN a THEN DEFAULT(a) END AS c,
137+
CASE WHEN a THEN DEFAULT(a) END IS FALSE AS ce
138+
FROM t1;
139+
SELECT a FROM t1 WHERE CASE WHEN a THEN DEFAULT(a) END IS FALSE;
140+
DROP TABLE t1;
141+
142+
--echo #
143+
--echo # End of 10.2 tests
144+
--echo #

sql/item.cc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9165,6 +9165,48 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
91659165
&view_error_processor);
91669166
}
91679167

9168+
double Item_default_value::val_result()
9169+
{
9170+
calculate();
9171+
return Item_field::val_result();
9172+
}
9173+
9174+
longlong Item_default_value::val_int_result()
9175+
{
9176+
calculate();
9177+
return Item_field::val_int_result();
9178+
}
9179+
9180+
String *Item_default_value::str_result(String* tmp)
9181+
{
9182+
calculate();
9183+
return Item_field::str_result(tmp);
9184+
}
9185+
9186+
bool Item_default_value::val_bool_result()
9187+
{
9188+
calculate();
9189+
return Item_field::val_bool_result();
9190+
}
9191+
9192+
bool Item_default_value::is_null_result()
9193+
{
9194+
calculate();
9195+
return Item_field::is_null_result();
9196+
}
9197+
9198+
my_decimal *Item_default_value::val_decimal_result(my_decimal *decimal_value)
9199+
{
9200+
calculate();
9201+
return Item_field::val_decimal_result(decimal_value);
9202+
}
9203+
9204+
bool Item_default_value::get_date_result(MYSQL_TIME *ltime,ulonglong fuzzydate)
9205+
{
9206+
calculate();
9207+
return Item_field::get_date_result(ltime, fuzzydate);
9208+
}
9209+
91689210
table_map Item_default_value::used_tables() const
91699211
{
91709212
if (!field || !field->default_value)

sql/item.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5478,6 +5478,16 @@ class Item_default_value : public Item_field
54785478
longlong val_int();
54795479
my_decimal *val_decimal(my_decimal *decimal_value);
54805480
bool get_date(MYSQL_TIME *ltime,ulonglong fuzzydate);
5481+
5482+
/* Result variants */
5483+
double val_result();
5484+
longlong val_int_result();
5485+
String *str_result(String* tmp);
5486+
my_decimal *val_decimal_result(my_decimal *val);
5487+
bool val_bool_result();
5488+
bool is_null_result();
5489+
bool get_date_result(MYSQL_TIME *ltime,ulonglong fuzzydate);
5490+
54815491
bool send(Protocol *protocol, String *buffer);
54825492
int save_in_field(Field *field_arg, bool no_conversions);
54835493
bool save_in_param(THD *thd, Item_param *param)

0 commit comments

Comments
 (0)