List:Internals« Previous MessageNext Message »
From:timour Date:December 7 2005 9:47am
Subject:bk commit into 5.1 tree (timour:1.1962)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of timka. When timka does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.1962 05/12/07 10:47:43 timour@stripped +13 -0
  Merge mysql.com:/home/timka/mysql/src/5.0-2486
  into  mysql.com:/home/timka/mysql/src/5.1-dbg

  sql/table.cc
    1.193 05/12/07 10:47:39 timour@stripped +0 -0
    SCCS merged

  sql/sql_base.cc
    1.284 05/12/07 10:47:39 timour@stripped +0 -0
    SCCS merged

  sql/table.h
    1.118 05/12/07 08:28:13 timour@stripped +0 -0
    Auto merged

  sql/sql_yacc.yy
    1.427 05/12/07 08:28:12 timour@stripped +0 -0
    Auto merged

  sql/sql_parse.cc
    1.493 05/12/07 08:28:12 timour@stripped +0 -0
    Auto merged

  sql/sql_lex.h
    1.209 05/12/07 08:28:12 timour@stripped +0 -0
    Auto merged

  sql/sql_lex.cc
    1.168 05/12/07 08:28:11 timour@stripped +0 -0
    Auto merged

  sql/sql_insert.cc
    1.177 05/12/07 08:28:11 timour@stripped +0 -0
    Auto merged

  sql/sql_acl.h
    1.42 05/12/07 08:28:11 timour@stripped +0 -0
    Auto merged

  sql/sql_acl.cc
    1.165 05/12/07 08:28:11 timour@stripped +0 -0
    Auto merged

  sql/mysql_priv.h
    1.352 05/12/07 08:28:11 timour@stripped +0 -0
    Auto merged

  sql/item.h
    1.186 05/12/07 08:28:10 timour@stripped +0 -0
    Auto merged

  sql/item.cc
    1.159 05/12/07 08:28:10 timour@stripped +0 -0
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	timour
# Host:	lamia.home
# Root:	/home/timka/mysql/src/5.1-dbg/RESYNC

--- 1.158/sql/item.cc	2005-12-02 19:42:57 +02:00
+++ 1.159/sql/item.cc	2005-12-07 08:28:10 +02:00
@@ -5207,7 +5207,7 @@
     set field_idx properly.
   */
   (void)find_field_in_table(thd, table, field_name, (uint) strlen(field_name),
-                            0, 0, &field_idx, 0);
+                            0, &field_idx);
   thd->set_query_id= save_set_query_id;
   triggers= table->triggers;
 }

--- 1.185/sql/item.h	2005-12-02 19:42:58 +02:00
+++ 1.186/sql/item.h	2005-12-07 08:28:10 +02:00
@@ -326,6 +326,48 @@
 };
 
 
+/*
+  Store and restore the current state of a name resolution context.
+*/
+
+class Name_resolution_context_state
+{
+private:
+  TABLE_LIST *save_table_list;
+  TABLE_LIST *save_first_name_resolution_table;
+  TABLE_LIST *save_next_name_resolution_table;
+  bool        save_resolve_in_select_list;
+
+public:
+  TABLE_LIST *save_next_local;
+
+public:
+  /* Save the state of a name resolution context. */
+  void save_state(Name_resolution_context *context, TABLE_LIST *table_list)
+  {
+    save_table_list=                  context->table_list;
+    save_first_name_resolution_table= context->first_name_resolution_table;
+    save_next_name_resolution_table=  (context->first_name_resolution_table) ?
+                                      context->first_name_resolution_table->
+                                               next_name_resolution_table :
+                                      NULL;
+    save_resolve_in_select_list=      context->resolve_in_select_list;
+    save_next_local=                  table_list->next_local;
+  }
+
+  /* Restore a name resolution context from saved state. */
+  void restore_state(Name_resolution_context *context, TABLE_LIST *table_list)
+  {
+    table_list->next_local=                save_next_local;
+    context->table_list=                   save_table_list;
+    context->first_name_resolution_table=  save_first_name_resolution_table;
+    if (context->first_name_resolution_table)
+      context->first_name_resolution_table->
+               next_name_resolution_table= save_next_name_resolution_table;
+    context->resolve_in_select_list=       save_resolve_in_select_list;
+  }
+};
+
 /*************************************************************************/
 
 typedef bool (Item::*Item_processor)(byte *arg);

--- 1.351/sql/mysql_priv.h	2005-12-06 09:29:01 +02:00
+++ 1.352/sql/mysql_priv.h	2005-12-07 08:28:11 +02:00
@@ -820,18 +820,15 @@
                      bool check_privileges, bool register_tree_change);
 Field *
 find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
-                        const char *name, const char *item_name,
-                        const char *table_name, const char *db_name,
-                        uint length, Item **ref,
-                        bool check_grants_table, bool check_grants_view,
-                        bool allow_rowid,
+                        const char *name, uint length,
+                        const char *item_name, const char *db_name,
+                        const char *table_name, Item **ref,
+                        bool check_privileges, bool allow_rowid,
                         uint *cached_field_index_ptr,
                         bool register_tree_change, TABLE_LIST **actual_table);
 Field *
-find_field_in_table(THD *thd, TABLE *table, const char *name,
-                    uint length, bool check_grants, bool allow_rowid,
-                    uint *cached_field_index_ptr,
-                    Security_context *sctx);
+find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
+                    bool allow_rowid, uint *cached_field_index_ptr);
 Field *
 find_field_in_table_sef(TABLE *table, const char *name);
 
