diff --git a/sql/sql_class.h b/sql/sql_class.h index 066e42ca0f0..3e95b614756 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -6910,6 +6910,50 @@ class Sql_mode_save sql_mode_t old_mode; // SQL mode saved at construction time. }; + +/* + Save the current sql_mode. Switch off sql_mode flags which can prevent + normal parsing of VIEWs, expressions in generated columns. + Restore the old sql_mode on destructor. +*/ +class Sql_mode_save_for_frm_handling: public Sql_mode_save +{ +public: + Sql_mode_save_for_frm_handling(THD *thd) + :Sql_mode_save(thd) + { + /* + - MODE_REAL_AS_FLOAT affect only CREATE TABLE parsing + + MODE_PIPES_AS_CONCAT affect expression parsing + + MODE_ANSI_QUOTES affect expression parsing + + MODE_IGNORE_SPACE affect expression parsing + - MODE_IGNORE_BAD_TABLE_OPTIONS affect only CREATE/ALTER TABLE parsing + * MODE_ONLY_FULL_GROUP_BY affect execution + * MODE_NO_UNSIGNED_SUBTRACTION affect execution + - MODE_NO_DIR_IN_CREATE affect table creation only + - MODE_POSTGRESQL compounded from other modes + + MODE_ORACLE affects Item creation (e.g for CONCAT) + - MODE_MSSQL compounded from other modes + - MODE_DB2 compounded from other modes + - MODE_MAXDB affect only CREATE TABLE parsing + - MODE_NO_KEY_OPTIONS affect only SHOW + - MODE_NO_TABLE_OPTIONS affect only SHOW + - MODE_NO_FIELD_OPTIONS affect only SHOW + - MODE_MYSQL323 affect only SHOW + - MODE_MYSQL40 affect only SHOW + - MODE_ANSI compounded from other modes + (+ transaction mode) + ? MODE_NO_AUTO_VALUE_ON_ZERO affect UPDATEs + + MODE_NO_BACKSLASH_ESCAPES affect expression parsing + + MODE_EMPTY_STRING_IS_NULL affect expression parsing + */ + thd->variables.sql_mode&= ~(MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | + MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES | + MODE_ORACLE | MODE_EMPTY_STRING_IS_NULL); + }; +}; + + class Abort_on_warning_instant_set { THD *m_thd; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 487800df1ab..74459480c61 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2589,11 +2589,9 @@ char *generate_partition_syntax_for_frm(THD *thd, partition_info *part_info, HA_CREATE_INFO *create_info, Alter_info *alter_info) { - sql_mode_t old_mode= thd->variables.sql_mode; - thd->variables.sql_mode &= ~MODE_ANSI_QUOTES; + Sql_mode_save_for_frm_handling sql_mode_save(thd); char *res= generate_partition_syntax(thd, part_info, buf_length, true, create_info, alter_info); - thd->variables.sql_mode= old_mode; return res; } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 54debf98eff..6eaf739a417 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -952,8 +952,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view_query.length(0); is_query.length(0); { - sql_mode_t sql_mode= thd->variables.sql_mode & MODE_ANSI_QUOTES; - thd->variables.sql_mode&= ~MODE_ANSI_QUOTES; + Sql_mode_save_for_frm_handling sql_mode_save(thd); lex->unit.print(&view_query, enum_query_type(QT_VIEW_INTERNAL | QT_ITEM_ORIGINAL_FUNC_NULLIF | @@ -962,8 +961,6 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, QT_WITHOUT_INTRODUCERS | QT_ITEM_ORIGINAL_FUNC_NULLIF | QT_NO_WRAPPERS_FOR_TVC_IN_VIEW)); - - thd->variables.sql_mode|= sql_mode; } DBUG_PRINT("info", ("View: %.*s", view_query.length(), view_query.ptr())); @@ -1423,35 +1420,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, lex_start(thd); lex->stmt_lex= old_lex; - sql_mode_t saved_mode= thd->variables.sql_mode; - /* switch off modes which can prevent normal parsing of VIEW - - MODE_REAL_AS_FLOAT affect only CREATE TABLE parsing - + MODE_PIPES_AS_CONCAT affect expression parsing - + MODE_ANSI_QUOTES affect expression parsing - + MODE_IGNORE_SPACE affect expression parsing - - MODE_IGNORE_BAD_TABLE_OPTIONS affect only CREATE/ALTER TABLE parsing - * MODE_ONLY_FULL_GROUP_BY affect execution - * MODE_NO_UNSIGNED_SUBTRACTION affect execution - - MODE_NO_DIR_IN_CREATE affect table creation only - - MODE_POSTGRESQL compounded from other modes - - MODE_ORACLE affects Item creation (e.g for CONCAT) - - MODE_MSSQL compounded from other modes - - MODE_DB2 compounded from other modes - - MODE_MAXDB affect only CREATE TABLE parsing - - MODE_NO_KEY_OPTIONS affect only SHOW - - MODE_NO_TABLE_OPTIONS affect only SHOW - - MODE_NO_FIELD_OPTIONS affect only SHOW - - MODE_MYSQL323 affect only SHOW - - MODE_MYSQL40 affect only SHOW - - MODE_ANSI compounded from other modes - (+ transaction mode) - ? MODE_NO_AUTO_VALUE_ON_ZERO affect UPDATEs - + MODE_NO_BACKSLASH_ESCAPES affect expression parsing - */ - thd->variables.sql_mode&= ~(MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | - MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES | - MODE_ORACLE); - + Sql_mode_save_for_frm_handling sql_mode_save(thd); /* Parse the query. */ parse_status= parse_sql(thd, & parser_state, table->view_creation_ctx); @@ -1464,8 +1433,6 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, (old_lex->sql_command == SQLCOM_SHOW_CREATE)) lex->sql_command= old_lex->sql_command; - thd->variables.sql_mode= saved_mode; - if (dbchanged && mysql_change_db(thd, &old_db, TRUE)) goto err; } diff --git a/sql/table.cc b/sql/table.cc index 44d639e27a4..e6684cd1c72 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1101,7 +1101,7 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, Field **vfield_ptr= table->vfield; Field **dfield_ptr= table->default_field; Virtual_column_info **check_constraint_ptr= table->check_constraints; - sql_mode_t saved_mode= thd->variables.sql_mode; + Sql_mode_save_for_frm_handling sql_mode_save(thd); Query_arena backup_arena; Virtual_column_info *vcol= 0; StringBuffer expr_str; @@ -1128,7 +1128,6 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table, thd->stmt_arena= table->expr_arena; thd->update_charset(&my_charset_utf8mb4_general_ci, table->s->table_charset); expr_str.append(&parse_vcol_keyword); - thd->variables.sql_mode &= ~(MODE_NO_BACKSLASH_ESCAPES | MODE_EMPTY_STRING_IS_NULL); while (pos < end) { @@ -1315,7 +1314,6 @@ end: thd->stmt_arena= backup_stmt_arena_ptr; if (save_character_set_client) thd->update_charset(save_character_set_client, save_collation); - thd->variables.sql_mode= saved_mode; DBUG_RETURN(res); } diff --git a/sql/unireg.cc b/sql/unireg.cc index b4213786abb..f2d57e7549f 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -42,7 +42,8 @@ static uint pack_keys(uchar *,uint, KEY *, ulong, uint); static bool pack_header(THD *, uchar *, List &, HA_CREATE_INFO *, ulong, handler *); -static bool pack_vcols(String *, List &, List *); +static bool pack_vcols(THD *thd, String *, + List &, List *); static uint get_interval_id(uint *,List &, Create_field *); static bool pack_fields(uchar **, List &, HA_CREATE_INFO*, ulong); @@ -199,10 +200,8 @@ LEX_CUSTRING build_frm_image(THD *thd, const LEX_CSTRING &table, create_info->null_bits++; data_offset= (create_info->null_bits + 7) / 8; - sql_mode_t save_sql_mode= thd->variables.sql_mode; - thd->variables.sql_mode &= ~MODE_ANSI_QUOTES; - error= pack_vcols(&vcols, create_fields, create_info->check_constraint_list); - thd->variables.sql_mode= save_sql_mode; + error= pack_vcols(thd, &vcols, + create_fields, create_info->check_constraint_list); if (unlikely(error)) DBUG_RETURN(frm); @@ -635,9 +634,10 @@ static bool pack_expression(String *buf, Virtual_column_info *vcol, } -static bool pack_vcols(String *buf, List &create_fields, - List *check_constraint_list) +static bool pack_vcols(THD *thd, String *buf, List &create_fields, + List *check_constraint_list) { + Sql_mode_save_for_frm_handling sql_mode_save(thd); List_iterator it(create_fields); Create_field *field;