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
This commit is contained in:
parent
d0700b819e
commit
83f90e060e
@ -1,4 +1,4 @@
|
|||||||
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
|
|||||||
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);
|
|||||||
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
|
|||||||
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;
|
|||||||
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
|
|||||||
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 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
--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;
|
|||||||
#
|
#
|
||||||
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 a from t2 on duplicate key update a= t1.a + t2.b;
|
||||||
|
select * from t1;
|
||||||
|
insert into t1 select a+1 from t2 on duplicate key update t1.a= t1.a + t2.b+1;
|
||||||
|
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;
|
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b;
|
||||||
select * from t1;
|
--error 1109
|
||||||
drop table t1;
|
insert into t1 select t2.a from t2 on duplicate key update t2.a= a + t2.b;
|
||||||
drop table t2;
|
--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);
|
|||||||
# 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;
|
|||||||
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)
|
|||||||
|
|
||||||
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,8 +439,10 @@ 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():
|
|||||||
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):
|
|||||||
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;
|
||||||
|
11
sql/item.h
11
sql/item.h
@ -107,11 +107,6 @@ public:
|
|||||||
|
|
||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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 @@ abort:
|
|||||||
|
|
||||||
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,
|
|||||||
(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))
|
||||||
|
@ -1943,10 +1943,10 @@ mysql_execute_command(THD *thd)
|
|||||||
if (tables || &lex->select_lex != lex->all_selects_list)
|
if (tables || &lex->select_lex != lex->all_selects_list)
|
||||||
mysql_reset_errors(thd);
|
mysql_reset_errors(thd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When subselects or time_zone info is used in a query
|
When subselects or time_zone info is used in a query
|
||||||
we create a new TABLE_LIST containing all referenced tables
|
we create a new TABLE_LIST containing all referenced tables
|
||||||
and set local variable 'tables' to point to this list.
|
and set local variable 'tables' to point to this list.
|
||||||
*/
|
*/
|
||||||
if ((&lex->select_lex != lex->all_selects_list ||
|
if ((&lex->select_lex != lex->all_selects_list ||
|
||||||
lex->time_zone_tables_used) &&
|
lex->time_zone_tables_used) &&
|
||||||
@ -2831,6 +2831,8 @@ unsent_create_error:
|
|||||||
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 @@ unsent_create_error:
|
|||||||
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;
|
||||||
if (!(res= mysql_prepare_insert(thd, tables, first_local_table,
|
dup_tables= *first_local_table;
|
||||||
tables->table, lex->field_list, 0,
|
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,
|
||||||
|
&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 @@ unsent_create_error:
|
|||||||
/* 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;
|
||||||
}
|
}
|
||||||
@ -4950,10 +4965,11 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
|||||||
the slow query log, and the relay log (if it exists).
|
the slow query log, and the relay log (if it exists).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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,
|
|||||||
|
|
||||||
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:
|
|||||||
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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user