Commit 83f90e06 authored by monty@mishka.local's avatar monty@mishka.local

Better bug fix for:

#9728  'Decreased functionality in "on duplicate key update
#8147  'a column proclaimed ambigous in INSERT ... SELECT .. ON DUPLICATE'

This ensures fields are uniquely qualified and also that one can't update other tables in the ON DUPLICATE KEY UPDATE part
parent d0700b81
drop table if exists t1,t2; drop table if exists t1,t2,t3;
create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL); create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12); insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12);
create table t2 (payoutID SMALLINT UNSIGNED NOT NULL PRIMARY KEY); create table t2 (payoutID SMALLINT UNSIGNED NOT NULL PRIMARY KEY);
...@@ -636,16 +636,35 @@ ff1 ff2 ...@@ -636,16 +636,35 @@ ff1 ff2
drop table t1, t2; drop table t1, t2;
create table t1 (a int unique); create table t1 (a int unique);
create table t2 (a int, b int); create table t2 (a int, b int);
create table t3 (c int, d int);
insert into t1 values (1),(2); insert into t1 values (1),(2);
insert into t2 values (1,2); insert into t2 values (1,2);
insert into t3 values (1,6),(3,7);
select * from t1; select * from t1;
a a
1 1
2 2
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b; insert into t1 select a from t2 on duplicate key update a= t1.a + t2.b;
select * from t1; select * from t1;
a a
2 2
3 3
drop table t1; insert into t1 select a+1 from t2 on duplicate key update t1.a= t1.a + t2.b+1;
drop table t2; select * from t1;
a
3
5
insert into t1 select t3.c from t3 on duplicate key update a= a + t3.d;
select * from t1;
a
1
5
10
insert into t1 select t2.a from t2 group by t2.a on duplicate key update a= a + 10;
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b;
ERROR 23000: Column 'a' in field list is ambiguous
insert into t1 select t2.a from t2 on duplicate key update t2.a= a + t2.b;
ERROR 42S02: Unknown table 't2' in field list
insert into t1 select t2.a from t2 group by t2.a on duplicate key update a= t1.a + t2.b;
ERROR 42S02: Unknown table 't2' in field list
drop table t1,t2,t3;
...@@ -143,7 +143,7 @@ INSERT t1 VALUES (1,2,10), (3,4,20); ...@@ -143,7 +143,7 @@ INSERT t1 VALUES (1,2,10), (3,4,20);
CREATE TABLE t2 (a INT, b INT, c INT, d INT); CREATE TABLE t2 (a INT, b INT, c INT, d INT);
INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1); INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1);
INSERT t2 VALUES (2,1,11,2), (7,4,40,2); INSERT t2 VALUES (2,1,11,2), (7,4,40,2);
INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100; INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=t1.c+100;
SELECT * FROM t1; SELECT * FROM t1;
a b c a b c
1 2 10 1 2 10
...@@ -158,6 +158,8 @@ a b c ...@@ -158,6 +158,8 @@ a b c
5 0 30 5 0 30
8 9 60 8 9 60
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a); INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
ERROR 23000: Column 'c' in field list is ambiguous
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=t1.c+VALUES(t1.a);
SELECT *, VALUES(a) FROM t1; SELECT *, VALUES(a) FROM t1;
a b c VALUES(a) a b c VALUES(a)
1 2 10 NULL 1 2 10 NULL
...@@ -174,7 +176,7 @@ select * from t1; ...@@ -174,7 +176,7 @@ select * from t1;
a a
1 1
2 2
insert ignore into t1 select a from t1 on duplicate key update a=a+1 ; insert ignore into t1 select a from t1 as t2 on duplicate key update a=t1.a+1 ;
select * from t1; select * from t1;
a a
1 1
...@@ -185,5 +187,7 @@ a ...@@ -185,5 +187,7 @@ a
2 2
3 3
insert into t1 select a from t1 on duplicate key update a=a+1 ; insert into t1 select a from t1 on duplicate key update a=a+1 ;
ERROR 23000: Duplicate entry '3' for key 1 ERROR 23000: Column 'a' in field list is ambiguous
insert ignore into t1 select a from t1 on duplicate key update a=t1.a+1 ;
ERROR 23000: Column 't1.a' in field list is ambiguous
drop table t1; drop table t1;
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
--disable_warnings --disable_warnings
drop table if exists t1,t2; drop table if exists t1,t2,t3;
--enable_warnings --enable_warnings
create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL); create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL);
...@@ -182,10 +182,24 @@ drop table t1, t2; ...@@ -182,10 +182,24 @@ drop table t1, t2;
# #
create table t1 (a int unique); create table t1 (a int unique);
create table t2 (a int, b int); create table t2 (a int, b int);
create table t3 (c int, d int);
insert into t1 values (1),(2); insert into t1 values (1),(2);
insert into t2 values (1,2); insert into t2 values (1,2);
insert into t3 values (1,6),(3,7);
select * from t1; select * from t1;
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b; insert into t1 select a from t2 on duplicate key update a= t1.a + t2.b;
select * from t1; select * from t1;
drop table t1; insert into t1 select a+1 from t2 on duplicate key update t1.a= t1.a + t2.b+1;
drop table t2; select * from t1;
insert into t1 select t3.c from t3 on duplicate key update a= a + t3.d;
select * from t1;
insert into t1 select t2.a from t2 group by t2.a on duplicate key update a= a + 10;
#Some error cases
--error 1052
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b;
--error 1109
insert into t1 select t2.a from t2 on duplicate key update t2.a= a + t2.b;
--error 1109
insert into t1 select t2.a from t2 group by t2.a on duplicate key update a= t1.a + t2.b;
drop table t1,t2,t3;
...@@ -72,11 +72,13 @@ CREATE TABLE t2 (a INT, b INT, c INT, d INT); ...@@ -72,11 +72,13 @@ CREATE TABLE t2 (a INT, b INT, c INT, d INT);
# column names deliberately clash with columns in t1 (Bug#8147) # column names deliberately clash with columns in t1 (Bug#8147)
INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1); INSERT t2 VALUES (5,6,30,1), (7,4,40,1), (8,9,60,1);
INSERT t2 VALUES (2,1,11,2), (7,4,40,2); INSERT t2 VALUES (2,1,11,2), (7,4,40,2);
INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=c+100; INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=t1.c+100;
SELECT * FROM t1; SELECT * FROM t1;
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0; INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
SELECT * FROM t1; SELECT * FROM t1;
--error 1052
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a); INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=t1.c+VALUES(t1.a);
SELECT *, VALUES(a) FROM t1; SELECT *, VALUES(a) FROM t1;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
...@@ -89,10 +91,12 @@ create table t1 (a int not null unique) engine=myisam; ...@@ -89,10 +91,12 @@ create table t1 (a int not null unique) engine=myisam;
insert into t1 values (1),(2); insert into t1 values (1),(2);
insert ignore into t1 select 1 on duplicate key update a=2; insert ignore into t1 select 1 on duplicate key update a=2;
select * from t1; select * from t1;
insert ignore into t1 select a from t1 on duplicate key update a=a+1 ; insert ignore into t1 select a from t1 as t2 on duplicate key update a=t1.a+1 ;
select * from t1; select * from t1;
insert into t1 select 1 on duplicate key update a=2; insert into t1 select 1 on duplicate key update a=2;
select * from t1; select * from t1;
--error 1062 --error 1052
insert into t1 select a from t1 on duplicate key update a=a+1 ; insert into t1 select a from t1 on duplicate key update a=a+1 ;
--error 1052
insert ignore into t1 select a from t1 on duplicate key update a=t1.a+1 ;
drop table t1; drop table t1;
...@@ -98,17 +98,16 @@ int check_if_legal_filename(const char *path) ...@@ -98,17 +98,16 @@ int check_if_legal_filename(const char *path)
for (reserved_name= reserved_names; *reserved_name; reserved_name++) for (reserved_name= reserved_names; *reserved_name; reserved_name++)
{ {
const char *reserved= *reserved_name; /* never empty */
const char *name= path; const char *name= path;
const char *current_reserved_name= *reserved_name;
while (name != end && *current_reserved_name) do
{ {
if (*current_reserved_name != my_toupper(&my_charset_latin1, *name)) if (*reserved != my_toupper(&my_charset_latin1, *name))
break; break;
current_reserved_name++;
if (++name == end) if (++name == end)
DBUG_RETURN(1); /* Found wrong path */ DBUG_RETURN(1); /* Found wrong path */
} } while (*++reserved);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -439,9 +439,11 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans) ...@@ -439,9 +439,11 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans)
if (m_rows_to_insert == 1) if (m_rows_to_insert == 1)
m_dupkey= table->primary_key; m_dupkey= table->primary_key;
else else
// We are batching inserts, offending key is not available {
/* We are batching inserts, offending key is not available */
m_dupkey= (uint) -1; m_dupkey= (uint) -1;
} }
}
DBUG_RETURN(res); DBUG_RETURN(res);
} }
......
...@@ -65,7 +65,6 @@ Item::Item(): ...@@ -65,7 +65,6 @@ Item::Item():
place == IN_HAVING) place == IN_HAVING)
thd->lex->current_select->select_n_having_items++; thd->lex->current_select->select_n_having_items++;
} }
item_flags= 0;
} }
/* /*
...@@ -84,8 +83,7 @@ Item::Item(THD *thd, Item *item): ...@@ -84,8 +83,7 @@ Item::Item(THD *thd, Item *item):
unsigned_flag(item->unsigned_flag), unsigned_flag(item->unsigned_flag),
with_sum_func(item->with_sum_func), with_sum_func(item->with_sum_func),
fixed(item->fixed), fixed(item->fixed),
collation(item->collation), collation(item->collation)
item_flags(item->item_flags)
{ {
next= thd->free_list; // Put in free list next= thd->free_list; // Put in free list
thd->free_list= this; thd->free_list= this;
......
...@@ -107,11 +107,6 @@ class DTCollation { ...@@ -107,11 +107,6 @@ class DTCollation {
typedef bool (Item::*Item_processor)(byte *arg); typedef bool (Item::*Item_processor)(byte *arg);
/*
See comments for sql_yacc.yy: insert_update_elem rule
*/
#define MY_ITEM_PREFER_1ST_TABLE 1
class Item { class Item {
Item(const Item &); /* Prevent use of these */ Item(const Item &); /* Prevent use of these */
void operator=(Item &); void operator=(Item &);
...@@ -147,7 +142,6 @@ class Item { ...@@ -147,7 +142,6 @@ class Item {
my_bool with_sum_func; my_bool with_sum_func;
my_bool fixed; /* If item fixed with fix_fields */ my_bool fixed; /* If item fixed with fix_fields */
DTCollation collation; DTCollation collation;
uint8 item_flags; /* Flags on how item should be processed */
// alloc & destruct is done as start of select using sql_alloc // alloc & destruct is done as start of select using sql_alloc
Item(); Item();
...@@ -333,11 +327,6 @@ class Item { ...@@ -333,11 +327,6 @@ class Item {
cleanup(); cleanup();
delete this; delete this;
} }
virtual bool set_flags_processor(byte *args)
{
this->item_flags|= *((uint8*)args);
return false;
}
}; };
......
...@@ -576,7 +576,8 @@ int mysql_multi_update_lock(THD *thd, ...@@ -576,7 +576,8 @@ int mysql_multi_update_lock(THD *thd,
List<Item> *fields, List<Item> *fields,
SELECT_LEX *select_lex); SELECT_LEX *select_lex);
int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
TABLE_LIST *insert_table_list, TABLE *table, TABLE_LIST *insert_table_list,
TABLE_LIST *dup_table_list, TABLE *table,
List<Item> &fields, List_item *values, List<Item> &fields, List_item *values,
List<Item> &update_fields, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates duplic); List<Item> &update_values, enum_duplicates duplic);
......
...@@ -1993,7 +1993,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, ...@@ -1993,7 +1993,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
const char *name=item->field_name; const char *name=item->field_name;
uint length=(uint) strlen(name); uint length=(uint) strlen(name);
char name_buff[NAME_LEN+1]; char name_buff[NAME_LEN+1];
bool allow_rowid;
if (item->cached_table) if (item->cached_table)
{ {
...@@ -2085,9 +2085,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, ...@@ -2085,9 +2085,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
return (Field*) not_found_field; return (Field*) not_found_field;
return (Field*) 0; return (Field*) 0;
} }
bool allow_rowid= tables && !tables->next; // Only one table allow_rowid= tables && !tables->next; // Only one table
uint table_idx= 0; for (; tables ; tables=tables->next)
for (; tables ; tables=tables->next, table_idx++)
{ {
if (!tables->table) if (!tables->table)
{ {
...@@ -2116,8 +2115,6 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, ...@@ -2116,8 +2115,6 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
return (Field*) 0; return (Field*) 0;
} }
found= field; found= field;
if (table_idx == 0 && item->item_flags & MY_ITEM_PREFER_1ST_TABLE)
break;
} }
} }
if (found) if (found)
......
...@@ -271,7 +271,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -271,7 +271,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->used_tables=0; thd->used_tables=0;
values= its++; values= its++;
if (mysql_prepare_insert(thd, table_list, insert_table_list, table, if (mysql_prepare_insert(thd, table_list, insert_table_list,
insert_table_list, table,
fields, values, update_fields, fields, values, update_fields,
update_values, duplic)) update_values, duplic))
goto abort; goto abort;
...@@ -499,22 +500,37 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -499,22 +500,37 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
SYNOPSIS SYNOPSIS
mysql_prepare_insert() mysql_prepare_insert()
thd - thread handler thd thread handler
table_list - global table list table_list global table list (not including first table for
insert_table_list - local table list of INSERT SELECT_LEX INSERT ... SELECT)
values - values to insert. NULL for INSERT ... SELECT insert_table_list Table we are inserting into (for INSERT ... SELECT)
dup_table_list Tables to be used in ON DUPLICATE KEY
It's either all global tables or only the table we
insert into, depending on if we are using GROUP BY
in the SELECT clause).
values Values to insert. NULL for INSERT ... SELECT
TODO (in far future)
In cases of:
INSERT INTO t1 SELECT a, sum(a) as sum1 from t2 GROUP BY a
ON DUPLICATE KEY ...
we should be able to refer to sum1 in the ON DUPLICATE KEY part
RETURN VALUE RETURN VALUE
0 - OK 0 OK
-1 - error (message is not sent to user) -1 error (message is not sent to user)
*/ */
int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
TABLE_LIST *insert_table_list, TABLE *table, TABLE_LIST *insert_table_list,
TABLE_LIST *dup_table_list,
TABLE *table,
List<Item> &fields, List_item *values, List<Item> &fields, List_item *values,
List<Item> &update_fields, List<Item> &update_values, List<Item> &update_fields, List<Item> &update_values,
enum_duplicates duplic) enum_duplicates duplic)
{ {
DBUG_ENTER("mysql_prepare_insert"); DBUG_ENTER("mysql_prepare_insert");
if (duplic == DUP_UPDATE && !table->insert_values) if (duplic == DUP_UPDATE && !table->insert_values)
{ {
/* it should be allocated before Item::fix_fields() */ /* it should be allocated before Item::fix_fields() */
...@@ -528,7 +544,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, ...@@ -528,7 +544,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
(values && setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0)) || (values && setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0)) ||
(duplic == DUP_UPDATE && (duplic == DUP_UPDATE &&
(check_update_fields(thd, table, insert_table_list, update_fields) || (check_update_fields(thd, table, insert_table_list, update_fields) ||
setup_fields(thd, 0, insert_table_list, update_values, 1, 0, 0)))) setup_fields(thd, 0, dup_table_list, update_values, 1, 0, 0))))
DBUG_RETURN(-1); DBUG_RETURN(-1);
if (values && find_real_table_in_list(table_list->next, table_list->db, if (values && find_real_table_in_list(table_list->next, table_list->db,
table_list->real_name)) table_list->real_name))
......
...@@ -2831,6 +2831,8 @@ mysql_execute_command(THD *thd) ...@@ -2831,6 +2831,8 @@ mysql_execute_command(THD *thd)
case SQLCOM_INSERT_SELECT: case SQLCOM_INSERT_SELECT:
{ {
TABLE_LIST *first_local_table= (TABLE_LIST *) select_lex->table_list.first; TABLE_LIST *first_local_table= (TABLE_LIST *) select_lex->table_list.first;
TABLE_LIST dup_tables;
TABLE *insert_table;
if ((res= insert_precheck(thd, tables))) if ((res= insert_precheck(thd, tables)))
break; break;
...@@ -2856,14 +2858,27 @@ mysql_execute_command(THD *thd) ...@@ -2856,14 +2858,27 @@ mysql_execute_command(THD *thd)
if ((res= open_and_lock_tables(thd, tables))) if ((res= open_and_lock_tables(thd, tables)))
break; break;
insert_table= tables->table;
/* Skip first table, which is the table we are inserting in */ /* Skip first table, which is the table we are inserting in */
select_lex->table_list.first= (byte*) first_local_table->next; select_lex->table_list.first= (byte*) first_local_table->next;
tables= (TABLE_LIST *) select_lex->table_list.first;
dup_tables= *first_local_table;
first_local_table->next= 0;
if (select_lex->group_list.elements != 0)
{
/*
When we are using GROUP BY we can't refere to other tables in the
ON DUPLICATE KEY part
*/
dup_tables.next= 0;
}
if (!(res= mysql_prepare_insert(thd, tables, first_local_table, if (!(res= mysql_prepare_insert(thd, tables, first_local_table,
tables->table, lex->field_list, 0, &dup_tables, insert_table,
lex->field_list, 0,
lex->update_list, lex->value_list, lex->update_list, lex->value_list,
lex->duplicates)) && lex->duplicates)) &&
(result= new select_insert(tables->table, &lex->field_list, (result= new select_insert(insert_table, &lex->field_list,
&lex->update_list, &lex->value_list, &lex->update_list, &lex->value_list,
lex->duplicates, lex->ignore))) lex->duplicates, lex->ignore)))
{ {
...@@ -2876,7 +2891,7 @@ mysql_execute_command(THD *thd) ...@@ -2876,7 +2891,7 @@ mysql_execute_command(THD *thd)
/* revert changes for SP */ /* revert changes for SP */
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
delete result; delete result;
tables->table->insert_values= 0; insert_table->insert_values= 0;
if (thd->net.report_error) if (thd->net.report_error)
res= -1; res= -1;
} }
...@@ -4951,9 +4966,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, ...@@ -4951,9 +4966,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
*/ */
/* /*
Writing this command to the binlog may result in infinite loops when doing Writing this command to the binlog may result in infinite loops when
mysqlbinlog|mysql, and anyway it does not really make sense to log it doing mysqlbinlog|mysql, and anyway it does not really make sense to
automatically (would cause more trouble to users than it would help them) log it automatically (would cause more trouble to users than it would
help them)
*/ */
tmp_write_to_binlog= 0; tmp_write_to_binlog= 0;
mysql_log.new_file(1); mysql_log.new_file(1);
......
...@@ -918,6 +918,7 @@ static int mysql_test_insert(Prepared_statement *stmt, ...@@ -918,6 +918,7 @@ static int mysql_test_insert(Prepared_statement *stmt,
table_list->table->insert_values=(byte *)1; // don't allocate insert_values table_list->table->insert_values=(byte *)1; // don't allocate insert_values
if ((res= mysql_prepare_insert(thd, table_list, insert_table_list, if ((res= mysql_prepare_insert(thd, table_list, insert_table_list,
insert_table_list,
table_list->table, fields, values, table_list->table, fields, values,
update_fields, update_values, duplic))) update_fields, update_values, duplic)))
goto error; goto error;
......
...@@ -4239,24 +4239,9 @@ insert_update_elem: ...@@ -4239,24 +4239,9 @@ insert_update_elem:
simple_ident equal expr_or_default simple_ident equal expr_or_default
{ {
LEX *lex= Lex; LEX *lex= Lex;
uint8 tmp= MY_ITEM_PREFER_1ST_TABLE;
if (lex->update_list.push_back($1) || if (lex->update_list.push_back($1) ||
lex->value_list.push_back($3)) lex->value_list.push_back($3))
YYABORT; YYABORT;
/*
INSERT INTO a1(a) SELECT b1.a FROM b1 ON DUPLICATE KEY
UPDATE a= a + b1.b
Set MY_ITEM_PREFER_1ST_TABLE flag to $1 and $3 items
to prevent find_field_in_tables() doing further item searching
if it finds item occurence in first table in insert_table_list.
This allows to avoid ambiguity in resolving 'a' field in
example above.
*/
$1->walk(&Item::set_flags_processor,
(byte *) &tmp);
$3->walk(&Item::set_flags_processor,
(byte *) &tmp);
}; };
opt_low_priority: opt_low_priority:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment