Below is the list of changes that have just been committed into a local
5.0 repository of bell. When bell 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.1856 05/07/01 07:05:42 bell@stripped +55 -0
Name resolution context added (BUG#6443)
sql/table.h
1.101 05/07/01 07:05:37 bell@stripped +37 -12
merged view processing moved
sql/table.cc
1.173 05/07/01 07:05:37 bell@stripped +226 -248
Name resolution context added
merged view processing moved
sql/sql_yacc.yy
1.402 05/07/01 07:05:36 bell@stripped +60 -35
Name resolution context added
sql/sql_view.h
1.7 05/07/01 07:05:36 bell@stripped +1 -1
table list removed from fix_fields() arguments
sql/sql_view.cc
1.49 05/07/01 07:05:36 bell@stripped +53 -21
Name resolution context added
sql/sql_update.cc
1.161 05/07/01 07:05:36 bell@stripped +16 -23
Name resolution context added
sql/sql_union.cc
1.123 05/07/01 07:05:36 bell@stripped +9 -0
Name resolution context added
sql/sql_udf.h
1.13 05/07/01 07:05:36 bell@stripped +2 -2
table list removed from fix_fields() arguments
sql/sql_trigger.cc
1.19 05/07/01 07:05:36 bell@stripped +1 -1
table list removed from fix_fields() arguments
sql/sql_show.cc
1.255 05/07/01 07:05:36 bell@stripped +28 -13
Name resolution context added
sql/sql_select.cc
1.325 05/07/01 07:05:36 bell@stripped +28 -23
table list removed from fix_fields() arguments
sql/sql_prepare.cc
1.129 05/07/01 07:05:36 bell@stripped +30 -27
table list removed from fix_fields() arguments
sql/sql_parse.cc
1.439 05/07/01 07:05:36 bell@stripped +37 -13
Name resolution context added
sql/sql_olap.cc
1.21 05/07/01 07:05:36 bell@stripped +6 -6
Name resolution context added
sql/sql_load.cc
1.81 05/07/01 07:05:36 bell@stripped +13 -7
table list removed from fix_fields() arguments
sql/sql_lex.h
1.187 05/07/01 07:05:36 bell@stripped +24 -21
removed resolve mode (information stored into name resolution context)
sql/sql_lex.cc
1.151 05/07/01 07:05:36 bell@stripped +48 -6
Name resolution context added
sql/sql_insert.cc
1.164 05/07/01 07:05:36 bell@stripped +118 -56
Name resolution context added
table list removed from fix_fields() arguments
sql/sql_help.cc
1.46 05/07/01 07:05:36 bell@stripped +13 -10
Name resolution context added
sql/sql_handler.cc
1.72 05/07/01 07:05:36 bell@stripped +7 -4
Name resolution context added
sql/sql_do.cc
1.11 05/07/01 07:05:36 bell@stripped +1 -1
table list removed from fix_fields() arguments
sql/sql_derived.cc
1.73 05/07/01 07:05:35 bell@stripped +4 -0
Name resolution context added
sql/sql_delete.cc
1.153 05/07/01 07:05:35 bell@stripped +5 -2
Name resolution context added
sql/sql_class.cc
1.191 05/07/01 07:05:35 bell@stripped +10 -6
renamed variable
sql/sql_base.cc
1.260 05/07/01 07:05:35 bell@stripped +94 -83
table list removed from fix_fields() arguments
Name resolution context added
sql/sp_head.h
1.59 05/07/01 07:05:35 bell@stripped +3 -2
Name resolution context added
sql/sp_head.cc
1.154 05/07/01 07:05:35 bell@stripped +4 -4
table list removed from fix_fields() arguments
sql/sp.cc
1.78 05/07/01 07:05:35 bell@stripped +7 -3
Name resolution context added
sql/share/errmsg.txt
1.36 05/07/01 07:05:35 bell@stripped +2 -0
new error message
sql/set_var.cc
1.122 05/07/01 07:05:35 bell@stripped +4 -4
table list removed from fix_fields() arguments
sql/mysql_priv.h
1.320 05/07/01 07:05:35 bell@stripped +19 -5
Name resolution context added
sql/log_event.h
1.112 05/07/01 07:05:35 bell@stripped +2 -1
Name resolution context added
sql/log_event.cc
1.181 05/07/01 07:05:35 bell@stripped +7 -4
Name resolution context added
sql/item_uniq.h
1.26 05/07/01 07:05:35 bell@stripped +1 -1
table list removed from fix_fields() arguments
sql/item_timefunc.h
1.55 05/07/01 07:05:35 bell@stripped +1 -1
table list removed from fix_fields() arguments
sql/item_timefunc.cc
1.88 05/07/01 07:05:35 bell@stripped +2 -2
table list removed from fix_fields() arguments
sql/item_sum.h
1.89 05/07/01 07:05:35 bell@stripped +43 -27
table list removed from fix_fields() arguments
sql/item_sum.cc
1.152 05/07/01 07:05:35 bell@stripped +11 -11
table list removed from fix_fields() arguments
sql/item_subselect.h
1.71 05/07/01 07:05:35 bell@stripped +4 -4
table list removed from fix_fields() arguments
sql/item_subselect.cc
1.113 05/07/01 07:05:35 bell@stripped +27 -23
table list removed from fix_fields() arguments
sql/item_strfunc.h
1.94 05/07/01 07:05:35 bell@stripped +3 -3
table list removed from fix_fields() arguments
sql/item_strfunc.cc
1.235 05/07/01 07:05:35 bell@stripped +1 -1
fixed server crash on NULL argument
sql/item_row.h
1.20 05/07/01 07:05:35 bell@stripped +1 -1
table list removed from fix_fields() arguments
sql/item_row.cc
1.30 05/07/01 07:05:35 bell@stripped +2 -2
table list removed from fix_fields() arguments
sql/item_func.h
1.120 05/07/01 07:05:35 bell@stripped +48 -28
table list removed from fix_fields() arguments
sql/item_func.cc
1.226 05/07/01 07:05:35 bell@stripped +24 -23
table list removed from fix_fields() arguments
sql/item_cmpfunc.h
1.102 05/07/01 07:05:34 bell@stripped +9 -9
table list removed from fix_fields() arguments
sql/item_cmpfunc.cc
1.160 05/07/01 07:05:34 bell@stripped +14 -17
table list removed from fix_fields() arguments
sql/item.h
1.145 05/07/01 07:05:34 bell@stripped +180 -47
Name resolution context added
table list removed from fix_fields() arguments
sql/item.cc
1.144 05/07/01 07:05:34 bell@stripped +304 -212
Name resolution context added
table list removed from fix_fields() arguments
sql/field.h
1.164 05/07/01 07:05:34 bell@stripped +1 -0
index of field in table added
mysys/my_bitmap.c
1.26 05/07/01 07:05:34 bell@stripped +45 -0
new bitmap operation
mysql-test/t/view.test
1.76 05/07/01 07:05:34 bell@stripped +18 -0
Correct inserting data check (absence of default value) for view underlying tables
(BUG#6443)
mysql-test/r/view.result
1.88 05/07/01 07:05:34 bell@stripped +15 -0
added warnings
Correct inserting data check (absence of default value) for view underlying tables
(BUG#6443)
include/my_bitmap.h
1.12 05/07/01 07:05:34 bell@stripped +2 -0
new bitmap operation
# 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: bell
# Host: sanja.is.com.ua
# Root: /home/bell/mysql/bk/work-bug7-5.0
--- 1.163/sql/field.h Thu Jun 30 11:38:21 2005
+++ 1.164/sql/field.h Fri Jul 1 07:05:34 2005
@@ -86,6 +86,7 @@
utype unireg_check;
uint32 field_length; // Length of field
+ uint field_index; // field number in fields array
uint16 flags;
uchar null_bit; // Bit used to test null bit
--- 1.143/sql/item.cc Thu Jun 30 11:38:21 2005
+++ 1.144/sql/item.cc Fri Jul 1 07:05:34 2005
@@ -440,16 +440,17 @@
}
-Item_ident::Item_ident(const char *db_name_par,const char *table_name_par,
- const char *field_name_par)
- :orig_db_name(db_name_par), orig_table_name(table_name_par),
- orig_field_name(field_name_par),
- db_name(db_name_par), table_name(table_name_par),
- field_name(field_name_par),
+Item_ident::Item_ident(Name_resolution_context *context_arg,
+ const char *db_name_arg,const char *table_name_arg,
+ const char *field_name_arg)
+ :orig_db_name(db_name_arg), orig_table_name(table_name_arg),
+ orig_field_name(field_name_arg), context(context_arg),
+ db_name(db_name_arg), table_name(table_name_arg),
+ field_name(field_name_arg),
alias_name_used(FALSE), cached_field_index(NO_CACHED_FIELD_INDEX),
cached_table(0), depended_from(0)
{
- name = (char*) field_name_par;
+ name = (char*) field_name_arg;
}
@@ -460,6 +461,7 @@
orig_db_name(item->orig_db_name),
orig_table_name(item->orig_table_name),
orig_field_name(item->orig_field_name),
+ context(item->context),
db_name(item->db_name),
table_name(item->table_name),
field_name(item->field_name),
@@ -785,7 +787,7 @@
}
-bool Item_splocal::fix_fields(THD *, struct st_table_list *, Item **)
+bool Item_splocal::fix_fields(THD *, Item **)
{
Item *it= this_item();
DBUG_ASSERT(it->fixed);
@@ -855,7 +857,8 @@
uint el= fields.elements;
Item *new_item;
ref_pointer_array[el]= this;
- if (!(new_item= new Item_ref(ref_pointer_array + el, 0, name)))
+ if (!(new_item= new Item_ref(&thd->lex->current_select->context,
+ ref_pointer_array + el, 0, name)))
return; // fatal_error is set
fields.push_front(this);
ref_pointer_array[el]= this;
@@ -995,7 +998,7 @@
}
Item_field::Item_field(Field *f)
- :Item_ident(NullS, *f->table_name, f->field_name),
+ :Item_ident(0, NullS, *f->table_name, f->field_name),
item_equal(0), no_const_subst(0),
have_privileges(0), any_privileges(0)
{
@@ -1007,8 +1010,9 @@
orig_table_name= orig_field_name= "";
}
-Item_field::Item_field(THD *thd, Field *f)
- :Item_ident(f->table->s->db, *f->table_name, f->field_name),
+Item_field::Item_field(THD *thd, Name_resolution_context *context_arg,
+ Field *f)
+ :Item_ident(context_arg, f->table->s->db, *f->table_name,
f->field_name),
item_equal(0), no_const_subst(0),
have_privileges(0), any_privileges(0)
{
@@ -1043,6 +1047,17 @@
set_field(f);
}
+
+Item_field::Item_field(Name_resolution_context *context_arg,
+ const char *db_arg,const char *table_name_arg,
+ const char *field_name_arg)
+ :Item_ident(context_arg, db_arg,table_name_arg,field_name_arg),
+ field(0), result_field(0), item_equal(0), no_const_subst(0),
+ have_privileges(0), any_privileges(0)
+{
+ collation.set(DERIVATION_IMPLICIT);
+}
+
// Constructor need to process subselect with temporary tables (see Item)
Item_field::Item_field(THD *thd, Item_field *item)
:Item_ident(thd, item),
@@ -2233,7 +2248,7 @@
return rc;
}
-bool Item_param::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
+bool Item_param::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
SELECT_LEX *cursel= (SELECT_LEX *) thd->lex->current_select;
@@ -2393,9 +2408,7 @@
*/
/* ARGSUSED */
-bool Item::fix_fields(THD *thd,
- struct st_table_list *list,
- Item ** ref)
+bool Item::fix_fields(THD *thd, Item ** ref)
{
// We do not check fields which are fixed during construction
@@ -2762,7 +2775,6 @@
SYNOPSIS
Item_field::fix_fields()
thd [in] current thread
- tables [in] the tables in a FROM clause
reference [in/out] view column if this item was resolved to a view column
DESCRIPTION
@@ -2808,7 +2820,7 @@
FALSE on success
*/
-bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
+bool Item_field::fix_fields(THD *thd, Item **reference)
{
enum_parsing_place place= NO_MATTER;
DBUG_ASSERT(fixed == 0);
@@ -2821,135 +2833,129 @@
expression to 'reference', i.e. it substitute that expression instead
of this Item_field
*/
- if ((from_field= find_field_in_tables(thd, this, tables, reference,
- IGNORE_EXCEPT_NON_UNIQUE,
- !any_privileges)) ==
+ if ((from_field= find_field_in_tables(thd, this, context->table_list,
+ reference,
+ IGNORE_EXCEPT_NON_UNIQUE,
+ !any_privileges &&
+ context->check_privileges)) ==
not_found_field)
{
- SELECT_LEX *last= 0;
- TABLE_LIST *table_list;
- Item **ref= (Item **) not_found_item;
- SELECT_LEX *current_sel= (SELECT_LEX *) thd->lex->current_select;
/*
- If there is an outer select, and it is not a derived table (which do
- not support the use of outer fields for now), try to resolve this
- reference in the outer select(s).
-
+ If there is an outer contexts (outer selects, but current select is
+ not derived table or view) try to resolve this reference in the
+ outer contexts.
+
We treat each subselect as a separate namespace, so that different
subselects may contain columns with the same names. The subselects are
- searched starting from the innermost.
+ searched starting from the innermost.
*/
- if (current_sel->master_unit()->first_select()->linkage !=
- DERIVED_TABLE_TYPE)
+ Name_resolution_context *last_checked_context= context;
+ Item **ref= (Item **) not_found_item;
+ Name_resolution_context *outer_context= context->outer_context;
+ for (;
+ outer_context;
+ outer_context= outer_context->outer_context)
{
- SELECT_LEX_UNIT *prev_unit= current_sel->master_unit();
- SELECT_LEX *outer_sel= prev_unit->outer_select();
- for ( ; outer_sel ;
- outer_sel= (prev_unit= outer_sel->master_unit())->outer_select())
- {
- last= outer_sel;
- Item_subselect *prev_subselect_item= prev_unit->item;
- upward_lookup= TRUE;
-
- /* Search in the tables of the FROM clause of the outer select. */
- table_list= outer_sel->get_table_list();
- if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list)
- {
- /*
- It is a primary INSERT st_select_lex => do not resolve against the
- first table.
- */
- table_list= table_list->next_local;
- }
- place= prev_subselect_item->parsing_place;
- /*
- Check table fields only if the subquery is used somewhere out of
- HAVING, or the outer SELECT does not use grouping (i.e. tables are
- accessible).
+ SELECT_LEX *select= outer_context->select_lex;
+ Item_subselect *prev_subselect_item=
+ last_checked_context->select_lex->master_unit()->item;
+ last_checked_context= outer_context;
+ upward_lookup= TRUE;
- In case of view, find_field_in_tables() write pointer to view
- field expression to 'reference', i.e. it substitute that
- expression instead of this Item_field
- */
- if ((place != IN_HAVING ||
- (outer_sel->with_sum_func == 0 &&
- outer_sel->group_list.elements == 0)) &&
- (from_field= find_field_in_tables(thd, this, table_list,
- reference,
- IGNORE_EXCEPT_NON_UNIQUE,
- TRUE)) !=
- not_found_field)
- {
- if (from_field)
- {
- if (from_field != view_ref_found)
- {
- prev_subselect_item->used_tables_cache|= from_field->table->map;
- prev_subselect_item->const_item_cache= 0;
- }
- else
- {
- Item::Type type= (*reference)->type();
- prev_subselect_item->used_tables_cache|=
- (*reference)->used_tables();
- prev_subselect_item->const_item_cache&=
- (*reference)->const_item();
- mark_as_dependent(thd, last, current_sel, this,
- ((type == REF_ITEM || type == FIELD_ITEM) ?
- (Item_ident*) (*reference) :
- 0));
- /*
- view reference found, we substituted it instead of this
- Item (find_field_in_tables do it by assigning new value to
- *reference), so can quit
- */
- return FALSE;
- }
- }
- break;
- }
+ place= prev_subselect_item->parsing_place;
+ /*
+ Check table fields only if the subquery is used somewhere out of
+ HAVING, or the outer SELECT does not use grouping (i.e. tables are
+ accessible).
- /* Search in the SELECT and GROUP lists of the outer select. */
- if (outer_sel->resolve_mode == SELECT_LEX::SELECT_MODE)
+ In case of a view, find_field_in_tables() writes the pointer to
+ the found view field into '*reference', in other words, it
+ substitutes this Item_field with the found expression.
+ */
+ if ((place != IN_HAVING ||
+ (!select->with_sum_func &&
+ select->group_list.elements == 0)) &&
+ (from_field= find_field_in_tables(thd, this,
+ outer_context->table_list,
+ reference,
+ IGNORE_EXCEPT_NON_UNIQUE,
+ outer_context->
+ check_privileges)) !=
+ not_found_field)
+ {
+ if (from_field)
{
- if (!(ref= resolve_ref_in_select_and_group(thd, this, outer_sel)))
- return TRUE; /* Some error occurred (e.g. ambiguous names). */
- if (ref != not_found_item)
+ if (from_field != view_ref_found)
{
- DBUG_ASSERT(*ref && (*ref)->fixed);
- prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
- prev_subselect_item->const_item_cache&= (*ref)->const_item();
- break;
+ prev_subselect_item->used_tables_cache|= from_field->table->map;
+ prev_subselect_item->const_item_cache= 0;
}
- }
+ else
+ {
+ Item::Type type= (*reference)->type();
+ prev_subselect_item->used_tables_cache|=
+ (*reference)->used_tables();
+ prev_subselect_item->const_item_cache&=
+ (*reference)->const_item();
+ mark_as_dependent(thd, last_checked_context->select_lex,
+ context->select_lex, this,
+ ((type == REF_ITEM || type == FIELD_ITEM) ?
+ (Item_ident*) (*reference) :
+ 0));
+ /*
+ A reference to a view field had been found and we
+ substituted it instead of this Item (find_field_in_tables
+ does it by assigning the new value to *reference), so now
+ we can return from this function.
+ */
+ return FALSE;
+ }
+ }
+ break;
+ }
- // Reference is not found => depend from outer (or just error)
- prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
- prev_subselect_item->const_item_cache= 0;
-
- if (outer_sel->master_unit()->first_select()->linkage ==
- DERIVED_TABLE_TYPE)
- break; // do not look over derived table
- }
+ /* Search in SELECT and GROUP lists of the outer select. */
+ if (outer_context->resolve_in_select_list)
+ {
+ if (!(ref= resolve_ref_in_select_and_group(thd, this, select)))
+ goto error; /* Some error occurred (e.g. ambiguous names). */
+ if (ref != not_found_item)
+ {
+ DBUG_ASSERT(*ref && (*ref)->fixed);
+ prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
+ prev_subselect_item->const_item_cache&= (*ref)->const_item();
+ break;
+ }
+ }
+
+ /*
+ Reference is not found in this select => this subquery depend on
+ outer select (or we just trying to find wrong identifier, in this
+ case it does not matter which used tables bits we set)
+ */
+ prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
+ prev_subselect_item->const_item_cache= 0;
}
DBUG_ASSERT(ref != 0);
if (!from_field)
- return TRUE;
+ goto error;
if (ref == not_found_item && from_field == not_found_field)
{
if (upward_lookup)
{
- // We can't say exactly what absent table or field
+ // We can't say exactly what absent table or field
my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where);
}
else
{
- // Call to report error
- find_field_in_tables(thd, this, tables, reference, REPORT_ALL_ERRORS,
- TRUE);
+ /* Call find_field_in_tables only to report the error */
+ find_field_in_tables(thd, this, context->table_list,
+ reference, REPORT_ALL_ERRORS,
+ !any_privileges &&
+ context->check_privileges);
}
- return TRUE;
+ goto error;
}
else if (ref != not_found_item)
{
@@ -2967,45 +2973,54 @@
save= *ref;
*ref= NULL; // Don't call set_properties()
rf= (place == IN_HAVING ?
- new Item_ref(ref, (char*) table_name, (char*) field_name) :
- new Item_direct_ref(ref, (char*) table_name, (char*) field_name));
+ new Item_ref(context, ref, (char*) table_name,
+ (char*) field_name) :
+ new Item_direct_ref(context, ref, (char*) table_name,
+ (char*) field_name));
*ref= save;
if (!rf)
- return TRUE;
+ goto error;
thd->change_item_tree(reference, rf);
/*
rf is Item_ref => never substitute other items (in this case)
during fix_fields() => we can use rf after fix_fields()
*/
DBUG_ASSERT(!rf->fixed); // Assured by Item_ref()
- if (rf->fix_fields(thd, tables, reference) || rf->check_cols(1))
- return TRUE;
+ if (rf->fix_fields(thd, reference) || rf->check_cols(1))
+ goto error;
- mark_as_dependent(thd, last, current_sel, this, rf);
+ mark_as_dependent(thd, last_checked_context->select_lex,
+ context->select_lex, this,
+ rf);
return FALSE;
}
else
{
- mark_as_dependent(thd, last, current_sel, this, this);
- if (last->having_fix_field)
+ mark_as_dependent(thd, last_checked_context->select_lex,
+ context->select_lex,
+ this, this);
+ if (last_checked_context->select_lex->having_fix_field)
{
Item_ref *rf;
- rf= new Item_ref((cached_table->db[0] ? cached_table->db : 0),
+ rf= new Item_ref(context,
+ (cached_table->db[0] ? cached_table->db : 0),
(char*) cached_table->alias, (char*) field_name);
if (!rf)
- return TRUE;
+ goto error;
thd->change_item_tree(reference, rf);
/*
rf is Item_ref => never substitute other items (in this case)
during fix_fields() => we can use rf after fix_fields()
*/
DBUG_ASSERT(!rf->fixed); // Assured by Item_ref()
- return (rf->fix_fields(thd, tables, reference) || rf->check_cols(1));
+ if (rf->fix_fields(thd, reference) || rf->check_cols(1))
+ goto error;
+ return FALSE;
}
}
}
else if (!from_field)
- return TRUE;
+ goto error;
/*
if it is not expression from merged VIEW we will set this field.
@@ -3053,12 +3068,16 @@
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
"ANY", thd->priv_user, thd->host_or_ip,
field_name, tab);
- return TRUE;
+ goto error;
}
}
#endif
fixed= 1;
return FALSE;
+
+error:
+ context->process_error(thd);
+ return TRUE;
}
@@ -3922,16 +3941,17 @@
}
-Item_ref::Item_ref(Item **item, const char *table_name_par,
- const char *field_name_par)
- :Item_ident(NullS, table_name_par, field_name_par), result_field(0),
- ref(item)
+Item_ref::Item_ref(Name_resolution_context *context_arg,
+ Item **item, const char *table_name_arg,
+ const char *field_name_arg)
+ :Item_ident(context_arg, NullS, table_name_arg, field_name_arg),
+ result_field(0), ref(item)
{
/*
This constructor used to create some internals references over fixed items
*/
DBUG_ASSERT(ref != 0);
- if (*ref)
+ if (*ref && (*ref)->fixed)
set_properties();
}
@@ -3942,7 +3962,6 @@
SYNOPSIS
Item_ref::fix_fields()
thd [in] current thread
- tables [in] the tables in a FROM clause
reference [in/out] view column if this item was resolved to a view column
DESCRIPTION
@@ -3994,59 +4013,56 @@
FALSE on success
*/
-bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
+bool Item_ref::fix_fields(THD *thd, Item **reference)
{
- DBUG_ASSERT(fixed == 0);
enum_parsing_place place= NO_MATTER;
+ DBUG_ASSERT(fixed == 0);
SELECT_LEX *current_sel= thd->lex->current_select;
if (!ref || ref == not_found_item)
{
- SELECT_LEX_UNIT *prev_unit= current_sel->master_unit();
- SELECT_LEX *outer_sel= prev_unit->outer_select();
-
- if (!(ref= resolve_ref_in_select_and_group(thd, this, current_sel)))
- return TRUE; /* Some error occurred (e.g. ambiguous names). */
+ if (!(ref= resolve_ref_in_select_and_group(thd, this,
+ context->select_lex)))
+ goto error; /* Some error occurred (e.g. ambiguous names). */
if (ref == not_found_item) /* This reference was not resolved. */
{
- TABLE_LIST *table_list;
+ Name_resolution_context *last_checked_context= context;
+ Name_resolution_context *outer_context= context->outer_context;
Field *from_field;
- SELECT_LEX *last;
ref= 0;
- if (!outer_sel || (current_sel->master_unit()->first_select()->linkage ==
- DERIVED_TABLE_TYPE))
+ if (!outer_context)
{
/* The current reference cannot be resolved in this query. */
my_error(ER_BAD_FIELD_ERROR,MYF(0),
this->full_name(), current_thd->where);
- return TRUE;
+ goto error;
}
+
/*
- If there is an outer select, and it is not a derived table (which do
- not support the use of outer fields for now), try to resolve this
- reference in the outer select(s).
+ If there is an outer context (select), and it is not a derived table
+ (which do not support the use of outer fields for now), try to
+ resolve this reference in the outer select(s).
We treat each subselect as a separate namespace, so that different
subselects may contain columns with the same names. The subselects are
searched starting from the innermost.
*/
from_field= (Field*) not_found_field;
- last= 0;
- /* The following loop will always be excuted at least once */
- for ( ; outer_sel ;
- outer_sel= (prev_unit= outer_sel->master_unit())->outer_select())
+ do
{
- last= outer_sel;
- Item_subselect *prev_subselect_item= prev_unit->item;
+ SELECT_LEX *select= outer_context->select_lex;
+ Item_subselect *prev_subselect_item=
+ last_checked_context->select_lex->master_unit()->item;
+ last_checked_context= outer_context;
/* Search in the SELECT and GROUP lists of the outer select. */
- if (outer_sel->resolve_mode == SELECT_LEX::SELECT_MODE)
+ if (outer_context->resolve_in_select_list)
{
- if (!(ref= resolve_ref_in_select_and_group(thd, this, outer_sel)))
- return TRUE; /* Some error occurred (e.g. ambiguous names). */
+ if (!(ref= resolve_ref_in_select_and_group(thd, this, select)))
+ goto error; /* Some error occurred (e.g. ambiguous names). */
if (ref != not_found_item)
{
DBUG_ASSERT(*ref && (*ref)->fixed);
@@ -4062,43 +4078,33 @@
ref= 0;
}
- /* Search in the tables of the FROM clause of the outer select. */
- table_list= outer_sel->get_table_list();
- if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list)
- {
- /*
- It is a primary INSERT st_select_lex => do not resolve against
- the first table.
- */
- table_list= table_list->next_local;
- }
-
place= prev_subselect_item->parsing_place;
/*
Check table fields only if the subquery is used somewhere out of
HAVING or the outer SELECT does not use grouping (i.e. tables are
accessible).
- TODO:
+ TODO:
Here we could first find the field anyway, and then test this
condition, so that we can give a better error message -
ER_WRONG_FIELD_WITH_GROUP, instead of the less informative
ER_BAD_FIELD_ERROR which we produce now.
*/
if ((place != IN_HAVING ||
- (!outer_sel->with_sum_func &&
- outer_sel->group_list.elements == 0)))
+ (!select->with_sum_func &&
+ select->group_list.elements == 0)))
{
/*
In case of view, find_field_in_tables() write pointer to view
field expression to 'reference', i.e. it substitute that
expression instead of this Item_ref
*/
- from_field= find_field_in_tables(thd, this, table_list,
+ from_field= find_field_in_tables(thd, this,
+ outer_context->table_list,
reference,
IGNORE_EXCEPT_NON_UNIQUE,
- TRUE);
+ outer_context->check_privileges);
if (! from_field)
- return TRUE;
+ goto error;
if (from_field == view_ref_found)
{
Item::Type type= (*reference)->type();
@@ -4107,7 +4113,8 @@
prev_subselect_item->const_item_cache&=
(*reference)->const_item();
DBUG_ASSERT((*reference)->type() == REF_ITEM);
- mark_as_dependent(thd, last, current_sel, this,
+ mark_as_dependent(thd, last_checked_context->select_lex,
+ context->select_lex, this,
((type == REF_ITEM || type == FIELD_ITEM) ?
(Item_ident*) (*reference) :
0));
@@ -4130,19 +4137,18 @@
prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
prev_subselect_item->const_item_cache= 0;
- if (outer_sel->master_unit()->first_select()->linkage ==
- DERIVED_TABLE_TYPE)
- break; /* Do not consider derived tables. */
- }
+ outer_context= outer_context->outer_context;
+ } while (outer_context);
DBUG_ASSERT(from_field != 0 && from_field != view_ref_found);
if (from_field != not_found_field)
{
Item_field* fld;
if (!(fld= new Item_field(from_field)))
- return TRUE;
+ goto error;
thd->change_item_tree(reference, fld);
- mark_as_dependent(thd, last, thd->lex->current_select, this, fld);
+ mark_as_dependent(thd, last_checked_context->select_lex,
+ thd->lex->current_select, this, fld);
return FALSE;
}
if (ref == 0)
@@ -4150,11 +4156,12 @@
/* The item was not a table field and not a reference */
my_error(ER_BAD_FIELD_ERROR, MYF(0),
this->full_name(), current_thd->where);
- return TRUE;
+ goto error;
}
/* Should be checked in resolve_ref_in_select_and_group(). */
DBUG_ASSERT(*ref && (*ref)->fixed);
- mark_as_dependent(thd, last, current_sel, this, this);
+ mark_as_dependent(thd, last_checked_context->select_lex,
+ context->select_lex, this, this);
}
}
@@ -4174,14 +4181,18 @@
name, ((*ref)->with_sum_func?
"reference to group function":
"forward reference in item list"));
- return TRUE;
+ goto error;
}
set_properties();
if ((*ref)->check_cols(1))
- return TRUE;
+ goto error;
return FALSE;
+
+error:
+ context->process_error(thd);
+ return TRUE;
}
@@ -4389,6 +4400,19 @@
}
+void Item_ref::make_field(Send_field *field)
+{
+ (*ref)->make_field(field);
+ /* Non-zero in case of a view */
+ if (name)
+ field->col_name= name;
+ if (table_name)
+ field->table_name= table_name;
+ if (db_name)
+ field->db_name= db_name;
+};
+
+
void Item_ref_null_helper::print(String *str)
{
str->append("<ref_null_helper>(", 18);
@@ -4452,6 +4476,31 @@
}
+/*
+ Prepare referenced view viewld then call usual Item_direct_ref::fix_fields
+
+ SYNOPSIS
+ Item_direct_view_ref::fix_fields()
+ thd thread handler
+ reference reference on reference where this item stored
+
+ RETURN
+ FALSE OK
+ TRUE Error
+*/
+
+bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
+{
+ /* view fild reference must be defined */
+ DBUG_ASSERT(*ref);
+ /* (*ref)->check_cols() will be made in Item_direct_ref::fix_fields */
+ if (!(*ref)->fixed &&
+ ((*ref)->fix_fields(thd, ref)))
+ return TRUE;
+ return Item_direct_ref::fix_fields(thd, reference);
+}
+
+
void Item_null_helper::print(String *str)
{
str->append("<null_helper>(", 14);
@@ -4467,9 +4516,7 @@
}
-bool Item_default_value::fix_fields(THD *thd,
- struct st_table_list *table_list,
- Item **items)
+bool Item_default_value::fix_fields(THD *thd, Item **items)
{
Item *real_arg;
Item_field *field_arg;
@@ -4481,29 +4528,34 @@
fixed= 1;
return FALSE;
}
- if (!arg->fixed && arg->fix_fields(thd, table_list, &arg))
- return TRUE;
+ if (!arg->fixed && arg->fix_fields(thd, &arg))
+ goto error;
+
real_arg= arg->real_item();
if (real_arg->type() != FIELD_ITEM)
{
my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), arg->name);
- return TRUE;
+ goto error;
}
field_arg= (Item_field *)real_arg;
if (field_arg->field->flags & NO_DEFAULT_VALUE_FLAG)
{
my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), field_arg->field->field_name);
- return TRUE;
+ goto error;
}
if (!(def_field= (Field*) sql_alloc(field_arg->field->size_of())))
- return TRUE;
+ goto error;
memcpy(def_field, field_arg->field, field_arg->field->size_of());
def_field->move_field(def_field->table->s->default_values -
def_field->table->record[0]);
set_field(def_field);
return FALSE;
+
+error:
+ context->process_error(thd);
+ return TRUE;
}
@@ -4526,11 +4578,27 @@
{
if (field_arg->flags & NO_DEFAULT_VALUE_FLAG)
{
- push_warning_printf(field_arg->table->in_use,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_NO_DEFAULT_FOR_FIELD,
- ER(ER_NO_DEFAULT_FOR_FIELD),
- field_arg->field_name);
+ if (context->error_processor == &view_error_processor)
+ {
+ TABLE_LIST *view= (cached_table->belong_to_view ?
+ cached_table->belong_to_view :
+ cached_table);
+ // TODO: make correct error message
+ push_warning_printf(field_arg->table->in_use,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_NO_DEFAULT_FOR_VIEW_FIELD,
+ ER(ER_NO_DEFAULT_FOR_VIEW_FIELD),
+ view->view_db.str,
+ view->view_name.str);
+ }
+ else
+ {
+ push_warning_printf(field_arg->table->in_use,
+ MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_NO_DEFAULT_FOR_FIELD,
+ ER(ER_NO_DEFAULT_FOR_FIELD),
+ field_arg->field_name);
+ }
return 1;
}
field_arg->set_default();
@@ -4547,12 +4615,10 @@
}
-bool Item_insert_value::fix_fields(THD *thd,
- struct st_table_list *table_list,
- Item **items)
+bool Item_insert_value::fix_fields(THD *thd, Item **items)
{
DBUG_ASSERT(fixed == 0);
- if (!arg->fixed && arg->fix_fields(thd, table_list, &arg))
+ if (!arg->fixed && arg->fix_fields(thd, &arg))
return TRUE;
if (arg->type() == REF_ITEM)
@@ -4641,9 +4707,7 @@
}
-bool Item_trigger_field::fix_fields(THD *thd,
- TABLE_LIST *table_list,
- Item **items)
+bool Item_trigger_field::fix_fields(THD *thd, Item **items)
{
/*
Since trigger is object tightly associated with TABLE object most
@@ -5409,6 +5473,34 @@
Item::cleanup();
result_field= 0;
DBUG_VOID_RETURN;
+}
+
+/*
+ Dummy error processor used by default by Name_resolution_context
+
+ SYNOPSIS
+ dummy_error_processor()
+
+ NOTE
+ do nothing
+*/
+
+void dummy_error_processor(THD *thd, void *data)
+{}
+
+/*
+ Wrapper of hide_view_error call for Name_resolution_context error processor
+
+ SYNOPSIS
+ view_error_processor()
+
+ NOTE
+ hide view underlying tables details in error messages
+*/
+
+void view_error_processor(THD *thd, void *data)
+{
+ ((TABLE_LIST *)data)->hide_view_error(thd);
}
/*****************************************************************************
--- 1.144/sql/item.h Wed Jun 22 23:56:00 2005
+++ 1.145/sql/item.h Fri Jul 1 07:05:34 2005
@@ -24,7 +24,6 @@
void item_init(void); /* Init item functions */
class Item_field;
-
/*
"Declared Type Collation"
A combination of collation and its derivation.
@@ -218,6 +217,97 @@
static const Hybrid_type_traits_integer *instance();
};
+
+void dummy_error_processor(THD *thd, void *data);
+
+void view_error_processor(THD *thd, void *data);
+
+/*
+ Instances of Name_resolution_context store the information necesary for
+ name resolution of Items and other context analysis of a query made in
+ fix_fields().
+
+ This structure is a part of SELECT_LEX, a pointer to this structure is
+ assigned when an item is created (which happens mostly during parsing
+ (sql_yacc.yy)), but the structure itself will be initialized after parsing
+ is complete
+
+ TODO: move subquery of INSERT ... SELECT and CREATE ... SELECT to
+ separate SELECT_LEX which allow to remove tricks of changing this
+ structure before and after INSERT/CREATE and its SELECT to make correct
+ field name resolution.
+*/
+struct Name_resolution_context
+{
+ /*
+ The name resolution context to search in when an Item cannot be
+ resolved in this context (the context of an outer select)
+ */
+ Name_resolution_context *outer_context;
+
+ /*
+ List of tables used to resolve the items of this context. Usually these
+ are tables from the FROM clause of SELECT statement. The exceptions are
+ INSERT ... SELECT and CREATE ... SELECT statements, where SELECT
+ subquery is not moved to a separate SELECT_LEX. For these types of
+ statements we have to change this member dynamically to ensure correct
+ name resolution of different parts of the statement.
+ */
+ TABLE_LIST *table_list;
+
+ /*
+ SELECT_LEX item belong to, in case of merged VIEW it can differ from
+ SELECT_LEX where item was created, so we can't use table_list/field_list
+ from there
+ */
+ st_select_lex *select_lex;
+
+ /*
+ Processor of errors caused during Item name resolving, now used only to
+ hide underlying tables in errors about views (i.e. it substitute some
+ errors for views)
+ */
+ void (*error_processor)(THD *, void *);
+ void *error_processor_data;
+
+ /*
+ When TRUE items are resolved in this context both against the
+ SELECT list and this->table_list. If FALSE, items are resolved
+ only against this->table_list.
+ */
+ bool resolve_in_select_list;
+
+ /*
+ When FALSE we do not check columns right of resolving items, used to
+ prevent rights check on underlying tables of view
+ */
+ bool check_privileges;
+
+ Name_resolution_context()
+ :outer_context(0), table_list(0), select_lex(0),
+ error_processor_data(0),
+ check_privileges(TRUE)
+ {}
+
+ void init()
+ {
+ resolve_in_select_list= FALSE;
+ error_processor= &dummy_error_processor;
+ }
+
+ void resolve_in_table_list_only(TABLE_LIST *tables)
+ {
+ table_list= tables;
+ resolve_in_select_list= FALSE;
+ }
+
+ void process_error(THD *thd)
+ {
+ (*error_processor)(thd, error_processor_data);
+ }
+};
+
+
/*************************************************************************/
typedef bool (Item::*Item_processor)(byte *arg);
@@ -234,7 +324,8 @@
Item(const Item &); /* Prevent use of these */
void operator=(Item &);
public:
- static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
+ static void *operator new(size_t size)
+ { return (void*) sql_alloc((uint) size); }
static void *operator new(size_t size, MEM_ROOT *mem_root)
{ return (void*) alloc_root(mem_root, (uint) size); }
/* Special for SP local variable assignment - reusing slots */
@@ -248,7 +339,8 @@
PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
- PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM};
+ PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
+ VIEW_FIXER_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
@@ -302,7 +394,7 @@
virtual void cleanup();
virtual void make_field(Send_field *field);
Field *make_string_field(TABLE *table);
- virtual bool fix_fields(THD *, struct st_table_list *, Item **);
+ virtual bool fix_fields(THD *, Item **);
/*
should be used in case where we are sure that we do not need
complete fix_fields() procedure.
@@ -554,6 +646,8 @@
virtual bool remove_fixed(byte * arg) { fixed= 0; return 0; }
virtual bool cleanup_processor(byte *arg);
virtual bool collect_item_field_processor(byte * arg) { return 0; }
+ virtual bool change_context_processor(byte *context) { return 0; }
+
virtual Item *equal_fields_propagator(byte * arg) { return this; }
virtual Item *set_no_const_sub(byte *arg) { return this; }
virtual Item *replace_equal_field(byte * arg) { return this; }
@@ -631,7 +725,7 @@
Item **this_item_addr(THD *thd, Item **);
Item *this_const_item() const;
- bool fix_fields(THD *, struct st_table_list *, Item **);
+ bool fix_fields(THD *, Item **);
void cleanup();
inline uint get_offset()
@@ -704,7 +798,9 @@
const char *orig_db_name;
const char *orig_table_name;
const char *orig_field_name;
+
public:
+ Name_resolution_context *context;
const char *db_name;
const char *table_name;
const char *field_name;
@@ -722,13 +818,16 @@
*/
TABLE_LIST *cached_table;
st_select_lex *depended_from;
- Item_ident(const char *db_name_par,const char *table_name_par,
- const char *field_name_par);
+ Item_ident(Name_resolution_context *context_arg,
+ const char *db_name_arg, const char *table_name_arg,
+ const char *field_name_arg);
Item_ident(THD *thd, Item_ident *item);
const char *full_name() const;
void cleanup();
bool remove_dependence_processor(byte * arg);
void print(String *str);
+ virtual bool change_context_processor(byte *cntx)
+ { context= (Name_resolution_context *)cntx; return FALSE; }
};
class Item_equal;
@@ -750,12 +849,9 @@
/* field need any privileges (for VIEW creation) */
bool any_privileges;
- Item_field(const char *db_par,const char *table_name_par,
- const char *field_name_par)
- :Item_ident(db_par,table_name_par,field_name_par),
- field(0), result_field(0), item_equal(0), no_const_subst(0),
- have_privileges(0), any_privileges(0)
- { collation.set(DERIVATION_IMPLICIT); }
+ Item_field(Name_resolution_context *context_arg,
+ const char *db_arg,const char *table_name_arg,
+ const char *field_name_arg);
/*
Constructor needed to process subselect with temporary tables (see Item)
*/
@@ -765,7 +861,7 @@
and database names will live as long as Item_field (this is important
in prepared statements).
*/
- Item_field(THD *thd, Field *field);
+ Item_field(THD *thd, Name_resolution_context *context_arg, Field *field);
/*
If this constructor is used, fix_fields() won't work, because
db_name, table_name and column_name are unknown. It's necessary to call
@@ -785,7 +881,7 @@
bool val_bool_result();
bool send(Protocol *protocol, String *str_arg);
void reset_field(Field *f);
- bool fix_fields(THD *, struct st_table_list *, Item **);
+ bool fix_fields(THD *, Item **);
void make_field(Send_field *tmp_field);
int save_in_field(Field *field,bool no_conversions);
void save_org_in_field(Field *field);
@@ -946,7 +1042,7 @@
bool get_time(TIME *tm);
bool get_date(TIME *tm, uint fuzzydate);
int save_in_field(Field *field, bool no_conversions);
- bool fix_fields(THD *, struct st_table_list *, Item **);
+ bool fix_fields(THD *, Item **);
void set_null();
void set_int(longlong i, uint32 max_length_arg);
@@ -1317,9 +1413,11 @@
public:
Field *result_field; /* Save result here */
Item **ref;
- Item_ref(const char *db_par, const char *table_name_par,
- const char *field_name_par)
- :Item_ident(db_par, table_name_par, field_name_par), result_field(0), ref(0) {}
+ Item_ref(Name_resolution_context *context_arg,
+ const char *db_arg, const char *table_name_arg,
+ const char *field_name_arg)
+ :Item_ident(context_arg, db_arg, table_name_arg, field_name_arg),
+ result_field(0), ref(0) {}
/*
This constructor is used in two scenarios:
A) *item = NULL
@@ -1334,10 +1432,12 @@
TODO we probably fix a superset of problems like in BUG#6658. Check this
with Bar, and if we have a more broader set of problems like this.
*/
- Item_ref(Item **item, const char *table_name_par, const char *field_name_par);
+ Item_ref(Name_resolution_context *context_arg, Item **item,
+ const char *table_name_arg, const char *field_name_arg);
/* Constructor need to process subselect with temporary tables (see Item) */
- Item_ref(THD *thd, Item_ref *item) :Item_ident(thd, item),
result_field(item->result_field), ref(item->ref) {}
+ Item_ref(THD *thd, Item_ref *item)
+ :Item_ident(thd, item), result_field(item->result_field), ref(item->ref) {}
enum Type type() const { return REF_ITEM; }
bool eq(const Item *item, bool binary_cmp) const
{ return ref && (*ref)->eq(item, binary_cmp); }
@@ -1354,8 +1454,8 @@
my_decimal *val_decimal_result(my_decimal *);
bool val_bool_result();
bool send(Protocol *prot, String *tmp);
- void make_field(Send_field *field) { (*ref)->make_field(field); }
- bool fix_fields(THD *, struct st_table_list *, Item **);
+ void make_field(Send_field *field);
+ bool fix_fields(THD *, Item **);
int save_in_field(Field *field, bool no_conversions);
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
enum Item_result result_type () const { return (*ref)->result_type(); }
@@ -1380,6 +1480,8 @@
{ return (*ref)->walk(processor, arg); }
void print(String *str);
void cleanup();
+ Item_field *filed_for_view_update()
+ { return (*ref)->filed_for_view_update(); }
};
@@ -1390,9 +1492,10 @@
class Item_direct_ref :public Item_ref
{
public:
- Item_direct_ref(Item **item, const char *table_name_par,
- const char *field_name_par)
- :Item_ref(item, table_name_par, field_name_par) {}
+ Item_direct_ref(Name_resolution_context *context_arg, Item **item,
+ const char *table_name_arg,
+ const char *field_name_arg)
+ :Item_ref(context_arg, item, table_name_arg, field_name_arg) {}
/* Constructor need to process subselect with temporary tables (see Item) */
Item_direct_ref(THD *thd, Item_direct_ref *item) : Item_ref(thd, item) {}
@@ -1405,6 +1508,24 @@
bool get_date(TIME *ltime,uint fuzzydate);
};
+/*
+ Class for view fields, the same as Item_direct_ref, but call fix_fields
+ of reference if it is not called yet
+*/
+class Item_direct_view_ref :public Item_direct_ref
+{
+public:
+ Item_direct_view_ref(Name_resolution_context *context_arg, Item **item,
+ const char *table_name_arg,
+ const char *field_name_arg)
+ :Item_direct_ref(context_arg, item, table_name_arg, field_name_arg) {}
+ /* Constructor need to process subselect with temporary tables (see Item) */
+ Item_direct_view_ref(THD *thd, Item_direct_ref *item)
+ :Item_direct_ref(thd, item) {}
+
+ bool fix_fields(THD *, Item **);
+};
+
class Item_in_subselect;
@@ -1413,9 +1534,11 @@
protected:
Item_in_subselect* owner;
public:
- Item_ref_null_helper(Item_in_subselect* master, Item **item,
- const char *table_name_par, const char *field_name_par):
- Item_ref(item, table_name_par, field_name_par), owner(master) {}
+ Item_ref_null_helper(Name_resolution_context *context_arg,
+ Item_in_subselect* master, Item **item,
+ const char *table_name_arg, const char *field_name_arg)
+ :Item_ref(context_arg, item, table_name_arg, field_name_arg),
+ owner(master) {}
double val_real();
longlong val_int();
String* val_str(String* s);
@@ -1429,10 +1552,11 @@
{
Item *store;
public:
- Item_null_helper(Item_in_subselect* master, Item *item,
- const char *table_name_par, const char *field_name_par)
- :Item_ref_null_helper(master, (store= 0, &store), table_name_par,
- field_name_par),
+ Item_null_helper(Name_resolution_context *context_arg,
+ Item_in_subselect* master, Item *item,
+ const char *table_name_arg, const char *field_name_arg)
+ :Item_ref_null_helper(context_arg, master, (store= 0, &store),
+ table_name_arg, field_name_arg),
store(item)
{ ref= &store; }
void print(String *str);
@@ -1583,13 +1707,17 @@
{
public:
Item *arg;
- Item_default_value() :
- Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(NULL) {}
- Item_default_value(Item *a) :
- Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(a) {}
+ Item_default_value(Name_resolution_context *context_arg)
+ :Item_field(context_arg, (const char *)NULL, (const char *)NULL,
+ (const char *)NULL),
+ arg(NULL) {}
+ Item_default_value(Name_resolution_context *context_arg, Item *a)
+ :Item_field(context_arg, (const char *)NULL, (const char *)NULL,
+ (const char *)NULL),
+ arg(a) {}
enum Type type() const { return DEFAULT_VALUE_ITEM; }
bool eq(const Item *item, bool binary_cmp) const;
- bool fix_fields(THD *, struct st_table_list *, Item **);
+ bool fix_fields(THD *, Item **);
void print(String *str);
int save_in_field(Field *field_arg, bool no_conversions);
table_map used_tables() const { return (table_map)0L; }
@@ -1618,10 +1746,12 @@
{
public:
Item *arg;
- Item_insert_value(Item *a) :
- Item_field((const char *)NULL, (const char *)NULL, (const char *)NULL), arg(a) {}
+ Item_insert_value(Name_resolution_context *context_arg, Item *a)
+ :Item_field(context_arg, (const char *)NULL, (const char *)NULL,
+ (const char *)NULL),
+ arg(a) {}
bool eq(const Item *item, bool binary_cmp) const;
- bool fix_fields(THD *, struct st_table_list *, Item **);
+ bool fix_fields(THD *, Item **);
void print(String *str);
int save_in_field(Field *field_arg, bool no_conversions)
{
@@ -1683,15 +1813,17 @@
/* Pointer to Table_trigger_list object for table of this trigger */
Table_triggers_list *triggers;
- Item_trigger_field(row_version_type row_ver_par,
- const char *field_name_par):
- Item_field((const char *)NULL, (const char *)NULL, field_name_par),
- row_version(row_ver_par), field_idx((uint)-1)
+ Item_trigger_field(Name_resolution_context *context_arg,
+ row_version_type row_ver_arg,
+ const char *field_name_arg)
+ :Item_field(context_arg,
+ (const char *)NULL, (const char *)NULL, field_name_arg),
+ row_version(row_ver_arg), field_idx((uint)-1)
{}
void setup_field(THD *thd, TABLE *table);
enum Type type() const { return TRIGGER_FIELD_ITEM; }
bool eq(const Item *item, bool binary_cmp) const;
- bool fix_fields(THD *, struct st_table_list *, Item **);
+ bool fix_fields(THD *, Item **);
void print(String *str);
table_map used_tables() const { return (table_map)0L; }
void cleanup();
@@ -1880,7 +2012,7 @@
Item_type_holder(THD*, Item*);
Item_result result_type() const;
- virtual enum_field_types field_type() const { return fld_type; };
+ enum_field_types field_type() const { return fld_type; };
enum Type type() const { return TYPE_HOLDER; }
double val_real();
longlong val_int();
@@ -1891,6 +2023,7 @@
static uint32 display_length(Item *item);
static enum_field_types get_real_type(Item *);
};
+
class st_select_lex;
void mark_select_range_as_dependent(THD *thd,
--- 1.159/sql/item_cmpfunc.cc Fri Jun 24 19:10:00 2005
+++ 1.160/sql/item_cmpfunc.cc Fri Jul 1 07:05:34 2005
@@ -638,11 +638,9 @@
}
-bool Item_in_optimizer::fix_left(THD *thd,
- struct st_table_list *tables,
- Item **ref)
+bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
{
- if (!args[0]->fixed && args[0]->fix_fields(thd, tables, args) ||
+ if (!args[0]->fixed && args[0]->fix_fields(thd, args) ||
!cache && !(cache= Item_cache::get_cache(args[0]->result_type())))
return 1;
@@ -679,16 +677,15 @@
}
-bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
- Item ** ref)
+bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
- if (fix_left(thd, tables, ref))
+ if (fix_left(thd, ref))
return TRUE;
if (args[0]->maybe_null)
maybe_null=1;
- if (!args[1]->fixed && args[1]->fix_fields(thd, tables, args+1))
+ if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
return TRUE;
Item_in_subselect * sub= (Item_in_subselect *)args[1];
if (args[0]->cols() != sub->engine->cols())
@@ -2312,7 +2309,7 @@
bool
-Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
+Item_cond::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
List_iterator<Item> li(list);
@@ -2360,7 +2357,7 @@
// item can be substituted in fix_fields
if ((!item->fixed &&
- item->fix_fields(thd, tables, li.ref())) ||
+ item->fix_fields(thd, li.ref())) ||
(item= *li.ref())->check_cols(1))
return TRUE; /* purecov: inspected */
used_tables_cache|= item->used_tables();
@@ -2747,11 +2744,11 @@
}
-bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
+bool Item_func_like::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
- if (Item_bool_func2::fix_fields(thd, tlist, ref) ||
- escape_item->fix_fields(thd, tlist, &escape_item))
+ if (Item_bool_func2::fix_fields(thd, ref) ||
+ escape_item->fix_fields(thd, &escape_item))
return TRUE;
if (!escape_item->const_during_execution())
@@ -2815,13 +2812,13 @@
#ifdef USE_REGEX
bool
-Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
+Item_func_regex::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
if ((!args[0]->fixed &&
- args[0]->fix_fields(thd, tables, args)) || args[0]->check_cols(1) ||
+ args[0]->fix_fields(thd, args)) || args[0]->check_cols(1) ||
(!args[1]->fixed &&
- args[1]->fix_fields(thd,tables, args + 1)) || args[1]->check_cols(1))
+ args[1]->fix_fields(thd, args + 1)) || args[1]->check_cols(1))
return TRUE; /* purecov: inspected */
with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
max_length= 1;
@@ -3481,7 +3478,7 @@
} while (swap);
}
-bool Item_equal::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
+bool Item_equal::fix_fields(THD *thd, Item **ref)
{
List_iterator_fast<Item_field> li(fields);
Item *item;
--- 1.101/sql/item_cmpfunc.h Thu Jun 2 17:20:27 2005
+++ 1.102/sql/item_cmpfunc.h Fri Jul 1 07:05:34 2005
@@ -108,8 +108,8 @@
Item_in_optimizer(Item *a, Item_in_subselect *b):
Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0), save_cache(0)
{}
- bool fix_fields(THD *, struct st_table_list *, Item **);
- bool fix_left(THD *thd, struct st_table_list *tables, Item **ref);
+ bool fix_fields(THD *, Item **);
+ bool fix_left(THD *thd, Item **ref);
bool is_null();
/*
Item_in_optimizer item is special boolean function. On value request
@@ -502,11 +502,11 @@
String *val_str(String *str);
my_decimal *val_decimal(my_decimal *);
enum Item_result result_type () const { return cached_result_type; }
- bool fix_fields(THD *thd,struct st_table_list *tlist, Item **ref)
+ bool fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
args[0]->top_level_item();
- return Item_func::fix_fields(thd, tlist, ref);
+ return Item_func::fix_fields(thd, ref);
}
void fix_length_and_dec();
uint decimal_precision() const;
@@ -961,7 +961,7 @@
optimize_type select_optimize() const;
cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return "like"; }
- bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
+ bool fix_fields(THD *thd, Item **ref);
};
#ifdef USE_REGEX
@@ -980,7 +980,7 @@
regex_compiled(0),regex_is_const(0) {}
void cleanup();
longlong val_int();
- bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
+ bool fix_fields(THD *thd, Item **ref);
const char *func_name() const { return "regexp"; }
void print(String *str) { print_op(str); }
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
@@ -1024,7 +1024,7 @@
:Item_bool_func(), list(nlist), abort_on_null(0) {}
bool add(Item *item) { return list.push_back(item); }
void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
- bool fix_fields(THD *, struct st_table_list *, Item **ref);
+ bool fix_fields(THD *, Item **ref);
enum Type type() const { return COND_ITEM; }
List<Item>* argument_list() { return &list; }
@@ -1033,7 +1033,7 @@
void print(String *str);
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
- COND **conds);
+ COND **conds);
void top_level_item() { abort_on_null=1; }
void copy_andor_arguments(THD *thd, Item_cond *item);
bool walk(Item_processor processor, byte *arg);
@@ -1141,7 +1141,7 @@
void sort(Item_field_cmpfunc cmp, void *arg);
friend class Item_equal_iterator;
void fix_length_and_dec();
- bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
+ bool fix_fields(THD *thd, Item **ref);
void update_used_tables();
bool walk(Item_processor processor, byte *arg);
Item *transform(Item_transformer transformer, byte *arg);
--- 1.225/sql/item_func.cc Thu Jun 23 19:33:15 2005
+++ 1.226/sql/item_func.cc Fri Jul 1 07:05:35 2005
@@ -194,11 +194,10 @@
((Item_field *)(*arg))->no_const_subst= 1;
/*
We do not check conv->fixed, because Item_func_conv_charset which can
- be return by safe_charset_converter can't be fixed at creation, also
- it do not need tables (second argument) for name resolving
+ be return by safe_charset_converter can't be fixed at creation
*/
*arg= conv;
- conv->fix_fields(thd, 0, arg);
+ conv->fix_fields(thd, arg);
}
if (arena)
thd->restore_backup_item_arena(arena, &backup);
@@ -261,7 +260,6 @@
SYNOPSIS:
fix_fields()
thd Thread object
- tables List of all open tables involved in the query
ref Pointer to where this object is used. This reference
is used if we want to replace this object with another
one (for example in the summary functions).
@@ -290,7 +288,7 @@
*/
bool
-Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
+Item_func::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
Item **arg,**arg_end;
@@ -312,7 +310,7 @@
We can't yet set item to *arg as fix_fields may change *arg
We shouldn't call fix_fields() twice, so check 'fixed' field first
*/
- if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)))
+ if ((!(*arg)->fixed && (*arg)->fix_fields(thd, arg)))
return TRUE; /* purecov: inspected */
item= *arg;
@@ -2010,10 +2008,9 @@
}
-bool Item_func_rand::fix_fields(THD *thd, struct st_table_list *tables,
- Item **ref)
+bool Item_func_rand::fix_fields(THD *thd,Item **ref)
{
- if (Item_real_func::fix_fields(thd, tables, ref))
+ if (Item_real_func::fix_fields(thd, ref))
return TRUE;
used_tables_cache|= RAND_TABLE_BIT;
if (arg_count)
@@ -2604,7 +2601,7 @@
bool
-udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
+udf_handler::fix_fields(THD *thd, Item_result_field *func,
uint arg_count, Item **arguments)
{
#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
@@ -2646,7 +2643,7 @@
arg++,i++)
{
if (!(*arg)->fixed &&
- (*arg)->fix_fields(thd, tables, arg))
+ (*arg)->fix_fields(thd, arg))
DBUG_RETURN(1);
// we can't assign 'item' before, because fix_fields() can change arg
Item *item= *arg;
@@ -3458,12 +3455,11 @@
SELECT @a:= ).
*/
-bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
- Item **ref)
+bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
/* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
- if (Item_func::fix_fields(thd, tables, ref) ||
+ if (Item_func::fix_fields(thd, ref) ||
!(entry= get_variable(&thd->user_vars, name, 1)))
return TRUE;
/*
@@ -4127,11 +4123,10 @@
}
-bool Item_user_var_as_out_param::fix_fields(THD *thd, TABLE_LIST *tables,
- Item **ref)
+bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
- if (Item::fix_fields(thd, tables, ref) ||
+ if (Item::fix_fields(thd, ref) ||
!(entry= get_variable(&thd->user_vars, name, 1)))
return TRUE;
entry->type= STRING_RESULT;
@@ -4314,7 +4309,7 @@
}
-bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
+bool Item_func_match::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
Item *item;
@@ -4329,7 +4324,7 @@
modifications to find_best and auto_close as complement to auto_init code
above.
*/
- if (Item_func::fix_fields(thd, tlist, ref) ||
+ if (Item_func::fix_fields(thd, ref) ||
!args[0]->const_during_execution())
{
my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST");
@@ -4690,8 +4685,9 @@
}
-Item_func_sp::Item_func_sp(sp_name *name)
- :Item_func(), m_name(name), m_sp(NULL), result_field(NULL)
+Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name)
+ :Item_func(), context(context_arg), m_name(name), m_sp(NULL),
+ result_field(NULL)
{
maybe_null= 1;
m_name->init_qname(current_thd);
@@ -4699,8 +4695,10 @@
}
-Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list)
- :Item_func(list), m_name(name), m_sp(NULL), result_field(NULL)
+Item_func_sp::Item_func_sp(Name_resolution_context *context_arg,
+ sp_name *name, List<Item> &list)
+ :Item_func(list), context(context_arg), m_name(name), m_sp(NULL),
+ result_field(NULL)
{
maybe_null= 1;
m_name->init_qname(current_thd);
@@ -4944,7 +4942,10 @@
}
if (!(field= sp_result_field()))
+ {
+ context->process_error(current_thd);
DBUG_VOID_RETURN;
+ }
decimals= field->decimals();
max_length= field->field_length;
maybe_null= 1;
--- 1.119/sql/item_func.h Fri Jun 17 17:27:43 2005
+++ 1.120/sql/item_func.h Fri Jul 1 07:05:35 2005
@@ -116,7 +116,7 @@
Item_func(List<Item> &list);
// Constructor used for Item_cond_and/or (see Item comment)
Item_func(THD *thd, Item_func *item);
- bool fix_fields(THD *,struct st_table_list *, Item **ref);
+ bool fix_fields(THD *, Item **ref);
table_map used_tables() const;
table_map not_null_tables() const;
void update_used_tables();
@@ -630,7 +630,7 @@
const char *func_name() const { return "rand"; }
bool const_item() const { return 0; }
void update_used_tables();
- bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref);
+ bool fix_fields(THD *thd, Item **ref);
};
@@ -885,14 +885,15 @@
udf_handler udf;
public:
- Item_udf_func(udf_func *udf_arg) :Item_func(), udf(udf_arg) {}
+ Item_udf_func(udf_func *udf_arg)
+ :Item_func(), udf(udf_arg) {}
Item_udf_func(udf_func *udf_arg, List<Item> &list)
:Item_func(list), udf(udf_arg) {}
const char *func_name() const { return udf.name(); }
- bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref)
+ bool fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
- bool res= udf.fix_fields(thd, tables, this, arg_count, args);
+ bool res= udf.fix_fields(thd, this, arg_count, args);
used_tables_cache= udf.used_tables_cache;
const_item_cache= udf.const_item_cache;
fixed= 1;
@@ -907,9 +908,11 @@
class Item_func_udf_float :public Item_udf_func
{
public:
- Item_func_udf_float(udf_func *udf_arg) :Item_udf_func(udf_arg) {}
- Item_func_udf_float(udf_func *udf_arg, List<Item> &list)
- :Item_udf_func(udf_arg,list) {}
+ Item_func_udf_float(udf_func *udf_arg)
+ :Item_udf_func(udf_arg) {}
+ Item_func_udf_float(udf_func *udf_arg,
+ List<Item> &list)
+ :Item_udf_func(udf_arg, list) {}
longlong val_int()
{
DBUG_ASSERT(fixed == 1);
@@ -932,9 +935,11 @@
class Item_func_udf_int :public Item_udf_func
{
public:
- Item_func_udf_int(udf_func *udf_arg) :Item_udf_func(udf_arg) {}
- Item_func_udf_int(udf_func *udf_arg, List<Item> &list)
- :Item_udf_func(udf_arg,list) {}
+ Item_func_udf_int(udf_func *udf_arg)
+ :Item_udf_func(udf_arg) {}
+ Item_func_udf_int(udf_func *udf_arg,
+ List<Item> &list)
+ :Item_udf_func(udf_arg, list) {}
longlong val_int();
double val_real() { return (double) Item_func_udf_int::val_int(); }
String *val_str(String *str);
@@ -946,9 +951,10 @@
class Item_func_udf_decimal :public Item_udf_func
{
public:
- Item_func_udf_decimal(udf_func *udf_arg) :Item_udf_func(udf_arg) {}
+ Item_func_udf_decimal(udf_func *udf_arg)
+ :Item_udf_func(udf_arg) {}
Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
- :Item_udf_func(udf_arg,list) {}
+ :Item_udf_func(udf_arg, list) {}
longlong val_int();
double val_real();
my_decimal *val_decimal(my_decimal *);
@@ -961,9 +967,10 @@
class Item_func_udf_str :public Item_udf_func
{
public:
- Item_func_udf_str(udf_func *udf_arg) :Item_udf_func(udf_arg) {}
+ Item_func_udf_str(udf_func *udf_arg)
+ :Item_udf_func(udf_arg) {}
Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
- :Item_udf_func(udf_arg,list) {}
+ :Item_udf_func(udf_arg, list) {}
String *val_str(String *);
double val_real()
{
@@ -998,8 +1005,10 @@
class Item_func_udf_float :public Item_real_func
{
public:
- Item_func_udf_float(udf_func *udf_arg) :Item_real_func() {}
- Item_func_udf_float(udf_func *udf_arg, List<Item> &list)
:Item_real_func(list) {}
+ Item_func_udf_float(udf_func *udf_arg)
+ :Item_real_func() {}
+ Item_func_udf_float(udf_func *udf_arg, List<Item> &list)
+ :Item_real_func(list) {}
double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
};
@@ -1007,8 +1016,10 @@
class Item_func_udf_int :public Item_int_func
{
public:
- Item_func_udf_int(udf_func *udf_arg) :Item_int_func() {}
- Item_func_udf_int(udf_func *udf_arg, List<Item> &list) :Item_int_func(list)
{}
+ Item_func_udf_int(udf_func *udf_arg)
+ :Item_int_func() {}
+ Item_func_udf_int(udf_func *udf_arg, List<Item> &list)
+ :Item_int_func(list) {}
longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; }
};
@@ -1016,8 +1027,10 @@
class Item_func_udf_decimal :public Item_int_func
{
public:
- Item_func_udf_decimal(udf_func *udf_arg) :Item_int_func() {}
- Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
:Item_int_func(list) {}
+ Item_func_udf_decimal(udf_func *udf_arg)
+ :Item_int_func() {}
+ Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
+ :Item_int_func(list) {}
my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; }
};
@@ -1025,8 +1038,10 @@
class Item_func_udf_str :public Item_func
{
public:
- Item_func_udf_str(udf_func *udf_arg) :Item_func() {}
- Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_func(list) {}
+ Item_func_udf_str(udf_func *udf_arg)
+ :Item_func() {}
+ Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
+ :Item_func(list) {}
String *val_str(String *)
{ DBUG_ASSERT(fixed == 1); null_value=1; return 0; }
double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; }
@@ -1116,7 +1131,7 @@
bool check();
bool update();
enum Item_result result_type () const { return cached_result_type; }
- bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref);
+ bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
void print(String *str);
void print_as_stmt(String *str);
@@ -1176,7 +1191,7 @@
String *val_str(String *str);
my_decimal *val_decimal(my_decimal *decimal_buffer);
/* fix_fields() binds variable name with its entry structure */
- bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref);
+ bool fix_fields(THD *thd, Item **ref);
void print(String *str);
void set_null_value(CHARSET_INFO* cs);
void set_value(const char *str, uint length, CHARSET_INFO* cs);
@@ -1230,7 +1245,7 @@
const char *func_name() const { return "match"; }
void update_used_tables() {}
table_map not_null_tables() const { return 0; }
- bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
+ bool fix_fields(THD *thd, Item **ref);
bool eq(const Item *, bool binary_cmp) const;
/* The following should be safe, even if we compare doubles */
longlong val_int() { DBUG_ASSERT(fixed == 1); return val_real() != 0.0; }
@@ -1302,6 +1317,7 @@
class Item_func_sp :public Item_func
{
private:
+ Name_resolution_context *context;
sp_name *m_name;
mutable sp_head *m_sp;
TABLE *dummy_table;
@@ -1314,9 +1330,10 @@
public:
- Item_func_sp(sp_name *name);
+ Item_func_sp(Name_resolution_context *context_arg, sp_name *name);
- Item_func_sp(sp_name *name, List<Item> &list);
+ Item_func_sp(Name_resolution_context *context_arg,
+ sp_name *name, List<Item> &list);
virtual ~Item_func_sp()
{}
@@ -1360,6 +1377,9 @@
return NULL;
return result_field->val_str(str);
}
+
+ virtual bool change_context_processor(byte *cntx)
+ { context= (Name_resolution_context *)cntx; return FALSE; }
void fix_length_and_dec();
--- 1.234/sql/item_strfunc.cc Wed Jun 22 14:48:27 2005
+++ 1.235/sql/item_strfunc.cc Fri Jul 1 07:05:35 2005
@@ -461,7 +461,7 @@
struct st_des_keyblock keyblock;
struct st_des_keyschedule keyschedule;
String *res= args[0]->val_str(str);
- uint length=res->length(),tail;
+ uint length= 0, tail;
if ((null_value=args[0]->null_value))
goto error;
--- 1.93/sql/item_strfunc.h Fri Jun 24 00:24:08 2005
+++ 1.94/sql/item_strfunc.h Fri Jul 1 07:05:35 2005
@@ -415,12 +415,12 @@
public:
Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {}
String *val_str(String *str);
- bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
+ bool fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
- return ((!item->fixed && item->fix_fields(thd, tlist, &item)) ||
+ return ((!item->fixed && item->fix_fields(thd, &item)) ||
item->check_cols(1) ||
- Item_func::fix_fields(thd, tlist, ref));
+ Item_func::fix_fields(thd, ref));
}
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
void fix_length_and_dec();
--- 1.151/sql/item_sum.cc Fri Jun 17 17:27:43 2005
+++ 1.152/sql/item_sum.cc Fri Jul 1 07:05:35 2005
@@ -193,7 +193,7 @@
bool
-Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
+Item_sum_num::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
@@ -208,7 +208,7 @@
maybe_null=0;
for (uint i=0 ; i < arg_count ; i++)
{
- if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1))
+ if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
return TRUE;
set_if_bigger(decimals, args[i]->decimals);
maybe_null |= args[i]->maybe_null;
@@ -253,7 +253,7 @@
}
bool
-Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
+Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
@@ -268,7 +268,7 @@
// 'item' can be changed during fix_fields
if (!item->fixed &&
- item->fix_fields(thd, tables, args) ||
+ item->fix_fields(thd, args) ||
(item= args[0])->check_cols(1))
return TRUE;
decimals=item->decimals;
@@ -2766,11 +2766,12 @@
*/
Item_func_group_concat::
-Item_func_group_concat(bool distinct_arg, List<Item> *select_list,
+Item_func_group_concat(Name_resolution_context *context_arg,
+ bool distinct_arg, List<Item> *select_list,
SQL_LIST *order_list, String *separator_arg)
:tmp_table_param(0), warning(0),
separator(separator_arg), tree(0), table(0),
- order(0), tables_list(0),
+ order(0), context(context_arg),
arg_count_order(order_list ? order_list->elements : 0),
arg_count_field(select_list->elements),
count_cut_values(0),
@@ -2826,7 +2827,7 @@
tree(item->tree),
table(item->table),
order(item->order),
- tables_list(item->tables_list),
+ context(item->context),
arg_count_order(item->arg_count_order),
arg_count_field(item->arg_count_field),
count_cut_values(item->count_cut_values),
@@ -2946,7 +2947,7 @@
bool
-Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
+Item_func_group_concat::fix_fields(THD *thd, Item **ref)
{
uint i; /* for loop variable */
DBUG_ASSERT(fixed == 0);
@@ -2968,7 +2969,7 @@
for (i=0 ; i < arg_count ; i++)
{
if ((!args[i]->fixed &&
- args[i]->fix_fields(thd, tables, args + i)) ||
+ args[i]->fix_fields(thd, args + i)) ||
args[i]->check_cols(1))
return TRUE;
if (i < arg_count_field)
@@ -2979,7 +2980,6 @@
null_value= 1;
thd->allow_sum_func= 1;
max_length= thd->variables.group_concat_max_len;
- tables_list= tables;
fixed= 1;
return FALSE;
}
@@ -3029,7 +3029,7 @@
tmp table columns.
*/
if (arg_count_order &&
- setup_order(thd, args, tables_list, list, all_fields, *order))
+ setup_order(thd, args, context->table_list, list, all_fields, *order))
DBUG_RETURN(TRUE);
count_field_types(tmp_table_param,all_fields,0);
--- 1.88/sql/item_sum.h Fri Jun 17 17:27:43 2005
+++ 1.89/sql/item_sum.h Fri Jul 1 07:05:35 2005
@@ -98,7 +98,7 @@
*/
virtual const char *func_name() const= 0;
virtual Item *result_item(Field *field)
- { return new Item_field(field);}
+ { return new Item_field(field); }
table_map used_tables() const { return ~(table_map) 0; } /* Not used */
bool const_item() const { return 0; }
bool is_null() { return null_value; }
@@ -124,7 +124,7 @@
Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {}
Item_sum_num(List<Item> &list) :Item_sum(list) {}
Item_sum_num(THD *thd, Item_sum_num *item) :Item_sum(thd, item) {}
- bool fix_fields(THD *, TABLE_LIST *, Item **);
+ bool fix_fields(THD *, Item **);
longlong val_int()
{
DBUG_ASSERT(fixed == 1);
@@ -543,7 +543,7 @@
was_values(TRUE)
{ collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item);
- bool fix_fields(THD *, TABLE_LIST *, Item **);
+ bool fix_fields(THD *, Item **);
table_map used_tables() const { return used_table_cache; }
bool const_item() const { return !used_table_cache; }
@@ -660,18 +660,21 @@
udf_handler udf;
public:
- Item_udf_sum(udf_func *udf_arg) :Item_sum(), udf(udf_arg) { quick_group=0;}
- Item_udf_sum( udf_func *udf_arg, List<Item> &list )
- :Item_sum( list ), udf(udf_arg)
+ Item_udf_sum(udf_func *udf_arg)
+ :Item_sum(), udf(udf_arg)
+ { quick_group=0; }
+ Item_udf_sum(udf_func *udf_arg, List<Item> &list)
+ :Item_sum(list), udf(udf_arg)
{ quick_group=0;}
Item_udf_sum(THD *thd, Item_udf_sum *item)
- :Item_sum(thd, item), udf(item->udf) { udf.not_original= TRUE; }
+ :Item_sum(thd, item), udf(item->udf)
+ { udf.not_original= TRUE; }
const char *func_name() const { return udf.name(); }
- bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
+ bool fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
fixed= 1;
- return udf.fix_fields(thd,tables,this,this->arg_count,this->args);
+ return udf.fix_fields(thd, this, this->arg_count, this->args);
}
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
virtual bool have_field_update(void) const { return 0; }
@@ -688,9 +691,10 @@
class Item_sum_udf_float :public Item_udf_sum
{
public:
- Item_sum_udf_float(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
+ Item_sum_udf_float(udf_func *udf_arg)
+ :Item_udf_sum(udf_arg) {}
Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
- :Item_udf_sum(udf_arg,list) {}
+ :Item_udf_sum(udf_arg, list) {}
Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
:Item_udf_sum(thd, item) {}
longlong val_int()
@@ -709,9 +713,10 @@
class Item_sum_udf_int :public Item_udf_sum
{
public:
- Item_sum_udf_int(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
+ Item_sum_udf_int(udf_func *udf_arg)
+ :Item_udf_sum(udf_arg) {}
Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
- :Item_udf_sum(udf_arg,list) {}
+ :Item_udf_sum(udf_arg, list) {}
Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
:Item_udf_sum(thd, item) {}
longlong val_int();
@@ -728,7 +733,8 @@
class Item_sum_udf_str :public Item_udf_sum
{
public:
- Item_sum_udf_str(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
+ Item_sum_udf_str(udf_func *udf_arg)
+ :Item_udf_sum(udf_arg) {}
Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
:Item_udf_sum(udf_arg,list) {}
Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
@@ -766,9 +772,10 @@
class Item_sum_udf_decimal :public Item_udf_sum
{
public:
- Item_sum_udf_decimal(udf_func *udf_arg) :Item_udf_sum(udf_arg) {}
+ Item_sum_udf_decimal(udf_func *udf_arg)
+ :Item_udf_sum(udf_arg) {}
Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list)
- :Item_udf_sum(udf_arg,list) {}
+ :Item_udf_sum(udf_arg, list) {}
Item_sum_udf_decimal(THD *thd, Item_sum_udf_decimal *item)
:Item_udf_sum(thd, item) {}
String *val_str(String *);
@@ -785,7 +792,8 @@
class Item_sum_udf_float :public Item_sum_num
{
public:
- Item_sum_udf_float(udf_func *udf_arg) :Item_sum_num() {}
+ Item_sum_udf_float(udf_func *udf_arg)
+ :Item_sum_num() {}
Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
:Item_sum_num(thd, item) {}
@@ -800,7 +808,8 @@
class Item_sum_udf_int :public Item_sum_num
{
public:
- Item_sum_udf_int(udf_func *udf_arg) :Item_sum_num() {}
+ Item_sum_udf_int(udf_func *udf_arg)
+ :Item_sum_num() {}
Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
:Item_sum_num(thd, item) {}
@@ -816,15 +825,17 @@
class Item_sum_udf_decimal :public Item_sum_num
{
public:
- Item_sum_udf_decimal(udf_func *udf_arg) :Item_sum_num() {}
- Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
+ Item_sum_udf_decimal(udf_func *udf_arg)
+ :Item_sum_num() {}
+ Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list)
+ :Item_sum_num() {}
Item_sum_udf_decimal(THD *thd, Item_sum_udf_float *item)
:Item_sum_num(thd, item) {}
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
my_decimal *val_decimal(my_decimal *) { DBUG_ASSERT(fixed == 1); return 0; }
void clear() {}
- bool add() { return 0; }
+ bool add() { return 0; }
void update_field() {}
};
@@ -832,8 +843,10 @@
class Item_sum_udf_str :public Item_sum_num
{
public:
- Item_sum_udf_str(udf_func *udf_arg) :Item_sum_num() {}
- Item_sum_udf_str(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
+ Item_sum_udf_str(udf_func *udf_arg)
+ :Item_sum_num() {}
+ Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
+ :Item_sum_num() {}
Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
:Item_sum_num(thd, item) {}
String *val_str(String *)
@@ -862,7 +875,7 @@
TREE *tree;
TABLE *table;
ORDER **order;
- TABLE_LIST *tables_list;
+ Name_resolution_context *context;
uint arg_count_order; // total count of ORDER BY items
uint arg_count_field; // count of arguments
uint count_cut_values;
@@ -887,8 +900,9 @@
Item_func_group_concat *group_concat_item);
public:
- Item_func_group_concat(bool is_distinct,List<Item> *is_select,
- SQL_LIST *is_order,String *is_separator);
+ Item_func_group_concat(Name_resolution_context *context_arg,
+ bool is_distinct, List<Item> *is_select,
+ SQL_LIST *is_order, String *is_separator);
Item_func_group_concat(THD *thd, Item_func_group_concat *item);
~Item_func_group_concat() {}
@@ -901,7 +915,7 @@
bool add();
void reset_field() {} // not used
void update_field() {} // not used
- bool fix_fields(THD *, TABLE_LIST *, Item **);
+ bool fix_fields(THD *,Item **);
bool setup(THD *thd);
void make_unique();
double val_real()
@@ -927,4 +941,6 @@
Item *copy_or_same(THD* thd);
void no_rows_in_result() {}
void print(String *str);
+ virtual bool change_context_processor(byte *cntx)
+ { context= (Name_resolution_context *)cntx; return FALSE; }
};
--- 1.87/sql/item_timefunc.cc Fri Jun 24 18:52:29 2005
+++ 1.88/sql/item_timefunc.cc Fri Jul 1 07:05:35 2005
@@ -1753,10 +1753,10 @@
bool
-Item_func_convert_tz::fix_fields(THD *thd_arg, TABLE_LIST *tables_arg, Item **ref)
+Item_func_convert_tz::fix_fields(THD *thd_arg, Item **ref)
{
String str;
- if (Item_date_func::fix_fields(thd_arg, tables_arg, ref))
+ if (Item_date_func::fix_fields(thd_arg, ref))
return TRUE;
tz_tables= thd_arg->lex->time_zone_tables_used;
--- 1.54/sql/item_timefunc.h Mon Jun 20 14:56:13 2005
+++ 1.55/sql/item_timefunc.h Fri Jul 1 07:05:35 2005
@@ -561,7 +561,7 @@
double val_real() { return (double) val_int(); }
String *val_str(String *str);
const char *func_name() const { return "convert_tz"; }
- bool fix_fields(THD *, struct st_table_list *, Item **);
+ bool fix_fields(THD *, Item **);
void fix_length_and_dec();
bool get_date(TIME *res, uint fuzzy_date);
void cleanup();
--- 1.25/sql/item_uniq.h Fri Jun 17 17:27:43 2005
+++ 1.26/sql/item_uniq.h Fri Jul 1 07:05:35 2005
@@ -47,7 +47,7 @@
bool add() { return 0; }
void reset_field() {}
void update_field() {}
- bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
+ bool fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
fixed= 1;
--- 1.180/sql/log_event.cc Thu Jun 9 08:28:33 2005
+++ 1.181/sql/log_event.cc Fri Jul 1 07:05:35 2005
@@ -2618,13 +2618,15 @@
#ifndef MYSQL_CLIENT
void Load_log_event::set_fields(const char* affected_db,
- List<Item> &field_list)
+ List<Item> &field_list,
+ Name_resolution_context *context)
{
uint i;
const char* field = fields;
for (i= 0; i < num_fields; i++)
{
- field_list.push_back(new Item_field(affected_db, table_name, field));
+ field_list.push_back(new Item_field(context,
+ affected_db, table_name, field));
field+= field_lens[i] + 1;
}
}
@@ -2789,7 +2791,8 @@
ex.skip_lines = skip_lines;
List<Item> field_list;
- set_fields(thd->db,field_list);
+ thd->main_lex.select_lex.context.resolve_in_table_list_only(&tables);
+ set_fields(thd->db, field_list, &thd->main_lex.select_lex.context);
thd->variables.pseudo_thread_id= thread_id;
List<Item> set_fields;
if (net)
@@ -3617,7 +3620,7 @@
Item_func_set_user_var can't substitute something else on its place =>
0 can be passed as last argument (reference on item)
*/
- e.fix_fields(thd, 0, 0);
+ e.fix_fields(thd, 0);
/*
A variable can just be considered as a table with
a single record and with a single column. Thus, like
--- 1.111/sql/log_event.h Thu May 26 20:54:25 2005
+++ 1.112/sql/log_event.h Fri Jul 1 07:05:35 2005
@@ -877,7 +877,8 @@
const char* table_name_arg,
List<Item>& fields_arg, enum enum_duplicates handle_dup, bool ignore,
bool using_trans);
- void set_fields(const char* db, List<Item> &fields_arg);
+ void set_fields(const char* db, List<Item> &fields_arg,
+ Name_resolution_context *context);
const char* get_db() { return db; }
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
--- 1.319/sql/mysql_priv.h Thu Jun 30 11:38:21 2005
+++ 1.320/sql/mysql_priv.h Fri Jul 1 07:05:35 2005
@@ -726,7 +726,8 @@
List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag,
bool ignore);
-int check_that_all_fields_are_given_values(THD *thd, TABLE *entry);
+int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
+ TABLE_LIST *table_list);
bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds);
bool mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order,
ha_rows rows, ulong options);
@@ -893,16 +894,29 @@
bool *unaliased);
bool get_key_map_from_key_list(key_map *map, TABLE *table,
List<String> *index_list);
-bool insert_fields(THD *thd,TABLE_LIST *tables,
+bool insert_fields(THD *thd, Name_resolution_context *context,
const char *db_name, const char *table_name,
- List_iterator<Item> *it, bool any_privileges);
-bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
+ List_iterator<Item> *it, bool any_privileges);
+bool setup_tables(THD *thd, Name_resolution_context *context,
+ TABLE_LIST *tables, Item **conds,
TABLE_LIST **leaves, bool select_insert);
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list, uint wild_num);
-bool setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables,
+bool setup_fields(THD *thd, Item** ref_pointer_array,
List<Item> &item, bool set_query_id,
List<Item> *sum_func_list, bool allow_sum_func);
+inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array,
+ List<Item> &item, bool set_query_id,
+ List<Item> *sum_func_list,
+ bool allow_sum_func)
+{
+ bool res;
+ thd->lex->select_lex.no_wrap_view_item= TRUE;
+ res= setup_fields(thd, ref_pointer_array, item, set_query_id, sum_func_list,
+ allow_sum_func);
+ thd->lex->select_lex.no_wrap_view_item= FALSE;
+ return res;
+}
int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
COND **conds);
int setup_ftfuncs(SELECT_LEX* select);
--- 1.259/sql/sql_base.cc Mon Jun 27 16:02:36 2005
+++ 1.260/sql/sql_base.cc Fri Jul 1 07:05:35 2005
@@ -2439,21 +2439,19 @@
table_list->alias, name, item_name, (ulong) ref));
if (table_list->field_translation)
{
- uint num;
- if (table_list->schema_table_reformed)
+ Field_iterator_view field_it;
+ field_it.set(table_list);
+ DBUG_ASSERT(table_list->schema_table_reformed ||
+ (ref != 0 && table_list->view != 0));
+ for (; !field_it.end_of_fields(); field_it.next())
{
- num= thd->lex->current_select->item_list.elements;
- }
- else
- {
- DBUG_ASSERT(ref != 0 && table_list->view != 0);
- num= table_list->view->select_lex.item_list.elements;
- }
- Field_translator *trans= table_list->field_translation;
- for (uint i= 0; i < num; i ++)
- {
- if (!my_strcasecmp(system_charset_info, trans[i].name, name))
+ if (!my_strcasecmp(system_charset_info, field_it.name(), name))
{
+ Item *item= field_it.create_item(thd);
+ if (!item)
+ {
+ DBUG_RETURN(0);
+ }
if (table_list->schema_table_reformed)
{
/*
@@ -2462,7 +2460,7 @@
So we can return ->field. It is used only for
'show & where' commands.
*/
- DBUG_RETURN(((Item_field*) (trans[i].item))->field);
+ DBUG_RETURN(((Item_field*) (field_it.item()))->field);
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_grants_view &&
@@ -2472,26 +2470,10 @@
name, length))
DBUG_RETURN(WRONG_GRANT);
#endif
- if (thd->lex->current_select->no_wrap_view_item)
- {
- if (register_tree_change)
- thd->change_item_tree(ref, trans[i].item);
- else
- *ref= trans[i].item;
- }
+ if (register_tree_change)
+ thd->change_item_tree(ref, item);
else
- {
- Item_ref *item_ref= new Item_ref(&trans[i].item,
- table_list->view_name.str,
- item_name);
- /* as far as Item_ref have defined reference it do not need tables */
- if (register_tree_change && item_ref)
- thd->change_item_tree(ref, item_ref);
- else if (item_ref)
- *ref= item_ref;
- if (!(*ref)->fixed)
- (*ref)->fix_fields(thd, 0, ref);
- }
+ *ref= item;
DBUG_RETURN((Field*) view_ref_found);
}
}
@@ -3066,7 +3048,8 @@
*/
it.replace(new Item_int("Not_used", (longlong) 1, 21));
}
- else if (insert_fields(thd,tables,((Item_field*) item)->db_name,
+ else if (insert_fields(thd, ((Item_field*) item)->context,
+ ((Item_field*) item)->db_name,
((Item_field*) item)->table_name, &it,
any_privileges))
{
@@ -3102,7 +3085,7 @@
** Check that all given fields exists and fill struct with current data
****************************************************************************/
-bool setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
+bool setup_fields(THD *thd, Item **ref_pointer_array,
List<Item> &fields, bool set_query_id,
List<Item> *sum_func_list, bool allow_sum_func)
{
@@ -3131,7 +3114,7 @@
Item **ref= ref_pointer_array;
while ((item= it++))
{
- if (!item->fixed && item->fix_fields(thd, tables, it.ref()) ||
+ if (!item->fixed && item->fix_fields(thd, it.ref()) ||
(item= *(it.ref()))->check_cols(1))
{
DBUG_RETURN(TRUE); /* purecov: inspected */
@@ -3181,6 +3164,7 @@
SYNOPSIS
setup_tables()
thd Thread handler
+ context name resolution contest to setup table list there
tables Table list
conds Condition of current SELECT (can be changed by VIEW)
leaves List of join table leaves list
@@ -3200,11 +3184,15 @@
TRUE error
*/
-bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
+bool setup_tables(THD *thd, Name_resolution_context *context,
+ TABLE_LIST *tables, Item **conds,
TABLE_LIST **leaves, bool select_insert)
{
uint tablenr= 0;
DBUG_ENTER("setup_tables");
+
+ context->table_list= tables;
+
/*
this is used for INSERT ... SELECT.
For select we setup tables except first (and its underlying tables)
@@ -3259,10 +3247,21 @@
table_list;
table_list= table_list->next_local)
{
- if (table_list->ancestor &&
- table_list->setup_ancestor(thd, conds,
- table_list->effective_with_check))
- DBUG_RETURN(1);
+ if (table_list->ancestor)
+ {
+ DBUG_ASSERT(table_list->view);
+ Query_arena *arena= thd->current_arena, backup;
+ bool res;
+ if (arena->is_conventional())
+ arena= 0; // For easier test
+ else
+ thd->set_n_backup_item_arena(arena, &backup);
+ res= table_list->setup_ancestor(thd);
+ if (arena)
+ thd->restore_backup_item_arena(arena, &backup);
+ if (res)
+ DBUG_RETURN(1);
+ }
}
DBUG_RETURN(0);
}
@@ -3314,7 +3313,7 @@
SYNOPSIS
insert_fields()
thd Thread handler
- tables List of tables
+ context Context for name resolution
db_name Database name in case of 'database_name.table_name.*'
table_name Table name in case of 'table_name.*'
it Pointer to '*'
@@ -3328,7 +3327,7 @@
*/
bool
-insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
+insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
const char *table_name, List_iterator<Item> *it,
bool any_privileges)
{
@@ -3352,7 +3351,9 @@
}
found= 0;
- for (; tables; tables= tables->next_local)
+ for (TABLE_LIST *tables= context->table_list;
+ tables;
+ tables= tables->next_local)
{
Field_iterator *iterator;
TABLE_LIST *natural_join_table;
@@ -3361,7 +3362,6 @@
TABLE_LIST *last;
TABLE_LIST *embedding;
TABLE *table= tables->table;
- bool alias_used= 0;
if (!table_name || (!my_strcasecmp(table_alias_charset, table_name,
tables->alias) &&
@@ -3395,16 +3395,6 @@
}
}
#endif
- if (table)
- thd->used_tables|= table->map;
- else
- {
- view_iter.set(tables);
- for (; !view_iter.end_of_fields(); view_iter.next())
- {
- thd->used_tables|= view_iter.item(thd)->used_tables();
- }
- }
natural_join_table= 0;
last= embedded= tables;
@@ -3435,8 +3425,6 @@
{
iterator= &view_iter;
view= 1;
- alias_used= my_strcasecmp(table_alias_charset,
- tables->table_name, tables->alias);
}
else
{
@@ -3445,6 +3433,10 @@
}
iterator->set(tables);
+ /* for view used tables will be collected in following loop */
+ if (table)
+ thd->used_tables|= table->map;
+
for (; !iterator->end_of_fields(); iterator->next())
{
Item *not_used_item;
@@ -3457,16 +3449,10 @@
strlen(field_name), ¬_used_item, 0, 0, 0,
¬_used_field_index, TRUE))
{
- Item *item= iterator->item(thd);
- if (view && !thd->lex->current_select->no_wrap_view_item)
- {
- /*
- as far as we have view, then item point to view_iter, so we
- can use it directly for this view specific operation
- */
- item= new Item_ref(view_iter.item_ptr(), tables->view_name.str,
- field_name);
- }
+ Item *item= iterator->create_item(thd);
+ if (!item)
+ goto err;
+ thd->used_tables|= item->used_tables();
if (!found++)
(void) it->replace(item); // Replace '*'
else
@@ -3537,9 +3523,7 @@
my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
else
my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
err:
-#endif
DBUG_RETURN(1);
}
@@ -3550,16 +3534,25 @@
SYNOPSIS
setup_conds()
thd thread handler
- tables list of tables for name resolving
leaves list of leaves of join table tree
*/
-int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds)
+int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
+ COND **conds)
{
SELECT_LEX *select_lex= thd->lex->current_select;
Query_arena *arena= thd->current_arena, backup;
- bool save_wrapper= thd->lex->current_select->no_wrap_view_item;
TABLE_LIST *table= NULL; // For HP compilers
+ /*
+ it_is_update set to TRUE when tables of primary SELECT_LEX (SELECT_LEX
+ which belong to LEX, i.e. most up SELECT) will be updated by
+ INSERT/UPDATE/LOAD
+ NOTE: using this condition helps to prevent call of prepare_check_option()
+ from subquery of VIEW, because tables of subquery belongs to VIEW
+ (see condition before prepare_check_option() call)
+ */
+ bool it_is_update= (select_lex == &thd->lex->select_lex) &&
+ thd->lex->which_check_option_applicable();
DBUG_ENTER("setup_conds");
if (select_lex->conds_processed_with_permanent_arena ||
@@ -3568,12 +3561,17 @@
thd->set_query_id=1;
- thd->lex->current_select->no_wrap_view_item= 0;
+ for (table= tables; table; table= table->next_local)
+ {
+ if (table->prepare_where(thd, conds, FALSE))
+ goto err_no_arena;
+ }
+
select_lex->cond_count= 0;
if (*conds)
{
thd->where="where clause";
- if (!(*conds)->fixed && (*conds)->fix_fields(thd, tables, conds) ||
+ if (!(*conds)->fixed && (*conds)->fix_fields(thd, conds) ||
(*conds)->check_cols(1))
goto err_no_arena;
}
@@ -3591,11 +3589,12 @@
/* Make a join an a expression */
thd->where="on clause";
if (!embedded->on_expr->fixed &&
- embedded->on_expr->fix_fields(thd, tables, &embedded->on_expr)
||
+ embedded->on_expr->fix_fields(thd, &embedded->on_expr) ||
embedded->on_expr->check_cols(1))
goto err_no_arena;
select_lex->cond_count++;
}
+
if (embedded->natural_join)
{
/* Make a join of all fields wich have the same name */
@@ -3675,7 +3674,8 @@
{
if (t2_field != view_ref_found)
{
- if (!(item_t2= new Item_field(thd, t2_field)))
+ if (!(item_t2= new Item_field(thd, &select_lex->context,
+ t2_field)))
goto err;
/* Mark field used for table cache */
t2_field->query_id= thd->query_id;
@@ -3687,7 +3687,7 @@
t1_field->query_id= thd->query_id;
t1->used_keys.intersect(t1_field->part_of_key);
}
- Item_func_eq *tmp= new Item_func_eq(iterator->item(thd),
+ Item_func_eq *tmp= new Item_func_eq(iterator->create_item(thd),
item_t2);
if (!tmp)
goto err;
@@ -3703,7 +3703,7 @@
{
COND *on_expr= cond_and;
if (!on_expr->fixed)
- on_expr->fix_fields(thd, 0, &on_expr);
+ on_expr->fix_fields(thd, &on_expr);
if (!embedded->outer_join) // Not left join
{
*conds= and_conds(*conds, cond_and);
@@ -3712,7 +3712,7 @@
thd->restore_backup_item_arena(arena, &backup);
if (*conds && !(*conds)->fixed)
{
- if ((*conds)->fix_fields(thd, tables, conds))
+ if ((*conds)->fix_fields(thd, conds))
goto err_no_arena;
}
}
@@ -3724,8 +3724,7 @@
thd->restore_backup_item_arena(arena, &backup);
if (embedded->on_expr && !embedded->on_expr->fixed)
{
- if (embedded->on_expr->fix_fields(thd, tables,
- &embedded->on_expr))
+ if (embedded->on_expr->fix_fields(thd, &embedded->on_expr))
goto err_no_arena;
}
}
@@ -3737,6 +3736,20 @@
}
while (embedding &&
embedding->nested_join->join_list.head() == embedded);
+
+ /* process CHECK OPTION */
+ if (it_is_update)
+ {
+ TABLE_LIST *view= table->belong_to_view;
+ if (!view)
+ view= table;
+ if (view->effective_with_check)
+ {
+ if (view->prepare_check_option(thd))
+ goto err_no_arena;
+ thd->change_item_tree(&table->check_option, view->check_option);
+ }
+ }
}
if (!thd->current_arena->is_conventional())
@@ -3750,14 +3763,12 @@
select_lex->where= *conds;
select_lex->conds_processed_with_permanent_arena= 1;
}
- thd->lex->current_select->no_wrap_view_item= save_wrapper;
DBUG_RETURN(test(thd->net.report_error));
err:
if (arena)
thd->restore_backup_item_arena(arena, &backup);
err_no_arena:
- thd->lex->current_select->no_wrap_view_item= save_wrapper;
DBUG_RETURN(1);
}
--- 1.190/sql/sql_class.cc Thu Jun 23 19:22:02 2005
+++ 1.191/sql/sql_class.cc Fri Jul 1 07:05:35 2005
@@ -1451,17 +1451,16 @@
(void)local_vars.push_back(new Item_splocal(mv->s, mv->offset));
else
{
- Item_func_set_user_var *xx = new Item_func_set_user_var(mv->s, item);
+ Item_func_set_user_var *var= new Item_func_set_user_var(mv->s, item);
/*
Item_func_set_user_var can't substitute something else on its place =>
0 can be passed as last argument (reference on item)
Item_func_set_user_var can't be fixed after creation, so we do not
- check xx->fixed
+ check var->fixed
*/
- xx->fix_fields(thd, (TABLE_LIST*) thd->lex->select_lex.table_list.first,
- 0);
- xx->fix_length_and_dec();
- vars.push_back(xx);
+ var->fix_fields(thd, 0);
+ var->fix_length_and_dec();
+ vars.push_back(var);
}
}
return 0;
@@ -1538,15 +1537,19 @@
void
Statement::set_n_backup_statement(Statement *stmt, Statement *backup)
{
+ DBUG_ENTER("Statement::set_n_backup_statement");
backup->set_statement(this);
set_statement(stmt);
+ DBUG_VOID_RETURN;
}
void Statement::restore_backup_statement(Statement *stmt, Statement *backup)
{
+ DBUG_ENTER("Statement::restore_backup_statement");
stmt->set_statement(this);
set_statement(backup);
+ DBUG_VOID_RETURN;
}
@@ -1569,6 +1572,7 @@
{
DBUG_ENTER("Query_arena::set_n_backup_item_arena");
DBUG_ASSERT(backup->is_backup_arena == FALSE);
+
backup->set_item_arena(this);
set_item_arena(set);
#ifndef DBUG_OFF
--- 1.152/sql/sql_delete.cc Sat Jun 18 00:14:28 2005
+++ 1.153/sql/sql_delete.cc Fri Jul 1 07:05:35 2005
@@ -300,7 +300,9 @@
SELECT_LEX *select_lex= &thd->lex->select_lex;
DBUG_ENTER("mysql_prepare_delete");
- if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables, FALSE) ||
+ if (setup_tables(thd, &thd->lex->select_lex.context,
+ table_list, conds, &select_lex->leaf_tables,
+ FALSE) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
setup_ftfuncs(select_lex))
DBUG_RETURN(TRUE);
@@ -356,7 +358,8 @@
lex->query_tables also point on local list of DELETE SELECT_LEX
*/
- if (setup_tables(thd, lex->query_tables, &lex->select_lex.where,
+ if (setup_tables(thd, &thd->lex->select_lex.context,
+ lex->query_tables, &lex->select_lex.where,
&lex->select_lex.leaf_tables, FALSE))
DBUG_RETURN(TRUE);
--- 1.163/sql/sql_insert.cc Wed Jun 22 20:07:26 2005
+++ 1.164/sql/sql_insert.cc Fri Jul 1 07:05:36 2005
@@ -31,7 +31,7 @@
extern "C" pthread_handler_decl(handle_delayed_insert,arg);
static void unlink_blobs(register TABLE *table);
#endif
-static bool check_view_insertability(TABLE_LIST *view, query_id_t query_id);
+static bool check_view_insertability(THD *thd, TABLE_LIST *view);
/* Define to force use of my_malloc() if the allocated memory block is big */
@@ -106,7 +106,11 @@
}
else
{ // Part field list
- TABLE_LIST *save_next;
+ Name_resolution_context *context= &thd->lex->select_lex.context;
+ TABLE_LIST *save_next= table_list->next_local,
+ *save_context= context->table_list;
+ bool save_resolve_in_select_list=
+ thd->lex->select_lex.context.resolve_in_select_list;
int res;
if (fields.elements != values.elements)
{
@@ -115,12 +119,15 @@
}
thd->dupp_field=0;
- thd->lex->select_lex.no_wrap_view_item= 1;
- save_next= table_list->next_local; // fields only from first table
+ thd->lex->select_lex.no_wrap_view_item= TRUE;
+ /* fields only from first table */
table_list->next_local= 0;
- res= setup_fields(thd, 0, table_list, fields, 1, 0, 0);
+ context->resolve_in_table_list_only(table_list);
+ res= setup_fields(thd, 0, fields, 1, 0, 0);
table_list->next_local= save_next;
- thd->lex->select_lex.no_wrap_view_item= 0;
+ thd->lex->select_lex.no_wrap_view_item= FALSE;
+ context->table_list= save_context;
+ context->resolve_in_select_list= save_resolve_in_select_list;
if (res)
return -1;
if (table_list->effective_algorithm == VIEW_ALGORITHM_MERGE)
@@ -159,7 +166,7 @@
if (check_key_in_view(thd, table_list) ||
(table_list->view &&
- check_view_insertability(table_list, thd->query_id)))
+ check_view_insertability(thd, table_list)))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT");
return -1;
@@ -209,7 +216,7 @@
Check the fields we are going to modify. This will set the query_id
of all used fields to the threads query_id.
*/
- if (setup_fields(thd, 0, insert_table_list, update_fields, 1, 0, 0))
+ if (setup_fields(thd, 0, update_fields, 1, 0, 0))
return -1;
if (table->timestamp_field)
@@ -247,6 +254,7 @@
ulonglong id;
COPY_INFO info;
TABLE *table= 0;
+ TABLE_LIST *next_local;
List_iterator_fast<List_item> its(values_list);
List_item *values;
#ifndef EMBEDDED_LIBRARY
@@ -327,7 +335,9 @@
/* mysql_prepare_insert set table_list->table if it was not set */
table= table_list->table;
- // is table which we are changing used somewhere in other parts of query
+ next_local= table_list->next_local;
+ table_list->next_local= 0;
+ thd->lex->select_lex.context.resolve_in_table_list_only(table_list);
value_count= values->elements;
while ((values= its++))
{
@@ -337,10 +347,11 @@
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
goto abort;
}
- if (setup_fields(thd, 0, table_list, *values, 0, 0, 0))
+ if (setup_fields(thd, 0, *values, 0, 0, 0))
goto abort;
}
its.rewind ();
+ table_list->next_local= next_local;
/*
Fill in the given fields and dump it to the table file
*/
@@ -387,12 +398,16 @@
MODE_STRICT_ALL_TABLES)));
if ((fields.elements || !value_count) &&
- check_that_all_fields_are_given_values(thd, table))
+ check_that_all_fields_are_given_values(thd, table, table_list))
{
/* thd->net.report_error is now set, which will abort the next loop */
error= 1;
}
+ if (table_list->prepare_where(thd, 0, TRUE) ||
+ table_list->prepare_check_option(thd))
+ error= 1;
+
while ((values= its++))
{
if (fields.elements || !value_count)
@@ -596,6 +611,7 @@
SYNOPSIS
check_view_insertability()
+ thd - thread handler
view - reference on VIEW
IMPLEMENTATION
@@ -612,7 +628,7 @@
TRUE - can't be used for insert
*/
-static bool check_view_insertability(TABLE_LIST *view, query_id_t query_id)
+static bool check_view_insertability(THD * thd, TABLE_LIST *view)
{
uint num= view->view->select_lex.item_list.elements;
TABLE *table= view->table;
@@ -620,15 +636,25 @@
*trans_end= trans_start + num;
Field_translator *trans;
Field **field_ptr= table->field;
- query_id_t other_query_id= query_id - 1;
+ uint used_fields_buff_size= (table->s->fields + 7) / 8;
+ uchar *used_fields_buff= (uchar*)thd->alloc(used_fields_buff_size);
+ MY_BITMAP used_fields;
DBUG_ENTER("check_key_in_view");
+ if (!used_fields_buff)
+ DBUG_RETURN(TRUE); // EOM
+
DBUG_ASSERT(view->table != 0 && view->field_translation != 0);
+ bitmap_init(&used_fields, used_fields_buff, used_fields_buff_size * 8, 0);
+ bitmap_clear_all(&used_fields);
+
view->contain_auto_increment= 0;
/* check simplicity and prepare unique test of view */
for (trans= trans_start; trans != trans_end; trans++)
{
+ if (!trans->item->fixed && trans->item->fix_fields(thd,
&trans->item))
+ return TRUE;
Item_field *field;
/* simple SELECT list entry (field without expression) */
if (!(field= trans->item->filed_for_view_update()))
@@ -636,7 +662,6 @@
if (field->field->unireg_check == Field::NEXT_NUMBER)
view->contain_auto_increment= 1;
/* prepare unique test */
- field->field->query_id= other_query_id;
/*
remove collation (or other transparent for update function) if we have
it
@@ -648,29 +673,12 @@
{
/* Thanks to test above, we know that all columns are of type Item_field */
Item_field *field= (Item_field *)trans->item;
- if (field->field->query_id == query_id)
+ /* check fields belong to table in which we are inserting */
+ if (field->field->table == table &&
+ bitmap_fast_test_and_set(&used_fields, field->field->field_index))
DBUG_RETURN(TRUE);
- field->field->query_id= query_id;
}
- /* VIEW contain all fields without default value */
- for (; *field_ptr; field_ptr++)
- {
- Field *field= *field_ptr;
- /* field have not default value */
- if ((field->type() == FIELD_TYPE_BLOB) &&
- (table->timestamp_field != field ||
- field->unireg_check == Field::TIMESTAMP_UN_FIELD))
- {
- for (trans= trans_start; ; trans++)
- {
- if (trans == trans_end)
- DBUG_RETURN(TRUE); // Field was not part of view
- if (((Item_field *)trans->item)->field == *field_ptr)
- break; // ok
- }
- }
- }
DBUG_RETURN(FALSE);
}
@@ -698,7 +706,8 @@
bool insert_into_view= (table_list->view != 0);
DBUG_ENTER("mysql_prepare_insert_check_table");
- if (setup_tables(thd, table_list, where, &thd->lex->select_lex.leaf_tables,
+ if (setup_tables(thd, &thd->lex->select_lex.context,
+ table_list, where, &thd->lex->select_lex.leaf_tables,
select_insert))
DBUG_RETURN(TRUE);
@@ -711,7 +720,7 @@
table_list->view_db.str, table_list->view_name.str);
DBUG_RETURN(TRUE);
}
- DBUG_RETURN(insert_view_fields(&fields, table_list));
+ DBUG_RETURN(insert_view_fields(thd, &fields, table_list));
}
DBUG_RETURN(FALSE);
@@ -741,8 +750,10 @@
enum_duplicates duplic,
COND **where, bool select_insert)
{
+ TABLE_LIST *save_table_list= thd->lex->select_lex.context.table_list;
bool insert_into_view= (table_list->view != 0);
- /* TODO: use this condition for 'WITH CHECK OPTION' */
+ bool save_resolve_in_select_list=
+ thd->lex->select_lex.context.resolve_in_select_list;
bool res;
TABLE_LIST *next_local;
DBUG_ENTER("mysql_prepare_insert");
@@ -750,6 +761,26 @@
(ulong)table_list, (ulong)table,
(int)insert_into_view));
+ /*
+ For subqueries in VALUES() we should not see the table in which we are
+ inserting (for INSERT ... SELECT this is done by changing table_list,
+ because INSERT ... SELECT share SELECT_LEX it with SELECT.
+ */
+ if (!select_insert)
+ {
+ for (SELECT_LEX_UNIT *un= thd->lex->select_lex.first_inner_unit();
+ un;
+ un= un->next_unit())
+ {
+ for (SELECT_LEX *sl= un->first_select();
+ sl;
+ sl= sl->next_select())
+ {
+ sl->context.outer_context= 0;
+ }
+ }
+ }
+
if (duplic == DUP_UPDATE)
{
/* it should be allocated before Item::fix_fields() */
@@ -763,29 +794,37 @@
next_local= table_list->next_local;
table_list->next_local= 0;
+ thd->lex->select_lex.context.resolve_in_table_list_only(table_list);
if ((values && check_insert_fields(thd, table_list, fields, *values,
!insert_into_view)) ||
- (values && setup_fields(thd, 0, table_list, *values, 0, 0, 0)) ||
+ (values && setup_fields(thd, 0, *values, 0, 0, 0)) ||
(duplic == DUP_UPDATE &&
- ((thd->lex->select_lex.no_wrap_view_item= 1,
+ ((thd->lex->select_lex.no_wrap_view_item= TRUE,
(res= check_update_fields(thd, table_list, update_fields)),
- thd->lex->select_lex.no_wrap_view_item= 0,
+ thd->lex->select_lex.no_wrap_view_item= FALSE,
res) ||
- setup_fields(thd, 0, table_list, update_values, 1, 0, 0))))
+ setup_fields(thd, 0, update_values, 1, 0, 0))))
DBUG_RETURN(TRUE);
table_list->next_local= next_local;
-
+ thd->lex->select_lex.context.table_list= save_table_list;
+ thd->lex->select_lex.context.resolve_in_select_list=
+ save_resolve_in_select_list;
if (!table)
table= table_list->table;
- if (!select_insert && unique_table(table_list, table_list->next_global))
+ if (!select_insert)
{
- my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
- DBUG_RETURN(TRUE);
+ Item *fake_conds= 0;
+ if (unique_table(table_list, table_list->next_global))
+ {
+ my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
+ DBUG_RETURN(TRUE);
+ }
+ thd->lex->select_lex.fix_prepare_information(thd, &fake_conds);
+ thd->lex->select_lex.first_execution= 0;
}
if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
- thd->lex->select_lex.first_execution= 0;
DBUG_RETURN(FALSE);
}
@@ -1038,7 +1077,8 @@
Check that all fields with arn't null_fields are used
******************************************************************************/
-int check_that_all_fields_are_given_values(THD *thd, TABLE *entry)
+int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
+ TABLE_LIST *table_list)
{
int err= 0;
for (Field **field=entry->field ; *field ; field++)
@@ -1047,10 +1087,29 @@
((*field)->flags & NO_DEFAULT_VALUE_FLAG) &&
((*field)->real_type() != FIELD_TYPE_ENUM))
{
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_NO_DEFAULT_FOR_FIELD,
- ER(ER_NO_DEFAULT_FOR_FIELD),
- (*field)->field_name);
+ bool view= FALSE;
+ if (table_list)
+ {
+ table_list= (table_list->belong_to_view ?
+ table_list->belong_to_view :
+ table_list);
+ view= (table_list->view);
+ }
+ if (view)
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_NO_DEFAULT_FOR_VIEW_FIELD,
+ ER(ER_NO_DEFAULT_FOR_VIEW_FIELD),
+ table_list->view_db.str,
+ table_list->view_name.str);
+ }
+ else
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_NO_DEFAULT_FOR_FIELD,
+ ER(ER_NO_DEFAULT_FOR_FIELD),
+ (*field)->field_name);
+ }
err= 1;
}
}
@@ -1938,7 +1997,6 @@
SELECT_LEX do not belong to INSERT statement, so we can't add WHERE
clause if table is VIEW
*/
- lex->query_tables->no_where_clause= 1;
if (mysql_prepare_insert(thd, lex->query_tables,
lex->query_tables->table, lex->field_list, 0,
lex->update_list, lex->value_list,
@@ -1988,8 +2046,8 @@
int
select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
- int res;
LEX *lex= thd->lex;
+ int res;
SELECT_LEX *lex_current_select_save= lex->current_select;
DBUG_ENTER("select_insert::prepare");
@@ -2043,8 +2101,11 @@
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES)));
- DBUG_RETURN(fields->elements &&
- check_that_all_fields_are_given_values(thd, table));
+ res= ((fields->elements &&
+ check_that_all_fields_are_given_values(thd, table, table_list)) ||
+ table_list->prepare_where(thd, 0, TRUE) ||
+ table_list->prepare_check_option(thd));
+ DBUG_RETURN(res);
}
@@ -2290,7 +2351,8 @@
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES)));
- DBUG_RETURN(check_that_all_fields_are_given_values(thd, table));
+ DBUG_RETURN(check_that_all_fields_are_given_values(thd, table,
+ table_list));
}
--- 1.150/sql/sql_lex.cc Fri Jun 17 22:27:21 2005
+++ 1.151/sql/sql_lex.cc Fri Jul 1 07:05:36 2005
@@ -1104,7 +1104,8 @@
having= where= prep_where= 0;
olap= UNSPECIFIED_OLAP_TYPE;
having_fix_field= 0;
- resolve_mode= NOMATTER_MODE;
+ context.select_lex= this;
+ context.init();
cond_count= with_wild= 0;
conds_processed_with_permanent_arena= 0;
ref_pointer_array= 0;
@@ -1703,8 +1704,7 @@
bool st_lex::only_view_structure()
{
- switch(sql_command)
- {
+ switch (sql_command) {
case SQLCOM_SHOW_CREATE:
case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_FIELDS:
@@ -1744,6 +1744,31 @@
}
}
+/*
+ Get effective type of CHECK OPTION for given view
+
+ SYNOPSIS
+ get_effective_with_check()
+ view given view
+
+ NOTE
+ It have not sense to set CHECK OPTION for SELECT satement or subqueries,
+ so we do not.
+
+ RETURN
+ VIEW_CHECK_NONE no need CHECK OPTION
+ VIEW_CHECK_LOCAL CHECK OPTION LOCAL
+ VIEW_CHECK_CASCADED CHECK OPTION CASCADED
+*/
+
+uint8 st_lex::get_effective_with_check(st_table_list *view)
+{
+ if (view->select_lex->master_unit() == &unit &&
+ which_check_option_applicable())
+ return (uint8)view->with_check;
+ return VIEW_CHECK_NONE;
+}
+
/*
initialize limit counters
@@ -1804,7 +1829,8 @@
*/
if ((*link_to_local= test(select_lex.table_list.first)))
{
- select_lex.table_list.first= (byte*) first->next_local;
+ select_lex.table_list.first= (byte*) (select_lex.context.table_list=
+ first->next_local);
select_lex.table_list.elements--; //safety
first->next_local= 0;
/*
@@ -1909,7 +1935,8 @@
if (link_to_local)
{
first->next_local= (TABLE_LIST*) select_lex.table_list.first;
- select_lex.table_list.first= (byte*) first;
+ select_lex.table_list.first=
+ (byte*) select_lex.context.table_list= first;
select_lex.table_list.elements++; //safety
}
}
@@ -1930,7 +1957,21 @@
if (!thd->current_arena->is_conventional() && first_execution)
{
first_execution= 0;
- prep_where= where;
+ if (*conds)
+ {
+ prep_where= *conds;
+ *conds= where= prep_where->copy_andor_structure(thd);
+ }
+ for (TABLE_LIST *tbl= (TABLE_LIST *)table_list.first;
+ tbl;
+ tbl= tbl->next_local)
+ {
+ if (tbl->on_expr)
+ {
+ tbl->prep_on_expr= tbl->on_expr;
+ tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
+ }
+ }
}
}
@@ -1945,3 +1986,4 @@
st_select_lex_unit::change_result
are in sql_union.cc
*/
+
--- 1.186/sql/sql_lex.h Fri Jun 24 21:48:06 2005
+++ 1.187/sql/sql_lex.h Fri Jul 1 07:05:36 2005
@@ -470,6 +470,7 @@
class st_select_lex: public st_select_lex_node
{
public:
+ Name_resolution_context context;
char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */
Item *where, *having; /* WHERE & HAVING clauses */
Item *prep_where; /* saved WHERE clause for prepared statement processing */
@@ -549,27 +550,6 @@
/* exclude this select from check of unique_table() */
bool exclude_from_table_unique_test;
- /*
- SELECT for SELECT command st_select_lex. Used to privent scaning
- item_list of non-SELECT st_select_lex (no sense find to finding
- reference in it (all should be in tables, it is dangerouse due
- to order of fix_fields calling for non-SELECTs commands (item list
- can be not fix_fieldsd)). This value will be assigned for
- primary select (sql_yac.yy) and for any subquery and
- UNION SELECT (sql_parse.cc mysql_new_select())
-
-
- INSERT for primary st_select_lex structure of simple INSERT/REPLACE
- (used for name resolution, see Item_fiels & Item_ref fix_fields,
- FALSE for INSERT/REPLACE ... SELECT, because it's
- st_select_lex->table_list will be preprocessed (first table removed)
- before passing to handle_select)
-
- NOMATTER for other
- */
- enum {NOMATTER_MODE, SELECT_MODE, INSERT_MODE} resolve_mode;
-
-
void init_query();
void init_select();
st_select_lex_unit* master_unit();
@@ -903,7 +883,30 @@
bool can_not_use_merged();
bool only_view_structure();
bool need_correct_ident();
+ uint8 get_effective_with_check(st_table_list *view);
+ /*
+ Is this update command where 'WHITH CHECK OPTION' clause is important
+ SYNOPSIS
+ st_lex::which_check_option_applicable()
+
+ RETURN
+ TRUE have to take 'WHITH CHECK OPTION' clause into account
+ FALSE 'WHITH CHECK OPTION' clause do not need
+ */
+ inline bool which_check_option_applicable()
+ {
+ switch (sql_command) {
+ case SQLCOM_UPDATE:
+ case SQLCOM_UPDATE_MULTI:
+ case SQLCOM_INSERT:
+ case SQLCOM_INSERT_SELECT:
+ case SQLCOM_LOAD:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ }
inline bool requires_prelocking()
{
return test(query_tables_own_last);
--- 1.80/sql/sql_load.cc Mon May 30 19:54:30 2005
+++ 1.81/sql/sql_load.cc Fri Jul 1 07:05:36 2005
@@ -149,7 +149,8 @@
}
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
- if (setup_tables(thd, table_list, &unused_conds,
+ if (setup_tables(thd, &thd->lex->select_lex.context,
+ table_list, &unused_conds,
&thd->lex->select_lex.leaf_tables, FALSE))
DBUG_RETURN(-1);
if (!table_list->table || // do not suport join view
@@ -159,6 +160,11 @@
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD");
DBUG_RETURN(TRUE);
}
+ if (table_list->prepare_where(thd, 0, TRUE) ||
+ table_list->prepare_check_option(thd))
+ {
+ DBUG_RETURN(TRUE);
+ }
/*
Let us emit an error if we are loading data to table which is used
in subselect in SET clause like we do it for INSERT.
@@ -186,16 +192,16 @@
Let us also prepare SET clause, altough it is probably empty
in this case.
*/
- if (setup_fields(thd, 0, table_list, set_fields, 1, 0, 0) ||
- setup_fields(thd, 0, table_list, set_values, 1, 0, 0))
+ if (setup_fields(thd, 0, set_fields, 1, 0, 0) ||
+ setup_fields(thd, 0, set_values, 1, 0, 0))
DBUG_RETURN(TRUE);
}
else
{ // Part field list
/* TODO: use this conds for 'WITH CHECK OPTIONS' */
- if (setup_fields(thd, 0, table_list, fields_vars, 1, 0, 0) ||
- setup_fields(thd, 0, table_list, set_fields, 1, 0, 0) ||
- check_that_all_fields_are_given_values(thd, table))
+ if (setup_fields(thd, 0, fields_vars, 1, 0, 0) ||
+ setup_fields(thd, 0, set_fields, 1, 0, 0) ||
+ check_that_all_fields_are_given_values(thd, table, table_list))
DBUG_RETURN(TRUE);
/*
Check whenever TIMESTAMP field with auto-set feature specified
@@ -209,7 +215,7 @@
check_that_all_fields_are_given_values() and setting use_timestamp
since it may update query_id for some fields.
*/
- if (setup_fields(thd, 0, table_list, set_values, 1, 0, 0))
+ if (setup_fields(thd, 0, set_values, 1, 0, 0))
DBUG_RETURN(TRUE);
}
--- 1.438/sql/sql_parse.cc Thu Jun 30 13:20:46 2005
+++ 1.439/sql/sql_parse.cc Fri Jul 1 07:05:36 2005
@@ -2289,6 +2289,10 @@
lex->first_lists_tables_same();
/* should be assigned after making first tables same */
all_tables= lex->query_tables;
+ /* set context for commands which do not use setup_tables */
+ select_lex->
+ context.resolve_in_table_list_only((TABLE_LIST*)select_lex->
+ table_list.first);
/*
Reset warning count for each query that uses tables
@@ -2572,7 +2576,7 @@
goto error;
/* PURGE MASTER LOGS BEFORE 'data' */
it= (Item *)lex->value_list.head();
- if ((!it->fixed &&it->fix_fields(lex->thd, 0, &it)) ||
+ if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
it->check_cols(1))
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
@@ -2881,9 +2885,7 @@
CREATE from SELECT give its SELECT_LEX for SELECT,
and item_list belong to SELECT
*/
- select_lex->resolve_mode= SELECT_LEX::SELECT_MODE;
res= handle_select(thd, lex, result, 0);
- select_lex->resolve_mode= SELECT_LEX::NOMATTER_MODE;
delete result;
}
/* reset for PS */
@@ -3222,6 +3224,8 @@
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if ((res= insert_precheck(thd, all_tables)))
break;
+ /* Skip first table, which is the table we are inserting in */
+ select_lex->context.table_list= first_table->next_local;
res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
lex->update_list, lex->value_list,
lex->duplicates, lex->ignore);
@@ -3252,18 +3256,17 @@
select_lex->table_list.first= (byte*)first_table->next_local;
res= mysql_insert_select_prepare(thd);
+ lex->select_lex.context.table_list= first_table->next_local;
if (!res && (result= new select_insert(first_table, first_table->table,
&lex->field_list,
- &lex->update_list,
&lex->value_list,
+ &lex->update_list,
+ &lex->value_list,
lex->duplicates, lex->ignore)))
{
- /*
- insert/replace from SELECT give its SELECT_LEX for SELECT,
- and item_list belong to SELECT
- */
- select_lex->resolve_mode= SELECT_LEX::SELECT_MODE;
+ /* Skip first table, which is the table we are inserting in */
+ select_lex->context.table_list= first_table->next_local;
+
res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
- select_lex->resolve_mode= SELECT_LEX::INSERT_MODE;
delete result;
}
/* revert changes for SP */
@@ -3863,7 +3866,7 @@
{
Item *it= (Item *)lex->value_list.head();
- if ((!it->fixed && it->fix_fields(lex->thd, 0, &it)) ||
it->check_cols(1))
+ if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
it->check_cols(1))
{
my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
MYF(0));
@@ -5230,16 +5233,27 @@
unit->link_prev= 0;
unit->return_to= lex->current_select;
select_lex->include_down(unit);
- /* TODO: assign resolve_mode for fake subquery after merging with new tree */
+ /*
+ By default we assume that it is usual subselect and we have outer name
+ resolution context, if no we will assign it to 0 later
+ */
+ select_lex->context.outer_context= &select_lex->outer_select()->context;
}
else
{
+ Name_resolution_context *outer_context;
if (lex->current_select->order_list.first &&
!lex->current_select->braces)
{
my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
DBUG_RETURN(1);
}
select_lex->include_neighbour(lex->current_select);
+ /*
+ we are not sure that we have one level of SELECTs above, so we take
+ outer_context address from first select of unit
+ */
+ outer_context=
+ select_lex->master_unit()->first_select()->context.outer_context;
SELECT_LEX_UNIT *unit= select_lex->master_unit();
SELECT_LEX *fake= unit->fake_select_lex;
if (!fake)
@@ -5256,13 +5270,23 @@
fake->make_empty_select();
fake->linkage= GLOBAL_OPTIONS_TYPE;
fake->select_limit= 0;
+
+ fake->context.outer_context= outer_context;
+ /* allow item list resolving in fake select for ORDER BY */
+ fake->context.resolve_in_select_list= TRUE;
+ fake->context.select_lex= fake;
}
+ select_lex->context.outer_context= outer_context;
}
select_lex->master_unit()->global_parameters= select_lex;
select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
lex->current_select= select_lex;
- select_lex->resolve_mode= SELECT_LEX::SELECT_MODE;
+ /*
+ in subquery is SELECT query and we allow resolution of names in SELECT
+ list
+ */
+ select_lex->context.resolve_in_select_list= TRUE;
DBUG_RETURN(0);
}
--- 1.324/sql/sql_select.cc Thu Jun 30 13:20:46 2005
+++ 1.325/sql/sql_select.cc Fri Jul 1 07:05:36 2005
@@ -182,8 +182,8 @@
static void reset_cache_write(JOIN_CACHE *cache);
static void read_cached_record(JOIN_TAB *tab);
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
-static bool setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
- List<Item> &all_fields,ORDER *new_order);
+static bool setup_new_fields(THD *thd, List<Item> &fields,
+ List<Item> &all_fields, ORDER *new_order);
static ORDER *create_distinct_group(THD *thd, ORDER *order,
List<Item> &fields,
bool *all_order_by_fields_used);
@@ -283,6 +283,7 @@
save_allow_sum_func= thd->allow_sum_func;
thd->allow_sum_func= 0;
res= setup_conds(thd, tables, leaves, conds);
+
thd->allow_sum_func= save_allow_sum_func;
res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
order);
@@ -339,11 +340,12 @@
/* Check that all tables, fields, conds and order are ok */
if ((!(select_options & OPTION_SETUP_TABLES_DONE) &&
- setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables,
+ setup_tables(thd, &select_lex->context,
+ tables_list, &conds, &select_lex->leaf_tables,
FALSE)) ||
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
select_lex->setup_ref_array(thd, og_num) ||
- setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
+ setup_fields(thd, (*rref_pointer_array), fields_list, 1,
&all_fields, 1) ||
setup_without_group(thd, (*rref_pointer_array), tables_list,
select_lex->leaf_tables, fields_list,
@@ -359,7 +361,7 @@
thd->allow_sum_func=1;
select_lex->having_fix_field= 1;
bool having_fix_rc= (!having->fixed &&
- (having->fix_fields(thd, tables_list, &having) ||
+ (having->fix_fields(thd, &having) ||
having->check_cols(1)));
select_lex->having_fix_field= 0;
if (having_fix_rc || thd->net.report_error)
@@ -432,7 +434,7 @@
goto err; /* purecov: inspected */
if (procedure)
{
- if (setup_new_fields(thd, tables_list, fields_list, all_fields,
+ if (setup_new_fields(thd, fields_list, all_fields,
procedure->param_fields))
goto err; /* purecov: inspected */
if (procedure->group)
@@ -566,7 +568,7 @@
Item_cond_and can't be fixed after creation, so we do not check
conds->fixed
*/
- conds->fix_fields(thd, tables_list, &conds);
+ conds->fix_fields(thd, &conds);
conds->change_ref_to_fields(thd, tables_list);
conds->top_level_item();
having= 0;
@@ -1117,7 +1119,6 @@
JOIN::reinit()
{
DBUG_ENTER("JOIN::reinit");
-
first_record= 0;
if (exec_tmp_table1)
@@ -1977,6 +1978,7 @@
bool free_join= 1;
DBUG_ENTER("mysql_select");
+ select_lex->context.resolve_in_select_list= TRUE;
JOIN *join;
if (select_lex->join != 0)
{
@@ -7445,7 +7447,7 @@
conds->top_level_item();
/* conds is always a new item as both cond and on_expr existed */
DBUG_ASSERT(!conds->fixed);
- conds->fix_fields(join->thd, 0, &conds);
+ conds->fix_fields(join->thd, &conds);
}
else
conds= table->on_expr;
@@ -7666,7 +7668,7 @@
cond->fixed, also it do not need tables so we use 0 as second
argument.
*/
- cond->fix_fields(thd, 0, &cond);
+ cond->fix_fields(thd, &cond);
}
thd->insert_id(0); // Clear for next request
}
@@ -7685,7 +7687,7 @@
cond->fixed, also it do not need tables so we use 0 as second
argument.
*/
- cond->fix_fields(thd, 0, &cond);
+ cond->fix_fields(thd, &cond);
}
}
}
@@ -8208,6 +8210,7 @@
*blob_field++= (uint) (reg_field - table->field);
blob_count++;
}
+ new_field->field_index= (uint) (reg_field - table->field);
*(reg_field++)= new_field;
if (new_field->real_type() == MYSQL_TYPE_STRING ||
new_field->real_type() == MYSQL_TYPE_VARCHAR)
@@ -8273,6 +8276,7 @@
new_field->flags|= GROUP_FLAG;
}
new_field->query_id= thd->query_id;
+ new_field->field_index= (uint) (reg_field - table->field);
*(reg_field++) =new_field;
}
if (!--hidden_field_count)
@@ -11181,8 +11185,7 @@
else // This should never happen
if (!(table->select->cond= new Item_cond_and(table->select->cond,
sort_table_cond)) ||
- table->select->cond->fix_fields(join->thd, join->tables_list,
- &table->select->cond))
+ table->select->cond->fix_fields(join->thd,
&table->select->cond))
return 1;
table->select_cond=table->select->cond;
table->select_cond->top_level_item();
@@ -11873,8 +11876,8 @@
original field name, we should additionaly check if we have conflict
for this name (in case if we would perform lookup in all tables).
*/
- if (unaliased && !order_item->fixed &&
order_item->fix_fields(thd, tables,
- order->item))
+ if (unaliased && !order_item->fixed &&
+ order_item->fix_fields(thd, order->item))
return TRUE;
/* Lookup the current GROUP field in the FROM clause. */
@@ -11941,7 +11944,7 @@
arguments for which fix_fields already was called.
*/
if (!order_item->fixed &&
- (order_item->fix_fields(thd, tables, order->item) ||
+ (order_item->fix_fields(thd, order->item) ||
(order_item= *order->item)->check_cols(1) ||
thd->is_fatal_error))
return TRUE; /* Wrong field. */
@@ -12053,7 +12056,7 @@
*/
static bool
-setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
+setup_new_fields(THD *thd, List<Item> &fields,
List<Item> &all_fields, ORDER *new_field)
{
Item **item;
@@ -12070,7 +12073,7 @@
else
{
thd->where="procedure list";
- if ((*new_field->item)->fix_fields(thd, tables, new_field->item))
+ if ((*new_field->item)->fix_fields(thd, new_field->item))
DBUG_RETURN(1); /* purecov: inspected */
all_fields.push_front(*new_field->item);
new_field->item=all_fields.head_ref();
@@ -12868,7 +12871,7 @@
DBUG_RETURN(TRUE);
if (!cond->fixed)
- cond->fix_fields(thd,(TABLE_LIST *) 0, (Item**)&cond);
+ cond->fix_fields(thd, (Item**)&cond);
if (join_tab->select)
{
error=(int) cond->add(join_tab->select->cond);
@@ -12910,8 +12913,8 @@
thd reference to the context
expr expression to make replacement
group_list list of references to group by items
- changed out: returns 1 if item contains a replaced field item
-
+ changed out: returns 1 if item contains a replaced field item
+
DESCRIPTION
The function replaces occurrences of group by fields in expr
by ref objects for these fields unless they are under aggregate
@@ -12940,6 +12943,7 @@
{
if (expr->arg_count)
{
+ Name_resolution_context *context= &thd->lex->current_select->context;
Item **arg,**arg_end;
for (arg= expr->arguments(),
arg_end= expr->arguments()+expr->arg_count;
@@ -12953,8 +12957,9 @@
{
if (item->eq(*group_tmp->item,0))
{
- Item *new_item;
- if(!(new_item= new Item_ref(group_tmp->item, 0, item->name)))
+ Item *new_item;
+ if(!(new_item= new Item_ref(context, group_tmp->item, 0,
+ item->name)))
return 1; // fatal_error is set
thd->change_item_tree(arg, new_item);
*changed= TRUE;
--- 1.254/sql/sql_show.cc Wed Jun 22 12:08:22 2005
+++ 1.255/sql/sql_show.cc Fri Jul 1 07:05:36 2005
@@ -3240,11 +3240,13 @@
int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
{
ST_FIELD_INFO *field_info= schema_table->fields_info;
+ Name_resolution_context *context= &thd->lex->select_lex.context;
for ( ; field_info->field_name; field_info++)
{
if (field_info->old_name)
{
- Item_field *field= new Item_field(NullS, NullS, field_info->field_name);
+ Item_field *field= new Item_field(context,
+ NullS, NullS, field_info->field_name);
if (field)
{
field->set_name(field_info->old_name,
@@ -3264,12 +3266,14 @@
char tmp[128];
LEX *lex= thd->lex;
SELECT_LEX *sel= lex->current_select;
+ Name_resolution_context *context= &sel->context;
if (!sel->item_list.elements)
{
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
String buffer(tmp,sizeof(tmp), system_charset_info);
- Item_field *field= new Item_field(NullS, NullS, field_info->field_name);
+ Item_field *field= new Item_field(context,
+ NullS, NullS, field_info->field_name);
if (!field || add_item_to_list(thd, field))
return 1;
buffer.length(0);
@@ -3291,6 +3295,7 @@
char tmp[128];
String buffer(tmp,sizeof(tmp), thd->charset());
LEX *lex= thd->lex;
+ Name_resolution_context *context= &lex->select_lex.context;
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
buffer.length(0);
@@ -3302,7 +3307,8 @@
buffer.append(lex->wild->ptr());
buffer.append(")");
}
- Item_field *field= new Item_field(NullS, NullS, field_info->field_name);
+ Item_field *field= new Item_field(context,
+ NullS, NullS, field_info->field_name);
if (add_item_to_list(thd, field))
return 1;
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
@@ -3310,7 +3316,7 @@
{
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
field_info= &schema_table->fields_info[3];
- field= new Item_field(NullS, NullS, field_info->field_name);
+ field= new Item_field(context, NullS, NullS, field_info->field_name);
if (add_item_to_list(thd, field))
return 1;
field->set_name(field_info->old_name, strlen(field_info->old_name),
@@ -3325,6 +3331,8 @@
int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
int *field_num= fields_arr;
ST_FIELD_INFO *field_info;
+ Name_resolution_context *context= &thd->lex->select_lex.context;
+
for (; *field_num >= 0; field_num++)
{
field_info= &schema_table->fields_info[*field_num];
@@ -3332,7 +3340,8 @@
*field_num == 17 ||
*field_num == 18))
continue;
- Item_field *field= new Item_field(NullS, NullS, field_info->field_name);
+ Item_field *field= new Item_field(context,
+ NullS, NullS, field_info->field_name);
if (field)
{
field->set_name(field_info->old_name,
@@ -3351,10 +3360,13 @@
int fields_arr[]= {0, 2, 1, 3, -1};
int *field_num= fields_arr;
ST_FIELD_INFO *field_info;
+ Name_resolution_context *context= &thd->lex->select_lex.context;
+
for (; *field_num >= 0; field_num++)
{
field_info= &schema_table->fields_info[*field_num];
- Item_field *field= new Item_field(NullS, NullS, field_info->field_name);
+ Item_field *field= new Item_field(context,
+ NullS, NullS, field_info->field_name);
if (field)
{
field->set_name(field_info->old_name,
@@ -3373,10 +3385,13 @@
int fields_arr[]= {2, 3, 4, 19, 16, 15, 14, 18, -1};
int *field_num= fields_arr;
ST_FIELD_INFO *field_info;
+ Name_resolution_context *context= &thd->lex->select_lex.context;
+
for (; *field_num >= 0; field_num++)
{
field_info= &schema_table->fields_info[*field_num];
- Item_field *field= new Item_field(NullS, NullS, field_info->field_name);
+ Item_field *field= new Item_field(context,
+ NullS, NullS, field_info->field_name);
if (field)
{
field->set_name(field_info->old_name,
@@ -3442,12 +3457,11 @@
if (table_list->field_translation)
{
- Field_translator *end= table_list->field_translation +
- sel->item_list.elements;
+ Field_translator *end= table_list->field_translation_end;
for (transl= table_list->field_translation; transl < end; transl++)
{
if (!transl->item->fixed &&
- transl->item->fix_fields(thd, table_list, &transl->item))
+ transl->item->fix_fields(thd, &transl->item))
DBUG_RETURN(1);
}
DBUG_RETURN(0);
@@ -3464,11 +3478,12 @@
{
char *name= item->name;
transl[i].item= item;
- if (!item->fixed && item->fix_fields(thd, table_list,
&transl[i].item))
+ if (!item->fixed && item->fix_fields(thd, &transl[i].item))
DBUG_RETURN(1);
transl[i++].name= name;
}
table_list->field_translation= transl;
+ table_list->field_translation_end= transl + sel->item_list.elements;
}
DBUG_RETURN(0);
@@ -3495,7 +3510,7 @@
ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
LEX_STRING db, table;
DBUG_ENTER("mysql_schema_select");
- /*
+ /*
We have to make non const db_name & table_name
because of lower_case_table_names
*/
@@ -3503,7 +3518,7 @@
information_schema_name.length, 0);
make_lex_string(thd, &table, schema_table->table_name,
strlen(schema_table->table_name), 0);
- if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
+ if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
!sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
0, 0, TL_READ, (List<String> *) 0,
(List<String> *) 0))
--- 1.12/sql/sql_udf.h Tue May 10 13:33:41 2005
+++ 1.13/sql/sql_udf.h Fri Jul 1 07:05:36 2005
@@ -65,8 +65,8 @@
Item_result result_type () const
{ return u_d ? u_d->returns : STRING_RESULT;}
bool get_arguments();
- bool fix_fields(THD *thd,struct st_table_list *tlist,Item_result_field *item,
- uint arg_count,Item **args);
+ bool fix_fields(THD *thd, Item_result_field *item,
+ uint arg_count, Item **args);
void cleanup();
double val(my_bool *null_value)
{
--- 1.160/sql/sql_update.cc Wed Jun 1 16:35:04 2005
+++ 1.161/sql/sql_update.cc Fri Jul 1 07:05:36 2005
@@ -67,6 +67,8 @@
List_iterator<Item> it(items);
Item *item;
Item_field *field;
+ Name_resolution_context *context= &thd->lex->select_lex.context;
+
while ((item= it++))
{
if (!(field= item->filed_for_view_update()))
@@ -185,14 +187,8 @@
#ifndef NO_EMBEDDED_ACCESS_CHECKS
table_list->grant.want_privilege= table->grant.want_privilege= want_privilege;
#endif
- {
- bool res;
- select_lex->no_wrap_view_item= 1;
- res= setup_fields(thd, 0, table_list, fields, 1, 0, 0);
- select_lex->no_wrap_view_item= 0;
- if (res)
- DBUG_RETURN(1); /* purecov: inspected */
- }
+ if (setup_fields_with_no_wrap(thd, 0, fields, 1, 0, 0))
+ DBUG_RETURN(1); /* purecov: inspected */
if (table_list->view && check_fields(thd, fields))
{
DBUG_RETURN(1);
@@ -216,7 +212,7 @@
table_list->grant.want_privilege= table->grant.want_privilege=
(SELECT_ACL & ~table->grant.privilege);
#endif
- if (setup_fields(thd, 0, table_list, values, 1, 0, 0))
+ if (setup_fields(thd, 0, values, 1, 0, 0))
{
free_underlaid_joins(thd, select_lex);
DBUG_RETURN(1); /* purecov: inspected */
@@ -557,7 +553,9 @@
tables.table= table;
tables.alias= table_list->alias;
- if (setup_tables(thd, table_list, conds, &select_lex->leaf_tables, FALSE) ||
+ if (setup_tables(thd, &select_lex->context,
+ table_list, conds, &select_lex->leaf_tables,
+ FALSE) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
select_lex->setup_ref_array(thd, order_num) ||
setup_order(thd, select_lex->ref_pointer_array,
@@ -617,7 +615,6 @@
TABLE_LIST *tl, *leaves;
List<Item> *fields= &lex->select_lex.item_list;
table_map tables_for_update;
- int res;
bool update_view= 0;
/*
if this multi-update was converted from usual update, here is table
@@ -642,15 +639,12 @@
call in setup_tables()).
*/
- if (setup_tables(thd, table_list, &lex->select_lex.where,
+ if (setup_tables(thd, &lex->select_lex.context,
+ table_list, &lex->select_lex.where,
&lex->select_lex.leaf_tables, FALSE))
DBUG_RETURN(TRUE);
- leaves= lex->select_lex.leaf_tables;
- if ((lex->select_lex.no_wrap_view_item= 1,
- res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
- lex->select_lex.no_wrap_view_item= 0,
- res))
+ if (setup_fields_with_no_wrap(thd, 0, *fields, 1, 0, 0))
DBUG_RETURN(TRUE);
for (tl= table_list; tl ; tl= tl->next_local)
@@ -672,6 +666,7 @@
/*
Setup timestamp handling and locking mode
*/
+ leaves= lex->select_lex.leaf_tables;
for (tl= leaves; tl; tl= tl->next_leaf)
{
TABLE *table= tl->table;
@@ -762,12 +757,10 @@
for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
tbl->cleanup_items();
- if (setup_tables(thd, table_list, &lex->select_lex.where,
+ if (setup_tables(thd, &lex->select_lex.context,
+ table_list, &lex->select_lex.where,
&lex->select_lex.leaf_tables, FALSE) ||
- (lex->select_lex.no_wrap_view_item= 1,
- res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0),
- lex->select_lex.no_wrap_view_item= 0,
- res))
+ setup_fields_with_no_wrap(thd, 0, *fields, 1, 0, 0))
DBUG_RETURN(TRUE);
}
@@ -897,7 +890,7 @@
reference tables
*/
- if (setup_fields(thd, 0, all_tables, *values, 1, 0, 0))
+ if (setup_fields(thd, 0, *values, 1, 0, 0))
DBUG_RETURN(1);
/*
--- 1.401/sql/sql_yacc.yy Thu Jun 23 00:02:41 2005
+++ 1.402/sql/sql_yacc.yy Fri Jul 1 07:05:36 2005
@@ -1259,7 +1259,6 @@
THD *thd= YYTHD;
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_CREATE_VIEW;
- lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE;
/* first table in list is target VIEW name */
if (!lex->select_lex.add_table_to_list(thd, $5, NULL, 0))
YYABORT;
@@ -3383,7 +3382,6 @@
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_CREATE_VIEW;
lex->create_view_mode= VIEW_ALTER;
- lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE;
/* first table in list is target VIEW name */
lex->select_lex.add_table_to_list(thd, $4, NULL, 0);
}
@@ -3941,7 +3939,6 @@
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SELECT;
- lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE;
}
;
@@ -4095,7 +4092,10 @@
| '*'
{
THD *thd= YYTHD;
- if (add_item_to_list(thd, new Item_field(NULL, NULL, "*")))
+ if (add_item_to_list(thd,
+ new Item_field(&thd->lex->current_select->
+ context,
+ NULL, NULL, "*")))
YYABORT;
(thd->lex->current_select->with_wild)++;
};
@@ -4393,10 +4393,10 @@
my_error(ER_WRONG_COLUMN_NAME, MYF(0), name->str);
YYABORT;
}
- $$= new Item_default_value($3);
+ $$= new Item_default_value(&Select->context, $3);
}
| VALUES '(' simple_ident ')'
- { $$= new Item_insert_value($3); }
+ { $$= new Item_insert_value(&Select->context, $3); }
| FUNC_ARG0 '(' ')'
{
if (!$1.symbol->create_func)
@@ -4687,15 +4687,16 @@
name->init_qname(YYTHD);
sp_add_to_hash(&lex->spfuns, name);
if ($5)
- $$= new Item_func_sp(name, *$5);
+ $$= new Item_func_sp(&lex->current_select->context, name, *$5);
else
- $$= new Item_func_sp(name);
+ $$= new Item_func_sp(&lex->current_select->context, name);
lex->safe_to_cache_query=0;
}
| IDENT_sys '(' udf_expr_list ')'
{
#ifdef HAVE_DLOPEN
udf_func *udf;
+ SELECT_LEX *sel= Select;
if (using_udf_functions && (udf=find_udf($1.str, $1.length)))
{
@@ -4776,9 +4777,9 @@
sp_add_to_hash(&lex->spfuns, name);
if ($3)
- $$= new Item_func_sp(name, *$3);
+ $$= new Item_func_sp(&lex->current_select->context, name, *$3);
else
- $$= new Item_func_sp(name);
+ $$= new Item_func_sp(&lex->current_select->context, name);
lex->safe_to_cache_query=0;
}
}
@@ -4980,8 +4981,10 @@
opt_gconcat_separator
')'
{
- Select->in_sum_expr--;
- $$=new Item_func_group_concat($3,$5,Select->gorder_list,$7);
+ SELECT_LEX *sel= Select;
+ sel->in_sum_expr--;
+ $$=new Item_func_group_concat(&sel->context, $3, $5,
+ sel->gorder_list, $7);
$5->empty();
};
@@ -5400,16 +5403,30 @@
ident
{
SELECT_LEX *sel= Select;
- if (!($$= new Item_func_eq(new Item_field(sel->db1, sel->table1,
+ if (!($$= new Item_func_eq(new Item_field(&sel->context,
+ sel->db1, sel->table1,
$1.str),
- new Item_field(sel->db2, sel->table2,
+ new Item_field(&sel->context,
+ sel->db2, sel->table2,
$1.str))))
YYABORT;
}
| using_list ',' ident
{
SELECT_LEX *sel= Select;
- if (!($$= new Item_cond_and(new Item_func_eq(new
Item_field(sel->db1,sel->table1,$3.str), new
Item_field(sel->db2,sel->table2,$3.str)), $1)))
+ if (!($$=
+ new Item_cond_and(new
+ Item_func_eq(new
+ Item_field(&sel->context,
+ sel->db1,
+ sel->table1,
+ $3.str),
+ new
+ Item_field(&sel->context,
+ sel->db2,
+ sel->table2,
+ $3.str)),
+ $1)))
YYABORT;
};
@@ -5675,7 +5692,10 @@
lex->proc_list.elements=0;
lex->proc_list.first=0;
lex->proc_list.next= (byte**) &lex->proc_list.first;
- if (add_proc_to_list(lex->thd, new Item_field(NULL,NULL,$2.str)))
+ if (add_proc_to_list(lex->thd, new Item_field(&lex->
+ current_select->
+ context,
+ NULL,NULL,$2.str)))
YYABORT;
Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
}
@@ -5922,7 +5942,6 @@
mysql_init_select(lex);
/* for subselects */
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
- lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
} insert_lock_option
opt_ignore insert2
{
@@ -5940,7 +5959,6 @@
lex->sql_command = SQLCOM_REPLACE;
lex->duplicates= DUP_REPLACE;
mysql_init_select(lex);
- lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
}
replace_lock_option insert2
{
@@ -6058,7 +6076,7 @@
expr_or_default:
expr { $$= $1;}
- | DEFAULT {$$= new Item_default_value(); }
+ | DEFAULT {$$= new Item_default_value(&Select->context); }
;
opt_insert_update:
@@ -7027,15 +7045,17 @@
table_wild:
ident '.' '*'
{
- $$ = new Item_field(NullS,$1.str,"*");
- Lex->current_select->with_wild++;
+ SELECT_LEX *sel= Select;
+ $$ = new Item_field(&sel->context, NullS, $1.str, "*");
+ sel->with_wild++;
}
| ident '.' ident '.' '*'
{
- $$ = new Item_field((YYTHD->client_capabilities &
+ SELECT_LEX *sel= Select;
+ $$ = new Item_field(&sel->context, (YYTHD->client_capabilities &
CLIENT_NO_SCHEMA ? NullS : $1.str),
$3.str,"*");
- Lex->current_select->with_wild++;
+ sel->with_wild++;
}
;
@@ -7060,8 +7080,8 @@
SELECT_LEX *sel=Select;
$$= (sel->parsing_place != IN_HAVING ||
sel->get_in_sum_expr() > 0) ?
- (Item*) new Item_field(NullS,NullS,$1.str) :
- (Item*) new Item_ref(NullS,NullS,$1.str);
+ (Item*) new Item_field(&sel->context, NullS, NullS, $1.str) :
+ (Item*) new Item_ref(&sel->context, NullS, NullS, $1.str);
}
}
| simple_ident_q { $$= $1; }
@@ -7073,8 +7093,8 @@
SELECT_LEX *sel=Select;
$$= (sel->parsing_place != IN_HAVING ||
sel->get_in_sum_expr() > 0) ?
- (Item*) new Item_field(NullS,NullS,$1.str) :
- (Item*) new Item_ref(NullS,NullS,$1.str);
+ (Item*) new Item_field(&sel->context, NullS, NullS, $1.str) :
+ (Item*) new Item_ref(&sel->context, NullS, NullS, $1.str);
}
| simple_ident_q { $$= $1; }
;
@@ -7111,7 +7131,8 @@
YYABORT;
}
- if (!(trg_fld= new Item_trigger_field(new_row ?
+ if (!(trg_fld= new
Item_trigger_field(&lex->current_select->context,
+ new_row ?
Item_trigger_field::NEW_ROW:
Item_trigger_field::OLD_ROW,
$3.str)))
@@ -7136,8 +7157,8 @@
}
$$= (sel->parsing_place != IN_HAVING ||
sel->get_in_sum_expr() > 0) ?
- (Item*) new Item_field(NullS,$1.str,$3.str) :
- (Item*) new Item_ref(NullS,$1.str,$3.str);
+ (Item*) new Item_field(&sel->context, NullS, $1.str, $3.str) :
+ (Item*) new Item_ref(&sel->context, NullS, $1.str, $3.str);
}
}
| '.' ident '.' ident
@@ -7152,8 +7173,8 @@
}
$$= (sel->parsing_place != IN_HAVING ||
sel->get_in_sum_expr() > 0) ?
- (Item*) new Item_field(NullS,$2.str,$4.str) :
- (Item*) new Item_ref(NullS, $2.str, $4.str);
+ (Item*) new Item_field(&sel->context, NullS, $2.str, $4.str) :
+ (Item*) new Item_ref(&sel->context, NullS, $2.str, $4.str);
}
| ident '.' ident '.' ident
{
@@ -7167,10 +7188,12 @@
}
$$= (sel->parsing_place != IN_HAVING ||
sel->get_in_sum_expr() > 0) ?
- (Item*) new Item_field((YYTHD->client_capabilities &
+ (Item*) new Item_field(&sel->context,
+ (YYTHD->client_capabilities &
CLIENT_NO_SCHEMA ? NullS : $1.str),
$3.str, $5.str) :
- (Item*) new Item_ref((YYTHD->client_capabilities &
+ (Item*) new Item_ref(&sel->context,
+ (YYTHD->client_capabilities &
CLIENT_NO_SCHEMA ? NullS : $1.str),
$3.str, $5.str);
};
@@ -7720,9 +7743,11 @@
it= new Item_null();
}
- if (!(trg_fld= new Item_trigger_field(Item_trigger_field::NEW_ROW,
+ if (!(trg_fld= new
Item_trigger_field(&lex->current_select->context,
+ Item_trigger_field::NEW_ROW,
$2.base_name.str)) ||
!(i= new sp_instr_set_trigger_field(
+ &lex->current_select->context,
lex->sphead->instructions(), lex->spcont,
trg_fld, it)))
YYABORT;
--- 1.172/sql/table.cc Wed Jun 22 12:08:22 2005
+++ 1.173/sql/table.cc Fri Jul 1 07:05:37 2005
@@ -594,6 +594,7 @@
goto err; /* purecov: inspected */
}
+ reg_field->field_index= i;
reg_field->comment=comment;
if (field_type == FIELD_TYPE_BIT && !f_bit_as_char(pack_flag))
{
@@ -1713,8 +1714,6 @@
}
if (tbl->multitable_view)
multitable_view= TRUE;
- if (tbl->table)
- tbl->table->grant= grant;
} while ((tbl= tbl->next_local));
if (!multitable_view)
@@ -1727,232 +1726,133 @@
/*
- Save old want_privilege and clear want_privilege
+ setup fields of placeholder of merged VIEW
SYNOPSIS
- save_and_clear_want_privilege()
+ st_table_list::setup_ancestor()
+ thd - thread handler
+
+ NOTES
+ ancestor is list of tables and views used by view (underlying tables/views)
+
+ DESCRIPTION
+ It is:
+ - preparing translation table for view columns
+ If there are underlying view(s) procedure first will be called for them.
+
+ RETURN
+ FALSE - OK
+ TRUE - error
*/
-void st_table_list::save_and_clear_want_privilege()
+bool st_table_list::setup_ancestor(THD *thd)
{
- for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
+ DBUG_ENTER("st_table_list::setup_ancestor");
+ if (!field_translation)
{
- if (tbl->table)
+ Field_translator *transl;
+ SELECT_LEX *select= &view->select_lex;
+ Item *item;
+ TABLE_LIST *tbl;
+ List_iterator_fast<Item> it(select->item_list);
+ uint field_count= 0;
+
+ if (check_stack_overrun(thd, STACK_MIN_SIZE, (char *)&field_count))
{
- privilege_backup= tbl->table->grant.want_privilege;
- tbl->table->grant.want_privilege= 0;
+ DBUG_RETURN(TRUE);
}
- else
+
+ for (tbl= ancestor; tbl; tbl= tbl->next_local)
{
- tbl->save_and_clear_want_privilege();
+ if (tbl->ancestor &&
+ tbl->setup_ancestor(thd))
+ {
+ DBUG_RETURN(TRUE);
+ }
}
- }
-}
+ /* Create view fields translation table */
-/*
- restore want_privilege saved by save_and_clear_want_privilege
+ if (!(transl=
+ (Field_translator*)(thd->current_arena->
+ alloc(select->item_list.elements *
+ sizeof(Field_translator)))))
+ {
+ DBUG_RETURN(TRUE);
+ }
- SYNOPSIS
- restore_want_privilege()
-*/
+ while ((item= it++))
+ {
+ transl[field_count].name= item->name;
+ transl[field_count++].item= item;
+ }
+ field_translation= transl;
+ field_translation_end= transl + field_count;
+ /* TODO: use hash for big number of fields */
-void st_table_list::restore_want_privilege()
-{
- for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
- {
- if (tbl->table)
- tbl->table->grant.want_privilege= privilege_backup;
- else
+ /* full text function moving to current select */
+ if (view->select_lex.ftfunc_list->elements)
{
- tbl->restore_want_privilege();
+ Item_func_match *ifm;
+ SELECT_LEX *current_select= thd->lex->current_select;
+ List_iterator_fast<Item_func_match>
+ li(*(view->select_lex.ftfunc_list));
+ while ((ifm= li++))
+ current_select->ftfunc_list->push_front(ifm);
}
}
+ DBUG_RETURN(FALSE);
}
/*
- setup fields of placeholder of merged VIEW
+ Prepare where expression of view
SYNOPSIS
- st_table_list::setup_ancestor()
- thd - thread handler
+ st_table_list::prep_where()
+ thd - thread handler
conds - condition of this JOIN
- check_opt_type - WHITH CHECK OPTION type (VIEW_CHECK_NONE,
- VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
- NOTES
- ancestor is list of tables and views used by view (underlying tables/views)
+ no_where_clause - do not build WHERE or ON outer qwery do not need it
+ (it is INSERT), we do not need conds if this flag is set
- DESCRIPTION
- It is:
- - preparing translation table for view columns (fix_fields() for every
- call and creation for first call)
- - preparing WHERE, ON and CHECK OPTION condition (fix_fields() for every
- call and merging for first call).
- If there are underlying view(s) procedure first will be called for them.
+ NOTE: have to be called befor CHECK OPTION preparation, because it makes
+ fix_fields for view WHERE clause
RETURN
FALSE - OK
TRUE - error
*/
-bool st_table_list::setup_ancestor(THD *thd, Item **conds,
- uint8 check_opt_type)
+bool st_table_list::prep_where(THD *thd, Item **conds,
+ bool no_where_clause)
{
- Field_translator *transl;
- SELECT_LEX *select= &view->select_lex;
- SELECT_LEX *current_select_save= thd->lex->current_select;
- byte *main_table_list_save= select_lex->table_list.first;
- Item *item;
- TABLE_LIST *tbl;
- List_iterator_fast<Item> it(select->item_list);
- uint i= 0;
- enum sub_select_type linkage_save=
- select_lex->master_unit()->first_select()->linkage;
- bool save_set_query_id= thd->set_query_id;
- bool save_wrapper= select_lex->no_wrap_view_item;
- bool save_allow_sum_func= thd->allow_sum_func;
- bool res= FALSE;
- DBUG_ENTER("st_table_list::setup_ancestor");
+ DBUG_ENTER("st_table_list::prep_where");
- if (check_stack_overrun(thd, STACK_MIN_SIZE, (char *)&res))
- return TRUE;
-
- for (tbl= ancestor; tbl; tbl= tbl->next_local)
+ for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
{
- if (tbl->ancestor &&
- tbl->setup_ancestor(thd, conds,
- (check_opt_type == VIEW_CHECK_CASCADED ?
- VIEW_CHECK_CASCADED :
- VIEW_CHECK_NONE)))
- DBUG_RETURN(TRUE);
- }
-
- /*
- We have to ensure that inside the view we are not referring to any
- table outside of the view. We do it by changing the pointers used
- by fix_fields to look up tables so that only tables and views in
- view are seen. We also set linkage to DERIVED_TABLE_TYPE as a barrier
- so that we stop resolving fields as this level.
- */
- thd->lex->current_select= select_lex;
- select_lex->table_list.first= (byte *)ancestor;
- select_lex->master_unit()->first_select()->linkage= DERIVED_TABLE_TYPE;
-
- if (field_translation)
- {
- DBUG_PRINT("info", ("there are already translation table"));
-
- select_lex->no_wrap_view_item= 1;
-
- thd->set_query_id= 1;
- /* this view was prepared already on previous PS/SP execution */
- Field_translator *end= field_translation + select->item_list.elements;
- /* real rights will be checked in VIEW field */
- save_and_clear_want_privilege();
- /* aggregate function are allowed */
- thd->allow_sum_func= 1;
- for (transl= field_translation; transl < end; transl++)
- {
- if (!transl->item->fixed &&
- transl->item->fix_fields(thd, ancestor, &transl->item))
- goto err;
- }
- for (tbl= ancestor; tbl; tbl= tbl->next_local)
+ if (tbl->view && tbl->prep_where(thd, conds, no_where_clause))
{
- if (tbl->on_expr && !tbl->on_expr->fixed &&
- tbl->on_expr->fix_fields(thd, ancestor, &tbl->on_expr))
- goto err;
- }
- if (where && !where->fixed && where->fix_fields(thd, ancestor,
&where))
- goto err;
- if (check_option && !check_option->fixed &&
- check_option->fix_fields(thd, ancestor, &check_option))
- goto err;
- restore_want_privilege();
-
- /* WHERE/ON resolved => we can rename fields */
- for (transl= field_translation; transl < end; transl++)
- {
- transl->item->rename((char *)transl->name);
+ DBUG_RETURN(TRUE);
}
- goto ok;
- }
-
- /* Create view fields translation table */
-
- if (!(transl=
- (Field_translator*)(thd->current_arena->
- alloc(select->item_list.elements *
- sizeof(Field_translator)))))
- {
- res= TRUE;
- goto ok; // Restore thd
- }
-
- select_lex->no_wrap_view_item= 1;
-
- /*
- Resolve all view items against ancestor table.
-
- TODO: do it only for real used fields "on demand" to mark really
- used fields correctly.
- */
- thd->set_query_id= 1;
- /* real rights will be checked in VIEW field */
- save_and_clear_want_privilege();
- /* aggregate function are allowed */
- thd->allow_sum_func= 1;
- while ((item= it++))
- {
- /* save original name of view column */
- char *name= item->name;
- transl[i].item= item;
- if (!item->fixed && item->fix_fields(thd, ancestor,
&transl[i].item))
- goto err;
- /* set new item get in fix fields and original column name */
- transl[i++].name= name;
}
- field_translation= transl;
- /* TODO: sort this list? Use hash for big number of fields */
- for (tbl= ancestor; tbl; tbl= tbl->next_local)
+ if (where)
{
- if (tbl->on_expr && !tbl->on_expr->fixed &&
- tbl->on_expr->fix_fields(thd, ancestor, &tbl->on_expr))
- goto err;
- }
- if (where ||
- (check_opt_type == VIEW_CHECK_CASCADED &&
- ancestor->check_option))
- {
- Query_arena *arena= thd->current_arena, backup;
- TABLE_LIST *tbl= this;
- if (arena->is_conventional())
- arena= 0; // For easier test
-
- if (where && !where->fixed && where->fix_fields(thd, ancestor,
&where))
- goto err;
-
- if (arena)
- thd->set_n_backup_item_arena(arena, &backup);
-
- if (check_opt_type)
+ if (!where->fixed && where->fix_fields(thd, &where))
{
- if (where)
- check_option= where->copy_andor_structure(thd);
- if (check_opt_type == VIEW_CHECK_CASCADED)
- {
- check_option= and_conds(check_option, ancestor->check_option);
- }
+ DBUG_RETURN(TRUE);
}
/*
check that it is not VIEW in which we insert with INSERT SELECT
(in this case we can't add view WHERE condition to main SELECT_LEX)
*/
- if (where && !no_where_clause)
+ if (!no_where_clause && !where_processed)
{
+ TABLE_LIST *tbl= this;
+ Query_arena *arena= thd->current_arena, backup;
+ arena= thd->change_arena_if_needed(&backup); // For easier test
+
/* Go up to join tree and try to find left join */
for (; tbl; tbl= tbl->embedding)
{
@@ -1969,72 +1869,107 @@
}
}
if (tbl == 0)
- {
- if (outer_join)
- {
- /*
- Store WHERE condition to ON expression for outer join, because
- we can't use WHERE to correctly execute left joins on VIEWs and
- this expression will not be moved to WHERE condition (i.e. will
- be clean correctly for PS/SP)
- */
- on_expr= and_conds(on_expr, where);
- }
- else
- {
- /*
- It is conds of JOIN, but it will be stored in
- st_select_lex::prep_where for next reexecution
- */
- *conds= and_conds(*conds, where);
- }
- }
+ *conds= and_conds(*conds, where);
+ if (arena)
+ thd->restore_backup_item_arena(arena, &backup);
+ where_processed= TRUE;
}
-
- if (arena)
- thd->restore_backup_item_arena(arena, &backup);
}
- restore_want_privilege();
- /*
- fix_fields do not need tables, because new are only AND operation and we
- just need recollect statistics
- */
- if (check_option && !check_option->fixed &&
- check_option->fix_fields(thd, 0, &check_option))
- goto err;
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
+ Prepare check option expression of table
+
+ SYNOPSIS
+ st_table_list::prep_check_option()
+ thd - thread handler
+ check_opt_type - WITH CHECK OPTION type (VIEW_CHECK_NONE,
+ VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
+ we use this parameter instead of direct check of
+ effective_with_check to change type of underlying
+ views to VIEW_CHECK_CASCADED if outer view have
+ such option and prevent processing of underlying
+ view check options if outer view have just
+ VIEW_CHECK_LOCAL option.
+
+ NOTE
+ This method build check options for every call
+ (usual execution or every SP/PS call)
+ This method have to be called after WHERE preparation
+ (st_table_list::prep_where)
+
+ RETURN
+ FALSE - OK
+ TRUE - error
+*/
+
+bool st_table_list::prep_check_option(THD *thd, uint8 check_opt_type)
+{
+ DBUG_ENTER("st_table_list::prep_check_option");
- /* WHERE/ON resolved => we can rename fields */
+ for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
{
- Field_translator *end= field_translation + select->item_list.elements;
- for (transl= field_translation; transl < end; transl++)
+ /* see comment of check_opt_type parameter */
+ if (tbl->view &&
+ tbl->prep_check_option(thd,
+ ((check_opt_type == VIEW_CHECK_CASCADED) ?
+ VIEW_CHECK_CASCADED :
+ VIEW_CHECK_NONE)))
{
- transl->item->rename((char *)transl->name);
+ DBUG_RETURN(TRUE);
}
}
- /* full text function moving to current select */
- if (view->select_lex.ftfunc_list->elements)
+ if (check_opt_type)
{
- Query_arena *arena= thd->current_arena, backup;
- if (arena->is_conventional())
- arena= 0; // For easier test
- else
- thd->set_n_backup_item_arena(arena, &backup);
+ Item *item= 0;
+ if (where)
+ {
+ DBUG_ASSERT(where->fixed);
+ item= where->copy_andor_structure(thd);
+ }
+ if (check_opt_type == VIEW_CHECK_CASCADED)
+ {
+ for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
+ {
+ if (tbl->check_option)
+ item= and_conds(item, tbl->check_option);
+ }
+ }
+ if (item)
+ thd->change_item_tree(&check_option, item);
+ }
- Item_func_match *ifm;
- List_iterator_fast<Item_func_match>
- li(*(view->select_lex.ftfunc_list));
- while ((ifm= li++))
- current_select_save->ftfunc_list->push_front(ifm);
- if (arena)
- thd->restore_backup_item_arena(arena, &backup);
+ if (check_option)
+ {
+ const char *save_where= thd->where;
+ thd->where= "check option";
+ if (!check_option->fixed &&
+ check_option->fix_fields(thd, &check_option) ||
+ check_option->check_cols(1))
+ {
+ DBUG_RETURN(TRUE);
+ }
+ thd->where= save_where;
}
+ DBUG_RETURN(FALSE);
+}
- goto ok;
-err:
- res= TRUE;
+/*
+ Hide errors which show view underlying table information
+
+ SYNOPSIS
+ st_table_list::hide_view_error()
+ thd thread handler
+
+*/
+
+void st_table_list::hide_view_error(THD *thd)
+{
/* Hide "Unknown column" or "Unknown function" error */
if (thd->net.last_errno == ER_BAD_FIELD_ERROR ||
thd->net.last_errno == ER_SP_DOES_NOT_EXIST)
@@ -2042,15 +1977,12 @@
thd->clear_error();
my_error(ER_VIEW_INVALID, MYF(0), view_db.str, view_name.str);
}
-
-ok:
- select_lex->no_wrap_view_item= save_wrapper;
- thd->lex->current_select= current_select_save;
- select_lex->table_list.first= main_table_list_save;
- select_lex->master_unit()->first_select()->linkage= linkage_save;
- thd->set_query_id= save_set_query_id;
- thd->allow_sum_func= save_allow_sum_func;
- DBUG_RETURN(res);
+ else if (thd->net.last_errno == ER_NO_DEFAULT_FOR_FIELD)
+ {
+ thd->clear_error();
+ // TODO: make correct error message
+ my_error(ER_NO_DEFAULT_FOR_VIEW_FIELD, MYF(0), view_db.str, view_name.str);
+ }
}
@@ -2094,9 +2026,9 @@
if (!field_translation)
return;
- Field_translator *end= (field_translation +
- view->select_lex.item_list.elements);
- for (Field_translator *transl= field_translation; transl < end; transl++)
+ for (Field_translator *transl= field_translation;
+ transl < field_translation_end;
+ transl++)
transl->item->walk(&Item::cleanup_processor, 0);
}
@@ -2209,8 +2141,9 @@
void Field_iterator_view::set(TABLE_LIST *table)
{
+ view= table;
ptr= table->field_translation;
- array_end= ptr + table->view->select_lex.item_list.elements;
+ array_end= table->field_translation_end;
}
@@ -2220,15 +2153,60 @@
}
-Item *Field_iterator_table::item(THD *thd)
+Item *Field_iterator_table::create_item(THD *thd)
{
- return new Item_field(thd, *ptr);
+ return new Item_field(thd, &thd->lex->current_select->context, *ptr);
}
const char *Field_iterator_view::name()
{
return ptr->name;
+}
+
+
+Item *Field_iterator_view::create_item(THD *thd)
+{
+ return create_view_field(thd, view, &ptr->item, ptr->name);
+}
+
+Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
+ const char *name)
+{
+ bool save_wrapper= thd->lex->select_lex.no_wrap_view_item;
+ Item *field= *field_ref;
+ DBUG_ENTER("create_view_field");
+
+ if (view->schema_table_reformed)
+ {
+ /*
+ In case of SHOW command (schema_table_reformed set) all items are
+ fixed
+ */
+ DBUG_ASSERT(field && field->fixed);
+ DBUG_RETURN(field);
+ }
+
+ DBUG_ASSERT(field);
+ thd->lex->current_select->no_wrap_view_item= TRUE;
+ if (!field->fixed)
+ {
+ if (field->fix_fields(thd, field_ref))
+ {
+ thd->lex->current_select->no_wrap_view_item= save_wrapper;
+ DBUG_RETURN(0);
+ }
+ field= *field_ref;
+ }
+ thd->lex->current_select->no_wrap_view_item= save_wrapper;
+ if (thd->lex->current_select->no_wrap_view_item)
+ {
+ DBUG_RETURN(field);
+ }
+ Item *item= new Item_direct_view_ref(&view->view->select_lex.context,
+ field_ref, view->view_name.str,
+ name);
+ DBUG_RETURN(item);
}
--- 1.100/sql/table.h Wed Jun 1 16:35:04 2005
+++ 1.101/sql/table.h Fri Jul 1 07:05:37 2005
@@ -314,9 +314,9 @@
#define JOIN_TYPE_LEFT 1
#define JOIN_TYPE_RIGHT 2
-#define VIEW_ALGORITHM_UNDEFINED 0
-#define VIEW_ALGORITHM_TMPTABLE 1
-#define VIEW_ALGORITHM_MERGE 2
+#define VIEW_ALGORITHM_UNDEFINED 0
+#define VIEW_ALGORITHM_TMPTABLE 1
+#define VIEW_ALGORITHM_MERGE 2
/* view WITH CHECK OPTION parameter options */
#define VIEW_CHECK_NONE 0
@@ -329,9 +329,13 @@
#define VIEW_CHECK_SKIP 2
struct st_lex;
+struct st_table_list;
class select_union;
class TMP_TABLE_PARAM;
+Item *create_view_field(THD *thd, st_table_list *view, Item **field_ref,
+ const char *name);
+
struct Field_translator
{
Item *item;
@@ -384,6 +388,8 @@
st_select_lex *select_lex;
st_lex *view; /* link on VIEW lex for merging */
Field_translator *field_translation; /* array of VIEW fields */
+ /* pointer to element after last one in translation table above */
+ Field_translator *field_translation_end;
/* list of ancestor(s) of this table (underlying table(s)/view(s) */
st_table_list *ancestor;
/* most upper view this table belongs to */
@@ -408,8 +414,7 @@
algorithm)
*/
uint8 effective_with_check;
- uint effective_algorithm; /* which algorithm was really used */
- uint privilege_backup; /* place for saving privileges */
+ uint8 effective_algorithm; /* which algorithm was really used */
GRANT_INFO grant;
/* data need by some engines in query cache*/
ulonglong engine_data;
@@ -424,7 +429,6 @@
bool updating; /* for replicate-do/ignore table */
bool force_index; /* prefer index over table scan */
bool ignore_leaves; /* preload only non-leaf nodes */
- bool no_where_clause; /* do not attach WHERE to SELECT */
table_map dep_tables; /* tables the table depends on */
table_map on_expr_dep_tables; /* tables on expression depends on */
struct st_nested_join *nested_join; /* if the element is a nested join */
@@ -437,6 +441,8 @@
/* TRUE if this merged view contain auto_increment field */
bool contain_auto_increment;
bool multitable_view; /* TRUE iff this is multitable view */
+ /* view where processed */
+ bool where_processed;
/* FRMTYPE_ERROR if any type is acceptable */
enum frm_type_enum required_type;
char timestamp_buffer[20]; /* buffer for timestamp (19+1) */
@@ -449,16 +455,32 @@
void calc_md5(char *buffer);
void set_ancestor();
int view_check_option(THD *thd, bool ignore_failure);
- bool setup_ancestor(THD *thd, Item **conds, uint8 check_option);
+ bool setup_ancestor(THD *thd);
void cleanup_items();
bool placeholder() {return derived || view; }
void print(THD *thd, String *str);
- void save_and_clear_want_privilege();
- void restore_want_privilege();
bool check_single_table(st_table_list **table, table_map map,
st_table_list *view);
bool set_insert_values(MEM_ROOT *mem_root);
+ void hide_view_error(THD *thd);
st_table_list *find_underlying_table(TABLE *table);
+ inline bool prepare_check_option(THD *thd)
+ {
+ bool res= FALSE;
+ if (effective_with_check)
+ res= prep_check_option(thd, effective_with_check);
+ return res;
+ }
+ inline bool prepare_where(THD *thd, Item **conds,
+ bool no_where_clause)
+ {
+ if (effective_algorithm == VIEW_ALGORITHM_MERGE)
+ return prep_where(thd, conds, no_where_clause);
+ return FALSE;
+ }
+private:
+ bool prep_check_option(THD *thd, uint8 check_opt_type);
+ bool prep_where(THD *thd, Item **conds, bool no_where_clause);
} TABLE_LIST;
class Item;
@@ -471,7 +493,7 @@
virtual void next()= 0;
virtual bool end_of_fields()= 0; /* Return 1 at end of list */
virtual const char *name()= 0;
- virtual Item *item(THD *)= 0;
+ virtual Item *create_item(THD *)= 0;
virtual Field *field()= 0;
};
@@ -486,7 +508,7 @@
void next() { ptr++; }
bool end_of_fields() { return *ptr == 0; }
const char *name();
- Item *item(THD *thd);
+ Item *create_item(THD *thd);
Field *field() { return *ptr; }
};
@@ -494,15 +516,18 @@
class Field_iterator_view: public Field_iterator
{
Field_translator *ptr, *array_end;
+ TABLE_LIST *view;
public:
Field_iterator_view() :ptr(0), array_end(0) {}
void set(TABLE_LIST *table);
void next() { ptr++; }
bool end_of_fields() { return ptr == array_end; }
const char *name();
- Item *item(THD *thd) { return ptr->item; }
+ Item *create_item(THD *thd);
Item **item_ptr() {return &ptr->item; }
Field *field() { return 0; }
+
+ inline Item *item() { return ptr->item; }
};
--- 1.72/sql/sql_derived.cc Tue Jun 7 13:11:28 2005
+++ 1.73/sql/sql_derived.cc Fri Jul 1 07:05:35 2005
@@ -114,6 +114,10 @@
bool is_union= first_select->next_select() &&
first_select->next_select()->linkage == UNION_TYPE;
+ /* prevent name resolving out of derived table */
+ for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select())
+ sl->context.outer_context= 0;
+
if (!(derived_result= new select_union(0)))
DBUG_RETURN(1); // out of memory
--- 1.20/sql/sql_olap.cc Mon Jun 6 21:21:27 2005
+++ 1.21/sql/sql_olap.cc Fri Jul 1 07:05:36 2005
@@ -77,7 +77,8 @@
{
not_found= 0;
((Item_field*)new_item)->db_name=iif->db_name;
- Item_field *new_one=new Item_field(iif->db_name, iif->table_name,
iif->field_name);
+ Item_field *new_one=new Item_field(&select_lex->context,
+ iif->db_name, iif->table_name,
iif->field_name);
privlist.push_back(new_one);
if (add_to_list(new_select->group_list,new_one,1))
return 1;
@@ -152,12 +153,11 @@
List<Item> all_fields(select_lex->item_list);
- if (setup_tables(lex->thd, (TABLE_LIST *)select_lex->table_list.first
+ if (setup_tables(lex->thd, &select_lex->context,
+ (TABLE_LIST *)select_lex->table_list.first
&select_lex->where, &select_lex->leaf_tables, FALSE) ||
- setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
- select_lex->item_list, 1, &all_fields,1) ||
- setup_fields(lex->thd, 0, (TABLE_LIST *)select_lex->table_list.first,
- item_list_copy, 1, &all_fields, 1))
+ setup_fields(lex->thd, 0, select_lex->item_list, 1, &all_fields,1) ||
+ setup_fields(lex->thd, 0, item_list_copy, 1, &all_fields, 1))
return -1;
if (select_lex->olap == CUBE_TYPE)
--- 1.122/sql/sql_union.cc Wed Jun 29 11:49:35 2005
+++ 1.123/sql/sql_union.cc Fri Jul 1 07:05:36 2005
@@ -124,6 +124,13 @@
fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
(byte **)
&result_table_list.next_local);
+ for (ORDER *order= (ORDER *)global_parameters->order_list.first;
+ order;
+ order=order->next)
+ {
+ (*order->item)->walk(&Item::change_context_processor,
+ (byte *) &fake_select_lex->context);
+ }
}
@@ -186,6 +193,8 @@
}
else
tmp_result= sel_result;
+
+ sl->context.resolve_in_select_list= TRUE;
for (;sl; sl= sl->next_select())
{
--- 1.35/sql/share/errmsg.txt Mon Jun 27 14:12:09 2005
+++ 1.36/sql/share/errmsg.txt Fri Jul 1 07:05:35 2005
@@ -5358,3 +5358,5 @@
eng "The statement (%lu) has no open cursor."
ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
eng "Explicit or implicit commit is not allowed in stored function or trigger."
+ER_NO_DEFAULT_FOR_VIEW_FIELD
+ eng "Field of view '%-.64s.%-.64s' underlying table doesn't have a default value"
--- 1.87/mysql-test/r/view.result Fri Jun 24 20:47:16 2005
+++ 1.88/mysql-test/r/view.result Fri Jul 1 07:05:34 2005
@@ -754,6 +754,8 @@
create view v2 as select * from t2;
insert into v1 values (1);
insert into v2 values (1);
+Warnings:
+Warning 1423 Field of view 'test.v2' underlying table doesn't have a default value
create view v3 (a,b) as select v1.col1 as a, v2.col1 as b from v1, v2 where v1.col1 =
v2.col1;
select * from v3;
a b
@@ -1850,3 +1852,16 @@
SUBSTRING_INDEX("dkjhgd:kjhdjh", ":", 1)
dkjhgd
drop view v1;
+set sql_mode='strict_all_tables';
+CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL) ENGINE = INNODB;
+CREATE VIEW v1 (vcol1) AS SELECT col1 FROM t1;
+CREATE VIEW v2 (vcol1) AS SELECT col1 FROM t1 WHERE col2 > 2;
+INSERT INTO t1 (col1) VALUES(12);
+ERROR HY000: Field 'col2' doesn't have a default value
+INSERT INTO v1 (vcol1) VALUES(12);
+ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default value
+INSERT INTO v2 (vcol1) VALUES(12);
+ERROR HY000: Field of view 'test.v2' underlying table doesn't have a default value
+set sql_mode=default;
+drop view v2,v1;
+drop table t1;
--- 1.75/mysql-test/t/view.test Fri Jun 24 20:47:16 2005
+++ 1.76/mysql-test/t/view.test Fri Jul 1 07:05:34 2005
@@ -1696,3 +1696,21 @@
CREATE VIEW v1 AS SELECT SUBSTRING_INDEX("dkjhgd:kjhdjh", ":", 1);
SELECT * FROM v1;
drop view v1;
+
+#
+# Correct inserting data check (absence of default value) for view
+# underlying tables (BUG#6443)
+#
+set sql_mode='strict_all_tables';
+CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL) ENGINE = INNODB;
+CREATE VIEW v1 (vcol1) AS SELECT col1 FROM t1;
+CREATE VIEW v2 (vcol1) AS SELECT col1 FROM t1 WHERE col2 > 2;
+-- error 1364
+INSERT INTO t1 (col1) VALUES(12);
+-- error 1423
+INSERT INTO v1 (vcol1) VALUES(12);
+-- error 1423
+INSERT INTO v2 (vcol1) VALUES(12);
+set sql_mode=default;
+drop view v2,v1;
+drop table t1;
--- 1.29/sql/item_row.cc Fri Apr 1 15:04:44 2005
+++ 1.30/sql/item_row.cc Fri Jul 1 07:05:35 2005
@@ -53,7 +53,7 @@
DBUG_VOID_RETURN;
}
-bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref)
+bool Item_row::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
null_value= 0;
@@ -61,7 +61,7 @@
Item **arg, **arg_end;
for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++)
{
- if ((*arg)->fix_fields(thd, tabl, arg))
+ if ((*arg)->fix_fields(thd, arg))
return TRUE;
// we can't assign 'item' before, because fix_fields() can change arg
Item *item= *arg;
--- 1.19/sql/item_row.h Wed Feb 9 00:49:33 2005
+++ 1.20/sql/item_row.h Fri Jul 1 07:05:35 2005
@@ -61,7 +61,7 @@
illegal_method_call((const char*)"val_decimal");
return 0;
};
- bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
+ bool fix_fields(THD *thd, Item **ref);
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
table_map used_tables() const { return used_tables_cache; };
bool const_item() const { return const_item_cache; };
--- 1.112/sql/item_subselect.cc Tue Jun 28 19:52:07 2005
+++ 1.113/sql/item_subselect.cc Fri Jul 1 07:05:35 2005
@@ -130,7 +130,7 @@
}
-bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
+bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
{
char const *save_where= thd_param->where;
bool res;
@@ -165,7 +165,7 @@
substitution= 0;
thd->where= "checking transformed subquery";
if (!(*ref)->fixed)
- ret= (*ref)->fix_fields(thd, tables, ref);
+ ret= (*ref)->fix_fields(thd, ref);
thd->where= save_where;
return ret;
}
@@ -833,7 +833,7 @@
reference, also Item_sum_(max|min) can't be fixed after creation, so
we do not check item->fixed
*/
- if (item->fix_fields(thd, join->tables_list, 0))
+ if (item->fix_fields(thd, 0))
DBUG_RETURN(RES_ERROR);
/* we added aggregate function => we have to change statistic */
count_field_types(&join->tmp_table_param, join->all_fields, 0);
@@ -862,7 +862,7 @@
thd->lex->current_select= up= current->return_after_parsing();
//optimizer never use Item **ref => we can pass 0 as parameter
- if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
+ if (!optimizer || optimizer->fix_left(thd, 0))
{
thd->lex->current_select= current;
DBUG_RETURN(RES_ERROR);
@@ -873,7 +873,8 @@
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
we can use same item for all selects.
*/
- expr= new Item_direct_ref((Item**)optimizer->get_cache(),
+ expr= new Item_direct_ref(&select_lex->context,
+ (Item**)optimizer->get_cache(),
(char *)"<no matter>",
(char *)in_left_expr_name);
@@ -893,7 +894,8 @@
{
bool tmp;
Item *item= func->create(expr,
- new Item_ref_null_helper(this,
+ new Item_ref_null_helper(&select_lex->context,
+ this,
select_lex->
ref_pointer_array,
(char *)"<ref>",
@@ -913,7 +915,7 @@
we do not check join->having->fixed, because Item_and (from and_items)
or comparison function (from func->create) can't be fixed after creation
*/
- tmp= join->having->fix_fields(thd, join->tables_list, 0);
+ tmp= join->having->fix_fields(thd, 0);
select_lex->having_fix_field= 0;
if (tmp)
DBUG_RETURN(RES_ERROR);
@@ -949,7 +951,7 @@
and_items) or comparison function (from func->create) can't be
fixed after creation
*/
- tmp= join->having->fix_fields(thd, join->tables_list, 0);
+ tmp= join->having->fix_fields(thd, 0);
select_lex->having_fix_field= 0;
if (tmp)
DBUG_RETURN(RES_ERROR);
@@ -971,7 +973,7 @@
we do not check join->conds->fixed, because Item_and can't be fixed
after creation
*/
- if (join->conds->fix_fields(thd, join->tables_list, 0))
+ if (join->conds->fix_fields(thd, 0))
DBUG_RETURN(RES_ERROR);
}
else
@@ -983,22 +985,23 @@
comparison functions can't be changed during fix_fields()
we can assign select_lex->having here, and pass 0 as last
argument (reference) to fix_fields()
- */
- item= func->create(expr,
- new Item_null_helper(this, item,
- (char *)"<no matter>",
- (char *)"<result>"));
+ */
+ item= func->create(expr,
+ new Item_null_helper(&select_lex->context,
+ this, item,
+ (char *)"<no matter>",
+ (char *)"<result>"));
#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE
if (!abort_on_null && left_expr->maybe_null)
item= new Item_cond_or(new Item_func_isnull(left_expr), item);
#endif
- select_lex->having= join->having= item;
+ select_lex->having= join->having= item;
select_lex->having_fix_field= 1;
/*
we do not check join->having->fixed, because comparison function
(from func->create) can't be fixed after creation
*/
- tmp= join->having->fix_fields(thd, join->tables_list, 0);
+ tmp= join->having->fix_fields(thd, 0);
select_lex->having_fix_field= 0;
if (tmp)
DBUG_RETURN(RES_ERROR);
@@ -1048,7 +1051,7 @@
SELECT_LEX *current= thd->lex->current_select, *up;
thd->lex->current_select= up= current->return_after_parsing();
//optimizer never use Item **ref => we can pass 0 as parameter
- if (!optimizer || optimizer->fix_left(thd, up->get_table_list(), 0))
+ if (!optimizer || optimizer->fix_left(thd, 0))
{
thd->lex->current_select= current;
DBUG_RETURN(RES_ERROR);
@@ -1071,12 +1074,14 @@
if (select_lex->ref_pointer_array[i]->
check_cols(left_expr->el(i)->cols()))
DBUG_RETURN(RES_ERROR);
- Item *func= new Item_ref_null_helper(this,
+ Item *func= new Item_ref_null_helper(&select_lex->context,
+ this,
select_lex->ref_pointer_array+i,
(char *) "<no matter>",
(char *) "<list ref>");
func=
- eq_creator.create(new Item_direct_ref((*optimizer->get_cache())->
+ eq_creator.create(new Item_direct_ref(&select_lex->context,
+ (*optimizer->get_cache())->
addr(i),
(char *)"<no matter>",
(char *)in_left_expr_name),
@@ -1099,7 +1104,7 @@
join->having can't be fixed after creation, so we do not check
join->having->fixed
*/
- if (join->having->fix_fields(thd, join->tables_list, 0))
+ if (join->having->fix_fields(thd, 0))
{
select_lex->having_fix_field= 0;
DBUG_RETURN(RES_ERROR);
@@ -1118,7 +1123,7 @@
join->conds can't be fixed after creation, so we do not check
join->conds->fixed
*/
- if (join->conds->fix_fields(thd, join->tables_list, 0))
+ if (join->conds->fix_fields(thd, 0))
DBUG_RETURN(RES_ERROR);
}
@@ -1189,8 +1194,7 @@
thd->lex->current_select= up= current->return_after_parsing();
result= (!left_expr->fixed &&
- left_expr->fix_fields(thd, up->get_table_list(),
- optimizer->arguments()));
+ left_expr->fix_fields(thd, optimizer->arguments()));
/* fix_fields can change reference to left_expr, we need reassign it */
left_expr= optimizer->arguments()[0];
--- 1.70/sql/item_subselect.h Mon May 9 12:26:46 2005
+++ 1.71/sql/item_subselect.h Fri Jul 1 07:05:35 2005
@@ -92,7 +92,7 @@
val_int();
return null_value;
}
- bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
+ bool fix_fields(THD *thd, Item **ref);
virtual bool exec();
virtual void fix_length_and_dec();
table_map used_tables() const;
@@ -119,9 +119,9 @@
friend class select_subselect;
friend class Item_in_optimizer;
- friend bool Item_field::fix_fields(THD *, TABLE_LIST *, Item **);
- friend bool Item_ref::fix_fields(THD *, TABLE_LIST *, Item **);
- friend bool Item_param::fix_fields(THD *, TABLE_LIST *, Item **);
+ friend bool Item_field::fix_fields(THD *, Item **);
+ friend bool Item_ref::fix_fields(THD *, Item **);
+ friend bool Item_param::fix_fields(THD *, Item **);
friend void mark_select_range_as_dependent(THD*,
st_select_lex*, st_select_lex*,
Field*, Item*, Item_ident*);
--- 1.48/sql/sql_view.cc Tue Jun 21 20:30:44 2005
+++ 1.49/sql/sql_view.cc Fri Jul 1 07:05:36 2005
@@ -828,10 +828,23 @@
table->effective_algorithm= VIEW_ALGORITHM_MERGE;
DBUG_PRINT("info", ("algorithm: MERGE"));
table->updatable= (table->updatable_view != 0);
- table->effective_with_check= (uint8)table->with_check;
-
- table->ancestor= view_tables;
+ table->effective_with_check=
+ old_lex->get_effective_with_check(table);
+ /* prepare view context */
+ lex->select_lex.context.resolve_in_table_list_only(table->ancestor=
+ view_tables);
+ lex->select_lex.context.outer_context= 0;
+ lex->select_lex.context.select_lex= table->select_lex;
+ /* do not check privileges & hide errors for view underlyings */
+ for (SELECT_LEX *sl= lex->all_selects_list;
+ sl;
+ sl= sl->next_select_in_list())
+ {
+ sl->context.check_privileges= FALSE;
+ sl->context.error_processor= &view_error_processor;
+ sl->context.error_processor_data= (void *)table;
+ }
/*
Tables of the main select of the view should be marked as belonging
to the same select as original view (again we can use LEX::select_lex
@@ -866,13 +879,12 @@
table->where= view_select->where;
/*
Add subqueries units to SELECT into which we merging current view.
-
unit(->next)* chain starts with subqueries that are used by this
view and continues with subqueries that are used by other views.
We must not add any subquery twice (otherwise we'll form a loop),
- to do this we remember in end_unit the first subquery that has
+ to do this we remember in end_unit the first subquery that has
been already added.
-
+
NOTE: we do not support UNION here, so we take only one select
*/
SELECT_LEX_NODE *end_unit= table->select_lex->slave;
@@ -1058,9 +1070,9 @@
bool check_key_in_view(THD *thd, TABLE_LIST *view)
{
TABLE *table;
- Field_translator *trans;
+ Field_translator *trans, *end_of_trans;
KEY *key_info, *key_info_end;
- uint i, elements_in_view;
+ uint i;
DBUG_ENTER("check_key_in_view");
/*
@@ -1077,9 +1089,24 @@
trans= view->field_translation;
key_info_end= (key_info= table->key_info)+ table->s->keys;
- elements_in_view= view->view->select_lex.item_list.elements;
+ end_of_trans= view->field_translation_end;
DBUG_ASSERT(table != 0 && view->field_translation != 0);
+ {
+ /*
+ We should be sure that all fields are ready to get keys from them, but
+ this operation should not have influence on Field::query_id, to avoid
+ marking as used fields which are not used
+ */
+ bool save_set_query_id= thd->set_query_id;
+ thd->set_query_id= 0;
+ for (Field_translator *fld= trans; fld < end_of_trans; fld++)
+ {
+ if (!fld->item->fixed && fld->item->fix_fields(thd,
&fld->item))
+ return TRUE;
+ }
+ thd->set_query_id= save_set_query_id;
+ }
/* Loop over all keys to see if a unique-not-null key is used */
for (;key_info != key_info_end ; key_info++)
{
@@ -1091,15 +1118,15 @@
/* check that all key parts are used */
for (;;)
{
- uint k;
- for (k= 0; k < elements_in_view; k++)
+ Field_translator *k;
+ for (k= trans; k < end_of_trans; k++)
{
Item_field *field;
- if ((field= trans[k].item->filed_for_view_update()) &&
+ if ((field= k->item->filed_for_view_update()) &&
field->field == key_part->field)
break;
}
- if (k == elements_in_view)
+ if (k == end_of_trans)
break; // Key is not possible
if (++key_part == key_part_end)
DBUG_RETURN(FALSE); // Found usable key
@@ -1111,19 +1138,20 @@
/* check all fields presence */
{
Field **field_ptr;
+ Field_translator *fld;
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
- for (i= 0; i < elements_in_view; i++)
+ for (fld= trans; fld < end_of_trans; fld++)
{
Item_field *field;
- if ((field= trans[i].item->filed_for_view_update()) &&
+ if ((field= fld->item->filed_for_view_update()) &&
field->field == *field_ptr)
break;
}
- if (i == elements_in_view) // If field didn't exists
+ if (fld == end_of_trans) // If field didn't exists
{
/*
- Keys or all fields of underlying tables are not foud => we have
+ Keys or all fields of underlying tables are not found => we have
to check variable updatable_views_with_limit to decide should we
issue an error or just a warning
*/
@@ -1148,6 +1176,7 @@
SYNOPSIS
insert_view_fields()
+ thd thread handler
list list for insertion
view view for processing
@@ -1156,19 +1185,22 @@
TRUE error (is not sent to cliet)
*/
-bool insert_view_fields(List<Item> *list, TABLE_LIST *view)
+bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
{
- uint elements_in_view= view->view->select_lex.item_list.elements;
+ Field_translator *trans_end;
Field_translator *trans;
DBUG_ENTER("insert_view_fields");
if (!(trans= view->field_translation))
DBUG_RETURN(FALSE);
+ trans_end= view->field_translation_end;
- for (uint i= 0; i < elements_in_view; i++)
+ for (Field_translator *entry= trans; entry < trans_end; entry++)
{
Item_field *fld;
- if ((fld= trans[i].item->filed_for_view_update()))
+ if (!entry->item->fixed && entry->item->fix_fields(thd,
&entry->item))
+ DBUG_RETURN(TRUE);
+ if ((fld= entry->item->filed_for_view_update()))
list->push_back(fld);
else
{
--- 1.6/sql/sql_view.h Thu Nov 25 02:23:08 2004
+++ 1.7/sql/sql_view.h Fri Jul 1 07:05:36 2005
@@ -25,7 +25,7 @@
bool check_key_in_view(THD *thd, TABLE_LIST * view);
-bool insert_view_fields(List<Item> *list, TABLE_LIST *view);
+bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view);
frm_type_enum mysql_frm_type(char *path);
--- 1.18/sql/sql_trigger.cc Tue May 24 21:19:28 2005
+++ 1.19/sql/sql_trigger.cc Fri Jul 1 07:05:36 2005
@@ -201,7 +201,7 @@
{
trg_field->setup_field(thd, table);
if (!trg_field->fixed &&
- trg_field->fix_fields(thd, (TABLE_LIST *)0, (Item **)0))
+ trg_field->fix_fields(thd, (Item **)0))
return 1;
}
--- 1.11/include/my_bitmap.h Sun Jan 16 23:18:16 2005
+++ 1.12/include/my_bitmap.h Fri Jul 1 07:05:34 2005
@@ -45,6 +45,8 @@
extern my_bool bitmap_is_set(const MY_BITMAP *map, uint bitmap_bit);
extern my_bool bitmap_is_set_all(const MY_BITMAP *map);
extern my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2);
+extern my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit);
+extern my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit);
extern uint bitmap_set_next(MY_BITMAP *map);
extern uint bitmap_get_first(const MY_BITMAP *map);
extern uint bitmap_bits_set(const MY_BITMAP *map);
--- 1.25/mysys/my_bitmap.c Wed Mar 9 20:22:21 2005
+++ 1.26/mysys/my_bitmap.c Fri Jul 1 07:05:34 2005
@@ -109,6 +109,51 @@
}
+/*
+ test if bit already set and set it if it was not (thread unsafe method)
+
+ SYNOPSIS
+ bitmap_fast_test_and_set()
+ MAP bit map struct
+ BIT bit number
+
+ RETURN
+ 0 bit was not set
+ !=0 bit was set
+*/
+
+my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit)
+{
+ uchar *byte= map->bitmap + (bitmap_bit / 8);
+ uchar bit= 1 << ((bitmap_bit) & 7);
+ uchar res= (*byte) & bit;
+ *byte|= bit;
+ return res;
+}
+
+
+/*
+ test if bit already set and set it if it was not (thread safe method)
+
+ SYNOPSIS
+ bitmap_fast_test_and_set()
+ map bit map struct
+ bitmap_bit bit number
+
+ RETURN
+ 0 bit was not set
+ !=0 bit was set
+*/
+
+my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit)
+{
+ my_bool res;
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
+ bitmap_lock(map);
+ res= bitmap_fast_test_and_set(map, bitmap_bit);
+ bitmap_unlock(map);
+}
+
uint bitmap_set_next(MY_BITMAP *map)
{
uchar *bitmap=map->bitmap;
--- 1.10/sql/sql_do.cc Tue Dec 21 12:37:38 2004
+++ 1.11/sql/sql_do.cc Fri Jul 1 07:05:36 2005
@@ -24,7 +24,7 @@
List_iterator<Item> li(values);
Item *value;
DBUG_ENTER("mysql_do");
- if (setup_fields(thd, 0, 0, values, 0, 0, 0))
+ if (setup_fields(thd, 0, values, 0, 0, 0))
DBUG_RETURN(TRUE);
while ((value = li++))
value->val_int();
--- 1.121/sql/set_var.cc Wed Jun 22 12:08:21 2005
+++ 1.122/sql/set_var.cc Fri Jul 1 07:05:35 2005
@@ -2983,7 +2983,7 @@
}
if ((!value->fixed &&
- value->fix_fields(thd, 0, &value)) || value->check_cols(1))
+ value->fix_fields(thd, &value)) || value->check_cols(1))
return -1;
if (var->check_update_type(value->result_type()))
{
@@ -3017,7 +3017,7 @@
if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))
return 1;
- if (value && ((!value->fixed && value->fix_fields(thd, 0,
&value)) ||
+ if (value && ((!value->fixed && value->fix_fields(thd,
&value)) ||
value->check_cols(1)))
return -1;
return 0;
@@ -3046,7 +3046,7 @@
Item_func_set_user_var can't substitute something else on its place =>
0 can be passed as last argument (reference on item)
*/
- return (user_var_item->fix_fields(thd, 0, (Item**) 0) ||
+ return (user_var_item->fix_fields(thd, (Item**) 0) ||
user_var_item->check()) ? -1 : 0;
}
@@ -3069,7 +3069,7 @@
Item_func_set_user_var can't substitute something else on its place =>
0 can be passed as last argument (reference on item)
*/
- return (user_var_item->fix_fields(thd, 0, (Item**) 0));
+ return (user_var_item->fix_fields(thd, (Item**) 0));
}
--- 1.77/sql/sp.cc Tue May 31 19:36:27 2005
+++ 1.78/sql/sp.cc Fri Jul 1 07:05:35 2005
@@ -676,14 +676,18 @@
tables is not VIEW for sure => we can pass 0 as condition
*/
- setup_tables(thd, &tables, 0, &leaves, FALSE);
+ thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
+ setup_tables(thd, &thd->lex->select_lex.context,
+ &tables, 0, &leaves, FALSE);
for (used_field= &used_fields[0];
used_field->field_name;
used_field++)
{
- Item_field *field= new Item_field("mysql", "proc",
+ Item_field *field= new Item_field(&thd->lex->select_lex.context,
+ "mysql", "proc",
used_field->field_name);
- if (!(used_field->field= find_field_in_tables(thd, field, &tables,
+ if (!field ||
+ !(used_field->field= find_field_in_tables(thd, field, &tables,
0, REPORT_ALL_ERRORS, 1)))
{
res= SP_INTERNAL_ERROR;
--- 1.153/sql/sp_head.cc Thu Jun 30 19:36:08 2005
+++ 1.154/sql/sp_head.cc Fri Jul 1 07:05:35 2005
@@ -117,7 +117,7 @@
DBUG_ENTER("sp_prepare_func_item");
it_addr= it->this_item_addr(thd, it_addr);
- if (!it->fixed && (*it_addr)->fix_fields(thd, 0, it_addr))
+ if (!it->fixed && (*it_addr)->fix_fields(thd, it_addr))
{
DBUG_PRINT("info", ("fix_fields() failed"));
DBUG_RETURN(NULL);
@@ -962,7 +962,7 @@
we do not check suv->fixed, because it can't be fixed after
creation
*/
- suv->fix_fields(thd, NULL, &item);
+ suv->fix_fields(thd, &item);
suv->fix_length_and_dec();
suv->check();
suv->update();
@@ -1579,8 +1579,8 @@
DBUG_ENTER("sp_instr_set_trigger_field::execute");
/* QQ: Still unsure what should we return in case of error 1 or -1 ? */
- if (!value->fixed && value->fix_fields(thd, 0, &value) ||
- trigger_field->fix_fields(thd, 0, 0) ||
+ if (!value->fixed && value->fix_fields(thd, &value) ||
+ trigger_field->fix_fields(thd, 0) ||
(value->save_in_field(trigger_field->field, 0) < 0))
res= -1;
*nextp= m_ip + 1;
--- 1.58/sql/sp_head.h Thu Jun 23 19:22:02 2005
+++ 1.59/sql/sp_head.h Fri Jul 1 07:05:35 2005
@@ -470,10 +470,11 @@
public:
- sp_instr_set_trigger_field(uint ip, sp_pcontext *ctx,
+ sp_instr_set_trigger_field(Name_resolution_context *context_arg,
+ uint ip, sp_pcontext *ctx,
Item_trigger_field *trg_fld, Item *val)
: sp_instr(ip, ctx),
- trigger_field(trg_fld),
+ trigger_field(context_arg, trg_fld),
value(val)
{}
--- 1.71/sql/sql_handler.cc Tue Jun 21 17:18:23 2005
+++ 1.72/sql/sql_handler.cc Fri Jul 1 07:05:36 2005
@@ -353,7 +353,9 @@
LINT_INIT(key);
LINT_INIT(key_len);
- list.push_front(new Item_field(NULL,NULL,"*"));
+ thd->lex->select_lex.context.resolve_in_table_list_only(tables);
+ list.push_front(new Item_field(&thd->lex->select_lex.context,
+ NULL, NULL, "*"));
List_iterator<Item> it(list);
it++;
@@ -410,7 +412,7 @@
tables->table=table;
if (cond && ((!cond->fixed &&
- cond->fix_fields(thd, tables, &cond)) || cond->check_cols(1)))
+ cond->fix_fields(thd, &cond)) || cond->check_cols(1)))
goto err0;
if (keyname)
@@ -422,7 +424,8 @@
}
}
- if (insert_fields(thd, tables, tables->db, tables->alias, &it, 0))
+ if (insert_fields(thd, &thd->lex->select_lex.context,
+ tables->db, tables->alias, &it, 0))
goto err0;
protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
@@ -505,7 +508,7 @@
{
// 'item' can be changed by fix_fields() call
if ((!item->fixed &&
- item->fix_fields(thd, tables, it_ke.ref())) ||
+ item->fix_fields(thd, it_ke.ref())) ||
(item= *it_ke.ref())->check_cols(1))
goto err;
if (item->used_tables() & ~RAND_TABLE_BIT)
--- 1.128/sql/sql_prepare.cc Thu Jun 23 19:22:02 2005
+++ 1.129/sql/sql_prepare.cc Fri Jul 1 07:05:36 2005
@@ -963,7 +963,7 @@
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
goto error;
}
- if (setup_fields(thd, 0, table_list, *values, 0, 0, 0))
+ if (setup_fields(thd, 0, *values, 0, 0, 0))
goto error;
}
}
@@ -1039,9 +1039,9 @@
table_list->grant.want_privilege= want_privilege;
table_list->table->grant.want_privilege= want_privilege;
#endif
- thd->lex->select_lex.no_wrap_view_item= 1;
- res= setup_fields(thd, 0, table_list, select->item_list, 1, 0, 0);
- thd->lex->select_lex.no_wrap_view_item= 0;
+ thd->lex->select_lex.no_wrap_view_item= TRUE;
+ res= setup_fields(thd, 0, select->item_list, 1, 0, 0);
+ thd->lex->select_lex.no_wrap_view_item= FALSE;
if (res)
goto error;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -1050,7 +1050,7 @@
table_list->table->grant.want_privilege=
(SELECT_ACL & ~table_list->table->grant.privilege);
#endif
- if (setup_fields(thd, 0, table_list, stmt->lex->value_list, 0, 0, 0))
+ if (setup_fields(thd, 0, stmt->lex->value_list, 0, 0, 0))
goto error;
/* TODO: here we should send types of placeholders to the client. */
DBUG_RETURN(0);
@@ -1119,6 +1119,8 @@
SELECT_LEX_UNIT *unit= &lex->unit;
DBUG_ENTER("mysql_test_select");
+ lex->select_lex.context.resolve_in_select_list= TRUE;
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL;
if (tables)
@@ -1207,7 +1209,7 @@
if (open_and_lock_tables(thd, tables))
DBUG_RETURN(TRUE);
- DBUG_RETURN(setup_fields(thd, 0, 0, *values, 0, 0, 0));
+ DBUG_RETURN(setup_fields(thd, 0, *values, 0, 0, 0));
}
@@ -1277,6 +1279,8 @@
THD *thd= stmt->thd;
LEX *lex= stmt->lex;
+ lex->select_lex.context.resolve_in_select_list= TRUE;
+
if (specific_prepare && (*specific_prepare)(thd))
DBUG_RETURN(TRUE);
@@ -1354,9 +1358,8 @@
if (select_lex->item_list.elements)
{
- select_lex->resolve_mode= SELECT_LEX::SELECT_MODE;
+ select_lex->context.resolve_in_select_list= TRUE;
res= select_like_stmt_test_with_open_n_lock(stmt, tables, 0, 0);
- select_lex->resolve_mode= SELECT_LEX::NOMATTER_MODE;
}
/* put tables back for PS rexecuting */
@@ -1446,16 +1449,21 @@
static bool mysql_insert_select_prepare_tester(THD *thd)
{
+ TABLE_LIST *first;
+ bool res;
SELECT_LEX *first_select= &thd->lex->select_lex;
/* Skip first table, which is the table we are inserting in */
- first_select->table_list.first= (byte*)((TABLE_LIST*)first_select->
- table_list.first)->next_local;
+ first_select->table_list.first= (byte*)(first=
+ ((TABLE_LIST*)first_select->
+ table_list.first)->next_local);
+ res= mysql_insert_select_prepare(thd);
/*
insert/replace from SELECT give its SELECT_LEX for SELECT,
and item_list belong to SELECT
*/
- first_select->resolve_mode= SELECT_LEX::SELECT_MODE;
- return mysql_insert_select_prepare(thd);
+ thd->lex->select_lex.context.resolve_in_select_list= TRUE;
+ thd->lex->select_lex.context.table_list= first;
+ return res;
}
@@ -1493,12 +1501,12 @@
first_local_table= (TABLE_LIST *)lex->select_lex.table_list.first;
DBUG_ASSERT(first_local_table != 0);
- res= select_like_stmt_test_with_open_n_lock(stmt, tables,
- &mysql_insert_select_prepare_tester,
- OPTION_SETUP_TABLES_DONE);
+ res=
+ select_like_stmt_test_with_open_n_lock(stmt, tables,
+ &mysql_insert_select_prepare_tester,
+ OPTION_SETUP_TABLES_DONE);
/* revert changes made by mysql_insert_select_prepare_tester */
lex->select_lex.table_list.first= (byte*) first_local_table;
- lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
return res;
}
@@ -1538,6 +1546,10 @@
lex->first_lists_tables_same();
tables= lex->query_tables;
+ /* set context for commands which do not use setup_tables */
+ lex->select_lex.context.resolve_in_table_list_only(select_lex->
+ get_table_list());
+
switch (sql_command) {
case SQLCOM_REPLACE:
case SQLCOM_INSERT:
@@ -1813,18 +1825,9 @@
void init_stmt_after_parse(THD *thd, LEX *lex)
{
SELECT_LEX *sl= lex->all_selects_list;
- /*
- Save WHERE clause pointers, because they may be changed during query
- optimisation.
- */
- for (; sl; sl= sl->next_select_in_list())
- {
- sl->prep_where= sl->where;
- sl->uncacheable&= ~UNCACHEABLE_PREPARE;
- }
- for (TABLE_LIST *table= lex->query_tables; table; table= table->next_global)
- table->prep_on_expr= table->on_expr;
+ for (; sl; sl= sl->next_select_in_list())
+ sl->uncacheable&= ~UNCACHEABLE_PREPARE;
}
--- 1.45/sql/sql_help.cc Mon May 30 19:54:30 2005
+++ 1.46/sql/sql_help.cc Fri Jul 1 07:05:36 2005
@@ -81,11 +81,14 @@
static bool init_fields(THD *thd, TABLE_LIST *tables,
struct st_find_field *find_fields, uint count)
{
+ Name_resolution_context *context= &thd->lex->select_lex.context;
DBUG_ENTER("init_fields");
+ context->resolve_in_table_list_only(tables);
for (; count-- ; find_fields++)
{
/* We have to use 'new' here as field will be re_linked on free */
- Item_field *field= new Item_field("mysql", find_fields->table_name,
+ Item_field *field= new Item_field(context,
+ "mysql", find_fields->table_name,
find_fields->field_name);
if (!(find_fields->field= find_field_in_tables(thd, field, tables,
0, REPORT_ALL_ERRORS, 1)))
@@ -544,7 +547,6 @@
prepare_simple_select()
thd Thread handler
cond WHERE part of select
- tables list of tables, used in WHERE
table goal table
error code of error (out)
@@ -553,11 +555,11 @@
# created SQL_SELECT
*/
-SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
+SQL_SELECT *prepare_simple_select(THD *thd, Item *cond,
TABLE *table, int *error)
{
if (!cond->fixed)
- cond->fix_fields(thd, tables, &cond); // can never fail
+ cond->fix_fields(thd, &cond); // can never fail
/* Assume that no indexes cover all required fields */
table->used_keys.clear_all();
@@ -599,7 +601,7 @@
new Item_string("\\",1,&my_charset_latin1));
if (thd->is_fatal_error)
return 0; // OOM
- return prepare_simple_select(thd,cond,tables,table,error);
+ return prepare_simple_select(thd, cond, table, error);
}
@@ -651,7 +653,8 @@
tables do not contain VIEWs => we can pass 0 as conds
*/
- setup_tables(thd, tables, 0, &leaves, FALSE);
+ setup_tables(thd, &thd->lex->select_lex.context,
+ tables, 0, &leaves, FALSE);
memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields));
if (init_fields(thd, tables, used_fields, array_elements(used_fields)))
goto error;
@@ -718,15 +721,15 @@
Item *cond_cat_by_cat=
new Item_func_equal(new Item_field(cat_cat_id),
new Item_int((int32)category_id));
- if (!(select= prepare_simple_select(thd,cond_topic_by_cat,
- tables,tables[0].table,&error)))
+ if (!(select= prepare_simple_select(thd, cond_topic_by_cat,
+ tables[0].table, &error)))
goto error;
get_all_items_for_category(thd,tables[0].table,
used_fields[help_topic_name].field,
select,&topics_list);
delete select;
- if (!(select= prepare_simple_select(thd,cond_cat_by_cat,tables,
- tables[1].table,&error)))
+ if (!(select= prepare_simple_select(thd, cond_cat_by_cat,
+ tables[1].table, &error)))
goto error;
get_all_items_for_category(thd,tables[1].table,
used_fields[help_category_name].field,
| Thread |
|---|
| • bk commit into 5.0 tree (bell:1.1856) BUG#6443 | sanja | 1 Jul |