mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 14:54:20 +01:00
Merge joreland@bk-internal.mysql.com:/home/bk/mysql-5.0
into perch.ndb.mysql.com:/home/jonas/src/mysql-5.0-push
This commit is contained in:
commit
1ddb06fcc4
78 changed files with 1533 additions and 294 deletions
|
@ -44,17 +44,21 @@ set -e
|
|||
export AM_MAKEFLAGS
|
||||
AM_MAKEFLAGS="-j 4"
|
||||
|
||||
# SSL library to use. Should be changed to --with-yassl
|
||||
SSL_LIBRARY=--with-openssl
|
||||
|
||||
# If you are not using codefusion add "-Wpointer-arith" to WARNINGS
|
||||
# The following warning flag will give too many warnings:
|
||||
# -Wshadow -Wunused -Winline (The later isn't usable in C++ as
|
||||
# __attribute()__ doesn't work with gnu C++)
|
||||
|
||||
global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings"
|
||||
#debug_extra_warnings="-Wuninitialized"
|
||||
c_warnings="$global_warnings -Wunused"
|
||||
cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor"
|
||||
base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine"
|
||||
base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine"
|
||||
max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine --with-openssl --with-embedded-server --with-big-tables"
|
||||
base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine $SSL_LIBRARY"
|
||||
base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine $SSL_LIBRARY"
|
||||
max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine $SSL_LIBRARY --with-embedded-server --with-big-tables"
|
||||
max_configs="$base_max_configs --with-embedded-server"
|
||||
max_no_ndb_configs="$base_max_no_ndb_configs --with-embedded-server"
|
||||
|
||||
|
|
13
BUILD/compile-pentium64-debug-max
Executable file
13
BUILD/compile-pentium64-debug-max
Executable file
|
@ -0,0 +1,13 @@
|
|||
#! /bin/sh
|
||||
|
||||
path=`dirname $0`
|
||||
. "$path/SETUP.sh" $@ --with-debug=full
|
||||
|
||||
extra_flags="$pentium64_cflags $debug_cflags $max_cflags"
|
||||
c_warnings="$c_warnings $debug_extra_warnings"
|
||||
cxx_warnings="$cxx_warnings $debug_extra_warnings"
|
||||
extra_configs="$pentium_configs $debug_configs $max_configs"
|
||||
|
||||
extra_configs="$extra_configs "
|
||||
|
||||
. "$path/FINISH.sh"
|
|
@ -3,13 +3,13 @@
|
|||
path=`dirname $0`
|
||||
. "$path/SETUP.sh"
|
||||
|
||||
extra_flags="$pentium64_cflags $debug_cflags -USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify -DMYSQL_SERVER_SUFFIX=-valgrind-max"
|
||||
extra_flags="$pentium64_cflags $debug_cflags $max_cflags -USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify -DMYSQL_SERVER_SUFFIX=-valgrind-max"
|
||||
c_warnings="$c_warnings $debug_extra_warnings"
|
||||
cxx_warnings="$cxx_warnings $debug_extra_warnings"
|
||||
extra_configs="$pentium_configs $debug_configs"
|
||||
|
||||
# We want to test isam when building with valgrind
|
||||
extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-isam --with-embedded-server --with-openssl --with-raid --with-ndbcluster"
|
||||
extra_configs="$extra_configs $max_leave_isam_configs --with-isam"
|
||||
|
||||
. "$path/FINISH.sh"
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ test:
|
|||
|
||||
test-force:
|
||||
cd mysql-test; \
|
||||
./mysql-test-run --force ; \
|
||||
./mysql-test-run --force && \
|
||||
./mysql-test-run --ps-protocol --force
|
||||
|
||||
# We are testing a new Perl version of the test script
|
||||
|
@ -123,7 +123,7 @@ test-pl:
|
|||
|
||||
test-force-pl:
|
||||
cd mysql-test; \
|
||||
./mysql-test-run.pl --force ; \
|
||||
./mysql-test-run.pl --force && \
|
||||
./mysql-test-run.pl --ps-protocol --force
|
||||
|
||||
# Don't update the files from bitkeeper
|
||||
|
|
|
@ -334,6 +334,10 @@ case "$target_os" in
|
|||
# Use the built-in alloca()
|
||||
CFLAGS="$CFLAGS -Kalloca"
|
||||
CXXFLAGS="$CFLAGS -Kalloca"
|
||||
# Use no_implicit for templates
|
||||
CXXFLAGS="$CXXFLAGS -Tno_implicit"
|
||||
AC_DEFINE([HAVE_EXPLICIT_TEMPLATE_INSTANTIATION],
|
||||
[1], [Defined by configure. Use explicit template instantiation.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include <string.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef __sun
|
||||
#if defined(__sun) || defined(__SCO_VERSION__)
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
|
||||
|
|
|
@ -26,13 +26,17 @@
|
|||
#include "runtime.hpp"
|
||||
#include "timer.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
namespace yaSSL {
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
timer_d timer()
|
||||
{
|
||||
static bool init(false);
|
||||
|
@ -57,8 +61,6 @@ namespace yaSSL {
|
|||
|
||||
#else // _WIN32
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
timer_d timer()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
|
|
@ -248,6 +248,7 @@ enum ha_base_keytype {
|
|||
#define HA_OPTION_CHECKSUM 32
|
||||
#define HA_OPTION_DELAY_KEY_WRITE 64
|
||||
#define HA_OPTION_NO_PACK_KEYS 128 /* Reserved for MySQL */
|
||||
#define HA_OPTION_CREATE_FROM_ENGINE 256
|
||||
#define HA_OPTION_TEMP_COMPRESS_RECORD ((uint) 16384) /* set by isamchk */
|
||||
#define HA_OPTION_READ_ONLY_DATA ((uint) 32768) /* Set by isamchk */
|
||||
|
||||
|
@ -258,7 +259,6 @@ enum ha_base_keytype {
|
|||
#define HA_CREATE_TMP_TABLE 4
|
||||
#define HA_CREATE_CHECKSUM 8
|
||||
#define HA_CREATE_DELAY_KEY_WRITE 64
|
||||
#define HA_CREATE_FROM_ENGINE 128
|
||||
|
||||
/* Bits in flag to _status */
|
||||
|
||||
|
|
|
@ -223,10 +223,10 @@ MYSQL_MANAGER_USER=root
|
|||
# number is to be used, 0 - 16 or similar.
|
||||
#
|
||||
if [ -n "$MTR_BUILD_THREAD" ] ; then
|
||||
MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 40 + 8120`
|
||||
MASTER_MYPORT=`expr $MTR_BUILD_THREAD '*' 5 + 10000`
|
||||
MYSQL_MANAGER_PORT=`expr $MASTER_MYPORT + 2`
|
||||
SLAVE_MYPORT=`expr $MASTER_MYPORT + 16`
|
||||
NDBCLUSTER_PORT=`expr $MASTER_MYPORT + 24`
|
||||
SLAVE_MYPORT=`expr $MASTER_MYPORT + 3`
|
||||
NDBCLUSTER_PORT=`expr $MASTER_MYPORT + 4`
|
||||
|
||||
echo "Using MTR_BUILD_THREAD = $MTR_BUILD_THREAD"
|
||||
echo "Using MASTER_MYPORT = $MASTER_MYPORT"
|
||||
|
|
|
@ -1870,7 +1870,7 @@ a b
|
|||
drop table t1;
|
||||
create table t1 (v varchar(65530), key(v));
|
||||
Warnings:
|
||||
Warning 1071 Specified key was too long; max key length is 1024 bytes
|
||||
Warning 1071 Specified key was too long; max key length is MAX_KEY_LENGTH bytes
|
||||
drop table if exists t1;
|
||||
create table t1 (v varchar(65536));
|
||||
Warnings:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
drop table if exists t1;
|
||||
drop table if exists t1, t2;
|
||||
select 0,256,00000000000000065536,2147483647,-2147483648,2147483648,+4294967296;
|
||||
0 256 00000000000000065536 2147483647 -2147483648 2147483648 4294967296
|
||||
0 256 65536 2147483647 -2147483648 2147483648 4294967296
|
||||
|
|
|
@ -20,9 +20,9 @@ time_zone_transition_type
|
|||
user
|
||||
show tables;
|
||||
Tables_in_test
|
||||
connect(localhost,root,z,test2,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock);
|
||||
connect(localhost,root,z,test2,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR 28000: Access denied for user 'root'@'localhost' (using password: YES)
|
||||
connect(localhost,root,z,test,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock);
|
||||
connect(localhost,root,z,test,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR 28000: Access denied for user 'root'@'localhost' (using password: YES)
|
||||
grant ALL on *.* to test@localhost identified by "gambling";
|
||||
grant ALL on *.* to test@127.0.0.1 identified by "gambling";
|
||||
|
@ -47,13 +47,13 @@ time_zone_transition_type
|
|||
user
|
||||
show tables;
|
||||
Tables_in_test
|
||||
connect(localhost,test,,test2,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock);
|
||||
connect(localhost,test,,test2,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO)
|
||||
connect(localhost,test,,"",MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock);
|
||||
connect(localhost,test,,"",MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO)
|
||||
connect(localhost,test,zorro,test2,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock);
|
||||
connect(localhost,test,zorro,test2,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES)
|
||||
connect(localhost,test,zorro,test,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock);
|
||||
connect(localhost,test,zorro,test,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES)
|
||||
update mysql.user set password=old_password("gambling2") where user=_binary"test";
|
||||
flush privileges;
|
||||
|
@ -82,13 +82,13 @@ time_zone_transition_type
|
|||
user
|
||||
show tables;
|
||||
Tables_in_test
|
||||
connect(localhost,test,,test2,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock);
|
||||
connect(localhost,test,,test2,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO)
|
||||
connect(localhost,test,,test,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock);
|
||||
connect(localhost,test,,test,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO)
|
||||
connect(localhost,test,zorro,test2,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock);
|
||||
connect(localhost,test,zorro,test2,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES)
|
||||
connect(localhost,test,zorro,test,MASTER_PORT,MYSQL_TEST_DIR/var/tmp/master.sock);
|
||||
connect(localhost,test,zorro,test,MASTER_PORT,MASTER_SOCKET);
|
||||
ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES)
|
||||
delete from mysql.user where user=_binary"test";
|
||||
flush privileges;
|
||||
|
|
|
@ -4929,3 +4929,50 @@ Warnings:
|
|||
Note 1051 Unknown table 't2'
|
||||
Note 1051 Unknown table 't3'
|
||||
Note 1051 Unknown table 't4'
|
||||
DROP TABLE IF EXISTS bug13894;
|
||||
CREATE TABLE bug13894 ( val integer ) ENGINE = CSV;
|
||||
INSERT INTO bug13894 VALUES (5);
|
||||
INSERT INTO bug13894 VALUES (10);
|
||||
INSERT INTO bug13894 VALUES (11);
|
||||
INSERT INTO bug13894 VALUES (10);
|
||||
SELECT * FROM bug13894;
|
||||
val
|
||||
5
|
||||
10
|
||||
11
|
||||
10
|
||||
UPDATE bug13894 SET val=6 WHERE val=10;
|
||||
SELECT * FROM bug13894;
|
||||
val
|
||||
5
|
||||
11
|
||||
6
|
||||
6
|
||||
DROP TABLE bug13894;
|
||||
DROP TABLE IF EXISTS bug14672;
|
||||
CREATE TABLE bug14672 (c1 integer) engine = CSV;
|
||||
INSERT INTO bug14672 VALUES (1), (2), (3);
|
||||
SELECT * FROM bug14672;
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
DELETE FROM bug14672 WHERE c1 = 2;
|
||||
SELECT * FROM bug14672;
|
||||
c1
|
||||
1
|
||||
3
|
||||
INSERT INTO bug14672 VALUES (4);
|
||||
SELECT * FROM bug14672;
|
||||
c1
|
||||
1
|
||||
3
|
||||
4
|
||||
INSERT INTO bug14672 VALUES (5);
|
||||
SELECT * FROM bug14672;
|
||||
c1
|
||||
1
|
||||
3
|
||||
4
|
||||
5
|
||||
DROP TABLE bug14672;
|
||||
|
|
17
mysql-test/r/ctype_cp932_binlog.result
Normal file
17
mysql-test/r/ctype_cp932_binlog.result
Normal file
|
@ -0,0 +1,17 @@
|
|||
drop table if exists t1;
|
||||
set names cp932;
|
||||
set character_set_database = cp932;
|
||||
RESET MASTER;
|
||||
CREATE TABLE t1(f1 blob);
|
||||
PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
|
||||
SET @var1= x'8300';
|
||||
EXECUTE stmt1 USING @var1;
|
||||
SHOW BINLOG EVENTS FROM 98;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 98 Query 1 185 use `test`; CREATE TABLE t1(f1 blob)
|
||||
master-bin.000001 185 User var 1 224 @`var1`=_binary 0x8300 COLLATE binary
|
||||
master-bin.000001 224 Query 1 317 use `test`; INSERT INTO t1 VALUES(@'var1')
|
||||
SELECT HEX(f1) FROM t1;
|
||||
HEX(f1)
|
||||
8300
|
||||
DROP table t1;
|
|
@ -93,7 +93,7 @@ explain extended select grp,group_concat(distinct c order by c desc) from t1 gro
|
|||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 9 Using filesort
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`grp` AS `grp`,group_concat(distinct `test`.`t1`.`c` order by `test`.`t1`.`c` separator ',') AS `group_concat(distinct c order by c desc)` from `test`.`t1` group by `test`.`t1`.`grp`
|
||||
Note 1003 select `test`.`t1`.`grp` AS `grp`,group_concat(distinct `test`.`t1`.`c` order by `test`.`t1`.`c` DESC separator ',') AS `group_concat(distinct c order by c desc)` from `test`.`t1` group by `test`.`t1`.`grp`
|
||||
select grp,group_concat(c order by c separator ",") from t1 group by grp;
|
||||
grp group_concat(c order by c separator ",")
|
||||
1 a
|
||||
|
@ -113,7 +113,7 @@ explain extended select grp,group_concat(distinct c order by c separator ",") fr
|
|||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 9 Using filesort
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`grp` AS `grp`,group_concat(distinct `test`.`t1`.`c` order by `test`.`t1`.`c` separator ',') AS `group_concat(distinct c order by c separator ",")` from `test`.`t1` group by `test`.`t1`.`grp`
|
||||
Note 1003 select `test`.`t1`.`grp` AS `grp`,group_concat(distinct `test`.`t1`.`c` order by `test`.`t1`.`c` ASC separator ',') AS `group_concat(distinct c order by c separator ",")` from `test`.`t1` group by `test`.`t1`.`grp`
|
||||
select grp,group_concat(distinct c order by c desc separator ",") from t1 group by grp;
|
||||
grp group_concat(distinct c order by c desc separator ",")
|
||||
1 a
|
||||
|
|
|
@ -1403,3 +1403,67 @@ SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
|
|||
ERROR 42S22: Unknown column 'v2.x' in 'field list'
|
||||
DROP VIEW v1, v2;
|
||||
DROP TABLE t1, t2, t3, t4, t5, t6;
|
||||
create table t1 (id1 int(11) not null);
|
||||
insert into t1 values (1),(2);
|
||||
create table t2 (id2 int(11) not null);
|
||||
insert into t2 values (1),(2),(3),(4);
|
||||
create table t3 (id3 char(16) not null);
|
||||
insert into t3 values ('100');
|
||||
create table t4 (id2 int(11) not null, id3 char(16));
|
||||
create table t5 (id1 int(11) not null, key (id1));
|
||||
insert into t5 values (1),(2),(1);
|
||||
create view v1 as
|
||||
select t4.id3 from t4 join t2 on t4.id2 = t2.id2;
|
||||
select t1.id1 from t1 inner join (t3 left join v1 on t3.id3 = v1.id3);
|
||||
id1
|
||||
1
|
||||
2
|
||||
drop view v1;
|
||||
drop table t1, t2, t3, t4, t5;
|
||||
create table t0 (a int);
|
||||
insert into t0 values (0),(1),(2),(3);
|
||||
create table t1(a int);
|
||||
insert into t1 select A.a + 10*(B.a) from t0 A, t0 B;
|
||||
create table t2 (a int, b int);
|
||||
insert into t2 values (1,1), (2,2), (3,3);
|
||||
create table t3(a int, b int, filler char(200), key(a));
|
||||
insert into t3 select a,a,'filler' from t1;
|
||||
insert into t3 select a,a,'filler' from t1;
|
||||
create table t4 like t3;
|
||||
insert into t4 select * from t3;
|
||||
insert into t4 select * from t3;
|
||||
create table t5 like t4;
|
||||
insert into t5 select * from t4;
|
||||
insert into t5 select * from t4;
|
||||
create table t6 like t5;
|
||||
insert into t6 select * from t5;
|
||||
insert into t6 select * from t5;
|
||||
create table t7 like t6;
|
||||
insert into t7 select * from t6;
|
||||
insert into t7 select * from t6;
|
||||
explain select * from t4 join
|
||||
t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL X
|
||||
1 SIMPLE t3 ref a a 5 test.t2.b X
|
||||
1 SIMPLE t5 ref a a 5 test.t3.b X
|
||||
1 SIMPLE t4 ref a a 5 test.t3.b X Using where
|
||||
explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b
|
||||
join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL X
|
||||
1 SIMPLE t3 ref a a 5 test.t2.b X Using where
|
||||
1 SIMPLE t4 ref a a 5 test.t3.b X
|
||||
1 SIMPLE t6 ref a a 5 test.t4.b X
|
||||
1 SIMPLE t5 ref a a 5 test.t2.b X
|
||||
1 SIMPLE t7 ref a a 5 test.t5.b X
|
||||
explain select * from t2 left join
|
||||
(t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b
|
||||
join t5 on t5.a=t3.b) on t3.a=t2.b;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL X
|
||||
1 SIMPLE t3 ref a a 5 test.t2.b X
|
||||
1 SIMPLE t4 ref a a 5 test.t3.b X
|
||||
1 SIMPLE t6 ref a a 5 test.t4.b X
|
||||
1 SIMPLE t5 ref a a 5 test.t3.b X
|
||||
drop table t0, t1, t2, t4, t5, t6;
|
||||
|
|
|
@ -2236,6 +2236,7 @@ DROP FUNCTION bug9056_func1;
|
|||
DROP FUNCTION bug9056_func2;
|
||||
DROP PROCEDURE bug9056_proc1;
|
||||
DROP PROCEDURE bug9056_proc2;
|
||||
DROP PROCEDURE `a'b`;
|
||||
drop table t1;
|
||||
drop table if exists t1;
|
||||
create table t1 (`d` timestamp, unique (`d`));
|
||||
|
|
|
@ -673,3 +673,7 @@ select * from atablewithareallylongandirritatingname;
|
|||
a
|
||||
2
|
||||
drop table atablewithareallylongandirritatingname;
|
||||
CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb;
|
||||
select * from t1;
|
||||
b
|
||||
drop table t1;
|
||||
|
|
43
mysql-test/r/read_only.result
Normal file
43
mysql-test/r/read_only.result
Normal file
|
@ -0,0 +1,43 @@
|
|||
DROP TABLE IF EXISTS t1,t2,t3;
|
||||
grant CREATE, SELECT, DROP on *.* to test@localhost;
|
||||
set global read_only=0;
|
||||
create table t1 (a int);
|
||||
insert into t1 values(1);
|
||||
create table t2 select * from t1;
|
||||
set global read_only=1;
|
||||
create table t3 (a int);
|
||||
drop table t3;
|
||||
select @@global.read_only;
|
||||
@@global.read_only
|
||||
1
|
||||
create table t3 (a int);
|
||||
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
|
||||
insert into t1 values(1);
|
||||
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
|
||||
update t1 set a=1 where 1=0;
|
||||
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
|
||||
update t1,t2 set t1.a=t2.a+1 where t1.a=t2.a;
|
||||
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
|
||||
delete t1,t2 from t1,t2 where t1.a=t2.a;
|
||||
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
|
||||
create temporary table t3 (a int);
|
||||
create temporary table t4 (a int) select * from t3;
|
||||
insert into t3 values(1);
|
||||
insert into t4 select * from t3;
|
||||
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
|
||||
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
|
||||
update t1,t3 set t3.a=t1.a+1 where t1.a=t3.a;
|
||||
update t4,t3 set t4.a=t3.a+1 where t4.a=t3.a;
|
||||
delete t1 from t1,t3 where t1.a=t3.a;
|
||||
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
|
||||
delete t3 from t1,t3 where t1.a=t3.a;
|
||||
delete t4 from t3,t4 where t4.a=t3.a;
|
||||
create temporary table t1 (a int);
|
||||
insert into t1 values(1);
|
||||
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
|
||||
delete t1 from t1,t3 where t1.a=t3.a;
|
||||
drop table t1;
|
||||
insert into t1 values(1);
|
||||
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
|
||||
drop table t1,t2;
|
||||
drop user test@localhost;
|
|
@ -3201,3 +3201,43 @@ a b c
|
|||
select * from t1 join t2 straight_join t3 on (t1.a=t3.c);
|
||||
a b c
|
||||
drop table t1, t2 ,t3;
|
||||
create table t1(f1 int, f2 date);
|
||||
insert into t1 values(1,'2005-01-01'),(2,'2005-09-01'),(3,'2005-09-30'),
|
||||
(4,'2005-10-01'),(5,'2005-12-30');
|
||||
select * from t1 where f2 >= 0;
|
||||
f1 f2
|
||||
1 2005-01-01
|
||||
2 2005-09-01
|
||||
3 2005-09-30
|
||||
4 2005-10-01
|
||||
5 2005-12-30
|
||||
select * from t1 where f2 >= '0000-00-00';
|
||||
f1 f2
|
||||
1 2005-01-01
|
||||
2 2005-09-01
|
||||
3 2005-09-30
|
||||
4 2005-10-01
|
||||
5 2005-12-30
|
||||
select * from t1 where f2 >= '2005-09-31';
|
||||
f1 f2
|
||||
4 2005-10-01
|
||||
5 2005-12-30
|
||||
select * from t1 where f2 >= '2005-09-3a';
|
||||
f1 f2
|
||||
4 2005-10-01
|
||||
5 2005-12-30
|
||||
Warnings:
|
||||
Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
|
||||
select * from t1 where f2 <= '2005-09-31';
|
||||
f1 f2
|
||||
1 2005-01-01
|
||||
2 2005-09-01
|
||||
3 2005-09-30
|
||||
select * from t1 where f2 <= '2005-09-3a';
|
||||
f1 f2
|
||||
1 2005-01-01
|
||||
2 2005-09-01
|
||||
3 2005-09-30
|
||||
Warnings:
|
||||
Warning 1292 Incorrect date value: '2005-09-3a' for column 'f2' at row 1
|
||||
drop table t1;
|
||||
|
|
|
@ -3575,4 +3575,46 @@ DROP VIEW bug13095_v1
|
|||
DROP PROCEDURE IF EXISTS bug13095;
|
||||
DROP VIEW IF EXISTS bug13095_v1;
|
||||
DROP TABLE IF EXISTS bug13095_t1;
|
||||
drop procedure if exists bug14210|
|
||||
set @@session.max_heap_table_size=16384|
|
||||
select @@session.max_heap_table_size|
|
||||
@@session.max_heap_table_size
|
||||
16384
|
||||
create table t3 (a char(255)) engine=InnoDB|
|
||||
create procedure bug14210_fill_table()
|
||||
begin
|
||||
declare table_size, max_table_size int default 0;
|
||||
select @@session.max_heap_table_size into max_table_size;
|
||||
delete from t3;
|
||||
insert into t3 (a) values (repeat('a', 255));
|
||||
repeat
|
||||
insert into t3 select a from t3;
|
||||
select count(*)*255 from t3 into table_size;
|
||||
until table_size > max_table_size*2 end repeat;
|
||||
end|
|
||||
call bug14210_fill_table()|
|
||||
drop procedure bug14210_fill_table|
|
||||
create table t4 like t3|
|
||||
create procedure bug14210()
|
||||
begin
|
||||
declare a char(255);
|
||||
declare done int default 0;
|
||||
declare c cursor for select * from t3;
|
||||
declare continue handler for sqlstate '02000' set done = 1;
|
||||
open c;
|
||||
repeat
|
||||
fetch c into a;
|
||||
if not done then
|
||||
insert into t4 values (upper(a));
|
||||
end if;
|
||||
until done end repeat;
|
||||
close c;
|
||||
end|
|
||||
call bug14210()|
|
||||
select count(*) from t4|
|
||||
count(*)
|
||||
256
|
||||
drop table t3, t4|
|
||||
drop procedure bug14210|
|
||||
set @@session.max_heap_table_size=default|
|
||||
drop table t1,t2;
|
||||
|
|
|
@ -846,15 +846,14 @@ select 0/0;
|
|||
NULL
|
||||
select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 as x;
|
||||
x
|
||||
999999999999999999999999999999999999999999999999999999999999999999999999999999999
|
||||
99999999999999999999999999999999999999999999999999999999999999999
|
||||
Warnings:
|
||||
Error 1292 Truncated incorrect DECIMAL value: ''
|
||||
select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x;
|
||||
x
|
||||
NULL
|
||||
100000000000000000000000000000000000000000000000000000000000000000
|
||||
Warnings:
|
||||
Error 1292 Truncated incorrect DECIMAL value: ''
|
||||
Error 1292 Truncated incorrect DECIMAL value: ''
|
||||
select 0.190287977636363637 + 0.040372670 * 0 - 0;
|
||||
0.190287977636363637 + 0.040372670 * 0 - 0
|
||||
0.190287977636363637
|
||||
|
@ -1021,3 +1020,26 @@ cast(@non_existing_user_var/2 as DECIMAL)
|
|||
NULL
|
||||
create table t (d decimal(0,10));
|
||||
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 'd').
|
||||
create table t1 (c1 decimal(64));
|
||||
insert into t1 values(
|
||||
89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);
|
||||
Warnings:
|
||||
Error 1292 Truncated incorrect DECIMAL value: ''
|
||||
Warning 1264 Out of range value adjusted for column 'c1' at row 1
|
||||
insert into t1 values(
|
||||
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 *
|
||||
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999);
|
||||
Warnings:
|
||||
Error 1292 Truncated incorrect DECIMAL value: ''
|
||||
Error 1292 Truncated incorrect DECIMAL value: ''
|
||||
Error 1292 Truncated incorrect DECIMAL value: ''
|
||||
Warning 1264 Out of range value adjusted for column 'c1' at row 1
|
||||
insert into t1 values(1e100);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value adjusted for column 'c1' at row 1
|
||||
select * from t1;
|
||||
c1
|
||||
9999999999999999999999999999999999999999999999999999999999999999
|
||||
9999999999999999999999999999999999999999999999999999999999999999
|
||||
9999999999999999999999999999999999999999999999999999999999999999
|
||||
drop table t1;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
drop table if exists t1,t2,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
|
||||
drop table if exists t1,t2,t3,t4,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
|
||||
drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6;
|
||||
drop database if exists mysqltest;
|
||||
use test;
|
||||
|
@ -2323,3 +2323,55 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
|
||||
DROP VIEW v1,v2;
|
||||
DROP TABLE t1,t2,t3;
|
||||
create table t1 (f1 int, f2 int);
|
||||
insert into t1 values(1,1),(1,2),(1,3);
|
||||
create view v1 as select f1 ,group_concat(f2 order by f2 asc) from t1 group by f1;
|
||||
create view v2 as select f1 ,group_concat(f2 order by f2 desc) from t1 group by f1;
|
||||
select * from v1;
|
||||
f1 group_concat(f2 order by f2 asc)
|
||||
1 1,2,3
|
||||
select * from v2;
|
||||
f1 group_concat(f2 order by f2 desc)
|
||||
1 3,2,1
|
||||
drop view v1,v2;
|
||||
drop table t1;
|
||||
create table t1 (x int, y int);
|
||||
create table t2 (x int, y int, z int);
|
||||
create table t3 (x int, y int, z int);
|
||||
create table t4 (x int, y int, z int);
|
||||
create view v1 as
|
||||
select t1.x
|
||||
from (
|
||||
(t1 join t2 on ((t1.y = t2.y)))
|
||||
join
|
||||
(t3 left join t4 on (t3.y = t4.y) and (t3.z = t4.z))
|
||||
);
|
||||
prepare stmt1 from "select count(*) from v1 where x = ?";
|
||||
set @parm1=1;
|
||||
execute stmt1 using @parm1;
|
||||
count(*)
|
||||
0
|
||||
execute stmt1 using @parm1;
|
||||
count(*)
|
||||
0
|
||||
drop view v1;
|
||||
drop table t1,t2,t3,t4;
|
||||
CREATE TABLE t1(id INT);
|
||||
CREATE VIEW v1 AS SELECT id FROM t1;
|
||||
OPTIMIZE TABLE v1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.v1 optimize note Unknown table 'test.v1'
|
||||
ANALYZE TABLE v1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.v1 analyze note Unknown table 'test.v1'
|
||||
REPAIR TABLE v1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.v1 repair note Unknown table 'test.v1'
|
||||
DROP TABLE t1;
|
||||
OPTIMIZE TABLE v1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.v1 optimize note Unknown table 'test.v1'
|
||||
Warnings:
|
||||
Error 1146 Table 'test.t1' doesn't exist
|
||||
Error 1356 View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
DROP VIEW v1;
|
||||
|
|
|
@ -962,6 +962,7 @@ source include/varchar.inc;
|
|||
# Some errors/warnings on create
|
||||
#
|
||||
|
||||
--replace_result 1024 MAX_KEY_LENGTH 3072 MAX_KEY_LENGTH
|
||||
create table t1 (v varchar(65530), key(v));
|
||||
drop table if exists t1;
|
||||
create table t1 (v varchar(65536));
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Initialize
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
drop table if exists t1, t2;
|
||||
--enable_warnings
|
||||
|
||||
#
|
||||
|
|
|
@ -17,10 +17,10 @@ show tables;
|
|||
connect (con2,localhost,root,,test);
|
||||
show tables;
|
||||
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 1045
|
||||
connect (fail_con,localhost,root,z,test2);
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 1045
|
||||
connect (fail_con,localhost,root,z,);
|
||||
|
||||
|
@ -35,16 +35,16 @@ show tables;
|
|||
connect (con4,localhost,test,gambling,test);
|
||||
show tables;
|
||||
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 1045
|
||||
connect (fail_con,localhost,test,,test2);
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 1045
|
||||
connect (fail_con,localhost,test,,"");
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 1045
|
||||
connect (fail_con,localhost,test,zorro,test2);
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 1045
|
||||
connect (fail_con,localhost,test,zorro,);
|
||||
|
||||
|
@ -63,16 +63,16 @@ show tables;
|
|||
connect (con6,localhost,test,gambling3,test);
|
||||
show tables;
|
||||
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 1045
|
||||
connect (fail_con,localhost,test,,test2);
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 1045
|
||||
connect (fail_con,localhost,test,,);
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 1045
|
||||
connect (fail_con,localhost,test,zorro,test2);
|
||||
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_PORT
|
||||
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
|
||||
--error 1045
|
||||
connect (fail_con,localhost,test,zorro,);
|
||||
|
||||
|
|
|
@ -1314,4 +1314,41 @@ select period from t1;
|
|||
|
||||
drop table if exists t1,t2,t3,t4;
|
||||
|
||||
#
|
||||
# Bug #13894 Server crashes on update of CSV table
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS bug13894;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE bug13894 ( val integer ) ENGINE = CSV;
|
||||
INSERT INTO bug13894 VALUES (5);
|
||||
INSERT INTO bug13894 VALUES (10);
|
||||
INSERT INTO bug13894 VALUES (11);
|
||||
INSERT INTO bug13894 VALUES (10);
|
||||
SELECT * FROM bug13894;
|
||||
UPDATE bug13894 SET val=6 WHERE val=10;
|
||||
SELECT * FROM bug13894;
|
||||
DROP TABLE bug13894;
|
||||
|
||||
#
|
||||
# Bug #14672 Bug in deletion
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS bug14672;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE bug14672 (c1 integer) engine = CSV;
|
||||
INSERT INTO bug14672 VALUES (1), (2), (3);
|
||||
SELECT * FROM bug14672;
|
||||
DELETE FROM bug14672 WHERE c1 = 2;
|
||||
SELECT * FROM bug14672;
|
||||
INSERT INTO bug14672 VALUES (4);
|
||||
SELECT * FROM bug14672;
|
||||
INSERT INTO bug14672 VALUES (5);
|
||||
SELECT * FROM bug14672;
|
||||
DROP TABLE bug14672;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
|
34
mysql-test/t/ctype_cp932_binlog.test
Normal file
34
mysql-test/t/ctype_cp932_binlog.test
Normal file
|
@ -0,0 +1,34 @@
|
|||
-- source include/not_embedded.inc
|
||||
-- source include/have_cp932.inc
|
||||
|
||||
--character_set cp932
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
set names cp932;
|
||||
set character_set_database = cp932;
|
||||
|
||||
# Test prepared statement with 0x8300 sequence in parameter while
|
||||
# running with cp932 client character set.
|
||||
RESET MASTER;
|
||||
CREATE TABLE t1(f1 blob);
|
||||
PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
|
||||
SET @var1= x'8300';
|
||||
# TODO: Note that this doesn't actually test the code which was added for
|
||||
# bug#11338 because this syntax for prepared statements causes the PS to
|
||||
# be replicated differently than if we executed the PS from C or Java.
|
||||
# Using this syntax, variable names are inserted into the binlog instead
|
||||
# of values. The real goal of this test is to check the code that was
|
||||
# added to Item_param::query_val_str() in order to do hex encoding of
|
||||
# PS parameters when the client character set is cp932;
|
||||
# Bug#11338 has an example java program which can be used to verify this
|
||||
# code (and I have used it to test the fix) until there is some way to
|
||||
# exercise this code from mysql-test-run.
|
||||
EXECUTE stmt1 USING @var1;
|
||||
SHOW BINLOG EVENTS FROM 98;
|
||||
SELECT HEX(f1) FROM t1;
|
||||
DROP table t1;
|
||||
# end test for bug#11338
|
||||
|
||||
# End of 4.1 tests
|
|
@ -832,3 +832,71 @@ SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d);
|
|||
|
||||
DROP VIEW v1, v2;
|
||||
DROP TABLE t1, t2, t3, t4, t5, t6;
|
||||
|
||||
#
|
||||
# BUG#13126 -test case from bug report
|
||||
#
|
||||
create table t1 (id1 int(11) not null);
|
||||
insert into t1 values (1),(2);
|
||||
|
||||
create table t2 (id2 int(11) not null);
|
||||
insert into t2 values (1),(2),(3),(4);
|
||||
|
||||
create table t3 (id3 char(16) not null);
|
||||
insert into t3 values ('100');
|
||||
|
||||
create table t4 (id2 int(11) not null, id3 char(16));
|
||||
|
||||
create table t5 (id1 int(11) not null, key (id1));
|
||||
insert into t5 values (1),(2),(1);
|
||||
|
||||
create view v1 as
|
||||
select t4.id3 from t4 join t2 on t4.id2 = t2.id2;
|
||||
|
||||
select t1.id1 from t1 inner join (t3 left join v1 on t3.id3 = v1.id3);
|
||||
|
||||
drop view v1;
|
||||
drop table t1, t2, t3, t4, t5;
|
||||
|
||||
create table t0 (a int);
|
||||
insert into t0 values (0),(1),(2),(3);
|
||||
create table t1(a int);
|
||||
insert into t1 select A.a + 10*(B.a) from t0 A, t0 B;
|
||||
|
||||
create table t2 (a int, b int);
|
||||
insert into t2 values (1,1), (2,2), (3,3);
|
||||
|
||||
create table t3(a int, b int, filler char(200), key(a));
|
||||
insert into t3 select a,a,'filler' from t1;
|
||||
insert into t3 select a,a,'filler' from t1;
|
||||
|
||||
create table t4 like t3;
|
||||
insert into t4 select * from t3;
|
||||
insert into t4 select * from t3;
|
||||
|
||||
create table t5 like t4;
|
||||
insert into t5 select * from t4;
|
||||
insert into t5 select * from t4;
|
||||
|
||||
create table t6 like t5;
|
||||
insert into t6 select * from t5;
|
||||
insert into t6 select * from t5;
|
||||
|
||||
create table t7 like t6;
|
||||
insert into t7 select * from t6;
|
||||
insert into t7 select * from t6;
|
||||
|
||||
--replace_column 9 X
|
||||
explain select * from t4 join
|
||||
t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b;
|
||||
|
||||
--replace_column 9 X
|
||||
explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b
|
||||
join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b;
|
||||
|
||||
--replace_column 9 X
|
||||
explain select * from t2 left join
|
||||
(t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b
|
||||
join t5 on t5.a=t3.b) on t3.a=t2.b;
|
||||
|
||||
drop table t0, t1, t2, t4, t5, t6;
|
||||
|
|
|
@ -917,6 +917,7 @@ DROP FUNCTION bug9056_func1;
|
|||
DROP FUNCTION bug9056_func2;
|
||||
DROP PROCEDURE bug9056_proc1;
|
||||
DROP PROCEDURE bug9056_proc2;
|
||||
DROP PROCEDURE `a'b`;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
|
|
|
@ -615,3 +615,12 @@ create table atablewithareallylongandirritatingname (a int);
|
|||
insert into atablewithareallylongandirritatingname values (2);
|
||||
select * from atablewithareallylongandirritatingname;
|
||||
drop table atablewithareallylongandirritatingname;
|
||||
|
||||
|
||||
#
|
||||
# BUG#14514
|
||||
#
|
||||
|
||||
CREATE TABLE t1 ( b INT ) PACK_KEYS = 0 ENGINE = ndb;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
|
103
mysql-test/t/read_only.test
Normal file
103
mysql-test/t/read_only.test
Normal file
|
@ -0,0 +1,103 @@
|
|||
# Test of the READ_ONLY global variable:
|
||||
# check that it blocks updates unless they are only on temporary tables.
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1,t2,t3;
|
||||
--enable_warnings
|
||||
|
||||
# READ_ONLY does nothing to SUPER users
|
||||
# so we use a non-SUPER one:
|
||||
|
||||
grant CREATE, SELECT, DROP on *.* to test@localhost;
|
||||
|
||||
connect (con1,localhost,test,,test);
|
||||
|
||||
connection default;
|
||||
|
||||
set global read_only=0;
|
||||
|
||||
connection con1;
|
||||
|
||||
create table t1 (a int);
|
||||
|
||||
insert into t1 values(1);
|
||||
|
||||
create table t2 select * from t1;
|
||||
|
||||
connection default;
|
||||
|
||||
set global read_only=1;
|
||||
|
||||
# We check that SUPER can:
|
||||
|
||||
create table t3 (a int);
|
||||
drop table t3;
|
||||
|
||||
connection con1;
|
||||
|
||||
select @@global.read_only;
|
||||
|
||||
--error 1290
|
||||
create table t3 (a int);
|
||||
|
||||
--error 1290
|
||||
insert into t1 values(1);
|
||||
|
||||
# if a statement, after parse stage, looks like it will update a
|
||||
# non-temp table, it will be rejected, even if at execution it would
|
||||
# have turned out that 0 rows would be updated
|
||||
--error 1290
|
||||
update t1 set a=1 where 1=0;
|
||||
|
||||
# multi-update is special (see sql_parse.cc) so we test it
|
||||
--error 1290
|
||||
update t1,t2 set t1.a=t2.a+1 where t1.a=t2.a;
|
||||
|
||||
# check multi-delete to be sure
|
||||
--error 1290
|
||||
delete t1,t2 from t1,t2 where t1.a=t2.a;
|
||||
|
||||
# With temp tables updates should be accepted:
|
||||
|
||||
create temporary table t3 (a int);
|
||||
|
||||
create temporary table t4 (a int) select * from t3;
|
||||
|
||||
insert into t3 values(1);
|
||||
|
||||
insert into t4 select * from t3;
|
||||
|
||||
# a non-temp table updated:
|
||||
--error 1290
|
||||
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
|
||||
|
||||
# no non-temp table updated (just swapped):
|
||||
update t1,t3 set t3.a=t1.a+1 where t1.a=t3.a;
|
||||
|
||||
update t4,t3 set t4.a=t3.a+1 where t4.a=t3.a;
|
||||
|
||||
--error 1290
|
||||
delete t1 from t1,t3 where t1.a=t3.a;
|
||||
|
||||
delete t3 from t1,t3 where t1.a=t3.a;
|
||||
|
||||
delete t4 from t3,t4 where t4.a=t3.a;
|
||||
|
||||
# and even homonymous ones
|
||||
|
||||
create temporary table t1 (a int);
|
||||
|
||||
insert into t1 values(1);
|
||||
|
||||
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
|
||||
|
||||
delete t1 from t1,t3 where t1.a=t3.a;
|
||||
|
||||
drop table t1;
|
||||
|
||||
--error 1290
|
||||
insert into t1 values(1);
|
||||
|
||||
connection default;
|
||||
drop table t1,t2;
|
||||
drop user test@localhost;
|
|
@ -2711,3 +2711,21 @@ select * from t1 join t2 left join t3 on (t1.a=t3.c);
|
|||
select * from t1 join t2 right join t3 on (t1.a=t3.c);
|
||||
select * from t1 join t2 straight_join t3 on (t1.a=t3.c);
|
||||
drop table t1, t2 ,t3;
|
||||
|
||||
#
|
||||
# Bug #14093 Query takes a lot of time when date format is not valid
|
||||
# fix optimizes execution. so here we just check that returned set is
|
||||
# correct.
|
||||
create table t1(f1 int, f2 date);
|
||||
insert into t1 values(1,'2005-01-01'),(2,'2005-09-01'),(3,'2005-09-30'),
|
||||
(4,'2005-10-01'),(5,'2005-12-30');
|
||||
# should return all records
|
||||
select * from t1 where f2 >= 0;
|
||||
select * from t1 where f2 >= '0000-00-00';
|
||||
# should return 4,5
|
||||
select * from t1 where f2 >= '2005-09-31';
|
||||
select * from t1 where f2 >= '2005-09-3a';
|
||||
# should return 1,2,3
|
||||
select * from t1 where f2 <= '2005-09-31';
|
||||
select * from t1 where f2 <= '2005-09-3a';
|
||||
drop table t1;
|
||||
|
|
|
@ -4488,6 +4488,58 @@ DROP TABLE IF EXISTS bug13095_t1;
|
|||
|
||||
delimiter |;
|
||||
|
||||
#
|
||||
# BUG#14210: "Simple query with > operator on large table gives server
|
||||
# crash"
|
||||
# Check that cursors work in case when HEAP tables are converted to
|
||||
# MyISAM
|
||||
#
|
||||
--disable_warnings
|
||||
drop procedure if exists bug14210|
|
||||
--enable_warnings
|
||||
set @@session.max_heap_table_size=16384|
|
||||
select @@session.max_heap_table_size|
|
||||
# To trigger the memory corruption the original table must be InnoDB.
|
||||
# No harm if it's not, so don't warn if the suite is run with --skip-innodb
|
||||
--disable_warnings
|
||||
create table t3 (a char(255)) engine=InnoDB|
|
||||
--enable_warnings
|
||||
create procedure bug14210_fill_table()
|
||||
begin
|
||||
declare table_size, max_table_size int default 0;
|
||||
select @@session.max_heap_table_size into max_table_size;
|
||||
delete from t3;
|
||||
insert into t3 (a) values (repeat('a', 255));
|
||||
repeat
|
||||
insert into t3 select a from t3;
|
||||
select count(*)*255 from t3 into table_size;
|
||||
until table_size > max_table_size*2 end repeat;
|
||||
end|
|
||||
call bug14210_fill_table()|
|
||||
drop procedure bug14210_fill_table|
|
||||
create table t4 like t3|
|
||||
|
||||
create procedure bug14210()
|
||||
begin
|
||||
declare a char(255);
|
||||
declare done int default 0;
|
||||
declare c cursor for select * from t3;
|
||||
declare continue handler for sqlstate '02000' set done = 1;
|
||||
open c;
|
||||
repeat
|
||||
fetch c into a;
|
||||
if not done then
|
||||
insert into t4 values (upper(a));
|
||||
end if;
|
||||
until done end repeat;
|
||||
close c;
|
||||
end|
|
||||
call bug14210()|
|
||||
select count(*) from t4|
|
||||
|
||||
drop table t3, t4|
|
||||
drop procedure bug14210|
|
||||
set @@session.max_heap_table_size=default|
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
|
|
|
@ -1050,3 +1050,19 @@ select cast(@non_existing_user_var/2 as DECIMAL);
|
|||
#
|
||||
--error 1427
|
||||
create table t (d decimal(0,10));
|
||||
|
||||
#
|
||||
# Bug #13573 (Wrong data inserted for too big values)
|
||||
#
|
||||
|
||||
create table t1 (c1 decimal(64));
|
||||
--disable_ps_protocol
|
||||
insert into t1 values(
|
||||
89000000000000000000000000000000000000000000000000000000000000000000000000000000000000000);
|
||||
insert into t1 values(
|
||||
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 *
|
||||
99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999);
|
||||
--enable_ps_protocol
|
||||
insert into t1 values(1e100);
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
--disable_warnings
|
||||
drop table if exists t1,t2,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
|
||||
drop table if exists t1,t2,t3,t4,t9,`t1a``b`,v1,v2,v3,v4,v5,v6;
|
||||
drop view if exists t1,t2,`t1a``b`,v1,v2,v3,v4,v5,v6;
|
||||
drop database if exists mysqltest;
|
||||
--enable_warnings
|
||||
|
@ -2189,4 +2189,54 @@ EXPLAIN SELECT * FROM v2 WHERE a=1;
|
|||
DROP VIEW v1,v2;
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
#
|
||||
# Bug #14466 lost sort order in GROUP_CONCAT() in a view
|
||||
#
|
||||
create table t1 (f1 int, f2 int);
|
||||
insert into t1 values(1,1),(1,2),(1,3);
|
||||
create view v1 as select f1 ,group_concat(f2 order by f2 asc) from t1 group by f1;
|
||||
create view v2 as select f1 ,group_concat(f2 order by f2 desc) from t1 group by f1;
|
||||
select * from v1;
|
||||
select * from v2;
|
||||
drop view v1,v2;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# BUG#14026 Crash on second PS execution when using views
|
||||
#
|
||||
create table t1 (x int, y int);
|
||||
create table t2 (x int, y int, z int);
|
||||
create table t3 (x int, y int, z int);
|
||||
create table t4 (x int, y int, z int);
|
||||
|
||||
create view v1 as
|
||||
select t1.x
|
||||
from (
|
||||
(t1 join t2 on ((t1.y = t2.y)))
|
||||
join
|
||||
(t3 left join t4 on (t3.y = t4.y) and (t3.z = t4.z))
|
||||
);
|
||||
|
||||
prepare stmt1 from "select count(*) from v1 where x = ?";
|
||||
set @parm1=1;
|
||||
|
||||
execute stmt1 using @parm1;
|
||||
execute stmt1 using @parm1;
|
||||
drop view v1;
|
||||
drop table t1,t2,t3,t4;
|
||||
|
||||
#
|
||||
# Bug #14540: OPTIMIZE, ANALYZE, REPAIR applied to not a view
|
||||
#
|
||||
|
||||
CREATE TABLE t1(id INT);
|
||||
CREATE VIEW v1 AS SELECT id FROM t1;
|
||||
|
||||
OPTIMIZE TABLE v1;
|
||||
ANALYZE TABLE v1;
|
||||
REPAIR TABLE v1;
|
||||
|
||||
DROP TABLE t1;
|
||||
OPTIMIZE TABLE v1;
|
||||
|
||||
DROP VIEW v1;
|
||||
|
|
|
@ -134,7 +134,7 @@ base64_decode(const char *src, size_t size, void *dst)
|
|||
{
|
||||
char b[3];
|
||||
size_t i= 0;
|
||||
void *d= dst;
|
||||
unsigned char *d= (unsigned char*)dst;
|
||||
size_t j;
|
||||
|
||||
while (i < size)
|
||||
|
@ -186,14 +186,14 @@ base64_decode(const char *src, size_t size, void *dst)
|
|||
b[2]= (c >> 0) & 0xff;
|
||||
|
||||
for (j=0; j<3-mark; j++)
|
||||
*(char *)d++= b[j];
|
||||
*d++= b[j];
|
||||
}
|
||||
|
||||
if (i != size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return d - dst;
|
||||
return d - (unsigned char*)dst;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -47,14 +47,12 @@ static inline int create_mysqld_command(Buffer *buf,
|
|||
if (buf->get_size()) /* malloc succeeded */
|
||||
{
|
||||
#ifdef __WIN__
|
||||
buf->append(position, "\"", 1);
|
||||
position++;
|
||||
buf->append(position++, "\"", 1);
|
||||
#endif
|
||||
buf->append(position, mysqld_path_str, mysqld_path_len);
|
||||
position+= mysqld_path_len;
|
||||
#ifdef __WIN__
|
||||
buf->append(position, "\"", 1);
|
||||
position++;
|
||||
buf->append(position++, "\"", 1);
|
||||
#endif
|
||||
/* here the '\0' character is copied from the option string */
|
||||
buf->append(position, option, option_len);
|
||||
|
@ -336,10 +334,15 @@ int Instance_options::complete_initialization(const char *default_path,
|
|||
uint instance_type)
|
||||
{
|
||||
const char *tmp;
|
||||
char *end;
|
||||
|
||||
if (!mysqld_path && !(mysqld_path= strdup_root(&alloc, default_path)))
|
||||
goto err;
|
||||
|
||||
// it's safe to cast this to char* since this is a buffer we are allocating
|
||||
end= convert_dirname((char*)mysqld_path, mysqld_path, NullS);
|
||||
end[-1]= 0;
|
||||
|
||||
mysqld_path_len= strlen(mysqld_path);
|
||||
|
||||
if (mysqld_port)
|
||||
|
|
|
@ -24,6 +24,20 @@
|
|||
#include "portability.h"
|
||||
|
||||
|
||||
void trim_space(const char **text, uint *word_len)
|
||||
{
|
||||
const char *start= *text;
|
||||
while (*start != 0 && *start == ' ')
|
||||
start++;
|
||||
*text= start;
|
||||
|
||||
int len= strlen(start);
|
||||
const char *end= start + len - 1;
|
||||
while (end > start && my_isspace(&my_charset_latin1, *end))
|
||||
end--;
|
||||
*word_len= (end - start)+1;
|
||||
}
|
||||
|
||||
/*
|
||||
Parse output of the given command
|
||||
|
||||
|
@ -82,20 +96,17 @@ int parse_output_and_get_value(const char *command, const char *word,
|
|||
linebuf[sizeof(linebuf) - 1]= '\0'; /* safety */
|
||||
|
||||
/*
|
||||
Get the word, which might contain non-alphanumeric characters. (Usually
|
||||
these are '/', '-' and '.' in the path expressions and filenames)
|
||||
Compare the start of our line with the word(s) we are looking for.
|
||||
*/
|
||||
get_word((const char **) &linep, &found_word_len, NONSPACE);
|
||||
if (!strncmp(word, linep, wordlen))
|
||||
{
|
||||
/*
|
||||
If we have found the word, return the next one (this is usually
|
||||
an option value) or the whole line (if flag)
|
||||
If we have found our word(s), then move linep past the word(s)
|
||||
*/
|
||||
linep+= found_word_len; /* swallow the previous one */
|
||||
linep+= wordlen;
|
||||
if (flag & GET_VALUE)
|
||||
{
|
||||
get_word((const char **) &linep, &found_word_len, NONSPACE);
|
||||
trim_space((const char**) &linep, &found_word_len);
|
||||
if (input_buffer_len <= found_word_len)
|
||||
goto err;
|
||||
strmake(result, linep, found_word_len);
|
||||
|
|
|
@ -73,8 +73,9 @@ unsigned long open_files_limit;
|
|||
int set_stacksize_n_create_thread(pthread_t *thread, pthread_attr_t *attr,
|
||||
void *(*start_routine)(void *), void *arg)
|
||||
{
|
||||
int rc;
|
||||
int rc= 0;
|
||||
|
||||
#ifndef __WIN__
|
||||
/*
|
||||
Set stack size to be safe on the platforms with too small
|
||||
default thread stack.
|
||||
|
@ -82,7 +83,7 @@ int set_stacksize_n_create_thread(pthread_t *thread, pthread_attr_t *attr,
|
|||
rc= pthread_attr_setstacksize(attr,
|
||||
(size_t) (PTHREAD_STACK_MIN +
|
||||
IM_THREAD_STACK_SIZE));
|
||||
|
||||
#endif
|
||||
if (!rc)
|
||||
rc= pthread_create(thread, attr, start_routine, arg);
|
||||
return rc;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "my_pthread.h"
|
||||
|
||||
/* the pid of the manager process (of the signal thread on the LinuxThreads) */
|
||||
extern pid_t manager_pid;
|
||||
|
|
|
@ -82,12 +82,16 @@ handlerton tina_hton= {
|
|||
** TINA tables
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Used for sorting chains.
|
||||
/*
|
||||
Used for sorting chains with qsort().
|
||||
*/
|
||||
int sort_set (tina_set *a, tina_set *b)
|
||||
{
|
||||
return ( a->begin > b->begin ? 1 : ( a->begin < b->begin ? -1 : 0 ) );
|
||||
/*
|
||||
We assume that intervals do not intersect. So, it is enought to compare
|
||||
any two points. Here we take start of intervals for comparison.
|
||||
*/
|
||||
return ( a->begin > b->begin ? -1 : ( a->begin < b->begin ? 1 : 0 ) );
|
||||
}
|
||||
|
||||
static byte* tina_get_key(TINA_SHARE *share,uint *length,
|
||||
|
@ -186,7 +190,8 @@ static TINA_SHARE *get_share(const char *table_name, TABLE *table)
|
|||
thr_lock_init(&share->lock);
|
||||
pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
|
||||
|
||||
if ((share->data_file= my_open(data_file_name, O_RDWR, MYF(0))) == -1)
|
||||
if ((share->data_file= my_open(data_file_name, O_RDWR|O_APPEND,
|
||||
MYF(0))) == -1)
|
||||
goto error2;
|
||||
|
||||
/* We only use share->data_file for writing, so we scan to the end to append */
|
||||
|
@ -797,13 +802,8 @@ int ha_tina::rnd_end()
|
|||
qsort(chain, (size_t)(chain_ptr - chain), sizeof(tina_set), (qsort_cmp)sort_set);
|
||||
for (ptr= chain; ptr < chain_ptr; ptr++)
|
||||
{
|
||||
/* We peek a head to see if this is the last chain */
|
||||
if (ptr+1 == chain_ptr)
|
||||
memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end,
|
||||
length - (size_t)ptr->end);
|
||||
else
|
||||
memmove((caddr_t)share->mapped_file + ptr->begin, (caddr_t)share->mapped_file + ptr->end,
|
||||
(size_t)((ptr++)->begin - ptr->end));
|
||||
memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end,
|
||||
length - (size_t)ptr->end);
|
||||
length= length - (size_t)(ptr->end - ptr->begin);
|
||||
}
|
||||
|
||||
|
|
17
sql/field.cc
17
sql/field.cc
|
@ -6202,9 +6202,16 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table)
|
|||
This is done to ensure that ALTER TABLE will convert old VARCHAR fields
|
||||
to now VARCHAR fields.
|
||||
*/
|
||||
return new Field_varstring(field_length, maybe_null(),
|
||||
field_name, new_table,
|
||||
charset());
|
||||
Field *new_field= new Field_varstring(field_length, maybe_null(),
|
||||
field_name, new_table,
|
||||
charset());
|
||||
/*
|
||||
delayed_insert::get_local_table() needs a ptr copied from old table.
|
||||
This is what other new_field() methods do too. The above method of
|
||||
Field_varstring sets ptr to NULL.
|
||||
*/
|
||||
new_field->ptr= ptr;
|
||||
return new_field;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -7931,7 +7938,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs)
|
|||
{
|
||||
int delta;
|
||||
|
||||
for (; !*from && length; from++, length--); // skip left 0's
|
||||
for (; length && !*from; from++, length--); // skip left 0's
|
||||
delta= field_length - length;
|
||||
|
||||
if (delta < -1 ||
|
||||
|
@ -8151,7 +8158,7 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
|
|||
int delta;
|
||||
uchar bits= create_length & 7;
|
||||
|
||||
for (; !*from && length; from++, length--); // skip left 0's
|
||||
for (; length && !*from; from++, length--); // skip left 0's
|
||||
delta= field_length - length;
|
||||
|
||||
if (delta < 0 ||
|
||||
|
|
|
@ -94,8 +94,8 @@ class ha_berkeley: public handler
|
|||
uint max_supported_keys() const { return MAX_KEY-1; }
|
||||
uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; }
|
||||
ha_rows estimate_rows_upper_bound();
|
||||
uint max_supported_key_length() const { return 4294967295L; }
|
||||
uint max_supported_key_part_length() const { return 4294967295L; }
|
||||
uint max_supported_key_length() const { return UINT_MAX32; }
|
||||
uint max_supported_key_part_length() const { return UINT_MAX32; }
|
||||
|
||||
const key_map *keys_to_use_for_scanning() { return &key_map_full; }
|
||||
bool has_transactions() { return 1;}
|
||||
|
|
|
@ -3861,7 +3861,8 @@ int ha_ndbcluster::create(const char *name,
|
|||
uint pack_length, length, i, pk_length= 0;
|
||||
const void *data, *pack_data;
|
||||
char name2[FN_HEADLEN];
|
||||
bool create_from_engine= (info->table_options & HA_CREATE_FROM_ENGINE);
|
||||
bool create_from_engine= test(info->table_options &
|
||||
HA_OPTION_CREATE_FROM_ENGINE);
|
||||
|
||||
DBUG_ENTER("ha_ndbcluster::create");
|
||||
DBUG_PRINT("enter", ("name: %s", name));
|
||||
|
|
|
@ -293,61 +293,61 @@ enum db_type ha_checktype(THD *thd, enum db_type database_type,
|
|||
} /* ha_checktype */
|
||||
|
||||
|
||||
handler *get_new_handler(TABLE *table, enum db_type db_type)
|
||||
handler *get_new_handler(TABLE *table, MEM_ROOT *alloc, enum db_type db_type)
|
||||
{
|
||||
switch (db_type) {
|
||||
#ifndef NO_HASH
|
||||
case DB_TYPE_HASH:
|
||||
return new ha_hash(table);
|
||||
return new (alloc) ha_hash(table);
|
||||
#endif
|
||||
case DB_TYPE_MRG_ISAM:
|
||||
return new ha_myisammrg(table);
|
||||
return new (alloc) ha_myisammrg(table);
|
||||
#ifdef HAVE_BERKELEY_DB
|
||||
case DB_TYPE_BERKELEY_DB:
|
||||
return new ha_berkeley(table);
|
||||
return new (alloc) ha_berkeley(table);
|
||||
#endif
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
case DB_TYPE_INNODB:
|
||||
return new ha_innobase(table);
|
||||
return new (alloc) ha_innobase(table);
|
||||
#endif
|
||||
#ifdef HAVE_EXAMPLE_DB
|
||||
case DB_TYPE_EXAMPLE_DB:
|
||||
return new ha_example(table);
|
||||
return new (alloc) ha_example(table);
|
||||
#endif
|
||||
#ifdef HAVE_ARCHIVE_DB
|
||||
case DB_TYPE_ARCHIVE_DB:
|
||||
return new ha_archive(table);
|
||||
return new (alloc) ha_archive(table);
|
||||
#endif
|
||||
#ifdef HAVE_BLACKHOLE_DB
|
||||
case DB_TYPE_BLACKHOLE_DB:
|
||||
return new ha_blackhole(table);
|
||||
return new (alloc) ha_blackhole(table);
|
||||
#endif
|
||||
#ifdef HAVE_FEDERATED_DB
|
||||
case DB_TYPE_FEDERATED_DB:
|
||||
return new ha_federated(table);
|
||||
return new (alloc) ha_federated(table);
|
||||
#endif
|
||||
#ifdef HAVE_CSV_DB
|
||||
case DB_TYPE_CSV_DB:
|
||||
return new ha_tina(table);
|
||||
return new (alloc) ha_tina(table);
|
||||
#endif
|
||||
#ifdef HAVE_NDBCLUSTER_DB
|
||||
case DB_TYPE_NDBCLUSTER:
|
||||
return new ha_ndbcluster(table);
|
||||
return new (alloc) ha_ndbcluster(table);
|
||||
#endif
|
||||
case DB_TYPE_HEAP:
|
||||
return new ha_heap(table);
|
||||
return new (alloc) ha_heap(table);
|
||||
default: // should never happen
|
||||
{
|
||||
enum db_type def=(enum db_type) current_thd->variables.table_type;
|
||||
/* Try first with 'default table type' */
|
||||
if (db_type != def)
|
||||
return get_new_handler(table, def);
|
||||
return get_new_handler(table, alloc, def);
|
||||
}
|
||||
/* Fall back to MyISAM */
|
||||
case DB_TYPE_MYISAM:
|
||||
return new ha_myisam(table);
|
||||
return new (alloc) ha_myisam(table);
|
||||
case DB_TYPE_MRG_MYISAM:
|
||||
return new ha_myisammrg(table);
|
||||
return new (alloc) ha_myisammrg(table);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1300,7 +1300,7 @@ int ha_delete_table(THD *thd, enum db_type table_type, const char *path,
|
|||
|
||||
/* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
|
||||
if (table_type == DB_TYPE_UNKNOWN ||
|
||||
! (file=get_new_handler(&dummy_table, table_type)))
|
||||
! (file=get_new_handler(&dummy_table, thd->mem_root, table_type)))
|
||||
DBUG_RETURN(ENOENT);
|
||||
|
||||
if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
|
||||
|
@ -2016,7 +2016,7 @@ int ha_create_table_from_engine(THD* thd,
|
|||
DBUG_RETURN(3);
|
||||
|
||||
update_create_info_from_table(&create_info, &table);
|
||||
create_info.table_options|= HA_CREATE_FROM_ENGINE;
|
||||
create_info.table_options|= HA_OPTION_CREATE_FROM_ENGINE;
|
||||
|
||||
if (lower_case_table_names == 2 &&
|
||||
!(table.file->table_flags() & HA_FILE_BASED))
|
||||
|
@ -2469,6 +2469,7 @@ int handler::index_read_idx(byte * buf, uint index, const byte * key,
|
|||
|
||||
TYPELIB *ha_known_exts(void)
|
||||
{
|
||||
MEM_ROOT *mem_root= current_thd->mem_root;
|
||||
if (!known_extensions.type_names || mysys_usage_id != known_extensions_id)
|
||||
{
|
||||
handlerton **types;
|
||||
|
@ -2483,7 +2484,8 @@ TYPELIB *ha_known_exts(void)
|
|||
{
|
||||
if ((*types)->state == SHOW_OPTION_YES)
|
||||
{
|
||||
handler *file= get_new_handler(0,(enum db_type) (*types)->db_type);
|
||||
handler *file= get_new_handler(0, mem_root,
|
||||
(enum db_type) (*types)->db_type);
|
||||
for (ext= file->bas_ext(); *ext; ext++)
|
||||
{
|
||||
while ((old_ext= it++))
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#define HA_ADMIN_REJECT -6
|
||||
#define HA_ADMIN_TRY_ALTER -7
|
||||
#define HA_ADMIN_WRONG_CHECKSUM -8
|
||||
#define HA_ADMIN_NOT_BASE_TABLE -9
|
||||
|
||||
/* Bits in table_flags() to show what database can do */
|
||||
|
||||
|
@ -874,7 +875,7 @@ extern ulong total_ha, total_ha_2pc;
|
|||
/* lookups */
|
||||
enum db_type ha_resolve_by_name(const char *name, uint namelen);
|
||||
const char *ha_get_storage_engine(enum db_type db_type);
|
||||
handler *get_new_handler(TABLE *table, enum db_type db_type);
|
||||
handler *get_new_handler(TABLE *table, MEM_ROOT *alloc, enum db_type db_type);
|
||||
enum db_type ha_checktype(THD *thd, enum db_type database_type,
|
||||
bool no_substitute, bool report_error);
|
||||
bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag);
|
||||
|
|
|
@ -1750,6 +1750,7 @@ public:
|
|||
return ref->save_in_field(field, no_conversions);
|
||||
}
|
||||
Item *new_item();
|
||||
virtual Item *real_item() { return ref; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -186,13 +186,18 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
|
|||
{
|
||||
if ((*item)->const_item())
|
||||
{
|
||||
/* For comparison purposes allow invalid dates like 2000-01-32 */
|
||||
ulong orig_sql_mode= field->table->in_use->variables.sql_mode;
|
||||
field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
|
||||
if (!(*item)->save_in_field(field, 1) && !((*item)->null_value))
|
||||
{
|
||||
Item *tmp=new Item_int_with_ref(field->val_int(), *item);
|
||||
field->table->in_use->variables.sql_mode= orig_sql_mode;
|
||||
if (tmp)
|
||||
thd->change_item_tree(item, tmp);
|
||||
return 1; // Item was replaced
|
||||
}
|
||||
field->table->in_use->variables.sql_mode= orig_sql_mode;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -972,8 +972,8 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
|||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if (!(null_value= (args[1]->null_value ||
|
||||
my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1,
|
||||
val2) > 1)))
|
||||
(my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1,
|
||||
val2) > 3))))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1045,8 +1045,8 @@ my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
|
|||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if (!(null_value= (args[1]->null_value ||
|
||||
my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1,
|
||||
val2) > 1)))
|
||||
(my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1,
|
||||
val2) > 3))))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1083,8 +1083,8 @@ my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
|
|||
return 0;
|
||||
val2= args[1]->val_decimal(&value2);
|
||||
if (!(null_value= (args[1]->null_value ||
|
||||
my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1,
|
||||
val2) > 1)))
|
||||
(my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1,
|
||||
val2) > 3))))
|
||||
return decimal_value;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1124,6 +1124,7 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
|
|||
{
|
||||
my_decimal value1, *val1;
|
||||
my_decimal value2, *val2;
|
||||
int err;
|
||||
|
||||
val1= args[0]->val_decimal(&value1);
|
||||
if ((null_value= args[0]->null_value))
|
||||
|
@ -1131,17 +1132,15 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
|
|||
val2= args[1]->val_decimal(&value2);
|
||||
if ((null_value= args[1]->null_value))
|
||||
return 0;
|
||||
switch (my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value,
|
||||
val1, val2, prec_increment)) {
|
||||
case E_DEC_TRUNCATED:
|
||||
case E_DEC_OK:
|
||||
return decimal_value;
|
||||
case E_DEC_DIV_ZERO:
|
||||
signal_divide_by_null();
|
||||
default:
|
||||
null_value= 1; // Safety
|
||||
if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value,
|
||||
val1, val2, prec_increment)) > 3)
|
||||
{
|
||||
if (err == E_DEC_DIV_ZERO)
|
||||
signal_divide_by_null();
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
return decimal_value;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1378,7 +1377,6 @@ my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value)
|
|||
void Item_func_abs::fix_length_and_dec()
|
||||
{
|
||||
Item_func_num1::fix_length_and_dec();
|
||||
maybe_null= 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3173,6 +3173,10 @@ void Item_func_group_concat::print(String *str)
|
|||
if (i)
|
||||
str->append(',');
|
||||
(*order[i]->item)->print(str);
|
||||
if (order[i]->asc)
|
||||
str->append(" ASC");
|
||||
else
|
||||
str->append(" DESC");
|
||||
}
|
||||
}
|
||||
str->append(" separator \'", 12);
|
||||
|
|
10
sql/log.cc
10
sql/log.cc
|
@ -356,9 +356,10 @@ static int find_uniq_filename(char *name)
|
|||
|
||||
MYSQL_LOG::MYSQL_LOG()
|
||||
:bytes_written(0), last_time(0), query_start(0), name(0),
|
||||
file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0),
|
||||
need_start_event(1), prepared_xids(0), description_event_for_exec(0),
|
||||
description_event_for_queue(0), readers_count(0), reset_pending(FALSE)
|
||||
prepared_xids(0), log_type(LOG_CLOSED), file_id(1), open_count(1),
|
||||
readers_count(0), reset_pending(FALSE), write_error(FALSE), inited(FALSE),
|
||||
need_start_event(TRUE),
|
||||
description_event_for_exec(0), description_event_for_queue(0)
|
||||
{
|
||||
/*
|
||||
We don't want to initialize LOCK_Log here as such initialization depends on
|
||||
|
@ -2074,7 +2075,10 @@ void MYSQL_LOG::wait_for_update(THD* thd, bool is_slave)
|
|||
DBUG_ENTER("wait_for_update");
|
||||
|
||||
if (reset_pending)
|
||||
{
|
||||
pthread_mutex_unlock(&LOCK_log);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
old_msg= thd->enter_cond(&update_cond, &LOCK_log,
|
||||
is_slave ?
|
||||
|
|
|
@ -185,7 +185,7 @@ int str2my_decimal(uint mask, const char *from, uint length,
|
|||
}
|
||||
}
|
||||
}
|
||||
check_result(mask, err);
|
||||
check_result_and_overflow(mask, err, decimal_value);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,19 @@ inline int decimal_operation_results(int result)
|
|||
}
|
||||
#endif /*MYSQL_CLIENT*/
|
||||
|
||||
inline
|
||||
void max_my_decimal(my_decimal *to, int precision, int frac)
|
||||
{
|
||||
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&&
|
||||
(frac <= DECIMAL_MAX_SCALE));
|
||||
max_decimal(precision, frac, (decimal_t*) to);
|
||||
}
|
||||
|
||||
inline void max_internal_decimal(my_decimal *to)
|
||||
{
|
||||
max_my_decimal(to, DECIMAL_MAX_PRECISION, 0);
|
||||
}
|
||||
|
||||
inline int check_result(uint mask, int result)
|
||||
{
|
||||
if (result & mask)
|
||||
|
@ -133,6 +146,18 @@ inline int check_result(uint mask, int result)
|
|||
return result;
|
||||
}
|
||||
|
||||
inline int check_result_and_overflow(uint mask, int result, my_decimal *val)
|
||||
{
|
||||
if (check_result(mask, result) & E_DEC_OVERFLOW)
|
||||
{
|
||||
bool sign= val->sign();
|
||||
val->fix_buffer_pointer();
|
||||
max_internal_decimal(val);
|
||||
val->sign(sign);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline uint my_decimal_length_to_precision(uint length, uint scale,
|
||||
bool unsigned_flag)
|
||||
{
|
||||
|
@ -256,7 +281,8 @@ int my_decimal2double(uint mask, const my_decimal *d, double *result)
|
|||
inline
|
||||
int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end)
|
||||
{
|
||||
return check_result(mask, string2decimal(str, (decimal_t*) d, end));
|
||||
return check_result_and_overflow(mask, string2decimal(str,(decimal_t*)d,end),
|
||||
d);
|
||||
}
|
||||
|
||||
|
||||
|
@ -274,7 +300,7 @@ int string2my_decimal(uint mask, const String *str, my_decimal *d)
|
|||
inline
|
||||
int double2my_decimal(uint mask, double val, my_decimal *d)
|
||||
{
|
||||
return check_result(mask, double2decimal(val, (decimal_t*) d));
|
||||
return check_result_and_overflow(mask, double2decimal(val, (decimal_t*)d), d);
|
||||
}
|
||||
|
||||
|
||||
|
@ -303,7 +329,9 @@ inline
|
|||
int my_decimal_add(uint mask, my_decimal *res, const my_decimal *a,
|
||||
const my_decimal *b)
|
||||
{
|
||||
return check_result(mask, decimal_add((decimal_t*) a, (decimal_t*) b, res));
|
||||
return check_result_and_overflow(mask,
|
||||
decimal_add((decimal_t*)a,(decimal_t*)b,res),
|
||||
res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -311,7 +339,9 @@ inline
|
|||
int my_decimal_sub(uint mask, my_decimal *res, const my_decimal *a,
|
||||
const my_decimal *b)
|
||||
{
|
||||
return check_result(mask, decimal_sub((decimal_t*) a, (decimal_t*) b, res));
|
||||
return check_result_and_overflow(mask,
|
||||
decimal_sub((decimal_t*)a,(decimal_t*)b,res),
|
||||
res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -319,7 +349,9 @@ inline
|
|||
int my_decimal_mul(uint mask, my_decimal *res, const my_decimal *a,
|
||||
const my_decimal *b)
|
||||
{
|
||||
return check_result(mask, decimal_mul((decimal_t*) a, (decimal_t*) b, res));
|
||||
return check_result_and_overflow(mask,
|
||||
decimal_mul((decimal_t*)a,(decimal_t*)b,res),
|
||||
res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -327,8 +359,10 @@ inline
|
|||
int my_decimal_div(uint mask, my_decimal *res, const my_decimal *a,
|
||||
const my_decimal *b, int div_scale_inc)
|
||||
{
|
||||
return check_result(mask, decimal_div((decimal_t*) a, (decimal_t*) b, res,
|
||||
div_scale_inc));
|
||||
return check_result_and_overflow(mask,
|
||||
decimal_div((decimal_t*)a,(decimal_t*)b,res,
|
||||
div_scale_inc),
|
||||
res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -336,7 +370,9 @@ inline
|
|||
int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
|
||||
const my_decimal *b)
|
||||
{
|
||||
return check_result(mask, decimal_mod((decimal_t*) a, (decimal_t*) b, res));
|
||||
return check_result_and_overflow(mask,
|
||||
decimal_mod((decimal_t*)a,(decimal_t*)b,res),
|
||||
res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -347,13 +383,5 @@ int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
|
|||
return decimal_cmp((decimal_t*) a, (decimal_t*) b);
|
||||
}
|
||||
|
||||
inline
|
||||
void max_my_decimal(my_decimal *to, int precision, int frac)
|
||||
{
|
||||
DBUG_ASSERT((precision <= DECIMAL_MAX_PRECISION)&&
|
||||
(frac <= DECIMAL_MAX_SCALE));
|
||||
max_decimal(precision, frac, (decimal_t*) to);
|
||||
}
|
||||
|
||||
#endif /*my_decimal_h*/
|
||||
|
||||
|
|
|
@ -44,6 +44,12 @@
|
|||
typedef ulonglong table_map; /* Used for table bits in join */
|
||||
typedef Bitmap<64> key_map; /* Used for finding keys */
|
||||
typedef ulong key_part_map; /* Used for finding key parts */
|
||||
/*
|
||||
Used to identify NESTED_JOIN structures within a join (applicable only to
|
||||
structures that have not been simplified away and embed more the one
|
||||
element)
|
||||
*/
|
||||
typedef ulonglong nested_join_map;
|
||||
|
||||
/* query_id */
|
||||
typedef ulonglong query_id_t;
|
||||
|
@ -1297,7 +1303,6 @@ int openfrm(THD *thd, const char *name,const char *alias,uint filestat,
|
|||
int readfrm(const char *name, const void** data, uint* length);
|
||||
int writefrm(const char* name, const void* data, uint len);
|
||||
int closefrm(TABLE *table);
|
||||
db_type get_table_type(THD *thd, const char *name);
|
||||
int read_string(File file, gptr *to, uint length);
|
||||
void free_blobs(TABLE *table);
|
||||
int set_zone(int nr,int min_zone,int max_zone);
|
||||
|
|
|
@ -1194,6 +1194,7 @@ static void clean_up_mutexes()
|
|||
(void) rwlock_destroy(&LOCK_sys_init_slave);
|
||||
(void) pthread_mutex_destroy(&LOCK_global_system_variables);
|
||||
(void) pthread_mutex_destroy(&LOCK_global_read_lock);
|
||||
(void) pthread_mutex_destroy(&LOCK_uuid_generator);
|
||||
(void) pthread_cond_destroy(&COND_thread_count);
|
||||
(void) pthread_cond_destroy(&COND_refresh);
|
||||
(void) pthread_cond_destroy(&COND_thread_cache);
|
||||
|
@ -3033,6 +3034,23 @@ server.");
|
|||
sql_print_error("Can't init databases");
|
||||
unireg_abort(1);
|
||||
}
|
||||
|
||||
/*
|
||||
Check that the default storage engine is actually available.
|
||||
*/
|
||||
if (!ha_storage_engine_is_enabled((enum db_type)
|
||||
global_system_variables.table_type))
|
||||
{
|
||||
if (!opt_bootstrap)
|
||||
{
|
||||
sql_print_error("Default storage engine (%s) is not available",
|
||||
ha_get_storage_engine((enum db_type)
|
||||
global_system_variables.table_type));
|
||||
unireg_abort(1);
|
||||
}
|
||||
global_system_variables.table_type= DB_TYPE_MYISAM;
|
||||
}
|
||||
|
||||
tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
|
||||
(TC_LOG *) &mysql_bin_log :
|
||||
(TC_LOG *) &tc_log_mmap) :
|
||||
|
@ -6999,22 +7017,6 @@ static void get_options(int argc,char **argv)
|
|||
!opt_slow_log)
|
||||
sql_print_warning("options --log-slow-admin-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set");
|
||||
|
||||
/*
|
||||
Check that the default storage engine is actually available.
|
||||
*/
|
||||
if (!ha_storage_engine_is_enabled((enum db_type)
|
||||
global_system_variables.table_type))
|
||||
{
|
||||
if (!opt_bootstrap)
|
||||
{
|
||||
sql_print_error("Default storage engine (%s) is not available",
|
||||
ha_get_storage_engine((enum db_type)
|
||||
global_system_variables.table_type));
|
||||
exit(1);
|
||||
}
|
||||
global_system_variables.table_type= DB_TYPE_MYISAM;
|
||||
}
|
||||
|
||||
if (argc > 0)
|
||||
{
|
||||
fprintf(stderr, "%s: Too many arguments (first extra is '%s').\nUse --help to get a list of available options\n", my_progname, *argv);
|
||||
|
|
|
@ -931,7 +931,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
|
|||
}
|
||||
|
||||
THD *thd= current_thd;
|
||||
if (!(file= get_new_handler(head, head->s->db_type)))
|
||||
if (!(file= get_new_handler(head, thd->mem_root, head->s->db_type)))
|
||||
goto failure;
|
||||
DBUG_PRINT("info", ("Allocated new handler %p", file));
|
||||
if (file->ha_open(head->s->path, head->db_stat, HA_OPEN_IGNORE_IF_LOCKED))
|
||||
|
@ -3776,6 +3776,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
|
|||
SEL_ARG *tree= 0;
|
||||
MEM_ROOT *alloc= param->mem_root;
|
||||
char *str;
|
||||
ulong orig_sql_mode;
|
||||
DBUG_ENTER("get_mm_leaf");
|
||||
|
||||
/*
|
||||
|
@ -3921,13 +3922,20 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
|
|||
value->result_type() != STRING_RESULT &&
|
||||
field->cmp_type() != value->result_type())
|
||||
goto end;
|
||||
|
||||
/* For comparison purposes allow invalid dates like 2000-01-32 */
|
||||
orig_sql_mode= field->table->in_use->variables.sql_mode;
|
||||
if (value->real_item()->type() == Item::STRING_ITEM &&
|
||||
(field->type() == FIELD_TYPE_DATE ||
|
||||
field->type() == FIELD_TYPE_DATETIME))
|
||||
field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
|
||||
if (value->save_in_field_no_warnings(field, 1) < 0)
|
||||
{
|
||||
field->table->in_use->variables.sql_mode= orig_sql_mode;
|
||||
/* This happens when we try to insert a NULL field in a not null column */
|
||||
tree= &null_element; // cmp with NULL is never TRUE
|
||||
goto end;
|
||||
}
|
||||
field->table->in_use->variables.sql_mode= orig_sql_mode;
|
||||
str= (char*) alloc_root(alloc, key_part->store_length+1);
|
||||
if (!str)
|
||||
goto end;
|
||||
|
|
|
@ -245,8 +245,8 @@ public:
|
|||
static Geometry *create_from_wkt(Geometry_buffer *buffer,
|
||||
Gis_read_stream *trs, String *wkt,
|
||||
bool init_stream=1);
|
||||
static int Geometry::create_from_wkb(Geometry_buffer *buffer,
|
||||
const char *wkb, uint32 len, String *res);
|
||||
static int create_from_wkb(Geometry_buffer *buffer,
|
||||
const char *wkb, uint32 len, String *res);
|
||||
int as_wkt(String *wkt, const char **end)
|
||||
{
|
||||
uint32 len= get_class_info()->m_name.length;
|
||||
|
|
|
@ -1193,10 +1193,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
|
|||
*/
|
||||
{
|
||||
char path[FN_REFLEN];
|
||||
db_type not_used;
|
||||
strxnmov(path, FN_REFLEN, mysql_data_home, "/", table_list->db, "/",
|
||||
table_list->table_name, reg_ext, NullS);
|
||||
(void) unpack_filename(path, path);
|
||||
if (mysql_frm_type(path) == FRMTYPE_VIEW)
|
||||
if (mysql_frm_type(thd, path, ¬_used) == FRMTYPE_VIEW)
|
||||
{
|
||||
TABLE tab;// will not be used (because it's VIEW) but have to be passed
|
||||
table= &tab;
|
||||
|
@ -2634,7 +2635,7 @@ bool rm_temporary_table(enum db_type base, char *path)
|
|||
if (my_delete(path,MYF(0)))
|
||||
error=1; /* purecov: inspected */
|
||||
*fn_ext(path)='\0'; // remove extension
|
||||
handler *file=get_new_handler((TABLE*) 0, base);
|
||||
handler *file= get_new_handler((TABLE*) 0, current_thd->mem_root, base);
|
||||
if (file && file->delete_table(path))
|
||||
{
|
||||
error=1;
|
||||
|
|
|
@ -190,10 +190,10 @@ class MYSQL_LOG: public TC_LOG
|
|||
private:
|
||||
/* LOCK_log and LOCK_index are inited by init_pthread_objects() */
|
||||
pthread_mutex_t LOCK_log, LOCK_index, LOCK_readers;
|
||||
pthread_mutex_t LOCK_prep_xids;
|
||||
pthread_cond_t COND_prep_xids;
|
||||
pthread_cond_t update_cond;
|
||||
pthread_cond_t reset_cond;
|
||||
bool reset_pending;
|
||||
int readers_count;
|
||||
ulonglong bytes_written;
|
||||
time_t last_time,query_start;
|
||||
IO_CACHE log_file;
|
||||
|
@ -201,21 +201,6 @@ class MYSQL_LOG: public TC_LOG
|
|||
char *name;
|
||||
char time_buff[20],db[NAME_LEN+1];
|
||||
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
|
||||
// current file sequence number for load data infile binary logging
|
||||
uint file_id;
|
||||
uint open_count; // For replication
|
||||
volatile enum_log_type log_type;
|
||||
enum cache_type io_cache_type;
|
||||
bool write_error, inited;
|
||||
bool need_start_event;
|
||||
/*
|
||||
no_auto_events means we don't want any of these automatic events :
|
||||
Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't want
|
||||
a Rotate_log event to be written to the relay log. When we start a relay log
|
||||
etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
|
||||
In 5.0 it's 0 for relay logs too!
|
||||
*/
|
||||
bool no_auto_events;
|
||||
/*
|
||||
The max size before rotation (usable only if log_type == LOG_BIN: binary
|
||||
logs and relay logs).
|
||||
|
@ -227,13 +212,38 @@ class MYSQL_LOG: public TC_LOG
|
|||
fix_max_relay_log_size).
|
||||
*/
|
||||
ulong max_size;
|
||||
|
||||
ulong prepared_xids; /* for tc log - number of xids to remember */
|
||||
pthread_mutex_t LOCK_prep_xids;
|
||||
pthread_cond_t COND_prep_xids;
|
||||
volatile enum_log_type log_type;
|
||||
enum cache_type io_cache_type;
|
||||
// current file sequence number for load data infile binary logging
|
||||
uint file_id;
|
||||
uint open_count; // For replication
|
||||
int readers_count;
|
||||
bool reset_pending;
|
||||
bool write_error, inited;
|
||||
bool need_start_event;
|
||||
/*
|
||||
no_auto_events means we don't want any of these automatic events :
|
||||
Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't
|
||||
want a Rotate_log event to be written to the relay log. When we start a
|
||||
relay log etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
|
||||
In 5.0 it's 0 for relay logs too!
|
||||
*/
|
||||
bool no_auto_events;
|
||||
friend class Log_event;
|
||||
|
||||
public:
|
||||
/*
|
||||
These describe the log's format. This is used only for relay logs.
|
||||
_for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
|
||||
necessary to have 2 distinct objects, because the I/O thread may be reading
|
||||
events in a different format from what the SQL thread is reading (consider
|
||||
the case of a master which has been upgraded from 5.0 to 5.1 without doing
|
||||
RESET MASTER, or from 4.x to 5.0).
|
||||
*/
|
||||
Format_description_log_event *description_event_for_exec,
|
||||
*description_event_for_queue;
|
||||
|
||||
MYSQL_LOG();
|
||||
/*
|
||||
note that there's no destructor ~MYSQL_LOG() !
|
||||
|
@ -246,18 +256,6 @@ public:
|
|||
int log(THD *thd, my_xid xid);
|
||||
void unlog(ulong cookie, my_xid xid);
|
||||
int recover(IO_CACHE *log, Format_description_log_event *fdle);
|
||||
|
||||
/*
|
||||
These describe the log's format. This is used only for relay logs.
|
||||
_for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
|
||||
necessary to have 2 distinct objects, because the I/O thread may be reading
|
||||
events in a different format from what the SQL thread is reading (consider
|
||||
the case of a master which has been upgraded from 5.0 to 5.1 without doing
|
||||
RESET MASTER, or from 4.x to 5.0).
|
||||
*/
|
||||
Format_description_log_event *description_event_for_exec,
|
||||
*description_event_for_queue;
|
||||
|
||||
void reset_bytes_written()
|
||||
{
|
||||
bytes_written = 0;
|
||||
|
|
|
@ -833,7 +833,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
|
|||
if (!dont_send_ok)
|
||||
{
|
||||
db_type table_type;
|
||||
if ((table_type=get_table_type(thd, path)) == DB_TYPE_UNKNOWN)
|
||||
mysql_frm_type(thd, path, &table_type);
|
||||
if (table_type == DB_TYPE_UNKNOWN)
|
||||
{
|
||||
my_error(ER_NO_SUCH_TABLE, MYF(0),
|
||||
table_list->db, table_list->table_name);
|
||||
|
|
|
@ -2037,6 +2037,35 @@ void st_lex::cleanup_after_one_table_open()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Do end-of-prepare fixup for list of tables and their merge-VIEWed tables
|
||||
|
||||
SYNOPSIS
|
||||
fix_prepare_info_in_table_list()
|
||||
thd Thread handle
|
||||
tbl List of tables to process
|
||||
|
||||
DESCRIPTION
|
||||
Perform end-end-of prepare fixup for list of tables, if any of the tables
|
||||
is a merge-algorithm VIEW, recursively fix up its underlying tables as
|
||||
well.
|
||||
|
||||
*/
|
||||
|
||||
static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
|
||||
{
|
||||
for (; tbl; tbl= tbl->next_local)
|
||||
{
|
||||
if (tbl->on_expr)
|
||||
{
|
||||
tbl->prep_on_expr= tbl->on_expr;
|
||||
tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
|
||||
}
|
||||
fix_prepare_info_in_table_list(thd, tbl->merge_underlying_list);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
fix some structures at the end of preparation
|
||||
|
||||
|
@ -2056,16 +2085,7 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds)
|
|||
prep_where= *conds;
|
||||
*conds= where= prep_where->copy_andor_structure(thd);
|
||||
}
|
||||
for (TABLE_LIST *tbl= (TABLE_LIST *)table_list.first;
|
||||
tbl;
|
||||
tbl= tbl->next_local)
|
||||
{
|
||||
if (tbl->on_expr)
|
||||
{
|
||||
tbl->prep_on_expr= tbl->on_expr;
|
||||
tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
|
||||
}
|
||||
}
|
||||
fix_prepare_info_in_table_list(thd, (TABLE_LIST *)table_list.first);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -194,6 +194,18 @@ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
|
|||
#endif
|
||||
|
||||
|
||||
static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
for (TABLE_LIST *table= tables; table; table= table->next_global)
|
||||
{
|
||||
DBUG_ASSERT(table->db && table->table_name);
|
||||
if (table->updating &&
|
||||
!find_temporary_table(thd, table->db, table->table_name))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static HASH hash_user_connections;
|
||||
|
||||
static int get_or_create_user_conn(THD *thd, const char *user,
|
||||
|
@ -2365,7 +2377,7 @@ mysql_execute_command(THD *thd)
|
|||
mysql_reset_errors(thd, 0);
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (thd->slave_thread)
|
||||
if (unlikely(thd->slave_thread))
|
||||
{
|
||||
/*
|
||||
Check if statment should be skipped because of slave filtering
|
||||
|
@ -2404,16 +2416,20 @@ mysql_execute_command(THD *thd)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
/*
|
||||
When option readonly is set deny operations which change tables.
|
||||
Except for the replication thread and the 'super' users.
|
||||
When option readonly is set deny operations which change non-temporary
|
||||
tables. Except for the replication thread and the 'super' users.
|
||||
*/
|
||||
if (opt_readonly &&
|
||||
!(thd->slave_thread ||
|
||||
(thd->security_ctx->master_access & SUPER_ACL)) &&
|
||||
uc_update_queries[lex->sql_command])
|
||||
!(thd->security_ctx->master_access & SUPER_ACL) &&
|
||||
uc_update_queries[lex->sql_command] &&
|
||||
!((lex->sql_command == SQLCOM_CREATE_TABLE) &&
|
||||
(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
|
||||
((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
|
||||
some_non_temp_table_to_be_updated(thd, all_tables)))
|
||||
{
|
||||
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
|
||||
DBUG_RETURN(-1);
|
||||
|
@ -3212,13 +3228,24 @@ end_with_restore_list:
|
|||
|
||||
#ifdef HAVE_REPLICATION
|
||||
/* Check slave filtering rules */
|
||||
if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
|
||||
if (unlikely(thd->slave_thread))
|
||||
{
|
||||
/* we warn the slave SQL thread */
|
||||
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
|
||||
if (all_tables_not_ok(thd, all_tables))
|
||||
{
|
||||
/* we warn the slave SQL thread */
|
||||
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_REPLICATION */
|
||||
if (opt_readonly &&
|
||||
!(thd->security_ctx->master_access & SUPER_ACL) &&
|
||||
some_non_temp_table_to_be_updated(thd, all_tables))
|
||||
{
|
||||
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
res= mysql_multi_update(thd, all_tables,
|
||||
&select_lex->item_list,
|
||||
|
|
|
@ -2109,8 +2109,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
|
|||
were closed in the end of previous prepare or execute call.
|
||||
*/
|
||||
tables->table= 0;
|
||||
if (tables->nested_join)
|
||||
tables->nested_join->counter= 0;
|
||||
|
||||
if (tables->prep_on_expr)
|
||||
{
|
||||
|
|
|
@ -134,6 +134,8 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
|
|||
{
|
||||
TABLE_LIST *ren_table,*new_table;
|
||||
frm_type_enum frm_type;
|
||||
db_type table_type;
|
||||
|
||||
DBUG_ENTER("rename_tables");
|
||||
|
||||
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
|
||||
|
@ -166,13 +168,12 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
|
|||
reg_ext);
|
||||
unpack_filename(name, name);
|
||||
|
||||
frm_type= mysql_frm_type(name);
|
||||
frm_type= mysql_frm_type(thd, name, &table_type);
|
||||
switch (frm_type)
|
||||
{
|
||||
case FRMTYPE_TABLE:
|
||||
{
|
||||
db_type table_type;
|
||||
if ((table_type= get_table_type(thd, name)) == DB_TYPE_UNKNOWN)
|
||||
if (table_type == DB_TYPE_UNKNOWN)
|
||||
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
|
||||
else
|
||||
rc= mysql_rename_table(table_type, ren_table->db, old_alias,
|
||||
|
|
|
@ -98,6 +98,12 @@ static COND* substitute_for_best_equal_field(COND *cond,
|
|||
void *table_join_idx);
|
||||
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
|
||||
COND *conds, bool top);
|
||||
static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next);
|
||||
static void restore_prev_nj_state(JOIN_TAB *last);
|
||||
static void reset_nj_counters(List<TABLE_LIST> *join_list);
|
||||
static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
|
||||
uint first_unused);
|
||||
|
||||
static COND *optimize_cond(JOIN *join, COND *conds,
|
||||
List<TABLE_LIST> *join_list,
|
||||
Item::cond_result *cond_value);
|
||||
|
@ -520,12 +526,14 @@ bool JOIN::test_in_subselect(Item **where)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
global select optimisation.
|
||||
return 0 - success
|
||||
1 - error
|
||||
error code saved in field 'error'
|
||||
*/
|
||||
|
||||
int
|
||||
JOIN::optimize()
|
||||
{
|
||||
|
@ -588,6 +596,7 @@ JOIN::optimize()
|
|||
|
||||
/* Convert all outer joins to inner joins if possible */
|
||||
conds= simplify_joins(this, join_list, conds, TRUE);
|
||||
build_bitmap_for_nested_joins(join_list, 0);
|
||||
|
||||
sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
|
||||
|
||||
|
@ -700,7 +709,8 @@ JOIN::optimize()
|
|||
DBUG_PRINT("error",("Error: make_select() failed"));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
|
||||
reset_nj_counters(join_list);
|
||||
make_outerjoin_info(this);
|
||||
|
||||
/*
|
||||
|
@ -1968,14 +1978,19 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
|||
continue;
|
||||
}
|
||||
outer_join|= table->map;
|
||||
s->embedding_map= 0;
|
||||
for (;embedding; embedding= embedding->embedding)
|
||||
s->embedding_map|= embedding->nested_join->nj_map;
|
||||
continue;
|
||||
}
|
||||
if (embedding)
|
||||
{
|
||||
/* s belongs to a nested join, maybe to several embedded joins */
|
||||
s->embedding_map= 0;
|
||||
do
|
||||
{
|
||||
NESTED_JOIN *nested_join= embedding->nested_join;
|
||||
s->embedding_map|=nested_join->nj_map;
|
||||
s->dependent|= embedding->dep_tables;
|
||||
embedding= embedding->embedding;
|
||||
outer_join|= nested_join->used_tables;
|
||||
|
@ -3549,6 +3564,8 @@ choose_plan(JOIN *join, table_map join_tables)
|
|||
bool straight_join= join->select_options & SELECT_STRAIGHT_JOIN;
|
||||
DBUG_ENTER("choose_plan");
|
||||
|
||||
join->cur_embedding_map= 0;
|
||||
reset_nj_counters(join->join_list);
|
||||
/*
|
||||
if (SELECT_STRAIGHT_JOIN option is set)
|
||||
reorder tables so dependent tables come after tables they depend
|
||||
|
@ -4029,7 +4046,9 @@ best_extension_by_limited_search(JOIN *join,
|
|||
for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
|
||||
{
|
||||
table_map real_table_bit= s->table->map;
|
||||
if ((remaining_tables & real_table_bit) && !(remaining_tables & s->dependent))
|
||||
if ((remaining_tables & real_table_bit) &&
|
||||
!(remaining_tables & s->dependent) &&
|
||||
(!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s)))
|
||||
{
|
||||
double current_record_count, current_read_time;
|
||||
|
||||
|
@ -4045,6 +4064,7 @@ best_extension_by_limited_search(JOIN *join,
|
|||
{
|
||||
DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx,
|
||||
"prune_by_cost"););
|
||||
restore_prev_nj_state(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -4073,6 +4093,7 @@ best_extension_by_limited_search(JOIN *join,
|
|||
{
|
||||
DBUG_EXECUTE("opt", print_plan(join, read_time, record_count, idx,
|
||||
"pruned_by_heuristic"););
|
||||
restore_prev_nj_state(s);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -4107,9 +4128,11 @@ best_extension_by_limited_search(JOIN *join,
|
|||
sizeof(POSITION) * (idx + 1));
|
||||
join->best_read= current_read_time - 0.001;
|
||||
}
|
||||
DBUG_EXECUTE("opt",
|
||||
print_plan(join, current_read_time, current_record_count, idx, "full_plan"););
|
||||
DBUG_EXECUTE("opt", print_plan(join, current_read_time,
|
||||
current_record_count, idx,
|
||||
"full_plan"););
|
||||
}
|
||||
restore_prev_nj_state(s);
|
||||
}
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -4154,7 +4177,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
|||
for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++)
|
||||
{
|
||||
table_map real_table_bit=s->table->map;
|
||||
if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent))
|
||||
if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
|
||||
(!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
|
||||
{
|
||||
double best,best_time,records;
|
||||
best=best_time=records=DBL_MAX;
|
||||
|
@ -4492,10 +4516,10 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
|||
join->unit->select_limit_cnt >= records)
|
||||
join->sort_by_table= (TABLE*) 1; // Must use temporary table
|
||||
|
||||
/*
|
||||
/*
|
||||
Go to the next level only if there hasn't been a better key on
|
||||
this level! This will cut down the search for a lot simple cases!
|
||||
*/
|
||||
*/
|
||||
double current_record_count=record_count*records;
|
||||
double current_read_time=read_time+best;
|
||||
if (best_record_count > current_record_count ||
|
||||
|
@ -4516,6 +4540,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
|||
return;
|
||||
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
|
||||
}
|
||||
restore_prev_nj_state(s);
|
||||
if (join->select_options & SELECT_STRAIGHT_JOIN)
|
||||
break; // Don't test all combinations
|
||||
}
|
||||
|
@ -5101,7 +5126,7 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
|
|||
This function can be called only after the execution plan
|
||||
has been chosen.
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
make_outerjoin_info(JOIN *join)
|
||||
{
|
||||
|
@ -7262,11 +7287,11 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
|
|||
ascent all attributes are calculated, all outer joins that can be
|
||||
converted are replaced and then all unnecessary braces are removed.
|
||||
As join list contains join tables in the reverse order sequential
|
||||
elimination of outer joins does not requite extra recursive calls.
|
||||
elimination of outer joins does not require extra recursive calls.
|
||||
|
||||
EXAMPLES
|
||||
Here is an example of a join query with invalid cross references:
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN ON t3.b=t1.b
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN t3 ON t3.b=t1.b
|
||||
|
||||
RETURN VALUE
|
||||
The new condition, if success
|
||||
|
@ -7423,7 +7448,257 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
|
|||
}
|
||||
DBUG_RETURN(conds);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Assign each nested join structure a bit in nested_join_map
|
||||
|
||||
SYNOPSIS
|
||||
build_bitmap_for_nested_joins()
|
||||
join Join being processed
|
||||
join_list List of tables
|
||||
first_unused Number of first unused bit in nested_join_map before the
|
||||
call
|
||||
|
||||
DESCRIPTION
|
||||
Assign each nested join structure (except "confluent" ones - those that
|
||||
embed only one element) a bit in nested_join_map.
|
||||
|
||||
NOTE
|
||||
This function is called after simplify_joins(), when there are no
|
||||
redundant nested joins, #non_confluent_nested_joins <= #tables_in_join so
|
||||
we will not run out of bits in nested_join_map.
|
||||
|
||||
RETURN
|
||||
First unused bit in nested_join_map after the call.
|
||||
*/
|
||||
|
||||
static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
|
||||
uint first_unused)
|
||||
{
|
||||
List_iterator<TABLE_LIST> li(*join_list);
|
||||
TABLE_LIST *table;
|
||||
DBUG_ENTER("build_bitmap_for_nested_joins");
|
||||
while ((table= li++))
|
||||
{
|
||||
NESTED_JOIN *nested_join;
|
||||
if ((nested_join= table->nested_join))
|
||||
{
|
||||
/*
|
||||
It is guaranteed by simplify_joins() function that a nested join
|
||||
that has only one child represents a single table VIEW (and the child
|
||||
is an underlying table). We don't assign bits to such nested join
|
||||
structures because
|
||||
1. it is redundant (a "sequence" of one table cannot be interleaved
|
||||
with anything)
|
||||
2. we could run out bits in nested_join_map otherwise.
|
||||
*/
|
||||
if (nested_join->join_list.elements != 1)
|
||||
{
|
||||
nested_join->nj_map= 1 << first_unused++;
|
||||
first_unused= build_bitmap_for_nested_joins(&nested_join->join_list,
|
||||
first_unused);
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(first_unused);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Set NESTED_JOIN::counter=0 in all nested joins in passed list
|
||||
|
||||
SYNOPSIS
|
||||
reset_nj_counters()
|
||||
join_list List of nested joins to process. It may also contain base
|
||||
tables which will be ignored.
|
||||
|
||||
DESCRIPTION
|
||||
Recursively set NESTED_JOIN::counter=0 for all nested joins contained in
|
||||
the passed join_list.
|
||||
*/
|
||||
|
||||
static void reset_nj_counters(List<TABLE_LIST> *join_list)
|
||||
{
|
||||
List_iterator<TABLE_LIST> li(*join_list);
|
||||
TABLE_LIST *table;
|
||||
DBUG_ENTER("reset_nj_counters");
|
||||
while ((table= li++))
|
||||
{
|
||||
NESTED_JOIN *nested_join;
|
||||
if ((nested_join= table->nested_join))
|
||||
{
|
||||
nested_join->counter= 0;
|
||||
reset_nj_counters(&nested_join->join_list);
|
||||
}
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check interleaving with an inner tables of an outer join for extension table
|
||||
|
||||
SYNOPSIS
|
||||
check_interleaving_with_nj()
|
||||
join Join being processed
|
||||
last_tab Last table in current partial join order (this function is
|
||||
not called for empty partial join orders)
|
||||
next_tab Table we're going to extend the current partial join with
|
||||
|
||||
DESCRIPTION
|
||||
Check if table next_tab can be added to current partial join order, and
|
||||
if yes, record that it has been added.
|
||||
|
||||
The function assumes that both current partial join order and its
|
||||
extension with next_tab are valid wrt table dependencies.
|
||||
|
||||
IMPLEMENTATION
|
||||
LIMITATIONS ON JOIN ORDER
|
||||
The nested [outer] joins executioner algorithm imposes these limitations
|
||||
on join order:
|
||||
1. "Outer tables first" - any "outer" table must be before any
|
||||
corresponding "inner" table.
|
||||
2. "No interleaving" - tables inside a nested join must form a continuous
|
||||
sequence in join order (i.e. the sequence must not be interrupted by
|
||||
tables that are outside of this nested join).
|
||||
|
||||
#1 is checked elsewhere, this function checks #2 provided that #1 has
|
||||
been already checked.
|
||||
|
||||
WHY NEED NON-INTERLEAVING
|
||||
Consider an example:
|
||||
|
||||
select * from t0 join t1 left join (t2 join t3) on cond1
|
||||
|
||||
The join order "t1 t2 t0 t3" is invalid:
|
||||
|
||||
table t0 is outside of the nested join, so WHERE condition for t0 is
|
||||
attached directly to t0 (without triggers, and it may be used to access
|
||||
t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss
|
||||
combinations of (t1, t2, t3) that satisfy condition cond1, and produce a
|
||||
null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have
|
||||
been produced.
|
||||
|
||||
If table t0 is not between t2 and t3, the problem doesn't exist:
|
||||
* If t0 is located after (t2,t3), WHERE(t0) is applied after nested join
|
||||
processing has finished.
|
||||
* If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are
|
||||
wrapped into condition triggers, which takes care of correct nested
|
||||
join processing.
|
||||
|
||||
HOW IT IS IMPLEMENTED
|
||||
The limitations on join order can be rephrased as follows: for valid
|
||||
join order one must be able to:
|
||||
1. write down the used tables in the join order on one line.
|
||||
2. for each nested join, put one '(' and one ')' on the said line
|
||||
3. write "LEFT JOIN" and "ON (...)" where appropriate
|
||||
4. get a query equivalent to the query we're trying to execute.
|
||||
|
||||
Calls to check_interleaving_with_nj() are equivalent to writing the
|
||||
above described line from left to right.
|
||||
A single check_interleaving_with_nj(A,B) call is equivalent to writing
|
||||
table B and appropriate brackets on condition that table A and
|
||||
appropriate brackets is the last what was written. Graphically the
|
||||
transition is as follows:
|
||||
|
||||
+---- current position
|
||||
|
|
||||
... last_tab ))) | ( next_tab ) )..) | ...
|
||||
X Y Z |
|
||||
+- need to move to this
|
||||
position.
|
||||
|
||||
Notes about the position:
|
||||
The caller guarantees that there is no more then one X-bracket by
|
||||
checking "!(remaining_tables & s->dependent)" before calling this
|
||||
function. X-bracket may have a pair in Y-bracket.
|
||||
|
||||
When "writing" we store/update this auxilary info about the current
|
||||
position:
|
||||
1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
|
||||
joins) we've opened but didn't close.
|
||||
2. {each NESTED_JOIN structure not simplified away}->counter - number
|
||||
of this nested join's children that have already been added to to
|
||||
the partial join order.
|
||||
|
||||
RETURN
|
||||
FALSE Join order extended, nested joins info about current join order
|
||||
(see NOTE section) updated.
|
||||
TRUE Requested join order extension not allowed.
|
||||
*/
|
||||
|
||||
static bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab)
|
||||
{
|
||||
TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding;
|
||||
JOIN *join= last_tab->join;
|
||||
|
||||
if (join->cur_embedding_map & ~next_tab->embedding_map)
|
||||
{
|
||||
/*
|
||||
next_tab is outside of the "pair of brackets" we're currently in.
|
||||
Cannot add it.
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
Do update counters for "pairs of brackets" that we've left (marked as
|
||||
X,Y,Z in the above picture)
|
||||
*/
|
||||
for (;next_emb; next_emb= next_emb->embedding)
|
||||
{
|
||||
next_emb->nested_join->counter++;
|
||||
if (next_emb->nested_join->counter == 1)
|
||||
{
|
||||
/*
|
||||
next_emb is the first table inside a nested join we've "entered". In
|
||||
the picture above, we're looking at the 'X' bracket. Don't exit yet as
|
||||
X bracket might have Y pair bracket.
|
||||
*/
|
||||
join->cur_embedding_map |= next_emb->nested_join->nj_map;
|
||||
}
|
||||
|
||||
if (next_emb->nested_join->join_list.elements !=
|
||||
next_emb->nested_join->counter)
|
||||
break;
|
||||
|
||||
/*
|
||||
We're currently at Y or Z-bracket as depicted in the above picture.
|
||||
Mark that we've left it and continue walking up the brackets hierarchy.
|
||||
*/
|
||||
join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Nested joins perspective: Remove the last table from the join order
|
||||
|
||||
SYNOPSIS
|
||||
restore_prev_nj_state()
|
||||
last join table to remove, it is assumed to be the last in current
|
||||
partial join order.
|
||||
|
||||
DESCRIPTION
|
||||
Remove the last table from the partial join order and update the nested
|
||||
joins counters and join->cur_embedding_map. It is ok to call this
|
||||
function for the first table in join order (for which
|
||||
check_interleaving_with_nj has not been called)
|
||||
*/
|
||||
|
||||
static void restore_prev_nj_state(JOIN_TAB *last)
|
||||
{
|
||||
TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding;
|
||||
JOIN *join= last->join;
|
||||
while (last_emb && !(--last_emb->nested_join->counter))
|
||||
{
|
||||
join->cur_embedding_map &= last_emb->nested_join->nj_map;
|
||||
last_emb= last_emb->embedding;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static COND *
|
||||
optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
|
||||
|
@ -8029,7 +8304,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
|
||||
statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status);
|
||||
|
||||
if (use_temp_pool)
|
||||
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
|
||||
temp_pool_slot = bitmap_set_next(&temp_pool);
|
||||
|
||||
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
|
||||
|
@ -8279,7 +8554,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
|
||||
OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
|
||||
{
|
||||
table->file=get_new_handler(table,table->s->db_type= DB_TYPE_MYISAM);
|
||||
table->file= get_new_handler(table, &table->mem_root,
|
||||
table->s->db_type= DB_TYPE_MYISAM);
|
||||
if (group &&
|
||||
(param->group_parts > table->file->max_key_parts() ||
|
||||
param->group_length > table->file->max_key_length()))
|
||||
|
@ -8287,7 +8563,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
}
|
||||
else
|
||||
{
|
||||
table->file=get_new_handler(table,table->s->db_type= DB_TYPE_HEAP);
|
||||
table->file= get_new_handler(table, &table->mem_root,
|
||||
table->s->db_type= DB_TYPE_HEAP);
|
||||
}
|
||||
|
||||
if (!using_unique_constraint)
|
||||
|
@ -8871,7 +9148,8 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
|
|||
new_table= *table;
|
||||
new_table.s= &new_table.share_not_to_be_used;
|
||||
new_table.s->db_type= DB_TYPE_MYISAM;
|
||||
if (!(new_table.file= get_new_handler(&new_table,DB_TYPE_MYISAM)))
|
||||
if (!(new_table.file= get_new_handler(&new_table, &new_table.mem_root,
|
||||
DB_TYPE_MYISAM)))
|
||||
DBUG_RETURN(1); // End of memory
|
||||
|
||||
save_proc_info=thd->proc_info;
|
||||
|
|
|
@ -136,7 +136,9 @@ typedef struct st_join_table {
|
|||
TABLE_REF ref;
|
||||
JOIN_CACHE cache;
|
||||
JOIN *join;
|
||||
|
||||
/* Bitmap of nested joins this table is part of */
|
||||
nested_join_map embedding_map;
|
||||
|
||||
void cleanup();
|
||||
} JOIN_TAB;
|
||||
|
||||
|
@ -193,6 +195,13 @@ class JOIN :public Sql_alloc
|
|||
*/
|
||||
ha_rows fetch_limit;
|
||||
POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
|
||||
|
||||
/*
|
||||
Bitmap of nested joins embedding the position at the end of the current
|
||||
partial join (valid only during join optimizer run).
|
||||
*/
|
||||
nested_join_map cur_embedding_map;
|
||||
|
||||
double best_read;
|
||||
List<Item> *fields;
|
||||
List<Cached_item> group_fields, group_fields_cache;
|
||||
|
|
|
@ -2006,6 +2006,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
Security_context *sctx= thd->security_ctx;
|
||||
uint derived_tables= lex->derived_tables;
|
||||
int error= 1;
|
||||
db_type not_used;
|
||||
Open_tables_state open_tables_state_backup;
|
||||
DBUG_ENTER("get_all_tables");
|
||||
|
||||
|
@ -2117,7 +2118,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||
else
|
||||
{
|
||||
my_snprintf(end, len, "/%s%s", file_name, reg_ext);
|
||||
switch (mysql_frm_type(path)) {
|
||||
switch (mysql_frm_type(thd, path, ¬_used)) {
|
||||
case FRMTYPE_ERROR:
|
||||
table->field[3]->store("ERROR", 5, system_charset_info);
|
||||
break;
|
||||
|
|
|
@ -218,6 +218,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||
String wrong_tables;
|
||||
int error;
|
||||
bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
|
||||
|
||||
DBUG_ENTER("mysql_rm_table_part2");
|
||||
|
||||
if (lock_table_names(thd, tables))
|
||||
|
@ -229,6 +230,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||
for (table= tables; table; table= table->next_local)
|
||||
{
|
||||
char *db=table->db;
|
||||
db_type table_type= DB_TYPE_UNKNOWN;
|
||||
|
||||
mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL);
|
||||
if (!close_temporary_table(thd, db, table->table_name))
|
||||
{
|
||||
|
@ -256,7 +259,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||
if (drop_temporary ||
|
||||
(access(path,F_OK) &&
|
||||
ha_create_table_from_engine(thd,db,alias)) ||
|
||||
(!drop_view && mysql_frm_type(path) != FRMTYPE_TABLE))
|
||||
(!drop_view &&
|
||||
mysql_frm_type(thd, path, &table_type) != FRMTYPE_TABLE))
|
||||
{
|
||||
// Table was not found on disk and table can't be created from engine
|
||||
if (if_exists)
|
||||
|
@ -269,7 +273,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||
else
|
||||
{
|
||||
char *end;
|
||||
db_type table_type= get_table_type(thd, path);
|
||||
if (table_type == DB_TYPE_UNKNOWN)
|
||||
mysql_frm_type(thd, path, &table_type);
|
||||
*(end=fn_ext(path))=0; // Remove extension for delete
|
||||
error= ha_delete_table(thd, table_type, path, table->table_name,
|
||||
!dont_log_query);
|
||||
|
@ -1508,7 +1513,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
|
|||
if (create_info->row_type == ROW_TYPE_DYNAMIC)
|
||||
db_options|=HA_OPTION_PACK_RECORD;
|
||||
alias= table_case_name(create_info, table_name);
|
||||
file=get_new_handler((TABLE*) 0, create_info->db_type);
|
||||
file= get_new_handler((TABLE*) 0, thd->mem_root, create_info->db_type);
|
||||
|
||||
#ifdef NOT_USED
|
||||
/*
|
||||
|
@ -1806,10 +1811,12 @@ mysql_rename_table(enum db_type base,
|
|||
const char *new_db,
|
||||
const char *new_name)
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
|
||||
char *from_base= from, *to_base= to;
|
||||
char tmp_name[NAME_LEN+1];
|
||||
handler *file=(base == DB_TYPE_UNKNOWN ? 0 : get_new_handler((TABLE*) 0, base));
|
||||
handler *file= (base == DB_TYPE_UNKNOWN ? 0 :
|
||||
get_new_handler((TABLE*) 0, thd->mem_root, base));
|
||||
int error=0;
|
||||
DBUG_ENTER("mysql_rename_table");
|
||||
|
||||
|
@ -2189,7 +2196,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||
/* if view are unsupported */
|
||||
if (table->view && view_operator_func == NULL)
|
||||
{
|
||||
result_code= HA_ADMIN_NOT_IMPLEMENTED;
|
||||
result_code= HA_ADMIN_NOT_BASE_TABLE;
|
||||
goto send_result;
|
||||
}
|
||||
thd->open_options&= ~extra_open_options;
|
||||
|
@ -2324,6 +2331,16 @@ send_result_message:
|
|||
}
|
||||
break;
|
||||
|
||||
case HA_ADMIN_NOT_BASE_TABLE:
|
||||
{
|
||||
char buf[ERRMSGSIZE+20];
|
||||
uint length= my_snprintf(buf, ERRMSGSIZE,
|
||||
ER(ER_BAD_TABLE_ERROR), table_name);
|
||||
protocol->store("note", 4, system_charset_info);
|
||||
protocol->store(buf, length, system_charset_info);
|
||||
}
|
||||
break;
|
||||
|
||||
case HA_ADMIN_OK:
|
||||
protocol->store("status", 6, system_charset_info);
|
||||
protocol->store("OK",2, system_charset_info);
|
||||
|
@ -2424,16 +2441,19 @@ send_result_message:
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (fatal_error)
|
||||
table->table->s->version=0; // Force close of table
|
||||
else if (open_for_modify)
|
||||
if (table->table)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_open);
|
||||
remove_table_from_cache(thd, table->table->s->db,
|
||||
table->table->s->table_name, RTFC_NO_FLAG);
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
/* May be something modified consequently we have to invalidate cache */
|
||||
query_cache_invalidate3(thd, table->table, 0);
|
||||
if (fatal_error)
|
||||
table->table->s->version=0; // Force close of table
|
||||
else if (open_for_modify)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_open);
|
||||
remove_table_from_cache(thd, table->table->s->db,
|
||||
table->table->s->table_name, RTFC_NO_FLAG);
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
/* Something may be modified, that's why we have to invalidate cache */
|
||||
query_cache_invalidate3(thd, table->table, 0);
|
||||
}
|
||||
}
|
||||
close_thread_tables(thd);
|
||||
table->table=0; // For query cache
|
||||
|
@ -2615,6 +2635,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||
char *src_table= table_ident->table.str;
|
||||
int err;
|
||||
bool res= TRUE;
|
||||
db_type not_used;
|
||||
|
||||
TABLE_LIST src_tables_list;
|
||||
DBUG_ENTER("mysql_create_like_table");
|
||||
src_db= table_ident->db.str ? table_ident->db.str : thd->db;
|
||||
|
@ -2662,7 +2684,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||
/*
|
||||
create like should be not allowed for Views, Triggers, ...
|
||||
*/
|
||||
if (mysql_frm_type(src_path) != FRMTYPE_TABLE)
|
||||
if (mysql_frm_type(thd, src_path, ¬_used) != FRMTYPE_TABLE)
|
||||
{
|
||||
my_error(ER_WRONG_OBJECT, MYF(0), src_db, src_table, "BASE TABLE");
|
||||
goto err;
|
||||
|
|
|
@ -121,7 +121,7 @@ int mysql_update(THD *thd,
|
|||
bool safe_update= thd->options & OPTION_SAFE_UPDATES;
|
||||
bool used_key_is_modified, transactional_table;
|
||||
int res;
|
||||
int error=0;
|
||||
int error;
|
||||
uint used_index= MAX_KEY;
|
||||
bool need_sort= TRUE;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
@ -132,7 +132,7 @@ int mysql_update(THD *thd,
|
|||
ha_rows updated, found;
|
||||
key_map old_used_keys;
|
||||
TABLE *table;
|
||||
SQL_SELECT *select= 0;
|
||||
SQL_SELECT *select;
|
||||
READ_RECORD info;
|
||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||
bool need_reopen;
|
||||
|
@ -237,8 +237,7 @@ int mysql_update(THD *thd,
|
|||
}
|
||||
// Don't count on usage of 'only index' when calculating which key to use
|
||||
table->used_keys.clear_all();
|
||||
if (limit)
|
||||
select= make_select(table, 0, 0, conds, 0, &error);
|
||||
select= make_select(table, 0, 0, conds, 0, &error);
|
||||
if (error || !limit ||
|
||||
(select && select->check_quick(thd, safe_update, limit)))
|
||||
{
|
||||
|
|
|
@ -1171,6 +1171,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
|||
char path[FN_REFLEN];
|
||||
TABLE_LIST *view;
|
||||
bool type= 0;
|
||||
db_type not_used;
|
||||
|
||||
for (view= views; view; view= view->next_local)
|
||||
{
|
||||
|
@ -1178,7 +1179,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
|||
view->table_name, reg_ext, NullS);
|
||||
(void) unpack_filename(path, path);
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
if (access(path, F_OK) || (type= (mysql_frm_type(path) != FRMTYPE_VIEW)))
|
||||
if (access(path, F_OK) ||
|
||||
(type= (mysql_frm_type(thd, path, ¬_used) != FRMTYPE_VIEW)))
|
||||
{
|
||||
char name[FN_REFLEN];
|
||||
my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name);
|
||||
|
@ -1225,24 +1227,36 @@ err:
|
|||
FRMTYPE_VIEW view
|
||||
*/
|
||||
|
||||
frm_type_enum mysql_frm_type(char *path)
|
||||
frm_type_enum mysql_frm_type(THD *thd, char *path, db_type *dbt)
|
||||
{
|
||||
File file;
|
||||
char header[10]; //"TYPE=VIEW\n" it is 10 characters
|
||||
int length;
|
||||
uchar header[10]; //"TYPE=VIEW\n" it is 10 characters
|
||||
int error;
|
||||
DBUG_ENTER("mysql_frm_type");
|
||||
|
||||
*dbt= DB_TYPE_UNKNOWN;
|
||||
|
||||
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
|
||||
{
|
||||
DBUG_RETURN(FRMTYPE_ERROR);
|
||||
}
|
||||
length= my_read(file, (byte*) header, sizeof(header), MYF(MY_WME));
|
||||
error= my_read(file, (byte*) header, sizeof(header), MYF(MY_WME | MY_NABP));
|
||||
my_close(file, MYF(MY_WME));
|
||||
if (length == (int) MY_FILE_ERROR)
|
||||
|
||||
if (error)
|
||||
DBUG_RETURN(FRMTYPE_ERROR);
|
||||
if (length < (int) sizeof(header) ||
|
||||
!strncmp(header, "TYPE=VIEW\n", sizeof(header)))
|
||||
if (!strncmp((char*) header, "TYPE=VIEW\n", sizeof(header)))
|
||||
DBUG_RETURN(FRMTYPE_VIEW);
|
||||
|
||||
/*
|
||||
This is just a check for DB_TYPE. We'll return default unknown type
|
||||
if the following test is true (arg #3). This should not have effect
|
||||
on return value from this function (default FRMTYPE_TABLE)
|
||||
*/
|
||||
if (header[0] != (uchar) 254 || header[1] != 1 ||
|
||||
(header[2] != FRM_VER && header[2] != FRM_VER+1 &&
|
||||
(header[2] < FRM_VER+3 || header[2] > FRM_VER+4)))
|
||||
DBUG_RETURN(FRMTYPE_TABLE);
|
||||
|
||||
*dbt= ha_checktype(thd, (enum db_type) (uint) *(header + 3), 0, 0);
|
||||
DBUG_RETURN(FRMTYPE_TABLE); // Is probably a .frm table
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST * view);
|
|||
|
||||
bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view);
|
||||
|
||||
frm_type_enum mysql_frm_type(char *path);
|
||||
frm_type_enum mysql_frm_type(THD *thd, char *path, db_type *dbt);
|
||||
|
||||
int view_checksum(THD *thd, TABLE_LIST *view);
|
||||
|
||||
|
|
28
sql/table.cc
28
sql/table.cc
|
@ -338,7 +338,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
|
|||
my_free(buff, MYF(0));
|
||||
}
|
||||
/* Allocate handler */
|
||||
if (!(outparam->file= get_new_handler(outparam, share->db_type)))
|
||||
if (!(outparam->file= get_new_handler(outparam, &outparam->mem_root,
|
||||
share->db_type)))
|
||||
goto err;
|
||||
|
||||
error=4;
|
||||
|
@ -1692,29 +1693,6 @@ bool check_column_name(const char *name)
|
|||
return last_char_is_space || (uint) (name - start) > NAME_LEN;
|
||||
}
|
||||
|
||||
/*
|
||||
** Get type of table from .frm file
|
||||
*/
|
||||
|
||||
db_type get_table_type(THD *thd, const char *name)
|
||||
{
|
||||
File file;
|
||||
uchar head[4];
|
||||
int error;
|
||||
DBUG_ENTER("get_table_type");
|
||||
DBUG_PRINT("enter",("name: '%s'",name));
|
||||
|
||||
if ((file=my_open(name,O_RDONLY, MYF(0))) < 0)
|
||||
DBUG_RETURN(DB_TYPE_UNKNOWN);
|
||||
error=my_read(file,(byte*) head,4,MYF(MY_NABP));
|
||||
my_close(file,MYF(0));
|
||||
if (error || head[0] != (uchar) 254 || head[1] != 1 ||
|
||||
(head[2] != FRM_VER && head[2] != FRM_VER+1 &&
|
||||
(head[2] < FRM_VER+3 || head[2] > FRM_VER+4)))
|
||||
DBUG_RETURN(DB_TYPE_UNKNOWN);
|
||||
DBUG_RETURN(ha_checktype(thd,(enum db_type) (uint) *(head+3),0,0));
|
||||
}
|
||||
|
||||
/*
|
||||
Create Item_field for each column in the table.
|
||||
|
||||
|
@ -2511,9 +2489,9 @@ bool st_table_list::prepare_security(THD *thd)
|
|||
{
|
||||
List_iterator_fast<TABLE_LIST> tb(*view_tables);
|
||||
TABLE_LIST *tbl;
|
||||
DBUG_ENTER("st_table_list::prepare_security");
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
Security_context *save_security_ctx= thd->security_ctx;
|
||||
DBUG_ENTER("st_table_list::prepare_security");
|
||||
|
||||
DBUG_ASSERT(!prelocking_placeholder);
|
||||
if (prepare_view_securety_context(thd))
|
||||
|
|
10
sql/table.h
10
sql/table.h
|
@ -795,7 +795,15 @@ typedef struct st_nested_join
|
|||
table_map used_tables; /* bitmap of tables in the nested join */
|
||||
table_map not_null_tables; /* tables that rejects nulls */
|
||||
struct st_join_table *first_nested;/* the first nested table in the plan */
|
||||
uint counter; /* to count tables in the nested join */
|
||||
/*
|
||||
Used to count tables in the nested join in 2 isolated places:
|
||||
1. In make_outerjoin_info().
|
||||
2. check_interleaving_with_nj/restore_prev_nj_state (these are called
|
||||
by the join optimizer.
|
||||
Before each use the counters are zeroed by reset_nj_counters.
|
||||
*/
|
||||
uint counter;
|
||||
nested_join_map nj_map; /* Bit used to identify this nested join*/
|
||||
} NESTED_JOIN;
|
||||
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ bool mysql_create_frm(THD *thd, my_string file_name,
|
|||
if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,0)))
|
||||
DBUG_RETURN(1);
|
||||
if (db_file == NULL)
|
||||
db_file= get_new_handler((TABLE*) 0, create_info->db_type);
|
||||
db_file= get_new_handler((TABLE*) 0, thd->mem_root, create_info->db_type);
|
||||
|
||||
/* If fixed row records, we need one bit to check for deleted rows */
|
||||
if (!(create_info->table_options & HA_OPTION_PACK_RECORD))
|
||||
|
@ -699,7 +699,7 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
|
|||
/* We need a table to generate columns for default values */
|
||||
bzero((char*) &table,sizeof(table));
|
||||
table.s= &table.share_not_to_be_used;
|
||||
handler= get_new_handler((TABLE*) 0, table_type);
|
||||
handler= get_new_handler((TABLE*) 0, thd->mem_root, table_type);
|
||||
|
||||
if (!handler ||
|
||||
!(buff=(uchar*) my_malloc((uint) reclength,MYF(MY_WME | MY_ZEROFILL))))
|
||||
|
|
|
@ -1986,7 +1986,11 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
|
|||
carry+=hi;
|
||||
}
|
||||
for (; carry; buf0--)
|
||||
{
|
||||
if (buf0 < to->buf)
|
||||
return E_DEC_OVERFLOW;
|
||||
ADD(*buf0, *buf0, 0, carry);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we have to check for -0.000 case */
|
||||
|
|
|
@ -259,6 +259,7 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \
|
|||
--includedir=%{_includedir} \
|
||||
--mandir=%{_mandir} \
|
||||
--enable-thread-safe-client \
|
||||
--with-zlib-dir=bundled \
|
||||
--with-readline ; \
|
||||
# Add this for more debugging support
|
||||
# --with-debug
|
||||
|
|
|
@ -14319,6 +14319,7 @@ static void test_bug12243()
|
|||
mysql_autocommit(mysql, TRUE); /* restore default */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Bug#11718: query with function, join and order by returns wrong type
|
||||
*/
|
||||
|
@ -14366,6 +14367,58 @@ static void test_bug12925()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Bug#14210 "Simple query with > operator on large table gives server
|
||||
crash"
|
||||
*/
|
||||
|
||||
static void test_bug14210()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc, i;
|
||||
const char *stmt_text;
|
||||
ulong type;
|
||||
|
||||
myheader("test_bug14210");
|
||||
|
||||
mysql_query(mysql, "drop table if exists t1");
|
||||
/*
|
||||
To trigger the problem the table must be InnoDB, although the problem
|
||||
itself is not InnoDB related. In case the table is MyISAM this test
|
||||
is harmless.
|
||||
*/
|
||||
mysql_query(mysql, "create table t1 (a varchar(255)) type=InnoDB");
|
||||
rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))");
|
||||
myquery(rc);
|
||||
rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384");
|
||||
/* Create a big enough table (more than max_heap_table_size) */
|
||||
for (i= 0; i < 8; i++)
|
||||
{
|
||||
rc= mysql_query(mysql, "insert into t1 (a) select a from t1");
|
||||
myquery(rc);
|
||||
}
|
||||
/* create statement */
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
type= (ulong) CURSOR_TYPE_READ_ONLY;
|
||||
mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
|
||||
|
||||
stmt_text= "select a from t1";
|
||||
|
||||
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
|
||||
check_execute(stmt, rc);
|
||||
rc= mysql_stmt_execute(stmt);
|
||||
while ((rc= mysql_stmt_fetch(stmt)) == 0)
|
||||
;
|
||||
DIE_UNLESS(rc == MYSQL_NO_DATA);
|
||||
|
||||
rc= mysql_stmt_close(stmt);
|
||||
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
myquery(rc);
|
||||
rc= mysql_query(mysql, "set @@session.max_heap_table_size=default");
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
Read and parse arguments and MySQL options from my.cnf
|
||||
*/
|
||||
|
@ -14621,6 +14674,7 @@ static struct my_tests_st my_tests[]= {
|
|||
{ "test_bug11901", test_bug11901 },
|
||||
{ "test_bug11904", test_bug11904 },
|
||||
{ "test_bug12243", test_bug12243 },
|
||||
{ "test_bug14210", test_bug14210 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue