Wrong result upon query from I_S and further Assertion `!alias_arg || strlen(alias_arg->str) == alias_arg->length' failed with certain connection charset
Alexander Barkov
added a comment - - edited Related problem:
DROP VIEW IF EXISTS v1;
SET NAMES utf8;
SET SESSION character_set_connection=latin1;
CREATE VIEW v1 AS SELECT 'ä' AS c1;
SELECT c1, HEX(c1) FROM v1;
+----+---------+
| c1 | hex(c1) |
+----+---------+
| ? | 3F |
+----+---------+
The expected result would be:
+----+---------+
| c1 | hex(c1) |
+----+---------+
| ä | E4 |
+----+---------+
The same crash happens with this script (without VIEWs):
DROPTABLEIF EXISTS t;
CREATETABLE t (a INT);
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME= CONCAT('t',0x00,'1');
LOCK TABLE t WRITE;
Before the crash, the SELECT returns a wrong record:
TABLE_CATALOG: def
TABLE_SCHEMA: test
TABLE_NAME: t 1 <<< --- This is wrong
TABLE_TYPE: BASE TABLE
ENGINE: InnoDB
VERSION: 10
ROW_FORMAT: Dynamic
TABLE_ROWS: 0
AVG_ROW_LENGTH: 0
DATA_LENGTH: 16384
MAX_DATA_LENGTH: 0
INDEX_LENGTH: 0
DATA_FREE: 0
AUTO_INCREMENT: NULL
CREATE_TIME: 2021-10-11 16:42:45
UPDATE_TIME: NULL
CHECK_TIME: NULL
TABLE_COLLATION: latin1_swedish_ci
CHECKSUM: NULL
CREATE_OPTIONS:
TABLE_COMMENT:
MAX_INDEX_LENGTH: 0
TEMPORARY: N
Alexander Barkov
added a comment - - edited The same crash happens with this script (without VIEWs):
DROP TABLE IF EXISTS t;
CREATE TABLE t (a INT );
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME= CONCAT( 't' ,0x00, '1' );
LOCK TABLE t WRITE;
Before the crash, the SELECT returns a wrong record:
TABLE_CATALOG: def
TABLE_SCHEMA: test
TABLE_NAME: t 1 <<< --- This is wrong
TABLE_TYPE: BASE TABLE
ENGINE: InnoDB
VERSION: 10
ROW_FORMAT: Dynamic
TABLE_ROWS: 0
AVG_ROW_LENGTH: 0
DATA_LENGTH: 16384
MAX_DATA_LENGTH: 0
INDEX_LENGTH: 0
DATA_FREE: 0
AUTO_INCREMENT: NULL
CREATE_TIME: 2021-10-11 16:42:45
UPDATE_TIME: NULL
CHECK_TIME: NULL
TABLE_COLLATION: latin1_swedish_ci
CHECKSUM: NULL
CREATE_OPTIONS:
TABLE_COMMENT:
MAX_INDEX_LENGTH: 0
TEMPORARY: N
SELECT TABLE_NAME, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME= CONCAT('t',0x00,'1');
+------------+-----------------+
| TABLE_NAME | HEX(TABLE_NAME) |
+------------+-----------------+
| t 1 | 740031 |
+------------+-----------------+
The result looks wrong
The expected result would be empty set, because there is no such table, with 0x00 in the middle of the name. So WHERE did not work fine.
The table name was copied from the WHERE condition into the SELECT sublist. This also looks wrong.
Alexander Barkov
added a comment - Similar to the above, but without LOCK:
DROP TABLE IF EXISTS t;
CREATE TABLE t (a INT );
SELECT TABLE_NAME, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME= CONCAT( 't' ,0x00, '1' );
+------------+-----------------+
| TABLE_NAME | HEX(TABLE_NAME) |
+------------+-----------------+
| t 1 | 740031 |
+------------+-----------------+
The result looks wrong
The expected result would be empty set, because there is no such table, with 0x00 in the middle of the name. So WHERE did not work fine.
The table name was copied from the WHERE condition into the SELECT sublist. This also looks wrong.
The same problem is repeatable with a condition on TABLE_SCHEMA:
USE test;
DROPTABLEIF EXISTS t;
CREATETABLE t (a INT);
SELECT TABLE_NAME, TABLE_SCHEMA, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA= CONCAT('test',0x00,'1');
+------------+--------------+-----------------+
| TABLE_NAME | TABLE_SCHEMA | HEX(TABLE_NAME) |
+------------+--------------+-----------------+
| t | test 1 | 74 |
+------------+--------------+-----------------+
Alexander Barkov
added a comment - The same problem is repeatable with a condition on TABLE_SCHEMA:
USE test;
DROP TABLE IF EXISTS t;
CREATE TABLE t (a INT );
SELECT TABLE_NAME, TABLE_SCHEMA, HEX(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA= CONCAT( 'test' ,0x00, '1' );
+------------+--------------+-----------------+
| TABLE_NAME | TABLE_SCHEMA | HEX(TABLE_NAME) |
+------------+--------------+-----------------+
| t | test 1 | 74 |
+------------+--------------+-----------------+
Alexander Barkov
added a comment - - edited Related problem:
SET NAMES utf8;
SET SESSION character_set_connection=latin1;
DROP PROCEDURE IF EXISTS p1;
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
DECLARE a VARCHAR (10) CHARACTER SET utf8;
SET a= 'ä' ;
END ;
$$
DELIMITER ;
SHOW PROCEDURE CODE p1;
+-----+--------------+
| Pos | Instruction |
+-----+--------------+
| 0 | set a@0 NULL |
| 1 | set a@0 '�' |
+-----+--------------+
Notice, the set value is not readable.
If I further run:
SET NAMES latin1;
SHOW PROCEDURE CODE p1;
+-----+--------------+
| Pos | Instruction |
+-----+--------------+
| 0 | set a@0 NULL |
| 1 | set a@0 '?' |
+-----+--------------+
the set value is still unreadable.
Note, the patch is for 10.3 to make sure it does not crash after the fix.
10.2 did not crash. It only returned wrong result sets.
But the patch should be pushed starting from 10.2.
Alexander Barkov
added a comment - sanja , can you please review a fix:
https://github.com/MariaDB/server/commit/901722d7d1fc021197f5f735fbde1c263b6f9028
Note, the patch is for 10.3 to make sure it does not crash after the fix.
10.2 did not crash. It only returned wrong result sets.
But the patch should be pushed starting from 10.2.
Alexander Barkov
added a comment - sanja , please review a new patch version, now using check_table_name():
https://github.com/MariaDB/server/commit/9789cbef195439a5c1a2351854becae3fd89324f
Thanks.
Related problem:
+----+---------+
| c1 | hex(c1) |
+----+---------+
| ? | 3F |
+----+---------+
The expected result would be:
+----+---------+
| c1 | hex(c1) |
+----+---------+
| ä | E4 |
+----+---------+