@@ -950,8 +947,9 @@
 				uint uint_geom_type);
 void store_position_for_column(const char *name);
 bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc);
-Name_resolution_context *make_join_on_context(THD *thd, TABLE_LIST *left_op,
-                                              TABLE_LIST *right_op);
+bool push_new_name_resolution_context(THD *thd,
+                                      TABLE_LIST *left_op,
+                                      TABLE_LIST *right_op);
 void add_join_on(TABLE_LIST *b,Item *expr);
 void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields);
 bool add_proc_to_list(THD *thd, Item *item);

--- 1.164/sql/sql_acl.cc	2005-11-28 21:07:12 +02:00
+++ 1.165/sql/sql_acl.cc	2005-12-07 08:28:11 +02:00
@@ -2760,8 +2760,9 @@
         uint unused_field_idx= NO_CACHED_FIELD_INDEX;
         TABLE_LIST *dummy;
         Field *f=find_field_in_table_ref(thd, table_list, column->column.ptr(),
+                                         column->column.length(),
                                          column->column.ptr(), NULL, NULL,
-                                         column->column.length(), 0, 1, 1, 0,
+                                         NULL, TRUE, FALSE,
                                          &unused_field_idx, FALSE, &dummy);
         if (f == (Field*)0)
         {
@@ -3616,11 +3617,28 @@
 }
 
 
+/*
+  Check column rights in given security context
+
+  SYNOPSIS
+    check_grant_column()
+    thd                  thread handler
+    grant                grant information structure
+    db_name              db name
+    table_name           table  name
+    name                 column name
+    length               column name length
+    sctx                 security context
+
+  RETURN
+    FALSE OK
+    TRUE  access denied
+*/
+
 bool check_grant_column(THD *thd, GRANT_INFO *grant,
 			const char *db_name, const char *table_name,
-			const char *name, uint length, uint show_tables)
+			const char *name, uint length,  Security_context *sctx)
 {
-  Security_context *sctx= thd->security_ctx;
   GRANT_TABLE *grant_table;
   GRANT_COLUMN *grant_column;
   ulong want_access= grant->want_privilege & ~grant->privilege;
@@ -3651,28 +3669,74 @@
     rw_unlock(&LOCK_grant);
     DBUG_RETURN(0);
   }
-#ifdef NOT_USED
-  if (show_tables && (grant_column || grant->privilege & COL_ACLS))
-  {
-    rw_unlock(&LOCK_grant);			/* purecov: deadcode */
-    DBUG_RETURN(0);				/* purecov: deadcode */
-  }
-#endif
 
 err:
   rw_unlock(&LOCK_grant);
-  if (!show_tables)
+  char command[128];
+  get_privilege_desc(command, sizeof(command), want_access);
+  my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
+           command,
+           sctx->priv_user,
+           sctx->host_or_ip,
+           name,
+           table_name);
+  DBUG_RETURN(1);
+}
+
+
+/*
+  Check the access right to a column depending on the type of table.
+
+  SYNOPSIS
+    check_column_grant_in_table_ref()
+    thd              thread handler
+    table_ref        table reference where to check the field
+    name             name of field to check
+    length           length of name
+
+  DESCRIPTION
+    Check the access rights to a column depending on the type of table
+    reference where the column is checked. The function provides a
+    generic interface to check column access rights that hides the
+    heterogeneity of the column representation - whether it is a view
+    or a stored table colum.
+
+  RETURN
+    FALSE OK
+    TRUE  access denied
+*/
+
+bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
+                                     const char *name, uint length)
+{
+  GRANT_INFO *grant;
+  const char *db_name;
+  const char *table_name;
+  Security_context *sctx= test(table_ref->security_ctx) ?
+                          table_ref->security_ctx : thd->security_ctx;
+
+  if (table_ref->view || table_ref->field_translation)
+  {
+    /* View or derived information schema table. */
+    grant= &(table_ref->grant);
+    db_name= table_ref->view_db.str;
+    table_name= table_ref->view_name.str;
+  }
+  else
   {
-    char command[128];
-    get_privilege_desc(command, sizeof(command), want_access);
-    my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
-             command,
-             sctx->priv_user,
-             sctx->host_or_ip,
-             name,
-             table_name);
+    /* Normal or temporary table. */
+    TABLE *table= table_ref->table;
+    grant= &(table->grant);
+    db_name= table->s->db;
+    table_name= table->s->table_name;
   }
-  DBUG_RETURN(1);
+
+  if (grant->want_privilege)
+    return check_grant_column(thd, grant, db_name, table_name, name,
+                              length, sctx);
+  else
+    return FALSE;
+
 }
 
 

--- 1.41/sql/sql_acl.h	2005-10-06 11:26:00 +03:00
+++ 1.42/sql/sql_acl.h	2005-12-07 08:28:11 +02:00
@@ -205,7 +205,9 @@
 		 uint show_command, uint number, bool dont_print_error);
 bool check_grant_column (THD *thd, GRANT_INFO *grant,
 			 const char *db_name, const char *table_name,
-			 const char *name, uint length, uint show_command=0);
+			 const char *name, uint length, Security_context *sctx);
+bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
+                                     const char *name, uint length);
 bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant,
                              const char* db_name, const char *table_name,
                              Field_iterator *fields);

