Commit e929e55f authored by msvensson@neptunus.(none)'s avatar msvensson@neptunus.(none)

Merge bk-internal.mysql.com:/home/bk/mysql-4.1

into neptunus.(none):/home/msvensson/mysql/mysql-4.1
parents 01b025c2 53761ce0
...@@ -2,8 +2,17 @@ This directory contains a test suite for mysql daemon. To run ...@@ -2,8 +2,17 @@ This directory contains a test suite for mysql daemon. To run
the currently existing test cases, simply execute ./mysql-test-run in the currently existing test cases, simply execute ./mysql-test-run in
this directory. It will fire up the newly built mysqld and test it. this directory. It will fire up the newly built mysqld and test it.
If you want to run the test with a running MySQL server use the --external If you want to run a test with a running MySQL server use the --extern
option to mysql-test-run. option to mysql-test-run. Please note that in this mode the test suite
expects user to specify test names to run. Otherwise it falls back to the
normal "non-extern" behaviour. The reason is that some tests
could not run with external server. Here is the sample command
to test "alias" and "analyze" tests on external server:
mysql-test-run --extern alias analyze
To match your setup you might also need to provide --socket, --user and
other relevant options.
Note that you do not have to have to do make install, and you could Note that you do not have to have to do make install, and you could
actually have a co-existing MySQL installation - the tests will not actually have a co-existing MySQL installation - the tests will not
......
...@@ -772,7 +772,8 @@ sub executable_setup () { ...@@ -772,7 +772,8 @@ sub executable_setup () {
{ {
if ( $glob_win32 ) if ( $glob_win32 )
{ {
$path_client_bindir= mtr_path_exists("$glob_basedir/client_release"); $path_client_bindir= mtr_path_exists("$glob_basedir/client_release",
"$glob_basedir/bin");
$exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt"); $exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt");
$path_language= mtr_path_exists("$glob_basedir/share/english/"); $path_language= mtr_path_exists("$glob_basedir/share/english/");
$path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets"); $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets");
...@@ -794,7 +795,7 @@ sub executable_setup () { ...@@ -794,7 +795,7 @@ sub executable_setup () {
} }
else else
{ {
$exe_mysqltest= mtr_exe_exists("$glob_basedir/client/mysqltest"); $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
$exe_mysql_client_test= $exe_mysql_client_test=
mtr_exe_exists("$glob_basedir/tests/mysql_client_test"); mtr_exe_exists("$glob_basedir/tests/mysql_client_test");
} }
...@@ -2013,6 +2014,14 @@ sub run_mysqltest ($$) { ...@@ -2013,6 +2014,14 @@ sub run_mysqltest ($$) {
"--port=$master->[0]->{'path_myport'} " . "--port=$master->[0]->{'path_myport'} " .
"--socket=$master->[0]->{'path_mysock'}"; "--socket=$master->[0]->{'path_mysock'}";
if ( $glob_use_embedded_server )
{
$cmdline_mysql_client_test.=
" -A --language=$path_language" .
" -A --datadir=$slave->[0]->{'path_myddir'}" .
" -A --character-sets-dir=$path_charsetsdir";
}
my $cmdline_mysql_fix_system_tables= my $cmdline_mysql_fix_system_tables=
"$exe_mysql_fix_system_tables --no-defaults --host=localhost --user=root --password= " . "$exe_mysql_fix_system_tables --no-defaults --host=localhost --user=root --password= " .
"--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " . "--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " .
...@@ -2129,8 +2138,7 @@ sub run_mysqltest ($$) { ...@@ -2129,8 +2138,7 @@ sub run_mysqltest ($$) {
# #
############################################################################## ##############################################################################
sub usage ($) sub usage ($) {
{
print STDERR <<HERE; print STDERR <<HERE;
mysql-test-run [ OPTIONS ] [ TESTCASE ] mysql-test-run [ OPTIONS ] [ TESTCASE ]
......
...@@ -741,3 +741,13 @@ SELECT dt DIV 1 AS f, id FROM t1 GROUP BY f; ...@@ -741,3 +741,13 @@ SELECT dt DIV 1 AS f, id FROM t1 GROUP BY f;
f id f id
20050501123000 1 20050501123000 1
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (id varchar(20) NOT NULL);
INSERT INTO t1 VALUES ('trans1'), ('trans2');
CREATE TABLE t2 (id varchar(20) NOT NULL, err_comment blob NOT NULL);
INSERT INTO t2 VALUES ('trans1', 'a problem');
SELECT COUNT(DISTINCT(t1.id)), LEFT(err_comment, 256) AS err_comment
FROM t1 LEFT JOIN t2 ON t1.id=t2.id GROUP BY err_comment;
COUNT(DISTINCT(t1.id)) err_comment
1 NULL
1 a problem
DROP TABLE t1, t2;
...@@ -625,3 +625,27 @@ select SQL_BUFFER_RESULT * from t1 WHERE (SEQ = 1); ...@@ -625,3 +625,27 @@ select SQL_BUFFER_RESULT * from t1 WHERE (SEQ = 1);
ID NO SEQ ID NO SEQ
1 1 1 1 1 1
drop table t1; drop table t1;
create table t1 (f1 int);
create table t2 (ff1 int unique, ff2 int default 1);
insert into t1 values (1),(1),(2);
insert into t2(ff1) select f1 from t1 on duplicate key update ff2=ff2+1;
select * from t2;
ff1 ff2
1 2
2 1
drop table t1, t2;
create table t1 (a int unique);
create table t2 (a int, b int);
insert into t1 values (1),(2);
insert into t2 values (1,2);
select * from t1;
a
1
2
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b;
select * from t1;
a
2
3
drop table t1;
drop table t2;
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-------- Test for BUG#9361 --------
CREATE TABLE t1 (
a int unsigned not null auto_increment primary key,
b int unsigned
) ENGINE=MyISAM;
CREATE TABLE t2 (
a int unsigned not null auto_increment primary key,
b int unsigned
) ENGINE=MyISAM;
INSERT INTO t1 VALUES (NULL, 0);
INSERT INTO t1 SELECT NULL, 0 FROM t1;
INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
SELECT * FROM t1 ORDER BY a;
a b
1 0
2 0
SELECT * FROM t2 ORDER BY a;
a b
1 0
2 1
UPDATE t2, (SELECT a FROM t1) AS t SET t2.b = t.a+5 ;
SELECT * FROM t1 ORDER BY a;
a b
1 0
2 0
SELECT * FROM t2 ORDER BY a;
a b
1 6
2 6
SELECT * FROM t1 ORDER BY a;
a b
1 0
2 0
SELECT * FROM t2 ORDER BY a;
a b
1 6
2 6
drop table t1,t2;
-------- Test 1 for BUG#9361 --------
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 (
a1 char(30),
a2 int,
a3 int,
a4 char(30),
a5 char(30)
);
CREATE TABLE t2 (
b1 int,
b2 char(30)
);
INSERT INTO t1 VALUES ('Yes', 1, NULL, 'foo', 'bar');
INSERT INTO t2 VALUES (1, 'baz');
UPDATE t1 a, t2
SET a.a1 = 'No'
WHERE a.a2 =
(SELECT b1
FROM t2
WHERE b2 = 'baz')
AND a.a3 IS NULL
AND a.a4 = 'foo'
AND a.a5 = 'bar';
SELECT * FROM t1;
a1 a2 a3 a4 a5
No 1 NULL foo bar
SELECT * FROM t2;
b1 b2
1 baz
DROP TABLE t1, t2;
-------- Test 2 for BUG#9361 --------
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
CREATE TABLE t1 (
i INT,
j INT,
x INT,
y INT,
z INT
);
CREATE TABLE t2 (
i INT,
k INT,
x INT,
y INT,
z INT
);
CREATE TABLE t3 (
j INT,
k INT,
x INT,
y INT,
z INT
);
INSERT INTO t1 VALUES ( 1, 2,13,14,15);
INSERT INTO t2 VALUES ( 1, 3,23,24,25);
INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36);
UPDATE t1 AS a
INNER JOIN t2 AS b
ON a.i = b.i
INNER JOIN t3 AS c
ON a.j = c.j AND b.k = c.k
SET a.x = b.x,
a.y = b.y,
a.z = (
SELECT sum(z)
FROM t3
WHERE y = 34
)
WHERE b.x = 23;
SELECT * FROM t1;
i j x y z
1 2 23 24 71
DROP TABLE t1, t2, t3;
...@@ -565,3 +565,18 @@ INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' ); ...@@ -565,3 +565,18 @@ INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' );
SELECT dt DIV 1 AS f, id FROM t1 GROUP BY f; SELECT dt DIV 1 AS f, id FROM t1 GROUP BY f;
DROP TABLE t1; DROP TABLE t1;
#
# Test for bug #11295: GROUP BY a BLOB column with COUNT(DISTINCT column1)
# when the BLOB column takes NULL values
#
CREATE TABLE t1 (id varchar(20) NOT NULL);
INSERT INTO t1 VALUES ('trans1'), ('trans2');
CREATE TABLE t2 (id varchar(20) NOT NULL, err_comment blob NOT NULL);
INSERT INTO t2 VALUES ('trans1', 'a problem');
SELECT COUNT(DISTINCT(t1.id)), LEFT(err_comment, 256) AS err_comment
FROM t1 LEFT JOIN t2 ON t1.id=t2.id GROUP BY err_comment;
DROP TABLE t1, t2;
...@@ -166,3 +166,26 @@ INSERT INTO t1 (SEQ, NO) SELECT "1" AS SEQ, IF(MAX(NO) IS NULL, 0, MAX(NO)) + 1 ...@@ -166,3 +166,26 @@ INSERT INTO t1 (SEQ, NO) SELECT "1" AS SEQ, IF(MAX(NO) IS NULL, 0, MAX(NO)) + 1
select SQL_BUFFER_RESULT * from t1 WHERE (SEQ = 1); select SQL_BUFFER_RESULT * from t1 WHERE (SEQ = 1);
drop table t1; drop table t1;
#
# Bug#10886 - Have to restore default values after update ON DUPLICATE KEY
#
create table t1 (f1 int);
create table t2 (ff1 int unique, ff2 int default 1);
insert into t1 values (1),(1),(2);
insert into t2(ff1) select f1 from t1 on duplicate key update ff2=ff2+1;
select * from t2;
drop table t1, t2;
#
# BUGS #9728 - 'Decreased functionality in "on duplicate key update"'
# #8147 - 'a column proclaimed ambigous in INSERT ... SELECT .. ON
# DUPLICATE'
#
create table t1 (a int unique);
create table t2 (a int, b int);
insert into t1 values (1),(2);
insert into t2 values (1,2);
select * from t1;
insert into t1 select t2.a from t2 on duplicate key update a= a + t2.b;
select * from t1;
drop table t1;
drop table t2;
source include/master-slave.inc;
##############################################################################
#
# Let's verify that multi-update with a subselect does not cause the slave to crash
# (BUG#10442)
#
--disable_query_log
SELECT '-------- Test for BUG#9361 --------' as "";
--enable_query_log
CREATE TABLE t1 (
a int unsigned not null auto_increment primary key,
b int unsigned
) ENGINE=MyISAM;
CREATE TABLE t2 (
a int unsigned not null auto_increment primary key,
b int unsigned
) ENGINE=MyISAM;
INSERT INTO t1 VALUES (NULL, 0);
INSERT INTO t1 SELECT NULL, 0 FROM t1;
INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2 ORDER BY a;
UPDATE t2, (SELECT a FROM t1) AS t SET t2.b = t.a+5 ;
SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2 ORDER BY a;
sync_slave_with_master;
connection slave;
SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2 ORDER BY a;
connection master;
drop table t1,t2;
##############################################################################
#
# Test for BUG#9361:
# Subselects should work inside multi-updates
#
--disable_query_log
SELECT '-------- Test 1 for BUG#9361 --------' as "";
--enable_query_log
connection master;
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
--enable_warnings
CREATE TABLE t1 (
a1 char(30),
a2 int,
a3 int,
a4 char(30),
a5 char(30)
);
CREATE TABLE t2 (
b1 int,
b2 char(30)
);
# Insert one row per table
INSERT INTO t1 VALUES ('Yes', 1, NULL, 'foo', 'bar');
INSERT INTO t2 VALUES (1, 'baz');
# This should update the row in t1
UPDATE t1 a, t2
SET a.a1 = 'No'
WHERE a.a2 =
(SELECT b1
FROM t2
WHERE b2 = 'baz')
AND a.a3 IS NULL
AND a.a4 = 'foo'
AND a.a5 = 'bar';
sync_slave_with_master;
connection slave;
SELECT * FROM t1;
SELECT * FROM t2;
connection master;
DROP TABLE t1, t2;
##############################################################################
#
# Second test for BUG#9361
#
--disable_query_log
SELECT '-------- Test 2 for BUG#9361 --------' as "";
--enable_query_log
connection master;
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
--enable_warnings
CREATE TABLE t1 (
i INT,
j INT,
x INT,
y INT,
z INT
);
CREATE TABLE t2 (
i INT,
k INT,
x INT,
y INT,
z INT
);
CREATE TABLE t3 (
j INT,
k INT,
x INT,
y INT,
z INT
);
INSERT INTO t1 VALUES ( 1, 2,13,14,15);
INSERT INTO t2 VALUES ( 1, 3,23,24,25);
INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36);
UPDATE t1 AS a
INNER JOIN t2 AS b
ON a.i = b.i
INNER JOIN t3 AS c
ON a.j = c.j AND b.k = c.k
SET a.x = b.x,
a.y = b.y,
a.z = (
SELECT sum(z)
FROM t3
WHERE y = 34
)
WHERE b.x = 23;
sync_slave_with_master;
connection slave;
SELECT * FROM t1;
connection master;
DROP TABLE t1, t2, t3;
...@@ -93,18 +93,20 @@ int check_if_legal_filename(const char *path) ...@@ -93,18 +93,20 @@ int check_if_legal_filename(const char *path)
path+= dirname_length(path); /* To start of filename */ path+= dirname_length(path); /* To start of filename */
if (!(end= strchr(path, FN_EXTCHAR))) if (!(end= strchr(path, FN_EXTCHAR)))
end= strend(path); end= strend(path);
if (path == end || (uint) (path - end) > MAX_RESERVED_NAME_LENGTH) if (path == end || (uint) (end - path) > MAX_RESERVED_NAME_LENGTH)
DBUG_RETURN(0); /* Simplify inner loop */ DBUG_RETURN(0); /* Simplify inner loop */
for (reserved_name= reserved_names; *reserved_name; reserved_name++) for (reserved_name= reserved_names; *reserved_name; reserved_name++)
{ {
const char *name= path; const char *name= path;
while (name != end) const char *current_reserved_name= *reserved_name;
while (name != end && *current_reserved_name)
{ {
if (my_toupper(&my_charset_latin1, *path) != if (*current_reserved_name != my_toupper(&my_charset_latin1, *name))
my_toupper(&my_charset_latin1, *name))
break; break;
if (name++ == end) current_reserved_name++;
if (++name == end)
DBUG_RETURN(1); /* Found wrong path */ DBUG_RETURN(1); /* Found wrong path */
} }
} }
......
...@@ -90,7 +90,7 @@ void ndbSetOwnVersion() {} ...@@ -90,7 +90,7 @@ void ndbSetOwnVersion() {}
#ifndef TEST_VERSION #ifndef TEST_VERSION
struct NdbUpGradeCompatible ndbCompatibleTable_full[] = { struct NdbUpGradeCompatible ndbCompatibleTable_full[] = {
{ MAKE_VERSION(4,1,12), MAKE_VERSION(4,1,10), UG_Range }, { MAKE_VERSION(4,1,NDB_VERSION_BUILD), MAKE_VERSION(4,1,10), UG_Range },
{ MAKE_VERSION(4,1,10), MAKE_VERSION(4,1,9), UG_Exact }, { MAKE_VERSION(4,1,10), MAKE_VERSION(4,1,9), UG_Exact },
{ MAKE_VERSION(4,1,9), MAKE_VERSION(4,1,8), UG_Exact }, { MAKE_VERSION(4,1,9), MAKE_VERSION(4,1,8), UG_Exact },
{ MAKE_VERSION(3,5,2), MAKE_VERSION(3,5,1), UG_Exact }, { MAKE_VERSION(3,5,2), MAKE_VERSION(3,5,1), UG_Exact },
......
...@@ -65,6 +65,7 @@ Item::Item(): ...@@ -65,6 +65,7 @@ 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;
} }
/* /*
...@@ -83,7 +84,8 @@ Item::Item(THD *thd, Item *item): ...@@ -83,7 +84,8 @@ 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,6 +107,11 @@ public: ...@@ -107,6 +107,11 @@ 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 &);
...@@ -142,6 +147,7 @@ public: ...@@ -142,6 +147,7 @@ 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();
...@@ -327,6 +333,11 @@ public: ...@@ -327,6 +333,11 @@ public:
cleanup(); cleanup();
delete this; delete this;
} }
virtual bool set_flags_processor(byte *args)
{
this->item_flags|= *((uint8*)args);
return false;
}
}; };
......
...@@ -51,8 +51,8 @@ bool Item_str_buff::cmp(void) ...@@ -51,8 +51,8 @@ bool Item_str_buff::cmp(void)
String *res; String *res;
bool tmp; bool tmp;
res=item->val_str(&tmp_value); if ((res=item->val_str(&tmp_value)))
res->length(min(res->length(), value.alloced_length())); res->length(min(res->length(), value.alloced_length()));
if (null_value != item->null_value) if (null_value != item->null_value)
{ {
if ((null_value= item->null_value)) if ((null_value= item->null_value))
......
...@@ -2096,7 +2096,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, ...@@ -2096,7 +2096,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
return (Field*) 0; return (Field*) 0;
} }
bool allow_rowid= tables && !tables->next; // Only one table bool allow_rowid= tables && !tables->next; // Only one table
for (; tables ; tables=tables->next) uint table_idx= 0;
for (; tables ; tables=tables->next, table_idx++)
{ {
if (!tables->table) if (!tables->table)
{ {
...@@ -2124,7 +2125,9 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, ...@@ -2124,7 +2125,9 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
name,thd->where); name,thd->where);
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)
......
...@@ -1636,11 +1636,22 @@ bool select_insert::send_data(List<Item> &values) ...@@ -1636,11 +1636,22 @@ bool select_insert::send_data(List<Item> &values)
store_values(values); store_values(values);
error=thd->net.report_error || write_record(table,&info); error=thd->net.report_error || write_record(table,&info);
thd->count_cuted_fields= CHECK_FIELD_IGNORE; thd->count_cuted_fields= CHECK_FIELD_IGNORE;
if (!error && table->next_number_field) // Clear for next record
if (!error)
{ {
table->next_number_field->reset(); /*
if (! last_insert_id && thd->insert_id_used) Restore fields of the record since it is possible that they were
last_insert_id=thd->insert_id(); changed by ON DUPLICATE KEY UPDATE clause.
*/
if (info.handle_duplicates == DUP_UPDATE)
restore_record(table, default_values);
if (table->next_number_field) // Clear for next record
{
table->next_number_field->reset();
if (! last_insert_id && thd->insert_id_used)
last_insert_id=thd->insert_id();
}
} }
DBUG_RETURN(error); DBUG_RETURN(error);
} }
......
...@@ -1943,6 +1943,16 @@ mysql_execute_command(THD *thd) ...@@ -1943,6 +1943,16 @@ 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
we create a new TABLE_LIST containing all referenced tables
and set local variable 'tables' to point to this list.
*/
if ((&lex->select_lex != lex->all_selects_list ||
lex->time_zone_tables_used) &&
lex->unit.create_total_list(thd, lex, &tables))
DBUG_VOID_RETURN;
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
if (thd->slave_thread) if (thd->slave_thread)
{ {
...@@ -1993,14 +2003,6 @@ mysql_execute_command(THD *thd) ...@@ -1993,14 +2003,6 @@ mysql_execute_command(THD *thd)
} }
#endif /* !HAVE_REPLICATION */ #endif /* !HAVE_REPLICATION */
/* When subselects or time_zone info is used in a query
* we create a new TABLE_LIST containing all referenced tables
* and set local variable 'tables' to point to this list. */
if ((&lex->select_lex != lex->all_selects_list ||
lex->time_zone_tables_used) &&
lex->unit.create_total_list(thd, lex, &tables))
DBUG_VOID_RETURN;
/* /*
When option readonly is set deny operations which change tables. When option readonly is set deny operations which change tables.
Except for the replication thread and the 'super' users. Except for the replication thread and the 'super' users.
...@@ -2854,17 +2856,14 @@ unsent_create_error: ...@@ -2854,17 +2856,14 @@ unsent_create_error:
if ((res= open_and_lock_tables(thd, tables))) if ((res= open_and_lock_tables(thd, tables)))
break; break;
TABLE *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;
first_local_table->next= 0;
if (!(res= mysql_prepare_insert(thd, tables, first_local_table, if (!(res= mysql_prepare_insert(thd, tables, first_local_table,
table, lex->field_list, 0, tables->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(table, &lex->field_list, (result= new select_insert(tables->table, &lex->field_list,
&lex->update_list, &lex->value_list, &lex->update_list, &lex->value_list,
lex->duplicates, lex->ignore))) lex->duplicates, lex->ignore)))
{ {
...@@ -2877,7 +2876,7 @@ unsent_create_error: ...@@ -2877,7 +2876,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;
table->insert_values= 0; tables->table->insert_values= 0;
if (thd->net.report_error) if (thd->net.report_error)
res= -1; res= -1;
} }
......
...@@ -4239,9 +4239,24 @@ insert_update_elem: ...@@ -4239,9 +4239,24 @@ 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