Bug Report
REPEAT(name, 5592406) on VARCHAR 'abc' is 16 777 218 bytes, one past
mysql.MaxBlobWidth (16 777 216). Vectorized REPEAT
(builtin_string_vec.go) NULLs that call via len(str) > Flen/num. Scalar
REPEAT (builtin_string.go evalString) only checks max_allowed_packet
(64 MiB here) and produces the string.
On a plain table, GROUP BY name plus HAVING MAX(id) <= (SELECT COUNT(*) FROM t)
takes the vectorized path: CAST(… AS CHAR(255)) is NULL. Replace the table with
the identity CTE
1. Minimal reproduce step (Required)
CREATE TABLE t__base (id BIGINT, name VARCHAR(255));
INSERT INTO t__base VALUES (2, 'abc'), (42, '');
CREATE VIEW t AS WITH t__base_cte_1 AS (SELECT * FROM t__base) SELECT * FROM t__base_cte_1;
SELECT name,
CAST(IF(name = name, REPEAT(name, 5592406), REGEXP_INSTR(name, '.')) AS CHAR(255)) IS NULL AS is_null,
CHAR_LENGTH(CAST(IF(name = name, REPEAT(name, 5592406), REGEXP_INSTR(name, '.')) AS CHAR(255))) AS clen
FROM t
GROUP BY name
HAVING MAX(id) <= (SELECT COUNT(*) FROM t);
-- Expected: ('abc', 1, NULL)
-- Actual: ('abc', 0, 255) -- WRONG
This is correct, selecting from a table instead of a view:
CREATE TABLE t__base (id BIGINT, name VARCHAR(255));
INSERT INTO t__base VALUES (2, 'abc'), (42, '');
CREATE TABLE t LIKE t__base;
INSERT INTO t SELECT * FROM t__base;
SELECT name,
CAST(IF(name = name, REPEAT(name, 5592406), REGEXP_INSTR(name, '.')) AS CHAR(255)) IS NULL AS is_null,
CHAR_LENGTH(CAST(IF(name = name, REPEAT(name, 5592406), REGEXP_INSTR(name, '.')) AS CHAR(255))) AS clen
FROM t
GROUP BY name
HAVING MAX(id) <= (SELECT COUNT(*) FROM t);
-- Expected: ('abc', 1, NULL)
-- Actual: ('abc', 1, NULL)
2. What did you expect to see? (Required)
| Query |
Expected |
Actual |
table, distilled IF/REPEAT/REGEXP_INSTR + HAVING |
NULL (IS NULL = 1) |
NULL |
| CTE view, same query |
NULL (same rows) |
255-char string |
query-level WITH t AS (SELECT * FROM t__base), same query |
NULL |
255-char string |
identity VIEW (no WITH) |
NULL |
NULL |
REPEAT(name, 5592405) (3·n = 16 777 215 ≤ MaxBlobWidth) |
255 on both |
255 on both |
IF(TRUE, REPEAT(…), REGEXP_INSTR(…)) |
NULL on both |
NULL on both |
ELSE NULL |
NULL on both |
NULL on both |
no HAVING |
'abc' NULL and '' length 0 on both |
both agree |
3. What did you see instead (Required)
4. What is your TiDB version? (Required)
TiDB v9.0.0-beta.2.pre @ 3bea819
Bug Report
REPEAT(name, 5592406)on VARCHAR'abc'is 16 777 218 bytes, one pastmysql.MaxBlobWidth(16 777 216). VectorizedREPEAT(
builtin_string_vec.go) NULLs that call vialen(str) > Flen/num. ScalarREPEAT(builtin_string.goevalString) only checksmax_allowed_packet(64 MiB here) and produces the string.
On a plain table,
GROUP BY nameplusHAVING MAX(id) <= (SELECT COUNT(*) FROM t)takes the vectorized path:
CAST(… AS CHAR(255))is NULL. Replace the table withthe identity CTE
1. Minimal reproduce step (Required)
This is correct, selecting from a table instead of a view:
2. What did you expect to see? (Required)
IF/REPEAT/REGEXP_INSTR+HAVINGIS NULL= 1)WITH t AS (SELECT * FROM t__base), same queryVIEW(noWITH)REPEAT(name, 5592405)(3·n = 16 777 215 ≤ MaxBlobWidth)IF(TRUE, REPEAT(…), REGEXP_INSTR(…))ELSE NULLHAVING'abc'NULL and''length 0 on both3. What did you see instead (Required)
4. What is your TiDB version? (Required)
TiDB v9.0.0-beta.2.pre @ 3bea819