1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-34123 CONCAT Function Returns Unexpected Empty Set in Query

Search conditions were evaluated using val_int(), which was wrong.
Fixing the code to use val_bool() instead.

Details:
- Adding a new item_base_t::IS_COND flag which marks Items used
  as <search condition> in WHERE, HAVING, JOIN ON, CASE WHEN clauses.
  The flag is at the parse time.
  These expressions must be evaluated using val_bool() rather than val_int().

  Note, the optimizer creates more Items which are used as search conditions.
  Most of these items are not marked with IS_COND yet. This is OK for now,
  but eventually these Items can also be fixed to have the flag.

- Adding a method Item::is_cond() which tests if the Item has the IS_COND flag.

- Implementing Item_cache_bool. It evaluates the cached expression using
  val_bool() rather than val_int().
  Overriding Type_handler_bool::Item_get_cache() to create Item_cache_bool.

- Implementing Item::save_bool_in_field(). It uses val_bool() rather than
  val_int() to evaluate the expression.

- Implementing Type_handler_bool::Item_save_in_field()
  using Item::save_bool_in_field().

- Fixing all Item_bool_func descendants to implement a virtual val_bool()
  rather than a virtual val_int().

- To find places where val_int() should be fixed to val_bool(), a few
  DBUG_ASSERT(!is_cond()) where added into val_int() implementations
  of selected (most frequent) classes:

  Item_field
  Item_str_func
  Item_datefunc
  Item_timefunc
  Item_datetimefunc
  Item_cache_bool
  Item_bool_func
  Item_func_hybrid_field_type
  Item_basic_constant descendants

- Fixing all places where DBUG_ASSERT() happened during an "mtr" run
  to use val_bool() instead of val_int().
This commit is contained in:
Alexander Barkov
2024-05-14 09:19:34 +04:00
committed by Oleksandr Byelkin
parent 6f6c1911dc
commit a931da82fa
52 changed files with 2098 additions and 151 deletions

View File

@@ -0,0 +1,201 @@
--echo #
--echo # WHERE <search condition>
--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 <search condition>
--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 # <join condition> := ON <search condition>
--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 # <delete statement: searched>
--echo # DELETE FROM <target table> [ WHERE <search condition> ]
--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 # <update statement: searched>
--echo # UPDATE <target table> SET <set clause list> [ WHERE <search condition> ]
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 # <check constraint definition>
--echo # CHECK <left paren> <search condition> <right paren>
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 # <case expression>
--echo # WHEN <search condition> THEN <result>
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;

View File

@@ -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 <search condition>
#
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 <search condition>
#
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;
#
# <join condition> := ON <search condition>
#
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 statement: searched>
# DELETE FROM <target table> [ WHERE <search condition> ]
#
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 statement: searched>
# UPDATE <target table> SET <set clause list> [ WHERE <search condition> ]
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 constraint definition>
# CHECK <left paren> <search condition> <right paren>
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;
#
# <case expression>
# WHEN <search condition> THEN <result>
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
#

View File

@@ -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 #

View File

@@ -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 <search condition>
#
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 <search condition>
#
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;
#
# <join condition> := ON <search condition>
#
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 statement: searched>
# DELETE FROM <target table> [ WHERE <search condition> ]
#
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 statement: searched>
# UPDATE <target table> SET <set clause list> [ WHERE <search condition> ]
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 constraint definition>
# CHECK <left paren> <search condition> <right paren>
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;
#
# <case expression>
# WHEN <search condition> THEN <result>
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
#

View File

@@ -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 #

View File

@@ -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 <search condition>
#
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 <search condition>
#
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;
#
# <join condition> := ON <search condition>
#
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 statement: searched>
# DELETE FROM <target table> [ WHERE <search condition> ]
#
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 statement: searched>
# UPDATE <target table> SET <set clause list> [ WHERE <search condition> ]
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 constraint definition>
# CHECK <left paren> <search condition> <right paren>
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;
#
# <case expression>
# WHEN <search condition> THEN <result>
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
#

View File

@@ -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 #

View File

@@ -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 <search condition>
#
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 <search condition>
#
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;
#
# <join condition> := ON <search condition>
#
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 statement: searched>
# DELETE FROM <target table> [ WHERE <search condition> ]
#
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 statement: searched>
# UPDATE <target table> SET <set clause list> [ WHERE <search condition> ]
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 constraint definition>
# CHECK <left paren> <search condition> <right paren>
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;
#
# <case expression>
# WHEN <search condition> THEN <result>
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
#

