diff --git a/mysql-test/include/search_condition.inc b/mysql-test/include/search_condition.inc new file mode 100644 index 00000000000..2e050e90af7 --- /dev/null +++ b/mysql-test/include/search_condition.inc @@ -0,0 +1,201 @@ +--echo # +--echo # WHERE +--echo # + +let datatype=`SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME='t0' AND COLUMN_NAME='c'`; +let use_string_func=0; +let use_field=1; +let update_source=c+11; + +if ($datatype == 'varchar') +{ + let use_string_func=1; +} + +if ($datatype == 'datetime') +{ + let update_source=c+0.1; +} + +if ($datatype == 'inet6') +{ + let use_field=0; + let update_source=concat(c,'77'); +} + + +CREATE TABLE t1 AS SELECT * FROM t0; +if ($use_field) +{ + SELECT * FROM t1 WHERE c; +} +SELECT * FROM t1 WHERE c IS FALSE; +SELECT * FROM t1 WHERE c IS TRUE; +SELECT * FROM t1 WHERE COALESCE(c); +if ($use_string_func) +{ + SELECT * FROM t1 WHERE CONCAT(c); + SELECT * FROM t1 WHERE LEFT(c,100); +} +DROP TABLE t1; + + +--echo # +--echo # HAVING +--echo # + +CREATE TABLE t1 AS SELECT * FROM t0; +if ($use_field) +{ + SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2; +} +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS FALSE; +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS TRUE; +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING COALESCE(c2); +if ($use_string_func) +{ + SELECT CONCAT(c,'0') AS c2 FROM t1 GROUP BY c2 HAVING LEFT(c2,100); +} +DROP TABLE t1; + + +--echo # +--echo # := ON +--echo # + +CREATE TABLE t1 AS SELECT * FROM t0; +if ($use_field) +{ + SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c); +} +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS FALSE); +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS TRUE); +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (COALESCE(t1.c)); +if ($use_string_func) +{ + SELECT t1.c FROM t1 JOIN t1 AS t2 ON (CONCAT(t1.c)); +} +DROP TABLE t1; + + +--echo # +--echo # +--echo # DELETE FROM [ WHERE ] +--echo # + +if ($use_field) +{ + CREATE TABLE t1 AS SELECT * FROM t0; + DELETE FROM t1 WHERE c; + SELECT * FROM t1; + DROP TABLE t1; +} + +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS FALSE; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS TRUE; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE COALESCE(c); +SELECT * FROM t1; +DROP TABLE t1; + +if ($use_string_func) +{ + CREATE TABLE t1 AS SELECT * FROM t0; + DELETE FROM t1 WHERE CONCAT(c); + SELECT * FROM t1; + DROP TABLE t1; +} + + +--echo # +--echo # +--echo # UPDATE SET [ WHERE ] + +if ($use_field) +{ + CREATE TABLE t1 AS SELECT * FROM t0; + eval UPDATE t1 SET c=$update_source WHERE c; + SELECT * FROM t1; + DROP TABLE t1; +} + +CREATE TABLE t1 AS SELECT * FROM t0; +eval UPDATE t1 SET c=$update_source WHERE c IS FALSE; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT * FROM t0; +eval UPDATE t1 SET c=$update_source WHERE c IS TRUE; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT * FROM t0; +eval UPDATE t1 SET c=$update_source WHERE COALESCE(c); +SELECT * FROM t1; +DROP TABLE t1; + +if ($use_string_func) +{ + CREATE TABLE t1 AS SELECT * FROM t0; + eval UPDATE t1 SET c=$update_source WHERE COALESCE(c); + SELECT * FROM t1; + DROP TABLE t1; +} + +--echo # +--echo # +--echo # CHECK + +if ($use_field) +{ + CREATE TABLE t1 LIKE t0; + ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c); +--error ER_CONSTRAINT_FAILED + INSERT INTO t1 SELECT * FROM t0 WHERE NOT c; + INSERT INTO t1 SELECT * FROM t0 WHERE c; + SELECT * FROM t1; + DROP TABLE t1; +} + +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS FALSE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +--error ER_CONSTRAINT_FAILED +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS TRUE); +--error ER_CONSTRAINT_FAILED +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(COALESCE(c)); +--error ER_CONSTRAINT_FAILED +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +DROP TABLE t1; + + +--echo # +--echo # +--echo # WHEN THEN + +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT c, CASE WHEN c THEN 'true' ELSE 'false' END AS c2 FROM t1; +SELECT c, CASE WHEN COALESCE(c) THEN 'true' ELSE 'false' END AS c2 FROM t1; +DROP TABLE t1; diff --git a/mysql-test/main/type_datetime.result b/mysql-test/main/type_datetime.result index 6ee2d3d0fe9..52c6b2890fe 100644 --- a/mysql-test/main/type_datetime.result +++ b/mysql-test/main/type_datetime.result @@ -1707,3 +1707,207 @@ indexed_col not_indexed_col DROP TABLE t2; DROP TABLE t1; SET note_verbosity=DEFAULT; +# +# MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +# +CREATE TABLE t0 (c DATETIME(1)); +INSERT INTO t0 VALUES ('0000-00-00 00:00:00.0'),('0000-00-00 00:00:00.1'),('2014-01-01 10:00:00.1'); +# +# WHERE +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT * FROM t1 WHERE c; +c +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +SELECT * FROM t1 WHERE c IS FALSE; +c +0000-00-00 00:00:00.0 +SELECT * FROM t1 WHERE c IS TRUE; +c +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +SELECT * FROM t1 WHERE COALESCE(c); +c +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +DROP TABLE t1; +# +# HAVING +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2; +c2 +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS FALSE; +c2 +0000-00-00 00:00:00.0 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS TRUE; +c2 +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING COALESCE(c2); +c2 +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +DROP TABLE t1; +# +# := ON +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c); +c +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS FALSE); +c +0000-00-00 00:00:00.0 +0000-00-00 00:00:00.0 +0000-00-00 00:00:00.0 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS TRUE); +c +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (COALESCE(t1.c)); +c +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +DROP TABLE t1; +# +# +# DELETE FROM [ WHERE ] +# +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c; +SELECT * FROM t1; +c +0000-00-00 00:00:00.0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS FALSE; +SELECT * FROM t1; +c +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS TRUE; +SELECT * FROM t1; +c +0000-00-00 00:00:00.0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE COALESCE(c); +SELECT * FROM t1; +c +0000-00-00 00:00:00.0 +DROP TABLE t1; +# +# +# UPDATE SET [ WHERE ] +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+0.1 WHERE c; +SELECT * FROM t1; +c +0000-00-00 00:00:00.0 +0000-00-00 00:00:00.2 +2014-01-01 10:00:00.2 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+0.1 WHERE c IS FALSE; +SELECT * FROM t1; +c +0000-00-00 00:00:00.1 +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+0.1 WHERE c IS TRUE; +SELECT * FROM t1; +c +0000-00-00 00:00:00.0 +0000-00-00 00:00:00.2 +2014-01-01 10:00:00.2 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+0.1 WHERE COALESCE(c); +SELECT * FROM t1; +c +0000-00-00 00:00:00.0 +0000-00-00 00:00:00.2 +2014-01-01 10:00:00.2 +DROP TABLE t1; +# +# +# CHECK +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c); +INSERT INTO t1 SELECT * FROM t0 WHERE NOT c; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c; +SELECT * FROM t1; +c +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS FALSE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +SELECT * FROM t1; +c +0000-00-00 00:00:00.0 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS TRUE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(COALESCE(c)); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +0000-00-00 00:00:00.1 +2014-01-01 10:00:00.1 +DROP TABLE t1; +# +# +# WHEN THEN +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT c, CASE WHEN c THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +0000-00-00 00:00:00.0 false +0000-00-00 00:00:00.1 true +2014-01-01 10:00:00.1 true +SELECT c, CASE WHEN COALESCE(c) THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +0000-00-00 00:00:00.0 false +0000-00-00 00:00:00.1 true +2014-01-01 10:00:00.1 true +DROP TABLE t1; +DROP TABLE t0; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/type_datetime.test b/mysql-test/main/type_datetime.test index c1d45870221..c5991c01508 100644 --- a/mysql-test/main/type_datetime.test +++ b/mysql-test/main/type_datetime.test @@ -1062,3 +1062,18 @@ DELIMITER ;$$ --source unusable_keys_joins.inc DROP TABLE t1; SET note_verbosity=DEFAULT; + + +--echo # +--echo # MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +--echo # + +CREATE TABLE t0 (c DATETIME(1)); +INSERT INTO t0 VALUES ('0000-00-00 00:00:00.0'),('0000-00-00 00:00:00.1'),('2014-01-01 10:00:00.1'); +--source include/search_condition.inc +DROP TABLE t0; + + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/mysql-test/main/type_decimal.result b/mysql-test/main/type_decimal.result index 29067f8f5a5..ce84660e420 100644 --- a/mysql-test/main/type_decimal.result +++ b/mysql-test/main/type_decimal.result @@ -1323,3 +1323,210 @@ SET sql_mode=DEFAULT; # # End of 10.4 tests # +# +# Start of 10.6 tests +# +# +# MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +# +CREATE TABLE t0 (c DECIMAL(10, 1)); +INSERT INTO t0 VALUES (0.0),(0.4),(0.6); +# +# WHERE +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT * FROM t1 WHERE c; +c +0.4 +0.6 +SELECT * FROM t1 WHERE c IS FALSE; +c +0.0 +SELECT * FROM t1 WHERE c IS TRUE; +c +0.4 +0.6 +SELECT * FROM t1 WHERE COALESCE(c); +c +0.4 +0.6 +DROP TABLE t1; +# +# HAVING +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2; +c2 +0.4 +0.6 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS FALSE; +c2 +0.0 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS TRUE; +c2 +0.4 +0.6 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING COALESCE(c2); +c2 +0.4 +0.6 +DROP TABLE t1; +# +# := ON +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c); +c +0.4 +0.6 +0.4 +0.6 +0.4 +0.6 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS FALSE); +c +0.0 +0.0 +0.0 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS TRUE); +c +0.4 +0.6 +0.4 +0.6 +0.4 +0.6 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (COALESCE(t1.c)); +c +0.4 +0.6 +0.4 +0.6 +0.4 +0.6 +DROP TABLE t1; +# +# +# DELETE FROM [ WHERE ] +# +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c; +SELECT * FROM t1; +c +0.0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS FALSE; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS TRUE; +SELECT * FROM t1; +c +0.0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE COALESCE(c); +SELECT * FROM t1; +c +0.0 +DROP TABLE t1; +# +# +# UPDATE SET [ WHERE ] +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c; +SELECT * FROM t1; +c +0.0 +11.4 +11.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c IS FALSE; +SELECT * FROM t1; +c +11.0 +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c IS TRUE; +SELECT * FROM t1; +c +0.0 +11.4 +11.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE COALESCE(c); +SELECT * FROM t1; +c +0.0 +11.4 +11.6 +DROP TABLE t1; +# +# +# CHECK +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c); +INSERT INTO t1 SELECT * FROM t0 WHERE NOT c; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS FALSE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +SELECT * FROM t1; +c +0.0 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS TRUE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(COALESCE(c)); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +# +# +# WHEN THEN +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT c, CASE WHEN c THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +0.0 false +0.4 true +0.6 true +SELECT c, CASE WHEN COALESCE(c) THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +0.0 false +0.4 true +0.6 true +DROP TABLE t1; +DROP TABLE t0; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/type_decimal.test b/mysql-test/main/type_decimal.test index 1076592fe62..b0c88e6244e 100644 --- a/mysql-test/main/type_decimal.test +++ b/mysql-test/main/type_decimal.test @@ -823,3 +823,21 @@ SET sql_mode=DEFAULT; --echo # --echo # End of 10.4 tests --echo # + + +--echo # +--echo # Start of 10.6 tests +--echo # + +--echo # +--echo # MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +--echo # + +CREATE TABLE t0 (c DECIMAL(10, 1)); +INSERT INTO t0 VALUES (0.0),(0.4),(0.6); +--source include/search_condition.inc +DROP TABLE t0; + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/mysql-test/main/type_float.result b/mysql-test/main/type_float.result index 36a227a4bd6..6dc5fec6f44 100644 --- a/mysql-test/main/type_float.result +++ b/mysql-test/main/type_float.result @@ -1547,3 +1547,207 @@ Warning 1292 Truncated incorrect DOUBLE value: '2001-01-02' DROP TABLE t2; DROP TABLE t1; SET note_verbosity=DEFAULT; +# +# MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +# +CREATE TABLE t0 (c DOUBLE); +INSERT INTO t0 VALUES (0.0),(0.4),(0.6); +# +# WHERE +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT * FROM t1 WHERE c; +c +0.4 +0.6 +SELECT * FROM t1 WHERE c IS FALSE; +c +0 +SELECT * FROM t1 WHERE c IS TRUE; +c +0.4 +0.6 +SELECT * FROM t1 WHERE COALESCE(c); +c +0.4 +0.6 +DROP TABLE t1; +# +# HAVING +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2; +c2 +0.4 +0.6 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS FALSE; +c2 +0 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS TRUE; +c2 +0.4 +0.6 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING COALESCE(c2); +c2 +0.4 +0.6 +DROP TABLE t1; +# +# := ON +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c); +c +0.4 +0.6 +0.4 +0.6 +0.4 +0.6 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS FALSE); +c +0 +0 +0 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS TRUE); +c +0.4 +0.6 +0.4 +0.6 +0.4 +0.6 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (COALESCE(t1.c)); +c +0.4 +0.6 +0.4 +0.6 +0.4 +0.6 +DROP TABLE t1; +# +# +# DELETE FROM [ WHERE ] +# +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c; +SELECT * FROM t1; +c +0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS FALSE; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS TRUE; +SELECT * FROM t1; +c +0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE COALESCE(c); +SELECT * FROM t1; +c +0 +DROP TABLE t1; +# +# +# UPDATE SET [ WHERE ] +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c; +SELECT * FROM t1; +c +0 +11.4 +11.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c IS FALSE; +SELECT * FROM t1; +c +11 +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c IS TRUE; +SELECT * FROM t1; +c +0 +11.4 +11.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE COALESCE(c); +SELECT * FROM t1; +c +0 +11.4 +11.6 +DROP TABLE t1; +# +# +# CHECK +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c); +INSERT INTO t1 SELECT * FROM t0 WHERE NOT c; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS FALSE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +SELECT * FROM t1; +c +0 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS TRUE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(COALESCE(c)); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +# +# +# WHEN THEN +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT c, CASE WHEN c THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +0 false +0.4 true +0.6 true +SELECT c, CASE WHEN COALESCE(c) THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +0 false +0.4 true +0.6 true +DROP TABLE t1; +DROP TABLE t0; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/type_float.test b/mysql-test/main/type_float.test index 994bf5ad9da..a08ee7fd4b2 100644 --- a/mysql-test/main/type_float.test +++ b/mysql-test/main/type_float.test @@ -834,3 +834,17 @@ DELIMITER ;$$ --source unusable_keys_joins.inc DROP TABLE t1; SET note_verbosity=DEFAULT; + + +--echo # +--echo # MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +--echo # + +CREATE TABLE t0 (c DOUBLE); +INSERT INTO t0 VALUES (0.0),(0.4),(0.6); +--source include/search_condition.inc +DROP TABLE t0; + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/mysql-test/main/type_int.result b/mysql-test/main/type_int.result index efa855da42e..58110bc0762 100644 --- a/mysql-test/main/type_int.result +++ b/mysql-test/main/type_int.result @@ -2102,3 +2102,207 @@ Warning 1292 Truncated incorrect INTEGER value: '2001-01-02' DROP TABLE t2; DROP TABLE t1; SET note_verbosity=DEFAULT; +# +# MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +# +CREATE TABLE t0 (c INT); +INSERT INTO t0 VALUES (0),(100),(200); +# +# WHERE +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT * FROM t1 WHERE c; +c +100 +200 +SELECT * FROM t1 WHERE c IS FALSE; +c +0 +SELECT * FROM t1 WHERE c IS TRUE; +c +100 +200 +SELECT * FROM t1 WHERE COALESCE(c); +c +100 +200 +DROP TABLE t1; +# +# HAVING +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2; +c2 +100 +200 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS FALSE; +c2 +0 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS TRUE; +c2 +100 +200 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING COALESCE(c2); +c2 +100 +200 +DROP TABLE t1; +# +# := ON +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c); +c +100 +200 +100 +200 +100 +200 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS FALSE); +c +0 +0 +0 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS TRUE); +c +100 +200 +100 +200 +100 +200 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (COALESCE(t1.c)); +c +100 +200 +100 +200 +100 +200 +DROP TABLE t1; +# +# +# DELETE FROM [ WHERE ] +# +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c; +SELECT * FROM t1; +c +0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS FALSE; +SELECT * FROM t1; +c +100 +200 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS TRUE; +SELECT * FROM t1; +c +0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE COALESCE(c); +SELECT * FROM t1; +c +0 +DROP TABLE t1; +# +# +# UPDATE SET [ WHERE ] +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c; +SELECT * FROM t1; +c +0 +111 +211 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c IS FALSE; +SELECT * FROM t1; +c +11 +100 +200 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c IS TRUE; +SELECT * FROM t1; +c +0 +111 +211 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE COALESCE(c); +SELECT * FROM t1; +c +0 +111 +211 +DROP TABLE t1; +# +# +# CHECK +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c); +INSERT INTO t1 SELECT * FROM t0 WHERE NOT c; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c; +SELECT * FROM t1; +c +100 +200 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS FALSE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +SELECT * FROM t1; +c +0 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS TRUE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +100 +200 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(COALESCE(c)); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +100 +200 +DROP TABLE t1; +# +# +# WHEN THEN +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT c, CASE WHEN c THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +0 false +100 true +200 true +SELECT c, CASE WHEN COALESCE(c) THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +0 false +100 true +200 true +DROP TABLE t1; +DROP TABLE t0; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/type_int.test b/mysql-test/main/type_int.test index f15f8688907..4e03987001a 100644 --- a/mysql-test/main/type_int.test +++ b/mysql-test/main/type_int.test @@ -682,3 +682,17 @@ DELIMITER ;$$ --source unusable_keys_joins.inc DROP TABLE t1; SET note_verbosity=DEFAULT; + + +--echo # +--echo # MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +--echo # + +CREATE TABLE t0 (c INT); +INSERT INTO t0 VALUES (0),(100),(200); +--source include/search_condition.inc +DROP TABLE t0; + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/mysql-test/main/type_temporal_innodb.result b/mysql-test/main/type_temporal_innodb.result index b11ea8476bd..f801baceb83 100644 --- a/mysql-test/main/type_temporal_innodb.result +++ b/mysql-test/main/type_temporal_innodb.result @@ -183,7 +183,7 @@ INSERT INTO t1 VALUES ('2024-02-29'); SELECT * FROM t1 WHERE SUBSTR(1 FROM BIT_LENGTH(f) FOR DEFAULT(f)); f Warnings: -Warning 1292 Truncated incorrect INTEGER value: '' +Warning 1292 Truncated incorrect DOUBLE value: '' DROP TABLE t1; # # End of 10.4 tests diff --git a/mysql-test/main/type_time.result b/mysql-test/main/type_time.result index 532672a095b..dc5ebc46c0f 100644 --- a/mysql-test/main/type_time.result +++ b/mysql-test/main/type_time.result @@ -2604,3 +2604,210 @@ Warning 1292 Truncated incorrect time value: '2001-01-02' DROP TABLE t2; DROP TABLE t1; SET note_verbosity=DEFAULT; +# +# Start of 10.6 tests +# +# +# MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +# +CREATE TABLE t0 (c TIME(1)); +INSERT INTO t0 VALUES ('00:00:00.0'),('00:00:00.4'),('00:00:00.6'); +# +# WHERE +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT * FROM t1 WHERE c; +c +00:00:00.4 +00:00:00.6 +SELECT * FROM t1 WHERE c IS FALSE; +c +00:00:00.0 +SELECT * FROM t1 WHERE c IS TRUE; +c +00:00:00.4 +00:00:00.6 +SELECT * FROM t1 WHERE COALESCE(c); +c +00:00:00.4 +00:00:00.6 +DROP TABLE t1; +# +# HAVING +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2; +c2 +00:00:00.4 +00:00:00.6 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS FALSE; +c2 +00:00:00.0 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS TRUE; +c2 +00:00:00.4 +00:00:00.6 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING COALESCE(c2); +c2 +00:00:00.4 +00:00:00.6 +DROP TABLE t1; +# +# := ON +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c); +c +00:00:00.4 +00:00:00.6 +00:00:00.4 +00:00:00.6 +00:00:00.4 +00:00:00.6 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS FALSE); +c +00:00:00.0 +00:00:00.0 +00:00:00.0 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS TRUE); +c +00:00:00.4 +00:00:00.6 +00:00:00.4 +00:00:00.6 +00:00:00.4 +00:00:00.6 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (COALESCE(t1.c)); +c +00:00:00.4 +00:00:00.6 +00:00:00.4 +00:00:00.6 +00:00:00.4 +00:00:00.6 +DROP TABLE t1; +# +# +# DELETE FROM [ WHERE ] +# +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c; +SELECT * FROM t1; +c +00:00:00.0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS FALSE; +SELECT * FROM t1; +c +00:00:00.4 +00:00:00.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS TRUE; +SELECT * FROM t1; +c +00:00:00.0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE COALESCE(c); +SELECT * FROM t1; +c +00:00:00.0 +DROP TABLE t1; +# +# +# UPDATE SET [ WHERE ] +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c; +SELECT * FROM t1; +c +00:00:00.0 +00:00:11.4 +00:00:11.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c IS FALSE; +SELECT * FROM t1; +c +00:00:11.0 +00:00:00.4 +00:00:00.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c IS TRUE; +SELECT * FROM t1; +c +00:00:00.0 +00:00:11.4 +00:00:11.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE COALESCE(c); +SELECT * FROM t1; +c +00:00:00.0 +00:00:11.4 +00:00:11.6 +DROP TABLE t1; +# +# +# CHECK +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c); +INSERT INTO t1 SELECT * FROM t0 WHERE NOT c; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c; +SELECT * FROM t1; +c +00:00:00.4 +00:00:00.6 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS FALSE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +SELECT * FROM t1; +c +00:00:00.0 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS TRUE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +00:00:00.4 +00:00:00.6 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(COALESCE(c)); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +00:00:00.4 +00:00:00.6 +DROP TABLE t1; +# +# +# WHEN THEN +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT c, CASE WHEN c THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +00:00:00.0 false +00:00:00.4 true +00:00:00.6 true +SELECT c, CASE WHEN COALESCE(c) THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +00:00:00.0 false +00:00:00.4 true +00:00:00.6 true +DROP TABLE t1; +DROP TABLE t0; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/type_time.test b/mysql-test/main/type_time.test index ae44427b370..3c78b913435 100644 --- a/mysql-test/main/type_time.test +++ b/mysql-test/main/type_time.test @@ -1635,3 +1635,22 @@ DELIMITER ;$$ --source unusable_keys_joins.inc DROP TABLE t1; SET note_verbosity=DEFAULT; + + +--echo # +--echo # Start of 10.6 tests +--echo # + +--echo # +--echo # MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +--echo # + +CREATE TABLE t0 (c TIME(1)); +INSERT INTO t0 VALUES ('00:00:00.0'),('00:00:00.4'),('00:00:00.6'); +--source include/search_condition.inc +DROP TABLE t0; + + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/mysql-test/main/type_timestamp.result b/mysql-test/main/type_timestamp.result index 6ff36d296fa..268670bad46 100644 --- a/mysql-test/main/type_timestamp.result +++ b/mysql-test/main/type_timestamp.result @@ -1276,9 +1276,8 @@ CREATE TABLE t1 (a TIMESTAMP(4), b TIMESTAMP DEFAULT 0) ENGINE=MyISAM; INSERT IGNORE INTO t1 VALUES ('2001-01-01','2002-01-01'),('2003-01-01','2004-01-01'); SELECT * FROM t1 WHERE DEFAULT(b) - a; a b -Warnings: -Warning 1916 Got overflow when converting '-20010101000000' to UNSIGNED INT. Value truncated -Warning 1916 Got overflow when converting '-20030101000000' to UNSIGNED INT. Value truncated +2001-01-01 00:00:00.0000 2002-01-01 00:00:00 +2003-01-01 00:00:00.0000 2004-01-01 00:00:00 SELECT LEFT('', DEFAULT(b)-a) FROM t1; LEFT('', DEFAULT(b)-a) @@ -1291,9 +1290,8 @@ CREATE TABLE t1 (a TIMESTAMP(4), b TIMESTAMP DEFAULT 0) ENGINE=MyISAM; INSERT IGNORE INTO t1 (a) VALUES ('2001-01-01'),('2003-01-01'); SELECT * FROM t1 WHERE (SELECT MIN(b) FROM t1) - a; a b -Warnings: -Warning 1916 Got overflow when converting '-20010101000000' to UNSIGNED INT. Value truncated -Warning 1916 Got overflow when converting '-20030101000000' to UNSIGNED INT. Value truncated +2001-01-01 00:00:00.0000 0000-00-00 00:00:00 +2003-01-01 00:00:00.0000 0000-00-00 00:00:00 SELECT (SELECT MIN(b) FROM t1) - a FROM t1; (SELECT MIN(b) FROM t1) - a -20010101000000.0000 diff --git a/mysql-test/main/type_varchar.result b/mysql-test/main/type_varchar.result index bcb1227a462..463dbe28b2f 100644 --- a/mysql-test/main/type_varchar.result +++ b/mysql-test/main/type_varchar.result @@ -1181,3 +1181,251 @@ Warnings: Note 1105 Cannot use key `i` part[0] for lookup: `test`.`t1`.`i` of type `char` < "10" of type `int` DROP TABLE t1; SET note_verbosity=DEFAULT; +# +# MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +# +CREATE TABLE IF NOT EXISTS t0 +( +c0_1 VARCHAR(200), +c0_2 TEXT +); +INSERT INTO t0 VALUES ('0.67882431850', '97966'); +SELECT (CONCAT(t0.c0_1, t0.c0_2)) AS ref0 FROM t0 WHERE (CONCAT(t0.c0_1, t0.c0_2)); +ref0 +0.6788243185097966 +DROP TABLE t0; +CREATE TABLE t0 (c VARCHAR(200)); +INSERT INTO t0 VALUES ('0.0'),('0.4'),('0.6'); +# +# WHERE +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT * FROM t1 WHERE c; +c +0.4 +0.6 +SELECT * FROM t1 WHERE c IS FALSE; +c +0.0 +SELECT * FROM t1 WHERE c IS TRUE; +c +0.4 +0.6 +SELECT * FROM t1 WHERE COALESCE(c); +c +0.4 +0.6 +SELECT * FROM t1 WHERE CONCAT(c); +c +0.4 +0.6 +SELECT * FROM t1 WHERE LEFT(c,100); +c +0.4 +0.6 +DROP TABLE t1; +# +# HAVING +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2; +c2 +0.4 +0.6 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS FALSE; +c2 +0.0 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS TRUE; +c2 +0.4 +0.6 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING COALESCE(c2); +c2 +0.4 +0.6 +SELECT CONCAT(c,'0') AS c2 FROM t1 GROUP BY c2 HAVING LEFT(c2,100); +c2 +0.40 +0.60 +DROP TABLE t1; +# +# := ON +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c); +c +0.4 +0.6 +0.4 +0.6 +0.4 +0.6 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS FALSE); +c +0.0 +0.0 +0.0 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS TRUE); +c +0.4 +0.6 +0.4 +0.6 +0.4 +0.6 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (COALESCE(t1.c)); +c +0.4 +0.6 +0.4 +0.6 +0.4 +0.6 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (CONCAT(t1.c)); +c +0.4 +0.6 +0.4 +0.6 +0.4 +0.6 +DROP TABLE t1; +# +# +# DELETE FROM [ WHERE ] +# +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c; +SELECT * FROM t1; +c +0.0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS FALSE; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS TRUE; +SELECT * FROM t1; +c +0.0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE COALESCE(c); +SELECT * FROM t1; +c +0.0 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE CONCAT(c); +SELECT * FROM t1; +c +0.0 +DROP TABLE t1; +# +# +# UPDATE SET [ WHERE ] +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c; +SELECT * FROM t1; +c +0.0 +11.4 +11.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c IS FALSE; +SELECT * FROM t1; +c +11 +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE c IS TRUE; +SELECT * FROM t1; +c +0.0 +11.4 +11.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE COALESCE(c); +SELECT * FROM t1; +c +0.0 +11.4 +11.6 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=c+11 WHERE COALESCE(c); +SELECT * FROM t1; +c +0.0 +11.4 +11.6 +DROP TABLE t1; +# +# +# CHECK +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c); +INSERT INTO t1 SELECT * FROM t0 WHERE NOT c; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS FALSE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +SELECT * FROM t1; +c +0.0 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS TRUE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(COALESCE(c)); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +0.4 +0.6 +DROP TABLE t1; +# +# +# WHEN THEN +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT c, CASE WHEN c THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +0.0 false +0.4 true +0.6 true +SELECT c, CASE WHEN COALESCE(c) THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +0.0 false +0.4 true +0.6 true +DROP TABLE t1; +DROP TABLE t0; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/type_varchar.test b/mysql-test/main/type_varchar.test index feb270272c1..b5ffc87ceed 100644 --- a/mysql-test/main/type_varchar.test +++ b/mysql-test/main/type_varchar.test @@ -498,3 +498,27 @@ EXPLAIN DELETE FROM t1 WHERE i < 10; DROP TABLE t1; SET note_verbosity=DEFAULT; + + +--echo # +--echo # MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +--echo # + +CREATE TABLE IF NOT EXISTS t0 +( + c0_1 VARCHAR(200), + c0_2 TEXT +); +INSERT INTO t0 VALUES ('0.67882431850', '97966'); +SELECT (CONCAT(t0.c0_1, t0.c0_2)) AS ref0 FROM t0 WHERE (CONCAT(t0.c0_1, t0.c0_2)); +DROP TABLE t0; + +CREATE TABLE t0 (c VARCHAR(200)); +INSERT INTO t0 VALUES ('0.0'),('0.4'),('0.6'); +--source include/search_condition.inc +DROP TABLE t0; + + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/plugin/type_inet/item_inetfunc.cc b/plugin/type_inet/item_inetfunc.cc index 1bdae5e896b..d92d51fa598 100644 --- a/plugin/type_inet/item_inetfunc.cc +++ b/plugin/type_inet/item_inetfunc.cc @@ -214,7 +214,7 @@ String *Item_func_inet6_ntoa::val_str_ascii(String *buffer) Checks if the passed string represents an IPv4-address. */ -longlong Item_func_is_ipv4::val_int() +bool Item_func_is_ipv4::val_bool() { DBUG_ASSERT(fixed()); String_ptr_and_buffer tmp(args[0]); @@ -242,7 +242,7 @@ public: Checks if the passed string represents an IPv6-address. */ -longlong Item_func_is_ipv6::val_int() +bool Item_func_is_ipv6::val_bool() { DBUG_ASSERT(fixed()); String_ptr_and_buffer tmp(args[0]); @@ -253,7 +253,7 @@ longlong Item_func_is_ipv6::val_int() Checks if the passed IPv6-address is an IPv4-compat IPv6-address. */ -longlong Item_func_is_ipv4_compat::val_int() +bool Item_func_is_ipv4_compat::val_bool() { IP6 ip6(args[0]); return !ip6.is_null() && ip6.is_v4compat(); @@ -264,7 +264,7 @@ longlong Item_func_is_ipv4_compat::val_int() Checks if the passed IPv6-address is an IPv4-mapped IPv6-address. */ -longlong Item_func_is_ipv4_mapped::val_int() +bool Item_func_is_ipv4_mapped::val_bool() { IP6 ip6(args[0]); return !ip6.is_null() && ip6.is_v4mapped(); diff --git a/plugin/type_inet/item_inetfunc.h b/plugin/type_inet/item_inetfunc.h index ec38bec3d3a..73aed8c1f44 100644 --- a/plugin/type_inet/item_inetfunc.h +++ b/plugin/type_inet/item_inetfunc.h @@ -181,7 +181,7 @@ public: Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - longlong val_int() override; + bool val_bool() override; }; @@ -204,7 +204,7 @@ public: Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - longlong val_int() override; + bool val_bool() override; }; @@ -225,7 +225,7 @@ public: } Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - longlong val_int() override; + bool val_bool() override; }; @@ -246,7 +246,7 @@ public: } Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - longlong val_int() override; + bool val_bool() override; }; #endif // ITEM_INETFUNC_INCLUDED diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_search_condition.result b/plugin/type_inet/mysql-test/type_inet/type_inet6_search_condition.result new file mode 100644 index 00000000000..7521b4f4d45 --- /dev/null +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_search_condition.result @@ -0,0 +1,167 @@ +# +# Start of 10.6 tests +# +# +# MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +# +CREATE TABLE t0 (c INET6); +INSERT INTO t0 VALUES ('::'),('::1'),('::2'); +# +# WHERE +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT * FROM t1 WHERE c IS FALSE; +c +:: +SELECT * FROM t1 WHERE c IS TRUE; +c +::1 +::2 +SELECT * FROM t1 WHERE COALESCE(c); +c +::1 +::2 +DROP TABLE t1; +# +# HAVING +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS FALSE; +c2 +:: +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING c2 IS TRUE; +c2 +::1 +::2 +SELECT COALESCE(c,c) AS c2 FROM t1 GROUP BY c2 HAVING COALESCE(c2); +c2 +::1 +::2 +DROP TABLE t1; +# +# := ON +# +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS FALSE); +c +:: +:: +:: +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (t1.c IS TRUE); +c +::1 +::2 +::1 +::2 +::1 +::2 +SELECT t1.c FROM t1 JOIN t1 AS t2 ON (COALESCE(t1.c)); +c +::1 +::2 +::1 +::2 +::1 +::2 +DROP TABLE t1; +# +# +# DELETE FROM [ WHERE ] +# +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS FALSE; +SELECT * FROM t1; +c +::1 +::2 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE c IS TRUE; +SELECT * FROM t1; +c +:: +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +DELETE FROM t1 WHERE COALESCE(c); +SELECT * FROM t1; +c +:: +DROP TABLE t1; +# +# +# UPDATE SET [ WHERE ] +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=concat(c,'77') WHERE c IS FALSE; +SELECT * FROM t1; +c +::77 +::1 +::2 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=concat(c,'77') WHERE c IS TRUE; +SELECT * FROM t1; +c +:: +::177 +::277 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT * FROM t0; +UPDATE t1 SET c=concat(c,'77') WHERE COALESCE(c); +SELECT * FROM t1; +c +:: +::177 +::277 +DROP TABLE t1; +# +# +# CHECK +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS FALSE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +SELECT * FROM t1; +c +:: +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(c IS TRUE); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +::1 +::2 +DROP TABLE t1; +CREATE TABLE t1 LIKE t0; +ALTER TABLE t1 ADD CONSTRAINT check0 CHECK(COALESCE(c)); +INSERT INTO t1 SELECT * FROM t0 WHERE c IS FALSE; +ERROR 23000: CONSTRAINT `check0` failed for `test`.`t1` +INSERT INTO t1 SELECT * FROM t0 WHERE c IS TRUE; +SELECT * FROM t1; +c +::1 +::2 +DROP TABLE t1; +# +# +# WHEN THEN +CREATE TABLE t1 AS SELECT * FROM t0; +SELECT c, CASE WHEN c THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +:: false +::1 true +::2 true +SELECT c, CASE WHEN COALESCE(c) THEN 'true' ELSE 'false' END AS c2 FROM t1; +c c2 +:: false +::1 true +::2 true +DROP TABLE t1; +DROP TABLE t0; +# +# End of 10.6 tests +# diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_search_condition.test b/plugin/type_inet/mysql-test/type_inet/type_inet6_search_condition.test new file mode 100644 index 00000000000..4df2dfb6b78 --- /dev/null +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_search_condition.test @@ -0,0 +1,16 @@ +--echo # +--echo # Start of 10.6 tests +--echo # + +--echo # +--echo # MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query +--echo # + +CREATE TABLE t0 (c INET6); +INSERT INTO t0 VALUES ('::'),('::1'),('::2'); +--source include/search_condition.inc +DROP TABLE t0; + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/plugin/type_inet/sql_type_inet.h b/plugin/type_inet/sql_type_inet.h index 2c1865a7cef..7e89fe8df08 100644 --- a/plugin/type_inet/sql_type_inet.h +++ b/plugin/type_inet/sql_type_inet.h @@ -39,6 +39,10 @@ public: using FixedBinTypeStorage::FixedBinTypeStorage; bool ascii_to_fbt(const char *str, size_t str_length); size_t to_string(char *dst, size_t dstsize) const; + bool to_bool() const + { + return !only_zero_bytes(m_buffer, sizeof(m_buffer)); + } static const Name &default_value(); }; diff --git a/sql/handler.cc b/sql/handler.cc index a21556d8181..b9294180210 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6899,7 +6899,7 @@ extern "C" check_result_t handler_index_cond_check(void* h_arg) if (h->end_range && h->compare_key2(h->end_range) > 0) return CHECK_OUT_OF_RANGE; h->increment_statistics(&SSV::ha_icp_attempts); - if ((res= h->pushed_idx_cond->val_int()? CHECK_POS : CHECK_NEG) == + if ((res= h->pushed_idx_cond->val_bool()? CHECK_POS : CHECK_NEG) == CHECK_POS) h->increment_statistics(&SSV::ha_icp_match); return res; diff --git a/sql/item.cc b/sql/item.cc index 20289c317a3..2f1cc9014fd 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3424,6 +3424,7 @@ double Item_field::val_real() longlong Item_field::val_int() { + DBUG_ASSERT(!is_cond()); DBUG_ASSERT(fixed()); if ((null_value=field->is_null())) return 0; @@ -4032,6 +4033,7 @@ double Item_string::val_real() */ longlong Item_string::val_int() { + DBUG_ASSERT(!is_cond()); return longlong_from_string_with_check(&str_value); } @@ -4042,6 +4044,12 @@ my_decimal *Item_string::val_decimal(my_decimal *decimal_value) } +bool Item_null::val_bool() +{ + null_value= true; + return false; +} + double Item_null::val_real() { null_value=1; @@ -4049,6 +4057,7 @@ double Item_null::val_real() } longlong Item_null::val_int() { + DBUG_ASSERT(!is_cond()); null_value=1; return 0; } @@ -7002,6 +7011,16 @@ int Item::save_int_in_field(Field *field, bool no_conversions) } +int Item::save_bool_in_field(Field *field, bool no_conversions) +{ + bool nr= val_bool(); + if (null_value) + return set_field_to_null_with_conversions(field, no_conversions); + field->set_notnull(); + return field->store((longlong) nr, false/*unsigned_flag*/); +} + + int Item::save_in_field(Field *field, bool no_conversions) { int error= type_handler()->Item_save_in_field(this, field, no_conversions); @@ -8910,7 +8929,8 @@ Item_cache_wrapper::Item_cache_wrapper(THD *thd, Item *item_arg): Type_std_attributes::set(orig_item); base_flags|= (item_base_t::FIXED | - (orig_item->base_flags & item_base_t::MAYBE_NULL)); + (orig_item->base_flags & + (item_base_t::MAYBE_NULL | item_base_t::IS_COND))); with_flags|= orig_item->with_flags; name= item_arg->name; @@ -10322,6 +10342,18 @@ void Item_cache::set_null() } +bool Item_cache_bool::cache_value() +{ + if (!example) + return false; + value_cached= true; + value= example->val_bool_result(); + null_value_inside= null_value= example->null_value; + unsigned_flag= false; + return true; +} + + bool Item_cache_int::cache_value() { if (!example) diff --git a/sql/item.h b/sql/item.h index 8ca9e31d4bb..3ae206370f0 100644 --- a/sql/item.h +++ b/sql/item.h @@ -776,8 +776,12 @@ enum class item_base_t : item_flags_t FIXED= (1<<2), // Was fixed with fix_fields(). IS_EXPLICIT_NAME= (1<<3), // The name of this Item was set by the user // (or was auto generated otherwise) - IS_IN_WITH_CYCLE= (1<<4) // This item is in CYCLE clause + IS_IN_WITH_CYCLE= (1<<4), // This item is in CYCLE clause // of WITH. + IS_COND= (1<<5) // The item is used as . + // Must be evaluated using val_bool(). + // Note, not all items used as a search + // condition set this flag yet. }; @@ -1092,6 +1096,8 @@ public: { return (bool) (base_flags & item_base_t::IS_EXPLICIT_NAME); } inline bool is_in_with_cycle() const { return (bool) (base_flags & item_base_t::IS_IN_WITH_CYCLE); } + inline bool is_cond() const + { return (bool) (base_flags & item_base_t::IS_COND); } inline bool with_sp_var() const { return (bool) (with_flags & item_with_t::SP_VAR); } @@ -1767,6 +1773,7 @@ public: int save_str_in_field(Field *field, bool no_conversions); int save_real_in_field(Field *field, bool no_conversions); int save_int_in_field(Field *field, bool no_conversions); + int save_bool_in_field(Field *field, bool no_conversions); int save_decimal_in_field(Field *field, bool no_conversions); int save_str_value_in_field(Field *field, String *result); @@ -3105,6 +3112,7 @@ public: DBUG_ASSERT(0); return this; } + bool val_bool() override = 0; }; @@ -3956,6 +3964,7 @@ public: } Type type() const override { return NULL_ITEM; } bool vcol_assignment_allowed_value() const override { return true; } + bool val_bool() override; double val_real() override; longlong val_int() override; String *val_str(String *str) override; @@ -4515,7 +4524,12 @@ public: Field *create_field_for_create_select(MEM_ROOT *root, TABLE *table) override { return tmp_table_field_from_field_type(root, table); } const longlong *const_ptr_longlong() const override { return &value; } - longlong val_int() override { return value; } + bool val_bool() override { return value != 0; } + longlong val_int() override + { + DBUG_ASSERT(!is_cond()); + return value; + } longlong val_int_min() const override { return value; } double val_real() override { return (double) value; } my_decimal *val_decimal(my_decimal *) override; @@ -4630,8 +4644,13 @@ public: const Type_handler *type_handler() const override { return &type_handler_newdecimal; } + bool val_bool() override + { return decimal_value.to_bool(); } longlong val_int() override - { return decimal_value.to_longlong(unsigned_flag); } + { + DBUG_ASSERT(!is_cond()); + return decimal_value.to_longlong(unsigned_flag); + } double val_real() override { return decimal_value.to_double(); } String *val_str(String *to) override @@ -4680,9 +4699,11 @@ public: const Type_handler *type_handler() const override { return &type_handler_double; } const double *const_ptr_double() const override { return &value; } + bool val_bool() override { return value != 0.0; } double val_real() override { return value; } longlong val_int() override { + DBUG_ASSERT(!is_cond()); if (value <= (double) LONGLONG_MIN) { return LONGLONG_MIN; @@ -4803,6 +4824,7 @@ public: { str_value.print(to); } + bool val_bool() override { return val_real() != 0.0; } double val_real() override; longlong val_int() override; const String *const_ptr_string() const override { return &str_value; } @@ -5062,12 +5084,17 @@ public: const Type_handler *type_handler() const override { return &type_handler_hex_hybrid; } decimal_digits_t decimal_precision() const override; + bool val_bool() override + { + return longlong_from_hex_hybrid(str_value.ptr(), str_value.length()) != 0; + } double val_real() override { return (double) (ulonglong) Item_hex_hybrid::val_int(); } longlong val_int() override { + DBUG_ASSERT(!is_cond()); return longlong_from_hex_hybrid(str_value.ptr(), str_value.length()); } my_decimal *val_decimal(my_decimal *decimal_value) override @@ -5103,8 +5130,13 @@ public: Item_hex_string(THD *thd): Item_hex_constant(thd) {} Item_hex_string(THD *thd, const char *str, size_t str_length): Item_hex_constant(thd, str, str_length) {} + bool val_bool() override + { + return double_from_string_with_check(&str_value) != 0.0; + } longlong val_int() override { + DBUG_ASSERT(!is_cond()); return longlong_from_string_with_check(&str_value); } double val_real() override @@ -5152,8 +5184,13 @@ public: Timestamp_or_zero_datetime_native native(m_value, decimals); return native.save_in_field(field, decimals); } + bool val_bool() override + { + return m_value.to_bool(); + } longlong val_int() override { + DBUG_ASSERT(!is_cond()); return m_value.to_datetime(current_thd).to_longlong(); } double val_real() override @@ -5252,8 +5289,13 @@ public: return cached_time.get_mysql_time(); } Item *clone_item(THD *thd) const override; + bool val_bool() override + { + return update_null() ? false : cached_time.to_bool(); + } longlong val_int() override { + DBUG_ASSERT(!is_cond()); return update_null() ? 0 : cached_time.to_longlong(); } double val_real() override @@ -5302,7 +5344,15 @@ public: return cached_time.get_mysql_time(); } Item *clone_item(THD *thd) const override; - longlong val_int() override { return cached_time.to_longlong(); } + bool val_bool() override + { + return cached_time.to_bool(); + } + longlong val_int() override + { + DBUG_ASSERT(!is_cond()); + return cached_time.to_longlong(); + } double val_real() override { return cached_time.to_double(); } String *val_str(String *to) override { return cached_time.to_string(to, decimals); } @@ -5356,8 +5406,13 @@ public: return cached_time.get_mysql_time(); } Item *clone_item(THD *thd) const override; + bool val_bool() override + { + return update_null() ? false : cached_time.to_bool(); + } longlong val_int() override { + DBUG_ASSERT(!is_cond()); return update_null() ? 0 : cached_time.to_longlong(); } double val_real() override @@ -7266,6 +7321,7 @@ public: { example= item; Type_std_attributes::set(item); + base_flags|= item->base_flags & item_base_t::IS_COND; if (item->type() == FIELD_ITEM) cached_field= ((Item_field *)item)->field; return 0; @@ -7409,6 +7465,27 @@ public: }; +class Item_cache_bool: public Item_cache_int +{ +public: + Item_cache_bool(THD *thd) + :Item_cache_int(thd, &type_handler_bool) + { } + bool cache_value() override; + bool val_bool() override + { + return !has_value() ? false : (bool) value; + } + longlong val_int() override + { + DBUG_ASSERT(!is_cond()); + return Item_cache_bool::val_bool(); + } + Item *do_get_copy(THD *thd) const override + { return get_item_copy(thd, this); } +}; + + class Item_cache_year: public Item_cache_int { public: diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index d1c797ae73b..8bc04d07dfd 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -197,7 +197,7 @@ static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE) NULL if some arg is NULL. */ -longlong Item_func_not::val_int() +bool Item_func_not::val_bool() { DBUG_ASSERT(fixed()); bool value= args[0]->val_bool(); @@ -216,7 +216,7 @@ void Item_func_not::print(String *str, enum_query_type query_type) */ -longlong Item_func_not_all::val_int() +bool Item_func_not_all::val_bool() { DBUG_ASSERT(fixed()); bool value= args[0]->val_bool(); @@ -257,7 +257,7 @@ void Item_func_not_all::print(String *str, enum_query_type query_type) returns some rows it return same value as argument (TRUE/FALSE). */ -longlong Item_func_nop_all::val_int() +bool Item_func_nop_all::val_bool() { DBUG_ASSERT(fixed()); longlong value= args[0]->val_int(); @@ -1246,12 +1246,6 @@ bool Item_func_truth::val_bool() } -longlong Item_func_truth::val_int() -{ - return (val_bool() ? 1 : 0); -} - - bool Item_in_optimizer::is_top_level_item() const { return args[1]->is_top_level_item(); @@ -1646,17 +1640,17 @@ void Item_in_optimizer::get_cache_parameters(List ¶meters) @see Item_is_not_null_test::val_int() */ -longlong Item_in_optimizer::val_int() +bool Item_in_optimizer::val_bool() { bool tmp; DBUG_ASSERT(fixed()); cache->store(args[0]); cache->cache_value(); - DBUG_ENTER(" Item_in_optimizer::val_int"); + DBUG_ENTER(" Item_in_optimizer::val_bool"); if (invisible_mode()) { - longlong res= args[1]->val_int(); + longlong res= args[1]->val_bool(); null_value= args[1]->null_value; DBUG_PRINT("info", ("pass trough")); DBUG_RETURN(res); @@ -1755,7 +1749,7 @@ void Item_in_optimizer::cleanup() bool Item_in_optimizer::is_null() { - val_int(); + val_bool(); return null_value; } @@ -1851,7 +1845,7 @@ bool Item_in_optimizer::is_expensive() } -longlong Item_func_eq::val_int() +bool Item_func_eq::val_bool() { DBUG_ASSERT(fixed()); int value= cmp.compare(); @@ -1879,13 +1873,13 @@ bool Item_func_equal::fix_length_and_dec() return rc; } -longlong Item_func_equal::val_int() +bool Item_func_equal::val_bool() { DBUG_ASSERT(fixed()); return cmp.compare(); } -longlong Item_func_ne::val_int() +bool Item_func_ne::val_bool() { DBUG_ASSERT(fixed()); int value= cmp.compare(); @@ -1893,7 +1887,7 @@ longlong Item_func_ne::val_int() } -longlong Item_func_ge::val_int() +bool Item_func_ge::val_bool() { DBUG_ASSERT(fixed()); int value= cmp.compare(); @@ -1901,14 +1895,14 @@ longlong Item_func_ge::val_int() } -longlong Item_func_gt::val_int() +bool Item_func_gt::val_bool() { DBUG_ASSERT(fixed()); int value= cmp.compare(); return value > 0 ? 1 : 0; } -longlong Item_func_le::val_int() +bool Item_func_le::val_bool() { DBUG_ASSERT(fixed()); int value= cmp.compare(); @@ -1916,7 +1910,7 @@ longlong Item_func_le::val_int() } -longlong Item_func_lt::val_int() +bool Item_func_lt::val_bool() { DBUG_ASSERT(fixed()); int value= cmp.compare(); @@ -4881,7 +4875,7 @@ void Item_func_in::print(String *str, enum_query_type query_type) Value of the function */ -longlong Item_func_in::val_int() +bool Item_func_in::val_bool() { DBUG_ASSERT(fixed()); if (array) @@ -5637,7 +5631,7 @@ void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding) */ -longlong Item_cond_and::val_int() +bool Item_cond_and::val_bool() { DBUG_ASSERT(fixed()); List_iterator_fast li(list); @@ -5655,7 +5649,7 @@ longlong Item_cond_and::val_int() } -longlong Item_cond_or::val_int() +bool Item_cond_or::val_bool() { DBUG_ASSERT(fixed()); List_iterator_fast li(list); @@ -5732,7 +5726,7 @@ bool Item_func_null_predicate::count_sargable_conds(void *arg) } -longlong Item_func_isnull::val_int() +bool Item_func_isnull::val_bool() { DBUG_ASSERT(fixed()); if (const_item() && !args[0]->maybe_null()) @@ -5765,7 +5759,7 @@ void Item_func_isnull::print(String *str, enum_query_type query_type) } -longlong Item_is_not_null_test::val_int() +bool Item_is_not_null_test::val_bool() { DBUG_ASSERT(fixed()); DBUG_ENTER("Item_is_not_null_test::val_int"); @@ -5793,7 +5787,7 @@ void Item_is_not_null_test::update_used_tables() } -longlong Item_func_isnotnull::val_int() +bool Item_func_isnotnull::val_bool() { DBUG_ASSERT(fixed()); return args[0]->is_null() ? 0 : 1; @@ -5832,7 +5826,7 @@ void Item_func_like::print(String *str, enum_query_type query_type) } -longlong Item_func_like::val_int() +bool Item_func_like::val_bool() { DBUG_ASSERT(fixed()); DBUG_ASSERT(escape != ESCAPE_NOT_INITIALIZED); @@ -6361,7 +6355,7 @@ Item_func_regex::fix_length_and_dec() } -longlong Item_func_regex::val_int() +bool Item_func_regex::val_bool() { DBUG_ASSERT(fixed()); if ((null_value= re.recompile(args[1]))) @@ -6635,7 +6629,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const very fast to use. */ -longlong Item_func_xor::val_int() +bool Item_func_xor::val_bool() { DBUG_ASSERT(fixed()); int result= 0; @@ -7418,7 +7412,7 @@ bool Item_equal::count_sargable_conds(void *arg) 1 otherwise */ -longlong Item_equal::val_int() +bool Item_equal::val_bool() { if (cond_false) return 0; @@ -7628,7 +7622,7 @@ Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item) } -longlong Item_func_dyncol_check::val_int() +bool Item_func_dyncol_check::val_bool() { char buff[STRING_BUFFER_USUAL_SIZE]; String tmp(buff, sizeof(buff), &my_charset_bin); @@ -7656,7 +7650,7 @@ null: return 0; } -longlong Item_func_dyncol_exists::val_int() +bool Item_func_dyncol_exists::val_bool() { char buff[STRING_BUFFER_USUAL_SIZE], nmstrbuf[11]; String tmp(buff, sizeof(buff), &my_charset_bin), diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 1b6b05b5da0..d680945826d 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -242,6 +242,12 @@ public: const Type_handler *fixed_type_handler() const override { return &type_handler_bool; } CHARSET_INFO *compare_collation() const override { return NULL; } + longlong val_int() override final + { + DBUG_ASSERT(!is_cond()); + return val_bool(); + } + bool val_bool() override= 0; bool fix_length_and_dec() override { decimals=0; max_length=1; return FALSE; } decimal_digits_t decimal_precision() const override { return 1; } bool need_parentheses_in_default() override { return true; } @@ -257,7 +263,6 @@ class Item_func_truth : public Item_bool_func { public: bool val_bool() override; - longlong val_int() override; bool fix_length_and_dec() override; void print(String *str, enum_query_type query_type) override; enum precedence precedence() const override { return CMP_PRECEDENCE; } @@ -407,7 +412,7 @@ public: bool fix_left(THD *thd); table_map not_null_tables() const override { return 0; } bool is_null() override; - longlong val_int() override; + bool val_bool() override; void cleanup() override; enum Functype functype() const override { return IN_OPTIMIZER_FUNC; } LEX_CSTRING func_name_cstring() const override @@ -638,7 +643,7 @@ public: enum precedence precedence() const override { return XOR_PRECEDENCE; } void print(String *str, enum_query_type query_type) override { Item_func::print_op(str, query_type); } - longlong val_int() override; + bool val_bool() override; bool find_not_null_fields(table_map allowed) override { return false; } Item *neg_transformer(THD *thd) override; Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) override @@ -658,7 +663,7 @@ public: Item_bool_func(thd, a), abort_on_null(FALSE) {} void top_level_item() override { abort_on_null= 1; } bool is_top_level_item() const override { return abort_on_null; } - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return NOT_FUNC; } LEX_CSTRING func_name_cstring() const override { @@ -711,7 +716,7 @@ class Item_func_trig_cond: public Item_bool_func public: Item_func_trig_cond(THD *thd, Item *a, bool *f): Item_bool_func(thd, a) { trig_var= f; } - longlong val_int() override { return *trig_var ? args[0]->val_int() : 1; } + bool val_bool() override { return *trig_var ? args[0]->val_bool() : true; } enum Functype functype() const override { return TRIG_COND_FUNC; }; LEX_CSTRING func_name_cstring() const override { @@ -740,7 +745,7 @@ public: Item_func_not(thd, a), test_sum_item(0), test_sub_item(0), show(0) {} table_map not_null_tables() const override { return 0; } - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return NOT_ALL_FUNC; } LEX_CSTRING func_name_cstring() const override { @@ -766,7 +771,7 @@ class Item_func_nop_all :public Item_func_not_all public: Item_func_nop_all(THD *thd, Item *a): Item_func_not_all(thd, a) {} - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("") }; @@ -786,7 +791,7 @@ public: Item_bool_rowready_func2(thd, a, b), abort_on_null(false), in_equality_no(UINT_MAX) {} - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return EQ_FUNC; } enum Functype rev_functype() const override { return EQ_FUNC; } cond_result eq_cmp_result() const override { return COND_TRUE; } @@ -828,7 +833,7 @@ class Item_func_equal final :public Item_bool_rowready_func2 public: Item_func_equal(THD *thd, Item *a, Item *b): Item_bool_rowready_func2(thd, a, b) {} - longlong val_int() override; + bool val_bool() override; bool fix_length_and_dec() override; table_map not_null_tables() const override { return 0; } bool find_not_null_fields(table_map allowed) override { return false; } @@ -858,7 +863,7 @@ class Item_func_ge :public Item_bool_rowready_func2 public: Item_func_ge(THD *thd, Item *a, Item *b): Item_bool_rowready_func2(thd, a, b) {}; - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return GE_FUNC; } enum Functype rev_functype() const override { return LE_FUNC; } cond_result eq_cmp_result() const override { return COND_TRUE; } @@ -878,7 +883,7 @@ class Item_func_gt :public Item_bool_rowready_func2 public: Item_func_gt(THD *thd, Item *a, Item *b): Item_bool_rowready_func2(thd, a, b) {}; - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return GT_FUNC; } enum Functype rev_functype() const override { return LT_FUNC; } cond_result eq_cmp_result() const override { return COND_FALSE; } @@ -898,7 +903,7 @@ class Item_func_le :public Item_bool_rowready_func2 public: Item_func_le(THD *thd, Item *a, Item *b): Item_bool_rowready_func2(thd, a, b) {}; - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return LE_FUNC; } enum Functype rev_functype() const override { return GE_FUNC; } cond_result eq_cmp_result() const override { return COND_TRUE; } @@ -918,7 +923,7 @@ class Item_func_lt :public Item_bool_rowready_func2 public: Item_func_lt(THD *thd, Item *a, Item *b): Item_bool_rowready_func2(thd, a, b) {} - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return LT_FUNC; } enum Functype rev_functype() const override { return GT_FUNC; } cond_result eq_cmp_result() const override { return COND_FALSE; } @@ -941,7 +946,7 @@ protected: public: Item_func_ne(THD *thd, Item *a, Item *b): Item_bool_rowready_func2(thd, a, b) {} - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return NE_FUNC; } enum Functype rev_functype() const override { return NE_FUNC; } cond_result eq_cmp_result() const override { return COND_FALSE; } @@ -1015,7 +1020,7 @@ public: String value0,value1,value2; Item_func_between(THD *thd, Item *a, Item *b, Item *c): Item_func_opt_neg(thd, a, b, c) { } - longlong val_int() override + bool val_bool() override { DBUG_ASSERT(fixed()); return m_comparator.type_handler()->Item_func_between_val_int(this); @@ -2570,7 +2575,7 @@ public: array(0), have_null(0), arg_types_compatible(FALSE), emb_on_expr_nest(0) { } - longlong val_int() override; + bool val_bool() override; bool fix_fields(THD *, Item **) override; bool fix_length_and_dec() override; bool compatible_types_scalar_bisection_possible() @@ -2764,7 +2769,7 @@ class Item_func_isnull :public Item_func_null_predicate { public: Item_func_isnull(THD *thd, Item *a): Item_func_null_predicate(thd, a) {} - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return ISNULL_FUNC; } LEX_CSTRING func_name_cstring() const override { @@ -2828,7 +2833,7 @@ public: Item_func_isnull(thd, a), owner(ow) {} enum Functype functype() const override { return ISNOTNULLTEST_FUNC; } - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("") }; @@ -2851,7 +2856,7 @@ public: Item_func_isnotnull(THD *thd, Item *a): Item_func_null_predicate(thd, a), abort_on_null(0) { } - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return ISNOTNULL_FUNC; } LEX_CSTRING func_name_cstring() const override { @@ -2916,7 +2921,7 @@ public: bool get_negated() const { return negated; } // Used by ColumnStore Sql_mode_dependency value_depends_on_sql_mode() const override; - longlong val_int() override; + bool val_bool() override; enum Functype functype() const override { return LIKE_FUNC; } void print(String *str, enum_query_type query_type) override; CHARSET_INFO *compare_collation() const override @@ -3116,7 +3121,7 @@ public: re.cleanup(); DBUG_VOID_RETURN; } - longlong val_int() override; + bool val_bool() override; bool fix_length_and_dec() override; LEX_CSTRING func_name_cstring() const override { @@ -3424,7 +3429,7 @@ public: bool only_intersected); void update_const(THD *thd); enum Functype functype() const override { return MULT_EQUAL_FUNC; } - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("multiple equal") }; @@ -3605,7 +3610,7 @@ public: Item_cond_and(THD *thd, Item_cond_and *item): Item_cond(thd, item) {} Item_cond_and(THD *thd, List &list_arg): Item_cond(thd, list_arg) {} enum Functype functype() const override { return COND_AND_FUNC; } - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("and") }; @@ -3645,7 +3650,7 @@ public: Item_cond_or(THD *thd, Item_cond_or *item): Item_cond(thd, item) {} Item_cond_or(THD *thd, List &list_arg): Item_cond(thd, list_arg) {} enum Functype functype() const override { return COND_OR_FUNC; } - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("or") }; @@ -3663,7 +3668,7 @@ class Item_func_dyncol_check :public Item_bool_func { public: Item_func_dyncol_check(THD *thd, Item *str): Item_bool_func(thd, str) {} - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("column_check") }; @@ -3679,7 +3684,7 @@ class Item_func_dyncol_exists :public Item_bool_func public: Item_func_dyncol_exists(THD *thd, Item *str, Item *num): Item_bool_func(thd, str, num) {} - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("column_exists") }; @@ -3718,7 +3723,7 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("%ISOPEN") }; return name; } - longlong val_int() override; + bool val_bool() override; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3737,7 +3742,7 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("%FOUND") }; return name; } - longlong val_int() override; + bool val_bool() override; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -3756,7 +3761,7 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("%NOTFOUND") }; return name; } - longlong val_int() override; + bool val_bool() override; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/sql/item_func.cc b/sql/item_func.cc index 02e9798b6db..6959d6f72a4 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -7031,7 +7031,7 @@ sp_cursor *Cursor_ref::get_open_cursor_or_error() } -longlong Item_func_cursor_isopen::val_int() +bool Item_func_cursor_isopen::val_bool() { sp_cursor *c= current_thd->spcont->get_cursor(m_cursor_offset); DBUG_ASSERT(c != NULL); @@ -7039,14 +7039,14 @@ longlong Item_func_cursor_isopen::val_int() } -longlong Item_func_cursor_found::val_int() +bool Item_func_cursor_found::val_bool() { sp_cursor *c= get_open_cursor_or_error(); return !(null_value= (!c || c->fetch_count() == 0)) && c->found(); } -longlong Item_func_cursor_notfound::val_int() +bool Item_func_cursor_notfound::val_bool() { sp_cursor *c= get_open_cursor_or_error(); return !(null_value= (!c || c->fetch_count() == 0)) && !c->found(); diff --git a/sql/item_func.h b/sql/item_func.h index bf3582ded03..db9dc5d2766 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -462,7 +462,7 @@ public: void convert_const_compared_to_int_field(THD *thd); Item_func *get_item_func() override { return this; } bool is_simplified_cond_processor(void *) override - { return const_item() && !val_int(); } + { return const_item() && !val_bool(); } }; @@ -974,6 +974,7 @@ public: } longlong val_int() override { + DBUG_ASSERT(!is_cond()); DBUG_ASSERT(fixed()); return Item_func_hybrid_field_type::type_handler()-> Item_func_hybrid_field_type_val_int(this); diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index b286039c30f..893f9253d94 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -1153,7 +1153,7 @@ LEX_CSTRING Item_func_spatial_mbr_rel::func_name_cstring() const } -longlong Item_func_spatial_mbr_rel::val_int() +bool Item_func_spatial_mbr_rel::val_bool() { DBUG_ASSERT(fixed()); String *res1= args[0]->val_str(&tmp_value1); @@ -1361,7 +1361,7 @@ public: }; -longlong Item_func_spatial_relate::val_int() +bool Item_func_spatial_relate::val_bool() { DBUG_ENTER("Item_func_spatial_relate::val_int"); DBUG_ASSERT(fixed()); @@ -1398,7 +1398,7 @@ exit: } -longlong Item_func_spatial_precise_rel::val_int() +bool Item_func_spatial_precise_rel::val_bool() { DBUG_ENTER("Item_func_spatial_precise_rel::val_int"); DBUG_ASSERT(fixed()); @@ -2061,7 +2061,7 @@ mem_error: } -longlong Item_func_isempty::val_int() +bool Item_func_isempty::val_bool() { DBUG_ASSERT(fixed()); String tmp; diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index e13900df335..50938cc4913 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -792,7 +792,7 @@ public: Item_func_spatial_mbr_rel(THD *thd, Item *a, Item *b, enum Functype sp_rel): Item_func_spatial_rel(thd, a, b, sp_rel) { } - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } @@ -808,7 +808,7 @@ public: Item_func_spatial_precise_rel(THD *thd, Item *a, Item *b, enum Functype sp_rel): Item_func_spatial_rel(thd, a, b, sp_rel), collector() { } - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } @@ -830,7 +830,7 @@ public: Item_func_spatial_relate(THD *thd, Item *a, Item *b, Item *matrix): Item_bool_func_args_geometry_geometry(thd, a, b, matrix) { } - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("st_relate") }; @@ -945,7 +945,7 @@ class Item_func_isempty: public Item_bool_func_args_geometry public: Item_func_isempty(THD *thd, Item *a) :Item_bool_func_args_geometry(thd, a) {} - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("st_isempty") }; diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 3755b880247..9104d8263f2 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -525,7 +525,7 @@ static int path_setup_nwc(json_path_t *p, CHARSET_INFO *i_cs, } -longlong Item_func_json_valid::val_int() +bool Item_func_json_valid::val_bool() { String *js= args[0]->val_json(&tmp_value); @@ -546,7 +546,7 @@ bool Item_func_json_exists::fix_length_and_dec() } -longlong Item_func_json_exists::val_int() +bool Item_func_json_exists::val_bool() { json_engine_t je; uint array_counters[JSON_DEPTH_LIMIT]; @@ -1342,7 +1342,7 @@ static int check_contains(json_engine_t *js, json_engine_t *value) } -longlong Item_func_json_contains::val_int() +bool Item_func_json_contains::val_bool() { String *js= args[0]->val_json(&tmp_js); json_engine_t je, ve; @@ -1557,7 +1557,7 @@ return_null: } #endif /*DUMMY*/ -longlong Item_func_json_contains_path::val_int() +bool Item_func_json_contains_path::val_bool() { String *js= args[0]->val_json(&tmp_js); json_engine_t je; diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h index 8c256e01ab4..58402376426 100644 --- a/sql/item_jsonfunc.h +++ b/sql/item_jsonfunc.h @@ -82,7 +82,7 @@ protected: public: Item_func_json_valid(THD *thd, Item *json) : Item_bool_func(thd, json) {} - longlong val_int() override; + bool val_bool() override; LEX_CSTRING func_name_cstring() const override { static LEX_CSTRING name= {STRING_WITH_LEN("json_valid") }; @@ -124,7 +124,7 @@ public: bool fix_length_and_dec() override; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } - longlong val_int() override; + bool val_bool() override; }; @@ -313,7 +313,7 @@ public: return name; } bool fix_length_and_dec() override; - longlong val_int() override; + bool val_bool() override; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } }; @@ -340,7 +340,7 @@ public: } bool fix_fields(THD *thd, Item **ref) override; bool fix_length_and_dec() override; - longlong val_int() override; + bool val_bool() override; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9b121094d06..efcacd0cba0 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -150,6 +150,7 @@ double Item_str_func::val_real() longlong Item_str_func::val_int() { + DBUG_ASSERT(!is_cond()); DBUG_ASSERT(fixed()); StringBuffer<22> tmp; String *res= val_str(&tmp); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index ed99c857aaf..7683550a1f8 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -4220,7 +4220,7 @@ int subselect_uniquesubquery_engine::scan_table() } } - if (!cond || cond->val_int()) + if (!cond || cond->val_bool()) { empty_result_set= FALSE; break; @@ -4530,7 +4530,7 @@ int subselect_indexsubquery_engine::exec() table->null_row= 0; if (!table->status) { - if ((!cond || cond->val_int()) && (!having || having->val_int())) + if ((!cond || cond->val_bool()) && (!having || having->val_bool())) { empty_result_set= FALSE; if (null_finding) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 2a2d3c51811..bebb0f213f7 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -650,7 +650,10 @@ public: const Type_handler *type_handler() const override { return &type_handler_newdate; } longlong val_int() override - { return Date(this).to_longlong(); } + { + DBUG_ASSERT(!is_cond()); + return Date(this).to_longlong(); + } double val_real() override { return Date(this).to_double(); } String *val_str(String *to) override @@ -676,7 +679,10 @@ public: const Type_handler *type_handler() const override { return &type_handler_time2; } longlong val_int() override - { return Time(this).to_longlong(); } + { + DBUG_ASSERT(!is_cond()); + return Time(this).to_longlong(); + } double val_real() override { return Time(this).to_double(); } String *val_str(String *to) override @@ -698,7 +704,11 @@ public: Item_func(thd, a, b ,c) {} const Type_handler *type_handler() const override { return &type_handler_datetime2; } - longlong val_int() override { return Datetime(this).to_longlong(); } + longlong val_int() override + { + DBUG_ASSERT(!is_cond()); + return Datetime(this).to_longlong(); + } double val_real() override { return Datetime(this).to_double(); } String *val_str(String *to) override { return Datetime(this).to_string(to, decimals); } diff --git a/sql/item_vers.cc b/sql/item_vers.cc index 3f648cde890..b806b8da78b 100644 --- a/sql/item_vers.cc +++ b/sql/item_vers.cc @@ -179,8 +179,8 @@ Item_func_trt_trx_sees::Item_func_trt_trx_sees(THD *thd, Item* a, Item* b) : DBUG_ASSERT(arg_count == 2 && args[0] && args[1]); } -longlong -Item_func_trt_trx_sees::val_int() +bool +Item_func_trt_trx_sees::val_bool() { THD *thd= current_thd; DBUG_ASSERT(thd); diff --git a/sql/item_vers.h b/sql/item_vers.h index 42a5f0faec5..47df8a1f70d 100644 --- a/sql/item_vers.h +++ b/sql/item_vers.h @@ -34,7 +34,6 @@ public: } bool val_bool() override; - longlong val_int() override { return val_bool(); } bool fix_length_and_dec() override { set_maybe_null(); @@ -126,7 +125,7 @@ public: static LEX_CSTRING name= {STRING_WITH_LEN("trt_trx_sees") }; return name; } - longlong val_int() override; + bool val_bool() override; Item *do_get_copy(THD *thd) const override { return get_item_copy(thd, this); } }; diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 906ff0121ff..3f7ce4db569 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -425,7 +425,7 @@ public: { return { STRING_WITH_LEN("xpath_cast_bool") }; } - longlong val_int() override + bool val_bool() override { if (args[0]->fixed_type_handler() == &type_handler_xpath_nodeset) { @@ -623,7 +623,7 @@ public: DBUG_ASSERT(0); return NULL; } - longlong val_int() override + bool val_bool() override { Item_func *comp= (Item_func*)args[1]; Item_string_xml_non_const *fake= diff --git a/sql/opt_range.cc b/sql/opt_range.cc index edf09ca4b47..012d9ab8feb 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -8564,7 +8564,7 @@ SEL_TREE *Item::get_mm_tree_for_const(RANGE_OPT_PARAM *param) param->thd->mem_root= param->old_root; SEL_TREE *tree; - const SEL_TREE::Type type= val_int()? SEL_TREE::ALWAYS: SEL_TREE::IMPOSSIBLE; + const SEL_TREE::Type type= val_bool()? SEL_TREE::ALWAYS: SEL_TREE::IMPOSSIBLE; param->thd->mem_root= tmp_root; tree= new (tmp_root) SEL_TREE(type, tmp_root, param->keys); diff --git a/sql/opt_range.h b/sql/opt_range.h index b9792ad5f38..636a980ceed 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -1731,13 +1731,13 @@ class SQL_SELECT :public Sql_alloc { /* RETURN - 0 if record must be skipped <-> (cond && cond->val_int() == 0) + 0 if record must be skipped <-> (cond && cond->val_bool() == false) -1 if error 1 otherwise */ inline int skip_record(THD *thd) { - int rc= MY_TEST(!cond || cond->val_int()); + int rc= MY_TEST(!cond || cond->val_bool()); if (thd->is_error()) rc= -1; return rc; diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 627ddc86abd..5a9c9282df7 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -1063,7 +1063,7 @@ static int maxmin_in_range(bool max_fl, Field* field, COND *cond) bool less_fl= 0; switch (((Item_func*) cond)->functype()) { case Item_func::BETWEEN: - return cond->val_int() == 0; // Return 1 if WHERE is false + return cond->val_bool() == false; // Return 1 if WHERE is false case Item_func::LT_FUNC: case Item_func::LE_FUNC: less_fl= 1; @@ -1082,7 +1082,7 @@ static int maxmin_in_range(bool max_fl, Field* field, COND *cond) SELECT MAX(b) FROM t1 WHERE a=const AND bval_int() == 0; // Return 1 if WHERE is false + return cond->val_bool() == false; // Return 1 if WHERE is false return 0; } default: diff --git a/sql/set_var.cc b/sql/set_var.cc index 3dd97527433..15c07b969af 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1112,7 +1112,7 @@ int fill_sysvars(THD *thd, TABLE_LIST *tables, COND *cond) fields[0]->store(name_buffer, strlen(name_buffer), scs); if ((wild && wild_case_compare(system_charset_info, name_buffer, wild)) - || (cond && !cond->val_int())) + || (cond && !cond->val_bool())) continue; mysql_mutex_lock(&LOCK_global_system_variables); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 32c7aae01a0..d17af093897 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -437,10 +437,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, DBUG_RETURN(TRUE); } - const_cond_result= const_cond && (!conds || conds->val_int()); + const_cond_result= const_cond && (!conds || conds->val_bool()); if (unlikely(thd->is_error())) { - /* Error evaluating val_int(). */ + /* Error evaluating val_bool(). */ DBUG_RETURN(TRUE); } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 4a53b11c9af..2158758eca5 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -989,7 +989,7 @@ retry: } goto ok; } - if (cond && !cond->val_int()) + if (cond && !cond->val_bool()) { if (thd->is_error()) goto err; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 2ee6317123b..53a8145f661 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -4564,7 +4564,7 @@ bool JOIN_CACHE_BKA::skip_index_tuple(range_id_t range_info) { DBUG_ENTER("JOIN_CACHE_BKA::skip_index_tuple"); get_record_by_pos((uchar*)range_info); - DBUG_RETURN(!join_tab->cache_idx_cond->val_int()); + DBUG_RETURN(!join_tab->cache_idx_cond->val_bool()); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2ebc734a39f..fad30ead822 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -9190,7 +9190,11 @@ Item *normalize_cond(THD *thd, Item *cond) Item::Type type= cond->type(); if (type == Item::FIELD_ITEM || type == Item::REF_ITEM) { + item_base_t is_cond_flag= cond->base_flags & item_base_t::IS_COND; + cond->base_flags&= ~item_base_t::IS_COND; cond= new (thd->mem_root) Item_func_ne(thd, cond, new (thd->mem_root) Item_int(thd, 0)); + if (cond) + cond->base_flags|= is_cond_flag; } else { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a25c88dfa54..528fe545f64 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3212,7 +3212,7 @@ int JOIN::optimize_stage2() having->update_used_tables(); if (having->const_item() && !having->is_expensive()) { - if (!having->val_int()) + if (!having->val_bool()) { having= const_cast(&Item_false); zero_result_cause= "Impossible HAVING noticed after reading const tables"; @@ -4791,8 +4791,8 @@ void JOIN::exec_inner() DBUG_ASSERT(error == 0); if (cond_value != Item::COND_FALSE && having_value != Item::COND_FALSE && - (!conds || conds->val_int()) && - (!having || having->val_int())) + (!conds || conds->val_bool()) && + (!having || having->val_bool())) { if (do_send_rows && (procedure ? (procedure->send_row(procedure_fields_list) || @@ -4825,11 +4825,11 @@ void JOIN::exec_inner() */ if (!zero_result_cause && exec_const_cond && !(select_options & SELECT_DESCRIBE) && - !exec_const_cond->val_int()) + !exec_const_cond->val_bool()) zero_result_cause= "Impossible WHERE noticed after reading const tables"; /* - We've called exec_const_cond->val_int(). This may have caused an error. + We've called exec_const_cond->val_bool(). This may have caused an error. */ if (unlikely(thd->is_error())) { @@ -12846,7 +12846,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) bool const_cond_result; { Json_writer_array a(thd, "computing_condition"); - const_cond_result= const_cond->val_int() != 0; + const_cond_result= const_cond->val_bool() != 0; } if (!const_cond_result) { @@ -15992,7 +15992,7 @@ return_zero_rows(JOIN *join, select_result *result, List *tables, join->no_rows_in_result_called= 1; while ((item= it++)) item->no_rows_in_result(); - if (having && having->val_int() == 0) + if (having && having->val_bool() == false) send_row=0; } @@ -17338,6 +17338,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels, return 0; eq_item->eval_not_null_tables(0); eq_item->quick_fix_field(); + eq_item->base_flags|= item_base_t::IS_COND; } current_sjm= field_sjm; } @@ -21780,7 +21781,7 @@ do_select(JOIN *join, Procedure *procedure) sufficient to check only the condition pseudo_bits_cond. */ DBUG_ASSERT(join->outer_ref_cond == NULL); - if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_int()) + if (!join->pseudo_bits_cond || join->pseudo_bits_cond->val_bool()) { // HAVING will be checked by end_select error= (*end_select)(join, 0, 0); @@ -21841,7 +21842,7 @@ do_select(JOIN *join, Procedure *procedure) JOIN_TAB *join_tab= join->join_tab + (join->tables_list ? join->const_tables : 0); - if (join->outer_ref_cond && !join->outer_ref_cond->val_int()) + if (join->outer_ref_cond && !join->outer_ref_cond->val_bool()) error= NESTED_LOOP_NO_MORE_ROWS; else error= join->first_select(join,join_tab,0); @@ -22419,7 +22420,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab, if (select_cond) { - select_cond_result= MY_TEST(select_cond->val_int()); + select_cond_result= MY_TEST(select_cond->val_bool()); /* check for errors evaluating the condition */ if (unlikely(join->thd->is_error())) @@ -22815,7 +22816,7 @@ join_read_const_table(THD *thd, JOIN_TAB *tab, POSITION *pos) (*tab->on_expr_ref)->update_used_tables(); DBUG_ASSERT((*tab->on_expr_ref)->const_item()); #endif - if ((table->null_row= MY_TEST((*tab->on_expr_ref)->val_int() == 0))) + if ((table->null_row= MY_TEST((*tab->on_expr_ref)->val_bool() == 0))) mark_as_null_row(table); } if (!table->null_row && ! tab->join->mixed_implicit_grouping) @@ -23571,7 +23572,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) /* Copy non-aggregated fields when loose index scan is used. */ copy_fields(&join->tmp_table_param); } - if (join->having && join->having->val_int() == 0) + if (join->having && join->having->val_bool() == 0) DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having if (join->procedure) { @@ -23762,7 +23763,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) while ((item= it++)) item->no_rows_in_result(); } - if (join->having && join->having->val_int() == 0) + if (join->having && join->having->val_bool() == 0)// TODO: tests error= -1; // Didn't satisfy having else { @@ -23872,7 +23873,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (copy_funcs(join_tab->tmp_table_param->items_to_copy, join->thd)) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ - if (likely(!join_tab->having || join_tab->having->val_int())) + if (likely(!join_tab->having || join_tab->having->val_bool())) { int error; join->found_records++; @@ -24123,7 +24124,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), } copy_sum_funcs(join->sum_funcs, join->sum_funcs_end[send_group_parts]); - if (!join_tab->having || join_tab->having->val_int()) + if (!join_tab->having || join_tab->having->val_bool()) { int error= table->file->ha_write_tmp_row(table->record[0]); if (unlikely(error) && @@ -26126,7 +26127,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, break; goto err; } - if (having && !having->val_int()) + if (having && !having->val_bool()) { if (unlikely((error= file->ha_delete_row(record)))) goto err; @@ -26264,7 +26265,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, break; goto err; } - if (having && !having->val_int()) + if (having && !having->val_bool()) { if (unlikely((error= file->ha_delete_row(record)))) goto err; @@ -28401,7 +28402,7 @@ int JOIN::rollup_send_data(uint idx) int res= 0; /* Get reference pointers to sum functions in place */ copy_ref_ptr_array(ref_ptrs, rollup.ref_pointer_arrays[i]); - if ((!having || having->val_int())) + if ((!having || having->val_bool())) { if (send_records < unit->lim.get_select_limit() && do_send_rows && (res= result->send_data_with_check(rollup.fields[i], diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e66f948c3a3..f323b42a84f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3832,7 +3832,7 @@ static bool show_status_array(THD *thd, const char *wild, if ((wild_checked || !(wild && wild[0] && wild_case_compare(system_charset_info, name_buffer, wild))) && - (!cond || cond->val_int())) + (!cond || cond->val_bool())) { const char *pos; // We assign a lot of const's size_t length; @@ -5315,7 +5315,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) table->field[schema_table->idx_field2]-> store(table_name->str, table_name->length, system_charset_info); - if (!partial_cond || partial_cond->val_int()) + if (!partial_cond || partial_cond->val_bool()) { /* If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN) @@ -8148,7 +8148,7 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) COND *partial_cond= make_cond_for_info_schema(thd, cond, tables); // Evaluate and cache const subqueries now, before the mutex. if (partial_cond) - partial_cond->val_int(); + partial_cond->val_bool(); tmp.local_memory_used= 0; // meaning tmp was not populated yet diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 1928090292b..f09fd14ff68 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -4363,6 +4363,13 @@ int Type_handler_int_result::Item_save_in_field(Item *item, Field *field, } +int Type_handler_bool::Item_save_in_field(Item *item, Field *field, + bool no_conversions) const +{ + return item->save_bool_in_field(field, no_conversions); +} + + /***********************************************************************/ bool Type_handler_row:: @@ -4523,6 +4530,12 @@ Type_handler_int_result::Item_get_cache(THD *thd, const Item *item) const return new (thd->mem_root) Item_cache_int(thd, item->type_handler()); } +Item_cache * +Type_handler_bool::Item_get_cache(THD *thd, const Item *item) const +{ + return new (thd->mem_root) Item_cache_bool(thd); +} + Item_cache * Type_handler_year::Item_get_cache(THD *thd, const Item *item) const { @@ -5153,7 +5166,22 @@ bool Type_handler_real_result::Item_val_bool(Item *item) const bool Type_handler_int_result::Item_val_bool(Item *item) const { - return item->val_int() != 0; + /* + Some Item descendants have DBUG_ASSERT(!is_cond()) is their + val_int() implementations, which means val_int() must not be used + to evaluate a condition: val_bool() must be used instead. + If we come here, it means item's class does not override val_bool() + and we need to evaluate the boolean value from the integer value + as a fall-back method. To avoid the assert, let's hide the IS_COND flag. + Eventually we'll need to implement val_bool() in all Item descendants and + remove the trick with flags. This change would be too ricky for 10.6. + Let's do it in a later version. + */ + item_base_t flags= item->base_flags; + item->base_flags &= ~item_base_t::IS_COND; + bool rc= item->val_int() != 0; + item->base_flags= flags; + return rc; } bool Type_handler_temporal_result::Item_val_bool(Item *item) const diff --git a/sql/sql_type.h b/sql/sql_type.h index b593c9aa053..b99a624d9ac 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -1964,6 +1964,11 @@ public: { return neg ? -to_seconds_abs() : to_seconds_abs(); } + bool to_bool() const + { + return is_valid_time() && + (TIME_to_ulonglong_time(this) != 0 || second_part != 0); + } longlong to_longlong() const { if (!is_valid_time()) @@ -2324,6 +2329,10 @@ public: DBUG_ASSERT(is_valid_date_slow()); return Temporal::to_packed(); } + bool to_bool() const + { + return to_longlong() != 0; + } longlong to_longlong() const { return is_valid_date() ? (longlong) TIME_to_ulonglong_date(this) : 0LL; @@ -2629,6 +2638,11 @@ public: ltime->time_type= type; return false; } + bool to_bool() const + { + return is_valid_datetime() && + (TIME_to_ulonglong_datetime(this) != 0 || second_part != 0); + } longlong to_longlong() const { return is_valid_datetime() ? @@ -2857,6 +2871,10 @@ public: return Datetime::zero(); return Timestamp::to_datetime(thd); } + bool to_bool() const + { + return !m_is_zero_datetime; + } bool is_zero_datetime() const { return m_is_zero_datetime; } void trunc(uint decimals) { @@ -5840,6 +5858,9 @@ public: const Type_handler *type_handler_signed() const override; void Item_update_null_value(Item *item) const override; bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *) const override; + Item_cache *Item_get_cache(THD *thd, const Item *item) const override; + int Item_save_in_field(Item *item, Field *field, bool no_conversions) + const override; }; diff --git a/sql/sql_type_fixedbin.h b/sql/sql_type_fixedbin.h index 4755a38e85e..995d255fa14 100644 --- a/sql/sql_type_fixedbin.h +++ b/sql/sql_type_fixedbin.h @@ -253,6 +253,10 @@ public: { return singleton(); } + bool val_bool() override + { + return m_value.to_bool(); + } longlong val_int() override { return 0; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9a21a93c788..67a702f8969 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1483,6 +1483,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type literal insert_ident order_ident temporal_literal simple_ident expr sum_expr in_sum_expr + search_condition variable variable_aux boolean_test predicate bit_expr parenthesized_expr @@ -4210,6 +4211,7 @@ simple_when_clause: searched_when_clause: WHEN_SYM expr_lex { + $2->get_item()->base_flags|= item_base_t::IS_COND; if (unlikely($2->case_stmt_action_when(false))) MYSQL_YYABORT; } @@ -9408,6 +9410,10 @@ optional_braces: | '(' ')' {} ; +search_condition: + expr { ($$= $1)->base_flags|= item_base_t::IS_COND ; } + ; + /* all possible expressions */ expr: expr or expr %prec OR_SYM @@ -11867,7 +11873,7 @@ join_table: MYSQL_YYABORT; Select->parsing_place= IN_ON; } - expr + search_condition { add_join_on(thd, $5, $8); $5->on_context= Lex->pop_context(); @@ -12224,7 +12230,7 @@ opt_where_clause: { Select->parsing_place= IN_WHERE; } - expr + search_condition { SELECT_LEX *select= Select; select->where= normalize_cond(thd, $3); @@ -12240,7 +12246,7 @@ opt_having_clause: { Select->parsing_place= IN_HAVING; } - expr + search_condition { SELECT_LEX *sel= Select; sel->having= normalize_cond(thd, $3); @@ -14359,7 +14365,7 @@ wild_and_where: MYSQL_YYABORT; $$= $2; } - | WHERE remember_tok_start expr + | WHERE remember_tok_start search_condition { Select->where= normalize_cond(thd, $3); if ($3) diff --git a/sql/table.cc b/sql/table.cc index b4e961677a9..6535c342521 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6416,7 +6416,7 @@ int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure) /* VIEW's CHECK OPTION CLAUSE */ Counting_error_handler ceh; thd->push_internal_handler(&ceh); - bool res= check_option->val_int() == 0; + bool res= check_option->val_bool() == false; thd->pop_internal_handler(); if (ceh.errors) return(VIEW_CHECK_ERROR); @@ -6459,7 +6459,7 @@ int TABLE::verify_constraints(bool ignore_failure) yes! NULL is ok. see 4.23.3.4 Table check constraints, part 2, SQL:2016 */ - if (((*chk)->expr->val_int() == 0 && !(*chk)->expr->null_value) || + if (((*chk)->expr->val_bool() == false && !(*chk)->expr->null_value) || in_use->is_error()) { enum_vcol_info_type vcol_type= (*chk)->get_vcol_type();