summaryrefslogtreecommitdiff
path: root/sql/sql_schema.h
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2022-04-04 14:50:21 +0400
committerAlexander Barkov <bar@mariadb.com>2022-04-22 15:35:16 +0400
commitd67c3f88883b616a9adf3abba43938c3a07a5eee (patch)
tree867038a8f48d10aec46f2f2f99d0d03f63f365e3 /sql/sql_schema.h
parent7355f7b1f5cec0f3db60053941d0c78288917c43 (diff)
downloadmariadb-git-bb-10.3-bar.tar.gz
MDEV-27744 InnoDB: Failing assertion: !cursor->index->is_committed() in row0ins.cc (from row_ins_sec_index_entry_by_modify) | Assertion `0' failed in row_upd_sec_index_entry (debug) | Corruptionbb-10.3-bar
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.
Diffstat (limited to 'sql/sql_schema.h')
-rw-r--r--sql/sql_schema.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/sql/sql_schema.h b/sql/sql_schema.h
index 7c8f284d526..36914e36990 100644
--- a/sql/sql_schema.h
+++ b/sql/sql_schema.h
@@ -19,6 +19,9 @@
#include "mysqld.h"
#include "lex_string.h"
+class Lex_ident_sys;
+class Create_func;
+
class Schema
{
LEX_CSTRING m_name;
@@ -33,6 +36,34 @@ public:
{
return src;
}
+
+
+ /**
+ Find the native function builder associated with a given function name.
+ @param thd The current thread
+ @param name The native function name
+ @return The native function builder associated with the name, or NULL
+ */
+ virtual Create_func *find_native_function_builder(THD *thd,
+ const LEX_CSTRING &name)
+ const;
+ /**
+ Find a native function builder, return an error if not found,
+ build an Item otherwise.
+ */
+ Item *make_item_func_call_native(THD *thd,
+ const Lex_ident_sys &name,
+ List<Item> *args) const;
+
+ // Builders for native SQL function with a special syntax in sql_yacc.yy
+ virtual Item *make_item_func_substr(THD *thd,
+ const Lex_substring_spec_st &spec) const;
+
+ virtual Item *make_item_func_trim(THD *thd, const Lex_trim_st &spec) const;
+ virtual Item *make_item_func_replace(THD *thd,
+ Item *subj,
+ Item *find,
+ Item *replace) const;
/*
For now we have *hard-coded* compatibility schemas:
schema_mariadb, schema_oracle, schema_maxdb.
@@ -66,5 +97,6 @@ public:
extern Schema mariadb_schema;
+extern const Schema &oracle_schema_ref;
#endif // SQL_SCHEMA_H_INCLUDED