mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 19:06:14 +01:00 
			
		
		
		
	 2b6d241ee4
			
		
	
	
	2b6d241ee4
	
	
	
		
			
			The crash happened with an indexed virtual column whose value is evaluated using a function that has a different meaning in sql_mode='' vs sql_mode=ORACLE: - DECODE() - LTRIM() - RTRIM() - LPAD() - RPAD() - REPLACE() - SUBSTR() For example: CREATE TABLE t1 ( b VARCHAR(1), g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL, KEY g(g) ); So far we had replacement XXX_ORACLE() functions for all mentioned function, e.g. SUBSTR_ORACLE() for SUBSTR(). So it was possible to correctly re-parse SUBSTR_ORACLE() even in sql_mode=''. But it was not possible to re-parse the MariaDB version of SUBSTR() after switching to sql_mode=ORACLE. It was erroneously mis-interpreted as SUBSTR_ORACLE(). As a result, this combination worked fine: SET sql_mode=ORACLE; CREATE TABLE t1 ... g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL, ...; INSERT ... FLUSH TABLES; SET sql_mode=''; INSERT ... But the other way around it crashed: SET sql_mode=''; CREATE TABLE t1 ... g CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL, ...; INSERT ... FLUSH TABLES; SET sql_mode=ORACLE; INSERT ... At CREATE time, SUBSTR was instantiated as Item_func_substr and printed in the FRM file as substr(). At re-open time with sql_mode=ORACLE, "substr()" was erroneously instantiated as Item_func_substr_oracle. Fix: The fix proposes a symmetric solution. It provides a way to re-parse reliably all sql_mode dependent functions to their original CREATE TABLE time meaning, no matter what the open-time sql_mode is. We take advantage of the same idea we previously used to resolve sql_mode dependent data types. Now all sql_mode dependent functions are printed by SHOW using a schema qualifier when the current sql_mode differs from the function sql_mode: SET sql_mode=''; CREATE TABLE t1 ... SUBSTR(a,b,c) ..; SET sql_mode=ORACLE; SHOW CREATE TABLE t1; -> mariadb_schema.substr(a,b,c) SET sql_mode=ORACLE; CREATE TABLE t2 ... SUBSTR(a,b,c) ..; SET sql_mode=''; SHOW CREATE TABLE t1; -> oracle_schema.substr(a,b,c) Old replacement names like substr_oracle() are still understood for backward compatibility and used in FRM files (for downgrade compatibility), but they are not printed by SHOW any more.
		
			
				
	
	
		
			32 lines
		
	
	
	
		
			935 B
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			32 lines
		
	
	
	
		
			935 B
		
	
	
	
		
			Text
		
	
	
	
	
	
| SET sql_mode=ORACLE;
 | |
| #
 | |
| # MDEV-13003 - Oracle compatibility : Replace function
 | |
| #
 | |
| SELECT REPLACE(null,'a','b') ;
 | |
| REPLACE(null,'a','b')
 | |
| NULL
 | |
| SELECT REPLACE('ab',null,'b') ;
 | |
| REPLACE('ab',null,'b')
 | |
| ab
 | |
| SELECT REPLACE('ab','a',null) ;
 | |
| REPLACE('ab','a',null)
 | |
| b
 | |
| SELECT REPLACE('ab',null,null) ;
 | |
| REPLACE('ab',null,null)
 | |
| ab
 | |
| SELECT REPLACE('aaa','a',null) ;
 | |
| REPLACE('aaa','a',null)
 | |
| NULL
 | |
| EXPLAIN EXTENDED SELECT REPLACE('ab','a',null) ;
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 | |
| 1	SIMPLE	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
 | |
| Warnings:
 | |
| Note	1003	select replace('ab','a',NULL) AS "REPLACE('ab','a',null)"
 | |
| CREATE VIEW v1 AS SELECT REPLACE('ab','a',null) ;
 | |
| SHOW CREATE VIEW v1;
 | |
| View	Create View	character_set_client	collation_connection
 | |
| v1	CREATE VIEW "v1" AS select replace('ab','a',NULL) AS "REPLACE('ab','a',null)"	latin1	latin1_swedish_ci
 | |
| SELECT * FROM v1;
 | |
| REPLACE('ab','a',null)
 | |
| b
 | |
| DROP VIEW v1;
 |