Below is the list of changes that have just been committed into a local
5.2 repository of reggie. When reggie 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.2156 06/02/21 17:51:37 reggie@stripped +8 -0
Merge linux.site:/home/reggie/work/mysql-5.1-bug15408
into linux.site:/home/reggie/work/mysql-5.2
configure.in
1.338 06/02/21 17:51:30 reggie@stripped +0 -1
updated version to 5.2.0
sql/sql_yacc.yy
1.462 06/02/21 17:45:35 reggie@stripped +0 -0
Auto merged
sql/share/errmsg.txt
1.82 06/02/21 17:45:35 reggie@stripped +0 -0
Auto merged
sql/item.h
1.192 06/02/21 17:45:34 reggie@stripped +0 -0
Auto merged
sql/item.cc
1.169 06/02/21 17:45:34 reggie@stripped +0 -0
Auto merged
sql/handler.cc
1.217 06/02/21 17:45:33 reggie@stripped +0 -0
Auto merged
scripts/make_binary_distribution.sh
1.111 06/02/21 17:45:33 reggie@stripped +0 -0
Auto merged
mysql-test/r/innodb.result
1.163 06/02/21 17:45:33 reggie@stripped +0 -0
Auto merged
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: reggie
# Host: linux.site
# Root: /home/reggie/work/mysql-5.2/RESYNC
--- 1.337/configure.in 2006-02-14 18:23:51 -06:00
+++ 1.338/configure.in 2006-02-21 17:51:30 -06:00
@@ -1856,7 +1856,7 @@
pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \
realpath rename rint rwlock_init setupterm \
shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \
- sighold sigset sigthreadmask \
+ sighold sigset sigthreadmask sleep \
snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr strtol \
strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \
posix_fallocate)
--- 1.110/scripts/make_binary_distribution.sh 2006-02-14 18:23:52 -06:00
+++ 1.111/scripts/make_binary_distribution.sh 2006-02-21 17:45:33 -06:00
@@ -131,7 +131,8 @@
extra/resolve_stack_dump$BS extra/mysql_waitpid$BS \
storage/myisam/myisamchk$BS storage/myisam/myisampack$BS \
storage/myisam/myisamlog$BS storage/myisam/myisam_ftdump$BS \
- sql/mysqld$BS sql/mysqld-debug$BS sql/mysql_tzinfo_to_sql$BS \
+ sql/mysqld$BS sql/mysqld-debug$BS sql/mysqld-max$BS \
+ sql/mysql_tzinfo_to_sql$BS \
server-tools/instance-manager/mysqlmanager$BS \
client/mysql$BS client/mysqlshow$BS client/mysqladmin$BS \
client/mysqlslap$BS \
--- 1.216/sql/handler.cc 2006-02-14 18:23:52 -06:00
+++ 1.217/sql/handler.cc 2006-02-21 17:45:33 -06:00
@@ -359,6 +359,7 @@
SETMSG(HA_ERR_NO_CONNECTION, "Could not connect to storage engine");
SETMSG(HA_ERR_TABLE_DEF_CHANGED, ER(ER_TABLE_DEF_CHANGED));
SETMSG(HA_ERR_FOREIGN_DUPLICATE_KEY, "FK constraint would lead to duplicate key");
+ SETMSG(HA_ERR_TABLE_NEEDS_UPGRADE, ER(ER_TABLE_NEEDS_UPGRADE));
/* Register the error messages for use with my_error(). */
return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST);
@@ -1975,6 +1976,9 @@
my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
DBUG_VOID_RETURN;
}
+ case HA_ERR_TABLE_NEEDS_UPGRADE:
+ textno=ER_TABLE_NEEDS_UPGRADE;
+ break;
default:
{
/* The error was "unknown" to this function.
@@ -2016,6 +2020,100 @@
}
+int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt)
+{
+ KEY *keyinfo, *keyend;
+ KEY_PART_INFO *keypart, *keypartend;
+
+ if (!table->s->mysql_version)
+ {
+ /* check for blob-in-key error */
+ keyinfo= table->key_info;
+ keyend= table->key_info + table->s->keys;
+ for (; keyinfo < keyend; keyinfo++)
+ {
+ keypart= keyinfo->key_part;
+ keypartend= keypart + keyinfo->key_parts;
+ for (; keypart < keypartend; keypart++)
+ {
+ if (!keypart->fieldnr)
+ continue;
+ Field *field= table->field[keypart->fieldnr-1];
+ if (field->type() == FIELD_TYPE_BLOB)
+ {
+ if (check_opt->sql_flags & TT_FOR_UPGRADE)
+ check_opt->flags= T_MEDIUM;
+ return HA_ADMIN_NEEDS_CHECK;
+ }
+ }
+ }
+ }
+ return check_for_upgrade(check_opt);
+}
+
+
+int handler::check_old_types()
+{
+ Field** field;
+
+ if (!table->s->mysql_version)
+ {
+ /* check for bad DECIMAL field */
+ for (field= table->field; (*field); field++)
+ {
+ if ((*field)->type() == FIELD_TYPE_NEWDECIMAL)
+ {
+ return HA_ADMIN_NEEDS_ALTER;
+ }
+ }
+ }
+ return 0;
+}
+
+
+static bool update_frm_version(TABLE *table, bool needs_lock)
+{
+ char path[FN_REFLEN];
+ File file;
+ int result= 1;
+ DBUG_ENTER("update_frm_version");
+
+ if (table->s->mysql_version != MYSQL_VERSION_ID)
+ DBUG_RETURN(0);
+
+ strxmov(path, table->s->normalized_path.str, reg_ext, NullS);
+
+ if (needs_lock)
+ pthread_mutex_lock(&LOCK_open);
+
+ if ((file= my_open(path, O_RDWR|O_BINARY, MYF(MY_WME))) >= 0)
+ {
+ uchar version[4];
+ char *key= table->s->table_cache_key.str;
+ uint key_length= table->s->table_cache_key.length;
+ TABLE *entry;
+ HASH_SEARCH_STATE state;
+
+ int4store(version, MYSQL_VERSION_ID);
+
+ if ((result= my_pwrite(file,(byte*) version,4,51L,MYF_RW)))
+ goto err;
+
+ for (entry=(TABLE*) hash_first(&open_cache,(byte*) key,key_length, &state);
+ entry;
+ entry= (TABLE*) hash_next(&open_cache,(byte*) key,key_length, &state))
+ entry->s->mysql_version= MYSQL_VERSION_ID;
+ }
+err:
+ if (file >= 0)
+ VOID(my_close(file,MYF(MY_WME)));
+ if (needs_lock)
+ pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(result);
+}
+
+
+
/* Return key if error because of duplicated keys */
uint handler::get_dup_key(int error)
@@ -2089,6 +2187,56 @@
{
close();
delete_table(name);
+}
+
+
+/*
+ Performs checks upon the table.
+
+ SYNOPSIS
+ check()
+ thd thread doing CHECK TABLE operation
+ check_opt options from the parser
+
+ NOTES
+
+ RETURN
+ HA_ADMIN_OK Successful upgrade
+ HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
+ HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
+ HA_ADMIN_NOT_IMPLEMENTED
+*/
+
+int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
+{
+ int error;
+
+ if ((table->s->mysql_version >= MYSQL_VERSION_ID) &&
+ (check_opt->sql_flags & TT_FOR_UPGRADE))
+ return 0;
+
+ if (table->s->mysql_version < MYSQL_VERSION_ID)
+ {
+ if ((error= check_old_types()))
+ return error;
+ error= ha_check_for_upgrade(check_opt);
+ if (error && (error != HA_ADMIN_NEEDS_CHECK))
+ return error;
+ if (!error && (check_opt->sql_flags & TT_FOR_UPGRADE))
+ return 0;
+ }
+ if ((error= check(thd, check_opt)))
+ return error;
+ return update_frm_version(table, 0);
+}
+
+
+int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
+{
+ int result;
+ if ((result= repair(thd, check_opt)))
+ return result;
+ return update_frm_version(table, 0);
}
--- 1.168/sql/item.cc 2006-02-09 09:32:54 -06:00
+++ 1.169/sql/item.cc 2006-02-21 17:45:34 -06:00
@@ -375,8 +375,8 @@
void Item::cleanup()
{
DBUG_ENTER("Item::cleanup");
- DBUG_PRINT("info", ("Item: 0x%lx, Type: %d, name %s, original name %s",
- this, (int)type(), name ? name : "(null)",
+ DBUG_PRINT("info", ("Item: 0x%lx, name %s, original name %s",
+ this, name ? name : "(null)",
orig_name ? orig_name : "null"));
fixed=0;
marker= 0;
@@ -3212,6 +3212,252 @@
/*
+ Resolve the name of an outer select column reference.
+
+ SYNOPSIS
+ Item_field::fix_outer_field()
+ thd [in] current thread
+ from_field [in/out] found field reference or (Field*)not_found_field
+ reference [in/out] view column if this item was resolved to a view column
+
+ DESCRIPTION
+ The method resolves the column reference represented by 'this' as a column
+ present in outer selects that contain current select.
+
+ NOTES
+ This is the inner loop of Item_field::fix_fields:
+
+ for each outer query Q_k beginning from the inner-most one
+ {
+ search for a column or derived column named col_ref_i
+ [in table T_j] in the FROM clause of Q_k;
+
+ if such a column is not found
+ Search for a column or derived column named col_ref_i
+ [in table T_j] in the SELECT and GROUP clauses of Q_k.
+ }
+
+ IMPLEMENTATION
+ In prepared statements, because of cache, find_field_in_tables()
+ can resolve fields even if they don't belong to current context.
+ In this case this method only finds appropriate context and marks
+ current select as dependent. The found reference of field should be
+ provided in 'from_field'.
+
+ RETURN
+ 1 - column succefully resolved and fix_fields() should continue.
+ 0 - column fully fixed and fix_fields() should return FALSE
+ -1 - error occured
+*/
+int
+Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
+{
+ enum_parsing_place place= NO_MATTER;
+ bool field_found= (*from_field != not_found_field);
+ bool upward_lookup= FALSE;
+
+ /*
+ If there are 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.
+ */
+ 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 *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;
+
+ place= prev_subselect_item->parsing_place;
+ /*
+ If outer_field is set, field was already found by first call
+ to find_field_in_tables(). Only need to find appropriate context.
+ */
+ if (field_found && outer_context->select_lex !=
+ cached_table->select_lex)
+ continue;
+ /*
+ 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 (field_found || (*from_field= find_field_in_tables(thd, this,
+ outer_context->
+ first_name_resolution_table,
+ outer_context->
+ last_name_resolution_table,
+ reference,
+ IGNORE_EXCEPT_NON_UNIQUE,
+ TRUE, 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;
+ if (thd->lex->in_sum_func &&
+ thd->lex->in_sum_func->nest_level ==
+ thd->lex->current_select->nest_level)
+ {
+ Item::Type type= (*reference)->type();
+ set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+ select->nest_level);
+ set_field(*from_field);
+ fixed= 1;
+ mark_as_dependent(thd, last_checked_context->select_lex,
+ context->select_lex, this,
+ ((type == REF_ITEM || type == FIELD_ITEM) ?
+ (Item_ident*) (*reference) : 0));
+ return 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 0;
+ }
+ }
+ break;
+ }
+
+ /* 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)))
+ return -1; /* 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 -1;
+ if (ref == not_found_item && *from_field == not_found_field)
+ {
+ if (upward_lookup)
+ {
+ // We can't say exactly what absent table or field
+ my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where);
+ }
+ else
+ {
+ /* Call find_field_in_tables only to report the error */
+ find_field_in_tables(thd, this,
+ context->first_name_resolution_table,
+ context->last_name_resolution_table,
+ reference, REPORT_ALL_ERRORS,
+ !any_privileges &&
+ TRUE, TRUE);
+ }
+ return -1;
+ }
+ else if (ref != not_found_item)
+ {
+ Item *save;
+ Item_ref *rf;
+
+ /* Should have been checked in resolve_ref_in_select_and_group(). */
+ DBUG_ASSERT(*ref && (*ref)->fixed);
+ /*
+ Here, a subset of actions performed by Item_ref::set_properties
+ is not enough. So we pass ptr to NULL into Item_[direct]_ref
+ constructor, so no initialization is performed, and call
+ fix_fields() below.
+ */
+ save= *ref;
+ *ref= NULL; // Don't call set_properties()
+ rf= (place == IN_HAVING ?
+ 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 -1;
+ 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, reference) || rf->check_cols(1))
+ return -1;
+
+ mark_as_dependent(thd, last_checked_context->select_lex,
+ context->select_lex, this,
+ rf);
+ return 0;
+ }
+ else
+ {
+ 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(context,
+ (cached_table->db[0] ? cached_table->db : 0),
+ (char*) cached_table->alias, (char*) field_name);
+ if (!rf)
+ return -1;
+ 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, reference) || rf->check_cols(1))
+ return -1;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
+/*
Resolve the name of a column reference.
SYNOPSIS
@@ -3258,12 +3504,11 @@
bool Item_field::fix_fields(THD *thd, Item **reference)
{
- enum_parsing_place place= NO_MATTER;
DBUG_ASSERT(fixed == 0);
if (!field) // If field is not checked
{
- bool upward_lookup= FALSE;
Field *from_field= (Field *)not_found_field;
+ bool outer_fixed= false;
/*
In case of view, find_field_in_tables() write pointer to view field
expression to 'reference', i.e. it substitute that expression instead
@@ -3278,7 +3523,7 @@
TRUE)) ==
not_found_field)
{
-
+ int ret;
/* Look up in current select's item_list to find aliased fields */
if (thd->lex->current_select->is_item_list_lookup)
{
@@ -3293,197 +3538,11 @@
return 0;
}
}
-
- /*
- If there are 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.
- */
- 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 *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;
-
- place= prev_subselect_item->parsing_place;
- /*
- 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 ((from_field= find_field_in_tables(thd, this,
- outer_context->
- first_name_resolution_table,
- outer_context->
- last_name_resolution_table,
- reference,
- IGNORE_EXCEPT_NON_UNIQUE,
- TRUE, 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;
- if (thd->lex->in_sum_func &&
- thd->lex->in_sum_func->nest_level ==
- thd->lex->current_select->nest_level)
- {
- Item::Type type= (*reference)->type();
- set_if_bigger(thd->lex->in_sum_func->max_arg_level,
- select->nest_level);
- set_field(from_field);
- fixed= 1;
- mark_as_dependent(thd, last_checked_context->select_lex,
- context->select_lex, this,
- ((type == REF_ITEM || type == FIELD_ITEM) ?
- (Item_ident*) (*reference) : 0));
- return FALSE;
- }
- }
- 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;
- }
-
- /* 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)
- 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
- my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where);
- }
- else
- {
- /* Call find_field_in_tables only to report the error */
- find_field_in_tables(thd, this,
- context->first_name_resolution_table,
- context->last_name_resolution_table,
- reference, REPORT_ALL_ERRORS,
- !any_privileges &&
- TRUE, TRUE);
- }
- goto error;
- }
- else if (ref != not_found_item)
- {
- Item *save;
- Item_ref *rf;
-
- /* Should have been checked in resolve_ref_in_select_and_group(). */
- DBUG_ASSERT(*ref && (*ref)->fixed);
- /*
- Here, a subset of actions performed by Item_ref::set_properties
- is not enough. So we pass ptr to NULL into Item_[direct]_ref
- constructor, so no initialization is performed, and call
- fix_fields() below.
- */
- save= *ref;
- *ref= NULL; // Don't call set_properties()
- rf= (place == IN_HAVING ?
- 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)
- 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, reference) || rf->check_cols(1))
- goto error;
-
- mark_as_dependent(thd, last_checked_context->select_lex,
- context->select_lex, this,
- rf);
- return FALSE;
- }
- else
- {
- 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(context,
- (cached_table->db[0] ? cached_table->db : 0),
- (char*) cached_table->alias, (char*) field_name);
- if (!rf)
- 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, reference) || rf->check_cols(1))
- goto error;
- return FALSE;
- }
- }
+ if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
+ goto error;
+ else if (!ret)
+ return FALSE;
+ outer_fixed= TRUE;
}
else if (!from_field)
goto error;
@@ -3503,6 +3562,17 @@
if (from_field == view_ref_found)
return FALSE;
+ if (!outer_fixed && cached_table && cached_table->select_lex
&&
+ context->select_lex &&
+ cached_table->select_lex != context->select_lex)
+ {
+ int ret;
+ if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
+ goto error;
+ else if (!ret)
+ return FALSE;
+ }
+
set_field(from_field);
if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level ==
@@ -4655,6 +4725,25 @@
}
if (from_field != not_found_field)
{
+ if (cached_table && cached_table->select_lex &&
+ outer_context->select_lex &&
+ cached_table->select_lex != outer_context->select_lex)
+ {
+ /*
+ Due to cache, find_field_in_tables() can return field which
+ doesn't belong to provided outer_context. In this case we have
+ to find proper field context in order to fix field correcly.
+ */
+ do
+ {
+ outer_context= outer_context->outer_context;
+ select= outer_context->select_lex;
+ prev_subselect_item=
+ last_checked_context->select_lex->master_unit()->item;
+ last_checked_context= outer_context;
+ } while (outer_context && outer_context->select_lex &&
+ cached_table->select_lex != outer_context->select_lex);
+ }
prev_subselect_item->used_tables_cache|= from_field->table->map;
prev_subselect_item->const_item_cache= 0;
break;
--- 1.191/sql/item.h 2006-02-09 09:32:55 -06:00
+++ 1.192/sql/item.h 2006-02-21 17:45:34 -06:00
@@ -1205,6 +1205,7 @@
inline uint32 max_disp_length() { return field->max_length(); }
Item_field *filed_for_view_update() { return this; }
Item *safe_charset_converter(CHARSET_INFO *tocs);
+ int fix_outer_field(THD *thd, Field **field, Item **reference);
friend class Item_default_value;
friend class Item_insert_value;
friend class st_select_lex_unit;
--- 1.461/sql/sql_yacc.yy 2006-02-14 18:23:52 -06:00
+++ 1.462/sql/sql_yacc.yy 2006-02-21 17:45:35 -06:00
@@ -665,6 +665,7 @@
%token UNSIGNED
%token UNTIL_SYM
%token UPDATE_SYM
+%token UPGRADE_SYM
%token USAGE
%token USER
%token USE_FRM
@@ -5349,6 +5350,11 @@
RESTORE_SYM table_or_tables
{
Lex->sql_command = SQLCOM_RESTORE_TABLE;
+ push_warning_printf(((THD *)yythd), MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_DEPRECATED_STATEMENT,
+ ER(ER_WARN_DEPRECATED_STATEMENT),
+ "RESTORE TABLE", "5.2",
+ "mysqldump, mysql, MySQL Administrator");
}
table_list FROM TEXT_STRING_sys
{
@@ -5359,6 +5365,11 @@
BACKUP_SYM table_or_tables
{
Lex->sql_command = SQLCOM_BACKUP_TABLE;
+ push_warning_printf(((THD *)yythd), MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_DEPRECATED_STATEMENT,
+ ER(ER_WARN_DEPRECATED_STATEMENT),
+ "BACKUP TABLE", "5.2",
+ "mysqldump, mysql, MySQL Administrator");
}
table_list TO_SYM TEXT_STRING_sys
{
@@ -5456,7 +5467,8 @@
| FAST_SYM { Lex->check_opt.flags|= T_FAST; }
| MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; }
| EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
- | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; };
+ | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }
+ | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; };
optimize:
OPTIMIZE opt_no_write_to_binlog table_or_tables
@@ -8664,7 +8676,12 @@
LOAD TABLE_SYM table_ident FROM MASTER_SYM
{
LEX *lex=Lex;
- if (lex->sphead)
+ push_warning_printf(((THD *)yythd), MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARN_DEPRECATED_STATEMENT,
+ ER(ER_WARN_DEPRECATED_STATEMENT),
+ "LOAD TABLE FROM MASTER", "5.2",
+ "mysqldump, mysql, MySQL Administrator");
+ if (lex->sphead)
{
my_error(ER_SP_BADSTATEMENT, MYF(0), "LOAD TABLE");
YYABORT;
@@ -9783,8 +9800,7 @@
| option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
{
LEX *lex=Lex;
- if ($1)
- lex->option_type= $1;
+ lex->option_type= $1;
lex->var_list.push_back(new set_var(lex->option_type,
find_sys_var("tx_isolation"),
&null_lex_str,
--- 1.81/sql/share/errmsg.txt 2006-02-14 18:23:53 -06:00
+++ 1.82/sql/share/errmsg.txt 2006-02-21 17:45:35 -06:00
@@ -5804,3 +5804,12 @@
eng "Upholding foreign key constraints for table '%.64s', entry '%-.64s', key %d would
lead to a duplicate entry"
ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE
eng "Column count of mysql.%s is wrong. Expected %d, found %d. Created with MySQL
%d, now running %d. Please use scripts/mysql_fix_privilege_tables"
+ER_TABLE_NEEDS_UPGRADE
+ eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!"
+ER_ILLEGAL_HA_CREATE_OPTION
+ eng "Table storage engine '%-.64s' does not support the create option '%.64s'"
+ER_CANT_CHANGE_TX_ISOLATION 25001
+ eng "Transaction isolation level can't be changed while a transaction is in progress"
+ER_WARN_DEPRECATED_STATEMENT
+ eng "The '%s' statement is deprecated and will be removed in MySQL %s. Please
use client programs (e.g. %s) instead."
+
| Thread |
|---|
| • bk commit into 5.2 tree (reggie:1.2156) | reggie | 22 Feb |