Commit 577cb323 authored by unknown's avatar unknown

Merge mysql.com:/home/pz/mysql/mysql-4.1-root

into mysql.com:/home/pz/mysql/mysql-4.1


sql/mysql_priv.h:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
parents 526ff493 265bf238
......@@ -140,6 +140,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef,
share->auto_key= create_info->auto_key;
share->auto_key_type= create_info->auto_key_type;
share->auto_increment= create_info->auto_increment;
/* Must be allocated separately for rename to work */
if (!(share->name= my_strdup(name,MYF(0))))
{
my_free((gptr) share,MYF(0));
......
......@@ -62,7 +62,8 @@ int heap_update(HP_INFO *info, const byte *old, const byte *heap_new)
/* we don't need to delete non-inserted key from rb-tree */
if ((*keydef->write_key)(info, keydef, old, pos))
{
if (++(share->records) == share->blength) share->blength+= share->blength;
if (++(share->records) == share->blength)
share->blength+= share->blength;
DBUG_RETURN(my_errno);
}
keydef--;
......@@ -78,6 +79,7 @@ int heap_update(HP_INFO *info, const byte *old, const byte *heap_new)
keydef--;
}
}
if (++(share->records) == share->blength) share->blength+= share->blength;
if (++(share->records) == share->blength)
share->blength+= share->blength;
DBUG_RETURN(my_errno);
} /* heap_update */
......@@ -155,7 +155,7 @@ static byte *next_free_record_pos(HP_SHARE *info)
/* Write a hash-key to the hash-index */
int hp_write_key(HP_INFO *info, HP_KEYDEF *keyinfo,
const byte *record, byte *recpos)
const byte *record, byte *recpos)
{
HP_SHARE *share = info->s;
int flag;
......
......@@ -109,7 +109,7 @@
#define ER_CANT_REMOVE_ALL_FIELDS 1090
#define ER_CANT_DROP_FIELD_OR_KEY 1091
#define ER_INSERT_INFO 1092
#define ER_INSERT_TABLE_USED 1093
#define ER_UPDATE_TABLE_USED 1093
#define ER_NO_SUCH_THREAD 1094
#define ER_KILL_DENIED_ERROR 1095
#define ER_NO_TABLES_USED 1096
......@@ -264,4 +264,5 @@
#define ER_ILLEGAL_REFERENCE 1245
#define ER_DERIVED_MUST_HAVE_ALIAS 1246
#define ER_SELECT_REDUCED 1247
#define ER_ERROR_MESSAGES 248
#define ER_TABLENAME_NOT_ALLOWED_HERE 1248
#define ER_ERROR_MESSAGES 249
......@@ -19,7 +19,7 @@ TZ=GMT-3; export TZ # for UNIX_TIMESTAMP tests to work
# Program Definitions
#--
PATH=/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin:/usr/bin/X11
PATH=/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin:/usr/bin/X11:$PATH
MASTER_40_ARGS="--rpl-recovery-rank=1 --init-rpl-role=master"
# Standard functions
......@@ -319,8 +319,8 @@ while test $# -gt 0; do
VALGRIND="valgrind --alignment=8 --leak-check=yes"
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc"
SLEEP_TIME_AFTER_RESTART=120
SLEEP_TIME_FOR_DELETE=120
SLEEP_TIME_AFTER_RESTART=60
SLEEP_TIME_FOR_DELETE=60
;;
--valgrind-options=*)
TMP=`$ECHO "$1" | $SED -e "s;--valgrind-options=;;"`
......
DROP TABLE IF EXISTS t1;
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 (5,6,30) ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
a b c
1 2 10
3 4 20
5 6 30
INSERT t1 VALUES (5,7,40) ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
a b c
1 2 10
3 4 20
5 6 130
INSERT t1 VALUES (8,4,50) ON DUPLICATE KEY UPDATE c=c+1000;
SELECT * FROM t1;
a b c
1 2 10
3 4 1020
5 6 130
INSERT t1 VALUES (1,4,60) ON DUPLICATE KEY UPDATE c=c+10000;
SELECT * FROM t1;
a b c
1 2 10010
3 4 1020
5 6 130
INSERT t1 VALUES (1,9,70) ON DUPLICATE KEY UPDATE c=c+100000, b=4;
Duplicate entry '4' for key 2
SELECT * FROM t1;
a b c
1 2 10010
3 4 1020
5 6 130
TRUNCATE TABLE t1;
INSERT t1 VALUES (1,2,10), (3,4,20);
INSERT t1 VALUES (5,6,30), (7,4,40), (8,9,60) ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
a b c
1 2 10
3 4 120
5 6 30
8 9 60
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
SELECT * FROM t1;
a b c
1 2 10
3 4 120
5 0 30
8 9 60
DROP TABLE t1;
SELECT (1,2,3)=(1,2,3);
(1,2,3)=(1,2,3)
SELECT ROW(1,2,3)=ROW(1,2,3);
ROW(1,2,3)=ROW(1,2,3)
1
SELECT (2,2,3)=(1+1,2,3);
(2,2,3)=(1+1,2,3)
SELECT ROW(2,2,3)=ROW(1+1,2,3);
ROW(2,2,3)=ROW(1+1,2,3)
1
SELECT (1,2,3)=(1+1,2,3);
(1,2,3)=(1+1,2,3)
SELECT ROW(1,2,3)=ROW(1+1,2,3);
ROW(1,2,3)=ROW(1+1,2,3)
0
SELECT (1,2,3)<(1+1,2,3);
(1,2,3)<(1+1,2,3)
SELECT ROW(1,2,3)<ROW(1+1,2,3);
ROW(1,2,3)<ROW(1+1,2,3)
1
SELECT (1,2,3)>(1+1,2,3);
(1,2,3)>(1+1,2,3)
SELECT ROW(1,2,3)>ROW(1+1,2,3);
ROW(1,2,3)>ROW(1+1,2,3)
0
SELECT (1,2,3)<=(1+1,2,3);
(1,2,3)<=(1+1,2,3)
SELECT ROW(1,2,3)<=ROW(1+1,2,3);
ROW(1,2,3)<=ROW(1+1,2,3)
1
SELECT (1,2,3)>=(1+1,2,3);
(1,2,3)>=(1+1,2,3)
SELECT ROW(1,2,3)>=ROW(1+1,2,3);
ROW(1,2,3)>=ROW(1+1,2,3)
0
SELECT (1,2,3)<>(1+1,2,3);
(1,2,3)<>(1+1,2,3)
SELECT ROW(1,2,3)<>ROW(1+1,2,3);
ROW(1,2,3)<>ROW(1+1,2,3)
1
SELECT (NULL,2,3)=(NULL,2,3);
(NULL,2,3)=(NULL,2,3)
SELECT ROW(NULL,2,3)=ROW(NULL,2,3);
ROW(NULL,2,3)=ROW(NULL,2,3)
NULL
SELECT (NULL,2,3)<=>(NULL,2,3);
(NULL,2,3)<=>(NULL,2,3)
SELECT ROW(NULL,2,3)<=>ROW(NULL,2,3);
ROW(NULL,2,3)<=>ROW(NULL,2,3)
1
SELECT (1,2,(3,4,5))=(1,2,(3,4,5));
(1,2,(3,4,5))=(1,2,(3,4,5))
SELECT ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5));
ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5))
1
SELECT ('test',2,3.33)=('test',2,3.33);
('test',2,3.33)=('test',2,3.33)
SELECT ROW('test',2,3.33)=ROW('test',2,3.33);
ROW('test',2,3.33)=ROW('test',2,3.33)
1
SELECT ('test',2,3.33)=('test',2,3.33,4);
SELECT ROW('test',2,3.33)=ROW('test',2,3.33,4);
Cardinality error (more/less than 3 columns)
drop table if exists t1;
create table t1 ( a int, b int, c int);
insert into t1 values (1,2,3), (2,3,1), (3,2,1);
select * from t1 where (1,2,3)=(a,b,c);
select * from t1 where ROW(1,2,3)=ROW(a,b,c);
a b c
1 2 3
select * from t1 where (0,2,3)=(a,b,c);
select * from t1 where ROW(0,2,3)=ROW(a,b,c);
a b c
select * from t1 where (1,2,3)<(a,b,c);
select * from t1 where ROW(1,2,3)<ROW(a,b,c);
a b c
2 3 1
3 2 1
drop table t1;
select (1,1);
select ROW(1,1);
Cardinality error (more/less than 1 columns)
drop table if exists t1;
create table t1 (i int);
select 1 from t1 where (1,1);
select 1 from t1 where ROW(1,1);
Cardinality error (more/less than 1 columns)
select count(*) from t1 order by (1,1);
select count(*) from t1 order by ROW(1,1);
Cardinality error (more/less than 1 columns)
drop table t1;
......@@ -412,7 +412,7 @@ a b
1 11
2 12
update t1 set b= (select b from t1);
INSERT TABLE 't1' isn't allowed in FROM table list
You can't specify target table 't1' for update in FROM clause
update t1 set b= (select b from t2);
Subselect returns more than 1 record
update t1 set b= (select b from t2 where t1.a = t2.a);
......@@ -435,7 +435,7 @@ select * from t1 where b = (select b from t2 where t1.a = t2.a);
a b
2 12
delete from t1 where b = (select b from t1);
INSERT TABLE 't1' isn't allowed in FROM table list
You can't specify target table 't1' for update in FROM clause
delete from t1 where b = (select b from t2);
Subselect returns more than 1 record
delete from t1 where b = (select b from t2 where t1.a = t2.a);
......@@ -462,7 +462,7 @@ a b
22 11
2 12
delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
INSERT TABLE 't12' isn't allowed in FROM table list
You can't specify target table 't12' for update in FROM clause
delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2);
Subselect returns more than 1 record
delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
......@@ -481,7 +481,7 @@ create table t3 (a int);
insert into t2 values (1);
insert into t3 values (1),(2);
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
INSERT TABLE 't1' isn't allowed in FROM table list
You can't specify target table 't1' for update in FROM clause
INSERT INTO t1 (x) VALUES ((SELECT a FROM t3));
Subselect returns more than 1 record
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
......@@ -502,7 +502,7 @@ x
3
3
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
INSERT TABLE 't1' isn't allowed in FROM table list
You can't specify target table 't1' for update in FROM clause
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
select * from t1;
x
......@@ -520,7 +520,7 @@ insert into t3 values (1),(2);
select * from t1;
x y
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
INSERT TABLE 't1' isn't allowed in FROM table list
You can't specify target table 't1' for update in FROM clause
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
Subselect returns more than 1 record
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
......@@ -584,7 +584,7 @@ SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 2);
id
2
INSERT INTO t VALUES ((SELECT * FROM t));
INSERT TABLE 't' isn't allowed in FROM table list
You can't specify target table 't' for update in FROM clause
SELECT * FROM t;
id
1
......
......@@ -84,6 +84,8 @@ a b
3 c
2 b
1 a
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b;
Table 't1' from one of SELECT's can not be used in order clause
explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
......
DROP TABLE IF EXISTS t1;
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 (5,6,30) ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
INSERT t1 VALUES (5,7,40) ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
INSERT t1 VALUES (8,4,50) ON DUPLICATE KEY UPDATE c=c+1000;
SELECT * FROM t1;
INSERT t1 VALUES (1,4,60) ON DUPLICATE KEY UPDATE c=c+10000;
SELECT * FROM t1;
-- error 1062
INSERT t1 VALUES (1,9,70) ON DUPLICATE KEY UPDATE c=c+100000, b=4;
SELECT * FROM t1;
TRUNCATE TABLE t1;
INSERT t1 VALUES (1,2,10), (3,4,20);
INSERT t1 VALUES (5,6,30), (7,4,40), (8,9,60) ON DUPLICATE KEY UPDATE c=c+100;
SELECT * FROM t1;
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
SELECT * FROM t1;
DROP TABLE t1;
SELECT (1,2,3)=(1,2,3);
SELECT (2,2,3)=(1+1,2,3);
SELECT (1,2,3)=(1+1,2,3);
SELECT (1,2,3)<(1+1,2,3);
SELECT (1,2,3)>(1+1,2,3);
SELECT (1,2,3)<=(1+1,2,3);
SELECT (1,2,3)>=(1+1,2,3);
SELECT (1,2,3)<>(1+1,2,3);
SELECT (NULL,2,3)=(NULL,2,3);
SELECT (NULL,2,3)<=>(NULL,2,3);
SELECT (1,2,(3,4,5))=(1,2,(3,4,5));
SELECT ('test',2,3.33)=('test',2,3.33);
SELECT ROW(1,2,3)=ROW(1,2,3);
SELECT ROW(2,2,3)=ROW(1+1,2,3);
SELECT ROW(1,2,3)=ROW(1+1,2,3);
SELECT ROW(1,2,3)<ROW(1+1,2,3);
SELECT ROW(1,2,3)>ROW(1+1,2,3);
SELECT ROW(1,2,3)<=ROW(1+1,2,3);
SELECT ROW(1,2,3)>=ROW(1+1,2,3);
SELECT ROW(1,2,3)<>ROW(1+1,2,3);
SELECT ROW(NULL,2,3)=ROW(NULL,2,3);
SELECT ROW(NULL,2,3)<=>ROW(NULL,2,3);
SELECT ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5));
SELECT ROW('test',2,3.33)=ROW('test',2,3.33);
-- error 1239
SELECT ('test',2,3.33)=('test',2,3.33,4);
SELECT ROW('test',2,3.33)=ROW('test',2,3.33,4);
drop table if exists t1;
create table t1 ( a int, b int, c int);
insert into t1 values (1,2,3), (2,3,1), (3,2,1);
select * from t1 where (1,2,3)=(a,b,c);
select * from t1 where (0,2,3)=(a,b,c);
select * from t1 where (1,2,3)<(a,b,c);
select * from t1 where ROW(1,2,3)=ROW(a,b,c);
select * from t1 where ROW(0,2,3)=ROW(a,b,c);
select * from t1 where ROW(1,2,3)<ROW(a,b,c);
drop table t1;
-- error 1239
select (1,1);
select ROW(1,1);
drop table if exists t1;
create table t1 (i int);
-- error 1239
select 1 from t1 where (1,1);
select 1 from t1 where ROW(1,1);
-- error 1239
select count(*) from t1 order by (1,1);
select count(*) from t1 order by ROW(1,1);
#TODO remove comments after parser fixing
#-- error 1239
#select count(*) from t1 order by i having (1,1);
......
......@@ -20,6 +20,8 @@ select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 g
(select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4;
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1);
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
--error 1248
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b;
explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
#(select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2;
select found_rows();
......
......@@ -536,8 +536,9 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
Item **refer= (Item **)not_found_item;
// Prevent using outer fields in subselects, that is not supported now
if (thd->lex.current_select->linkage != DERIVED_TABLE_TYPE)
for (SELECT_LEX *sl= thd->lex.current_select->outer_select();
SELECT_LEX *cursel=(SELECT_LEX *) thd->lex.current_select;
if (cursel->linkage != DERIVED_TABLE_TYPE)
for (SELECT_LEX *sl=cursel->outer_select();
sl;
sl= sl->outer_select())
{
......@@ -573,7 +574,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
if (r->check_cols(1) || r->fix_fields(thd, tables, ref))
return 1;
r->depended_from= last;
thd->lex.current_select->mark_as_dependent(last);
cursel->mark_as_dependent(last);
thd->add_possible_loop(r);
return 0;
}
......
......@@ -98,6 +98,7 @@ class Item {
// Row emulation
virtual uint cols() { return 1; }
virtual Item* el(uint i) { return this; }
virtual Item** addr(uint i) { return 0; }
virtual bool check_cols(uint c);
};
......
......@@ -106,7 +106,8 @@ void Item_bool_func2::fix_length_and_dec()
{
if (convert_constant_item(field,&args[1]))
{
arg_store.set_compare_func(this, INT_RESULT); // Works for all types.
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
return;
}
}
......@@ -118,7 +119,8 @@ void Item_bool_func2::fix_length_and_dec()
{
if (convert_constant_item(field,&args[0]))
{
arg_store.set_compare_func(this, INT_RESULT); // Works for all types.
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
return;
}
}
......@@ -133,8 +135,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
1:0];
if (type == ROW_RESULT)
{
uint n= args[0]->cols();
if (n != args[1]->cols())
uint n= (*a)->cols();
if (n != (*b)->cols())
{
my_error(ER_CARDINALITY_COL, MYF(0), n);
comparators= 0;
......@@ -142,11 +144,7 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
}
if ((comparators= (Arg_comparator *) sql_alloc(sizeof(Arg_comparator)*n)))
for (uint i=0; i < n; i++)
{
comparators[i].set_arg(0, args[0]->el(i));
comparators[i].set_arg(1, args[1]->el(i));
comparators[i].set_compare_func(owner);
}
comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i));
else
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
......@@ -160,9 +158,9 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
int Arg_comparator::compare_string()
{
String *res1,*res2;
if ((res1= args[0]->val_str(&owner->tmp_value1)))
if ((res1= (*a)->val_str(&owner->tmp_value1)))
{
if ((res2= args[1]->val_str(&owner->tmp_value2)))
if ((res2= (*b)->val_str(&owner->tmp_value2)))
{
owner->null_value= 0;
return owner->binary() ? stringcmp(res1,res2) : sortcmp(res1,res2);
......@@ -175,8 +173,8 @@ int Arg_comparator::compare_string()
int Arg_comparator::compare_e_string()
{
String *res1,*res2;
res1= args[0]->val_str(&owner->tmp_value1);
res2= args[1]->val_str(&owner->tmp_value2);
res1= (*a)->val_str(&owner->tmp_value1);
res2= (*b)->val_str(&owner->tmp_value2);
if (!res1 || !res2)
return test(res1 == res2);
return (owner->binary() ? test(stringcmp(res1, res2) == 0) :
......@@ -186,11 +184,11 @@ int Arg_comparator::compare_e_string()
int Arg_comparator::compare_real()
{
double val1= args[0]->val();
if (!args[0]->null_value)
double val1= (*a)->val();
if (!(*a)->null_value)
{
double val2= args[1]->val();
if (!args[1]->null_value)
double val2= (*b)->val();
if (!(*b)->null_value)
{
owner->null_value= 0;
if (val1 < val2) return -1;
......@@ -204,20 +202,20 @@ int Arg_comparator::compare_real()
int Arg_comparator::compare_e_real()
{
double val1= args[0]->val();
double val2= args[1]->val();
if (args[0]->null_value || args[1]->null_value)
return test(args[0]->null_value && args[1]->null_value);
double val1= (*a)->val();
double val2= (*b)->val();
if ((*a)->null_value || (*b)->null_value)
return test((*a)->null_value && (*b)->null_value);
return test(val1 == val2);
}
int Arg_comparator::compare_int()
{
longlong val1= args[0]->val_int();
if (!args[0]->null_value)
longlong val1= (*a)->val_int();
if (!(*a)->null_value)
{
longlong val2= args[1]->val_int();
if (!args[1]->null_value)
longlong val2= (*b)->val_int();
if (!(*b)->null_value)
{
owner->null_value= 0;
if (val1 < val2) return -1;
......@@ -231,10 +229,10 @@ int Arg_comparator::compare_int()
int Arg_comparator::compare_e_int()
{
longlong val1= args[0]->val_int();
longlong val2= args[1]->val_int();
if (args[0]->null_value || args[1]->null_value)
return test(args[0]->null_value && args[1]->null_value);
longlong val1= (*a)->val_int();
longlong val2= (*b)->val_int();
if ((*a)->null_value || (*b)->null_value)
return test((*a)->null_value && (*b)->null_value);
return test(val1 == val2);
}
......@@ -242,7 +240,7 @@ int Arg_comparator::compare_e_int()
int Arg_comparator::compare_row()
{
int res= 0;
uint n= args[0]->cols();
uint n= (*a)->cols();
for (uint i= 0; i<n; i++)
{
if ((res= comparators[i].compare()))
......@@ -256,7 +254,7 @@ int Arg_comparator::compare_row()
int Arg_comparator::compare_e_row()
{
int res= 0;
uint n= args[0]->cols();
uint n= (*a)->cols();
for (uint i= 0; i<n; i++)
{
if ((res= comparators[i].compare()))
......@@ -268,7 +266,7 @@ int Arg_comparator::compare_e_row()
longlong Item_func_eq::val_int()
{
int value= arg_store.compare();
int value= cmp.compare();
return value == 0 ? 1 : 0;
}
......@@ -283,39 +281,39 @@ void Item_func_equal::fix_length_and_dec()
longlong Item_func_equal::val_int()
{
return arg_store.compare();
return cmp.compare();
}
longlong Item_func_ne::val_int()
{
int value= arg_store.compare();
int value= cmp.compare();
return value != 0 && !null_value ? 1 : 0;
}
longlong Item_func_ge::val_int()
{
int value= arg_store.compare();
int value= cmp.compare();
return value >= 0 ? 1 : 0;
}
longlong Item_func_gt::val_int()
{
int value= arg_store.compare();
int value= cmp.compare();
return value > 0 ? 1 : 0;
}
longlong Item_func_le::val_int()
{
int value= arg_store.compare();
int value= cmp.compare();
return value <= 0 && !null_value ? 1 : 0;
}
longlong Item_func_lt::val_int()
{
int value= arg_store.compare();
int value= cmp.compare();
return value < 0 && !null_value ? 1 : 0;
}
......@@ -664,7 +662,7 @@ double
Item_func_nullif::val()
{
double value;
if (!arg_store.compare() || null_value)
if (!cmp.compare() || null_value)
{
null_value=1;
return 0.0;
......@@ -678,7 +676,7 @@ longlong
Item_func_nullif::val_int()
{
longlong value;
if (!arg_store.compare() || null_value)
if (!cmp.compare() || null_value)
{
null_value=1;
return 0;
......@@ -692,7 +690,7 @@ String *
Item_func_nullif::val_str(String *str)
{
String *res;
if (!arg_store.compare() || null_value)
if (!cmp.compare() || null_value)
{
null_value=1;
return 0;
......
......@@ -21,6 +21,63 @@
#pragma interface /* gcc class implementation */
#endif
extern Item_result item_cmp_type(Item_result a,Item_result b);
class Item_bool_func2;
class Arg_comparator;
typedef int (Arg_comparator::*arg_cmp_func)();
class Arg_comparator: public Sql_alloc
{
Item **a, **b;
arg_cmp_func func;
Item_bool_func2 *owner;
Arg_comparator *comparators; // used only for compare_row()
public:
Arg_comparator() {};
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2) {};
inline void seta(Item **item) { a= item; }
inline void setb(Item **item) { b= item; }
int set_compare_func(Item_bool_func2 *owner, Item_result type);
inline int set_compare_func(Item_bool_func2 *owner)
{
return set_compare_func(owner, item_cmp_type((*a)->result_type(),
(*b)->result_type()));
}
inline int set_cmp_func(Item_bool_func2 *owner,
Item **a1, Item **a2,
Item_result type)
{
a= a1;
b= a2;
return set_compare_func(owner, type);
}
inline int set_cmp_func(Item_bool_func2 *owner,
Item **a1, Item **a2)
{
return set_cmp_func(owner, a1, a2, item_cmp_type((*a1)->result_type(),
(*a2)->result_type()));
}
inline int compare() { return (this->*func)(); }
int compare_string(); // compare args[0] & args[1]
int compare_real(); // compare args[0] & args[1]
int compare_int(); // compare args[0] & args[1]
int compare_row(); // compare args[0] & args[1]
int compare_e_string(); // compare args[0] & args[1]
int compare_e_real(); // compare args[0] & args[1]
int compare_e_int(); // compare args[0] & args[1]
int compare_e_row(); // compare args[0] & args[1]
static arg_cmp_func comparator_matrix [4][2];
friend class Item_func;
};
class Item_bool_func :public Item_int_func
{
public:
......@@ -33,13 +90,15 @@ class Item_bool_func :public Item_int_func
class Item_bool_func2 :public Item_int_func
{ /* Bool with 2 string args */
protected:
Arg_comparator cmp;
String tmp_value1,tmp_value2;
public:
Item_bool_func2(Item *a,Item *b) :Item_int_func(a,b) {}
Item_bool_func2(Item *a,Item *b):
Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1) {}
void fix_length_and_dec();
void set_cmp_func()
{
arg_store.set_compare_func(this);
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1);
}
optimize_type select_optimize() const { return OPTIMIZE_OP; }
virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
......
......@@ -28,48 +28,10 @@ extern "C" /* Bug in BSDI include file */
}
#endif
extern Item_result item_cmp_type(Item_result a,Item_result b);
class Item_bool_func2;
class Arg_comparator;
typedef int (Arg_comparator::*arg_cmp_func)();
class Arg_comparator: public Sql_alloc
{
Item *args[2];
arg_cmp_func func;
Item_bool_func2 *owner;
Arg_comparator *comparators; // used only for compare_row()
public:
inline void set_arg(int i, Item *item) { args[i]= item; }
int set_compare_func(Item_bool_func2 *owner, Item_result type);
inline int set_compare_func(Item_bool_func2 *owner)
{
return set_compare_func(owner, item_cmp_type(args[0]->result_type(),
args[1]->result_type()));
}
inline int compare() { return (this->*func)(); }
int compare_string(); // compare args[0] & args[1]
int compare_real(); // compare args[0] & args[1]
int compare_int(); // compare args[0] & args[1]
int compare_row(); // compare args[0] & args[1]
int compare_e_string(); // compare args[0] & args[1]
int compare_e_real(); // compare args[0] & args[1]
int compare_e_int(); // compare args[0] & args[1]
int compare_e_row(); // compare args[0] & args[1]
static arg_cmp_func comparator_matrix [4][2];
friend class Item_func;
};
class Item_func :public Item_result_field
{
protected:
Item **args;
Arg_comparator arg_store;
Item **args, *tmp_arg[2];
uint allowed_arg_cols;
public:
uint arg_count;
......@@ -96,14 +58,14 @@ class Item_func :public Item_result_field
Item_func(Item *a):
allowed_arg_cols(1), arg_count(1)
{
args= arg_store.args;
args= tmp_arg;
args[0]= a;
with_sum_func= a->with_sum_func;
}
Item_func(Item *a,Item *b):
allowed_arg_cols(1), arg_count(2)
{
args= arg_store.args;
args= tmp_arg;
args[0]= a; args[1]= b;
with_sum_func= a->with_sum_func || b->with_sum_func;
}
......
......@@ -61,5 +61,6 @@ class Item_row: public Item
virtual uint cols() { return arg_count; }
virtual Item* el(uint i) { return items[i]; }
virtual Item** addr(uint i) { return items + i; }
virtual bool check_cols(uint c);
};
......@@ -41,7 +41,7 @@ Item_sum::Item_sum(List<Item> &list)
list.empty(); // Fields are used
}
inline void Item_sum::mark_as_sum_func()
void Item_sum::mark_as_sum_func()
{
current_thd->lex.current_select->with_sum_func= with_sum_func= 1;
}
......
......@@ -34,7 +34,7 @@ class Item_sum :public Item_result_field
uint arg_count;
bool quick_group; /* If incremental update of fields */
inline void mark_as_sum_func();
void mark_as_sum_func();
Item_sum() : arg_count(0),quick_group(1)
{
mark_as_sum_func();
......
......@@ -431,7 +431,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
bool drop_primary,
enum enum_duplicates handle_duplicates,
enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
bool simple_alter=0);
bool simple_alter=0);
bool mysql_rename_table(enum db_type base,
const char *old_db,
const char * old_name,
......@@ -442,11 +442,12 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
List<Alter_drop> &drop_list);
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &values,COND *conds,
List<Item> &values,COND *conds,
ORDER *order, ha_rows limit,
enum enum_duplicates handle_duplicates);
int mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, enum_duplicates flag);
List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag);
void kill_delayed_threads(void);
int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, ORDER *order,
ha_rows rows, ulong options);
......
......@@ -103,7 +103,7 @@ v/*
"Nen-B mon vymazat vechny poloky s ALTER TABLE. Pouijte DROP TABLE",
"Nemohu zru-Bit '%-.64s' (provst DROP). Zkontrolujte, zda neexistuj zznamy/kle",
"Z-Bznam: %ld Zdvojench: %ld Varovn: %ld",
"INSERT TABLE '%-.64s' nen-B dovoleno v seznamu tabulek FROM",
"You can't specify target table '%-.64s' for update in FROM clause",
"Nezn-Bm identifikace threadu: %lu",
"Nejste vlastn-Bkem threadu %lu",
"Nejsou pou-Bity dn tabulky",
......@@ -258,3 +258,4 @@ v/*
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -97,7 +97,7 @@
"Man kan ikke slette alle felter med ALTER TABLE. Brug DROP TABLE i stedet.",
"Kan ikke udføre DROP '%-.64s'. Undersøg om feltet/nøglen eksisterer.",
"Poster: %ld Ens: %ld Advarsler: %ld",
"INSERT TABLE '%-.64s' er ikke tilladt i FROM tabel liste",
"You can't specify target table '%-.64s' for update in FROM clause",
"Ukendt tråd id: %lu",
"Du er ikke ejer af tråden %lu",
"Ingen tabeller i brug",
......@@ -252,3 +252,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -105,7 +105,7 @@
"Het is niet mogelijk alle velden te verwijderen met ALTER TABLE. Gebruik a.u.b. DROP TABLE hiervoor!",
"Kan '%-.64s' niet weggooien. Controleer of het veld of de zoeksleutel daadwerkelijk bestaat.",
"Records: %ld Dubbel: %ld Waarschuwing: %ld",
"INSERT TABLE '%-.64s' is niet toegestaan in de FROM tabel-lijst",
"You can't specify target table '%-.64s' for update in FROM clause",
"Onbekend thread id: %lu",
"U bent geen bezitter van thread %lu",
"Geen tabellen gebruikt.",
......@@ -260,3 +260,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -94,7 +94,7 @@
"You can't delete all columns with ALTER TABLE. Use DROP TABLE instead",
"Can't DROP '%-.64s'. Check that column/key exists",
"Records: %ld Duplicates: %ld Warnings: %ld",
"INSERT TABLE '%-.64s' isn't allowed in FROM table list",
"You can't specify target table '%-.64s' for update in FROM clause",
"Unknown thread id: %lu",
"You are not owner of thread %lu",
"No tables used",
......@@ -247,5 +247,6 @@
"Cyclic reference on subqueries",
"Converting column '%s' from %s to %s",
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Every derived table must have it's own alias",
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -99,7 +99,7 @@
"ALTER TABLE kasutades ei saa kustutada kiki tulpasid. Kustuta tabel DROP TABLE abil",
"Ei suuda kustutada '%-.64s'. Kontrolli kas tulp/vti eksisteerib",
"Kirjeid: %ld Kattuvaid: %ld Hoiatusi: %ld",
"INSERT TABLE '%-.64s' ei ole lubatud FROM tabelite nimekirjas",
"You can't specify target table '%-.64s' for update in FROM clause",
"Tundmatu lim: %lu",
"Ei ole lime %lu omanik",
"htegi tabelit pole kasutusel",
......@@ -254,3 +254,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -94,7 +94,7 @@
"Vous ne pouvez effacer tous les champs avec ALTER TABLE. Utilisez DROP TABLE",
"Ne peut effacer (DROP) '%-.64s'. Vérifiez s'il existe",
"Enregistrements: %ld Doublons: %ld Avertissements: %ld",
"INSERT TABLE '%-.64s' n'est pas permis dans FROM liste des tables",
"You can't specify target table '%-.64s' for update in FROM clause",
"Numéro de tâche inconnu: %lu",
"Vous n'êtes pas propriétaire de la tâche no: %lu",
"Aucune table utilisée",
......@@ -249,3 +249,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -97,7 +97,7 @@
"Mit ALTER TABLE können nicht alle Felder auf einmal gelöscht werden. Verwende DROP TABLE stattdessen.",
"Kann '%-.64s' nicht löschen (DROP). Existiert das Feld/der Schlüssel?",
"Datensätze: %ld Duplikate: %ld Warnungen: %ld",
"INSERT TABLE '%-.64s' nicht erlaubt im FROM Abschnitt.",
"You can't specify target table '%-.64s' for update in FROM clause",
"Unbekannte Thread-ID: %lu",
"Nicht Besitzer des Threads %lu.",
"Keine Tabellen in Verwendung.",
......@@ -252,3 +252,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -94,7 +94,7 @@
" ALTER TABLE. DROP TABLE",
" (DROP) '%-.64s'. / ",
": %ld : %ld : %ld",
"INSERT TABLE '%-.64s' FROM table list",
"You can't specify target table '%-.64s' for update in FROM clause",
" thread id: %lu",
" owner thread %lu",
" ",
......@@ -249,3 +249,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -96,7 +96,7 @@
"Az osszes mezo nem torolheto az ALTER TABLE-lel. Hasznalja a DROP TABLE-t helyette",
"A DROP '%-.64s' nem lehetseges. Ellenorizze, hogy a mezo/kulcs letezik-e",
"Rekordok: %ld Duplikalva: %ld Warnings: %ld",
"INSERT TABLE '%-.64s' nem engedelyezett a FROM table listabol",
"You can't specify target table '%-.64s' for update in FROM clause",
"Ervenytelen szal (thread) id: %lu",
"A %lu thread-nek mas a tulajdonosa",
"Nincs hasznalt tabla",
......@@ -251,3 +251,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -94,7 +94,7 @@
"Non si possono cancellare tutti i campi con una ALTER TABLE. Utilizzare DROP TABLE",
"Impossibile cancellare '%-.64s'. Controllare che il campo chiave esista",
"Records: %ld Duplicati: %ld Avvertimenti: %ld",
"INSERT TABLE '%-.64s' non e` permesso nella FROM table list",
"You can't specify target table '%-.64s' for update in FROM clause",
"Thread id: %lu sconosciuto",
"Utente non proprietario del thread %lu",
"Nessuna tabella usata",
......@@ -249,3 +249,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -96,7 +96,7 @@
"ALTER TABLE で全ての column は削除できません. DROP TABLE を使用してください",
"'%-.64s' を破棄できませんでした. Check that column/key exists",
"レコード数: %ld 重複数: %ld Warnings: %ld",
"INSERT TABLE '%-.64s' isn't allowed in FROM table list",
"You can't specify target table '%-.64s' for update in FROM clause",
"thread id: %lu はありません",
"thread %lu のオーナーではありません",
"No tables used",
......@@ -251,3 +251,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -94,7 +94,7 @@
"ALTER TABLE 명령으로는 모든 칼럼을 지울 수 없습니다. DROP TABLE 명령을 이용하세요.",
"'%-.64s'를 DROP할 수 없습니다. 칼럼이나 키가 존재하는지 채크하세요.",
"레코드: %ld개 중복: %ld개 경고: %ld개",
"INSERT TABLE '%-.64s' 는 FROM 테이블 list에서 허가되지 않았습니다.",
"You can't specify target table '%-.64s' for update in FROM clause",
"알수 없는 쓰레드 id: %lu",
"쓰레드(Thread) %lu의 소유자가 아닙니다.",
"어떤 테이블도 사용되지 않았습니다.",
......@@ -249,3 +249,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -96,7 +96,7 @@
"Ein kan ikkje slette alle felt med ALTER TABLE. Bruk DROP TABLE istadenfor.",
"Kan ikkje DROP '%-.64s'. Undersk om felt/nkkel eksisterar.",
"Postar: %ld Like: %ld tvaringar: %ld",
"INSERT TABLE '%-.64s' er ikkje tillate i FROM tabell liste",
"You can't specify target table '%-.64s' for update in FROM clause",
"Ukjent trd id: %lu",
"Du er ikkje eigar av trd %lu",
"Ingen tabellar i bruk",
......@@ -251,3 +251,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -96,7 +96,7 @@
"En kan ikke slette alle felt med ALTER TABLE. Bruk DROP TABLE isteden.",
"Kan ikke DROP '%-.64s'. Undersøk om felt/nøkkel eksisterer.",
"Poster: %ld Like: %ld Advarsler: %ld",
"INSERT TABLE '%-.64s' er ikke tillatt i FROM tabell liste",
"You can't specify target table '%-.64s' for update in FROM clause",
"Ukjent tråd id: %lu",
"Du er ikke eier av tråden %lu",
"Ingen tabeller i bruk",
......@@ -251,3 +251,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -98,7 +98,7 @@
"Nie mona usun? wszystkich pl wykorzystuj?c ALTER TABLE. W zamian uyj DROP TABLE",
"Nie mona wykona operacji DROP '%-.64s'. Sprawd, czy to pole/klucz istnieje",
"Rekordw: %ld Duplikatw: %ld Ostrzee: %ld",
"Operacja INSERT TABLE '%-.64s' nie jest dozwolona w li?cie tabel w FROM",
"You can't specify target table '%-.64s' for update in FROM clause",
"Nieznany identyfikator w?tku: %lu",
"Nie jeste? wa?cicielem w?tku %lu",
"Nie ma adej uytej tabeli",
......@@ -253,3 +253,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -94,7 +94,7 @@
"Você não pode deletar todas as colunas com ALTER TABLE. Use DROP TABLE em seu lugar",
"Não se pode fazer DROP '%-.64s'. Confira se esta coluna/chave existe",
"Registros: %ld - Duplicados: %ld - Avisos: %ld",
"INSERT TABLE '%-.64s' não é permitido na lista de tabelas contidas em FROM",
"You can't specify target table '%-.64s' for update in FROM clause",
"'Id' de 'thread' %lu desconhecido",
"Você não é proprietário da 'thread' %lu",
"Nenhuma tabela usada",
......@@ -249,3 +249,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -98,7 +98,7 @@
"Nu poti sterge toate coloanele cu ALTER TABLE. Foloseste DROP TABLE in schimb",
"Nu pot sa DROP '%-.64s'. Verifica daca coloana/cheia exista",
"Recorduri: %ld Duplicate: %ld Atentionari (warnings): %ld",
"INSERT TABLE '%-.64s' nu este permis in lista FROM de tabele",
"You can't specify target table '%-.64s' for update in FROM clause",
"Id-ul: %lu thread-ului este necunoscut",
"Nu sinteti proprietarul threadului %lu",
"Nici o tabela folosita",
......@@ -253,3 +253,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -97,7 +97,7 @@
" ALTER TABLE. DROP TABLE",
" '%-.64s'. , / ",
": %ld : %ld : %ld",
"INSERT TABLE '%-.64s' FROM TABLE",
" '%-.64s' FROM",
" : %lu",
" %lu",
" ",
......@@ -252,3 +252,4 @@
" '%-.64s' (%s)",
"Every derived table must have it's own alias"
"Select %u ",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -100,7 +100,7 @@
"Ne moete da izbriete sve kolone pomou komande 'ALTER TABLE'. Upotrebite komandu 'DROP TABLE' ako elite to da uradite",
"Ne mogu da izvrim komandu drop 'DROP' na '%-.64s'. Proverite da li ta kolona (odnosno klju) postoji",
"Slogova: %ld Duplikata: %ld Upozorenja: %ld",
"Komanda 'INSERT TABLE' na '%-.64s' nije dozvoljena u listi 'FROM' tabela",
"You can't specify target table '%-.64s' for update in FROM clause",
"Nepoznat thread identifikator: %lu",
"Vi niste vlasnik thread-a %lu",
"Nema upotrebljenih tabela",
......@@ -245,3 +245,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -102,7 +102,7 @@
"One nemem zmaza all fields with ALTER TABLE. Use DROP TABLE instead",
"Nemem zrui (DROP) '%-.64s'. Skontrolujte, i neexistuj zznamy/ke",
"Zznamov: %ld Opakovanch: %ld Varovania: %ld",
"INSERT TABLE '%-.64s' nie je dovolen v zozname tabuliek FROM",
"You can't specify target table '%-.64s' for update in FROM clause",
"Neznma identifikcia vlkna: %lu",
"Nie ste vlastnkom vlkna %lu",
"Nie je pouit iadna tabuka",
......@@ -257,3 +257,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -95,7 +95,7 @@
"No puede borrar todos los campos con ALTER TABLE. Usa DROP TABLE para hacerlo",
"No puedo ELIMINAR '%-.64s'. compuebe que el campo/clave existe",
"Registros: %ld Duplicados: %ld Peligros: %ld",
"INSERT TABLE '%-.64s' no esta permitido en FROM tabla lista",
"You can't specify target table '%-.64s' for update in FROM clause",
"Identificador del thread: %lu desconocido",
"Tu no eres el propietario del thread%lu",
"No ha tablas usadas",
......@@ -250,3 +250,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -94,7 +94,7 @@
"Man kan inte radera alla fält med ALTER TABLE. Använd DROP TABLE istället",
"Kan inte ta bort '%-.64s'. Kontrollera att fältet/nyckel finns",
"Rader: %ld Dubletter: %ld Varningar: %ld",
"INSERT table '%-.64s' får inte finnas i FROM tabell-listan",
"You can't specify target table '%-.64s' for update in FROM clause",
"Finns inget thread med id %lu",
"Du är inte ägare till thread %lu",
"Inga tabeller angivna",
......@@ -249,3 +249,4 @@
"Reference '%-.64s' not supported (%s)",
"Every derived table must have it's own alias"
"Select %u was reduced during optimisation",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -99,7 +99,7 @@
" Ӧ æ ALTER TABLE. DROP TABLE",
" DROP '%-.64s'. צ, / դ",
"Ӧ: %ld ̦Ԧ: %ld : %ld",
"INSERT TABLE '%-.64s' ̦ FROM TABLE",
" '%-.64s' ͦ ̦ FROM",
"צ Ʀ Ǧ: %lu",
" Ǧ %lu",
" ",
......@@ -254,3 +254,4 @@
" '%-.64s' i (%s)",
"Every derived table must have it's own alias"
"Select %u was iii",
"Table '%-.64s' from one of SELECT's can not be used in %-.32s"
......@@ -1957,8 +1957,14 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
table_name=buff;
}
if (report_error)
my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
table_name, thd->where);
{
if (thd->lex.current_select->get_master()->order_list.elements)
my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, ER(ER_TABLENAME_NOT_ALLOWED_HERE),
MYF(0), table_name, thd->where);
else
my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
table_name, thd->where);
}
else
return (Field*) not_found_field;
}
......
......@@ -142,8 +142,6 @@ THD::THD():user_time(0), fatal_error(0),
bzero((char*) &con_root,sizeof(con_root));
bzero((char*) &warn_root,sizeof(warn_root));
init_alloc_root(&warn_root, 1024, 0);
bzero((char*) warn_count, sizeof(warn_count));
warn_list.empty();
user_connect=(USER_CONN *)0;
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
......@@ -187,17 +185,20 @@ THD::THD():user_time(0), fatal_error(0),
void THD::init(void)
{
pthread_mutex_lock(&LOCK_global_system_variables);
variables= global_system_variables;
pthread_mutex_unlock(&LOCK_global_system_variables);
server_status= SERVER_STATUS_AUTOCOMMIT;
update_lock_default= (variables.low_priority_updates ?
TL_WRITE_LOW_PRIORITY :
TL_WRITE);
options= thd_startup_options;
sql_mode=(uint) opt_sql_mode;
open_options=ha_open_options;
pthread_mutex_lock(&LOCK_global_system_variables);
variables= global_system_variables;
pthread_mutex_unlock(&LOCK_global_system_variables);
update_lock_default= (variables.low_priority_updates ?
TL_WRITE_LOW_PRIORITY :
TL_WRITE);
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
warn_list.empty();
bzero((char*) warn_count, sizeof(warn_count));
total_warn_count= 0;
}
/*
......@@ -228,6 +229,7 @@ void THD::cleanup(void)
{
DBUG_ENTER("THD::cleanup");
ha_rollback(this);
delete_tree(&prepared_statements);
if (locked_tables)
{
lock=locked_tables; locked_tables=0;
......@@ -289,7 +291,6 @@ THD::~THD()
free_root(&con_root,MYF(0));
free_root(&warn_root,MYF(0));
free_root(&transaction.mem_root,MYF(0));
delete_tree(&prepared_statements);
mysys_var=0; // Safety (shouldn't be needed)
pthread_mutex_destroy(&LOCK_delete);
#ifndef DBUG_OFF
......
......@@ -29,12 +29,12 @@ class Slave_log_event;
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY };
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE };
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE, DUP_UPDATE };
enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
DELAY_KEY_WRITE_ALL };
// log info errors
// log info errors
#define LOG_INFO_EOF -1
#define LOG_INFO_IO -2
#define LOG_INFO_INVALID -3
......@@ -188,6 +188,9 @@ typedef struct st_copy_info {
ha_rows error_count;
enum enum_duplicates handle_duplicates;
int escape_char, last_errno;
/* for INSERT ... UPDATE */
List<Item> *update_fields;
List<Item> *update_values;
} COPY_INFO;
......
......@@ -54,7 +54,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
if (find_real_table_in_list(table_list->next,
table_list->db, table_list->real_name))
{
my_error(ER_INSERT_TABLE_USED, MYF(0), table_list->real_name);
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
DBUG_RETURN(-1);
}
......
......@@ -97,8 +97,12 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
}
int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
List<List_item> &values_list,enum_duplicates duplic)
int mysql_insert(THD *thd,TABLE_LIST *table_list,
List<Item> &fields,
List<List_item> &values_list,
List<Item> &update_fields,
List<Item> &update_values,
enum_duplicates duplic)
{
int error;
bool log_on= ((thd->options & OPTION_UPDATE_LOG) ||
......@@ -126,7 +130,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
if ((lock_type == TL_WRITE_DELAYED &&
((specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) ||
thd->slave_thread)) ||
(lock_type == TL_WRITE_CONCURRENT_INSERT && duplic == DUP_REPLACE))
(lock_type == TL_WRITE_CONCURRENT_INSERT && duplic == DUP_REPLACE) ||
(duplic == DUP_UPDATE))
lock_type=TL_WRITE;
table_list->lock_type= lock_type;
......@@ -166,7 +171,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
values= its++;
if (check_insert_fields(thd,table,fields,*values,1) ||
setup_tables(insert_table_list) ||
setup_fields(thd, insert_table_list, *values, 0, 0, 0))
setup_fields(thd, insert_table_list, *values, 0, 0, 0) ||
(duplic == DUP_UPDATE &&
(setup_fields(thd, insert_table_list, update_fields, 0, 0, 0) ||
setup_fields(thd, insert_table_list, update_values, 0, 0, 0))))
{
table->time_stamp= save_time_stamp;
goto abort;
......@@ -174,7 +182,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
if (find_real_table_in_list(table_list->next,
table_list->db, table_list->real_name))
{
my_error(ER_INSERT_TABLE_USED, MYF(0), table_list->real_name);
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
goto abort;
}
......@@ -203,6 +211,8 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
info.records=info.deleted=info.copied=0;
info.handle_duplicates=duplic;
info.update_fields=&update_fields;
info.update_values=&update_values;
// Don't count warnings for simple inserts
if (values_list.elements > 1 || (thd->options & OPTION_WARNINGS))
thd->count_cuted_fields = 1;
......@@ -212,7 +222,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
error=0;
id=0;
thd->proc_info="update";
if (duplic == DUP_IGNORE || duplic == DUP_REPLACE)
if (duplic != DUP_ERROR)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if ((bulk_insert= (values_list.elements >= MIN_ROWS_TO_USE_BULK_INSERT &&
lock_type != TL_WRITE_DELAYED &&
......@@ -358,7 +368,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
table->next_number_field=0;
thd->count_cuted_fields=0;
thd->next_insert_id=0; // Reset this if wrongly used
if (duplic == DUP_IGNORE || duplic == DUP_REPLACE)
if (duplic != DUP_ERROR)
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
if (error)
goto abort;
......@@ -410,7 +420,8 @@ int write_record(TABLE *table,COPY_INFO *info)
char *key=0;
info->records++;
if (info->handle_duplicates == DUP_REPLACE)
if (info->handle_duplicates == DUP_REPLACE ||
info->handle_duplicates == DUP_UPDATE)
{
while ((error=table->file->write_row(table->record[0])))
{
......@@ -427,7 +438,9 @@ int write_record(TABLE *table,COPY_INFO *info)
was used. This ensures that we don't get a problem when the
whole range of the key has been used.
*/
if (table->next_number_field && key_nr == table->next_number_index &&
if (info->handle_duplicates == DUP_REPLACE &&
table->next_number_field &&
key_nr == table->next_number_index &&
table->file->auto_increment_column_changed)
goto err;
if (table->file->table_flags() & HA_DUPP_POS)
......@@ -459,16 +472,33 @@ int write_record(TABLE *table,COPY_INFO *info)
HA_READ_KEY_EXACT))))
goto err;
}
if (last_uniq_key(table,key_nr))
if (info->handle_duplicates == DUP_UPDATE)
{
if ((error=table->file->update_row(table->record[1],table->record[0])))
goto err;
info->deleted++;
break; /* Update logfile and count */
/* we don't check for other UNIQUE keys - the first row
that matches, is updated. If update causes a conflict again,
an error is returned
*/
restore_record(table,1);
if (fill_record(*info->update_fields,*info->update_values))
goto err;
if ((error=table->file->update_row(table->record[1],table->record[0])))
goto err;
info->deleted++;
break;
}
else /* DUP_REPLACE */
{
if (last_uniq_key(table,key_nr))
{
if ((error=table->file->update_row(table->record[1],table->record[0])))
goto err;
info->deleted++;
break; /* Update logfile and count */
}
else if ((error=table->file->delete_row(table->record[1])))
goto err;
info->deleted++;
}
else if ((error=table->file->delete_row(table->record[1])))
goto err;
info->deleted++;
}
info->copied++;
}
......
......@@ -458,7 +458,7 @@ int yylex(void *arg, void *yythd)
LINT_INIT(c);
for (;;)
{
switch(state) {
switch (state) {
case STATE_OPERATOR_OR_IDENT: // Next is operator or keyword
case STATE_START: // Start of token
// Skip startspace
......@@ -900,7 +900,8 @@ int yylex(void *arg, void *yythd)
return((int) '@');
case STATE_HOSTNAME: // end '@' of user@hostname
for (c=yyGet() ;
my_isalnum(system_charset_info,c) || c == '.' || c == '_' || c == '$';
my_isalnum(system_charset_info,c) || c == '.' || c == '_' ||
c == '$';
c= yyGet()) ;
yylval->lex_str=get_token(lex,yyLength());
return(LEX_HOSTNAME);
......
......@@ -1804,7 +1804,7 @@ mysql_execute_command(THD *thd)
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
find_real_table_in_list(tables->next, tables->db, tables->real_name))
{
net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name);
net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name);
DBUG_VOID_RETURN;
}
if (tables->next)
......@@ -2130,14 +2130,21 @@ mysql_execute_command(THD *thd)
case SQLCOM_REPLACE:
case SQLCOM_INSERT:
{
my_bool update=(lex->value_list.elements ? UPDATE_ACL : 0);
ulong privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL | DELETE_ACL : INSERT_ACL);
INSERT_ACL | DELETE_ACL : INSERT_ACL | update);
if (check_access(thd,privilege,tables->db,&tables->grant.privilege))
goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,privilege,tables))
goto error;
if (select_lex->item_list.elements != lex->value_list.elements)
{
send_error(thd,ER_WRONG_VALUE_COUNT);
DBUG_VOID_RETURN;
}
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
lex->duplicates);
select_lex->item_list, lex->value_list,
(update ? DUP_UPDATE : lex->duplicates));
if (thd->net.report_error)
res= -1;
break;
......@@ -2172,7 +2179,7 @@ mysql_execute_command(THD *thd)
if (find_real_table_in_list(tables->next, tables->db, tables->real_name))
{
net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name);
net_printf(thd,ER_UPDATE_TABLE_USED,tables->real_name);
DBUG_VOID_RETURN;
}
......@@ -2273,7 +2280,7 @@ mysql_execute_command(THD *thd)
{
if (find_real_table_in_list(t->table_list->next, t->db, t->real_name))
{
my_error(ER_INSERT_TABLE_USED, MYF(0), t->real_name);
my_error(ER_UPDATE_TABLE_USED, MYF(0), t->real_name);
res= -1;
break;
}
......@@ -2460,7 +2467,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_LOAD:
{
uint privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL | UPDATE_ACL | DELETE_ACL : INSERT_ACL);
INSERT_ACL | DELETE_ACL : INSERT_ACL);
if (!lex->local_file)
{
......
......@@ -4115,6 +4115,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
keyinfo->key_length=0;
keyinfo->rec_per_key=0;
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
for (; group ; group=group->next,key_part_info++)
{
Field *field=(*group->item)->tmp_table_field();
......@@ -4191,6 +4192,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
keyinfo->key_length=(uint16) reclength;
keyinfo->name=(char*) "tmp";
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
if (null_pack_length)
{
key_part_info->null_bit=0;
......
......@@ -89,7 +89,7 @@ int mysql_update(THD *thd,
if (find_real_table_in_list(table_list->next,
table_list->db, table_list->real_name))
{
my_error(ER_INSERT_TABLE_USED, MYF(0), table_list->real_name);
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
DBUG_RETURN(-1);
}
......
......@@ -1461,7 +1461,7 @@ alter_list_item:
lex->simple_alter=0;
}
| RENAME opt_to table_ident
{
{
LEX *lex=Lex;
lex->select_lex.db=$3->db.str;
lex->name= $3->table.str;
......@@ -1979,10 +1979,12 @@ simple_expr:
| NOT expr %prec NEG { $$= new Item_func_not($2); }
| '!' expr %prec NEG { $$= new Item_func_not($2); }
| '(' expr ')' { $$= $2; }
| '(' expr ',' expr_list ')'
/* Note: In SQL-99 "ROW" is optional, but not having it mandatory
causes conflicts with the INTERVAL syntax. */
| ROW_SYM '(' expr ',' expr_list ')'
{
$4->push_front($2);
$$= new Item_row(*$4);
$5->push_front($3);
$$= new Item_row(*$5);
}
| EXISTS exists_subselect { $$= $2; }
| singleval_subselect { $$= $1; }
......@@ -2680,7 +2682,11 @@ order_dir:
opt_limit_clause:
/* empty */ {}
| LIMIT
| limit_clause {}
;
limit_clause:
LIMIT
{
LEX *lex= Lex;
if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE &&
......@@ -3047,7 +3053,7 @@ expr_or_default:
opt_insert_update:
/* empty */
| ON DUPLICATE KEY_SYM UPDATE_SYM SET update_list
| ON DUPLICATE
{ /* for simplisity, let's forget about
INSERT ... SELECT ... UPDATE
for a moment */
......@@ -3057,6 +3063,7 @@ opt_insert_update:
YYABORT;
}
}
KEY_SYM UPDATE_SYM update_list
;
/* Update rows in a table */
......@@ -4378,10 +4385,7 @@ union_opt:
;
optional_order_or_limit:
/* empty
intentional reduce/reduce conflict here !!!
{ code } below should not be executed
when neither ORDER BY nor LIMIT are used */ {}
/* Empty */ {}
|
{
LEX *lex=Lex;
......@@ -4397,7 +4401,13 @@ optional_order_or_limit:
lex->current_select->select_limit=
lex->thd->variables.select_limit;
}
opt_order_clause opt_limit_clause
order_or_limit
;
order_or_limit:
order_clause opt_limit_clause
|
limit_clause
;
union_option:
......
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