--- 1.283/sql/sql_base.cc	2005-12-07 04:22:48 +02:00
+++ 1.284/sql/sql_base.cc	2005-12-07 10:47:39 +02:00
@@ -3368,47 +3368,6 @@
 }
 
 
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-/*
-  Check column rights in given security context
-
-  SYNOPSIS
-    check_grant_column_in_sctx()
-    thd                  thread handler
-    grant                grant information structure
-    db                   db name
-    table                table  name
-    name                 column name
-    length               column name length
-    check_grants         need to check grants
-    sctx                 0 or security context
-
-  RETURN
-    FALSE OK
-    TRUE  access denied
-*/
-
-static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
-                                       const char *db, const char *table,
-                                       const char *name, uint length,
-                                       bool check_grants,
-                                       Security_context *sctx)
-{
-  if (!check_grants)
-    return FALSE;
-  Security_context *save_security_ctx= thd->security_ctx;
-  bool res;
-  if (sctx)
-  {
-    thd->security_ctx= sctx;
-  }
-  res= check_grant_column(thd, grant, db, table, name, length);
-  thd->security_ctx= save_security_ctx;
-  return res;
-}
-#endif
-
-
 /*
   Find a field by name in a view that uses merge algorithm.
 
@@ -3417,11 +3376,10 @@
     thd				thread handler
     table_list			view to search for 'name'
     name			name of field
-    item_name                   name of item if it will be created (VIEW)
     length			length of name
+    item_name                   name of item if it will be created (VIEW)
     ref				expression substituted in VIEW should be passed
                                 using this reference (return view_ref_found)
-    check_grants		do check columns grants for view?
     register_tree_change        TRUE if ref is not stack variable and we
                                 need register changes in item tree
 
@@ -3433,8 +3391,8 @@
 
 static Field *
 find_field_in_view(THD *thd, TABLE_LIST *table_list,
-                   const char *name, const char *item_name,
-                   uint length, Item **ref, bool check_grants,
+                   const char *name, uint length,
+                   const char *item_name, Item **ref,
                    bool register_tree_change)
 {
   DBUG_ENTER("find_field_in_view");
@@ -3451,24 +3409,13 @@
   {
     if (!my_strcasecmp(system_charset_info, field_it.name(), name))
     {
-      if (table_list->schema_table_reformed)
-        /*
-          Translation table items are always Item_fields and fixed already
-          ('mysql_schema_table' function). So we can return ->field. It is
-          used only for 'show & where' commands.
-        */
-        DBUG_RETURN(((Item_field*) (field_it.item()))->field);
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-      if (check_grant_column_in_sctx(thd, &table_list->grant,
-                                     table_list->view_db.str,
-                                     table_list->view_name.str, name, length,
-                                     check_grants,
-                                     table_list->security_ctx))
-        DBUG_RETURN(WRONG_GRANT);
-#endif
       // in PS use own arena or data will be freed after prepare
       if (register_tree_change)
         arena= thd->activate_stmt_arena_if_needed(&backup);
+      /*
+        create_item() may, or may not create a new Item, depending on
+        the column reference. See create_view_field() for details.
+      */
       Item *item= field_it.create_item(thd);
       if (register_tree_change && arena)
         thd->restore_active_arena(arena, &backup);
@@ -3510,7 +3457,6 @@
     length		 [in]  length of name
     ref                  [in/out] if 'name' is resolved to a view field, ref is
                                set to point to the found view field
-    check_grants	 [in]  do check columns grants?
     register_tree_change [in]  TRUE if ref is not stack variable and we
                                need register changes in item tree
     actual_table         [out] the original table reference where the field
@@ -3531,8 +3477,7 @@
 
 static Field *
 find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
-                           uint length, Item **ref, bool check_grants,
-                           bool register_tree_change,
+                           uint length, Item **ref, bool register_tree_change,
                            TABLE_LIST **actual_table)
 {
   List_iterator_fast<Natural_join_column>
@@ -3557,23 +3502,16 @@
       break;
   }
 
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-  if (check_grants && nj_col->check_grants(thd, name, length))
-    DBUG_RETURN(WRONG_GRANT);
-#endif
-
   if (nj_col->view_field)
   {
     Item *item;
-    /*
-      The found field is a view field, we do as in find_field_in_view()
-      and return a pointer to pointer to the Item of that field.
-    */
     if (register_tree_change)
       arena= thd->activate_stmt_arena_if_needed(&backup);
-
+    /*
+      create_item() may, or may not create a new Item, depending on the
+      column reference. See create_view_field() for details.
+    */
     item= nj_col->create_item(thd);
-
     if (register_tree_change && arena)
       thd->restore_active_arena(arena, &backup);
 
@@ -3619,7 +3557,6 @@
     table			table where to search for the field
     name			name of field
     length			length of name
-    check_grants		do check columns grants?
     allow_rowid			do allow finding of "_rowid" field?
     cached_field_index_ptr	cached position in field list (used to speedup
                                 lookup for fields in prepared tables)
@@ -3631,9 +3568,7 @@
 
 Field *
 find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
-                    bool check_grants, bool allow_rowid,
-                    uint *cached_field_index_ptr,
-                    Security_context *sctx)
+                    bool allow_rowid, uint *cached_field_index_ptr)
 {
   Field **field_ptr, *field;
   uint cached_field_index= *cached_field_index_ptr;
@@ -3683,13 +3618,6 @@
 
   update_field_dependencies(thd, field, table);
 
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-  if (check_grant_column_in_sctx(thd, &table->grant,
-                                 table->s->db.str, table->s->table_name.str,
-                                 name, length,
-                                 check_grants, sctx))
-    field= WRONG_GRANT;
-#endif
   DBUG_RETURN(field);
 }
 
@@ -3702,14 +3630,13 @@
     thd			   [in]  thread handler
     table_list		   [in]  table reference to search
     name		   [in]  name of field
