[Commits] e801d6fd007: MENT-1062 : add outer reference in VIEWs.
revision-id: e801d6fd0075915e58999d7d48251b3f91674c8e (mariadb-10.5.2-1037-ge801d6fd007) parent(s): 7172ff780bd6c1d131d6134c4f92ae71604a0b1c author: Oleksandr Byelkin committer: Sergei Petrunia timestamp: 2021-06-18 00:43:34 +0300 message: MENT-1062 : add outer reference in VIEWs. CONTEXT_ANALYSIS_ONLY_VIEW devided on two: really view and others (mostly PS) Potential tables aliases found and fixed outer references printed as an expression --- mysql-test/main/alias_in_where.result | 50 +++++++++++++++++++++++++++++++ mysql-test/main/alias_in_where.test | 30 +++++++++++++++++++ sql/item.cc | 6 ++-- sql/item.h | 30 ++++++++++++++++++- sql/item_func.cc | 2 +- sql/mysqld.h | 3 +- sql/sp_rcontext.cc | 4 +-- sql/sql_base.cc | 43 ++++++++++++++++++++++++++- sql/sql_base.h | 3 +- sql/sql_lex.cc | 55 +++++++++++++++++++++++++++++++++++ sql/sql_lex.h | 11 +++++-- sql/sql_prepare.cc | 2 +- sql/sql_priv.h | 12 ++++---- sql/sql_select.cc | 2 +- sql/sql_show.cc | 4 +-- sql/sql_tvc.cc | 2 +- sql/sql_union.cc | 10 +++---- sql/sql_view.cc | 2 +- sql/table.cc | 6 ++-- 19 files changed, 247 insertions(+), 30 deletions(-) diff --git a/mysql-test/main/alias_in_where.result b/mysql-test/main/alias_in_where.result index 05094d1d545..b66b3ed169a 100644 --- a/mysql-test/main/alias_in_where.result +++ b/mysql-test/main/alias_in_where.result @@ -374,4 +374,54 @@ a a NULL 5 NULL 10 drop tables t1,t3; +# +# test of possible table alias problem +# +create table t1 (a int, b int); +insert into t1 values (1,1), (5,5), (10, 10); +set sql_mode="ALIASES_IN_WHERE"; +create view v1 as select a, (select t1.a from t1 limit 1) as cc from t1; +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,(select `t__1__0__`.`a` from `t1` `t__1__0__` limit 1) AS `cc` from `t1` latin1 latin1_swedish_ci +select * from v1; +a cc +1 1 +5 1 +10 1 +select a, (select t1.a from t1 limit 1) as cc from t1; +a cc +1 1 +5 1 +10 1 +drop view v1; +drop table t1; +# +# test of view with outer reference and changing sql_mode +# +create table t1 (a int, b int); +insert into t1 values (1,1), (2,2), (10, 10); +create view v1 as select a+1 as d, (select b from t1 where d=a) as cc from t1; +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` + 1 AS `d`,(select `t__1__0__`.`b` from `t1` `t__1__0__` where `t1`.`a` + 1 = `t__1__0__`.`a`) AS `cc` from `t1` latin1 latin1_swedish_ci +select * from v1; +d cc +2 2 +3 NULL +11 NULL +select a+1 as d, (select b from t1 where d=a) as cc from t1; +d cc +2 2 +3 NULL +11 NULL +set sql_mode=""; +select * from v1; +d cc +2 2 +3 NULL +11 NULL +set sql_mode="ALIASES_IN_WHERE"; +drop view v1; +drop table t1; set @@sql_mode= @save_sql_mode; diff --git a/mysql-test/main/alias_in_where.test b/mysql-test/main/alias_in_where.test index 5073446e435..7638e96ecc3 100644 --- a/mysql-test/main/alias_in_where.test +++ b/mysql-test/main/alias_in_where.test @@ -265,4 +265,34 @@ execute stmt; drop tables t1,t3; + +--echo # +--echo # test of possible table alias problem +--echo # + +create table t1 (a int, b int); +insert into t1 values (1,1), (5,5), (10, 10); +set sql_mode="ALIASES_IN_WHERE"; +create view v1 as select a, (select t1.a from t1 limit 1) as cc from t1; +show create view v1; +select * from v1; +select a, (select t1.a from t1 limit 1) as cc from t1; +drop view v1; +drop table t1; + +--echo # +--echo # test of view with outer reference and changing sql_mode +--echo # +create table t1 (a int, b int); +insert into t1 values (1,1), (2,2), (10, 10); +create view v1 as select a+1 as d, (select b from t1 where d=a) as cc from t1; +show create view v1; +select * from v1; +select a+1 as d, (select b from t1 where d=a) as cc from t1; +set sql_mode=""; +select * from v1; +set sql_mode="ALIASES_IN_WHERE"; +drop view v1; +drop table t1; + set @@sql_mode= @save_sql_mode; diff --git a/sql/item.cc b/sql/item.cc index 10107d137dd..eb3cc17378e 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -8251,7 +8251,8 @@ bool Item_ref_alias::fix_fields(THD *thd, Item **reference) { // It is outer resolved field Item_outer_ref *rf= new(thd->mem_root) Item_outer_ref(thd, context, ref, - {0, 0}, name, true); + {0, 0}, name, + true, true); rf->base_flags&= ~item_base_t::FIXED; if (!rf) return TRUE; @@ -8412,7 +8413,8 @@ void Item_ref::print(String *str, enum_query_type query_type) if ((*ref)->type() != Item::CACHE_ITEM && (*ref)->type() != Item::WINDOW_FUNC_ITEM && ref_type() != VIEW_REF && - !table_name.str && name.str && alias_name_used) + !table_name.str && name.str && alias_name_used && + !(query_type & QT_FORCE_REF_EXPRESSION)) { THD *thd= current_thd; append_identifier(thd, str, &(*ref)->real_item()->name); diff --git a/sql/item.h b/sql/item.h index 6e0e9f707c3..04de60460db 100644 --- a/sql/item.h +++ b/sql/item.h @@ -33,6 +33,12 @@ C_MODE_START #include <ma_dyncol.h> +struct st_replace_table_processor_param +{ + LEX_CSTRING new_alias; + LEX_CSTRING old_alias; +}; + /* A prototype for a C-compatible structure to store a value of any data type. Currently it has to stay in /sql, as it depends on String and my_decimal. @@ -2158,6 +2164,7 @@ class Item :public Value_source, is_expensive_cache= (int8)(-1); return 0; } + virtual bool replace_table_processor(void *arg) { return 0; } /** Check db/table_name if they defined in item and match arg values @@ -3495,6 +3502,16 @@ class Item_ident :public Item_result_field const char *db_name, const char *table_name, List_iterator<Item> *it, bool any_privileges); + virtual bool replace_table_processor(void *arg) override + { + st_replace_table_processor_param *param= + ((st_replace_table_processor_param *)arg); + DBUG_ASSERT(param->old_alias.length > 0); + if (table_name.length == param->old_alias.length && + strncmp(table_name.str, param->old_alias.str, table_name.length) == 0) + orig_table_name= table_name= param->new_alias; + return 0; + } }; @@ -6202,6 +6219,7 @@ class Item_direct_view_ref :public Item_direct_ref class Item_sum; class Item_outer_ref :public Item_direct_ref { + bool outer_alias; public: Item *outer_ref; /* The aggregate function under which this outer ref is used, if any. */ @@ -6216,6 +6234,7 @@ class Item_outer_ref :public Item_direct_ref Item_field *outer_field_arg): Item_direct_ref(thd, context_arg, 0, outer_field_arg->table_name, outer_field_arg->field_name), + outer_alias(false), outer_ref(outer_field_arg), in_sum_func(0), found_in_select_list(0), found_in_group_by(0) { @@ -6226,9 +6245,10 @@ class Item_outer_ref :public Item_direct_ref } Item_outer_ref(THD *thd, Name_resolution_context *context_arg, Item **item, const LEX_CSTRING &table_name_arg, LEX_CSTRING &field_name_arg, - bool alias_name_used_arg): + bool alias_name_used_arg, bool alias= false): Item_direct_ref(thd, context_arg, item, table_name_arg, field_name_arg, alias_name_used_arg), + outer_alias(alias), outer_ref(0), in_sum_func(0), found_in_select_list(1), found_in_group_by(0) {} void save_in_result_field(bool no_conversions) override @@ -6245,6 +6265,14 @@ class Item_outer_ref :public Item_direct_ref table_map not_null_tables() const override { return 0; } Ref_Type ref_type() override { return OUTER_REF; } bool check_inner_refs_processor(void * arg) override; + void print(String *str, enum_query_type query_type) override + { + if (outer_alias && (query_type & QT_VIEW_INTERNAL)) + (*ref)->print(str, enum_query_type(((uint)query_type) | + QT_FORCE_REF_EXPRESSION)); + else + Item_direct_ref::print(str, query_type); + } }; diff --git a/sql/item_func.cc b/sql/item_func.cc index 965809ff460..129f6cf0eb2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6702,7 +6702,7 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) Checking privileges to execute the function while creating view and executing the function of select. */ - if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) || + if (!(thd->lex->is_view_context_analysis()) || (thd->lex->sql_command == SQLCOM_CREATE_VIEW)) { Security_context *save_security_ctx= thd->security_ctx; diff --git a/sql/mysqld.h b/sql/mysqld.h index 9cb7423f455..ae05eab3c71 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -870,7 +870,6 @@ enum enum_query_type QT_ITEM_ORIGINAL_FUNC_NULLIF= (1 << 7), /// good for parsing QT_PARSABLE= (1 << 8), - /// This value means focus on readability, not on ability to parse back, etc. QT_EXPLAIN= QT_TO_SYSTEM_CHARSET | QT_ITEM_IDENT_SKIP_DB_NAMES | @@ -895,6 +894,8 @@ enum enum_query_type // it evaluates to. Should be used for error messages, so that they // don't reveal values. QT_NO_DATA_EXPANSION= (1 << 9), + // Force expression instead of aliases + QT_FORCE_REF_EXPRESSION= (1 << 12) }; diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index c4c19dd39f6..c2cedad1cf9 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -238,7 +238,7 @@ bool Qualified_column_ident::resolve_type_ref(THD *thd, Column_definition *def) sp_lex_local lex(thd, thd->lex); thd->lex= &lex; - lex.context_analysis_only= CONTEXT_ANALYSIS_ONLY_VIEW; + lex.context_analysis_only= CONTEXT_ANALYSIS_ONLY_PS; // Make %TYPE variables see temporary tables that shadow permanent tables thd->temporary_tables= open_tables_state_backup.temporary_tables; @@ -297,7 +297,7 @@ bool Table_ident::resolve_table_rowtype_ref(THD *thd, sp_lex_local lex(thd, thd->lex); thd->lex= &lex; - lex.context_analysis_only= CONTEXT_ANALYSIS_ONLY_VIEW; + lex.context_analysis_only= CONTEXT_ANALYSIS_ONLY_PS; // Make %ROWTYPE variables see temporary tables that shadow permanent tables thd->temporary_tables= open_tables_state_backup.temporary_tables; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 62c7af44256..b72606fbc6c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7656,13 +7656,54 @@ static enum check_dep_loops_res check_dep_loops(THD* thd, return LOOP_OK; } +static bool check_and_fix_table_aliases(THD *thd, + Name_resolution_context *context) +{ + for (TABLE_LIST *t= context->first_name_resolution_table; + t; + t= t->next_local) + { + /* + checked by add_table_to_list + if (context->select_lex->find_table_alias_in_the_from_clause(t)) + { + my_error(ER_NONUNIQ_TABLE, MYF(0), t->alias.str); + return true; + } + */ + Name_resolution_context *c= context->outer_context; + for(; c; c= c->outer_context) + { + if (c->select_lex->find_table_alias_in_the_from_clause(t)) + { + // possible alias conflicts + if (context->select_lex->change_to_unique_table_alias(t)) + return true; + break; // it will be unique, there is no sens to continue this check + } + } + } + return false; +} + bool pre_setup_aliases(THD *thd, List<Item> &fields, Item **conds, - Item ***current_select_list_fix) + Name_resolution_context *context, + Item ***current_select_list_fix) { List_iterator<Item> it(fields); uint num= fields.elements; DBUG_ENTER("pre_setup_aliases"); + /* + If it is CREATE VIEW we have to check and fix conflicting table aliases + on this level (before fix_field on this level) and on this level only + (compatibility for other levels is already checked before) + */ + if ((thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW_REAL) && + check_and_fix_table_aliases(thd, context)) + DBUG_RETURN(1); + + // Process SELECT-list Cyclic_dep_check *ctrl= (Cyclic_dep_check *) diff --git a/sql/sql_base.h b/sql/sql_base.h index 31a64a63d2d..05b9807cad1 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -186,7 +186,8 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array, List<Item> &item, enum_column_usage column_usage, List<Item> *sum_func_list, List<Item> *pre_fix, bool allow_sum_func, Item ***progress_pointer= NULL); -bool pre_setup_aliases(THD*, List<Item> &, Item **, Item ***); +bool pre_setup_aliases(THD*, List<Item> &, Item**, + Name_resolution_context *, Item ***); void unfix_fields(List<Item> &items); bool fill_record(THD * thd, TABLE *table_arg, List<Item> &fields, List<Item> &values, bool ignore_errors, bool update); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 53bf876eb75..821b597b3de 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -36,6 +36,7 @@ #include "sql_partition.h" #include "sql_partition_admin.h" // Sql_cmd_alter_table_*_part #include "event_parse_data.h" +#include <sql_string.h> // stringcmp void LEX::parse_error(uint err_number) { @@ -10416,6 +10417,60 @@ bool SELECT_LEX::make_unique_derived_name(THD *thd, LEX_CSTRING *alias) } +bool SELECT_LEX::find_table_alias_in_the_from_clause(TABLE_LIST *table) +{ + for(TABLE_LIST *t=get_table_list(); t; t= t->next_local) + { + if (table->alias.length == t->alias.length && + table != t && + strncmp(table->alias.str, t->alias.str, table->alias.length) == 0) + return TRUE; + } + return FALSE; +} + + +bool SELECT_LEX::change_to_unique_table_alias(TABLE_LIST *table) +{ + char buffer[1+2*3+2*11+1]; + + uint cnt= 0; + for (TABLE_LIST *t=get_table_list(); t && t != table; t= t->next_local) + cnt++; + int len= my_snprintf(buffer, sizeof(buffer) - 1, + "t__%d__%u__", nest_level, cnt); + DBUG_ASSERT(len >= 1+2*3+2); + + st_replace_table_processor_param param; + param.old_alias= table->alias; + table->alias.length= (size_t) len; + if (!(table->alias.str= strmake_root(parent_lex->thd->stmt_arena->mem_root, + buffer, len))) + return true; + table->is_alias= TRUE; + if (table->table) + { + table->table->alias_name_used= TRUE; + for (Field **field_ptr= table->table->field; *field_ptr; field_ptr++) + { + field_ptr[0]->table_name= &table->alias.str; + } + } + param.new_alias= table->alias; + if (where) + where->walk(&Item::replace_table_processor, FALSE, (void*)(¶m)); + if (table->on_expr) + table->on_expr->walk(&Item::replace_table_processor, FALSE, + (void*)(¶m)); + List_iterator_fast<Item> it(item_list); + Item *item; + while((item= it++)) + { + item->walk(&Item::replace_table_processor, FALSE, (void*)(¶m)); + } + return false; +} + /* Make a new sp_instr_stmt and set its m_query to a concatenation of two strings. diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 8b4bdc3a19e..4996db30c30 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1654,6 +1654,9 @@ class st_select_lex: public st_select_lex_node void lex_start(LEX *plex); bool is_unit_nest() { return (nest_flags & UNIT_NEST_FL); } void mark_as_unit_nest() { nest_flags= UNIT_NEST_FL; } + + bool find_table_alias_in_the_from_clause(TABLE_LIST *table); + bool change_to_unique_table_alias(TABLE_LIST *table); }; typedef class st_select_lex SELECT_LEX; @@ -3445,6 +3448,7 @@ struct LEX: public Query_tables_list holds number of tables from which we will delete records. */ uint table_count; + uint context_analysis_only; uint8 describe; /* @@ -3453,7 +3457,6 @@ struct LEX: public Query_tables_list DERIVED_SUBQUERY and DERIVED_VIEW). */ uint8 derived_tables; - uint8 context_analysis_only; uint8 lex_options; // see OPTION_LEX_* enum_nmresolve nm_resolve_mode; @@ -3611,12 +3614,14 @@ struct LEX: public Query_tables_list return (context_analysis_only & (CONTEXT_ANALYSIS_ONLY_PREPARE | CONTEXT_ANALYSIS_ONLY_VCOL_EXPR | - CONTEXT_ANALYSIS_ONLY_VIEW)); + CONTEXT_ANALYSIS_ONLY_PS | + CONTEXT_ANALYSIS_ONLY_VIEW_REAL)); } inline bool is_view_context_analysis() { - return (context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW); + return (context_analysis_only & (CONTEXT_ANALYSIS_ONLY_PS | + CONTEXT_ANALYSIS_ONLY_VIEW_REAL)); } inline void uncacheable(uint8 cause) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 59006638294..a064df6264d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2073,7 +2073,7 @@ static bool mysql_test_create_view(Prepared_statement *stmt) if (thd->open_temporary_tables(tables)) goto err; - lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; + lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW_REAL; if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL, DT_INIT | DT_PREPARE)) goto err; diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 07f07a7150f..126f02206b8 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -297,18 +297,20 @@ any optimizations: afterwards definition of the view will be reconstructed by means of ::print() methods and written to to an .frm file. We need this definition to stay untouched. -*/ -#define CONTEXT_ANALYSIS_ONLY_VIEW 2 +*/ +#define CONTEXT_ANALYSIS_ONLY_VIEW_REAL 2 +// The same as above but mostly for PS +#define CONTEXT_ANALYSIS_ONLY_PS 4 /* Don't evaluate this subquery during derived table prepare even if it's a constant one. */ -#define CONTEXT_ANALYSIS_ONLY_DERIVED 4 +#define CONTEXT_ANALYSIS_ONLY_DERIVED 8 /* Don't evaluate constant sub-expressions of virtual column expressions when opening tables -*/ -#define CONTEXT_ANALYSIS_ONLY_VCOL_EXPR 8 +*/ +#define CONTEXT_ANALYSIS_ONLY_VCOL_EXPR 16 /* diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9d40e238cbf..0f7fa6a81e9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1395,7 +1395,7 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num, if ((thd->lex->nm_resolve_mode == NMRESOLVE_ALIAS || (thd->lex->nm_resolve_mode == NMRESOLVE_NONE && thd->variables.sql_mode & MODE_ALIASES_IN_WHERE)) && - pre_setup_aliases(thd, fields_list, &conds, + pre_setup_aliases(thd, fields_list, &conds, &select_lex->context, &select_lex->current_select_list_fix)) DBUG_RETURN(-1); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a2cd4e232f5..a980e071795 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1185,7 +1185,7 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list, /* Access is granted. Execute the command. */ /* We want to preserve the tree for views. */ - lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; + lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_PS; { /* @@ -4582,7 +4582,7 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root, lex->sql_command= old_lex->sql_command; /* Disable constant subquery evaluation as we won't be locking tables. */ - lex->context_analysis_only= CONTEXT_ANALYSIS_ONLY_VIEW; + lex->context_analysis_only= CONTEXT_ANALYSIS_ONLY_PS; /* Some of process_table() functions rely on wildcard being passed from diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 49f319b3856..b28c58e6d7d 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -303,7 +303,7 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl, /* setup_order() for a TVC is not called when the following is true - (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) + (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_PS) */ thd->where="order clause"; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index f75391c4503..5074b12e81d 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1501,7 +1501,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, !sl->tvc->to_be_wrapped_as_with_tail()) { SELECT_LEX_UNIT *unit= sl->master_unit(); - if (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) + if (thd->lex->is_view_context_analysis()) { unit->fake_select_lex= 0; unit->saved_fake_select_lex= 0; @@ -1538,7 +1538,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, if (sl->tvc) { if (sl->tvc->to_be_wrapped_as_with_tail() && - !(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)) + !(thd->lex->is_view_context_analysis())) { st_select_lex *wrapper_sl= wrap_tvc_with_tail(thd, sl); @@ -1802,7 +1802,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, if (fake_select_lex != NULL && (thd->stmt_arena->is_stmt_prepare() || - (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW))) + (thd->lex->is_view_context_analysis()))) { /* Validate the global parameters of this union */ @@ -1841,7 +1841,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, } if (fake_select_lex != NULL && (thd->stmt_arena->is_stmt_prepare() || - (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW))) + (thd->lex->is_view_context_analysis()))) { if (!fake_select_lex->join && !(fake_select_lex->join= @@ -1904,7 +1904,7 @@ void st_select_lex_unit::optimize_bag_operation(bool is_outer_distinct) recursive */ if ((thd->variables.sql_mode & MODE_ORACLE) || - (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) || + (thd->lex->is_view_context_analysis()) || (fake_select_lex != NULL && thd->stmt_arena->is_stmt_prepare()) || (with_element && with_element->is_recursive )) return; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 3fc55552f6b..14fe87a5779 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -547,7 +547,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } /* prepare select to resolve all fields */ - lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; + lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW_REAL; if (unit->prepare(unit->derived, 0, 0)) { /* diff --git a/sql/table.cc b/sql/table.cc index c9420892160..f0ecd78e7cf 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3993,7 +3993,9 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, DBUG_PRINT("enter",("name: '%s.%s' form: %p", share->db.str, share->table_name.str, outparam)); - thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_VIEW; // not a view + // not a view + thd->lex->context_analysis_only&= ~(CONTEXT_ANALYSIS_ONLY_PS | + CONTEXT_ANALYSIS_ONLY_VIEW_REAL); error= OPEN_FRM_ERROR_ALREADY_ISSUED; // for OOM errors below bzero((char*) outparam, sizeof(*outparam)); @@ -9369,7 +9371,7 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view) { if (is_view() || (unit->prepared && - !(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW))) + !(thd->lex->is_view_context_analysis()))) create_field_translation(thd); }
participants (1)
-
psergey