Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into rakia.gmz:/home/kgeorge/mysql/autopush/B25831-5.0-opt sql/item.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_prepare.cc: Auto merged sql/sql_yacc.yy: Auto merged
This commit is contained in:
commit
6d537f01fd
@ -219,3 +219,20 @@ SELECT * FROM t1;
|
||||
a b
|
||||
45 2
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (i INT PRIMARY KEY, j INT);
|
||||
INSERT INTO t1 SELECT 1, j;
|
||||
ERROR 42S22: Unknown column 'j' in 'field list'
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (i INT PRIMARY KEY, j INT);
|
||||
CREATE TABLE t2 (a INT, b INT);
|
||||
CREATE TABLE t3 (a INT, c INT);
|
||||
INSERT INTO t1 SELECT 1, a FROM t2 NATURAL JOIN t3
|
||||
ON DUPLICATE KEY UPDATE j= a;
|
||||
DROP TABLE t1,t2,t3;
|
||||
CREATE TABLE t1 (i INT PRIMARY KEY, j INT);
|
||||
CREATE TABLE t2 (a INT);
|
||||
INSERT INTO t1 VALUES (1, 1);
|
||||
INSERT INTO t2 VALUES (1), (3);
|
||||
INSERT INTO t1 SELECT 1, COUNT(*) FROM t2 ON DUPLICATE KEY UPDATE j= a;
|
||||
ERROR 42S22: Unknown column 'a' in 'field list'
|
||||
DROP TABLE t1,t2;
|
||||
|
@ -139,3 +139,26 @@ INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
|
||||
SELECT * FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#25831: Deficiencies in INSERT ... SELECT ... field name resolving.
|
||||
#
|
||||
CREATE TABLE t1 (i INT PRIMARY KEY, j INT);
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
INSERT INTO t1 SELECT 1, j;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (i INT PRIMARY KEY, j INT);
|
||||
CREATE TABLE t2 (a INT, b INT);
|
||||
CREATE TABLE t3 (a INT, c INT);
|
||||
INSERT INTO t1 SELECT 1, a FROM t2 NATURAL JOIN t3
|
||||
ON DUPLICATE KEY UPDATE j= a;
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
CREATE TABLE t1 (i INT PRIMARY KEY, j INT);
|
||||
CREATE TABLE t2 (a INT);
|
||||
INSERT INTO t1 VALUES (1, 1);
|
||||
INSERT INTO t2 VALUES (1), (3);
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
INSERT INTO t1 SELECT 1, COUNT(*) FROM t2 ON DUPLICATE KEY UPDATE j= a;
|
||||
DROP TABLE t1,t2;
|
||||
|
@ -325,10 +325,10 @@ private:
|
||||
TABLE_LIST *save_first_name_resolution_table;
|
||||
TABLE_LIST *save_next_name_resolution_table;
|
||||
bool save_resolve_in_select_list;
|
||||
TABLE_LIST *save_next_local;
|
||||
|
||||
public:
|
||||
Name_resolution_context_state() {} /* Remove gcc warning */
|
||||
TABLE_LIST *save_next_local;
|
||||
|
||||
public:
|
||||
/* Save the state of a name resolution context. */
|
||||
@ -350,6 +350,11 @@ public:
|
||||
context->first_name_resolution_table= save_first_name_resolution_table;
|
||||
context->resolve_in_select_list= save_resolve_in_select_list;
|
||||
}
|
||||
|
||||
TABLE_LIST *get_first_name_resolution_table()
|
||||
{
|
||||
return save_first_name_resolution_table;
|
||||
}
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
@ -4527,21 +4527,8 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
||||
uint tablenr= 0;
|
||||
DBUG_ENTER("setup_tables");
|
||||
|
||||
/*
|
||||
Due to the various call paths that lead to setup_tables() it may happen
|
||||
that context->table_list and context->first_name_resolution_table can be
|
||||
NULL (this is typically done when creating TABLE_LISTs internally).
|
||||
TODO:
|
||||
Investigate all cases when this my happen, initialize the name resolution
|
||||
context correctly in all those places, and remove the context reset below.
|
||||
*/
|
||||
if (!context->table_list || !context->first_name_resolution_table)
|
||||
{
|
||||
/* Test whether the context is in a consistent state. */
|
||||
DBUG_ASSERT(!context->first_name_resolution_table && !context->table_list);
|
||||
context->table_list= context->first_name_resolution_table= tables;
|
||||
}
|
||||
|
||||
DBUG_ASSERT ((select_insert && !tables->next_name_resolution_table) || !tables ||
|
||||
(context->table_list && context->first_name_resolution_table));
|
||||
/*
|
||||
this is used for INSERT ... SELECT.
|
||||
For select we setup tables except first (and its underlying tables)
|
||||
|
@ -656,6 +656,8 @@ bool mysqld_help(THD *thd, const char *mask)
|
||||
Init tables and fields to be usable from items
|
||||
tables do not contain VIEWs => we can pass 0 as conds
|
||||
*/
|
||||
thd->lex->select_lex.context.table_list=
|
||||
thd->lex->select_lex.context.first_name_resolution_table= &tables[0];
|
||||
setup_tables(thd, &thd->lex->select_lex.context,
|
||||
&thd->lex->select_lex.top_join_list,
|
||||
tables, 0, &leaves, FALSE);
|
||||
|
@ -966,6 +966,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
||||
DBUG_PRINT("enter", ("table_list 0x%lx, table 0x%lx, view %d",
|
||||
(ulong)table_list, (ulong)table,
|
||||
(int)insert_into_view));
|
||||
/* INSERT should have a SELECT or VALUES clause */
|
||||
DBUG_ASSERT (!select_insert || !values);
|
||||
|
||||
/*
|
||||
For subqueries in VALUES() we should not see the table in which we are
|
||||
@ -998,44 +1000,40 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
||||
select_insert))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
/* Save the state of the current name resolution context. */
|
||||
ctx_state.save_state(context, table_list);
|
||||
|
||||
/*
|
||||
Perform name resolution only in the first table - 'table_list',
|
||||
which is the table that is inserted into.
|
||||
*/
|
||||
table_list->next_local= 0;
|
||||
context->resolve_in_table_list_only(table_list);
|
||||
|
||||
/* Prepare the fields in the statement. */
|
||||
if (values &&
|
||||
!(res= check_insert_fields(thd, context->table_list, fields, *values,
|
||||
!insert_into_view, &map) ||
|
||||
setup_fields(thd, 0, *values, 0, 0, 0)) &&
|
||||
duplic == DUP_UPDATE)
|
||||
if (values)
|
||||
{
|
||||
select_lex->no_wrap_view_item= TRUE;
|
||||
res= check_update_fields(thd, context->table_list, update_fields, &map);
|
||||
select_lex->no_wrap_view_item= FALSE;
|
||||
/* if we have INSERT ... VALUES () we cannot have a GROUP BY clause */
|
||||
DBUG_ASSERT (!select_lex->group_list.elements);
|
||||
|
||||
/* Save the state of the current name resolution context. */
|
||||
ctx_state.save_state(context, table_list);
|
||||
|
||||
/*
|
||||
When we are not using GROUP BY we can refer to other tables in the
|
||||
ON DUPLICATE KEY part.
|
||||
*/
|
||||
if (select_lex->group_list.elements == 0)
|
||||
Perform name resolution only in the first table - 'table_list',
|
||||
which is the table that is inserted into.
|
||||
*/
|
||||
table_list->next_local= 0;
|
||||
context->resolve_in_table_list_only(table_list);
|
||||
|
||||
if (!(res= check_insert_fields(thd, context->table_list, fields, *values,
|
||||
!insert_into_view, &map) ||
|
||||
setup_fields(thd, 0, *values, 0, 0, 0))
|
||||
&& duplic == DUP_UPDATE)
|
||||
{
|
||||
context->table_list->next_local= ctx_state.save_next_local;
|
||||
/* first_name_resolution_table was set by resolve_in_table_list_only() */
|
||||
context->first_name_resolution_table->
|
||||
next_name_resolution_table= ctx_state.save_next_local;
|
||||
select_lex->no_wrap_view_item= TRUE;
|
||||
res= check_update_fields(thd, context->table_list, update_fields, &map);
|
||||
select_lex->no_wrap_view_item= FALSE;
|
||||
}
|
||||
|
||||
/* Restore the current context. */
|
||||
ctx_state.restore_state(context, table_list);
|
||||
|
||||
if (!res)
|
||||
res= setup_fields(thd, 0, update_values, 1, 0, 0);
|
||||
}
|
||||
|
||||
/* Restore the current context. */
|
||||
ctx_state.restore_state(context, table_list);
|
||||
|
||||
if (res)
|
||||
DBUG_RETURN(res);
|
||||
|
||||
@ -2361,7 +2359,6 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
|
||||
if (info.handle_duplicates == DUP_UPDATE)
|
||||
{
|
||||
/* Save the state of the current name resolution context. */
|
||||
Name_resolution_context *context= &lex->select_lex.context;
|
||||
Name_resolution_context_state ctx_state;
|
||||
|
||||
@ -2377,16 +2374,20 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
*info.update_fields, &map);
|
||||
lex->select_lex.no_wrap_view_item= FALSE;
|
||||
/*
|
||||
When we are not using GROUP BY we can refer to other tables in the
|
||||
ON DUPLICATE KEY part
|
||||
When we are not using GROUP BY and there are no ungrouped aggregate functions
|
||||
we can refer to other tables in the ON DUPLICATE KEY part.
|
||||
We use next_name_resolution_table descructively, so check it first (views?)
|
||||
*/
|
||||
if (lex->select_lex.group_list.elements == 0)
|
||||
{
|
||||
context->table_list->next_local= ctx_state.save_next_local;
|
||||
/* first_name_resolution_table was set by resolve_in_table_list_only() */
|
||||
context->first_name_resolution_table->
|
||||
next_name_resolution_table= ctx_state.save_next_local;
|
||||
}
|
||||
DBUG_ASSERT (!table_list->next_name_resolution_table);
|
||||
if (lex->select_lex.group_list.elements == 0 &&
|
||||
!lex->select_lex.with_sum_func)
|
||||
/*
|
||||
We must make a single context out of the two separate name resolution contexts :
|
||||
the INSERT table and the tables in the SELECT part of INSERT ... SELECT.
|
||||
To do that we must concatenate the two lists
|
||||
*/
|
||||
table_list->next_name_resolution_table= ctx_state.get_first_name_resolution_table();
|
||||
|
||||
res= res || setup_fields(thd, 0, *info.update_values, 1, 0, 0);
|
||||
if (!res)
|
||||
{
|
||||
|
@ -1571,21 +1571,16 @@ error:
|
||||
|
||||
static bool mysql_insert_select_prepare_tester(THD *thd)
|
||||
{
|
||||
TABLE_LIST *first;
|
||||
bool res;
|
||||
SELECT_LEX *first_select= &thd->lex->select_lex;
|
||||
TABLE_LIST *second_table= ((TABLE_LIST*)first_select->table_list.first)->
|
||||
next_local;
|
||||
|
||||
/* Skip first table, which is the table we are inserting in */
|
||||
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
|
||||
*/
|
||||
thd->lex->select_lex.context.resolve_in_select_list= TRUE;
|
||||
thd->lex->select_lex.context.table_list= first;
|
||||
return res;
|
||||
first_select->table_list.first= (byte *) second_table;
|
||||
thd->lex->select_lex.context.table_list=
|
||||
thd->lex->select_lex.context.first_name_resolution_table= second_table;
|
||||
|
||||
return mysql_insert_select_prepare(thd);
|
||||
}
|
||||
|
||||
|
||||
|
@ -147,6 +147,8 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd)
|
||||
fake_select_lex->table_list.link_in_list((byte *)&result_table_list,
|
||||
(byte **)
|
||||
&result_table_list.next_local);
|
||||
fake_select_lex->context.table_list= fake_select_lex->context.first_name_resolution_table=
|
||||
fake_select_lex->get_table_list();
|
||||
for (ORDER *order= (ORDER *)global_parameters->order_list.first;
|
||||
order;
|
||||
order=order->next)
|
||||
|
@ -4188,8 +4188,13 @@ select_into:
|
||||
| select_from into;
|
||||
|
||||
select_from:
|
||||
FROM join_table_list where_clause group_clause having_clause
|
||||
FROM join_table_list where_clause group_clause having_clause
|
||||
opt_order_clause opt_limit_clause procedure_clause
|
||||
{
|
||||
Select->context.table_list=
|
||||
Select->context.first_name_resolution_table=
|
||||
(TABLE_LIST *) Select->table_list.first;
|
||||
}
|
||||
| FROM DUAL_SYM where_clause opt_limit_clause
|
||||
/* oracle compatibility: oracle always requires FROM clause,
|
||||
and DUAL is system table without fields.
|
||||
|
Loading…
x
Reference in New Issue
Block a user