mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
Merge work:/home/bk/mysql-4.1 into mashka.mysql.fi:/home/my/mysql-4.1
This commit is contained in:
commit
3d1af24f0f
34 changed files with 388 additions and 102 deletions
|
@ -72,6 +72,12 @@ if (@config_env > 0)
|
|||
$opt_config_env= join(" ", @config_env);
|
||||
}
|
||||
|
||||
if (@config_env > 0)
|
||||
{
|
||||
chomp(@config_env);
|
||||
$opt_config_env= join(" ", @config_env);
|
||||
}
|
||||
|
||||
chomp($host=`hostname`);
|
||||
$full_host_name=$host;
|
||||
$connect_option= ($opt_tcpip ? "--host=$host" : "");
|
||||
|
|
|
@ -15,6 +15,7 @@ SHARED_LIB_VERSION=12:0:0
|
|||
# Set all version vars based on $VERSION. How do we do this more elegant ?
|
||||
# Remember that regexps needs to quote [ and ] since this is run through m4
|
||||
MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|-.*$||"`
|
||||
MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|[[a-z]]*-.*$||"`
|
||||
MYSQL_BASE_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|\.[[^.]]*$||"`
|
||||
F_PART=`echo $MYSQL_BASE_VERSION | sed -e "s|\.||g"| sed -e "s|[a-zA-Z]\+||"|sed -e "s|^\(..\)$|\\10|"`
|
||||
L_PART=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|^[[0-9]]\.[[0-9]]*\.||" | sed -e "s|^\(.\)$|0\\1|" | sed -e "s|[[a-z]]||"`
|
||||
|
|
|
@ -90,6 +90,12 @@ ut_malloc_low(
|
|||
"InnoDB: on Linux we get a stack trace.\n",
|
||||
n, ut_total_allocated_memory, errno);
|
||||
|
||||
/* Flush stderr to make more probable that the error
|
||||
message gets in the error file before we generate a seg
|
||||
fault */
|
||||
|
||||
fflush(stderr);
|
||||
|
||||
os_fast_mutex_unlock(&ut_list_mutex);
|
||||
|
||||
/* Make an intentional seg fault so that we get a stack
|
||||
|
|
|
@ -52,24 +52,3 @@ select min(big),max(big),max(big)-1 from t1 group by a;
|
|||
min(big) max(big) max(big)-1
|
||||
-1 9223372036854775807 9223372036854775806
|
||||
drop table t1;
|
||||
select CAST(1-2 AS UNSIGNED);
|
||||
CAST(1-2 AS UNSIGNED)
|
||||
18446744073709551615
|
||||
select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
|
||||
CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
|
||||
-1
|
||||
select CONVERT('-1',UNSIGNED);
|
||||
CONVERT('-1',UNSIGNED)
|
||||
18446744073709551615
|
||||
select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
|
||||
cast(-5 as unsigned) | 1 cast(-5 as unsigned) & -1
|
||||
18446744073709551611 18446744073709551611
|
||||
select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
|
||||
cast(-5 as unsigned) -1 cast(-5 as unsigned) + 1
|
||||
18446744073709551610 18446744073709551612
|
||||
select ~5, cast(~5 as signed);
|
||||
~5 cast(~5 as signed)
|
||||
18446744073709551610 -6
|
||||
select cast(5 as unsigned) -6.0;
|
||||
cast(5 as unsigned) -6.0
|
||||
-1.0
|
||||
|
|
39
mysql-test/r/cast.result
Normal file
39
mysql-test/r/cast.result
Normal file
|
@ -0,0 +1,39 @@
|
|||
select CAST(1-2 AS UNSIGNED);
|
||||
CAST(1-2 AS UNSIGNED)
|
||||
18446744073709551615
|
||||
select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
|
||||
CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
|
||||
-1
|
||||
select CONVERT('-1',UNSIGNED);
|
||||
CONVERT('-1',UNSIGNED)
|
||||
18446744073709551615
|
||||
select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
|
||||
cast(-5 as unsigned) | 1 cast(-5 as unsigned) & -1
|
||||
18446744073709551611 18446744073709551611
|
||||
select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
|
||||
cast(-5 as unsigned) -1 cast(-5 as unsigned) + 1
|
||||
18446744073709551610 18446744073709551612
|
||||
select ~5, cast(~5 as signed);
|
||||
~5 cast(~5 as signed)
|
||||
18446744073709551610 -6
|
||||
select cast(5 as unsigned) -6.0;
|
||||
cast(5 as unsigned) -6.0
|
||||
-1.0
|
||||
select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A";
|
||||
cast("A" as binary) = "a" cast(BINARY "a" as CHAR) = "A"
|
||||
0 1
|
||||
select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME);
|
||||
cast("2001-1-1" as DATE) cast("2001-1-1" as DATETIME)
|
||||
2001-1-1 2001-1-1
|
||||
select cast("1:2:3" as TIME);
|
||||
cast("1:2:3" as TIME)
|
||||
1:2:3
|
||||
select cast("2001-1-1" as date) = "2001-01-01";
|
||||
cast("2001-1-1" as date) = "2001-01-01"
|
||||
0
|
||||
select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
|
||||
cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"
|
||||
0
|
||||
select cast("1:2:3" as TIME) = "1:02:03";
|
||||
cast("1:2:3" as TIME) = "1:02:03"
|
||||
0
|
16
mysql-test/r/constraints.result
Normal file
16
mysql-test/r/constraints.result
Normal file
|
@ -0,0 +1,16 @@
|
|||
drop table if exists t1;
|
||||
create table t1 (a int check (a>0));
|
||||
insert into t1 values (1);
|
||||
insert into t1 values (0);
|
||||
drop table t1;
|
||||
create table t1 (a int ,b int, check a>b);
|
||||
insert into t1 values (1,0);
|
||||
insert into t1 values (0,1);
|
||||
drop table t1;
|
||||
create table t1 (a int ,b int, constraint abc check (a>b));
|
||||
insert into t1 values (1,0);
|
||||
insert into t1 values (0,1);
|
||||
drop table t1;
|
||||
create table t1 (a int null);
|
||||
insert into t1 values (1),(NULL);
|
||||
drop table t1;
|
|
@ -24,6 +24,12 @@ now()-curdate()*1000000-curtime()
|
|||
select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
|
||||
strcmp(current_timestamp(),concat(current_date()," ",current_time()))
|
||||
0
|
||||
select strcmp(localtime(),concat(current_date()," ",current_time()));
|
||||
strcmp(localtime(),concat(current_date()," ",current_time()))
|
||||
0
|
||||
select strcmp(localtimestamp(),concat(current_date()," ",current_time()));
|
||||
strcmp(localtimestamp(),concat(current_date()," ",current_time()))
|
||||
0
|
||||
select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w");
|
||||
date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")
|
||||
January Thursday 2nd 1997 97 01 02 03 04 05 4
|
||||
|
|
20
mysql-test/r/innodb-deadlock.result
Normal file
20
mysql-test/r/innodb-deadlock.result
Normal file
|
@ -0,0 +1,20 @@
|
|||
drop table if exists t1;
|
||||
create table t1 (id integer, x integer) type=INNODB;
|
||||
insert into t1 values(0, 0);
|
||||
set autocommit=0;
|
||||
SELECT * from t1 where id = 0 FOR UPDATE;
|
||||
id x
|
||||
0 0
|
||||
set autocommit=0;
|
||||
update t1 set x=2 where id = 0;
|
||||
update t1 set x=1 where id = 0;
|
||||
select * from t1;
|
||||
id x
|
||||
0 1
|
||||
commit;
|
||||
commit;
|
||||
select * from t1;
|
||||
id x
|
||||
0 2
|
||||
commit;
|
||||
drop table t1;
|
|
@ -98,3 +98,13 @@ commit;
|
|||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
drop table if exists t1;
|
||||
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) TYPE=InnoDB;
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
0
|
||||
insert into t1 (id) values (0);
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
1
|
||||
drop table t1;
|
||||
|
|
|
@ -228,3 +228,36 @@ alter table t1 add key id (id);
|
|||
select * from t1, t2 where t1.id = t2.id;
|
||||
id id
|
||||
drop table t1,t2;
|
||||
create table t1 (
|
||||
id integer,
|
||||
id2 integer not null,
|
||||
index (id),
|
||||
index (id2)
|
||||
);
|
||||
insert into t1 values(null,null),(1,1);
|
||||
select * from t1;
|
||||
id id2
|
||||
NULL 0
|
||||
1 1
|
||||
select * from t1 where id <=> null;
|
||||
id id2
|
||||
NULL 0
|
||||
select * from t1 where id <=> null or id > 0;
|
||||
id id2
|
||||
NULL 0
|
||||
1 1
|
||||
select * from t1 where id is null or id > 0;
|
||||
id id2
|
||||
NULL 0
|
||||
1 1
|
||||
select * from t1 where id2 <=> null or id2 > 0;
|
||||
id id2
|
||||
1 1
|
||||
select * from t1 where id2 is null or id2 > 0;
|
||||
id id2
|
||||
1 1
|
||||
delete from t1 where id <=> NULL;
|
||||
select * from t1;
|
||||
id id2
|
||||
1 1
|
||||
drop table t1;
|
||||
|
|
|
@ -35,11 +35,3 @@ alter table t1 modify big bigint not null;
|
|||
select min(big),max(big),max(big)-1 from t1;
|
||||
select min(big),max(big),max(big)-1 from t1 group by a;
|
||||
drop table t1;
|
||||
|
||||
select CAST(1-2 AS UNSIGNED);
|
||||
select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
|
||||
select CONVERT('-1',UNSIGNED);
|
||||
select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
|
||||
select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
|
||||
select ~5, cast(~5 as signed);
|
||||
select cast(5 as unsigned) -6.0;
|
||||
|
|
22
mysql-test/t/cast.test
Normal file
22
mysql-test/t/cast.test
Normal file
|
@ -0,0 +1,22 @@
|
|||
#
|
||||
# Test of cast function
|
||||
#
|
||||
|
||||
select CAST(1-2 AS UNSIGNED);
|
||||
select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
|
||||
select CONVERT('-1',UNSIGNED);
|
||||
select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
|
||||
select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
|
||||
select ~5, cast(~5 as signed);
|
||||
select cast(5 as unsigned) -6.0;
|
||||
select cast("A" as binary) = "a", cast(BINARY "a" as CHAR) = "A";
|
||||
select cast("2001-1-1" as DATE), cast("2001-1-1" as DATETIME);
|
||||
select cast("1:2:3" as TIME);
|
||||
|
||||
#
|
||||
# The following should be fixed in 4.1
|
||||
#
|
||||
|
||||
select cast("2001-1-1" as date) = "2001-01-01";
|
||||
select cast("2001-1-1" as datetime) = "2001-01-01 00:00:00";
|
||||
select cast("1:2:3" as TIME) = "1:02:03";
|
21
mysql-test/t/constraints.test
Normal file
21
mysql-test/t/constraints.test
Normal file
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# Testing of constraints
|
||||
# Currently MySQL only ignores the syntax.
|
||||
#
|
||||
drop table if exists t1;
|
||||
|
||||
create table t1 (a int check (a>0));
|
||||
insert into t1 values (1);
|
||||
insert into t1 values (0);
|
||||
drop table t1;
|
||||
create table t1 (a int ,b int, check a>b);
|
||||
insert into t1 values (1,0);
|
||||
insert into t1 values (0,1);
|
||||
drop table t1;
|
||||
create table t1 (a int ,b int, constraint abc check (a>b));
|
||||
insert into t1 values (1,0);
|
||||
insert into t1 values (0,1);
|
||||
drop table t1;
|
||||
create table t1 (a int null);
|
||||
insert into t1 values (1),(NULL);
|
||||
drop table t1;
|
|
@ -12,6 +12,8 @@ select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
|
|||
select sec_to_time(time_to_sec('-838:59:59'));
|
||||
select now()-curdate()*1000000-curtime();
|
||||
select strcmp(current_timestamp(),concat(current_date()," ",current_time()));
|
||||
select strcmp(localtime(),concat(current_date()," ",current_time()));
|
||||
select strcmp(localtimestamp(),concat(current_date()," ",current_time()));
|
||||
select date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w");
|
||||
select date_format("1997-01-02", concat("%M %W %D ","%Y %y %m %d %h %i %s %w"));
|
||||
select dayofmonth("1997-01-02"),dayofmonth(19970323);
|
||||
|
@ -164,6 +166,7 @@ select to_days("0000-00-00"),to_days(d),to_days(dt),to_days(t),to_days(c) from t
|
|||
select extract(MONTH FROM "0000-00-00"),extract(MONTH FROM d),extract(MONTH FROM dt),extract(MONTH FROM t),extract(MONTH FROM c) from t1;
|
||||
drop table t1;
|
||||
|
||||
|
||||
#
|
||||
# Test problem with TIMESTAMP and BETWEEN
|
||||
#
|
||||
|
|
38
mysql-test/t/innodb-deadlock.test
Normal file
38
mysql-test/t/innodb-deadlock.test
Normal file
|
@ -0,0 +1,38 @@
|
|||
-- source include/have_innodb.inc
|
||||
|
||||
connect (con1,localhost,root,,);
|
||||
connect (con2,localhost,root,,);
|
||||
drop table if exists t1;
|
||||
|
||||
#
|
||||
# Testing of FOR UPDATE
|
||||
#
|
||||
|
||||
connection con1;
|
||||
create table t1 (id integer, x integer) type=INNODB;
|
||||
insert into t1 values(0, 0);
|
||||
set autocommit=0;
|
||||
SELECT * from t1 where id = 0 FOR UPDATE;
|
||||
|
||||
connection con2;
|
||||
set autocommit=0;
|
||||
|
||||
# The following query should hang because con1 is locking the page
|
||||
--send
|
||||
update t1 set x=2 where id = 0;
|
||||
--sleep 2;
|
||||
|
||||
connection con1;
|
||||
update t1 set x=1 where id = 0;
|
||||
select * from t1;
|
||||
commit;
|
||||
|
||||
connection con2;
|
||||
reap;
|
||||
commit;
|
||||
|
||||
connection con1;
|
||||
select * from t1;
|
||||
commit;
|
||||
|
||||
drop table t1;
|
|
@ -47,4 +47,11 @@ select * from t3;
|
|||
show status like "Qcache_queries_in_cache";
|
||||
show status like "Qcache_hits";
|
||||
commit;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
show status like "Qcache_queries_in_cache";
|
||||
|
||||
drop table if exists t1;
|
||||
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) TYPE=InnoDB;
|
||||
select count(*) from t1;
|
||||
insert into t1 (id) values (0);
|
||||
select count(*) from t1;
|
||||
drop table t1;
|
||||
|
|
|
@ -135,3 +135,24 @@ select * from t1, t2 where t1.id = t2.id;
|
|||
alter table t1 add key id (id);
|
||||
select * from t1, t2 where t1.id = t2.id;
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# Check bug when doing <=> NULL on an indexed null field
|
||||
#
|
||||
|
||||
create table t1 (
|
||||
id integer,
|
||||
id2 integer not null,
|
||||
index (id),
|
||||
index (id2)
|
||||
);
|
||||
insert into t1 values(null,null),(1,1);
|
||||
select * from t1;
|
||||
select * from t1 where id <=> null;
|
||||
select * from t1 where id <=> null or id > 0;
|
||||
select * from t1 where id is null or id > 0;
|
||||
select * from t1 where id2 <=> null or id2 > 0;
|
||||
select * from t1 where id2 is null or id2 > 0;
|
||||
delete from t1 where id <=> NULL;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
|
|
@ -314,7 +314,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
|||
}
|
||||
#endif
|
||||
#ifdef HAVE_QUERY_CACHE
|
||||
if (transaction_commited)
|
||||
if (transaction_commited && thd->transaction.changed_tables)
|
||||
query_cache.invalidate(thd->transaction.changed_tables);
|
||||
#endif /*HAVE_QUERY_CACHE*/
|
||||
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
|
||||
|
|
10
sql/item.h
10
sql/item.h
|
@ -86,12 +86,14 @@ public:
|
|||
virtual bool get_date(TIME *ltime,bool fuzzydate);
|
||||
virtual bool get_time(TIME *ltime);
|
||||
virtual bool is_null() { return 0; };
|
||||
virtual CHARSET_INFO *thd_charset() const;
|
||||
virtual CHARSET_INFO *charset() const { return str_value.charset(); };
|
||||
virtual bool binary() const { return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0 ; }
|
||||
virtual void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); }
|
||||
virtual bool check_loop(uint id);
|
||||
virtual void top_level_item() {}
|
||||
|
||||
virtual bool binary() const
|
||||
{ return str_value.charset()->state & MY_CS_BINSORT ? 1 : 0 ; }
|
||||
CHARSET_INFO *thd_charset() const;
|
||||
CHARSET_INFO *charset() const { return str_value.charset(); };
|
||||
void set_charset(CHARSET_INFO *cs) { str_value.set_charset(cs); }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -432,6 +432,7 @@ Item *create_func_cast(Item *a, Item_cast cast_type)
|
|||
LINT_INIT(res);
|
||||
switch (cast_type) {
|
||||
case ITEM_CAST_BINARY: res= new Item_func_binary(a); break;
|
||||
case ITEM_CAST_CHAR: res= new Item_char_typecast(a); break;
|
||||
case ITEM_CAST_SIGNED_INT: res= new Item_func_signed(a); break;
|
||||
case ITEM_CAST_UNSIGNED_INT: res= new Item_func_unsigned(a); break;
|
||||
case ITEM_CAST_DATE: res= new Item_date_typecast(a); break;
|
||||
|
|
|
@ -1124,5 +1124,5 @@ public:
|
|||
enum Item_cast
|
||||
{
|
||||
ITEM_CAST_BINARY, ITEM_CAST_SIGNED_INT, ITEM_CAST_UNSIGNED_INT,
|
||||
ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME
|
||||
ITEM_CAST_DATE, ITEM_CAST_TIME, ITEM_CAST_DATETIME, ITEM_CAST_CHAR
|
||||
};
|
||||
|
|
|
@ -1363,17 +1363,19 @@ String *Item_func_decode::val_str(String *str)
|
|||
|
||||
String *Item_func_database::val_str(String *str)
|
||||
{
|
||||
if (!current_thd->db)
|
||||
THD *thd= current_thd;
|
||||
if (!thd->db)
|
||||
str->length(0);
|
||||
else
|
||||
str->copy((const char*) current_thd->db,(uint) strlen(current_thd->db), system_charset_info, thd_charset());
|
||||
str->copy((const char*) thd->db,(uint) strlen(thd->db),
|
||||
system_charset_info, thd->thd_charset);
|
||||
return str;
|
||||
}
|
||||
|
||||
String *Item_func_user::val_str(String *str)
|
||||
{
|
||||
THD *thd=current_thd;
|
||||
CHARSET_INFO *cs=thd_charset();
|
||||
CHARSET_INFO *cs=thd->thd_charset;
|
||||
const char *host=thd->host ? thd->host : thd->ip ? thd->ip : "";
|
||||
uint32 res_length=(strlen(thd->user)+strlen(host)+10) * cs->mbmaxlen;
|
||||
|
||||
|
@ -2130,7 +2132,8 @@ String *Item_func_charset::val_str(String *str)
|
|||
|
||||
if ((null_value=(args[0]->null_value || !res->charset())))
|
||||
return 0;
|
||||
str->copy(res->charset()->name,strlen(res->charset()->name),my_charset_latin1,thd_charset());
|
||||
str->copy(res->charset()->name,strlen(res->charset()->name),
|
||||
my_charset_latin1, thd_charset());
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
|
@ -494,8 +494,9 @@ public:
|
|||
{
|
||||
String *tmp=args[0]->val_str(a);
|
||||
null_value=args[0]->null_value;
|
||||
tmp->set_charset(my_charset_bin);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
set_charset(my_charset_bin);
|
||||
|
|
|
@ -513,6 +513,7 @@ public:
|
|||
bool get_date(TIME *res,bool fuzzy_date);
|
||||
};
|
||||
|
||||
|
||||
class Item_extract :public Item_int_func
|
||||
{
|
||||
const interval_type int_type;
|
||||
|
@ -526,17 +527,40 @@ class Item_extract :public Item_int_func
|
|||
void fix_length_and_dec();
|
||||
};
|
||||
|
||||
|
||||
class Item_typecast :public Item_str_func
|
||||
{
|
||||
public:
|
||||
Item_typecast(Item *a) :Item_str_func(a) {}
|
||||
const char *func_name() const { return "char"; }
|
||||
String *val_str(String *a)
|
||||
{ a=args[0]->val_str(a); null_value=args[0]->null_value; return a; }
|
||||
void fix_length_and_dec() { max_length=args[0]->max_length; }
|
||||
{
|
||||
String *tmp=args[0]->val_str(a);
|
||||
null_value=args[0]->null_value;
|
||||
tmp->set_charset(charset());
|
||||
return tmp;
|
||||
}
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
set_charset(thd_charset());
|
||||
max_length=args[0]->max_length;
|
||||
}
|
||||
void print(String *str);
|
||||
};
|
||||
|
||||
|
||||
class Item_char_typecast :public Item_typecast
|
||||
{
|
||||
public:
|
||||
Item_char_typecast(Item *a) :Item_typecast(a) {}
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
set_charset(thd_charset());
|
||||
max_length=args[0]->max_length;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Item_date_typecast :public Item_typecast
|
||||
{
|
||||
public:
|
||||
|
@ -553,6 +577,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
class Item_time_typecast :public Item_typecast
|
||||
{
|
||||
public:
|
||||
|
@ -569,6 +594,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
class Item_datetime_typecast :public Item_typecast
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -221,6 +221,8 @@ static SYMBOL symbols[] = {
|
|||
{ "LIMIT", SYM(LIMIT),0,0},
|
||||
{ "LOAD", SYM(LOAD),0,0},
|
||||
{ "LOCAL", SYM(LOCAL_SYM),0,0},
|
||||
{ "LOCALTIME", SYM(NOW_SYM),0,0},
|
||||
{ "LOCALTIMESTAMP", SYM(NOW_SYM),0,0},
|
||||
{ "LOCK", SYM(LOCK_SYM),0,0},
|
||||
{ "LOCKS", SYM(LOCKS_SYM),0,0},
|
||||
{ "LOGS", SYM(LOGS_SYM),0,0},
|
||||
|
@ -417,7 +419,9 @@ static SYMBOL sql_functions[] = {
|
|||
{ "BIT_OR", SYM(BIT_OR),0,0},
|
||||
{ "BIT_AND", SYM(BIT_AND),0,0},
|
||||
{ "CAST", SYM(CAST_SYM),0,0},
|
||||
{ "CEIL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
|
||||
{ "CEILING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
|
||||
{ "CURRENT_USER", SYM(USER),0,0},
|
||||
{ "BIT_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)},
|
||||
{ "CENTROID", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_centroid)},
|
||||
{ "CHAR_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
|
||||
|
|
|
@ -4498,7 +4498,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||
else
|
||||
{
|
||||
struct hostent *ent;
|
||||
if (!argument || !argument[0])
|
||||
if (argument || argument[0])
|
||||
ent=gethostbyname(argument);
|
||||
else
|
||||
{
|
||||
|
@ -4687,7 +4687,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initiates DEBUG - but no debugging here ! */
|
||||
|
||||
static void get_options(int argc,char **argv)
|
||||
|
|
|
@ -937,8 +937,11 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
|||
if (!(res= value->val_str(&tmp)))
|
||||
DBUG_RETURN(&null_element);
|
||||
|
||||
// Check if this was a function. This should have be optimized away
|
||||
// in the sql_select.cc
|
||||
/*
|
||||
TODO:
|
||||
Check if this was a function. This should have be optimized away
|
||||
in the sql_select.cc
|
||||
*/
|
||||
if (res != &tmp)
|
||||
{
|
||||
tmp.copy(*res); // Get own copy
|
||||
|
@ -1007,8 +1010,10 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
|||
type != Item_func::EQUAL_FUNC)
|
||||
DBUG_RETURN(0); // Can't optimize this
|
||||
|
||||
/* We can't always use indexes when comparing a string index to a number */
|
||||
/* cmp_type() is checked to allow compare of dates to numbers */
|
||||
/*
|
||||
We can't always use indexes when comparing a string index to a number
|
||||
cmp_type() is checked to allow compare of dates to numbers
|
||||
*/
|
||||
if (field->result_type() == STRING_RESULT &&
|
||||
value->result_type() != STRING_RESULT &&
|
||||
field->cmp_type() != value->result_type())
|
||||
|
@ -1016,6 +1021,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
|||
|
||||
if (value->save_in_field(field) > 0)
|
||||
{
|
||||
/* This happens when we try to insert a NULL field in a not null column */
|
||||
// TODO; Check if we can we remove the following block.
|
||||
if (type == Item_func::EQUAL_FUNC)
|
||||
{
|
||||
|
@ -1027,7 +1033,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
|||
*str = 1;
|
||||
DBUG_RETURN(new SEL_ARG(field,str,str));
|
||||
}
|
||||
DBUG_RETURN(&null_element); // NULL is never true
|
||||
DBUG_RETURN(&null_element); // cmp with NULL is never true
|
||||
}
|
||||
// Get local copy of key
|
||||
char *str= (char*) alloc_root(param->mem_root,
|
||||
|
@ -1035,7 +1041,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
|
|||
if (!str)
|
||||
DBUG_RETURN(0);
|
||||
if (maybe_null)
|
||||
*str=0; // Not NULL
|
||||
*str= (char) field->is_real_null(); // Set to 1 if null
|
||||
field->get_key_image(str+maybe_null,key_part->part_length, key_part->image_type);
|
||||
if (!(tree=new SEL_ARG(field,str,str)))
|
||||
DBUG_RETURN(0);
|
||||
|
|
|
@ -180,14 +180,12 @@ cleanup:
|
|||
if (ha_autocommit_or_rollback(thd,error >= 0))
|
||||
error=1;
|
||||
}
|
||||
|
||||
/*
|
||||
Only invalidate the query cache if something changed or if we
|
||||
didn't commit the transacion (query cache is automaticly
|
||||
invalidated on commit)
|
||||
Store table for future invalidation or invalidate it in
|
||||
the query cache if something changed
|
||||
*/
|
||||
if (deleted &&
|
||||
(!transactional_table ||
|
||||
thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
|
||||
if (deleted)
|
||||
{
|
||||
query_cache_invalidate3(thd, table_list, 1);
|
||||
}
|
||||
|
|
|
@ -319,13 +319,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
|
|||
error=ha_autocommit_or_rollback(thd,error);
|
||||
|
||||
/*
|
||||
Only invalidate the query cache if something changed or if we
|
||||
didn't commit the transacion (query cache is automaticly
|
||||
invalidated on commit)
|
||||
Store table for future invalidation or invalidate it in
|
||||
the query cache if something changed
|
||||
*/
|
||||
if ((info.copied || info.deleted) &&
|
||||
(!transactional_table ||
|
||||
thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
|
||||
if (info.copied || info.deleted)
|
||||
{
|
||||
query_cache_invalidate3(thd, table_list, 1);
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ inline int lex_casecmp(const char *s, const char *t, uint len)
|
|||
|
||||
#include "lex_hash.h"
|
||||
|
||||
static uchar state_map[256];
|
||||
static uchar state_map[256], ident_map[256];
|
||||
|
||||
|
||||
void lex_init(void)
|
||||
|
@ -91,7 +91,7 @@ void lex_init(void)
|
|||
VOID(pthread_key_create(&THR_LEX,NULL));
|
||||
|
||||
/* Fill state_map with states to get a faster parser */
|
||||
for (i=0; i < 256 ; i++)
|
||||
for (i=0; i < sizeof(state_map) ; i++)
|
||||
{
|
||||
if (my_isalpha(system_charset_info,i))
|
||||
state_map[i]=(uchar) STATE_IDENT;
|
||||
|
@ -126,6 +126,20 @@ void lex_init(void)
|
|||
{
|
||||
state_map[(uchar) '"'] = STATE_USER_VARIABLE_DELIMITER;
|
||||
}
|
||||
|
||||
/*
|
||||
Create a second map to make it faster to find identifiers
|
||||
*/
|
||||
for (i=0; i < sizeof(ident_map) ; i++)
|
||||
{
|
||||
ident_map[i]= (uchar) (state_map[i] == STATE_IDENT ||
|
||||
state_map[i] == STATE_NUMBER_IDENT);
|
||||
}
|
||||
|
||||
/* Special handling of hex and binary strings */
|
||||
state_map[(uchar)'x']= state_map[(uchar)'X']= (uchar) STATE_IDENT_OR_HEX;
|
||||
state_map[(uchar)'b']= state_map[(uchar)'b']= (uchar) STATE_IDENT_OR_BIN;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -460,7 +474,7 @@ int yylex(void *arg)
|
|||
}
|
||||
case STATE_CHAR: // Unknown or single char token
|
||||
case STATE_SKIP: // This should not happen
|
||||
yylval->lex_str.str=(char*) (lex->ptr=lex->tok_start);// Set to first char
|
||||
yylval->lex_str.str=(char*) (lex->ptr=lex->tok_start);// Set to first chr
|
||||
yylval->lex_str.length=1;
|
||||
c=yyGet();
|
||||
if (c != ')')
|
||||
|
@ -469,12 +483,15 @@ int yylex(void *arg)
|
|||
lex->tok_start=lex->ptr; // Let tok_start point at next item
|
||||
return((int) c);
|
||||
|
||||
case STATE_IDENT: // Incomplete keyword or ident
|
||||
if ((c == 'x' || c == 'X') && yyPeek() == '\'')
|
||||
case STATE_IDENT_OR_HEX:
|
||||
if (yyPeek() == '\'')
|
||||
{ // Found x'hex-number'
|
||||
state=STATE_HEX_NUMBER;
|
||||
state= STATE_HEX_NUMBER;
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
case STATE_IDENT_OR_BIN: // TODO: Add binary string handling
|
||||
case STATE_IDENT:
|
||||
#if defined(USE_MB) && defined(USE_MB_IDENT)
|
||||
if (use_mb(system_charset_info))
|
||||
{
|
||||
|
@ -489,8 +506,7 @@ int yylex(void *arg)
|
|||
}
|
||||
lex->ptr += l - 1;
|
||||
}
|
||||
while (state_map[c=yyGet()] == STATE_IDENT ||
|
||||
state_map[c] == STATE_NUMBER_IDENT)
|
||||
while (ident_map[c=yyGet()])
|
||||
{
|
||||
if (my_ismbhead(system_charset_info, c))
|
||||
{
|
||||
|
@ -505,15 +521,13 @@ int yylex(void *arg)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
while (state_map[c=yyGet()] == STATE_IDENT ||
|
||||
state_map[c] == STATE_NUMBER_IDENT) ;
|
||||
while (ident_map[c=yyGet()]) ;
|
||||
length= (uint) (lex->ptr - lex->tok_start)-1;
|
||||
if (lex->ignore_space)
|
||||
{
|
||||
for (; state_map[c] == STATE_SKIP ; c= yyGet());
|
||||
}
|
||||
if (c == '.' && (state_map[yyPeek()] == STATE_IDENT ||
|
||||
state_map[yyPeek()] == STATE_NUMBER_IDENT))
|
||||
if (c == '.' && ident_map[yyPeek()])
|
||||
lex->next_state=STATE_IDENT_SEP;
|
||||
else
|
||||
{ // '(' must follow directly if function
|
||||
|
@ -551,7 +565,7 @@ int yylex(void *arg)
|
|||
|
||||
case STATE_NUMBER_IDENT: // number or ident which num-start
|
||||
while (my_isdigit(system_charset_info,(c = yyGet()))) ;
|
||||
if (state_map[c] != STATE_IDENT)
|
||||
if (!ident_map[c])
|
||||
{ // Can't be identifier
|
||||
state=STATE_INT_OR_REAL;
|
||||
break;
|
||||
|
@ -576,7 +590,7 @@ int yylex(void *arg)
|
|||
lex->tok_start[0] == '0' )
|
||||
{ // Varbinary
|
||||
while (my_isxdigit(system_charset_info,(c = yyGet()))) ;
|
||||
if ((lex->ptr - lex->tok_start) >= 4 && state_map[c] != STATE_IDENT)
|
||||
if ((lex->ptr - lex->tok_start) >= 4 && !ident_map[c])
|
||||
{
|
||||
yylval->lex_str=get_token(lex,yyLength());
|
||||
yylval->lex_str.str+=2; // Skip 0x
|
||||
|
@ -603,8 +617,7 @@ int yylex(void *arg)
|
|||
}
|
||||
lex->ptr += l - 1;
|
||||
}
|
||||
while (state_map[c=yyGet()] == STATE_IDENT ||
|
||||
state_map[c] == STATE_NUMBER_IDENT)
|
||||
while (ident_map[c=yyGet()])
|
||||
{
|
||||
if (my_ismbhead(system_charset_info, c))
|
||||
{
|
||||
|
@ -619,11 +632,9 @@ int yylex(void *arg)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
while (state_map[c = yyGet()] == STATE_IDENT ||
|
||||
state_map[c] == STATE_NUMBER_IDENT) ;
|
||||
while (ident_map[c = yyGet()]) ;
|
||||
|
||||
if (c == '.' && (state_map[yyPeek()] == STATE_IDENT ||
|
||||
state_map[yyPeek()] == STATE_NUMBER_IDENT))
|
||||
if (c == '.' && ident_map[yyPeek()])
|
||||
lex->next_state=STATE_IDENT_SEP;// Next is '.'
|
||||
// fall through
|
||||
|
||||
|
@ -901,8 +912,7 @@ int yylex(void *arg)
|
|||
[(global | local | session) .]variable_name
|
||||
*/
|
||||
|
||||
while (state_map[c=yyGet()] == STATE_IDENT ||
|
||||
state_map[c] == STATE_NUMBER_IDENT) ;
|
||||
while (ident_map[c=yyGet()]) ;
|
||||
if (c == '.')
|
||||
lex->next_state=STATE_IDENT_SEP;
|
||||
length= (uint) (lex->ptr - lex->tok_start)-1;
|
||||
|
|
|
@ -78,7 +78,7 @@ enum lex_states
|
|||
STATE_REAL_OR_POINT, STATE_BOOL, STATE_EOL, STATE_ESCAPE, STATE_LONG_COMMENT,
|
||||
STATE_END_LONG_COMMENT, STATE_COLON, STATE_SET_VAR, STATE_USER_END,
|
||||
STATE_HOSTNAME, STATE_SKIP, STATE_USER_VARIABLE_DELIMITER, STATE_SYSTEM_VAR,
|
||||
STATE_IDENT_OR_KEYWORD
|
||||
STATE_IDENT_OR_KEYWORD, STATE_IDENT_OR_HEX, STATE_IDENT_OR_BIN
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
{ sql_element_free(ptr_arg); }
|
||||
~String() { free(); }
|
||||
|
||||
inline void set_charset(CHARSET_INFO *charset) { str_charset=charset; }
|
||||
inline void set_charset(CHARSET_INFO *charset) { str_charset= charset; }
|
||||
inline CHARSET_INFO *charset() const { return str_charset; }
|
||||
inline uint32 length() const { return str_length;}
|
||||
inline uint32 alloced_length() const { return Alloced_length;}
|
||||
|
@ -177,7 +177,8 @@ public:
|
|||
bool copy(); // Alloc string if not alloced
|
||||
bool copy(const String &s); // Allocate new string
|
||||
bool copy(const char *s,uint32 arg_length, CHARSET_INFO *cs); // Allocate new string
|
||||
bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom, CHARSET_INFO *csto);
|
||||
bool copy(const char*s,uint32 arg_length, CHARSET_INFO *csfrom,
|
||||
CHARSET_INFO *csto);
|
||||
bool append(const String &s);
|
||||
bool append(const char *s,uint32 arg_length=0);
|
||||
bool append(IO_CACHE* file, uint32 arg_length);
|
||||
|
|
|
@ -319,14 +319,12 @@ int mysql_update(THD *thd,
|
|||
if (ha_autocommit_or_rollback(thd, error >= 0))
|
||||
error=1;
|
||||
}
|
||||
|
||||
/*
|
||||
Only invalidate the query cache if something changed or if we
|
||||
didn't commit the transacion (query cache is automaticly
|
||||
invalidated on commit)
|
||||
Store table for future invalidation or invalidate it in
|
||||
the query cache if something changed
|
||||
*/
|
||||
if (updated &&
|
||||
(!transactional_table ||
|
||||
thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
|
||||
if (updated)
|
||||
{
|
||||
query_cache_invalidate3(thd, table_list, 1);
|
||||
}
|
||||
|
|
|
@ -991,7 +991,7 @@ field_list:
|
|||
|
||||
|
||||
field_list_item:
|
||||
field_spec
|
||||
field_spec check_constraint
|
||||
| field_spec references
|
||||
{
|
||||
Lex->col_list.empty(); /* Alloced by sql_alloc */
|
||||
|
@ -1013,10 +1013,16 @@ field_list_item:
|
|||
lex->fk_match_option));
|
||||
lex->col_list.empty(); /* Alloced by sql_alloc */
|
||||
}
|
||||
| opt_constraint CHECK_SYM '(' expr ')'
|
||||
| opt_constraint check_constraint
|
||||
{
|
||||
Lex->col_list.empty(); /* Alloced by sql_alloc */
|
||||
};
|
||||
}
|
||||
;
|
||||
|
||||
check_constraint:
|
||||
/* empty */
|
||||
| CHECK_SYM expr
|
||||
;
|
||||
|
||||
opt_constraint:
|
||||
/* empty */
|
||||
|
@ -1110,6 +1116,12 @@ type:
|
|||
$$=FIELD_TYPE_SET;
|
||||
}
|
||||
| LONG_SYM opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; }
|
||||
| SERIAL_SYM
|
||||
{
|
||||
$$=FIELD_TYPE_LONGLONG;
|
||||
Lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG |
|
||||
UNIQUE_FLAG);
|
||||
}
|
||||
;
|
||||
|
||||
char:
|
||||
|
@ -1184,12 +1196,13 @@ attribute:
|
|||
| DEFAULT literal { Lex->default_value=$2; }
|
||||
| AUTO_INC { Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
|
||||
| SERIAL_SYM DEFAULT VALUE_SYM
|
||||
{ Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
|
||||
| PRIMARY_SYM KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; }
|
||||
{ Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG; }
|
||||
| opt_primary KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; }
|
||||
| UNIQUE_SYM { Lex->type|= UNIQUE_FLAG; }
|
||||
| UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; }
|
||||
| COMMENT_SYM text_literal { Lex->comment= $2; };
|
||||
|
||||
|
||||
charset_name:
|
||||
BINARY
|
||||
{
|
||||
|
@ -1227,6 +1240,11 @@ opt_binary:
|
|||
| BINARY { Lex->charset=my_charset_bin; }
|
||||
| CHAR_SYM SET charset_name { Lex->charset=$3; } ;
|
||||
|
||||
|
||||
opt_primary:
|
||||
/* empty */
|
||||
| PRIMARY_SYM
|
||||
|
||||
references:
|
||||
REFERENCES table_ident
|
||||
{
|
||||
|
@ -2258,13 +2276,15 @@ in_sum_expr:
|
|||
|
||||
cast_type:
|
||||
BINARY { $$=ITEM_CAST_BINARY; }
|
||||
| CHAR_SYM { $$=ITEM_CAST_CHAR; }
|
||||
| SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; }
|
||||
| SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; }
|
||||
| UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; }
|
||||
| UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; }
|
||||
| DATE_SYM { $$=ITEM_CAST_DATE; }
|
||||
| TIME_SYM { $$=ITEM_CAST_TIME; }
|
||||
| DATETIME { $$=ITEM_CAST_DATETIME; };
|
||||
| DATETIME { $$=ITEM_CAST_DATETIME; }
|
||||
;
|
||||
|
||||
expr_list:
|
||||
{ Select->expr_list.push_front(new List<Item>); }
|
||||
|
@ -2801,7 +2821,7 @@ table_name:
|
|||
{ if (!Select->add_table_to_list($1, NULL, 1)) YYABORT; };
|
||||
|
||||
if_exists:
|
||||
/* empty */ { $$=0; }
|
||||
/* empty */ { $$= 0; }
|
||||
| IF EXISTS { $$= 1; }
|
||||
;
|
||||
|
||||
|
@ -2882,6 +2902,7 @@ fields:
|
|||
|
||||
insert_values:
|
||||
VALUES values_list {}
|
||||
| VALUE_SYM values_list {}
|
||||
| SELECT_SYM
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
|
@ -3574,7 +3595,6 @@ keyword:
|
|||
| CHANGED {}
|
||||
| CHARSET {}
|
||||
| CHECKSUM_SYM {}
|
||||
| CHECK_SYM {}
|
||||
| CIPHER_SYM {}
|
||||
| CLIENT_SYM {}
|
||||
| CLOSE_SYM {}
|
||||
|
|
Loading…
Reference in a new issue