summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2002-11-25 17:34:51 +0200
committerunknown <monty@mashka.mysql.fi>2002-11-25 17:34:51 +0200
commitcfb331bf9048aa30ec439d2e49627830fabeebff (patch)
tree52ec6ced220f0893673ffb9cf7fbd0a2ae67db17
parent8da0fd29aa44c23a80750cdc783332bccf1c385f (diff)
parent1b9becc35824401f22b4e7c2b2f9b3dab5348fe9 (diff)
downloadmariadb-git-cfb331bf9048aa30ec439d2e49627830fabeebff.tar.gz
Merge work:/home/bk/mysql-4.1 into mashka.mysql.fi:/home/my/mysql-4.1
sql/item.h: Auto merged sql/item_create.cc: Auto merged sql/item_func.h: Auto merged sql/item_strfunc.cc: Auto merged sql/opt_range.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_yacc.yy: Auto merged
-rwxr-xr-xBuild-tools/Do-compile6
-rw-r--r--configure.in1
-rw-r--r--innobase/ut/ut0mem.c6
-rw-r--r--mysql-test/r/bigint.result21
-rw-r--r--mysql-test/r/cast.result39
-rw-r--r--mysql-test/r/constraints.result16
-rw-r--r--mysql-test/r/func_time.result6
-rw-r--r--mysql-test/r/innodb-deadlock.result20
-rw-r--r--mysql-test/r/innodb_cache.result10
-rw-r--r--mysql-test/r/null_key.result33
-rw-r--r--mysql-test/t/bigint.test8
-rw-r--r--mysql-test/t/cast.test22
-rw-r--r--mysql-test/t/constraints.test21
-rw-r--r--mysql-test/t/func_time.test3
-rw-r--r--mysql-test/t/innodb-deadlock.test38
-rw-r--r--mysql-test/t/innodb_cache.test9
-rw-r--r--mysql-test/t/null_key.test21
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/item.h10
-rw-r--r--sql/item_create.cc1
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/item_strfunc.cc11
-rw-r--r--sql/item_strfunc.h3
-rw-r--r--sql/item_timefunc.h30
-rw-r--r--sql/lex.h4
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/opt_range.cc18
-rw-r--r--sql/sql_delete.cc10
-rw-r--r--sql/sql_insert.cc9
-rw-r--r--sql/sql_lex.cc54
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_string.h5
-rw-r--r--sql/sql_update.cc10
-rw-r--r--sql/sql_yacc.yy36
34 files changed, 388 insertions, 102 deletions
diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile
index 8d647ef0d82..52c1951f48f 100755
--- a/Build-tools/Do-compile
+++ b/Build-tools/Do-compile
@@ -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" : "");
diff --git a/configure.in b/configure.in
index 2ac8e050ae5..d25041dea7a 100644
--- a/configure.in
+++ b/configure.in
@@ -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]]||"`
diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c
index 2a7643551ad..03f15031fdf 100644
--- a/innobase/ut/ut0mem.c
+++ b/innobase/ut/ut0mem.c
@@ -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
diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result
index f666c5311b8..6afa74d20e2 100644
--- a/mysql-test/r/bigint.result
+++ b/mysql-test/r/bigint.result
@@ -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
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
new file mode 100644
index 00000000000..572b32c171c
--- /dev/null
+++ b/mysql-test/r/cast.result
@@ -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
diff --git a/mysql-test/r/constraints.result b/mysql-test/r/constraints.result
new file mode 100644
index 00000000000..3b41e291e0f
--- /dev/null
+++ b/mysql-test/r/constraints.result
@@ -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;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 4a1012f73bf..2941352c776 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -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
diff --git a/mysql-test/r/innodb-deadlock.result b/mysql-test/r/innodb-deadlock.result
new file mode 100644
index 00000000000..121bfa8c6cb
--- /dev/null
+++ b/mysql-test/r/innodb-deadlock.result
@@ -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;
diff --git a/mysql-test/r/innodb_cache.result b/mysql-test/r/innodb_cache.result
index eaa030046da..47abcb45fe5 100644
--- a/mysql-test/r/innodb_cache.result
+++ b/mysql-test/r/innodb_cache.result
@@ -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;
diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result
index 85687df411b..484437959a0 100644
--- a/mysql-test/r/null_key.result
+++ b/mysql-test/r/null_key.result
@@ -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;
diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test
index 15b35ac7c87..15c61c2c0dc 100644
--- a/mysql-test/t/bigint.test
+++ b/mysql-test/t/bigint.test
@@ -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;
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
new file mode 100644
index 00000000000..7a120ef5005
--- /dev/null
+++ b/mysql-test/t/cast.test
@@ -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";
diff --git a/mysql-test/t/constraints.test b/mysql-test/t/constraints.test
new file mode 100644
index 00000000000..8682cdc42a2
--- /dev/null
+++ b/mysql-test/t/constraints.test
@@ -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;
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 2ff57959965..dd589ff2e66 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -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
#
diff --git a/mysql-test/t/innodb-deadlock.test b/mysql-test/t/innodb-deadlock.test
new file mode 100644
index 00000000000..bc2839bfb3a
--- /dev/null
+++ b/mysql-test/t/innodb-deadlock.test
@@ -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;
diff --git a/mysql-test/t/innodb_cache.test b/mysql-test/t/innodb_cache.test
index 21d30420eaf..9066a5f19ba 100644
--- a/mysql-test/t/innodb_cache.test
+++ b/mysql-test/t/innodb_cache.test
@@ -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"; \ No newline at end of file
+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;
diff --git a/mysql-test/t/null_key.test b/mysql-test/t/null_key.test
index 3ab8b993f43..b1cbd5cdfb0 100644
--- a/mysql-test/t/null_key.test
+++ b/mysql-test/t/null_key.test
@@ -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;
diff --git a/sql/handler.cc b/sql/handler.cc
index b2cf86a6abc..cdd007f2cc2 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -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())
diff --git a/sql/item.h b/sql/item.h
index 39e90cef561..bed59b99def 100644
--- a/sql/item.h
+++ b/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); }
};
diff --git a/sql/item_create.cc b/sql/item_create.cc
index ad9058c1691..aa3e7779d73 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -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;
diff --git a/sql/item_func.h b/sql/item_func.h
index b3daa0d4890..38f461acc13 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -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
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 6a0aaa3b032..fc3b4da8561 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -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;
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 2b308630b48..9fd9143586e 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -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);
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 07cdfde115b..f9b987324f0 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -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:
diff --git a/sql/lex.h b/sql/lex.h
index 0d0d60fe204..1f83423a0ba 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -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)},
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index ebda24b404a..86da0e846a0 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -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)
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index cee5502fb32..0fad5769998 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -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);
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index c9e10b5b0b5..16d6b6d4631 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -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);
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 6cb146afb33..c8a29dcd8da 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -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);
}
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index e3ffe2a8120..e5860346863 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -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;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index ce3acb4f450..93f01dd66dc 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -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
};
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 42f9e446981..dde67b11d50 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -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);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index e3e0bca9856..f2a24eda530 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -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);
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 5dcb4f09951..fad0fb39020 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -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 {}