summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/information_schema.result7
-rw-r--r--mysql-test/r/information_schema_db.result14
-rw-r--r--mysql-test/r/ndb_partition_key.result63
-rw-r--r--mysql-test/r/partition.result129
-rw-r--r--mysql-test/r/query_cache_notembedded.result30
-rw-r--r--mysql-test/t/disabled.def2
-rw-r--r--mysql-test/t/information_schema.test5
-rw-r--r--mysql-test/t/information_schema_db.test31
-rw-r--r--mysql-test/t/ndb_partition_key.test45
-rw-r--r--mysql-test/t/partition.test90
-rw-r--r--mysql-test/t/query_cache_notembedded.test40
-rw-r--r--sql/ha_innodb.cc47
-rw-r--r--sql/lex.h2
-rw-r--r--sql/sql_acl.cc7
-rw-r--r--sql/sql_insert.cc53
-rw-r--r--sql/sql_lex.h1
-rw-r--r--sql/sql_parse.cc13
-rw-r--r--sql/sql_partition.cc147
-rw-r--r--sql/sql_show.cc5
-rw-r--r--sql/sql_table.cc1
-rw-r--r--sql/sql_yacc.yy39
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp3
-rw-r--r--vio/viosocket.c22
23 files changed, 701 insertions, 95 deletions
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index d467ad23cea..e4a8226bb37 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -294,6 +294,13 @@ sub1 sub1
select count(*) from information_schema.ROUTINES;
count(*)
2
+create view v1 as select routine_schema, routine_name from information_schema.routines
+order by routine_schema, routine_name;
+select * from v1;
+routine_schema routine_name
+test sel2
+test sub1
+drop view v1;
select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES;
ROUTINE_NAME ROUTINE_DEFINITION
show create function sub1;
diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result
index b9f19368635..584e1701a14 100644
--- a/mysql-test/r/information_schema_db.result
+++ b/mysql-test/r/information_schema_db.result
@@ -33,4 +33,18 @@ create database `inf%`;
use `inf%`;
show tables;
Tables_in_inf%
+grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost';
+create table t1 (f1 int);
+create function func1(curr_int int) returns int
+begin
+declare ret_val int;
+select max(f1) from t1 into ret_val;
+return ret_val;
+end|
+create view v1 as select f1 from t1 where f1 = func1(f1);
+select * from information_schema.tables;
+drop user mysqltest_1@localhost;
+drop view v1;
+drop function func1;
+drop table t1;
drop database `inf%`;
diff --git a/mysql-test/r/ndb_partition_key.result b/mysql-test/r/ndb_partition_key.result
index 90ecde51e9f..87b019c83e2 100644
--- a/mysql-test/r/ndb_partition_key.result
+++ b/mysql-test/r/ndb_partition_key.result
@@ -89,6 +89,69 @@ ALTER TABLE t1
PARTITION BY KEY(a)
(PARTITION p0 ENGINE = NDB, PARTITION p1 ENGINE = NDB);
drop table t1;
+create table t1 (a int)
+engine=ndb
+partition by key(a)
+(partition p0, partition p1);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = ndbcluster, PARTITION p1 ENGINE = ndbcluster)
+alter table t1 engine=heap;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY)
+alter table t1 engine=ndb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = ndbcluster, PARTITION p1 ENGINE = ndbcluster)
+alter table t1 engine=heap remove partitioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+alter table t1 engine=ndb
+partition by key(a)
+(partition p0, partition p1 engine = ndb);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = ndbcluster, PARTITION p1 ENGINE = ndbcluster)
+alter table t1
+partition by key (a)
+(partition p0 engine=ndb, partition p1 engine=ndb);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = ndbcluster, PARTITION p1 ENGINE = ndbcluster)
+alter table t1 remove partitioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY ()
+alter table t1
+partition by key(a)
+(partition p0 engine=ndb, partition p1);
+ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
+alter table t1
+engine=ndb
+partition by key(a)
+(partition p0 engine=ndb, partition p1 engine = ndb);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = ndbcluster, PARTITION p1 ENGINE = ndbcluster)
+drop table t1;
CREATE TABLE t1 (
c1 MEDIUMINT NOT NULL AUTO_INCREMENT,
c2 TEXT NOT NULL,
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 51a4707f5b1..7244dd6ccbf 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -315,6 +315,135 @@ drop table t1;
create table t1 (s1 int, unique (s1)) partition by list (s1) (partition x1 VALUES in (10), partition x2 values in (20));
alter table t1 add partition (partition x3 values in (30));
drop table t1;
+create table t1 (a int)
+partition by key(a)
+partitions 2
+(partition p0 engine=myisam, partition p1 engine=myisam);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MyISAM, PARTITION p1 ENGINE = MyISAM)
+alter table t1;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MyISAM, PARTITION p1 ENGINE = MyISAM)
+alter table t1 engine=myisam;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MyISAM, PARTITION p1 ENGINE = MyISAM)
+alter table t1 engine=heap;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY)
+alter table t1 remove partitioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int)
+engine=myisam
+partition by key(a)
+partitions 2
+(partition p0 engine=myisam, partition p1 engine=myisam);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MyISAM, PARTITION p1 ENGINE = MyISAM)
+alter table t1 add column b int remove partitioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1
+engine=myisam
+partition by key(a)
+(partition p0 engine=myisam, partition p1);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MyISAM, PARTITION p1 ENGINE = MyISAM)
+alter table t1
+engine=heap
+partition by key(a)
+(partition p0, partition p1 engine=heap);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY)
+alter table t1 engine=myisam, add column c int remove partitioning;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1
+engine=heap
+partition by key (a)
+(partition p0, partition p1);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY)
+alter table t1
+partition by key (a)
+(partition p0, partition p1);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY)
+alter table t1
+engine=heap
+partition by key (a)
+(partition p0, partition p1);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` int(11) DEFAULT NULL,
+ `c` int(11) DEFAULT NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1 PARTITION BY KEY (a) (PARTITION p0 ENGINE = MEMORY, PARTITION p1 ENGINE = MEMORY)
+alter table t1
+partition by key(a)
+(partition p0, partition p1 engine=heap);
+ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
+alter table t1
+partition by key(a)
+(partition p0 engine=heap, partition p1);
+ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
+alter table t1
+engine=heap
+partition by key (a)
+(partition p0 engine=heap, partition p1 engine=myisam);
+ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
+alter table t1
+partition by key (a)
+(partition p0 engine=heap, partition p1 engine=myisam);
+ERROR HY000: The mix of handlers in the partitions is not allowed in this version of MySQL
+drop table t1;
CREATE TABLE t1 (
f_int1 INTEGER, f_int2 INTEGER,
f_char1 CHAR(10), f_char2 CHAR(10), f_charbig VARCHAR(1000)
diff --git a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result
index 77fa198eb80..4226738725a 100644
--- a/mysql-test/r/query_cache_notembedded.result
+++ b/mysql-test/r/query_cache_notembedded.result
@@ -314,4 +314,34 @@ drop procedure f2;
drop procedure f3;
drop procedure f4;
drop table t1;
+reset query cache;
+drop function if exists f1;
+create table t1 (id int);
+create function f1 ()
+returns int
+begin
+declare i_var int;
+set i_var = sleep(3);
+insert into t1 values(3);
+set i_var = sleep(3);
+return 0;
+end;|
+ select f1();
+select sleep(4);
+sleep(4)
+0
+select * from t1;
+id
+3
+f1()
+0
+select * from t1;
+id
+3
+reset query cache;
+select * from t1;
+id
+3
+drop table t1;
+drop function f1;
set GLOBAL query_cache_size=0;
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 2c6973b4558..91f8c986cc4 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -34,7 +34,7 @@ rpl_ndb_ddl : master hangs
rpl_ndb_innodb2ndb : Bug#18261: Cluster Replication: tests rpl_ndb_xxx2ndb fails
rpl_ndb_insert_ignore : Bugs: #17431: INSERT IGNORE INTO returns failed: 1296
rpl_ndb_myisam2ndb : Bug#18261: Cluster Replication: tests rpl_ndb_xxx2ndb fails
-#rpl_ndb_log : result not deterministic
+rpl_ndb_log : result not deterministic, TBD if should remove
rpl_ndb_relay_space : Bug#16993
#rpl_ndb_multi_update3 : Bug#17400: delete & update of rows in table without pk fails
rpl_ndb_sp007 : Bug #17290
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 6a1a9f60bc5..f9bd4bddff9 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -146,6 +146,11 @@ select a.ROUTINE_NAME, b.name from information_schema.ROUTINES a,
mysql.proc b where a.ROUTINE_NAME = convert(b.name using utf8) order by 1;
select count(*) from information_schema.ROUTINES;
+create view v1 as select routine_schema, routine_name from information_schema.routines
+order by routine_schema, routine_name;
+select * from v1;
+drop view v1;
+
connect (user1,localhost,mysqltest_1,,);
connection user1;
select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES;
diff --git a/mysql-test/t/information_schema_db.test b/mysql-test/t/information_schema_db.test
index efb738d682c..b65135a621d 100644
--- a/mysql-test/t/information_schema_db.test
+++ b/mysql-test/t/information_schema_db.test
@@ -8,4 +8,35 @@ show tables from INFORMATION_SCHEMA like 'T%';
create database `inf%`;
use `inf%`;
show tables;
+
+#
+# Bug#18113 SELECT * FROM information_schema.xxx crashes server
+# Crash happened when one selected data from one of INFORMATION_SCHEMA
+# tables and in order to build its contents server had to open view which
+# used stored function and table or view on which one had not global or
+# database-level privileges (e.g. had only table-level or had no
+# privileges at all).
+#
+grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost';
+create table t1 (f1 int);
+delimiter |;
+create function func1(curr_int int) returns int
+begin
+ declare ret_val int;
+ select max(f1) from t1 into ret_val;
+ return ret_val;
+end|
+delimiter ;|
+create view v1 as select f1 from t1 where f1 = func1(f1);
+connect (user1,localhost,mysqltest_1,,);
+connection user1;
+--disable_result_log
+select * from information_schema.tables;
+--enable_result_log
+connection default;
+drop user mysqltest_1@localhost;
+drop view v1;
+drop function func1;
+drop table t1;
+
drop database `inf%`;
diff --git a/mysql-test/t/ndb_partition_key.test b/mysql-test/t/ndb_partition_key.test
index 22c84bf132e..d43dc7e49e4 100644
--- a/mysql-test/t/ndb_partition_key.test
+++ b/mysql-test/t/ndb_partition_key.test
@@ -81,6 +81,51 @@ PARTITION BY KEY(a)
drop table t1;
#
+# Bug #17754 Improper handling of removal of partitioning in ALTER TABLE
+# Also added a number of general test cases in the same area
+#
+create table t1 (a int)
+engine=ndb
+partition by key(a)
+(partition p0, partition p1);
+show create table t1;
+
+alter table t1 engine=heap;
+show create table t1;
+
+alter table t1 engine=ndb;
+show create table t1;
+
+alter table t1 engine=heap remove partitioning;
+show create table t1;
+
+alter table t1 engine=ndb
+partition by key(a)
+(partition p0, partition p1 engine = ndb);
+show create table t1;
+
+alter table t1
+partition by key (a)
+(partition p0 engine=ndb, partition p1 engine=ndb);
+show create table t1;
+
+alter table t1 remove partitioning;
+show create table t1;
+
+--error ER_MIX_HANDLER_ERROR
+alter table t1
+partition by key(a)
+(partition p0 engine=ndb, partition p1);
+
+alter table t1
+engine=ndb
+partition by key(a)
+(partition p0 engine=ndb, partition p1 engine = ndb);
+show create table t1;
+
+drop table t1;
+
+#
# BUG 16810 Out of memory when coalesce partition
#
CREATE TABLE t1 (
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index 9da52b916de..ad01977a458 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -409,6 +409,96 @@ alter table t1 add partition (partition x3 values in (30));
drop table t1;
#
+# Bug #17754 Change to explicit removal of partitioning scheme
+# Also added a number of tests to ensure that proper engine is
+# choosen in all kinds of scenarios.
+#
+
+create table t1 (a int)
+partition by key(a)
+partitions 2
+(partition p0 engine=myisam, partition p1 engine=myisam);
+show create table t1;
+
+alter table t1;
+show create table t1;
+
+alter table t1 engine=myisam;
+show create table t1;
+
+alter table t1 engine=heap;
+show create table t1;
+
+alter table t1 remove partitioning;
+show create table t1;
+
+drop table t1;
+
+create table t1 (a int)
+engine=myisam
+partition by key(a)
+partitions 2
+(partition p0 engine=myisam, partition p1 engine=myisam);
+show create table t1;
+
+alter table t1 add column b int remove partitioning;
+show create table t1;
+
+alter table t1
+engine=myisam
+partition by key(a)
+(partition p0 engine=myisam, partition p1);
+show create table t1;
+
+alter table t1
+engine=heap
+partition by key(a)
+(partition p0, partition p1 engine=heap);
+show create table t1;
+
+alter table t1 engine=myisam, add column c int remove partitioning;
+show create table t1;
+
+alter table t1
+engine=heap
+partition by key (a)
+(partition p0, partition p1);
+show create table t1;
+
+alter table t1
+partition by key (a)
+(partition p0, partition p1);
+show create table t1;
+
+alter table t1
+engine=heap
+partition by key (a)
+(partition p0, partition p1);
+show create table t1;
+
+--error ER_MIX_HANDLER_ERROR
+alter table t1
+partition by key(a)
+(partition p0, partition p1 engine=heap);
+
+--error ER_MIX_HANDLER_ERROR
+alter table t1
+partition by key(a)
+(partition p0 engine=heap, partition p1);
+
+--error ER_MIX_HANDLER_ERROR
+alter table t1
+engine=heap
+partition by key (a)
+(partition p0 engine=heap, partition p1 engine=myisam);
+
+--error ER_MIX_HANDLER_ERROR
+alter table t1
+partition by key (a)
+(partition p0 engine=heap, partition p1 engine=myisam);
+
+drop table t1;
+
# Bug #17432: Partition functions containing NULL values should return
# LONGLONG_MIN
#
diff --git a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test
index 5e1ab7051e5..97be9f9f7ca 100644
--- a/mysql-test/t/query_cache_notembedded.test
+++ b/mysql-test/t/query_cache_notembedded.test
@@ -180,5 +180,45 @@ drop procedure f3;
drop procedure f4;
drop table t1;
+#
+# bug#14767: INSERT in SF + concurrent SELECT with query cache
+#
+reset query cache;
+--disable_warnings
+drop function if exists f1;
+--enable_warnings
+create table t1 (id int);
+delimiter |;
+create function f1 ()
+ returns int
+begin
+ declare i_var int;
+ set i_var = sleep(3);
+ insert into t1 values(3);
+ set i_var = sleep(3);
+ return 0;
+end;|
+delimiter ;|
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+connection con1;
+send select f1();
+connection con2;
+select sleep(4);
+select * from t1;
+connection con1;
+reap;
+connection con2;
+# This gives wrong result i.e. 't' table seems to be empty
+select * from t1;
+reset query cache;
+select * from t1;
+drop table t1;
+drop function f1;
+disconnect con1;
+disconnect con2;
+connection default;
set GLOBAL query_cache_size=0;
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 6c8559a1077..416d67aec39 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -534,16 +534,23 @@ convert_error_code_to_mysql(
} else if (error == (int) DB_CORRUPTION) {
- return(HA_ERR_CRASHED);
- } else if (error == (int) DB_NO_SAVEPOINT) {
+ return(HA_ERR_CRASHED);
+ } else if (error == (int) DB_NO_SAVEPOINT) {
- return(HA_ERR_NO_SAVEPOINT);
- } else if (error == (int) DB_LOCK_TABLE_FULL) {
+ return(HA_ERR_NO_SAVEPOINT);
+ } else if (error == (int) DB_LOCK_TABLE_FULL) {
+ /* Since we rolled back the whole transaction, we must
+ tell it also to MySQL so that MySQL knows to empty the
+ cached binlog for this transaction */
- return(HA_ERR_LOCK_TABLE_FULL);
- } else {
- return(-1); // Unknown error
- }
+ if (thd) {
+ ha_rollback(thd);
+ }
+
+ return(HA_ERR_LOCK_TABLE_FULL);
+ } else {
+ return(-1); // Unknown error
+ }
}
/*****************************************************************
@@ -6950,25 +6957,25 @@ ha_innobase::store_lock(
}
/* If we are not doing a LOCK TABLE, DISCARD/IMPORT
- TABLESPACE or TRUNCATE TABLE then allow multiple
+ TABLESPACE or TRUNCATE TABLE then allow multiple
writers. Note that ALTER TABLE uses a TL_WRITE_ALLOW_READ
< TL_WRITE_CONCURRENT_INSERT.
- We especially allow multiple writers if MySQL is at the
- start of a stored procedure call (SQLCOM_CALL)
+ We especially allow multiple writers if MySQL is at the
+ start of a stored procedure call (SQLCOM_CALL)
(MySQL does have thd->in_lock_tables TRUE there). */
- if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
- && lock_type <= TL_WRITE)
- && (!thd->in_lock_tables
- || thd->lex->sql_command == SQLCOM_CALL)
- && !thd->tablespace_op
- && thd->lex->sql_command != SQLCOM_TRUNCATE
- && thd->lex->sql_command != SQLCOM_OPTIMIZE
- && thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
+ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
+ && lock_type <= TL_WRITE)
+ && !(thd->in_lock_tables
+ && thd->lex->sql_command == SQLCOM_LOCK_TABLES)
+ && !thd->tablespace_op
+ && thd->lex->sql_command != SQLCOM_TRUNCATE
+ && thd->lex->sql_command != SQLCOM_OPTIMIZE
+ && thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
lock_type = TL_WRITE_ALLOW_WRITE;
- }
+ }
/* In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
MySQL would use the lock TL_READ_NO_INSERT on t2, and that
diff --git a/sql/lex.h b/sql/lex.h
index 574d7036c8a..9fd8cae1325 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -391,6 +391,7 @@ static SYMBOL symbols[] = {
{ "PARSER", SYM(PARSER_SYM)},
{ "PARTIAL", SYM(PARTIAL)},
{ "PARTITION", SYM(PARTITION_SYM)},
+ { "PARTITIONING", SYM(PARTITIONING_SYM)},
{ "PARTITIONS", SYM(PARTITIONS_SYM)},
{ "PASSWORD", SYM(PASSWORD)},
{ "PHASE", SYM(PHASE_SYM)},
@@ -428,6 +429,7 @@ static SYMBOL symbols[] = {
{ "RELAY_THREAD", SYM(RELAY_THREAD)},
{ "RELEASE", SYM(RELEASE_SYM)},
{ "RELOAD", SYM(RELOAD)},
+ { "REMOVE", SYM(REMOVE_SYM)},
{ "RENAME", SYM(RENAME)},
{ "REORGANIZE", SYM(REORGANIZE_SYM)},
{ "REPAIR", SYM(REPAIR)},
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index f6da9fc588a..aa426cb33f9 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -3668,6 +3668,13 @@ end:
RETURN
0 ok
1 Error: User did not have the requested privileges
+
+ NOTE
+ This functions assumes that either number of tables to be inspected
+ by it is limited explicitly (i.e. is is not UINT_MAX) or table list
+ used and thd->lex->query_tables_own_last value correspond to each
+ other (the latter should be either 0 or point to next_global member
+ of one of elements of this table list).
****************************************************************************/
bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 6e797f558d4..13e1f80f512 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -272,6 +272,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
bool log_on= (thd->options & OPTION_BIN_LOG) ||
(!(thd->security_ctx->master_access & SUPER_ACL));
bool transactional_table, joins_freed= FALSE;
+ bool changed;
uint value_count;
ulong counter = 1;
ulonglong id;
@@ -558,35 +559,33 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
else if (table->next_number_field && info.copied)
id=table->next_number_field->val_int(); // Return auto_increment value
- /*
- Invalidate the table in the query cache if something changed.
- For the transactional algorithm to work the invalidation must be
- before binlog writing and ha_autocommit_or_rollback
- */
- if (info.copied || info.deleted || info.updated)
- {
- query_cache_invalidate3(thd, table_list, 1);
- }
-
transactional_table= table->file->has_transactions();
- if ((info.copied || info.deleted || info.updated) &&
- (error <= 0 || !transactional_table))
+ if ((changed= (info.copied || info.deleted || info.updated)))
{
- if (mysql_bin_log.is_open())
+ /*
+ Invalidate the table in the query cache if something changed.
+ For the transactional algorithm to work the invalidation must be
+ before binlog writing and ha_autocommit_or_rollback
+ */
+ query_cache_invalidate3(thd, table_list, 1);
+ if (error <= 0 || !transactional_table)
{
- if (error <= 0)
- thd->clear_error();
- if (thd->binlog_query(THD::ROW_QUERY_TYPE,
- thd->query, thd->query_length,
- transactional_table, FALSE) &&
- transactional_table)
+ if (mysql_bin_log.is_open())
{
- error=1;
+ if (error <= 0)
+ thd->clear_error();
+ if (thd->binlog_query(THD::ROW_QUERY_TYPE,
+ thd->query, thd->query_length,
+ transactional_table, FALSE) &&
+ transactional_table)
+ {
+ error=1;
+ }
}
+ if (!transactional_table)
+ thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
- if (!transactional_table)
- thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
if (transactional_table)
error=ha_autocommit_or_rollback(thd,error);
@@ -594,6 +593,16 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
+ /*
+ Invalidate the table in the query cache if something changed
+ after unlocking when changes become fisible.
+ TODO: this is workaround. right way will be move invalidating in
+ the unlock procedure.
+ */
+ if (lock_type == TL_WRITE_CONCURRENT_INSERT && changed)
+ {
+ query_cache_invalidate3(thd, table_list, 1);
+ }
thd->lock=0;
}
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 5e67b60cb85..1fea4971c4d 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -705,6 +705,7 @@ typedef class st_select_lex SELECT_LEX;
#define ALTER_ANALYZE_PARTITION (1L << 22)
#define ALTER_CHECK_PARTITION (1L << 23)
#define ALTER_REPAIR_PARTITION (1L << 24)
+#define ALTER_REMOVE_PARTITIONING (1L << 25)
typedef struct st_alter_info
{
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index cb231a7adea..eea2ae57e75 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3351,6 +3351,19 @@ end_with_restore_list:
select_lex->context.table_list=
select_lex->context.first_name_resolution_table= second_table;
res= handle_select(thd, lex, result, OPTION_SETUP_TABLES_DONE);
+ /*
+ Invalidate the table in the query cache if something changed
+ after unlocking when changes become visible.
+ TODO: this is workaround. right way will be move invalidating in
+ the unlock procedure.
+ */
+ if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
+ thd->lock)
+ {
+ mysql_unlock_tables(thd, thd->lock);
+ query_cache_invalidate3(thd, first_table, 1);
+ thd->lock=0;
+ }
delete result;
}
/* revert changes for SP */
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 608db994f66..62c48ba37dc 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -3820,6 +3820,42 @@ end:
/*
+ Set engine type on all partition element objects
+ SYNOPSIS
+ set_engine_all_partitions()
+ part_info Partition info
+ engine_type Handlerton reference of engine
+ RETURN VALUES
+ NONE
+*/
+
+static
+void
+set_engine_all_partitions(partition_info *part_info,
+ handlerton *engine_type)
+{
+ uint i= 0;
+ List_iterator<partition_element> part_it(part_info->partitions);
+ do
+ {
+ partition_element *part_elem= part_it++;
+
+ part_elem->engine_type= engine_type;
+ if (part_info->is_sub_partitioned())
+ {
+ List_iterator<partition_element> sub_it(part_elem->subpartitions);
+ uint j= 0;
+
+ do
+ {
+ partition_element *sub_elem= sub_it++;
+
+ sub_elem->engine_type= engine_type;
+ } while (++j < part_info->no_subparts);
+ }
+ } while (++i < part_info->no_parts);
+}
+/*
SYNOPSIS
fast_alter_partition_error_handler()
lpt Container for parameters
@@ -3921,17 +3957,34 @@ static bool check_engine_condition(partition_element *p_elem,
handlerton **engine_type,
bool *first)
{
+ DBUG_ENTER("check_engine_condition");
+
+ DBUG_PRINT("enter", ("def_eng = %u, first = %u", default_engine, *first));
+ if (*engine_type)
+ DBUG_PRINT("info", ("engine_type = %s", (*engine_type)->name));
+ else
+ DBUG_PRINT("info", ("engine_type = NULL"));
if (*first && default_engine)
+ {
*engine_type= p_elem->engine_type;
+ if (*engine_type)
+ DBUG_PRINT("info", ("engine_type changed to = %s", (*engine_type)->name));
+ else
+ DBUG_PRINT("info", ("engine_type changed to = NULL"));
+ }
*first= FALSE;
if ((!default_engine &&
- (p_elem->engine_type != *engine_type &&
- !p_elem->engine_type)) ||
+ (p_elem->engine_type != (*engine_type) &&
+ p_elem->engine_type)) ||
(default_engine &&
- p_elem->engine_type != *engine_type))
- return TRUE;
+ p_elem->engine_type != (*engine_type)))
+ {
+ DBUG_RETURN(TRUE);
+ }
else
- return FALSE;
+ {
+ DBUG_RETURN(FALSE);
+ }
}
/*
@@ -3968,8 +4021,8 @@ static bool check_native_partitioned(HA_CREATE_INFO *create_info,bool *ret_val,
uint no_parts= part_info->partitions.elements;
DBUG_ENTER("check_native_partitioned");
- default_engine= (create_info->used_fields | HA_CREATE_USED_ENGINE) ?
- TRUE : FALSE;
+ default_engine= (create_info->used_fields & HA_CREATE_USED_ENGINE) ?
+ FALSE : TRUE;
DBUG_PRINT("info", ("engine_type = %u, default = %u",
ha_legacy_type(engine_type),
default_engine));
@@ -4028,6 +4081,7 @@ error:
Mixed engines not yet supported but when supported it will need
the partition handler
*/
+ my_error(ER_MIX_HANDLER_ERROR, MYF(0));
*ret_val= FALSE;
DBUG_RETURN(TRUE);
}
@@ -4811,7 +4865,7 @@ the generated partition syntax in a correct manner.
Case IIa:
There was a partitioning before and there is no new one defined.
- Also the user has not specified an explicit engine to use.
+ Also the user has not specified to remove partitioning explicitly.
We use the old partitioning also for the new table. We do this
by assigning the partition_info from the table loaded in
@@ -4820,12 +4874,11 @@ the generated partition syntax in a correct manner.
Case IIb:
There was a partitioning before and there is no new one defined.
- The user has specified an explicit engine to use.
+ The user has specified explicitly to remove partitioning
- Since the user has specified an explicit engine to use we override
- the old partitioning info and create a new table using the specified
- engine. This is the reason for the extra check if old and new engine
- is equal.
+ Since the user has specified explicitly to remove partitioning
+ we override the old partitioning info and create a new table using
+ the specified engine.
In this case the partition also is changed.
Case III:
@@ -4848,12 +4901,41 @@ the generated partition syntax in a correct manner.
*/
if (table->part_info)
{
- if (!thd->work_part_info &&
- create_info->db_type == old_db_type)
+ if (thd->lex->alter_info.flags & ALTER_REMOVE_PARTITIONING)
+ {
+ DBUG_PRINT("info", ("Remove partitioning"));
+ if (!(thd->lex->create_info.used_fields & HA_CREATE_USED_ENGINE))
+ {
+ DBUG_PRINT("info", ("No explicit engine used"));
+ create_info->db_type= table->part_info->default_engine_type;
+ }
+ DBUG_PRINT("info", ("New engine type = %s",
+ create_info->db_type->name));
+ thd->work_part_info= NULL;
+ *partition_changed= TRUE;
+ }
+ else if (!thd->work_part_info)
+ {
+ /*
+ Retain partitioning but possibly with a new storage engine
+ beneath.
+ */
thd->work_part_info= table->part_info;
+ if (thd->lex->create_info.used_fields & HA_CREATE_USED_ENGINE &&
+ create_info->db_type != table->part_info->default_engine_type)
+ {
+ /*
+ Make sure change of engine happens to all partitions.
+ */
+ set_engine_all_partitions(thd->work_part_info, create_info->db_type);
+ *partition_changed= TRUE;
+ }
+ }
}
if (thd->work_part_info)
{
+ partition_info *part_info= thd->work_part_info;
+ bool is_native_partitioned= FALSE;
/*
Need to cater for engine types that can handle partition without
using the partition handler.
@@ -4861,35 +4943,20 @@ the generated partition syntax in a correct manner.
if (thd->work_part_info != table->part_info)
*partition_changed= TRUE;
if (create_info->db_type == &partition_hton)
+ part_info->default_engine_type= table->part_info->default_engine_type;
+ else
+ part_info->default_engine_type= create_info->db_type;
+ if (check_native_partitioned(create_info, &is_native_partitioned,
+ part_info, thd))
{
- if (table->part_info)
- {
- thd->work_part_info->default_engine_type=
- table->part_info->default_engine_type;
- }
- else
- {
- thd->work_part_info->default_engine_type=
- ha_checktype(thd, DB_TYPE_DEFAULT, FALSE, FALSE);
- }
+ DBUG_RETURN(TRUE);
}
- else
+ if (!is_native_partitioned)
{
- bool is_native_partitioned= FALSE;
- partition_info *part_info= thd->work_part_info;
- part_info->default_engine_type= create_info->db_type;
- if (check_native_partitioned(create_info, &is_native_partitioned,
- part_info, thd))
- {
- DBUG_RETURN(TRUE);
- }
- if (!is_native_partitioned)
- {
- DBUG_ASSERT(create_info->db_type != &default_hton);
- create_info->db_type= &partition_hton;
- }
+ DBUG_ASSERT(create_info->db_type != &default_hton);
+ create_info->db_type= &partition_hton;
}
- DBUG_PRINT("info", ("default_db_type = %s",
+ DBUG_PRINT("info", ("default_engine_type = %s",
thd->work_part_info->default_engine_type->name));
}
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 9310b65e44a..da372d9063d 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -476,7 +476,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
table_list.table_name= file->name;
table_list.table_name_length= strlen(file->name);
table_list.grant.privilege=col_access;
- if (check_grant(thd, TABLE_ACLS, &table_list, 1, UINT_MAX, 1))
+ if (check_grant(thd, TABLE_ACLS, &table_list, 1, 1, 1))
continue;
}
#endif
@@ -4664,7 +4664,8 @@ bool get_schema_tables_result(JOIN *join)
TABLE_LIST *table_list= tab->table->pos_in_table_list;
if (table_list->schema_table && thd->fill_derived_tables())
{
- bool is_subselect= (&lex->unit != lex->current_select->master_unit());
+ bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
+ lex->current_select->master_unit()->item);
/*
The schema table is already processed and
the statement is not a subselect.
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index caf32659eb8..de7b273d57e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2054,6 +2054,7 @@ bool mysql_create_table_internal(THD *thd,
DBUG_RETURN(TRUE);
}
file->set_auto_partitions(part_info);
+ part_info->default_engine_type= create_info->db_type;
}
if (part_info)
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 9accacbd7b4..9304bc3f27c 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -495,6 +495,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token PARSER_SYM
%token PARTIAL
%token PARTITION_SYM
+%token PARTITIONING_SYM
%token PARTITIONS_SYM
%token PASSWORD
%token PARAM_MARKER
@@ -537,6 +538,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token RELAY_THREAD
%token RELEASE_SYM
%token RELOAD
+%token REMOVE_SYM
%token RENAME
%token REORGANIZE_SYM
%token REPAIR
@@ -4908,6 +4910,9 @@ alter_commands:
| IMPORT TABLESPACE { Lex->alter_info.tablespace_op= IMPORT_TABLESPACE; }
| alter_list
opt_partitioning
+ | alter_list
+ remove_partitioning
+ | remove_partitioning
| partitioning
/*
This part was added for release 5.1 by Mikael Ronström.
@@ -4973,6 +4978,13 @@ alter_commands:
| reorg_partition_rule
;
+remove_partitioning:
+ REMOVE_SYM PARTITIONING_SYM
+ {
+ Lex->alter_info.flags|= ALTER_REMOVE_PARTITIONING;
+ }
+ ;
+
all_or_alt_part_name_list:
ALL
{
@@ -7809,7 +7821,19 @@ replace:
;
insert_lock_option:
- /* empty */ { $$= TL_WRITE_CONCURRENT_INSERT; }
+ /* empty */
+ {
+#ifdef HAVE_QUERY_CACHE
+ /*
+ If it is SP we do not allow insert optimisation whan result of
+ insert visible only after the table unlocking but everyone can
+ read table.
+ */
+ $$= (Lex->sphead ? TL_WRITE :TL_WRITE_CONCURRENT_INSERT);
+#else
+ $$= TL_WRITE_CONCURRENT_INSERT;
+#endif
+ }
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
| DELAYED_SYM { $$= TL_WRITE_DELAYED; }
| HIGH_PRIORITY { $$= TL_WRITE; }
@@ -8728,7 +8752,16 @@ opt_local:
load_data_lock:
/* empty */ { $$= YYTHD->update_lock_default; }
- | CONCURRENT { $$= TL_WRITE_CONCURRENT_INSERT ; }
+ | CONCURRENT
+ {
+#ifdef HAVE_QUERY_CACHE
+ /*
+ Ignore this option in SP to avoid problem with query cache
+ */
+ if (Lex->sphead != 0)
+#endif
+ $$= TL_WRITE_CONCURRENT_INSERT;
+ }
| LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; };
@@ -9326,6 +9359,7 @@ keyword:
| PARTITION_SYM {}
| PLUGIN_SYM {}
| PREPARE_SYM {}
+ | REMOVE_SYM {}
| REPAIR {}
| RESET_SYM {}
| RESTORE_SYM {}
@@ -9500,6 +9534,7 @@ keyword_sp:
| ONE_SYM {}
| PACK_KEYS_SYM {}
| PARTIAL {}
+ | PARTITIONING_SYM {}
| PARTITIONS_SYM {}
| PASSWORD {}
| PHASE_SYM {}
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index 6d8eb9faba1..130ae44c057 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -3829,6 +3829,9 @@ NdbDictionaryImpl::dropBlobEvents(const NdbEventImpl& evnt)
} else {
// loop over MAX_ATTRIBUTES_IN_TABLE ...
Uint32 i;
+ DBUG_PRINT("info", ("missing table definition, looping over "
+ "MAX_ATTRIBUTES_IN_TABLE(%d)",
+ MAX_ATTRIBUTES_IN_TABLE));
for (i = 0; i < MAX_ATTRIBUTES_IN_TABLE; i++) {
char bename[MAX_TAB_NAME_SIZE];
// XXX should get name from NdbBlob
diff --git a/vio/viosocket.c b/vio/viosocket.c
index 5e0ed20b039..710f7a93607 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -560,14 +560,20 @@ int vio_close_shared_memory(Vio * vio)
Close all handlers. UnmapViewOfFile and CloseHandle return non-zero
result if they are success.
*/
- r= UnmapViewOfFile(vio->handle_map) || CloseHandle(vio->event_server_wrote) ||
- CloseHandle(vio->event_server_read) || CloseHandle(vio->event_client_wrote) ||
- CloseHandle(vio->event_client_read) || CloseHandle(vio->handle_file_map);
- if (!r)
- {
- DBUG_PRINT("vio_error", ("close() failed, error: %d",r));
- /* FIXME: error handling (not critical for MySQL) */
- }
+ if (UnmapViewOfFile(vio->handle_map) == 0)
+ DBUG_PRINT("vio_error", ("UnmapViewOfFile() failed"));
+ if (CloseHandle(vio->event_server_wrote) == 0)
+ DBUG_PRINT("vio_error", ("CloseHandle(vio->esw) failed"));
+ if (CloseHandle(vio->event_server_read) == 0)
+ DBUG_PRINT("vio_error", ("CloseHandle(vio->esr) failed"));
+ if (CloseHandle(vio->event_client_wrote) == 0)
+ DBUG_PRINT("vio_error", ("CloseHandle(vio->ecw) failed"));
+ if (CloseHandle(vio->event_client_read) == 0)
+ DBUG_PRINT("vio_error", ("CloseHandle(vio->ecr) failed"));
+ if (CloseHandle(vio->handle_file_map) == 0)
+ DBUG_PRINT("vio_error", ("CloseHandle(vio->hfm) failed"));
+ if (CloseHandle(vio->event_conn_closed) == 0)
+ DBUG_PRINT("vio_error", ("CloseHandle(vio->ecc) failed"));
}
vio->type= VIO_CLOSED;
vio->sd= -1;