[Commits] e801d6fd007: MENT-1062 : add outer reference in VIEWs.

psergey sergey at mariadb.com
Fri Jun 18 00:43:34 EEST 2021


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*)(&param));
+  if (table->on_expr)
+    table->on_expr->walk(&Item::replace_table_processor, FALSE,
+                         (void*)(&param));
+  List_iterator_fast<Item> it(item_list);
+  Item *item;
+  while((item= it++))
+  {
+    item->walk(&Item::replace_table_processor, FALSE, (void*)(&param));
+  }
+  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);
   }
 


More information about the commits mailing list