mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge epotemkin@bk-internal.mysql.com:/home/bk/mysql-5.0
into moonbone.local:/work/mysql-5.0-merge
This commit is contained in:
@ -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
|
||||||
|
@ -634,3 +634,18 @@ ff1 ff2
|
|||||||
1 2
|
1 2
|
||||||
2 1
|
2 1
|
||||||
drop table t1, t2;
|
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;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
DROP TABLE IF EXISTS t1;
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B));
|
CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B));
|
||||||
INSERT t1 VALUES (1,2,10), (3,4,20);
|
INSERT t1 VALUES (1,2,10), (3,4,20);
|
||||||
INSERT t1 VALUES (5,6,30) ON DUPLICATE KEY UPDATE c=c+100;
|
INSERT t1 VALUES (5,6,30) ON DUPLICATE KEY UPDATE c=c+100;
|
||||||
|
@ -173,3 +173,17 @@ insert into t1 values (1),(1),(2);
|
|||||||
insert into t2(ff1) select f1 from t1 on duplicate key update ff2=ff2+1;
|
insert into t2(ff1) select f1 from t1 on duplicate key update ff2=ff2+1;
|
||||||
select * from t2;
|
select * from t2;
|
||||||
drop table t1, 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;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
--disable_warnings
|
--disable_warnings
|
||||||
DROP TABLE IF EXISTS t1;
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B));
|
CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B));
|
||||||
|
@ -338,6 +338,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -358,7 +359,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;
|
||||||
|
11
sql/item.h
11
sql/item.h
@ -225,6 +225,11 @@ typedef Item* (Item::*Item_transformer) (byte *arg);
|
|||||||
|
|
||||||
typedef void (*Cond_traverser) (const Item *item, void *arg);
|
typedef void (*Cond_traverser) (const Item *item, void *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 &);
|
||||||
@ -272,6 +277,7 @@ public:
|
|||||||
my_bool is_autogenerated_name; /* indicate was name of this Item
|
my_bool is_autogenerated_name; /* indicate was name of this Item
|
||||||
autogenerated or set by user */
|
autogenerated or set by user */
|
||||||
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();
|
||||||
@ -584,6 +590,11 @@ public:
|
|||||||
cleanup();
|
cleanup();
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
virtual bool set_flags_processor(byte *args)
|
||||||
|
{
|
||||||
|
this->item_flags|= *((uint8*)args);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool is_splocal() { return 0; } /* Needed for error checking */
|
virtual bool is_splocal() { return 0; } /* Needed for error checking */
|
||||||
};
|
};
|
||||||
|
@ -2626,7 +2626,6 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||||||
uint length=(uint) strlen(name);
|
uint length=(uint) strlen(name);
|
||||||
char name_buff[NAME_LEN+1];
|
char name_buff[NAME_LEN+1];
|
||||||
|
|
||||||
|
|
||||||
if (item->cached_table)
|
if (item->cached_table)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -2693,10 +2692,13 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||||||
db= name_buff;
|
db= name_buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool search_global= item->item_flags & MY_ITEM_PREFER_1ST_TABLE;
|
||||||
if (table_name && table_name[0])
|
if (table_name && table_name[0])
|
||||||
{ /* Qualified field */
|
{ /* Qualified field */
|
||||||
bool found_table=0;
|
bool found_table=0;
|
||||||
for (; tables; tables= tables->next_local)
|
uint table_idx= 0;
|
||||||
|
for (; tables; tables= search_global?tables->next_global:tables->next_local,
|
||||||
|
table_idx++)
|
||||||
{
|
{
|
||||||
/* TODO; Ensure that db and tables->db always points to something ! */
|
/* TODO; Ensure that db and tables->db always points to something ! */
|
||||||
if (!my_strcasecmp(table_alias_charset, tables->alias, table_name) &&
|
if (!my_strcasecmp(table_alias_charset, tables->alias, table_name) &&
|
||||||
@ -2732,6 +2734,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||||||
return (Field*) 0;
|
return (Field*) 0;
|
||||||
}
|
}
|
||||||
found=find;
|
found=find;
|
||||||
|
if (table_idx == 0 && item->item_flags & MY_ITEM_PREFER_1ST_TABLE)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2756,9 +2760,10 @@ 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_local; // Only one table
|
bool allow_rowid= tables && !tables->next_local; // Only one table
|
||||||
for (; tables ; tables= tables->next_local)
|
uint table_idx= 0;
|
||||||
|
for (; tables ; tables= search_global?tables->next_global:tables->next_local,
|
||||||
|
table_idx++)
|
||||||
{
|
{
|
||||||
if (!tables->table && !tables->ancestor)
|
if (!tables->table && !tables->ancestor)
|
||||||
{
|
{
|
||||||
@ -2793,7 +2798,9 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||||||
my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where);
|
my_error(ER_NON_UNIQ_ERROR, MYF(0), 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)
|
||||||
|
@ -6120,9 +6120,24 @@ insert_update_elem:
|
|||||||
simple_ident_nospvar equal expr_or_default
|
simple_ident_nospvar 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:
|
||||||
|
Reference in New Issue
Block a user