Merge ramayana.hindu.god:/home/tsmith/m/bk/51

into  ramayana.hindu.god:/home/tsmith/m/bk/maint/51
This commit is contained in:
tsmith@ramayana.hindu.god 2008-01-25 10:37:29 -07:00
commit 3906cc27d7
66 changed files with 1937 additions and 395 deletions

View File

@ -1727,6 +1727,30 @@ case "$with_atomic_ops" in
*) AC_MSG_ERROR(["$with_atomic_ops" is not a valid value for --with-atomic-ops]) ;; *) AC_MSG_ERROR(["$with_atomic_ops" is not a valid value for --with-atomic-ops]) ;;
esac esac
AC_CACHE_CHECK([whether the compiler provides atomic builtins],
[mysql_cv_gcc_atomic_builtins], [AC_TRY_RUN([
int main()
{
int foo= -10; int bar= 10;
if (!__sync_fetch_and_add(&foo, bar) || foo)
return -1;
bar= __sync_lock_test_and_set(&foo, bar);
if (bar || foo != 10)
return -1;
bar= __sync_val_compare_and_swap(&bar, foo, 15);
if (bar)
return -1;
return 0;
}
], [mysql_cv_gcc_atomic_builtins=yes],
[mysql_cv_gcc_atomic_builtins=no],
[mysql_cv_gcc_atomic_builtins=no])])
if test "x$mysql_cv_gcc_atomic_builtins" = xyes; then
AC_DEFINE(HAVE_GCC_ATOMIC_BUILTINS, 1,
[Define to 1 if compiler provides atomic builtins.])
fi
# Force static compilation to avoid linking problems/get more speed # Force static compilation to avoid linking problems/get more speed
AC_ARG_WITH(mysqld-ldflags, AC_ARG_WITH(mysqld-ldflags,
[ --with-mysqld-ldflags Extra linking arguments for mysqld], [ --with-mysqld-ldflags Extra linking arguments for mysqld],

View File

@ -36,7 +36,7 @@ noinst_HEADERS = config-win.h config-netware.h \
mysql_version.h.in my_handler.h my_time.h \ mysql_version.h.in my_handler.h my_time.h \
my_vle.h my_user.h my_atomic.h atomic/nolock.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \
atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
my_libwrap.h atomic/gcc_builtins.h my_libwrap.h
# Remove built files and the symlinked directories # Remove built files and the symlinked directories
CLEANFILES = $(BUILT_SOURCES) readline openssl CLEANFILES = $(BUILT_SOURCES) readline openssl

View File

@ -0,0 +1,33 @@
/* Copyright (C) 2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define make_atomic_add_body(S) \
v= __sync_fetch_and_add(a, v);
#define make_atomic_swap_body(S) \
v= __sync_lock_test_and_set(a, v);
#define make_atomic_cas_body(S) \
int ## S sav; \
sav= __sync_val_compare_and_swap(a, *cmp, set); \
if (!(ret= (sav == *cmp))) *cmp= sav;
#ifdef MY_ATOMIC_MODE_DUMMY
#define make_atomic_load_body(S) ret= *a
#define make_atomic_store_body(S) *a= v
#else
#define make_atomic_load_body(S) \
ret= __sync_fetch_and_or(a, 0);
#define make_atomic_store_body(S) \
(void) __sync_lock_test_and_set(a, v);
#endif

View File

@ -13,7 +13,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#if defined(__i386__) || defined(_M_IX86) #if defined(__i386__) || defined(_M_IX86) || defined(HAVE_GCC_ATOMIC_BUILTINS)
#ifdef MY_ATOMIC_MODE_DUMMY #ifdef MY_ATOMIC_MODE_DUMMY
# define LOCK "" # define LOCK ""
@ -21,7 +21,9 @@
# define LOCK "lock" # define LOCK "lock"
#endif #endif
#ifdef __GNUC__ #ifdef HAVE_GCC_ATOMIC_BUILTINS
#include "gcc_builtins.h"
#elif __GNUC__
#include "x86-gcc.h" #include "x86-gcc.h"
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#include "x86-msvc.h" #include "x86-msvc.h"

View File

@ -419,7 +419,7 @@ connection master;
update t31 set f5=555555555555555 where f3=6; update t31 set f5=555555555555555 where f3=6;
update t31 set f2=2 where f3=2; update t31 set f2=2 where f3=2;
update t31 set f1=NULL where f3=1; update t31 set f1=NULL where f3=1;
update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3;
--echo --echo
--echo ** Delete from Master ** --echo ** Delete from Master **

View File

@ -723,20 +723,6 @@ set @@sort_buffer_size=default;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Bug #32815: query with ORDER BY and a possible ref_or_null access
#
CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2);
EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
DROP TABLE t1;
# Test of behaviour with CREATE ... SELECT # Test of behaviour with CREATE ... SELECT
# #
@ -1091,6 +1077,19 @@ desc t1;
show create table t1; show create table t1;
drop table t1; drop table t1;
#
# Bug #32815: query with ORDER BY and a possible ref_or_null access
#
CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2);
EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
# Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY # Fix for BUG#19243 "wrong LAST_INSERT_ID() after ON DUPLICATE KEY
@ -1383,4 +1382,32 @@ create table t1 (a int auto_increment primary key) engine=innodb;
alter table t1 order by a; alter table t1 order by a;
drop table t1; drop table t1;
#
# Bug #33697: ORDER BY primary key DESC vs. ref access + filesort
# (reproduced only with InnoDB tables)
#
CREATE TABLE t1
(vid integer NOT NULL,
tid integer NOT NULL,
idx integer NOT NULL,
name varchar(128) NOT NULL,
type varchar(128) NULL,
PRIMARY KEY(idx, vid, tid),
UNIQUE(vid, tid, name)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(1,1,1,'pk',NULL),(2,1,1,'pk',NULL),(3,1,1,'pk',NULL),(4,1,1,'c1',NULL),
(5,1,1,'pk',NULL),(1,1,2,'c1',NULL),(2,1,2,'c1',NULL),(3,1,2,'c1',NULL),
(4,1,2,'c2',NULL),(5,1,2,'c1',NULL),(2,1,3,'c2',NULL),(3,1,3,'c2',NULL),
(4,1,3,'pk',NULL),(5,1,3,'c2',NULL),
(2,1,4,'c_extra',NULL),(3,1,4,'c_extra',NULL);
EXPLAIN SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC;
SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC;
DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests

View File

@ -108,6 +108,7 @@ execute stmt1 using @arg00, @arg01;
select a,b from t1 where a=@arg00; select a,b from t1 where a=@arg00;
set @arg00=NULL; set @arg00=NULL;
set @arg01=2; set @arg01=2;
--error 1048
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
select a,b from t1 order by a; select a,b from t1 order by a;
set @arg00=0; set @arg00=0;

View File

@ -231,8 +231,7 @@ a b
204 7 204 7
delete from t1 where a=0; delete from t1 where a=0;
update t1 set a=NULL where b=6; update t1 set a=NULL where b=6;
Warnings: ERROR 23000: Column 'a' cannot be null
Warning 1048 Column 'a' cannot be null
update t1 set a=300 where b=7; update t1 set a=300 where b=7;
SET SQL_MODE=''; SET SQL_MODE='';
insert into t1(a,b)values(NULL,8); insert into t1(a,b)values(NULL,8);
@ -247,7 +246,7 @@ a b
1 1 1 1
200 2 200 2
201 4 201 4
0 6 203 6
300 7 300 7
301 8 301 8
400 9 400 9
@ -263,6 +262,7 @@ a b
1 1 1 1
200 2 200 2
201 4 201 4
203 6
300 7 300 7
301 8 301 8
400 9 400 9
@ -273,20 +273,20 @@ a b
405 14 405 14
delete from t1 where a=0; delete from t1 where a=0;
update t1 set a=NULL where b=13; update t1 set a=NULL where b=13;
Warnings: ERROR 23000: Column 'a' cannot be null
Warning 1048 Column 'a' cannot be null
update t1 set a=500 where b=14; update t1 set a=500 where b=14;
select * from t1 order by b; select * from t1 order by b;
a b a b
1 1 1 1
200 2 200 2
201 4 201 4
203 6
300 7 300 7
301 8 301 8
400 9 400 9
401 10 401 10
402 11 402 11
0 13 404 13
500 14 500 14
drop table t1; drop table t1;
create table t1 (a bigint); create table t1 (a bigint);

View File

@ -1478,3 +1478,39 @@ NULL
1 1
2 2
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 ( a INT, b INT );
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1;
c (SELECT a FROM t1 WHERE b = c)
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1
HAVING b = 10;
c (SELECT a FROM t1 WHERE b = c)
SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c)
FROM t1
HAVING b = 10;
ERROR 42S22: Reference 'c' not supported (reference to group function)
SET @old_sql_mode = @@sql_mode;
SET @@sql_mode='ONLY_FULL_GROUP_BY';
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1;
c (SELECT a FROM t1 WHERE b = c)
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1
HAVING b = 10;
ERROR 42000: non-grouping field 'b' is used in HAVING clause
SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c)
FROM t1
HAVING b = 10;
ERROR 42S22: Reference 'c' not supported (reference to group function)
INSERT INTO t1 VALUES (1, 1);
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1;
c (SELECT a FROM t1 WHERE b = c)
1 1
INSERT INTO t1 VALUES (2, 1);
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1;
ERROR 21000: Subquery returns more than 1 row
DROP TABLE t1;
SET @@sql_mode = @old_sql_mode;

View File

@ -1349,7 +1349,7 @@ INSERT INTO t1 VALUES
(191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2); (191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2);
EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL idx NULL NULL NULL 3 Using where; Using filesort 1 SIMPLE t1 ALL idx NULL NULL NULL 4 Using where; Using filesort
SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
id type d id type d
191 member 1 191 member 1
@ -1609,4 +1609,29 @@ alter table t1 order by a;
Warnings: Warnings:
Warning 1105 ORDER BY ignored as there is a user-defined clustered index in the table 't1' Warning 1105 ORDER BY ignored as there is a user-defined clustered index in the table 't1'
drop table t1; drop table t1;
CREATE TABLE t1
(vid integer NOT NULL,
tid integer NOT NULL,
idx integer NOT NULL,
name varchar(128) NOT NULL,
type varchar(128) NULL,
PRIMARY KEY(idx, vid, tid),
UNIQUE(vid, tid, name)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(1,1,1,'pk',NULL),(2,1,1,'pk',NULL),(3,1,1,'pk',NULL),(4,1,1,'c1',NULL),
(5,1,1,'pk',NULL),(1,1,2,'c1',NULL),(2,1,2,'c1',NULL),(3,1,2,'c1',NULL),
(4,1,2,'c2',NULL),(5,1,2,'c1',NULL),(2,1,3,'c2',NULL),(3,1,3,'c2',NULL),
(4,1,3,'pk',NULL),(5,1,3,'c2',NULL),
(2,1,4,'c_extra',NULL),(3,1,4,'c_extra',NULL);
EXPLAIN SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index vid PRIMARY 12 NULL 16 Using where
SELECT * FROM t1 WHERE tid = 1 AND vid = 3 ORDER BY idx DESC;
vid tid idx name type
3 1 4 c_extra NULL
3 1 3 c2 NULL
3 1 2 c1 NULL
3 1 1 pk NULL
DROP TABLE t1;
End of 5.1 tests End of 5.1 tests

View File

@ -93,11 +93,9 @@ INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55";
Warnings: Warnings:
Warning 1265 Data truncated for column 'd' at row 1 Warning 1265 Data truncated for column 'd' at row 1
UPDATE t1 SET d=1/NULL; UPDATE t1 SET d=1/NULL;
Warnings: ERROR 23000: Column 'd' cannot be null
Warning 1265 Data truncated for column 'd' at row 1
UPDATE t1 SET d=NULL; UPDATE t1 SET d=NULL;
Warnings: ERROR 23000: Column 'd' cannot be null
Warning 1048 Column 'd' cannot be null
INSERT INTO t1 (a) values (null); INSERT INTO t1 (a) values (null);
ERROR 23000: Column 'a' cannot be null ERROR 23000: Column 'a' cannot be null
INSERT INTO t1 (a) values (1/null); INSERT INTO t1 (a) values (1/null);
@ -132,7 +130,7 @@ Warning 1048 Column 'd' cannot be null
Warning 1048 Column 'd' cannot be null Warning 1048 Column 'd' cannot be null
select * from t1; select * from t1;
a b c d a b c d
0 0000-00-00 00:00:00 0 0 0000-00-00 00:00:00 2003
0 0000-00-00 00:00:00 0 0 0000-00-00 00:00:00 0
0 0000-00-00 00:00:00 0 0 0000-00-00 00:00:00 0
0 0000-00-00 00:00:00 0 0 0000-00-00 00:00:00 0

View File

@ -527,3 +527,23 @@ SELECT * FROM t1 WHERE a = INTERVAL(3,2,1) + 1;
a b a b
3 1998-01-01 00:00:00 3 1998-01-01 00:00:00
DROP TABLE t1; DROP TABLE t1;
DROP TABLE IF EXISTS t1,t2,t3;
CREATE TABLE t1 (a1 INT, a2 INT, a3 INT, a4 DATETIME);
CREATE TABLE t2 LIKE t1;
CREATE TABLE t3 LIKE t1;
SELECT t1.* FROM t1 AS t0, { OJ t2 INNER JOIN t1 ON (t1.a1=t2.a1) } WHERE t0.a3=2;
a1 a2 a3 a4
SELECT t1.*,t2.* FROM { OJ ((t1 INNER JOIN t2 ON (t1.a1=t2.a2)) LEFT OUTER JOIN t3 ON t3.a3=t2.a1)};
a1 a2 a3 a4 a1 a2 a3 a4
SELECT t1.*,t2.* FROM { OJ ((t1 LEFT OUTER JOIN t2 ON t1.a3=t2.a2) INNER JOIN t3 ON (t3.a1=t2.a2))};
a1 a2 a3 a4 a1 a2 a3 a4
SELECT t1.*,t2.* FROM { OJ (t1 LEFT OUTER JOIN t2 ON t1.a1=t2.a2) CROSS JOIN t3 ON (t3.a2=t2.a3)};
a1 a2 a3 a4 a1 a2 a3 a4
SELECT * FROM {oj t1 LEFT OUTER JOIN t2 ON t1.a1=t2.a3} WHERE t1.a2 > 10;
a1 a2 a3 a4 a1 a2 a3 a4
SELECT {fn CONCAT(a1,a2)} FROM t1;
{fn CONCAT(a1,a2)}
UPDATE t3 SET a4={d '1789-07-14'} WHERE a1=0;
SELECT a1, a4 FROM t2 WHERE a4 LIKE {fn UCASE('1789-07-14')};
a1 a4
DROP TABLE t1, t2, t3;

View File

@ -1303,12 +1303,11 @@ a b
set @arg00=NULL; set @arg00=NULL;
set @arg01=2; set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: ERROR 23000: Column 'a' cannot be null
Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a; select a,b from t1 order by a;
a b a b
0 two
1 one 1 one
2 two
3 three 3 three
4 four 4 four
set @arg00=0; set @arg00=0;

View File

@ -1286,12 +1286,11 @@ a b
set @arg00=NULL; set @arg00=NULL;
set @arg01=2; set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: ERROR 23000: Column 'a' cannot be null
Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a; select a,b from t1 order by a;
a b a b
0 two
1 one 1 one
2 two
3 three 3 three
4 four 4 four
set @arg00=0; set @arg00=0;

View File

@ -1287,12 +1287,11 @@ a b
set @arg00=NULL; set @arg00=NULL;
set @arg01=2; set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: ERROR 23000: Column 'a' cannot be null
Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a; select a,b from t1 order by a;
a b a b
0 two
1 one 1 one
2 two
3 three 3 three
4 four 4 four
set @arg00=0; set @arg00=0;

View File

@ -1329,12 +1329,11 @@ a b
set @arg00=NULL; set @arg00=NULL;
set @arg01=2; set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: ERROR 23000: Column 'a' cannot be null
Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a; select a,b from t1 order by a;
a b a b
0 two
1 one 1 one
2 two
3 three 3 three
4 four 4 four
set @arg00=0; set @arg00=0;
@ -4351,12 +4350,11 @@ a b
set @arg00=NULL; set @arg00=NULL;
set @arg01=2; set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: ERROR 23000: Column 'a' cannot be null
Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a; select a,b from t1 order by a;
a b a b
0 two
1 one 1 one
2 two
3 three 3 three
4 four 4 four
set @arg00=0; set @arg00=0;

View File

@ -0,0 +1,24 @@
flush status;
set query_cache_type=DEMAND;
set global query_cache_size= 1024*1024*512;
drop table if exists t1;
create table t1 (a varchar(100));
insert into t1 values ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
Activate debug hook and attempt to retrieve the statement from the cache.
set session debug='+d,wait_in_query_cache_insert';
select SQL_CACHE * from t1;;
On a second connection; clear the query cache.
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 1
set global query_cache_size= 0;
Signal the debug hook to release the lock.
select id from information_schema.processlist where state='wait_in_query_cache_insert' into @thread_id;
kill query @thread_id;
Show query cache status.
show status like 'Qcache_queries_in_cache';
Variable_name Value
Qcache_queries_in_cache 0
set global query_cache_size= 0;
use test;
drop table t1;

View File

@ -733,6 +733,115 @@ optimizer: keep hreturn
drop table t1; drop table t1;
drop procedure proc_26977_broken; drop procedure proc_26977_broken;
drop procedure proc_26977_works; drop procedure proc_26977_works;
drop procedure if exists proc_33618_h;
drop procedure if exists proc_33618_c;
create procedure proc_33618_h(num int)
begin
declare count1 int default '0';
declare vb varchar(30);
declare last_row int;
while(num>=1) do
set num=num-1;
begin
declare cur1 cursor for select `a` from t_33618;
declare continue handler for not found set last_row = 1;
set last_row:=0;
open cur1;
rep1:
repeat
begin
declare exit handler for 1062 begin end;
fetch cur1 into vb;
if (last_row = 1) then
## should generate a hpop instruction here
leave rep1;
end if;
end;
until last_row=1
end repeat;
close cur1;
end;
end while;
end//
create procedure proc_33618_c(num int)
begin
declare count1 int default '0';
declare vb varchar(30);
declare last_row int;
while(num>=1) do
set num=num-1;
begin
declare cur1 cursor for select `a` from t_33618;
declare continue handler for not found set last_row = 1;
set last_row:=0;
open cur1;
rep1:
repeat
begin
declare cur2 cursor for select `b` from t_33618;
fetch cur1 into vb;
if (last_row = 1) then
## should generate a cpop instruction here
leave rep1;
end if;
end;
until last_row=1
end repeat;
close cur1;
end;
end while;
end//
show procedure code proc_33618_h;
Pos Instruction
0 set count1@1 _latin1'0'
1 set vb@2 NULL
2 set last_row@3 NULL
3 jump_if_not 24(24) (num@0 >= 1)
4 set num@0 (num@0 - 1)
5 cpush cur1@0
6 hpush_jump 9 4 CONTINUE
7 set last_row@3 1
8 hreturn 4
9 set last_row@3 0
10 copen cur1@0
11 hpush_jump 13 4 EXIT
12 hreturn 0 17
13 cfetch cur1@0 vb@2
14 jump_if_not 17(17) (last_row@3 = 1)
15 hpop 1
16 jump 19
17 hpop 1
18 jump_if_not 11(19) (last_row@3 = 1)
19 cclose cur1@0
20 hpop 1
21 cpop 1
22 jump 3
show procedure code proc_33618_c;
Pos Instruction
0 set count1@1 _latin1'0'
1 set vb@2 NULL
2 set last_row@3 NULL
3 jump_if_not 23(23) (num@0 >= 1)
4 set num@0 (num@0 - 1)
5 cpush cur1@0
6 hpush_jump 9 4 CONTINUE
7 set last_row@3 1
8 hreturn 4
9 set last_row@3 0
10 copen cur1@0
11 cpush cur2@1
12 cfetch cur1@0 vb@2
13 jump_if_not 16(16) (last_row@3 = 1)
14 cpop 1
15 jump 18
16 cpop 1
17 jump_if_not 11(18) (last_row@3 = 1)
18 cclose cur1@0
19 hpop 1
20 cpop 1
21 jump 3
drop procedure proc_33618_h;
drop procedure proc_33618_c;
End of 5.0 tests. End of 5.0 tests.
CREATE PROCEDURE p1() CREATE PROCEDURE p1()
BEGIN BEGIN

View File

@ -1579,3 +1579,51 @@ drop function f2;
drop table t2; drop table t2;
ERROR 42S02: Unknown table 't2' ERROR 42S02: Unknown table 't2'
End of 5.1 tests End of 5.1 tests
drop procedure if exists proc_33983_a;
drop procedure if exists proc_33983_b;
drop procedure if exists proc_33983_c;
drop procedure if exists proc_33983_d;
create procedure proc_33983_a()
begin
label1:
begin
label2:
begin
select 1;
end label1;
end;
end|
ERROR 42000: End-label label1 without match
create procedure proc_33983_b()
begin
label1:
repeat
label2:
repeat
select 1;
until FALSE end repeat label1;
until FALSE end repeat;
end|
ERROR 42000: End-label label1 without match
create procedure proc_33983_c()
begin
label1:
while TRUE do
label2:
while TRUE do
select 1;
end while label1;
end while;
end|
ERROR 42000: End-label label1 without match
create procedure proc_33983_d()
begin
label1:
loop
label2:
loop
select 1;
end loop label1;
end loop;
end|
ERROR 42000: End-label label1 without match

View File

@ -6812,7 +6812,59 @@ DROP PROCEDURE db28318_b.t2;
DROP DATABASE db28318_a; DROP DATABASE db28318_a;
DROP DATABASE db28318_b; DROP DATABASE db28318_b;
use test; use test;
End of 5.0 tests DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS bug29770;
CREATE TABLE t1(a int);
CREATE PROCEDURE bug29770()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S22' SET @state:= 'run';
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @exception:= 'run';
SELECT x FROM t1;
END|
CALL bug29770();
SELECT @state, @exception;
@state @exception
run NULL
DROP TABLE t1;
DROP PROCEDURE bug29770;
use test;
drop table if exists t_33618;
drop procedure if exists proc_33618;
create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam;
insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2');
create procedure proc_33618(num int)
begin
declare count1 int default '0';
declare vb varchar(30);
declare last_row int;
while(num>=1) do
set num=num-1;
begin
declare cur1 cursor for select `a` from t_33618;
declare continue handler for not found set last_row = 1;
set last_row:=0;
open cur1;
rep1:
repeat
begin
declare exit handler for 1062 begin end;
fetch cur1 into vb;
if (last_row = 1) then
leave rep1;
end if;
end;
until last_row=1
end repeat;
close cur1;
end;
end while;
end//
call proc_33618(20);
drop table t_33618;
drop procedure proc_33618;
# ------------------------------------------------------------------
# -- End of 5.0 tests
# ------------------------------------------------------------------
# #
# Bug#20550. # Bug#20550.
@ -6911,4 +6963,6 @@ END latin1 latin1_swedish_ci latin1_swedish_ci
DROP FUNCTION f1; DROP FUNCTION f1;
End of 5.1 tests # ------------------------------------------------------------------
# -- End of 5.1 tests
# ------------------------------------------------------------------

View File

@ -4291,6 +4291,54 @@ select count(*) from t1 where f12 =
count(*) count(*)
3 3
drop table t1,t2; drop table t1,t2;
CREATE TABLE t4 (
f7 varchar(32) collate utf8_bin NOT NULL default '',
f10 varchar(32) collate utf8_bin default NULL,
PRIMARY KEY (f7)
);
INSERT INTO t4 VALUES(1,1), (2,null);
CREATE TABLE t2 (
f4 varchar(32) collate utf8_bin NOT NULL default '',
f2 varchar(50) collate utf8_bin default NULL,
f3 varchar(10) collate utf8_bin default NULL,
PRIMARY KEY (f4),
UNIQUE KEY uk1 (f2)
);
INSERT INTO t2 VALUES(1,1,null), (2,2,null);
CREATE TABLE t1 (
f8 varchar(32) collate utf8_bin NOT NULL default '',
f1 varchar(10) collate utf8_bin default NULL,
f9 varchar(32) collate utf8_bin default NULL,
PRIMARY KEY (f8)
);
INSERT INTO t1 VALUES (1,'P',1), (2,'P',1), (3,'R',2);
CREATE TABLE t3 (
f6 varchar(32) collate utf8_bin NOT NULL default '',
f5 varchar(50) collate utf8_bin default NULL,
PRIMARY KEY (f6)
);
INSERT INTO t3 VALUES (1,null), (2,null);
SELECT
IF(t1.f1 = 'R', a1.f2, t2.f2) AS a4,
IF(t1.f1 = 'R', a1.f3, t2.f3) AS f3,
SUM(
IF(
(SELECT VPC.f2
FROM t2 VPC, t4 a2, t2 a3
WHERE
VPC.f4 = a2.f10 AND a3.f2 = a4
LIMIT 1) IS NULL,
0,
t3.f5
)
) AS a6
FROM
t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4
GROUP BY a4;
a4 f3 a6
1 NULL NULL
2 NULL NULL
DROP TABLE t1, t2, t3, t4;
End of 5.0 tests. End of 5.0 tests.
CREATE TABLE t1 (a int, b int); CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22); INSERT INTO t1 VALUES (2,22),(1,11),(2,22);

View File

@ -794,7 +794,7 @@ dps tinyint(3) unsigned default NULL
INSERT INTO t1 VALUES (1.1325,3); INSERT INTO t1 VALUES (1.1325,3);
SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1; SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1;
ROUND(qty,3) dps ROUND(qty,dps) ROUND(qty,3) dps ROUND(qty,dps)
1.133 3 1.133 1.133 3 1.133000
DROP TABLE t1; DROP TABLE t1;
SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%'; SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%';
% %
@ -885,4 +885,65 @@ c
1000 1000
1234567890 1234567890
DROP TABLE t1, t2, t3, t4; DROP TABLE t1, t2, t3, t4;
CREATE TABLE t1( a DECIMAL(4, 3), b INT );
INSERT INTO t1 VALUES ( 1, 5 ), ( 2, 4 ), ( 3, 3 ), ( 4, 2 ), ( 5, 1 );
SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c;
a b c
1.000 5 1.000
2.000 4 2.000
3.000 3 3.000
4.000 2 4.000
5.000 1 5.000
SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c DESC;
a b c
5.000 1 5.000
4.000 2 4.000
3.000 3 3.000
2.000 4 2.000
1.000 5 1.000
CREATE TABLE t2 ( a INT, b INT, c DECIMAL(5, 4) );
INSERT INTO t2 VALUES ( 0, 1, 1.2345 ), ( 1, 2, 1.2345 ),
( 3, 3, 1.2345 ), ( 2, 4, 1.2345 );
SELECT a, b, MAX(ROUND(c, a))
FROM t2
GROUP BY a, b
ORDER BY b;
a b MAX(ROUND(c, a))
0 1 1.0000
1 2 1.2000
3 3 1.2350
2 4 1.2300
SELECT a, b, ROUND(c, a)
FROM t2;
a b ROUND(c, a)
0 1 1.0000
1 2 1.2000
3 3 1.2350
2 4 1.2300
CREATE TABLE t3( a INT, b DECIMAL(6, 3) );
INSERT INTO t3 VALUES( 0, 1.5 );
SELECT ROUND( b, a ) FROM t3;
ROUND( b, a )
2.000
CREATE TABLE t4( a INT, b DECIMAL( 12, 0) );
INSERT INTO t4 VALUES( -9, 1.5e9 );
SELECT ROUND( b, a ) FROM t4;
ROUND( b, a )
2000000000
CREATE TABLE t5( a INT, b DECIMAL( 13, 12 ) );
INSERT INTO t5 VALUES( 0, 1.5 );
INSERT INTO t5 VALUES( 9, 1.5e-9 );
SELECT ROUND( b, a ) FROM t5;
ROUND( b, a )
2.000000000000
0.000000002000
CREATE TABLE t6( a INT );
INSERT INTO t6 VALUES( 6 / 8 );
SELECT * FROM t6;
a
1
SELECT ROUND(20061108085411.000002);
ROUND(20061108085411.000002)
20061108085411
DROP TABLE t1, t2, t3, t4, t5, t6;
End of 5.0 tests End of 5.0 tests

View File

@ -3597,6 +3597,22 @@ DROP VIEW v1;
DROP VIEW v2; DROP VIEW v2;
DROP VIEW v3; DROP VIEW v3;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#29477: Not all fields of the target table were checked to have
# a default value when inserting into a view.
#
create table t1(f1 int, f2 int not null);
create view v1 as select f1 from t1;
insert into v1 values(1);
Warnings:
Warning 1423 Field of view 'test.v1' underlying table doesn't have a default value
set @old_mode=@@sql_mode;
set @@sql_mode=traditional;
insert into v1 values(1);
ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default value
set @@sql_mode=@old_mode;
drop view v1;
drop table t1;
End of 5.0 tests. End of 5.0 tests.
DROP DATABASE IF EXISTS `d-1`; DROP DATABASE IF EXISTS `d-1`;
CREATE DATABASE `d-1`; CREATE DATABASE `d-1`;

View File

@ -98,8 +98,7 @@ Warning 1265 Data truncated for column 'c' at row 1
Warning 1265 Data truncated for column 'c' at row 2 Warning 1265 Data truncated for column 'c' at row 2
alter table t1 add d char(2); alter table t1 add d char(2);
update t1 set a=NULL where a=10; update t1 set a=NULL where a=10;
Warnings: ERROR 23000: Column 'a' cannot be null
Warning 1048 Column 'a' cannot be null
update t1 set c='mysql ab' where c='test'; update t1 set c='mysql ab' where c='test';
Warnings: Warnings:
Warning 1265 Data truncated for column 'c' at row 4 Warning 1265 Data truncated for column 'c' at row 4

View File

@ -1286,12 +1286,11 @@ a b
set @arg00=NULL; set @arg00=NULL;
set @arg01=2; set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: ERROR 23000: Column 'a' cannot be null
Warning 1048 Column 'a' cannot be null
select a,b from t1 order by a; select a,b from t1 order by a;
a b a b
0 two
1 one 1 one
2 two
3 three 3 three
4 four 4 four
set @arg00=0; set @arg00=0;

View File

@ -454,9 +454,7 @@ f1 f2 f3 f4
update t31 set f5=555555555555555 where f3=6; update t31 set f5=555555555555555 where f3=6;
update t31 set f2=2 where f3=2; update t31 set f2=2 where f3=2;
update t31 set f1=NULL where f3=1; update t31 set f1=NULL where f3=1;
update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3;
Warnings:
Warning 1048 Column 'f3' cannot be null
** Delete from Master ** ** Delete from Master **
@ -1595,9 +1593,7 @@ f1 f2 f3 f4
update t31 set f5=555555555555555 where f3=6; update t31 set f5=555555555555555 where f3=6;
update t31 set f2=2 where f3=2; update t31 set f2=2 where f3=2;
update t31 set f1=NULL where f3=1; update t31 set f1=NULL where f3=1;
update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3;
Warnings:
Warning 1048 Column 'f3' cannot be null
** Delete from Master ** ** Delete from Master **
@ -2736,9 +2732,7 @@ f1 f2 f3 f4
update t31 set f5=555555555555555 where f3=6; update t31 set f5=555555555555555 where f3=6;
update t31 set f2=2 where f3=2; update t31 set f2=2 where f3=2;
update t31 set f1=NULL where f3=1; update t31 set f1=NULL where f3=1;
update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3;
Warnings:
Warning 1048 Column 'f3' cannot be null
** Delete from Master ** ** Delete from Master **

View File

@ -454,9 +454,7 @@ f1 f2 f3 f4
update t31 set f5=555555555555555 where f3=6; update t31 set f5=555555555555555 where f3=6;
update t31 set f2=2 where f3=2; update t31 set f2=2 where f3=2;
update t31 set f1=NULL where f3=1; update t31 set f1=NULL where f3=1;
update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3;
Warnings:
Warning 1048 Column 'f3' cannot be null
** Delete from Master ** ** Delete from Master **
@ -1595,9 +1593,7 @@ f1 f2 f3 f4
update t31 set f5=555555555555555 where f3=6; update t31 set f5=555555555555555 where f3=6;
update t31 set f2=2 where f3=2; update t31 set f2=2 where f3=2;
update t31 set f1=NULL where f3=1; update t31 set f1=NULL where f3=1;
update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3;
Warnings:
Warning 1048 Column 'f3' cannot be null
** Delete from Master ** ** Delete from Master **
@ -2736,9 +2732,7 @@ f1 f2 f3 f4
update t31 set f5=555555555555555 where f3=6; update t31 set f5=555555555555555 where f3=6;
update t31 set f2=2 where f3=2; update t31 set f2=2 where f3=2;
update t31 set f1=NULL where f3=1; update t31 set f1=NULL where f3=1;
update t31 set f3=NULL, f27=NULL, f35='f35 new value' where f3=3; update t31 set f3=0, f27=NULL, f35='f35 new value' where f3=3;
Warnings:
Warning 1048 Column 'f3' cannot be null
** Delete from Master ** ** Delete from Master **

View File

@ -49,7 +49,7 @@ kill @id;
drop table t2,t3; drop table t2,t3;
insert into t4 values (3),(4); insert into t4 values (3),(4);
connection master; connection master;
--error 0,1053,2013 --error 0,1053,2013,1048
reap; reap;
connection master1; connection master1;
save_master_pos; save_master_pos;

View File

@ -149,6 +149,7 @@ delete from t1 where a=0;
update t1 set a=0 where b=5; update t1 set a=0 where b=5;
select * from t1 order by b; select * from t1 order by b;
delete from t1 where a=0; delete from t1 where a=0;
--error 1048
update t1 set a=NULL where b=6; update t1 set a=NULL where b=6;
update t1 set a=300 where b=7; update t1 set a=300 where b=7;
SET SQL_MODE=''; SET SQL_MODE='';
@ -164,6 +165,7 @@ delete from t1 where a=0;
update t1 set a=0 where b=12; update t1 set a=0 where b=12;
select * from t1 order by b; select * from t1 order by b;
delete from t1 where a=0; delete from t1 where a=0;
--error 1048
update t1 set a=NULL where b=13; update t1 set a=NULL where b=13;
update t1 set a=500 where b=14; update t1 set a=500 where b=14;
select * from t1 order by b; select * from t1 order by b;

View File

@ -789,8 +789,6 @@ select t1.f1,t.* from t1, t1 t group by 1;
drop table t1; drop table t1;
SET SQL_MODE = ''; SET SQL_MODE = '';
#
# #
# Bug #32202: ORDER BY not working with GROUP BY # Bug #32202: ORDER BY not working with GROUP BY
# #
@ -824,6 +822,7 @@ SELECT * FROM t1 GROUP BY c2 ORDER BY c2 DESC, c1 DESC;
DROP TABLE t1; DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
# Bug #21174: Index degrades sort performance and # Bug #21174: Index degrades sort performance and
# optimizer does not honor IGNORE INDEX. # optimizer does not honor IGNORE INDEX.
@ -946,3 +945,51 @@ EXPLAIN SELECT b from t2 GROUP BY b;
SELECT b from t2 GROUP BY b; SELECT b from t2 GROUP BY b;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #31797: error while parsing subqueries -- WHERE is parsed as HAVING
#
CREATE TABLE t1 ( a INT, b INT );
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1;
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1
HAVING b = 10;
--error ER_ILLEGAL_REFERENCE
SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c)
FROM t1
HAVING b = 10;
SET @old_sql_mode = @@sql_mode;
SET @@sql_mode='ONLY_FULL_GROUP_BY';
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1;
--error ER_NON_GROUPING_FIELD_USED
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1
HAVING b = 10;
--error ER_ILLEGAL_REFERENCE
SELECT MAX(b) c, (SELECT a FROM t1 WHERE b = c)
FROM t1
HAVING b = 10;
INSERT INTO t1 VALUES (1, 1);
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1;
INSERT INTO t1 VALUES (2, 1);
--error ER_SUBQUERY_NO_1_ROW
SELECT b c, (SELECT a FROM t1 WHERE b = c)
FROM t1;
DROP TABLE t1;
SET @@sql_mode = @old_sql_mode;

View File

@ -61,7 +61,9 @@ drop table t1;
# #
CREATE TABLE t1 (a varchar(16) NOT NULL default '', b smallint(6) NOT NULL default 0, c datetime NOT NULL default '0000-00-00 00:00:00', d smallint(6) NOT NULL default 0); CREATE TABLE t1 (a varchar(16) NOT NULL default '', b smallint(6) NOT NULL default 0, c datetime NOT NULL default '0000-00-00 00:00:00', d smallint(6) NOT NULL default 0);
INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55"; INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55";
--error 1048
UPDATE t1 SET d=1/NULL; UPDATE t1 SET d=1/NULL;
--error 1048
UPDATE t1 SET d=NULL; UPDATE t1 SET d=NULL;
--error 1048 --error 1048
INSERT INTO t1 (a) values (null); INSERT INTO t1 (a) values (null);

View File

@ -657,3 +657,23 @@ CREATE TABLE t1 (a INT, b DATETIME);
INSERT INTO t1 VALUES (INTERVAL(3,2,1) + 1, "1997-12-31 23:59:59" + INTERVAL 1 SECOND); INSERT INTO t1 VALUES (INTERVAL(3,2,1) + 1, "1997-12-31 23:59:59" + INTERVAL 1 SECOND);
SELECT * FROM t1 WHERE a = INTERVAL(3,2,1) + 1; SELECT * FROM t1 WHERE a = INTERVAL(3,2,1) + 1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#28317 Left Outer Join with {oj outer-join}
#
--disable_warnings
DROP TABLE IF EXISTS t1,t2,t3;
--enable_warnings
CREATE TABLE t1 (a1 INT, a2 INT, a3 INT, a4 DATETIME);
CREATE TABLE t2 LIKE t1;
CREATE TABLE t3 LIKE t1;
SELECT t1.* FROM t1 AS t0, { OJ t2 INNER JOIN t1 ON (t1.a1=t2.a1) } WHERE t0.a3=2;
SELECT t1.*,t2.* FROM { OJ ((t1 INNER JOIN t2 ON (t1.a1=t2.a2)) LEFT OUTER JOIN t3 ON t3.a3=t2.a1)};
SELECT t1.*,t2.* FROM { OJ ((t1 LEFT OUTER JOIN t2 ON t1.a3=t2.a2) INNER JOIN t3 ON (t3.a1=t2.a2))};
SELECT t1.*,t2.* FROM { OJ (t1 LEFT OUTER JOIN t2 ON t1.a1=t2.a2) CROSS JOIN t3 ON (t3.a2=t2.a3)};
SELECT * FROM {oj t1 LEFT OUTER JOIN t2 ON t1.a1=t2.a3} WHERE t1.a2 > 10;
SELECT {fn CONCAT(a1,a2)} FROM t1;
UPDATE t3 SET a4={d '1789-07-14'} WHERE a1=0;
SELECT a1, a4 FROM t2 WHERE a4 LIKE {fn UCASE('1789-07-14')};
DROP TABLE t1, t2, t3;

View File

@ -1316,6 +1316,5 @@ SELECT 1 FROM t1 GROUP BY
(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1); (SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
DROP TABLE t1; DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests

View File

@ -0,0 +1,46 @@
--source include/not_embedded.inc
--source include/have_query_cache.inc
--source include/have_debug.inc
#
# Bug #30887 Server crashes on SET GLOBAL query_cache_size=0
#
flush status;
set query_cache_type=DEMAND;
set global query_cache_size= 1024*1024*512;
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a varchar(100));
insert into t1 values ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
connect (bug30887con1, localhost, root, ,test);
connect (bug30887con2, localhost, root, ,test);
connection bug30887con1;
--echo Activate debug hook and attempt to retrieve the statement from the cache.
set session debug='+d,wait_in_query_cache_insert';
--send select SQL_CACHE * from t1;
connection default;
let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'wait_in_query_cache_insert';
--source include/wait_condition.inc
connection bug30887con2;
--echo On a second connection; clear the query cache.
show status like 'Qcache_queries_in_cache';
set global query_cache_size= 0;
connection default;
--echo Signal the debug hook to release the lock.
select id from information_schema.processlist where state='wait_in_query_cache_insert' into @thread_id;
kill query @thread_id;
--echo Show query cache status.
show status like 'Qcache_queries_in_cache';
disconnect bug30887con1;
disconnect bug30887con2;
set global query_cache_size= 0;
use test;
drop table t1;

View File

@ -520,6 +520,83 @@ drop table t1;
drop procedure proc_26977_broken; drop procedure proc_26977_broken;
drop procedure proc_26977_works; drop procedure proc_26977_works;
#
# Bug#33618 Crash in sp_rcontext
#
--disable_warnings
drop procedure if exists proc_33618_h;
drop procedure if exists proc_33618_c;
--enable_warnings
delimiter //;
create procedure proc_33618_h(num int)
begin
declare count1 int default '0';
declare vb varchar(30);
declare last_row int;
while(num>=1) do
set num=num-1;
begin
declare cur1 cursor for select `a` from t_33618;
declare continue handler for not found set last_row = 1;
set last_row:=0;
open cur1;
rep1:
repeat
begin
declare exit handler for 1062 begin end;
fetch cur1 into vb;
if (last_row = 1) then
## should generate a hpop instruction here
leave rep1;
end if;
end;
until last_row=1
end repeat;
close cur1;
end;
end while;
end//
create procedure proc_33618_c(num int)
begin
declare count1 int default '0';
declare vb varchar(30);
declare last_row int;
while(num>=1) do
set num=num-1;
begin
declare cur1 cursor for select `a` from t_33618;
declare continue handler for not found set last_row = 1;
set last_row:=0;
open cur1;
rep1:
repeat
begin
declare cur2 cursor for select `b` from t_33618;
fetch cur1 into vb;
if (last_row = 1) then
## should generate a cpop instruction here
leave rep1;
end if;
end;
until last_row=1
end repeat;
close cur1;
end;
end while;
end//
delimiter ;//
show procedure code proc_33618_h;
show procedure code proc_33618_c;
drop procedure proc_33618_h;
drop procedure proc_33618_c;
--echo End of 5.0 tests. --echo End of 5.0 tests.

View File

@ -2305,6 +2305,69 @@ drop table t2;
--echo End of 5.1 tests --echo End of 5.1 tests
#
# Bug#33983 (Stored Procedures: wrong end <label> syntax is accepted)
#
--disable_warnings
drop procedure if exists proc_33983_a;
drop procedure if exists proc_33983_b;
drop procedure if exists proc_33983_c;
drop procedure if exists proc_33983_d;
--enable_warnings
delimiter |;
--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_a()
begin
label1:
begin
label2:
begin
select 1;
end label1;
end;
end|
--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_b()
begin
label1:
repeat
label2:
repeat
select 1;
until FALSE end repeat label1;
until FALSE end repeat;
end|
--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_c()
begin
label1:
while TRUE do
label2:
while TRUE do
select 1;
end while label1;
end while;
end|
--error ER_SP_LABEL_MISMATCH
create procedure proc_33983_d()
begin
label1:
loop
label2:
loop
select 1;
end loop label1;
end loop;
end|
delimiter ;|
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #

View File

@ -7902,7 +7902,86 @@ use test;
########################################################################### ###########################################################################
--echo End of 5.0 tests #
# Bug#29770 Two handlers are allowed to catch an error in an stored procedure.
#
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS bug29770;
--enable_warnings
CREATE TABLE t1(a int);
delimiter |;
CREATE PROCEDURE bug29770()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S22' SET @state:= 'run';
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @exception:= 'run';
SELECT x FROM t1;
END|
delimiter ;|
CALL bug29770();
SELECT @state, @exception;
DROP TABLE t1;
DROP PROCEDURE bug29770;
#
# Bug#33618 Crash in sp_rcontext
#
use test;
--disable_warnings
drop table if exists t_33618;
drop procedure if exists proc_33618;
--enable_warnings
create table t_33618 (`a` int, unique(`a`), `b` varchar(30)) engine=myisam;
insert into t_33618 (`a`,`b`) values (1,'1'),(2,'2');
delimiter //;
create procedure proc_33618(num int)
begin
declare count1 int default '0';
declare vb varchar(30);
declare last_row int;
while(num>=1) do
set num=num-1;
begin
declare cur1 cursor for select `a` from t_33618;
declare continue handler for not found set last_row = 1;
set last_row:=0;
open cur1;
rep1:
repeat
begin
declare exit handler for 1062 begin end;
fetch cur1 into vb;
if (last_row = 1) then
leave rep1;
end if;
end;
until last_row=1
end repeat;
close cur1;
end;
end while;
end//
delimiter ;//
call proc_33618(20);
drop table t_33618;
drop procedure proc_33618;
###########################################################################
--echo # ------------------------------------------------------------------
--echo # -- End of 5.0 tests
--echo # ------------------------------------------------------------------
########################################################################### ###########################################################################
@ -8056,4 +8135,6 @@ DROP FUNCTION f1;
########################################################################### ###########################################################################
--echo End of 5.1 tests --echo # ------------------------------------------------------------------
--echo # -- End of 5.1 tests
--echo # ------------------------------------------------------------------

View File

@ -3159,6 +3159,60 @@ select count(*) from t1 where f12 =
drop table t1,t2; drop table t1,t2;
#
# BUG#33794 "MySQL crashes executing specific query on specific dump"
#
CREATE TABLE t4 (
f7 varchar(32) collate utf8_bin NOT NULL default '',
f10 varchar(32) collate utf8_bin default NULL,
PRIMARY KEY (f7)
);
INSERT INTO t4 VALUES(1,1), (2,null);
CREATE TABLE t2 (
f4 varchar(32) collate utf8_bin NOT NULL default '',
f2 varchar(50) collate utf8_bin default NULL,
f3 varchar(10) collate utf8_bin default NULL,
PRIMARY KEY (f4),
UNIQUE KEY uk1 (f2)
);
INSERT INTO t2 VALUES(1,1,null), (2,2,null);
CREATE TABLE t1 (
f8 varchar(32) collate utf8_bin NOT NULL default '',
f1 varchar(10) collate utf8_bin default NULL,
f9 varchar(32) collate utf8_bin default NULL,
PRIMARY KEY (f8)
);
INSERT INTO t1 VALUES (1,'P',1), (2,'P',1), (3,'R',2);
CREATE TABLE t3 (
f6 varchar(32) collate utf8_bin NOT NULL default '',
f5 varchar(50) collate utf8_bin default NULL,
PRIMARY KEY (f6)
);
INSERT INTO t3 VALUES (1,null), (2,null);
SELECT
IF(t1.f1 = 'R', a1.f2, t2.f2) AS a4,
IF(t1.f1 = 'R', a1.f3, t2.f3) AS f3,
SUM(
IF(
(SELECT VPC.f2
FROM t2 VPC, t4 a2, t2 a3
WHERE
VPC.f4 = a2.f10 AND a3.f2 = a4
LIMIT 1) IS NULL,
0,
t3.f5
)
) AS a6
FROM
t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4
GROUP BY a4;
DROP TABLE t1, t2, t3, t4;
--echo End of 5.0 tests. --echo End of 5.0 tests.
# #
@ -3194,3 +3248,4 @@ CREATE TABLE t1 (s1 char(1));
INSERT INTO t1 VALUES ('a'); INSERT INTO t1 VALUES ('a');
SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
DROP TABLE t1; DROP TABLE t1;

View File

@ -478,4 +478,47 @@ select round(a,b) as c from t1 order by c;
DROP TABLE t1, t2, t3, t4; DROP TABLE t1, t2, t3, t4;
#
# Bug #33143: Incorrect ORDER BY for ROUND()/TRUNCATE() result
#
CREATE TABLE t1( a DECIMAL(4, 3), b INT );
INSERT INTO t1 VALUES ( 1, 5 ), ( 2, 4 ), ( 3, 3 ), ( 4, 2 ), ( 5, 1 );
SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c;
SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c DESC;
CREATE TABLE t2 ( a INT, b INT, c DECIMAL(5, 4) );
INSERT INTO t2 VALUES ( 0, 1, 1.2345 ), ( 1, 2, 1.2345 ),
( 3, 3, 1.2345 ), ( 2, 4, 1.2345 );
SELECT a, b, MAX(ROUND(c, a))
FROM t2
GROUP BY a, b
ORDER BY b;
SELECT a, b, ROUND(c, a)
FROM t2;
CREATE TABLE t3( a INT, b DECIMAL(6, 3) );
INSERT INTO t3 VALUES( 0, 1.5 );
SELECT ROUND( b, a ) FROM t3;
CREATE TABLE t4( a INT, b DECIMAL( 12, 0) );
INSERT INTO t4 VALUES( -9, 1.5e9 );
SELECT ROUND( b, a ) FROM t4;
CREATE TABLE t5( a INT, b DECIMAL( 13, 12 ) );
INSERT INTO t5 VALUES( 0, 1.5 );
INSERT INTO t5 VALUES( 9, 1.5e-9 );
SELECT ROUND( b, a ) FROM t5;
CREATE TABLE t6( a INT );
INSERT INTO t6 VALUES( 6 / 8 );
SELECT * FROM t6;
SELECT ROUND(20061108085411.000002);
DROP TABLE t1, t2, t3, t4, t5, t6;
--echo End of 5.0 tests --echo End of 5.0 tests

View File

@ -3453,6 +3453,20 @@ DROP VIEW v2;
DROP VIEW v3; DROP VIEW v3;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Bug#29477: Not all fields of the target table were checked to have
--echo # a default value when inserting into a view.
--echo #
create table t1(f1 int, f2 int not null);
create view v1 as select f1 from t1;
insert into v1 values(1);
set @old_mode=@@sql_mode;
set @@sql_mode=traditional;
--error ER_NO_DEFAULT_FOR_VIEW_FIELD
insert into v1 values(1);
set @@sql_mode=@old_mode;
drop view v1;
drop table t1;
--echo End of 5.0 tests. --echo End of 5.0 tests.

View File

@ -65,6 +65,7 @@ create table t1(a tinyint NOT NULL, b tinyint unsigned, c char(5));
insert into t1 values(NULL,100,'mysql'),(10,-1,'mysql ab'),(500,256,'open source'),(20,NULL,'test'); insert into t1 values(NULL,100,'mysql'),(10,-1,'mysql ab'),(500,256,'open source'),(20,NULL,'test');
alter table t1 modify c char(4); alter table t1 modify c char(4);
alter table t1 add d char(2); alter table t1 add d char(2);
--error 1048
update t1 set a=NULL where a=10; update t1 set a=NULL where a=10;
update t1 set c='mysql ab' where c='test'; update t1 set c='mysql ab' where c='test';
update t1 set d=c; update t1 set d=c;

View File

@ -367,7 +367,7 @@ bool ha_partition::initialise_partition(MEM_ROOT *mem_root)
HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_CAN_SQL_HANDLER, HA_DUPLICATE_POS, HA_CAN_GEOMETRY, HA_CAN_FULLTEXT, HA_CAN_SQL_HANDLER, HA_DUPLICATE_POS,
HA_CAN_INSERT_DELAYED is disabled until further investigated. HA_CAN_INSERT_DELAYED is disabled until further investigated.
*/ */
m_table_flags= (ulong)m_file[0]->table_flags(); m_table_flags= (ulong)m_file[0]->ha_table_flags();
m_low_byte_first= m_file[0]->low_byte_first(); m_low_byte_first= m_file[0]->low_byte_first();
m_pkey_is_clustered= TRUE; m_pkey_is_clustered= TRUE;
file_array= m_file; file_array= m_file;
@ -382,7 +382,7 @@ bool ha_partition::initialise_partition(MEM_ROOT *mem_root)
} }
if (!file->primary_key_is_clustered()) if (!file->primary_key_is_clustered())
m_pkey_is_clustered= FALSE; m_pkey_is_clustered= FALSE;
m_table_flags&= file->table_flags(); m_table_flags&= file->ha_table_flags();
} while (*(++file_array)); } while (*(++file_array));
m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPLICATE_POS | m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPLICATE_POS |
HA_CAN_SQL_HANDLER | HA_CAN_INSERT_DELAYED | HA_CAN_SQL_HANDLER | HA_CAN_INSERT_DELAYED |
@ -616,7 +616,7 @@ int ha_partition::drop_partitions(const char *path)
sub_elem->partition_name, name_variant); sub_elem->partition_name, name_variant);
file= m_file[part]; file= m_file[part];
DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff)); DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff));
if ((ret_error= file->delete_table((const char *) part_name_buff))) if ((ret_error= file->ha_delete_table(part_name_buff)))
error= ret_error; error= ret_error;
if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
@ -629,7 +629,7 @@ int ha_partition::drop_partitions(const char *path)
TRUE); TRUE);
file= m_file[i]; file= m_file[i];
DBUG_PRINT("info", ("Drop partition %s", part_name_buff)); DBUG_PRINT("info", ("Drop partition %s", part_name_buff));
if ((ret_error= file->delete_table((const char *) part_name_buff))) if ((ret_error= file->ha_delete_table(part_name_buff)))
error= ret_error; error= ret_error;
if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
error= 1; error= 1;
@ -707,7 +707,7 @@ int ha_partition::rename_partitions(const char *path)
sub_elem->partition_name, sub_elem->partition_name,
NORMAL_PART_NAME); NORMAL_PART_NAME);
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if ((ret_error= file->delete_table((const char *) norm_name_buff))) if ((ret_error= file->ha_delete_table(norm_name_buff)))
error= ret_error; error= ret_error;
else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
@ -722,7 +722,7 @@ int ha_partition::rename_partitions(const char *path)
part_elem->partition_name, NORMAL_PART_NAME, part_elem->partition_name, NORMAL_PART_NAME,
TRUE); TRUE);
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
if ((ret_error= file->delete_table((const char *) norm_name_buff))) if ((ret_error= file->ha_delete_table(norm_name_buff)))
error= ret_error; error= ret_error;
else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
error= 1; error= 1;
@ -778,7 +778,7 @@ int ha_partition::rename_partitions(const char *path)
{ {
file= m_reorged_file[part_count++]; file= m_reorged_file[part_count++];
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if ((ret_error= file->delete_table((const char *) norm_name_buff))) if ((ret_error= file->ha_delete_table(norm_name_buff)))
error= ret_error; error= ret_error;
else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
@ -791,8 +791,8 @@ int ha_partition::rename_partitions(const char *path)
TEMP_PART_NAME); TEMP_PART_NAME);
DBUG_PRINT("info", ("Rename subpartition from %s to %s", DBUG_PRINT("info", ("Rename subpartition from %s to %s",
part_name_buff, norm_name_buff)); part_name_buff, norm_name_buff));
if ((ret_error= file->rename_table((const char *) part_name_buff, if ((ret_error= file->ha_rename_table(part_name_buff,
(const char *) norm_name_buff))) norm_name_buff)))
error= ret_error; error= ret_error;
else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
@ -809,7 +809,7 @@ int ha_partition::rename_partitions(const char *path)
{ {
file= m_reorged_file[part_count++]; file= m_reorged_file[part_count++];
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
if ((ret_error= file->delete_table((const char *) norm_name_buff))) if ((ret_error= file->ha_delete_table(norm_name_buff)))
error= ret_error; error= ret_error;
else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
error= 1; error= 1;
@ -821,8 +821,8 @@ int ha_partition::rename_partitions(const char *path)
TRUE); TRUE);
DBUG_PRINT("info", ("Rename partition from %s to %s", DBUG_PRINT("info", ("Rename partition from %s to %s",
part_name_buff, norm_name_buff)); part_name_buff, norm_name_buff));
if ((ret_error= file->rename_table((const char *) part_name_buff, if ((ret_error= file->ha_rename_table(part_name_buff,
(const char *) norm_name_buff))) norm_name_buff)))
error= ret_error; error= ret_error;
else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
error= 1; error= 1;
@ -1036,9 +1036,9 @@ static int handle_opt_part(THD *thd, HA_CHECK_OPT *check_opt,
DBUG_PRINT("enter", ("flag = %u", flag)); DBUG_PRINT("enter", ("flag = %u", flag));
if (flag == OPTIMIZE_PARTS) if (flag == OPTIMIZE_PARTS)
error= file->optimize(thd, check_opt); error= file->ha_optimize(thd, check_opt);
else if (flag == ANALYZE_PARTS) else if (flag == ANALYZE_PARTS)
error= file->analyze(thd, check_opt); error= file->ha_analyze(thd, check_opt);
else if (flag == CHECK_PARTS) else if (flag == CHECK_PARTS)
error= file->ha_check(thd, check_opt); error= file->ha_check(thd, check_opt);
else if (flag == REPAIR_PARTS) else if (flag == REPAIR_PARTS)
@ -1139,7 +1139,7 @@ int ha_partition::prepare_new_partition(TABLE *tbl,
if ((error= set_up_table_before_create(tbl, part_name, create_info, if ((error= set_up_table_before_create(tbl, part_name, create_info,
0, p_elem))) 0, p_elem)))
goto error; goto error;
if ((error= file->create(part_name, tbl, create_info))) if ((error= file->ha_create(part_name, tbl, create_info)))
goto error; goto error;
create_flag= TRUE; create_flag= TRUE;
if ((error= file->ha_open(tbl, part_name, m_mode, m_open_test_lock))) if ((error= file->ha_open(tbl, part_name, m_mode, m_open_test_lock)))
@ -1150,13 +1150,13 @@ int ha_partition::prepare_new_partition(TABLE *tbl,
assumes that external_lock() is last call that may fail here. assumes that external_lock() is last call that may fail here.
Otherwise see description for cleanup_new_partition(). Otherwise see description for cleanup_new_partition().
*/ */
if ((error= file->external_lock(current_thd, m_lock_type))) if ((error= file->ha_external_lock(current_thd, m_lock_type)))
goto error; goto error;
DBUG_RETURN(0); DBUG_RETURN(0);
error: error:
if (create_flag) if (create_flag)
VOID(file->delete_table(part_name)); VOID(file->ha_delete_table(part_name));
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -1574,14 +1574,18 @@ int ha_partition::copy_partitions(ulonglong *copied, ulonglong *deleted)
} }
else else
{ {
THD *thd= ha_thd();
/* Copy record to new handler */ /* Copy record to new handler */
copied++; copied++;
if ((result= m_new_file[new_part]->write_row(m_rec0))) tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
result= m_new_file[new_part]->ha_write_row(m_rec0);
reenable_binlog(thd);
if (result)
goto error; goto error;
} }
} }
late_extra_no_cache(reorg_part); late_extra_no_cache(reorg_part);
file->rnd_end(); file->ha_rnd_end();
reorg_part++; reorg_part++;
} }
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
@ -1698,16 +1702,15 @@ uint ha_partition::del_ren_cre_table(const char *from,
{ // Rename branch { // Rename branch
create_partition_name(to_buff, to, name_buffer_ptr, NORMAL_PART_NAME, create_partition_name(to_buff, to, name_buffer_ptr, NORMAL_PART_NAME,
FALSE); FALSE);
error= (*file)->rename_table((const char*) from_buff, error= (*file)->ha_rename_table(from_buff, to_buff);
(const char*) to_buff);
} }
else if (table_arg == NULL) // delete branch else if (table_arg == NULL) // delete branch
error= (*file)->delete_table((const char*) from_buff); error= (*file)->ha_delete_table(from_buff);
else else
{ {
if ((error= set_up_table_before_create(table_arg, from_buff, if ((error= set_up_table_before_create(table_arg, from_buff,
create_info, i, NULL)) || create_info, i, NULL)) ||
((error= (*file)->create(from_buff, table_arg, create_info)))) ((error= (*file)->ha_create(from_buff, table_arg, create_info))))
goto create_error; goto create_error;
} }
name_buffer_ptr= strend(name_buffer_ptr) + 1; name_buffer_ptr= strend(name_buffer_ptr) + 1;
@ -1722,7 +1725,7 @@ create_error:
{ {
create_partition_name(from_buff, from, name_buffer_ptr, NORMAL_PART_NAME, create_partition_name(from_buff, from, name_buffer_ptr, NORMAL_PART_NAME,
FALSE); FALSE);
VOID((*file)->delete_table((const char*) from_buff)); VOID((*file)->ha_delete_table((const char*) from_buff));
name_buffer_ptr= strend(name_buffer_ptr) + 1; name_buffer_ptr= strend(name_buffer_ptr) + 1;
} }
DBUG_RETURN(error); DBUG_RETURN(error);
@ -2314,7 +2317,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
} }
/* Recalculate table flags as they may change after open */ /* Recalculate table flags as they may change after open */
m_table_flags= m_file[0]->table_flags(); m_table_flags= m_file[0]->ha_table_flags();
file= m_file; file= m_file;
do do
{ {
@ -2326,7 +2329,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
m_no_locks+= (*file)->lock_count(); m_no_locks+= (*file)->lock_count();
name_buffer_ptr+= strlen(name_buffer_ptr) + 1; name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
set_if_bigger(ref_length, ((*file)->ref_length)); set_if_bigger(ref_length, ((*file)->ref_length));
m_table_flags&= (*file)->table_flags(); m_table_flags&= (*file)->ha_table_flags();
} while (*(++file)); } while (*(++file));
m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPLICATE_POS | m_table_flags&= ~(HA_CAN_GEOMETRY | HA_CAN_FULLTEXT | HA_DUPLICATE_POS |
HA_CAN_SQL_HANDLER | HA_CAN_INSERT_DELAYED); HA_CAN_SQL_HANDLER | HA_CAN_INSERT_DELAYED);
@ -2482,7 +2485,7 @@ repeat:
{ {
DBUG_PRINT("info", ("external_lock(thd, %d) iteration %d", DBUG_PRINT("info", ("external_lock(thd, %d) iteration %d",
lock_type, (int) (file - m_file))); lock_type, (int) (file - m_file)));
if ((error= (*file)->external_lock(thd, lock_type))) if ((error= (*file)->ha_external_lock(thd, lock_type)))
{ {
if (F_UNLCK != lock_type) if (F_UNLCK != lock_type)
goto err_handler; goto err_handler;
@ -2501,7 +2504,7 @@ repeat:
err_handler: err_handler:
while (file-- != m_file) while (file-- != m_file)
{ {
(*file)->external_lock(thd, F_UNLCK); (*file)->ha_external_lock(thd, F_UNLCK);
} }
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -2694,6 +2697,7 @@ int ha_partition::write_row(uchar * buf)
longlong func_value; longlong func_value;
bool autoincrement_lock= FALSE; bool autoincrement_lock= FALSE;
my_bitmap_map *old_map; my_bitmap_map *old_map;
THD *thd= ha_thd();
#ifdef NOT_NEEDED #ifdef NOT_NEEDED
uchar *rec0= m_rec0; uchar *rec0= m_rec0;
#endif #endif
@ -2765,7 +2769,9 @@ int ha_partition::write_row(uchar * buf)
} }
m_last_part= part_id; m_last_part= part_id;
DBUG_PRINT("info", ("Insert in partition %d", part_id)); DBUG_PRINT("info", ("Insert in partition %d", part_id));
error= m_file[part_id]->write_row(buf); tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
error= m_file[part_id]->ha_write_row(buf);
reenable_binlog(thd);
exit: exit:
if (autoincrement_lock) if (autoincrement_lock)
pthread_mutex_unlock(&table_share->mutex); pthread_mutex_unlock(&table_share->mutex);
@ -2806,6 +2812,7 @@ exit:
int ha_partition::update_row(const uchar *old_data, uchar *new_data) int ha_partition::update_row(const uchar *old_data, uchar *new_data)
{ {
THD *thd= ha_thd();
uint32 new_part_id, old_part_id; uint32 new_part_id, old_part_id;
int error= 0; int error= 0;
longlong func_value; longlong func_value;
@ -2840,16 +2847,25 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data)
if (new_part_id == old_part_id) if (new_part_id == old_part_id)
{ {
DBUG_PRINT("info", ("Update in partition %d", new_part_id)); DBUG_PRINT("info", ("Update in partition %d", new_part_id));
error= m_file[new_part_id]->update_row(old_data, new_data); tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
error= m_file[new_part_id]->ha_update_row(old_data, new_data);
reenable_binlog(thd);
goto exit; goto exit;
} }
else else
{ {
DBUG_PRINT("info", ("Update from partition %d to partition %d", DBUG_PRINT("info", ("Update from partition %d to partition %d",
old_part_id, new_part_id)); old_part_id, new_part_id));
if ((error= m_file[new_part_id]->write_row(new_data))) tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
error= m_file[new_part_id]->ha_write_row(new_data);
reenable_binlog(thd);
if (error)
goto exit; goto exit;
if ((error= m_file[old_part_id]->delete_row(old_data)))
tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
error= m_file[old_part_id]->ha_delete_row(old_data);
reenable_binlog(thd);
if (error)
{ {
#ifdef IN_THE_FUTURE #ifdef IN_THE_FUTURE
(void) m_file[new_part_id]->delete_last_inserted_row(new_data); (void) m_file[new_part_id]->delete_last_inserted_row(new_data);
@ -2896,6 +2912,7 @@ int ha_partition::delete_row(const uchar *buf)
{ {
uint32 part_id; uint32 part_id;
int error; int error;
THD *thd= ha_thd();
DBUG_ENTER("ha_partition::delete_row"); DBUG_ENTER("ha_partition::delete_row");
if ((error= get_part_for_delete(buf, m_rec0, m_part_info, &part_id))) if ((error= get_part_for_delete(buf, m_rec0, m_part_info, &part_id)))
@ -2903,7 +2920,10 @@ int ha_partition::delete_row(const uchar *buf)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
m_last_part= part_id; m_last_part= part_id;
DBUG_RETURN(m_file[part_id]->delete_row(buf)); tmp_disable_binlog(thd);
error= m_file[part_id]->ha_delete_row(buf);
reenable_binlog(thd);
DBUG_RETURN(error);
} }
@ -2938,7 +2958,7 @@ int ha_partition::delete_all_rows()
file= m_file; file= m_file;
do do
{ {
if ((error= (*file)->delete_all_rows())) if ((error= (*file)->ha_delete_all_rows()))
DBUG_RETURN(error); DBUG_RETURN(error);
} while (*(++file)); } while (*(++file));
DBUG_RETURN(0); DBUG_RETURN(0);
@ -3980,7 +4000,7 @@ int ha_partition::partition_scan_set_up(uchar * buf, bool idx_read_flag)
int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same) int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same)
{ {
handler *file= file= m_file[m_part_spec.start_part]; handler *file= m_file[m_part_spec.start_part];
int error; int error;
DBUG_ENTER("ha_partition::handle_unordered_next"); DBUG_ENTER("ha_partition::handle_unordered_next");
@ -3999,7 +4019,7 @@ int ha_partition::handle_unordered_next(uchar *buf, bool is_next_same)
} }
else if (!(error= file->index_next(buf))) else if (!(error= file->index_next(buf)))
{ {
if (!(file->table_flags() & HA_READ_ORDER) || if (!(file->ha_table_flags() & HA_READ_ORDER) ||
compare_key(end_range) <= 0) compare_key(end_range) <= 0)
{ {
m_last_part= m_part_spec.start_part; m_last_part= m_part_spec.start_part;
@ -4077,7 +4097,7 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
} }
if (!error) if (!error)
{ {
if (!(file->table_flags() & HA_READ_ORDER) || if (!(file->ha_table_flags() & HA_READ_ORDER) ||
compare_key(end_range) <= 0) compare_key(end_range) <= 0)
{ {
m_last_part= i; m_last_part= i;
@ -4999,7 +5019,7 @@ int ha_partition::reset(void)
file= m_file; file= m_file;
do do
{ {
if ((tmp= (*file)->reset())) if ((tmp= (*file)->ha_reset()))
result= tmp; result= tmp;
} while (*(++file)); } while (*(++file));
DBUG_RETURN(result); DBUG_RETURN(result);
@ -5641,7 +5661,7 @@ void ha_partition::release_auto_increment()
for (uint i= 0; i < m_tot_parts; i++) for (uint i= 0; i < m_tot_parts; i++)
{ {
m_file[i]->release_auto_increment(); m_file[i]->ha_release_auto_increment();
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -5677,7 +5697,7 @@ int ha_partition::disable_indexes(uint mode)
for (file= m_file; *file; file++) for (file= m_file; *file; file++)
{ {
if ((error= (*file)->disable_indexes(mode))) if ((error= (*file)->ha_disable_indexes(mode)))
break; break;
} }
return error; return error;
@ -5701,7 +5721,7 @@ int ha_partition::enable_indexes(uint mode)
for (file= m_file; *file; file++) for (file= m_file; *file; file++)
{ {
if ((error= (*file)->enable_indexes(mode))) if ((error= (*file)->ha_enable_indexes(mode)))
break; break;
} }
return error; return error;

View File

@ -1479,7 +1479,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
DBUG_RETURN(ENOENT); DBUG_RETURN(ENOENT);
path= check_lowercase_names(file, path, tmp_path); path= check_lowercase_names(file, path, tmp_path);
if ((error= file->delete_table(path)) && generate_warning) if ((error= file->ha_delete_table(path)) && generate_warning)
{ {
/* /*
Because file->print_error() use my_error() to generate the error message Because file->print_error() use my_error() to generate the error message
@ -1498,8 +1498,7 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
dummy_share.table_name.length= strlen(alias); dummy_share.table_name.length= strlen(alias);
dummy_table.alias= alias; dummy_table.alias= alias;
file->table_share= &dummy_share; file->change_table_ptr(&dummy_table, &dummy_share);
file->table= &dummy_table;
thd->push_internal_handler(&ha_delete_table_error_handler); thd->push_internal_handler(&ha_delete_table_error_handler);
file->print_error(error, 0); file->print_error(error, 0);
@ -2508,6 +2507,12 @@ int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
} }
/**
Repair table: public interface.
@sa handler::repair()
*/
int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt) int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
{ {
int result; int result;
@ -2517,6 +2522,328 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
} }
/**
Bulk update row: public interface.
@sa handler::bulk_update_row()
*/
int
handler::ha_bulk_update_row(const uchar *old_data, uchar *new_data,
uint *dup_key_found)
{
return bulk_update_row(old_data, new_data, dup_key_found);
}
/**
Delete all rows: public interface.
@sa handler::delete_all_rows()
*/
int
handler::ha_delete_all_rows()
{
return delete_all_rows();
}
/**
Reset auto increment: public interface.
@sa handler::reset_auto_increment()
*/
int
handler::ha_reset_auto_increment(ulonglong value)
{
return reset_auto_increment(value);
}
/**
Backup table: public interface.
@sa handler::backup()
*/
int
handler::ha_backup(THD* thd, HA_CHECK_OPT* check_opt)
{
return backup(thd, check_opt);
}
/**
Restore table: public interface.
@sa handler::restore()
*/
int
handler::ha_restore(THD* thd, HA_CHECK_OPT* check_opt)
{
return restore(thd, check_opt);
}
/**
Optimize table: public interface.
@sa handler::optimize()
*/
int
handler::ha_optimize(THD* thd, HA_CHECK_OPT* check_opt)
{
return optimize(thd, check_opt);
}
/**
Analyze table: public interface.
@sa handler::analyze()
*/
int
handler::ha_analyze(THD* thd, HA_CHECK_OPT* check_opt)
{
return analyze(thd, check_opt);
}
/**
Check and repair table: public interface.
@sa handler::check_and_repair()
*/
bool
handler::ha_check_and_repair(THD *thd)
{
return check_and_repair(thd);
}
/**
Disable indexes: public interface.
@sa handler::disable_indexes()
*/
int
handler::ha_disable_indexes(uint mode)
{
return disable_indexes(mode);
}
/**
Enable indexes: public interface.
@sa handler::enable_indexes()
*/
int
handler::ha_enable_indexes(uint mode)
{
return enable_indexes(mode);
}
/**
Discard or import tablespace: public interface.
@sa handler::discard_or_import_tablespace()
*/
int
handler::ha_discard_or_import_tablespace(my_bool discard)
{
return discard_or_import_tablespace(discard);
}
/**
Prepare for alter: public interface.
Called to prepare an *online* ALTER.
@sa handler::prepare_for_alter()
*/
void
handler::ha_prepare_for_alter()
{
prepare_for_alter();
}
/**
Rename table: public interface.
@sa handler::rename_table()
*/
int
handler::ha_rename_table(const char *from, const char *to)
{
return rename_table(from, to);
}
/**
Delete table: public interface.
@sa handler::delete_table()
*/
int
handler::ha_delete_table(const char *name)
{
return delete_table(name);
}
/**
Drop table in the engine: public interface.
@sa handler::drop_table()
*/
void
handler::ha_drop_table(const char *name)
{
return drop_table(name);
}
/**
Create a table in the engine: public interface.
@sa handler::create()
*/
int
handler::ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info)
{
return create(name, form, info);
}
/**
Create handler files for CREATE TABLE: public interface.
@sa handler::create_handler_files()
*/
int
handler::ha_create_handler_files(const char *name, const char *old_name,
int action_flag, HA_CREATE_INFO *info)
{
return create_handler_files(name, old_name, action_flag, info);
}
/**
Change partitions: public interface.
@sa handler::change_partitions()
*/
int
handler::ha_change_partitions(HA_CREATE_INFO *create_info,
const char *path,
ulonglong *copied,
ulonglong *deleted,
const uchar *pack_frm_data,
size_t pack_frm_len)
{
return change_partitions(create_info, path, copied, deleted,
pack_frm_data, pack_frm_len);
}
/**
Drop partitions: public interface.
@sa handler::drop_partitions()
*/
int
handler::ha_drop_partitions(const char *path)
{
return drop_partitions(path);
}
/**
Rename partitions: public interface.
@sa handler::rename_partitions()
*/
int
handler::ha_rename_partitions(const char *path)
{
return rename_partitions(path);
}
/**
Optimize partitions: public interface.
@sa handler::optimize_partitions()
*/
int
handler::ha_optimize_partitions(THD *thd)
{
return optimize_partitions(thd);
}
/**
Analyze partitions: public interface.
@sa handler::analyze_partitions()
*/
int
handler::ha_analyze_partitions(THD *thd)
{
return analyze_partitions(thd);
}
/**
Check partitions: public interface.
@sa handler::check_partitions()
*/
int
handler::ha_check_partitions(THD *thd)
{
return check_partitions(thd);
}
/**
Repair partitions: public interface.
@sa handler::repair_partitions()
*/
int
handler::ha_repair_partitions(THD *thd)
{
return repair_partitions(thd);
}
/** /**
Tell the storage engine that it is allowed to "disable transaction" in the Tell the storage engine that it is allowed to "disable transaction" in the
handler. It is a hint that ACID is not required - it is used in NDB for handler. It is a hint that ACID is not required - it is used in NDB for
@ -2657,7 +2984,7 @@ int ha_create_table(THD *thd, const char *path,
name= check_lowercase_names(table.file, share.path.str, name_buff); name= check_lowercase_names(table.file, share.path.str, name_buff);
error= table.file->create(name, &table, create_info); error= table.file->ha_create(name, &table, create_info);
VOID(closefrm(&table, 0)); VOID(closefrm(&table, 0));
if (error) if (error)
{ {
@ -2728,7 +3055,7 @@ int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE; create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE;
check_lowercase_names(table.file, path, path); check_lowercase_names(table.file, path, path);
error=table.file->create(path,&table,&create_info); error=table.file->ha_create(path, &table, &create_info);
VOID(closefrm(&table, 1)); VOID(closefrm(&table, 1));
DBUG_RETURN(error != 0); DBUG_RETURN(error != 0);

View File

@ -967,10 +967,6 @@ uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
class handler :public Sql_alloc class handler :public Sql_alloc
{ {
friend class ha_partition;
friend int ha_delete_table(THD*,handlerton*,const char*,const char*,
const char*,bool);
public: public:
typedef ulonglong Table_flags; typedef ulonglong Table_flags;
protected: protected:
@ -1118,6 +1114,40 @@ public:
estimation_rows_to_insert= 0; estimation_rows_to_insert= 0;
return end_bulk_insert(); return end_bulk_insert();
} }
int ha_bulk_update_row(const uchar *old_data, uchar *new_data,
uint *dup_key_found);
int ha_delete_all_rows();
int ha_reset_auto_increment(ulonglong value);
int ha_backup(THD* thd, HA_CHECK_OPT* check_opt);
int ha_restore(THD* thd, HA_CHECK_OPT* check_opt);
int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt);
int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt);
bool ha_check_and_repair(THD *thd);
int ha_disable_indexes(uint mode);
int ha_enable_indexes(uint mode);
int ha_discard_or_import_tablespace(my_bool discard);
void ha_prepare_for_alter();
int ha_rename_table(const char *from, const char *to);
int ha_delete_table(const char *name);
void ha_drop_table(const char *name);
int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
int ha_create_handler_files(const char *name, const char *old_name,
int action_flag, HA_CREATE_INFO *info);
int ha_change_partitions(HA_CREATE_INFO *create_info,
const char *path,
ulonglong *copied,
ulonglong *deleted,
const uchar *pack_frm_data,
size_t pack_frm_len);
int ha_drop_partitions(const char *path);
int ha_rename_partitions(const char *path);
int ha_optimize_partitions(THD *thd);
int ha_analyze_partitions(THD *thd);
int ha_check_partitions(THD *thd);
int ha_repair_partitions(THD *thd);
void adjust_next_insert_id_after_explicit_value(ulonglong nr); void adjust_next_insert_id_after_explicit_value(ulonglong nr);
int update_auto_increment(); int update_auto_increment();
@ -1203,25 +1233,6 @@ public:
@retval 1 Bulk delete not used, normal operation used @retval 1 Bulk delete not used, normal operation used
*/ */
virtual bool start_bulk_delete() { return 1; } virtual bool start_bulk_delete() { return 1; }
/**
This method is similar to update_row, however the handler doesn't need
to execute the updates at this point in time. The handler can be certain
that another call to bulk_update_row will occur OR a call to
exec_bulk_update before the set of updates in this query is concluded.
@param old_data Old record
@param new_data New record
@param dup_key_found Number of duplicate keys found
@retval 0 Bulk delete used by handler
@retval 1 Bulk delete not used, normal operation used
*/
virtual int bulk_update_row(const uchar *old_data, uchar *new_data,
uint *dup_key_found)
{
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
}
/** /**
After this call all outstanding updates must be performed. The number After this call all outstanding updates must be performed. The number
of duplicate key errors are reported in the duplicate key parameter. of duplicate key errors are reported in the duplicate key parameter.
@ -1365,14 +1376,6 @@ public:
virtual void try_semi_consistent_read(bool) {} virtual void try_semi_consistent_read(bool) {}
virtual void unlock_row() {} virtual void unlock_row() {}
virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;} virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
/**
This is called to delete all rows in a table
If the handler don't support this, then this function will
return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
by one.
*/
virtual int delete_all_rows()
{ return (my_errno=HA_ERR_WRONG_COMMAND); }
virtual void get_auto_increment(ulonglong offset, ulonglong increment, virtual void get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong nb_desired_values, ulonglong nb_desired_values,
ulonglong *first_value, ulonglong *first_value,
@ -1397,42 +1400,17 @@ public:
next_insert_id= (prev_insert_id > 0) ? prev_insert_id : next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
insert_id_for_cur_row; insert_id_for_cur_row;
} }
/**
Reset the auto-increment counter to the given value, i.e. the next row
inserted will get the given value. This is called e.g. after TRUNCATE
is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
returned by storage engines that don't support this operation.
*/
virtual int reset_auto_increment(ulonglong value)
{ return HA_ERR_WRONG_COMMAND; }
virtual void update_create_info(HA_CREATE_INFO *create_info) {} virtual void update_create_info(HA_CREATE_INFO *create_info) {}
int check_old_types(); int check_old_types();
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
/**
Restore assumes .frm file must exist, and that generate_table() has been
called; It will just copy the data file and run repair.
*/
virtual int restore(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt) virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; } { return HA_ADMIN_NOT_IMPLEMENTED; }
virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt) virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; } { return HA_ADMIN_NOT_IMPLEMENTED; }
/* end of the list of admin commands */ /* end of the list of admin commands */
virtual bool check_and_repair(THD *thd) { return HA_ERR_WRONG_COMMAND; }
virtual int dump(THD* thd, int fd = -1) { return HA_ERR_WRONG_COMMAND; } virtual int dump(THD* thd, int fd = -1) { return HA_ERR_WRONG_COMMAND; }
virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int indexes_are_disabled(void) {return 0;} virtual int indexes_are_disabled(void) {return 0;}
virtual int discard_or_import_tablespace(my_bool discard)
{return HA_ERR_WRONG_COMMAND;}
virtual int net_read_dump(NET* net) { return HA_ERR_WRONG_COMMAND; } virtual int net_read_dump(NET* net) { return HA_ERR_WRONG_COMMAND; }
virtual char *update_table_comment(const char * comment) virtual char *update_table_comment(const char * comment)
{ return (char*) comment;} { return (char*) comment;}
@ -1489,7 +1467,6 @@ public:
virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0; virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
virtual void prepare_for_alter() { return; }
virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys) virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
{ return (HA_ERR_WRONG_COMMAND); } { return (HA_ERR_WRONG_COMMAND); }
virtual int prepare_drop_index(TABLE *table_arg, uint *key_num, virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
@ -1521,44 +1498,12 @@ public:
virtual bool is_crashed() const { return 0; } virtual bool is_crashed() const { return 0; }
virtual bool auto_repair() const { return 0; } virtual bool auto_repair() const { return 0; }
/**
default rename_table() and delete_table() rename/delete files with a
given name and extensions from bas_ext()
*/
virtual int rename_table(const char *from, const char *to);
virtual int delete_table(const char *name);
virtual void drop_table(const char *name);
virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
#define CHF_CREATE_FLAG 0 #define CHF_CREATE_FLAG 0
#define CHF_DELETE_FLAG 1 #define CHF_DELETE_FLAG 1
#define CHF_RENAME_FLAG 2 #define CHF_RENAME_FLAG 2
#define CHF_INDEX_FLAG 3 #define CHF_INDEX_FLAG 3
virtual int create_handler_files(const char *name, const char *old_name,
int action_flag, HA_CREATE_INFO *info)
{ return FALSE; }
virtual int change_partitions(HA_CREATE_INFO *create_info,
const char *path,
ulonglong *copied,
ulonglong *deleted,
const uchar *pack_frm_data,
size_t pack_frm_len)
{ return HA_ERR_WRONG_COMMAND; }
virtual int drop_partitions(const char *path)
{ return HA_ERR_WRONG_COMMAND; }
virtual int rename_partitions(const char *path)
{ return HA_ERR_WRONG_COMMAND; }
virtual int optimize_partitions(THD *thd)
{ return HA_ERR_WRONG_COMMAND; }
virtual int analyze_partitions(THD *thd)
{ return HA_ERR_WRONG_COMMAND; }
virtual int check_partitions(THD *thd)
{ return HA_ERR_WRONG_COMMAND; }
virtual int repair_partitions(THD *thd)
{ return HA_ERR_WRONG_COMMAND; }
/** /**
@note lock_count() can return > 1 if the table is MERGE or partitioned. @note lock_count() can return > 1 if the table is MERGE or partitioned.
@ -1674,22 +1619,6 @@ public:
uint table_changes) uint table_changes)
{ return COMPATIBLE_DATA_NO; } { return COMPATIBLE_DATA_NO; }
/** These are only called from sql_select for internal temporary tables */
virtual int write_row(uchar *buf __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
virtual int update_row(const uchar *old_data __attribute__((unused)),
uchar *new_data __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
virtual int delete_row(const uchar *buf __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
/** /**
use_hidden_primary_key() is called in case of an update/delete when use_hidden_primary_key() is called in case of an update/delete when
(table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined (table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
@ -1702,6 +1631,16 @@ protected:
void ha_statistic_increment(ulong SSV::*offset) const; void ha_statistic_increment(ulong SSV::*offset) const;
void **ha_data(THD *) const; void **ha_data(THD *) const;
THD *ha_thd(void) const; THD *ha_thd(void) const;
/**
Default rename_table() and delete_table() rename/delete files with a
given name and extensions from bas_ext().
These methods can be overridden, but their default implementation
provide useful functionality.
*/
virtual int rename_table(const char *from, const char *to);
virtual int delete_table(const char *name);
private: private:
/* /*
Low-level primitives for storage engines. These should be Low-level primitives for storage engines. These should be
@ -1721,6 +1660,21 @@ private:
*/ */
virtual int rnd_init(bool scan)= 0; virtual int rnd_init(bool scan)= 0;
virtual int rnd_end() { return 0; } virtual int rnd_end() { return 0; }
virtual int write_row(uchar *buf __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
virtual int update_row(const uchar *old_data __attribute__((unused)),
uchar *new_data __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
virtual int delete_row(const uchar *buf __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
/** /**
Reset state of file to after 'open'. Reset state of file to after 'open'.
This function is called after every statement for all tables used This function is called after every statement for all tables used
@ -1776,6 +1730,85 @@ private:
{ return HA_ERR_WRONG_COMMAND; } { return HA_ERR_WRONG_COMMAND; }
virtual int index_read_last(uchar * buf, const uchar * key, uint key_len) virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
{ return (my_errno= HA_ERR_WRONG_COMMAND); } { return (my_errno= HA_ERR_WRONG_COMMAND); }
/**
This method is similar to update_row, however the handler doesn't need
to execute the updates at this point in time. The handler can be certain
that another call to bulk_update_row will occur OR a call to
exec_bulk_update before the set of updates in this query is concluded.
@param old_data Old record
@param new_data New record
@param dup_key_found Number of duplicate keys found
@retval 0 Bulk delete used by handler
@retval 1 Bulk delete not used, normal operation used
*/
virtual int bulk_update_row(const uchar *old_data, uchar *new_data,
uint *dup_key_found)
{
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
}
/**
This is called to delete all rows in a table
If the handler don't support this, then this function will
return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
by one.
*/
virtual int delete_all_rows()
{ return (my_errno=HA_ERR_WRONG_COMMAND); }
/**
Reset the auto-increment counter to the given value, i.e. the next row
inserted will get the given value. This is called e.g. after TRUNCATE
is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
returned by storage engines that don't support this operation.
*/
virtual int reset_auto_increment(ulonglong value)
{ return HA_ERR_WRONG_COMMAND; }
virtual int backup(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
/**
Restore assumes .frm file must exist, and that generate_table() has been
called; It will just copy the data file and run repair.
*/
virtual int restore(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
{ return HA_ADMIN_NOT_IMPLEMENTED; }
virtual bool check_and_repair(THD *thd) { return HA_ERR_WRONG_COMMAND; }
virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int discard_or_import_tablespace(my_bool discard)
{ return (my_errno=HA_ERR_WRONG_COMMAND); }
virtual void prepare_for_alter() { return; }
virtual void drop_table(const char *name);
virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
virtual int create_handler_files(const char *name, const char *old_name,
int action_flag, HA_CREATE_INFO *info)
{ return FALSE; }
virtual int change_partitions(HA_CREATE_INFO *create_info,
const char *path,
ulonglong *copied,
ulonglong *deleted,
const uchar *pack_frm_data,
size_t pack_frm_len)
{ return HA_ERR_WRONG_COMMAND; }
virtual int drop_partitions(const char *path)
{ return HA_ERR_WRONG_COMMAND; }
virtual int rename_partitions(const char *path)
{ return HA_ERR_WRONG_COMMAND; }
virtual int optimize_partitions(THD *thd)
{ return HA_ERR_WRONG_COMMAND; }
virtual int analyze_partitions(THD *thd)
{ return HA_ERR_WRONG_COMMAND; }
virtual int check_partitions(THD *thd)
{ return HA_ERR_WRONG_COMMAND; }
virtual int repair_partitions(THD *thd)
{ return HA_ERR_WRONG_COMMAND; }
}; };

View File

@ -3418,7 +3418,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
@param thd current thread @param thd current thread
@param ref column reference being resolved @param ref column reference being resolved
@param select the sub-select that ref is resolved against @param select the select that ref is resolved against
@note @note
The resolution procedure is: The resolution procedure is:
@ -3478,6 +3478,7 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
} }
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
select->having_fix_field &&
select_ref != not_found_item && !group_by_ref) select_ref != not_found_item && !group_by_ref)
{ {
/* /*

View File

@ -1994,7 +1994,7 @@ void Item_func_round::fix_length_and_dec()
int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1; int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
precision-= decimals_delta - length_increase; precision-= decimals_delta - length_increase;
decimals= decimals_to_set; decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
max_length= my_decimal_precision_to_length(precision, decimals, max_length= my_decimal_precision_to_length(precision, decimals,
unsigned_flag); unsigned_flag);
break; break;
@ -2093,18 +2093,18 @@ my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value)
{ {
my_decimal val, *value= args[0]->val_decimal(&val); my_decimal val, *value= args[0]->val_decimal(&val);
longlong dec= args[1]->val_int(); longlong dec= args[1]->val_int();
if (dec > 0 || (dec < 0 && args[1]->unsigned_flag)) if (dec >= 0 || args[1]->unsigned_flag)
{
dec= min((ulonglong) dec, decimals); dec= min((ulonglong) dec, decimals);
decimals= (uint8) dec; // to get correct output
}
else if (dec < INT_MIN) else if (dec < INT_MIN)
dec= INT_MIN; dec= INT_MIN;
if (!(null_value= (args[0]->null_value || args[1]->null_value || if (!(null_value= (args[0]->null_value || args[1]->null_value ||
my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec, my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec,
truncate, decimal_value) > 1))) truncate, decimal_value) > 1)))
{
decimal_value->frac= decimals;
return decimal_value; return decimal_value;
}
return 0; return 0;
} }

View File

@ -2617,7 +2617,7 @@ void Item_sum_count_distinct::clear()
else if (table) else if (table)
{ {
table->file->extra(HA_EXTRA_NO_CACHE); table->file->extra(HA_EXTRA_NO_CACHE);
table->file->delete_all_rows(); table->file->ha_delete_all_rows();
table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_WRITE_CACHE);
} }
} }

View File

@ -608,7 +608,10 @@ char *opt_logname, *opt_slow_logname;
/* Static variables */ /* Static variables */
static bool kill_in_progress, segfaulted; static bool kill_in_progress, segfaulted;
static my_bool opt_do_pstack, opt_bootstrap, opt_myisam_log; #ifdef HAVE_STACK_TRACE_ON_SEGV
static my_bool opt_do_pstack;
#endif /* HAVE_STACK_TRACE_ON_SEGV */
static my_bool opt_bootstrap, opt_myisam_log;
static int cleanup_done; static int cleanup_done;
static ulong opt_specialflag, opt_myisam_block_size; static ulong opt_specialflag, opt_myisam_block_size;
static char *opt_update_logname, *opt_binlog_index_name; static char *opt_update_logname, *opt_binlog_index_name;
@ -5461,9 +5464,11 @@ struct my_option my_long_options[] =
(uchar**) &opt_enable_named_pipe, (uchar**) &opt_enable_named_pipe, 0, GET_BOOL, (uchar**) &opt_enable_named_pipe, (uchar**) &opt_enable_named_pipe, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0}, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif #endif
#ifdef HAVE_STACK_TRACE_ON_SEGV
{"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.", {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.",
(uchar**) &opt_do_pstack, (uchar**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0, (uchar**) &opt_do_pstack, (uchar**) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0}, 0, 0, 0, 0},
#endif /* HAVE_STACK_TRACE_ON_SEGV */
{"engine-condition-pushdown", {"engine-condition-pushdown",
OPT_ENGINE_CONDITION_PUSHDOWN, OPT_ENGINE_CONDITION_PUSHDOWN,
"Push supported query conditions to the storage engine.", "Push supported query conditions to the storage engine.",

View File

@ -2120,11 +2120,17 @@ sp_head::backpatch(sp_label_t *lab)
uint dest= instructions(); uint dest= instructions();
List_iterator_fast<bp_t> li(m_backpatch); List_iterator_fast<bp_t> li(m_backpatch);
DBUG_ENTER("sp_head::backpatch");
while ((bp= li++)) while ((bp= li++))
{ {
if (bp->lab == lab) if (bp->lab == lab)
{
DBUG_PRINT("info", ("backpatch: (m_ip %d, label 0x%lx <%s>) to dest %d",
bp->instr->m_ip, (ulong) lab, lab->name, dest));
bp->instr->backpatch(dest, lab->ctx); bp->instr->backpatch(dest, lab->ctx);
}
} }
DBUG_VOID_RETURN;
} }
/** /**

View File

@ -888,8 +888,9 @@ public:
virtual void backpatch(uint dest, sp_pcontext *dst_ctx) virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
{ {
if (m_dest == 0) // Don't reset /* Calling backpatch twice is a logic flaw in jump resolution. */
m_dest= dest; DBUG_ASSERT(m_dest == 0);
m_dest= dest;
} }
/** /**

View File

@ -314,17 +314,91 @@ sp_rcontext::handle_error(uint sql_errno,
void void
sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i) sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
{ {
DBUG_ENTER("sp_rcontext::push_cursor");
DBUG_ASSERT(m_ccount < m_root_parsing_ctx->max_cursor_index());
m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i); m_cstack[m_ccount++]= new sp_cursor(lex_keeper, i);
DBUG_PRINT("info", ("m_ccount: %d", m_ccount));
DBUG_VOID_RETURN;
} }
void void
sp_rcontext::pop_cursors(uint count) sp_rcontext::pop_cursors(uint count)
{ {
DBUG_ENTER("sp_rcontext::pop_cursors");
DBUG_ASSERT(m_ccount >= count);
while (count--) while (count--)
{ {
delete m_cstack[--m_ccount]; delete m_cstack[--m_ccount];
} }
DBUG_PRINT("info", ("m_ccount: %d", m_ccount));
DBUG_VOID_RETURN;
}
void
sp_rcontext::push_handler(struct sp_cond_type *cond, uint h, int type, uint f)
{
DBUG_ENTER("sp_rcontext::push_handler");
DBUG_ASSERT(m_hcount < m_root_parsing_ctx->max_handler_index());
m_handler[m_hcount].cond= cond;
m_handler[m_hcount].handler= h;
m_handler[m_hcount].type= type;
m_handler[m_hcount].foffset= f;
m_hcount+= 1;
DBUG_PRINT("info", ("m_hcount: %d", m_hcount));
DBUG_VOID_RETURN;
}
void
sp_rcontext::pop_handlers(uint count)
{
DBUG_ENTER("sp_rcontext::pop_handlers");
DBUG_ASSERT(m_hcount >= count);
m_hcount-= count;
DBUG_PRINT("info", ("m_hcount: %d", m_hcount));
DBUG_VOID_RETURN;
}
void
sp_rcontext::push_hstack(uint h)
{
DBUG_ENTER("sp_rcontext::push_hstack");
DBUG_ASSERT(m_hsp < m_root_parsing_ctx->max_handler_index());
m_hstack[m_hsp++]= h;
DBUG_PRINT("info", ("m_hsp: %d", m_hsp));
DBUG_VOID_RETURN;
}
uint
sp_rcontext::pop_hstack()
{
uint handler;
DBUG_ENTER("sp_rcontext::pop_hstack");
DBUG_ASSERT(m_hsp);
handler= m_hstack[--m_hsp];
DBUG_PRINT("info", ("m_hsp: %d", m_hsp));
DBUG_RETURN(handler);
}
void
sp_rcontext::enter_handler(int hid)
{
DBUG_ENTER("sp_rcontext::enter_handler");
DBUG_ASSERT(m_ihsp < m_root_parsing_ctx->max_handler_index());
m_in_handler[m_ihsp++]= hid;
DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp));
DBUG_VOID_RETURN;
}
void
sp_rcontext::exit_handler()
{
DBUG_ENTER("sp_rcontext::exit_handler");
DBUG_ASSERT(m_ihsp);
m_ihsp-= 1;
DBUG_PRINT("info", ("m_ihsp: %d", m_ihsp));
DBUG_VOID_RETURN;
} }

View File

@ -107,21 +107,9 @@ class sp_rcontext : public Sql_alloc
return m_return_value_set; return m_return_value_set;
} }
inline void void push_handler(struct sp_cond_type *cond, uint h, int type, uint f);
push_handler(struct sp_cond_type *cond, uint h, int type, uint f)
{
m_handler[m_hcount].cond= cond;
m_handler[m_hcount].handler= h;
m_handler[m_hcount].type= type;
m_handler[m_hcount].foffset= f;
m_hcount+= 1;
}
inline void void pop_handlers(uint count);
pop_handlers(uint count)
{
m_hcount-= count;
}
// Returns 1 if a handler was found, 0 otherwise. // Returns 1 if a handler was found, 0 otherwise.
bool bool
@ -158,29 +146,13 @@ class sp_rcontext : public Sql_alloc
m_hfound= -1; m_hfound= -1;
} }
inline void void push_hstack(uint h);
push_hstack(uint h)
{
m_hstack[m_hsp++]= h;
}
inline uint uint pop_hstack();
pop_hstack()
{
return m_hstack[--m_hsp];
}
inline void void enter_handler(int hid);
enter_handler(int hid)
{
m_in_handler[m_ihsp++]= hid;
}
inline void void exit_handler();
exit_handler()
{
m_ihsp-= 1;
}
void void
push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i); push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i);

View File

@ -3934,7 +3934,7 @@ retry:
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
ha_open_options | HA_OPEN_FOR_REPAIR, ha_open_options | HA_OPEN_FOR_REPAIR,
entry, FALSE) || ! entry->file || entry, FALSE) || ! entry->file ||
(entry->file->is_crashed() && entry->file->check_and_repair(thd))) (entry->file->is_crashed() && entry->file->ha_check_and_repair(thd)))
{ {
/* Give right error message */ /* Give right error message */
thd->clear_error(); thd->clear_error();
@ -5400,7 +5400,7 @@ bool rm_temporary_table(handlerton *base, char *path)
error=1; /* purecov: inspected */ error=1; /* purecov: inspected */
*ext= 0; // remove extension *ext= 0; // remove extension
file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base); file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base);
if (file && file->delete_table(path)) if (file && file->ha_delete_table(path))
{ {
error=1; error=1;
sql_print_warning("Could not remove temporary table: '%s', error: %d", sql_print_warning("Could not remove temporary table: '%s', error: %d",
@ -8099,7 +8099,7 @@ my_bool mysql_rm_tmp_tables(void)
((handler_file= get_new_handler(&share, thd->mem_root, ((handler_file= get_new_handler(&share, thd->mem_root,
share.db_type())))) share.db_type()))))
{ {
handler_file->delete_table(filePathCopy); handler_file->ha_delete_table(filePathCopy);
delete handler_file; delete handler_file;
} }
free_table_share(&share); free_table_share(&share);

View File

@ -371,6 +371,32 @@ TODO list:
__LINE__,(ulong)(B)));B->query()->unlock_reading();} __LINE__,(ulong)(B)));B->query()->unlock_reading();}
#define DUMP(C) DBUG_EXECUTE("qcache", {\ #define DUMP(C) DBUG_EXECUTE("qcache", {\
(C)->cache_dump(); (C)->queries_dump();(C)->tables_dump();}) (C)->cache_dump(); (C)->queries_dump();(C)->tables_dump();})
/**
Causes the thread to wait in a spin lock for a query kill signal.
This function is used by the test frame work to identify race conditions.
The signal is caught and ignored and the thread is not killed.
*/
static void debug_wait_for_kill(const char *info)
{
DBUG_ENTER("debug_wait_for_kill");
const char *prev_info;
THD *thd;
thd= current_thd;
prev_info= thd->proc_info;
thd->proc_info= info;
sql_print_information(info);
while(!thd->killed)
my_sleep(1000);
thd->killed= THD::NOT_KILLED;
sql_print_information("Exit debug_wait_for_kill");
thd->proc_info= prev_info;
DBUG_VOID_RETURN;
}
#else #else
#define MUTEX_LOCK(M) pthread_mutex_lock(M) #define MUTEX_LOCK(M) pthread_mutex_lock(M)
#define MUTEX_UNLOCK(M) pthread_mutex_unlock(M) #define MUTEX_UNLOCK(M) pthread_mutex_unlock(M)
@ -647,13 +673,16 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
if (net->query_cache_query == 0) if (net->query_cache_query == 0)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
DBUG_EXECUTE_IF("wait_in_query_cache_insert",
debug_wait_for_kill("wait_in_query_cache_insert"); );
STRUCT_LOCK(&query_cache.structure_guard_mutex); STRUCT_LOCK(&query_cache.structure_guard_mutex);
bool interrupt; bool interrupt;
query_cache.wait_while_table_flush_is_in_progress(&interrupt); query_cache.wait_while_table_flush_is_in_progress(&interrupt);
if (interrupt) if (interrupt)
{ {
STRUCT_UNLOCK(&query_cache.structure_guard_mutex); STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
return; DBUG_VOID_RETURN;
} }
Query_cache_block *query_block= (Query_cache_block*)net->query_cache_query; Query_cache_block *query_block= (Query_cache_block*)net->query_cache_query;
@ -667,11 +696,11 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
BLOCK_LOCK_WR(query_block);
Query_cache_query *header= query_block->query(); Query_cache_query *header= query_block->query();
Query_cache_block *result= header->result(); Query_cache_block *result= header->result();
DUMP(&query_cache); DUMP(&query_cache);
BLOCK_LOCK_WR(query_block);
DBUG_PRINT("qcache", ("insert packet %lu bytes long",length)); DBUG_PRINT("qcache", ("insert packet %lu bytes long",length));
/* /*
@ -687,6 +716,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
DBUG_PRINT("qcache", ("free query 0x%lx", (ulong) query_block)); DBUG_PRINT("qcache", ("free query 0x%lx", (ulong) query_block));
// The following call will remove the lock on query_block // The following call will remove the lock on query_block
query_cache.free_query(query_block); query_cache.free_query(query_block);
query_cache.refused++;
// append_result_data no success => we need unlock // append_result_data no success => we need unlock
STRUCT_UNLOCK(&query_cache.structure_guard_mutex); STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -886,6 +916,31 @@ ulong Query_cache::resize(ulong query_cache_size_arg)
m_cache_status= Query_cache::FLUSH_IN_PROGRESS; m_cache_status= Query_cache::FLUSH_IN_PROGRESS;
STRUCT_UNLOCK(&structure_guard_mutex); STRUCT_UNLOCK(&structure_guard_mutex);
/*
Wait for all readers and writers to exit. When the list of all queries
is iterated over with a block level lock, we are done.
*/
Query_cache_block *block= queries_blocks;
if (block)
{
do
{
BLOCK_LOCK_WR(block);
Query_cache_query *query= block->query();
if (query && query->writer())
{
/*
Drop the writer; this will cancel any attempts to store
the processed statement associated with this writer.
*/
query->writer()->query_cache_query= 0;
query->writer(0);
refused++;
}
BLOCK_UNLOCK_WR(block);
block= block->next;
} while (block != queries_blocks);
}
free_cache(); free_cache();
query_cache_size= query_cache_size_arg; query_cache_size= query_cache_size_arg;

View File

@ -123,7 +123,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
ha_rows const maybe_deleted= table->file->stats.records; ha_rows const maybe_deleted= table->file->stats.records;
DBUG_PRINT("debug", ("Trying to use delete_all_rows()")); DBUG_PRINT("debug", ("Trying to use delete_all_rows()"));
if (!(error=table->file->delete_all_rows())) if (!(error=table->file->ha_delete_all_rows()))
{ {
error= -1; // ok error= -1; // ok
deleted= maybe_deleted; deleted= maybe_deleted;
@ -328,7 +328,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
We're really doing a truncate and need to reset the table's We're really doing a truncate and need to reset the table's
auto-increment counter. auto-increment counter.
*/ */
int error2= table->file->reset_auto_increment(0); int error2= table->file->ha_reset_auto_increment(0);
if (error2 && (error2 != HA_ERR_WRONG_COMMAND)) if (error2 && (error2 != HA_ERR_WRONG_COMMAND))
{ {

View File

@ -619,7 +619,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (mysql_prepare_insert(thd, table_list, table, fields, values, if (mysql_prepare_insert(thd, table_list, table, fields, values,
update_fields, update_values, duplic, &unused_conds, update_fields, update_values, duplic, &unused_conds,
FALSE, FALSE,
(fields.elements || !value_count), (fields.elements || !value_count ||
table_list->view != 0),
!ignore && (thd->variables.sql_mode & !ignore && (thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | (MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES)))) MODE_STRICT_ALL_TABLES))))
@ -1862,7 +1863,6 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
{ {
if (!(di= new Delayed_insert())) if (!(di= new Delayed_insert()))
{ {
my_error(ER_OUTOFMEMORY,MYF(0),sizeof(Delayed_insert));
thd->fatal_error(); thd->fatal_error();
goto end_create; goto end_create;
} }

View File

@ -5108,9 +5108,9 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ENTER("mysql_change_partitions"); DBUG_ENTER("mysql_change_partitions");
build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0);
if ((error= file->change_partitions(lpt->create_info, path, &lpt->copied, if ((error= file->ha_change_partitions(lpt->create_info, path, &lpt->copied,
&lpt->deleted, lpt->pack_frm_data, &lpt->deleted, lpt->pack_frm_data,
lpt->pack_frm_len))) lpt->pack_frm_len)))
{ {
if (error != ER_OUTOFMEMORY) if (error != ER_OUTOFMEMORY)
file->print_error(error, MYF(0)); file->print_error(error, MYF(0));
@ -5148,7 +5148,7 @@ static bool mysql_rename_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ENTER("mysql_rename_partitions"); DBUG_ENTER("mysql_rename_partitions");
build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0);
if ((error= lpt->table->file->rename_partitions(path))) if ((error= lpt->table->file->ha_rename_partitions(path)))
{ {
if (error != 1) if (error != 1)
lpt->table->file->print_error(error, MYF(0)); lpt->table->file->print_error(error, MYF(0));
@ -5189,7 +5189,7 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
DBUG_ENTER("mysql_drop_partitions"); DBUG_ENTER("mysql_drop_partitions");
build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0); build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0);
if ((error= lpt->table->file->drop_partitions(path))) if ((error= lpt->table->file->ha_drop_partitions(path)))
{ {
lpt->table->file->print_error(error, MYF(0)); lpt->table->file->print_error(error, MYF(0));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@ -6105,13 +6105,13 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
int error; int error;
written_bin_log= FALSE; written_bin_log= FALSE;
if (((alter_info->flags & ALTER_OPTIMIZE_PARTITION) && if (((alter_info->flags & ALTER_OPTIMIZE_PARTITION) &&
(error= table->file->optimize_partitions(thd))) || (error= table->file->ha_optimize_partitions(thd))) ||
((alter_info->flags & ALTER_ANALYZE_PARTITION) && ((alter_info->flags & ALTER_ANALYZE_PARTITION) &&
(error= table->file->analyze_partitions(thd))) || (error= table->file->ha_analyze_partitions(thd))) ||
((alter_info->flags & ALTER_CHECK_PARTITION) && ((alter_info->flags & ALTER_CHECK_PARTITION) &&
(error= table->file->check_partitions(thd))) || (error= table->file->ha_check_partitions(thd))) ||
((alter_info->flags & ALTER_REPAIR_PARTITION) && ((alter_info->flags & ALTER_REPAIR_PARTITION) &&
(error= table->file->repair_partitions(thd)))) (error= table->file->ha_repair_partitions(thd))))
{ {
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
goto err; goto err;

View File

@ -1567,14 +1567,14 @@ JOIN::reinit()
if (exec_tmp_table1) if (exec_tmp_table1)
{ {
exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE); exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE);
exec_tmp_table1->file->delete_all_rows(); exec_tmp_table1->file->ha_delete_all_rows();
free_io_cache(exec_tmp_table1); free_io_cache(exec_tmp_table1);
filesort_free_buffers(exec_tmp_table1,0); filesort_free_buffers(exec_tmp_table1,0);
} }
if (exec_tmp_table2) if (exec_tmp_table2)
{ {
exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE); exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE);
exec_tmp_table2->file->delete_all_rows(); exec_tmp_table2->file->ha_delete_all_rows();
free_io_cache(exec_tmp_table2); free_io_cache(exec_tmp_table2);
filesort_free_buffers(exec_tmp_table2,0); filesort_free_buffers(exec_tmp_table2,0);
} }
@ -5618,7 +5618,8 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
(keyuse->val->type() == Item::REF_ITEM && (keyuse->val->type() == Item::REF_ITEM &&
((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF && ((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF &&
(*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() == (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
Item_ref::DIRECT_REF) ) Item_ref::DIRECT_REF &&
keyuse->val->real_item()->type() == Item::FIELD_ITEM))
return new store_key_field(thd, return new store_key_field(thd,
key_part->field, key_part->field,
key_buff + maybe_null, key_buff + maybe_null,
@ -10526,9 +10527,9 @@ free_tmp_table(THD *thd, TABLE *entry)
if (entry->file) if (entry->file)
{ {
if (entry->db_stat) if (entry->db_stat)
entry->file->drop_table(entry->s->table_name.str); entry->file->ha_drop_table(entry->s->table_name.str);
else else
entry->file->delete_table(entry->s->table_name.str); entry->file->ha_delete_table(entry->s->table_name.str);
delete entry->file; delete entry->file;
} }
@ -10585,7 +10586,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
if (open_tmp_table(&new_table)) if (open_tmp_table(&new_table))
goto err1; goto err1;
if (table->file->indexes_are_disabled()) if (table->file->indexes_are_disabled())
new_table.file->disable_indexes(HA_KEY_SWITCH_ALL); new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
table->file->ha_index_or_rnd_end(); table->file->ha_index_or_rnd_end();
table->file->ha_rnd_init(1); table->file->ha_rnd_init(1);
if (table->no_rows) if (table->no_rows)
@ -10614,13 +10615,13 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
*/ */
while (!table->file->rnd_next(new_table.record[1])) while (!table->file->rnd_next(new_table.record[1]))
{ {
write_err= new_table.file->write_row(new_table.record[1]); write_err= new_table.file->ha_write_row(new_table.record[1]);
DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;); DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
if (write_err) if (write_err)
goto err; goto err;
} }
/* copy row that filled HEAP table */ /* copy row that filled HEAP table */
if ((write_err=new_table.file->write_row(table->record[0]))) if ((write_err=new_table.file->ha_write_row(table->record[0])))
{ {
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) || if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
!ignore_last_dupp_key_error) !ignore_last_dupp_key_error)
@ -10651,7 +10652,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
(void) table->file->ha_rnd_end(); (void) table->file->ha_rnd_end();
(void) new_table.file->close(); (void) new_table.file->close();
err1: err1:
new_table.file->delete_table(new_table.s->table_name.str); new_table.file->ha_delete_table(new_table.s->table_name.str);
err2: err2:
delete new_table.file; delete new_table.file;
thd_proc_info(thd, save_proc_info); thd_proc_info(thd, save_proc_info);
@ -12093,7 +12094,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{ {
int error; int error;
join->found_records++; join->found_records++;
if ((error=table->file->write_row(table->record[0]))) if ((error=table->file->ha_write_row(table->record[0])))
{ {
if (!table->file->is_fatal_error(error, HA_CHECK_DUP)) if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
goto end; goto end;
@ -12155,8 +12156,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{ /* Update old record */ { /* Update old record */
restore_record(table,record[1]); restore_record(table,record[1]);
update_tmptable_sum_func(join->sum_funcs,table); update_tmptable_sum_func(join->sum_funcs,table);
if ((error=table->file->update_row(table->record[1], if ((error=table->file->ha_update_row(table->record[1],
table->record[0]))) table->record[0])))
{ {
table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
@ -12179,7 +12180,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
} }
init_tmptable_sum_functions(join->sum_funcs); init_tmptable_sum_functions(join->sum_funcs);
copy_funcs(join->tmp_table_param.items_to_copy); copy_funcs(join->tmp_table_param.items_to_copy);
if ((error=table->file->write_row(table->record[0]))) if ((error=table->file->ha_write_row(table->record[0])))
{ {
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param, if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
error, 0)) error, 0))
@ -12215,7 +12216,7 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
copy_fields(&join->tmp_table_param); // Groups are copied twice. copy_fields(&join->tmp_table_param); // Groups are copied twice.
copy_funcs(join->tmp_table_param.items_to_copy); copy_funcs(join->tmp_table_param.items_to_copy);
if (!(error=table->file->write_row(table->record[0]))) if (!(error=table->file->ha_write_row(table->record[0])))
join->send_records++; // New group join->send_records++; // New group
else else
{ {
@ -12231,8 +12232,8 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
} }
restore_record(table,record[1]); restore_record(table,record[1]);
update_tmptable_sum_func(join->sum_funcs,table); update_tmptable_sum_func(join->sum_funcs,table);
if ((error=table->file->update_row(table->record[1], if ((error=table->file->ha_update_row(table->record[1],
table->record[0]))) table->record[0])))
{ {
table->file->print_error(error,MYF(0)); /* purecov: inspected */ table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
@ -12275,7 +12276,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
join->sum_funcs_end[send_group_parts]); join->sum_funcs_end[send_group_parts]);
if (!join->having || join->having->val_int()) if (!join->having || join->having->val_int())
{ {
int error= table->file->write_row(table->record[0]); int error= table->file->ha_write_row(table->record[0]);
if (error && create_myisam_from_heap(join->thd, table, if (error && create_myisam_from_heap(join->thd, table,
&join->tmp_table_param, &join->tmp_table_param,
error, 0)) error, 0))
@ -13190,7 +13191,8 @@ check_reverse_order:
select->quick=tmp; select->quick=tmp;
} }
} }
else if (tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts) else if (tab->type != JT_NEXT &&
tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
{ {
/* /*
SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
@ -13503,7 +13505,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
} }
if (having && !having->val_int()) if (having && !having->val_int())
{ {
if ((error=file->delete_row(record))) if ((error=file->ha_delete_row(record)))
goto err; goto err;
error=file->rnd_next(record); error=file->rnd_next(record);
continue; continue;
@ -13530,7 +13532,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
} }
if (compare_record(table, first_field) == 0) if (compare_record(table, first_field) == 0)
{ {
if ((error=file->delete_row(record))) if ((error=file->ha_delete_row(record)))
goto err; goto err;
} }
else if (!found) else if (!found)
@ -13629,7 +13631,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
} }
if (having && !having->val_int()) if (having && !having->val_int())
{ {
if ((error=file->delete_row(record))) if ((error=file->ha_delete_row(record)))
goto err; goto err;
continue; continue;
} }
@ -13646,7 +13648,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
if (hash_search(&hash, org_key_pos, key_length)) if (hash_search(&hash, org_key_pos, key_length))
{ {
/* Duplicated found ; Remove the row */ /* Duplicated found ; Remove the row */
if ((error=file->delete_row(record))) if ((error=file->ha_delete_row(record)))
goto err; goto err;
} }
else else
@ -15670,7 +15672,7 @@ int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
item->save_in_result_field(1); item->save_in_result_field(1);
} }
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]); copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
if ((write_error= table_arg->file->write_row(table_arg->record[0]))) if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
{ {
if (create_myisam_from_heap(thd, table_arg, &tmp_table_param, if (create_myisam_from_heap(thd, table_arg, &tmp_table_param,
write_error, 0)) write_error, 0))

View File

@ -5871,7 +5871,7 @@ bool get_schema_tables_result(JOIN *join,
{ {
table_list->table->file->extra(HA_EXTRA_NO_CACHE); table_list->table->file->extra(HA_EXTRA_NO_CACHE);
table_list->table->file->extra(HA_EXTRA_RESET_STATE); table_list->table->file->extra(HA_EXTRA_RESET_STATE);
table_list->table->file->delete_all_rows(); table_list->table->file->ha_delete_all_rows();
free_io_cache(table_list->table); free_io_cache(table_list->table);
filesort_free_buffers(table_list->table,1); filesort_free_buffers(table_list->table,1);
table_list->table->null_row= 0; table_list->table->null_row= 0;

View File

@ -630,7 +630,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
} }
else else
{ {
if ((error= file->delete_table(ddl_log_entry->name))) if ((error= file->ha_delete_table(ddl_log_entry->name)))
{ {
if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE) if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE)
break; break;
@ -667,8 +667,8 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
} }
else else
{ {
if (file->rename_table(ddl_log_entry->from_name, if (file->ha_rename_table(ddl_log_entry->from_name,
ddl_log_entry->name)) ddl_log_entry->name))
break; break;
} }
if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos))) if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
@ -1299,9 +1299,9 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
lpt->table_name, lpt->create_info, lpt->table_name, lpt->create_info,
lpt->alter_info->create_list, lpt->key_count, lpt->alter_info->create_list, lpt->key_count,
lpt->key_info_buffer, lpt->table->file)) || lpt->key_info_buffer, lpt->table->file)) ||
lpt->table->file->create_handler_files(shadow_path, NULL, lpt->table->file->ha_create_handler_files(shadow_path, NULL,
CHF_CREATE_FLAG, CHF_CREATE_FLAG,
lpt->create_info)) lpt->create_info))
{ {
my_delete(shadow_frm_name, MYF(0)); my_delete(shadow_frm_name, MYF(0));
error= 1; error= 1;
@ -1353,15 +1353,15 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
if (my_delete(frm_name, MYF(MY_WME)) || if (my_delete(frm_name, MYF(MY_WME)) ||
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
lpt->table->file->create_handler_files(path, shadow_path, lpt->table->file->ha_create_handler_files(path, shadow_path,
CHF_DELETE_FLAG, NULL) || CHF_DELETE_FLAG, NULL) ||
deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) || deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) ||
(sync_ddl_log(), FALSE) || (sync_ddl_log(), FALSE) ||
#endif #endif
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
my_rename(shadow_frm_name, frm_name, MYF(MY_WME)) || my_rename(shadow_frm_name, frm_name, MYF(MY_WME)) ||
lpt->table->file->create_handler_files(path, shadow_path, lpt->table->file->ha_create_handler_files(path, shadow_path,
CHF_RENAME_FLAG, NULL)) CHF_RENAME_FLAG, NULL))
#else #else
my_rename(shadow_frm_name, frm_name, MYF(MY_WME))) my_rename(shadow_frm_name, frm_name, MYF(MY_WME)))
#endif #endif
@ -3718,14 +3718,14 @@ mysql_rename_table(handlerton *base, const char *old_db,
to_base= lc_to; to_base= lc_to;
} }
if (!file || !(error=file->rename_table(from_base, to_base))) if (!file || !(error=file->ha_rename_table(from_base, to_base)))
{ {
if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext)) if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
{ {
error=my_errno; error=my_errno;
/* Restore old file name */ /* Restore old file name */
if (file) if (file)
file->rename_table(to_base, from_base); file->ha_rename_table(to_base, from_base);
} }
} }
delete file; delete file;
@ -4376,7 +4376,7 @@ send_result_message:
if (!result_code) // recreation went ok if (!result_code) // recreation went ok
{ {
if ((table->table= open_ltable(thd, table, lock_type, 0)) && if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
((result_code= table->table->file->analyze(thd, check_opt)) > 0)) ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
result_code= 0; // analyze went ok result_code= 0; // analyze went ok
} }
if (result_code) // either mysql_recreate_table or analyze failed if (result_code) // either mysql_recreate_table or analyze failed
@ -4486,7 +4486,7 @@ bool mysql_backup_table(THD* thd, TABLE_LIST* table_list)
"MySQL Administrator (mysqldump, mysql)"); "MySQL Administrator (mysqldump, mysql)");
DBUG_RETURN(mysql_admin_table(thd, table_list, 0, DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
"backup", TL_READ, 0, 0, 0, 0, "backup", TL_READ, 0, 0, 0, 0,
&handler::backup, 0)); &handler::ha_backup, 0));
} }
@ -4498,7 +4498,7 @@ bool mysql_restore_table(THD* thd, TABLE_LIST* table_list)
DBUG_RETURN(mysql_admin_table(thd, table_list, 0, DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
"restore", TL_WRITE, 1, 1, 0, "restore", TL_WRITE, 1, 1, 0,
&prepare_for_restore, &prepare_for_restore,
&handler::restore, 0)); &handler::ha_restore, 0));
} }
@ -4519,7 +4519,7 @@ bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
DBUG_ENTER("mysql_optimize_table"); DBUG_ENTER("mysql_optimize_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
"optimize", TL_WRITE, 1,0,0,0, "optimize", TL_WRITE, 1,0,0,0,
&handler::optimize, 0)); &handler::ha_optimize, 0));
} }
@ -4933,7 +4933,7 @@ bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
DBUG_ENTER("mysql_analyze_table"); DBUG_ENTER("mysql_analyze_table");
DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
"analyze", lock_type, 1, 0, 0, 0, "analyze", lock_type, 1, 0, 0, 0,
&handler::analyze, 0)); &handler::ha_analyze, 0));
} }
@ -4980,7 +4980,7 @@ mysql_discard_or_import_tablespace(THD *thd,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
error=table->file->discard_or_import_tablespace(discard); error= table->file->ha_discard_or_import_tablespace(discard);
thd_proc_info(thd, "end"); thd_proc_info(thd, "end");
@ -5353,14 +5353,14 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
switch (keys_onoff) { switch (keys_onoff) {
case ENABLE: case ENABLE:
error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
break; break;
case LEAVE_AS_IS: case LEAVE_AS_IS:
if (!indexes_were_disabled) if (!indexes_were_disabled)
break; break;
/* fall-through: disabled indexes */ /* fall-through: disabled indexes */
case DISABLE: case DISABLE:
error= table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
} }
if (error == HA_ERR_WRONG_COMMAND) if (error == HA_ERR_WRONG_COMMAND)
@ -6130,14 +6130,14 @@ view_err:
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000);); DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* COND_refresh will be signaled in close_thread_tables() */ /* COND_refresh will be signaled in close_thread_tables() */
break; break;
case DISABLE: case DISABLE:
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* COND_refresh will be signaled in close_thread_tables() */ /* COND_refresh will be signaled in close_thread_tables() */
break; break;
default: default:
@ -6545,7 +6545,7 @@ view_err:
KEY_PART_INFO *part_end; KEY_PART_INFO *part_end;
DBUG_PRINT("info", ("No new_table, checking add/drop index")); DBUG_PRINT("info", ("No new_table, checking add/drop index"));
table->file->prepare_for_alter(); table->file->ha_prepare_for_alter();
if (index_add_count) if (index_add_count)
{ {
/* The add_index() method takes an array of KEY structs. */ /* The add_index() method takes an array of KEY structs. */
@ -6763,8 +6763,8 @@ view_err:
t_table= table; t_table= table;
} }
/* Tell the handler that a new frm file is in place. */ /* Tell the handler that a new frm file is in place. */
if (t_table->file->create_handler_files(path, NULL, CHF_INDEX_FLAG, if (t_table->file->ha_create_handler_files(path, NULL, CHF_INDEX_FLAG,
create_info)) create_info))
goto err_with_placeholders; goto err_with_placeholders;
if (thd->locked_tables && new_name == table_name && new_db == db) if (thd->locked_tables && new_name == table_name && new_db == db)
{ {
@ -7064,7 +7064,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
copy_ptr->do_copy(copy_ptr); copy_ptr->do_copy(copy_ptr);
} }
prev_insert_id= to->file->next_insert_id; prev_insert_id= to->file->next_insert_id;
error=to->file->write_row(to->record[0]); error=to->file->ha_write_row(to->record[0]);
to->auto_increment_field_not_null= FALSE; to->auto_increment_field_not_null= FALSE;
if (error) if (error)
{ {

View File

@ -440,10 +440,10 @@ bool st_select_lex_unit::exec()
{ {
item->assigned(0); // We will reinit & rexecute unit item->assigned(0); // We will reinit & rexecute unit
item->reset(); item->reset();
table->file->delete_all_rows(); table->file->ha_delete_all_rows();
} }
/* re-enabling indexes for next subselect iteration */ /* re-enabling indexes for next subselect iteration */
if (union_distinct && table->file->enable_indexes(HA_KEY_SWITCH_ALL)) if (union_distinct && table->file->ha_enable_indexes(HA_KEY_SWITCH_ALL))
{ {
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
@ -485,7 +485,7 @@ bool st_select_lex_unit::exec()
sl->join->exec(); sl->join->exec();
if (sl == union_distinct) if (sl == union_distinct)
{ {
if (table->file->disable_indexes(HA_KEY_SWITCH_ALL)) if (table->file->ha_disable_indexes(HA_KEY_SWITCH_ALL))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
table->no_keyread=1; table->no_keyread=1;
} }

View File

@ -526,7 +526,9 @@ int mysql_update(THD *thd,
init_read_record(&info,thd,table,select,0,1); init_read_record(&info,thd,table,select,0,1);
updated= found= 0; updated= found= 0;
thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */ /* Generate an error when trying to set a NOT NULL field to NULL. */
thd->count_cuted_fields= ignore ? CHECK_FIELD_WARN
: CHECK_FIELD_ERROR_FOR_NULL;
thd->cuted_fields=0L; thd->cuted_fields=0L;
thd_proc_info(thd, "Updating"); thd_proc_info(thd, "Updating");
@ -623,9 +625,9 @@ int mysql_update(THD *thd,
call then it should be included in the count of dup_key_found call then it should be included in the count of dup_key_found
and error should be set to 0 (only if these errors are ignored). and error should be set to 0 (only if these errors are ignored).
*/ */
error= table->file->bulk_update_row(table->record[1], error= table->file->ha_bulk_update_row(table->record[1],
table->record[0], table->record[0],
&dup_key_found); &dup_key_found);
limit+= dup_key_found; limit+= dup_key_found;
updated-= dup_key_found; updated-= dup_key_found;
} }

View File

@ -508,10 +508,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%pure_parser /* We have threads */ %pure_parser /* We have threads */
/* /*
Currently there are 177 shift/reduce conflicts. Currently there are 169 shift/reduce conflicts.
We should not introduce new conflicts any more. We should not introduce new conflicts any more.
*/ */
%expect 177 %expect 169
/* /*
Comments for TOKENS. Comments for TOKENS.
@ -1204,7 +1204,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <table_list> %type <table_list>
join_table_list join_table join_table_list join_table
table_factor table_ref table_factor table_ref esc_table_ref
select_derived derived_table_list select_derived derived_table_list
%type <date_time_type> date_time_type; %type <date_time_type> date_time_type;
@ -1295,7 +1295,9 @@ END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
%type <NONE> sp_proc_stmt_statement sp_proc_stmt_return %type <NONE> sp_proc_stmt_statement sp_proc_stmt_return
%type <NONE> sp_proc_stmt_if %type <NONE> sp_proc_stmt_if
%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled sp_proc_stmt_leave %type <NONE> sp_labeled_control sp_proc_stmt_unlabeled
%type <NONE> sp_labeled_block sp_unlabeled_block
%type <NONE> sp_proc_stmt_leave
%type <NONE> sp_proc_stmt_iterate %type <NONE> sp_proc_stmt_iterate
%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close %type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
%type <NONE> case_stmt_specification simple_case_stmt searched_case_stmt %type <NONE> case_stmt_specification simple_case_stmt searched_case_stmt
@ -1956,6 +1958,8 @@ ev_sql_stmt_inner:
| sp_proc_stmt_return | sp_proc_stmt_return
| sp_proc_stmt_if | sp_proc_stmt_if
| case_stmt_specification | case_stmt_specification
| sp_labeled_block
| sp_unlabeled_block
| sp_labeled_control | sp_labeled_control
| sp_proc_stmt_unlabeled | sp_proc_stmt_unlabeled
| sp_proc_stmt_leave | sp_proc_stmt_leave
@ -2530,6 +2534,8 @@ sp_proc_stmt:
| sp_proc_stmt_return | sp_proc_stmt_return
| sp_proc_stmt_if | sp_proc_stmt_if
| case_stmt_specification | case_stmt_specification
| sp_labeled_block
| sp_unlabeled_block
| sp_labeled_control | sp_labeled_control
| sp_proc_stmt_unlabeled | sp_proc_stmt_unlabeled
| sp_proc_stmt_leave | sp_proc_stmt_leave
@ -2656,14 +2662,35 @@ sp_proc_stmt_leave:
sp_instr_jump *i; sp_instr_jump *i;
uint ip= sp->instructions(); uint ip= sp->instructions();
uint n; uint n;
/*
When jumping to a BEGIN-END block end, the target jump
points to the block hpop/cpop cleanup instructions,
so we should exclude the block context here.
When jumping to something else (i.e., SP_LAB_ITER),
there are no hpop/cpop at the jump destination,
so we should include the block context here for cleanup.
*/
bool exclusive= (lab->type == SP_LAB_BEGIN);
n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */ n= ctx->diff_handlers(lab->ctx, exclusive);
if (n) if (n)
sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); {
n= ctx->diff_cursors(lab->ctx, TRUE); /* Exclusive the dest. */ sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
if (hpop == NULL)
MYSQL_YYABORT;
sp->add_instr(hpop);
}
n= ctx->diff_cursors(lab->ctx, exclusive);
if (n) if (n)
sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); {
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
if (cpop == NULL)
MYSQL_YYABORT;
sp->add_instr(cpop);
}
i= new sp_instr_jump(ip, ctx); i= new sp_instr_jump(ip, ctx);
if (i == NULL)
MYSQL_YYABORT;
sp->push_backpatch(i, lab); /* Jumping forward */ sp->push_backpatch(i, lab); /* Jumping forward */
sp->add_instr(i); sp->add_instr(i);
} }
@ -2691,10 +2718,20 @@ sp_proc_stmt_iterate:
n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */ n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */
if (n) if (n)
sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); {
sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
if (hpop == NULL)
MYSQL_YYABORT;
sp->add_instr(hpop);
}
n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */ n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */
if (n) if (n)
sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); {
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
if (cpop == NULL)
MYSQL_YYABORT;
sp->add_instr(cpop);
}
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
sp->add_instr(i); sp->add_instr(i);
} }
@ -2978,19 +3015,17 @@ sp_labeled_control:
sp_unlabeled_control sp_opt_label sp_unlabeled_control sp_opt_label
{ {
LEX *lex= Lex; LEX *lex= Lex;
sp_label_t *lab= lex->spcont->pop_label();
if ($5.str) if ($5.str)
{ {
sp_label_t *lab= lex->spcont->find_label($5.str); if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
if (!lab ||
my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
{ {
my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str); my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
MYSQL_YYABORT; MYSQL_YYABORT;
} }
} }
lex->sphead->backpatch(lex->spcont->pop_label()); lex->sphead->backpatch(lab);
} }
; ;
@ -2999,15 +3034,59 @@ sp_opt_label:
| label_ident { $$= $1; } | label_ident { $$= $1; }
; ;
sp_unlabeled_control: sp_labeled_block:
label_ident ':'
{
LEX *lex= Lex;
sp_pcontext *ctx= lex->spcont;
sp_label_t *lab= ctx->find_label($1.str);
if (lab)
{
my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str);
MYSQL_YYABORT;
}
lab= lex->spcont->push_label($1.str,
lex->sphead->instructions());
lab->type= SP_LAB_BEGIN;
}
sp_block_content sp_opt_label
{
LEX *lex= Lex;
sp_label_t *lab= lex->spcont->pop_label();
if ($5.str)
{
if (my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
{
my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
MYSQL_YYABORT;
}
}
}
;
sp_unlabeled_block:
{ /* Unlabeled blocks get a secret label. */
LEX *lex= Lex;
uint ip= lex->sphead->instructions();
sp_label_t *lab= lex->spcont->push_label((char *)"", ip);
lab->type= SP_LAB_BEGIN;
}
sp_block_content
{
LEX *lex= Lex;
lex->spcont->pop_label();
}
;
sp_block_content:
BEGIN_SYM BEGIN_SYM
{ /* QQ This is just a dummy for grouping declarations and statements { /* QQ This is just a dummy for grouping declarations and statements
together. No [[NOT] ATOMIC] yet, and we need to figure out how together. No [[NOT] ATOMIC] yet, and we need to figure out how
make it coexist with the existing BEGIN COMMIT/ROLLBACK. */ make it coexist with the existing BEGIN COMMIT/ROLLBACK. */
LEX *lex= Lex; LEX *lex= Lex;
sp_label_t *lab= lex->spcont->last_label();
lab->type= SP_LAB_BEGIN;
lex->spcont= lex->spcont->push_context(LABEL_DEFAULT_SCOPE); lex->spcont= lex->spcont->push_context(LABEL_DEFAULT_SCOPE);
} }
sp_decls sp_decls
@ -3027,7 +3106,10 @@ sp_unlabeled_control:
$3.curs)); $3.curs));
lex->spcont= ctx->pop_context(); lex->spcont= ctx->pop_context();
} }
| LOOP_SYM ;
sp_unlabeled_control:
LOOP_SYM
sp_proc_stmts1 END LOOP_SYM sp_proc_stmts1 END LOOP_SYM
{ {
LEX *lex= Lex; LEX *lex= Lex;
@ -7463,10 +7545,22 @@ join_table_list:
derived_table_list { MYSQL_YYABORT_UNLESS($$=$1); } derived_table_list { MYSQL_YYABORT_UNLESS($$=$1); }
; ;
/*
The ODBC escape syntax for Outer Join is: '{' OJ join_table '}'
The parser does not define OJ as a token, any ident is accepted
instead in $2 (ident). Also, all productions from table_ref can
be escaped, not only join_table. Both syntax extensions are safe
and are ignored.
*/
esc_table_ref:
table_ref { $$=$1; }
| '{' ident table_ref '}' { $$=$3; }
;
/* Warning - may return NULL in case of incomplete SELECT */ /* Warning - may return NULL in case of incomplete SELECT */
derived_table_list: derived_table_list:
table_ref { $$=$1; } esc_table_ref { $$=$1; }
| derived_table_list ',' table_ref | derived_table_list ',' esc_table_ref
{ {
MYSQL_YYABORT_UNLESS($1 && ($$=$3)); MYSQL_YYABORT_UNLESS($1 && ($$=$3));
} }
@ -7631,25 +7725,6 @@ table_factor:
MYSQL_YYABORT; MYSQL_YYABORT;
Select->add_joined_table($$); Select->add_joined_table($$);
} }
| '{' ident table_ref LEFT OUTER JOIN_SYM table_ref
ON
{
/* Change the current name resolution context to a local context. */
if (push_new_name_resolution_context(YYTHD, $3, $7))
MYSQL_YYABORT;
}
expr '}'
{
LEX *lex= Lex;
MYSQL_YYABORT_UNLESS($3 && $7);
add_join_on($7,$10);
Lex->pop_context();
$7->outer_join|=JOIN_TYPE_LEFT;
$$=$7;
if (!($$= lex->current_select->nest_last_join(lex->thd)))
MYSQL_YYABORT;
}
| select_derived_init get_select_lex select_derived2 | select_derived_init get_select_lex select_derived2
{ {
LEX *lex= Lex; LEX *lex= Lex;

View File

@ -401,7 +401,7 @@ int rea_create_table(THD *thd, const char *path,
DBUG_ASSERT(*fn_rext(frm_name)); DBUG_ASSERT(*fn_rext(frm_name));
if (thd->variables.keep_files_on_create) if (thd->variables.keep_files_on_create)
create_info->options|= HA_CREATE_KEEP_FILES; create_info->options|= HA_CREATE_KEEP_FILES;
if (file->create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info)) if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info))
goto err_handler; goto err_handler;
if (!create_info->frm_only && ha_create_table(thd, path, db, table_name, if (!create_info->frm_only && ha_create_table(thd, path, db, table_name,
create_info,0)) create_info,0))
@ -409,7 +409,7 @@ int rea_create_table(THD *thd, const char *path,
DBUG_RETURN(0); DBUG_RETURN(0);
err_handler: err_handler:
VOID(file->create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info)); VOID(file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info));
my_delete(frm_name, MYF(0)); my_delete(frm_name, MYF(0));
DBUG_RETURN(1); DBUG_RETURN(1);
} /* rea_create_table */ } /* rea_create_table */

View File

@ -1601,9 +1601,21 @@ decimal_round(decimal_t *from, decimal_t *to, int scale,
x+=10; x+=10;
*buf1=powers10[pos]*(x-y); *buf1=powers10[pos]*(x-y);
} }
if (frac0 < 0) /*
In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside
the buffer are as follows.
Before <1, 5e8>
After <2, 5e8>
Hence we need to set the 2nd field to 0.
The same holds if we round 1.5e-9 to 2e-9.
*/
if (frac0 < frac1)
{ {
dec1 *end=to->buf+intg0, *buf=buf1+1; dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0);
dec1 *end= to->buf + len;
while (buf < end) while (buf < end)
*buf++=0; *buf++=0;
} }

View File

@ -15674,7 +15674,7 @@ static void test_mysql_insert_id()
myquery(rc); myquery(rc);
res= mysql_insert_id(mysql); res= mysql_insert_id(mysql);
DIE_UNLESS(res == 0); DIE_UNLESS(res == 0);
rc= mysql_query(mysql, "update t2 set f1=NULL where f1=14"); rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
myquery(rc); myquery(rc);
res= mysql_insert_id(mysql); res= mysql_insert_id(mysql);
DIE_UNLESS(res == 0); DIE_UNLESS(res == 0);