View File

@@ -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 #

View File

@@ -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

View File

@@ -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 <search condition>
#
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 <search condition>
#
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;
#
# <join condition> := ON <search condition>
#
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 statement: searched>
# DELETE FROM <target table> [ WHERE <search condition> ]
#
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 statement: searched>
# UPDATE <target table> SET <set clause list> [ WHERE <search condition> ]
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 constraint definition>
# CHECK <left paren> <search condition> <right paren>
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;
#
# <case expression>
# WHEN <search condition> THEN <result>
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
#

View File

@@ -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 #

View File

@@ -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

View File

@@ -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 <search condition>
#
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 <search condition>
#
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;
#
# <join condition> := ON <search condition>
#
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 statement: searched>
# DELETE FROM <target table> [ WHERE <search condition> ]
#
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 statement: searched>
# UPDATE <target table> SET <set clause list> [ WHERE <search condition> ]
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 constraint definition>
# CHECK <left paren> <search condition> <right paren>
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;
#
# <case expression>
# WHEN <search condition> THEN <result>
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
#

View File

@@ -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 #

View File

@@ -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<STRING_BUFFER_USUAL_SIZE> 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<STRING_BUFFER_USUAL_SIZE> 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();

View File

@@ -181,7 +181,7 @@ public:
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_is_ipv4>(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<Item_func_is_ipv6>(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<Item_func_is_ipv4_compat>(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<Item_func_is_ipv4_mapped>(thd, this); }
longlong val_int() override;
bool val_bool() override;
};
#endif // ITEM_INETFUNC_INCLUDED

View File

@@ -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 <search condition>
#
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 <search condition>
#
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;
#
# <join condition> := ON <search condition>
#
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 statement: searched>
# DELETE FROM <target table> [ WHERE <search condition> ]
#
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 statement: searched>
# UPDATE <target table> SET <set clause list> [ WHERE <search condition> ]
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 constraint definition>
# CHECK <left paren> <search condition> <right paren>
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;
#
# <case expression>
# WHEN <search condition> THEN <result>
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
#

View File

@@ -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 #

View File

@@ -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();
};

View File

@@ -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;

View File

@@ -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)

View File

@@ -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 <search condition>.
// 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<Item_cache_bool>(thd, this); }
};
class Item_cache_year: public Item_cache_int
{
public:

View File

@@ -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<Item> &parameters)
@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<Item> 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<Item> 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),

View File

@@ -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("<nop>") };
@@ -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("<is_not_null_test>") };
@@ -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<Item> &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<Item> &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<Item_func_cursor_isopen>(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<Item_func_cursor_found>(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<Item_func_cursor_notfound>(thd, this); }
};

View File

@@ -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();

View File

@@ -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);

View File

@@ -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;

View File

@@ -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<Item_func_spatial_mbr_rel>(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<Item_func_spatial_precise_rel>(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") };

View File

@@ -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;

View File

@@ -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<Item_func_json_exists>(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<Item_func_json_contains>(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<Item_func_json_contains_path>(thd, this); }
};

View File

@@ -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);

View File

@@ -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)

View File

@@ -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); }

View File

@@ -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);

View File

@@ -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<Item_func_trt_trx_sees>(thd, this); }
};

View File

@@ -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=

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 b<const
*/
if (max_fl != less_fl)
return cond->val_int() == 0; // Return 1 if WHERE is false
return cond->val_bool() == false; // Return 1 if WHERE is false
return 0;
}
default:

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -989,7 +989,7 @@ retry:
}
goto ok;
}
if (cond && !cond->val_int())
if (cond && !cond->val_bool())
{
if (thd->is_error())
goto err;

View File

@@ -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());
}

View File

@@ -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
{

View File

@@ -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_bool_static*>(&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<TABLE_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],

View File

@@ -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

View File

@@ -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

View File

@@ -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;
};

View File

@@ -253,6 +253,10 @@ public:
{
return singleton();
}
bool val_bool() override
{
return m_value.to_bool();
}
longlong val_int() override
{
return 0;

View File

@@ -1483,6 +1483,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <item>
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)

View File

@@ -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();