+    length		   [in]  field length of name
     item_name              [in]  name of item if it will be created (VIEW)
-    table_name             [in]  optional table name that qualifies the field
     db_name                [in]  optional database name that qualifies the
-    length		   [in]  field length of name
+    table_name             [in]  optional table name that qualifies the field
     ref		       [in/out] if 'name' is resolved to a view field, ref
                                  is set to point to the found view field
-    check_grants_table	   [in]  do check columns grants for table?
-    check_grants_view	   [in]  do check columns grants for view?
+    check_privileges       [in]  check privileges
     allow_rowid		   [in]  do allow finding of "_rowid" field?
     cached_field_index_ptr [in]  cached position in field list (used to
                                  speedup lookup for fields in prepared tables)
@@ -3739,11 +3666,11 @@
 
 Field *
 find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
-                        const char *name, const char *item_name,
-                        const char *table_name, const char *db_name,
-                        uint length, Item **ref,
-                        bool check_grants_table, bool check_grants_view,
-                        bool allow_rowid, uint *cached_field_index_ptr,
+                        const char *name, uint length,
+                        const char *item_name, const char *db_name,
+                        const char *table_name, Item **ref,
+                        bool check_privileges, bool allow_rowid,
+                        uint *cached_field_index_ptr,
                         bool register_tree_change, TABLE_LIST **actual_table)
 {
   Field *fld;
@@ -3788,8 +3715,7 @@
   if (table_list->field_translation)
   {
     /* 'table_list' is a view or an information schema table. */
-    if ((fld= find_field_in_view(thd, table_list, name, item_name, length,
-                                 ref, check_grants_view,
+    if ((fld= find_field_in_view(thd, table_list, name, length, item_name, ref,
                                  register_tree_change)))
       *actual_table= table_list;
   }
@@ -3798,20 +3724,9 @@
     /* 'table_list' is a stored table. */
     DBUG_ASSERT(table_list->table);
     if ((fld= find_field_in_table(thd, table_list->table, name, length,
-                                  check_grants_table, allow_rowid,
-                                  cached_field_index_ptr,
-                                  table_list->security_ctx)))
+                                  allow_rowid,
+                                  cached_field_index_ptr)))
       *actual_table= table_list;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-    /* check for views with temporary table algorithm */
-    if (check_grants_view && table_list->view &&
-        fld && fld != WRONG_GRANT &&
-        check_grant_column(thd, &table_list->grant,
-                           table_list->view_db.str,
-                           table_list->view_name.str,
-                           name, length))
-    fld= WRONG_GRANT;
-#endif
   }
   else
   {
@@ -3828,11 +3743,10 @@
       TABLE_LIST *table;
       while ((table= it++))
       {
-        if ((fld= find_field_in_table_ref(thd, table, name, item_name,
-                                          table_name, db_name, length, ref,
-                                          check_grants_table,
-                                          check_grants_view,
-                                          allow_rowid, cached_field_index_ptr,
+        if ((fld= find_field_in_table_ref(thd, table, name, length, item_name,
+                                          db_name, table_name, ref,
+                                          check_privileges, allow_rowid,
+                                          cached_field_index_ptr,
                                           register_tree_change, actual_table)))
           DBUG_RETURN(fld);
       }
@@ -3845,11 +3759,16 @@
       directly the top-most NATURAL/USING join.
     */
     fld= find_field_in_natural_join(thd, table_list, name, length, ref,
-                                    /* TIMOUR_TODO: check this with Sanja */
-                                    check_grants_table || check_grants_view,
                                     register_tree_change, actual_table);
   }
 
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+  /* Check if there are sufficient access rights to the found field. */
+  if (fld && check_privileges &&
+      check_column_grant_in_table_ref(thd, *actual_table, name, length))
+    fld= WRONG_GRANT;
+#endif
+
   DBUG_RETURN(fld);
 }
 
@@ -3967,21 +3886,11 @@
       */
     if (table_ref->table && !table_ref->view)
       found= find_field_in_table(thd, table_ref->table, name, length,
-                                 test(table_ref->table->
-                                      grant.want_privilege) &&
-                                 check_privileges,
-                                 1, &(item->cached_field_index),
-                                 table_ref->security_ctx);
+                                 TRUE, &(item->cached_field_index));
     else
-      found= find_field_in_table_ref(thd, table_ref, name, item->name,
-                                     NULL, NULL, length, ref,
-                                     (table_ref->table &&
-                                      test(table_ref->table->grant.
-                                           want_privilege) &&
-                                      check_privileges),
-                                     (test(table_ref->grant.want_privilege) &&
-                                      check_privileges),
-                                     1, &(item->cached_field_index),
+      found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
+                                     NULL, NULL, ref, check_privileges,
+                                     TRUE, &(item->cached_field_index),
                                      register_tree_change,
                                      &actual_table);
     if (found)
@@ -4021,17 +3930,9 @@
   for (; cur_table != last_table ;
        cur_table= cur_table->next_name_resolution_table)
   {
-    Field *cur_field= find_field_in_table_ref(thd, cur_table, name, item->name,
-                                              table_name, db,
-                                              length, ref,
-                                              (cur_table->table &&
-                                               test(cur_table->table->grant.
-                                                    want_privilege) &&
-                                               check_privileges),
-                                              (test(cur_table->grant.
-                                                    want_privilege)
-                                               && check_privileges),
-                                              allow_rowid,
+    Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
+                                              item->name, db, table_name, ref,
+                                              check_privileges, allow_rowid,
                                               &(item->cached_field_index),
                                               register_tree_change,
                                               &actual_table);
@@ -4439,7 +4340,7 @@
   {
     bool is_created_1;
     bool found= FALSE;
-    if (!(nj_col_1= it_1.get_or_create_column_ref(thd, &is_created_1)))
+    if (!(nj_col_1= it_1.get_or_create_column_ref(&is_created_1)))
       goto err;
     field_name_1= nj_col_1->name();
 
@@ -4460,7 +4361,7 @@
       bool is_created_2;
       Natural_join_column *cur_nj_col_2;
       const char *cur_field_name_2;
-      if (!(cur_nj_col_2= it_2.get_or_create_column_ref(thd, &is_created_2)))
+      if (!(cur_nj_col_2= it_2.get_or_create_column_ref(&is_created_2)))
         goto err;
       cur_field_name_2= cur_nj_col_2->name();
 
@@ -4656,13 +4557,7 @@
   /* Append the columns of the first join operand. */
   for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next())
   {
-    if (!(nj_col_1= it_1.get_or_create_column_ref(thd, &is_created)))
-      goto err;
-    /*
-      The following assert checks that mark_common_columns() was run and
-      we created the list table_ref_1->join_columns.
-    */
-    DBUG_ASSERT(!is_created);
+    nj_col_1= it_1.get_natural_column_ref();
     if (nj_col_1->is_common)
     {
       natural_using_join->join_columns->push_back(nj_col_1);
@@ -4708,13 +4603,7 @@
   /* Append the non-equi-join columns of the second join operand. */
   for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next())
   {
-    if (!(nj_col_2= it_2.get_or_create_column_ref(thd, &is_created)))
-      goto err;
-    /*
-      The following assert checks that mark_common_columns() was run and
-      we created the list table_ref_2->join_columns.
-    */
-    DBUG_ASSERT(!is_created);
+    nj_col_2= it_2.get_natural_column_ref();
     if (!nj_col_2->is_common)
       non_join_columns->push_back(nj_col_2);
     else
@@ -5449,8 +5338,7 @@
             because it was already created and stored with the natural join.
           */
           Natural_join_column *nj_col;
-          if (!(nj_col= field_iterator.get_or_create_column_ref(thd,
-                                                                &is_created)))
+          if (!(nj_col= field_iterator.get_or_create_column_ref(&is_created)))
             DBUG_RETURN(TRUE);
           DBUG_ASSERT(nj_col->table_field && !is_created);
           field_table= nj_col->table_ref->table;

--- 1.176/sql/sql_insert.cc	2005-11-24 06:23:46 +02:00
+++ 1.177/sql/sql_insert.cc	2005-12-07 08:28:11 +02:00
@@ -113,11 +113,7 @@
   {						// Part field list
     SELECT_LEX *select_lex= &thd->lex->select_lex;
     Name_resolution_context *context= &select_lex->context;
-    TABLE_LIST *save_next_local;
-    TABLE_LIST *save_table_list;
-    TABLE_LIST *save_first_name_resolution_table;
-    TABLE_LIST *save_next_name_resolution_table;
-    bool        save_resolve_in_select_list;
+    Name_resolution_context_state ctx_state;
     int res;
 
     if (fields.elements != values.elements)
@@ -130,14 +126,7 @@
     select_lex->no_wrap_view_item= TRUE;
 
     /* Save the state of the current name resolution context. */
-    save_table_list=                  context->table_list;
-    save_first_name_resolution_table= context->first_name_resolution_table;
-    save_next_name_resolution_table=  (context->first_name_resolution_table) ?
-                                      context->first_name_resolution_table->
-                                               next_name_resolution_table :
-                                      NULL;
-    save_resolve_in_select_list=      context->resolve_in_select_list;
-    save_next_local=                  table_list->next_local;
+    ctx_state.save_state(context, table_list);
 
     /*
       Perform name resolution only in the first table - 'table_list',
@@ -152,13 +141,7 @@
     res= setup_fields(thd, 0, fields, 2, 0, 0);
 
     /* Restore the current context. */
-    table_list->next_local=                save_next_local;
-    context->table_list=                   save_table_list;
-    context->first_name_resolution_table=  save_first_name_resolution_table;
-    if (context->first_name_resolution_table)
-      context->first_name_resolution_table->
-               next_name_resolution_table= save_next_name_resolution_table;
-    context->resolve_in_select_list=       save_resolve_in_select_list;
+    ctx_state.restore_state(context, table_list);
     thd->lex->select_lex.no_wrap_view_item= FALSE;
 
     if (res)
@@ -293,13 +276,10 @@
   ulonglong id;
   COPY_INFO info;
   TABLE *table= 0;
-  TABLE_LIST *save_table_list;
-  TABLE_LIST *save_next_local;
-  TABLE_LIST *save_first_name_resolution_table;
-  TABLE_LIST *save_next_name_resolution_table;
   List_iterator_fast<List_item> its(values_list);
   List_item *values;
   Name_resolution_context *context;
+  Name_resolution_context_state ctx_state;
 #ifndef EMBEDDED_LIBRARY
   char *query= thd->query;
 #endif
@@ -380,13 +360,7 @@
 
   context= &thd->lex->select_lex.context;
   /* Save the state of the current name resolution context. */
-  save_table_list=                  context->table_list;
-  save_first_name_resolution_table= context->first_name_resolution_table;
-  save_next_name_resolution_table=  (context->first_name_resolution_table) ?
-                                    context->first_name_resolution_table->
-                                             next_name_resolution_table :
-                                    NULL;
-  save_next_local=                  table_list->next_local;
+  ctx_state.save_state(context, table_list);
 
   /*
     Perform name resolution only in the first table - 'table_list',
@@ -410,16 +384,11 @@
   its.rewind ();
  
   /* Restore the current context. */
-  table_list->next_local= save_next_local;
-  context->first_name_resolution_table= save_first_name_resolution_table;
-  if (context->first_name_resolution_table)
-    context->first_name_resolution_table->
-             next_name_resolution_table= save_next_name_resolution_table;
+  ctx_state.restore_state(context, table_list);
 
   /*
     Fill in the given fields and dump it to the table file
   */
-
   info.records= info.deleted= info.copied= info.updated= 0;
   info.ignore= ignore;
   info.handle_duplicates=duplic;
@@ -827,11 +796,7 @@
 {
   SELECT_LEX *select_lex= &thd->lex->select_lex;
   Name_resolution_context *context= &select_lex->context;
-  TABLE_LIST *save_table_list;
-  TABLE_LIST *save_next_local;
-  TABLE_LIST *save_first_name_resolution_table;
-  TABLE_LIST *save_next_name_resolution_table;
-  bool        save_resolve_in_select_list;
+  Name_resolution_context_state ctx_state;
   bool insert_into_view= (table_list->view != 0);
   bool res= 0;
   DBUG_ENTER("mysql_prepare_insert");
@@ -871,15 +836,7 @@
     DBUG_RETURN(TRUE);
 
   /* Save the state of the current name resolution context. */
-  save_table_list=                  context->table_list;
-  /* Here first_name_resolution_table points to the first select table. */
-  save_first_name_resolution_table= context->first_name_resolution_table;
-  save_next_name_resolution_table=  (context->first_name_resolution_table) ?
-                                    context->first_name_resolution_table->
-                                             next_name_resolution_table :
-                                    NULL;
-  save_resolve_in_select_list=      context->resolve_in_select_list;
-  save_next_local=                  table_list->next_local;
+  ctx_state.save_state(context, table_list);
 
   /*
     Perform name resolution only in the first table - 'table_list',
@@ -904,23 +861,17 @@
     */       
     if (select_lex->group_list.elements == 0)
     {
-      context->table_list->next_local=       save_next_local;
+      context->table_list->next_local=       ctx_state.save_next_local;
       /* first_name_resolution_table was set by resolve_in_table_list_only() */
       context->first_name_resolution_table->
-        next_name_resolution_table=          save_next_local;
+        next_name_resolution_table=          ctx_state.save_next_local;
     }
     if (!res)
       res= setup_fields(thd, 0, update_values, 1, 0, 0);
   }
 
   /* Restore the current context. */
-  table_list->next_local= save_next_local;
-  context->table_list= save_table_list;
-  context->first_name_resolution_table= save_first_name_resolution_table;
-  if (context->first_name_resolution_table)
-    context->first_name_resolution_table->
-             next_name_resolution_table= save_next_name_resolution_table;
-  context->resolve_in_select_list= save_resolve_in_select_list;
+  ctx_state.restore_state(context, table_list);
 
   if (res)
     DBUG_RETURN(res);
@@ -2187,17 +2138,10 @@
   {
     /* Save the state of the current name resolution context. */
     Name_resolution_context *context= &lex->select_lex.context;
-    TABLE_LIST *save_table_list;
-    TABLE_LIST *save_next_local;
-    TABLE_LIST *save_first_name_resolution_table;
-    TABLE_LIST *save_next_name_resolution_table;
-    save_table_list=                  context->table_list;
-    save_first_name_resolution_table= context->first_name_resolution_table;
-    save_next_name_resolution_table=  (context->first_name_resolution_table) ?
-                                      context->first_name_resolution_table->
-                                               next_name_resolution_table :
-                                      NULL;
-    save_next_local= table_list->next_local;
+    Name_resolution_context_state ctx_state;
+
+    /* Save the state of the current name resolution context. */
+    ctx_state.save_state(context, table_list);
 
     /* Perform name resolution only in the first table - 'table_list'. */
     table_list->next_local= 0;
@@ -2213,20 +2157,15 @@
     */       
     if (lex->select_lex.group_list.elements == 0)
     {
-      context->table_list->next_local=       save_next_local;
+      context->table_list->next_local=       ctx_state.save_next_local;
       /* first_name_resolution_table was set by resolve_in_table_list_only() */
       context->first_name_resolution_table->
-        next_name_resolution_table=          save_next_local;
+        next_name_resolution_table=          ctx_state.save_next_local;
     }
     res= res || setup_fields(thd, 0, *info.update_values, 1, 0, 0);
 
     /* Restore the current context. */
-    table_list->next_local= save_next_local;
-    context->first_name_resolution_table= save_first_name_resolution_table;
-    if (context->first_name_resolution_table)
-      context->first_name_resolution_table->
-               next_name_resolution_table= save_next_name_resolution_table;
-
+    ctx_state.restore_state(context, table_list);
   }
 
   lex->current_select= lex_current_select_save;

--- 1.167/sql/sql_lex.cc	2005-11-23 22:47:29 +02:00
+++ 1.168/sql/sql_lex.cc	2005-12-07 08:28:11 +02:00
@@ -1130,6 +1130,11 @@
   /*
     Add the name resolution context of the current (sub)query to the
     stack of contexts for the whole query.
+    TODO:
+    push_context may return an error if there is no memory for a new
+    element in the stack, however this method has no return value,
+    thus push_context should be moved to a place where query
+    initialization is checked for failure.
   */
   parent_lex->push_context(&context);
   cond_count= with_wild= 0;

--- 1.208/sql/sql_lex.h	2005-12-03 08:55:57 +02:00
+++ 1.209/sql/sql_lex.h	2005-12-07 08:28:12 +02:00
@@ -1024,9 +1024,9 @@
   }
   void cleanup_after_one_table_open();
 
-  void push_context(Name_resolution_context *context)
+  bool push_context(Name_resolution_context *context)
   {
-    context_stack.push_front(context);
+    return context_stack.push_front(context);
   }
 
   void pop_context()

--- 1.492/sql/sql_parse.cc	2005-12-07 04:22:48 +02:00
+++ 1.493/sql/sql_parse.cc	2005-12-07 08:28:12 +02:00
@@ -6585,36 +6585,39 @@
 
 
 /*
-  Create a new name resolution context for a JOIN ... ON clause.
+  Push a new name resolution context for a JOIN ... ON clause to the
+  context stack of a query block.
 
   SYNOPSIS
-    make_join_on_context()
+    push_new_name_resolution_context()
     thd       pointer to current thread
     left_op   left  operand of the JOIN
     right_op  rigth operand of the JOIN
 
   DESCRIPTION
     Create a new name resolution context for a JOIN ... ON clause,
-    and set the first and last leaves of the list of table references
-    to be used for name resolution.
+    set the first and last leaves of the list of table references
+    to be used for name resolution, and push the newly created
+    context to the stack of contexts of the query.
 
   RETURN
-    A new context if all is OK
-    NULL - if a memory allocation error occured
+    FALSE  if all is OK
+    TRUE   if a memory allocation error occured
 */
 
-Name_resolution_context *
-make_join_on_context(THD *thd, TABLE_LIST *left_op, TABLE_LIST *right_op)
+bool
+push_new_name_resolution_context(THD *thd,
+                                 TABLE_LIST *left_op, TABLE_LIST *right_op)
 {
   Name_resolution_context *on_context;
   if (!(on_context= new (thd->mem_root) Name_resolution_context))
-    return NULL;
+    return TRUE;
   on_context->init();
   on_context->first_name_resolution_table=
     left_op->first_leaf_for_name_resolution();
   on_context->last_name_resolution_table=
     right_op->last_leaf_for_name_resolution();
-  return on_context;
+  return thd->lex->push_context(on_context);
 }
 
 

--- 1.426/sql/sql_yacc.yy	2005-12-07 04:22:48 +02:00
+++ 1.427/sql/sql_yacc.yy	2005-12-07 08:28:12 +02:00
@@ -5808,10 +5808,8 @@
           {
             YYERROR_UNLESS($1 && ($$=$3));
             /* Change the current name resolution context to a local context. */
-            Name_resolution_context *on_context;
-            if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
+            if (push_new_name_resolution_context(YYTHD, $1, $3))
               YYABORT;
-            Lex->push_context(on_context);
           }
           expr
 	  {
@@ -5823,10 +5821,8 @@
           {
             YYERROR_UNLESS($1 && ($$=$3));
             /* Change the current name resolution context to a local context. */
-            Name_resolution_context *on_context;
-            if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
+            if (push_new_name_resolution_context(YYTHD, $1, $3))
               YYABORT;
-            Lex->push_context(on_context);
           }
           expr
           {
@@ -5853,10 +5849,8 @@
           ON
           {
             /* Change the current name resolution context to a local context. */
-            Name_resolution_context *on_context;
-            if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
+            if (push_new_name_resolution_context(YYTHD, $1, $5))
               YYABORT;
-            Lex->push_context(on_context);
           }
           expr
 	  {
@@ -5886,10 +5880,8 @@
           ON
           {
             /* Change the current name resolution context to a local context. */
-            Name_resolution_context *on_context;
-            if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
+            if (push_new_name_resolution_context(YYTHD, $1, $5))
               YYABORT;
-            Lex->push_context(on_context);
           }
           expr
           {
@@ -5950,10 +5942,9 @@
           ON
           {
             /* Change the current name resolution context to a local context. */
-            Name_resolution_context *on_context;
-            if (!(on_context= make_join_on_context(YYTHD,$3,$7)))
+            if (push_new_name_resolution_context(YYTHD, $3, $7))
               YYABORT;
-            Lex->push_context(on_context);
+
           }
           expr '}'
 	  {

--- 1.192/sql/table.cc	2005-11-30 23:43:49 +02:00
+++ 1.193/sql/table.cc	2005-12-07 10:47:39 +02:00
@@ -3080,60 +3080,6 @@
 }
 
 
-
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-
-/*
-  Check the access rights for the current join column.
-  columns.
-
-  SYNOPSIS
-    Natural_join_column::check_grants()
-
-  DESCRIPTION
-    Check the access rights to a column from a natural join in a generic
-    way that hides the heterogeneity of the column representation - whether
-    it is a view or a stored table colum.
-
-  RETURN
-    FALSE  The column can be accessed
-    TRUE   There are no access rights to all equivalent columns
-*/
-
-bool
-Natural_join_column::check_grants(THD *thd, const char *name, uint length)
-{
-  GRANT_INFO *grant;
-  const char *db_name;
-  const char *table_name;
-  Security_context *save_security_ctx= thd->security_ctx;
-  Security_context *new_sctx= table_ref->security_ctx;
-  bool res;
-
-  if (view_field)
-  {
-    DBUG_ASSERT(table_field == NULL);
-    grant= &(table_ref->grant);
-    db_name= table_ref->view_db.str;
-    table_name= table_ref->view_name.str;
-  }
-  else
-  {
-    DBUG_ASSERT(table_field && view_field == NULL);
-    grant= &(table_ref->table->grant);
-    db_name= table_ref->table->s->db.str;
-    table_name= table_ref->table->s->table_name.str;
-  }
-
-  if (new_sctx)
-    thd->security_ctx= new_sctx;
-  res= check_grant_column(thd, grant, db_name, table_name, name, length);
-  thd->security_ctx= save_security_ctx;
-  return res;
-}
-#endif
-
-
 void Field_iterator_view::set(TABLE_LIST *table)
 {
   DBUG_ASSERT(table->field_translation);
@@ -3176,8 +3122,9 @@
   if (view->schema_table_reformed)
   {
     /*
-      In case of SHOW command (schema_table_reformed set) all items are
-      fixed
+      Translation table items are always Item_fields and already fixed
+      ('mysql_schema_table' function). So we can return directly the
+      field. This case happens only for 'show & where' commands.
     */
     DBUG_ASSERT(field && field->fixed);
     DBUG_RETURN(field);
@@ -3209,21 +3156,14 @@
 void Field_iterator_natural_join::set(TABLE_LIST *table_ref)
 {
   DBUG_ASSERT(table_ref->join_columns);
-  delete column_ref_it;
-
-  /*
-    TODO: try not to allocate new iterator every time. If we have to,
-    then check for out of memory condition.
-  */
-  column_ref_it= new List_iterator_fast<Natural_join_column>
-                     (*(table_ref->join_columns));
-  cur_column_ref= (*column_ref_it)++;
+  column_ref_it.init(*(table_ref->join_columns));
+  cur_column_ref= column_ref_it++;
 }
 
 
 void Field_iterator_natural_join::next()
 {
-  cur_column_ref= (*column_ref_it)++;
+  cur_column_ref= column_ref_it++;
   DBUG_ASSERT(!cur_column_ref || ! cur_column_ref->table_field ||
               cur_column_ref->table_ref->table ==
               cur_column_ref->table_field->table);
@@ -3350,7 +3290,6 @@
 
   SYNOPSIS
     Field_iterator_table_ref::get_or_create_column_ref()
-    thd         [in]  pointer to current thread
     is_created  [out] set to TRUE if the column was created,
                       FALSE if we return an already created colum
 
@@ -3363,7 +3302,7 @@
 */
 
 Natural_join_column *
-Field_iterator_table_ref::get_or_create_column_ref(THD *thd, bool *is_created)
+Field_iterator_table_ref::get_or_create_column_ref(bool *is_created)
 {
   Natural_join_column *nj_col;
 
@@ -3393,6 +3332,41 @@
   }
   DBUG_ASSERT(!nj_col->table_field ||
               nj_col->table_ref->table == nj_col->table_field->table);
+  return nj_col;
+}
+
+
+/*
+  Return an existing reference to a column of a natural/using join.
+
+  SYNOPSIS
+    Field_iterator_table_ref::get_natural_column_ref()
+
+  DESCRIPTION
+    The method should be called in contexts where it is expected that
+    all natural join columns are already created, and that the column
+    being retrieved is a Natural_join_column.
+
+  RETURN
+    #     Pointer to a column of a natural join (or its operand)
+    NULL  No memory to allocate the column
+*/
+
+Natural_join_column *
+Field_iterator_table_ref::get_natural_column_ref()
+{
+  Natural_join_column *nj_col;
+
+  DBUG_ASSERT(field_it == &natural_join_it);
+  /*
+    The field belongs to a NATURAL join, therefore the column reference was
+    already created via one of the two constructor calls above. In this case
+    we just return the already created column reference.
+  */
+  nj_col= natural_join_it.column_ref();
+  DBUG_ASSERT(nj_col &&
+              (!nj_col->table_field ||
+               nj_col->table_ref->table == nj_col->table_field->table));
   return nj_col;
 }
 

--- 1.117/sql/table.h	2005-11-23 22:44:57 +02:00
+++ 1.118/sql/table.h	2005-12-07 08:28:13 +02:00
@@ -432,9 +432,6 @@
   const char *table_name();
   const char *db_name();
   GRANT_INFO *grant();
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-  bool check_grants(THD *thd, const char *name, uint length);
-#endif
 };
 
 
@@ -760,11 +757,11 @@
 
 class Field_iterator_natural_join: public Field_iterator
 {
-  List_iterator_fast<Natural_join_column> *column_ref_it;
+  List_iterator_fast<Natural_join_column> column_ref_it;
   Natural_join_column *cur_column_ref;
 public:
-  Field_iterator_natural_join() :column_ref_it(NULL), cur_column_ref(NULL) {}
-  ~Field_iterator_natural_join() { delete column_ref_it; }
+  Field_iterator_natural_join() :cur_column_ref(NULL) {}
+  ~Field_iterator_natural_join() {}
   void set(TABLE_LIST *table);
   void next();
   bool end_of_fields() { return !cur_column_ref; }
@@ -811,7 +808,8 @@
   GRANT_INFO *grant();
   Item *create_item(THD *thd) { return field_it->create_item(thd); }
   Field *field() { return field_it->field(); }
-  Natural_join_column *get_or_create_column_ref(THD *thd, bool *is_created);
+  Natural_join_column *get_or_create_column_ref(bool *is_created);
+  Natural_join_column *get_natural_column_ref();
 };
 
 
Thread
bk commit into 5.1 tree (timour:1.1962)timour7 Dec