mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
Manual merge from mysql-trunk.
This commit is contained in:
commit
e7e1a36755
37 changed files with 663 additions and 141 deletions
|
@ -1,4 +1,4 @@
|
|||
[MYSQL]
|
||||
post_commit_to = "commits@lists.mysql.com"
|
||||
post_push_to = "commits@lists.mysql.com"
|
||||
tree_name = "mysql-5.5-trunk"
|
||||
tree_name = "mysql-trunk"
|
||||
|
|
|
@ -12,7 +12,7 @@ dnl
|
|||
dnl Remember to also update version.c in ndb.
|
||||
dnl When changing major version number please also check switch statement
|
||||
dnl in client/mysqlbinlog.cc:check_master_version().
|
||||
AC_INIT([MySQL Server], [5.5.2-m2], [], [mysql])
|
||||
AC_INIT([MySQL Server], [5.5.3-m2], [], [mysql])
|
||||
AC_CONFIG_SRCDIR([sql/mysqld.cc])
|
||||
AC_CANONICAL_SYSTEM
|
||||
# USTAR format gives us the possibility to store longer path names in
|
||||
|
|
|
@ -66,8 +66,9 @@ typedef struct st_mysql_xid MYSQL_XID;
|
|||
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
|
||||
#define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */
|
||||
#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */
|
||||
#define MYSQL_REPLICATION_PLUGIN 5 /* The replication plugin type */
|
||||
#define MYSQL_MAX_PLUGIN_TYPE_NUM 6 /* The number of plugin types */
|
||||
#define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */
|
||||
#define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */
|
||||
#define MYSQL_MAX_PLUGIN_TYPE_NUM 7 /* The number of plugin types */
|
||||
|
||||
/* We use the following strings to define licenses for plugins */
|
||||
#define PLUGIN_LICENSE_PROPRIETARY 0
|
||||
|
|
|
@ -1354,3 +1354,15 @@ DROP i,
|
|||
ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
AUTO_INCREMENT = 1;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a CHAR(1), PRIMARY KEY (a(255)));
|
||||
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
|
||||
CREATE TABLE t1 (a CHAR(1));
|
||||
ALTER TABLE t1 ADD PRIMARY KEY (a(20));
|
||||
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
|
||||
ALTER TABLE t1 ADD KEY (a(20));
|
||||
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
|
||||
CREATE UNIQUE INDEX i1 ON t1 (a(20));
|
||||
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
|
||||
CREATE INDEX i2 ON t1 (a(20));
|
||||
ERROR HY000: Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -1058,3 +1058,33 @@ SELECT Polygon(12345123,'');
|
|||
Polygon(12345123,'')
|
||||
NULL
|
||||
End of 5.1 tests
|
||||
CREATE TABLE t1(
|
||||
col0 BINARY NOT NULL,
|
||||
col2 TIMESTAMP,
|
||||
SPATIAL INDEX i1 (col0)
|
||||
) ENGINE=MyISAM;
|
||||
ERROR 42000: A SPATIAL index may only contain a geometrical type column
|
||||
CREATE TABLE t1 (
|
||||
col0 BINARY NOT NULL,
|
||||
col2 TIMESTAMP
|
||||
) ENGINE=MyISAM;
|
||||
CREATE SPATIAL INDEX idx0 ON t1(col0);
|
||||
ERROR 42000: A SPATIAL index may only contain a geometrical type column
|
||||
ALTER TABLE t1 ADD SPATIAL INDEX i1 (col0);
|
||||
ERROR 42000: A SPATIAL index may only contain a geometrical type column
|
||||
CREATE TABLE t2 (
|
||||
col0 INTEGER NOT NULL,
|
||||
col1 POINT,
|
||||
col2 POINT
|
||||
);
|
||||
CREATE SPATIAL INDEX idx0 ON t2 (col1, col2);
|
||||
ERROR HY000: Incorrect arguments to SPATIAL INDEX
|
||||
CREATE TABLE t3 (
|
||||
col0 INTEGER NOT NULL,
|
||||
col1 POINT,
|
||||
col2 LINESTRING,
|
||||
SPATIAL INDEX i1 (col1, col2)
|
||||
);
|
||||
ERROR HY000: Incorrect arguments to SPATIAL INDEX
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
|
|
@ -2699,7 +2699,7 @@ a c COUNT(DISTINCT c, a, b)
|
|||
1 1 1
|
||||
1 1 1
|
||||
1 1 1
|
||||
2 1 1
|
||||
1 1 1
|
||||
2 1 1
|
||||
2 1 1
|
||||
2 1 1
|
||||
|
@ -2727,7 +2727,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE t2 range NULL a 10 NULL 9 Using index for group-by
|
||||
SELECT a, COUNT(DISTINCT b), SUM(DISTINCT b) FROM t2 GROUP BY a;
|
||||
a COUNT(DISTINCT b) SUM(DISTINCT b)
|
||||
2 8 36
|
||||
1 8 36
|
||||
2 8 36
|
||||
EXPLAIN SELECT COUNT(DISTINCT b), SUM(DISTINCT b) FROM t2 GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
@ -2774,7 +2774,7 @@ SELECT 42 * (a + c + COUNT(DISTINCT c, a, b)) FROM t2 GROUP BY a, b, c;
|
|||
126
|
||||
126
|
||||
126
|
||||
168
|
||||
126
|
||||
168
|
||||
168
|
||||
168
|
||||
|
@ -2792,3 +2792,24 @@ SELECT (SUM(DISTINCT a) + MAX(b)) FROM t2 GROUP BY a;
|
|||
10
|
||||
DROP TABLE t1,t2;
|
||||
# end of WL#3220 tests
|
||||
#
|
||||
# Bug#50539: Wrong result when loose index scan is used for an aggregate
|
||||
# function with distinct
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
f1 int(11) NOT NULL DEFAULT '0',
|
||||
f2 char(1) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (f1,f2)
|
||||
) ;
|
||||
insert into t1 values(1,'A'),(1 , 'B'), (1, 'C'), (2, 'A'),
|
||||
(3, 'A'), (3, 'B'), (3, 'C'), (3, 'D');
|
||||
SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1;
|
||||
f1 COUNT(DISTINCT f2)
|
||||
1 3
|
||||
2 1
|
||||
3 4
|
||||
explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range NULL PRIMARY 5 NULL 9 Using index for group-by (scanning)
|
||||
drop table t1;
|
||||
# End of test#50539.
|
||||
|
|
14
mysql-test/suite/parts/r/partition_innodb_status_file.result
Normal file
14
mysql-test/suite/parts/r/partition_innodb_status_file.result
Normal file
|
@ -0,0 +1,14 @@
|
|||
CREATE TABLE t1 (a INT) ENGINE = InnoDB PARTITION BY HASH(a);
|
||||
INSERT INTO t1 VALUES (0), (1), (2);
|
||||
START TRANSACTION;
|
||||
UPDATE t1 SET a = 5 WHERE a = 1;
|
||||
# Connection con1
|
||||
# InnoDB lock timeout and monitor thread runs every 15 seconds
|
||||
SET innodb_lock_wait_timeout = 20;
|
||||
START TRANSACTION;
|
||||
UPDATE t1 SET a = 3 WHERE a = 1;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
COMMIT;
|
||||
# Connection default
|
||||
COMMIT;
|
||||
DROP TABLE t1;
|
|
@ -0,0 +1 @@
|
|||
--innodb-status-file=1
|
20
mysql-test/suite/parts/t/partition_innodb_status_file.test
Normal file
20
mysql-test/suite/parts/t/partition_innodb_status_file.test
Normal file
|
@ -0,0 +1,20 @@
|
|||
--source include/have_innodb.inc
|
||||
--source include/have_partition.inc
|
||||
|
||||
CREATE TABLE t1 (a INT) ENGINE = InnoDB PARTITION BY HASH(a);
|
||||
INSERT INTO t1 VALUES (0), (1), (2);
|
||||
START TRANSACTION;
|
||||
UPDATE t1 SET a = 5 WHERE a = 1;
|
||||
connect (con1, localhost, root,,);
|
||||
--echo # Connection con1
|
||||
--echo # InnoDB lock timeout and monitor thread runs every 15 seconds
|
||||
SET innodb_lock_wait_timeout = 20;
|
||||
START TRANSACTION;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
UPDATE t1 SET a = 3 WHERE a = 1;
|
||||
COMMIT;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
--echo # Connection default
|
||||
COMMIT;
|
||||
DROP TABLE t1;
|
|
@ -89,6 +89,7 @@ show grants for rpl_do_grant2@localhost;
|
|||
ERROR 42000: There is no such grant defined for user 'rpl_do_grant2' on host 'localhost'
|
||||
show grants for rpl_do_grant2@localhost;
|
||||
ERROR 42000: There is no such grant defined for user 'rpl_do_grant2' on host 'localhost'
|
||||
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
|
||||
DROP DATABASE IF EXISTS bug42217_db;
|
||||
CREATE DATABASE bug42217_db;
|
||||
GRANT CREATE ROUTINE ON bug42217_db.* TO 'create_rout_db'@'localhost'
|
||||
|
@ -166,9 +167,12 @@ DROP FUNCTION upgrade_del_func;
|
|||
DROP FUNCTION upgrade_alter_func;
|
||||
DROP DATABASE bug42217_db;
|
||||
DROP USER 'create_rout_db'@'localhost';
|
||||
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
|
||||
USE mtr;
|
||||
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
######## BUG#49119 #######
|
||||
### i) test case from the 'how to repeat section'
|
||||
stop slave;
|
||||
|
|
|
@ -120,8 +120,27 @@ min(a)
|
|||
select max(a) from t1;
|
||||
max(a)
|
||||
300
|
||||
|
||||
# BUG#50157
|
||||
# semi-sync replication crashes when replicating a transaction which
|
||||
# include 'CREATE TEMPORARY TABLE `MyISAM_t` SELECT * FROM `Innodb_t` ;
|
||||
[ on master ]
|
||||
SET SESSION AUTOCOMMIT= 0;
|
||||
CREATE TABLE t2(c1 INT) ENGINE=innodb;
|
||||
BEGIN;
|
||||
|
||||
# Even though it is in a transaction, this statement is binlogged into binlog
|
||||
# file immediately.
|
||||
CREATE TEMPORARY TABLE t3 SELECT c1 FROM t2 where 1=1;
|
||||
|
||||
# These statements will not be binlogged until the transaction is committed
|
||||
INSERT INTO t2 VALUES(11);
|
||||
INSERT INTO t2 VALUES(22);
|
||||
COMMIT;
|
||||
DROP TABLE t2, t3;
|
||||
SET SESSION AUTOCOMMIT= 1;
|
||||
#
|
||||
# Test semi-sync master will switch OFF after one transacton
|
||||
# Test semi-sync master will switch OFF after one transaction
|
||||
# timeout waiting for slave reply.
|
||||
#
|
||||
include/stop_slave.inc
|
||||
|
@ -135,7 +154,7 @@ Variable_name Value
|
|||
Rpl_semi_sync_master_no_tx 0
|
||||
show status like 'Rpl_semi_sync_master_yes_tx';
|
||||
Variable_name Value
|
||||
Rpl_semi_sync_master_yes_tx 301
|
||||
Rpl_semi_sync_master_yes_tx 304
|
||||
show status like 'Rpl_semi_sync_master_clients';
|
||||
Variable_name Value
|
||||
Rpl_semi_sync_master_clients 1
|
||||
|
@ -150,7 +169,7 @@ Variable_name Value
|
|||
Rpl_semi_sync_master_no_tx 1
|
||||
show status like 'Rpl_semi_sync_master_yes_tx';
|
||||
Variable_name Value
|
||||
Rpl_semi_sync_master_yes_tx 301
|
||||
Rpl_semi_sync_master_yes_tx 304
|
||||
insert into t1 values (100);
|
||||
[ master status should be OFF ]
|
||||
show status like 'Rpl_semi_sync_master_status';
|
||||
|
@ -161,7 +180,7 @@ Variable_name Value
|
|||
Rpl_semi_sync_master_no_tx 302
|
||||
show status like 'Rpl_semi_sync_master_yes_tx';
|
||||
Variable_name Value
|
||||
Rpl_semi_sync_master_yes_tx 301
|
||||
Rpl_semi_sync_master_yes_tx 304
|
||||
#
|
||||
# Test semi-sync status on master will be ON again when slave catches up
|
||||
#
|
||||
|
@ -194,7 +213,7 @@ Variable_name Value
|
|||
Rpl_semi_sync_master_no_tx 302
|
||||
show status like 'Rpl_semi_sync_master_yes_tx';
|
||||
Variable_name Value
|
||||
Rpl_semi_sync_master_yes_tx 301
|
||||
Rpl_semi_sync_master_yes_tx 304
|
||||
show status like 'Rpl_semi_sync_master_clients';
|
||||
Variable_name Value
|
||||
Rpl_semi_sync_master_clients 1
|
||||
|
@ -213,7 +232,7 @@ Variable_name Value
|
|||
Rpl_semi_sync_master_no_tx 302
|
||||
SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx';
|
||||
Variable_name Value
|
||||
Rpl_semi_sync_master_yes_tx 302
|
||||
Rpl_semi_sync_master_yes_tx 305
|
||||
FLUSH NO_WRITE_TO_BINLOG STATUS;
|
||||
[ Semi-sync master status variables after FLUSH STATUS ]
|
||||
SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx';
|
||||
|
|
|
@ -12,5 +12,4 @@
|
|||
|
||||
rpl_get_master_version_and_clock: # Bug#46931 2009-10-17 joro rpl.rpl_get_master_version_and_clock fails
|
||||
rpl_row_create_table : Bug#45576 2009-12-01 joro rpl_row_create_table fails on PB2
|
||||
rpl_cross_version : BUG#43913 2009-10-22 luis rpl_cross_version fails with symptom in described in bug report
|
||||
rpl_spec_variables : BUG#47661 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux
|
||||
|
|
|
@ -1 +1 @@
|
|||
--replicate-same-server-id --relay-log=slave-relay-bin --secure-file-priv=$MYSQL_TMP_DIR
|
||||
--replicate-same-server-id --relay-log=slave-relay-bin
|
||||
|
|
|
@ -120,6 +120,9 @@ show grants for rpl_do_grant2@localhost;
|
|||
# BUG42217 mysql.procs_priv does not get replicated
|
||||
#####################################################
|
||||
connection master;
|
||||
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS bug42217_db;
|
||||
|
@ -209,12 +212,19 @@ USE bug42217_db;
|
|||
DROP FUNCTION upgrade_del_func;
|
||||
DROP FUNCTION upgrade_alter_func;
|
||||
DROP DATABASE bug42217_db;
|
||||
-- sync_slave_with_master
|
||||
-- connection master
|
||||
|
||||
# user was already dropped in the slave before
|
||||
# so no need to wait for the slave to replicate
|
||||
# this statement (if it did and we later synced
|
||||
# the slave it would end up in an error anyway)
|
||||
DROP USER 'create_rout_db'@'localhost';
|
||||
|
||||
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
|
||||
connection slave;
|
||||
USE mtr;
|
||||
call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396");
|
||||
# finish entire clean up (remove binlogs)
|
||||
# so that we leave a pristine environment for the
|
||||
# following tests
|
||||
-- source include/master-slave-reset.inc
|
||||
|
||||
# BUG#49119: Master crashes when executing 'REVOKE ... ON
|
||||
# {PROCEDURE|FUNCTION} FROM ...'
|
||||
|
|
|
@ -382,7 +382,7 @@ let $slave_param_comparison= =;
|
|||
let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1);
|
||||
# Flush logs every 0.1 second during 5 sec
|
||||
--disable_query_log
|
||||
let $i=50;
|
||||
let $i=100;
|
||||
while ($i) {
|
||||
FLUSH LOGS;
|
||||
dec $i;
|
||||
|
|
|
@ -11,6 +11,7 @@ disable_query_log;
|
|||
connection master;
|
||||
call mtr.add_suppression("Timeout waiting for reply of binlog");
|
||||
call mtr.add_suppression("Read semi-sync reply");
|
||||
call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT.");
|
||||
connection slave;
|
||||
call mtr.add_suppression("Master server does not support semi-sync");
|
||||
call mtr.add_suppression("Semi-sync slave .* reply");
|
||||
|
@ -193,8 +194,38 @@ select count(distinct a) from t1;
|
|||
select min(a) from t1;
|
||||
select max(a) from t1;
|
||||
|
||||
--echo
|
||||
--echo # BUG#50157
|
||||
--echo # semi-sync replication crashes when replicating a transaction which
|
||||
--echo # include 'CREATE TEMPORARY TABLE `MyISAM_t` SELECT * FROM `Innodb_t` ;
|
||||
|
||||
connection master;
|
||||
echo [ on master ];
|
||||
SET SESSION AUTOCOMMIT= 0;
|
||||
CREATE TABLE t2(c1 INT) ENGINE=innodb;
|
||||
sync_slave_with_master;
|
||||
|
||||
connection master;
|
||||
BEGIN;
|
||||
--echo
|
||||
--echo # Even though it is in a transaction, this statement is binlogged into binlog
|
||||
--echo # file immediately.
|
||||
--disable_warnings
|
||||
CREATE TEMPORARY TABLE t3 SELECT c1 FROM t2 where 1=1;
|
||||
--enable_warnings
|
||||
--echo
|
||||
--echo # These statements will not be binlogged until the transaction is committed
|
||||
INSERT INTO t2 VALUES(11);
|
||||
INSERT INTO t2 VALUES(22);
|
||||
COMMIT;
|
||||
|
||||
DROP TABLE t2, t3;
|
||||
SET SESSION AUTOCOMMIT= 1;
|
||||
sync_slave_with_master;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Test semi-sync master will switch OFF after one transacton
|
||||
--echo # Test semi-sync master will switch OFF after one transaction
|
||||
--echo # timeout waiting for slave reply.
|
||||
--echo #
|
||||
connection slave;
|
||||
|
|
|
@ -10,4 +10,5 @@ source include/have_binlog_format_row.inc;
|
|||
|
||||
LET $ENGINE_TYPE= MyISAM;
|
||||
source extra/rpl_tests/rpl_tmp_table_and_DDL.test;
|
||||
sync_slave_with_master;
|
||||
|
||||
|
|
|
@ -1089,3 +1089,31 @@ ALTER TABLE t1
|
|||
ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
AUTO_INCREMENT = 1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
#
|
||||
# Bug#50542 5.5.x doesn't check length of key prefixes:
|
||||
# corruption and crash results
|
||||
#
|
||||
# This case is related to Bug#31031 (above)
|
||||
# A statement where the index key is larger/wider than
|
||||
# the column type, should cause an error
|
||||
#
|
||||
--error ER_WRONG_SUB_KEY
|
||||
CREATE TABLE t1 (a CHAR(1), PRIMARY KEY (a(255)));
|
||||
|
||||
# Test other variants of creating indices
|
||||
CREATE TABLE t1 (a CHAR(1));
|
||||
# ALTER TABLE
|
||||
--error ER_WRONG_SUB_KEY
|
||||
ALTER TABLE t1 ADD PRIMARY KEY (a(20));
|
||||
--error ER_WRONG_SUB_KEY
|
||||
ALTER TABLE t1 ADD KEY (a(20));
|
||||
# CREATE INDEX
|
||||
--error ER_WRONG_SUB_KEY
|
||||
CREATE UNIQUE INDEX i1 ON t1 (a(20));
|
||||
--error ER_WRONG_SUB_KEY
|
||||
CREATE INDEX i2 ON t1 (a(20));
|
||||
# cleanup
|
||||
DROP TABLE t1;
|
||||
|
||||
|
|
|
@ -723,3 +723,48 @@ SELECT Polygon(1234512,'');
|
|||
SELECT Polygon(12345123,'');
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
||||
#
|
||||
# Bug #50574 5.5.x allows spatial indexes on non-spatial
|
||||
# columns, causing crashes!
|
||||
#
|
||||
--error ER_SPATIAL_MUST_HAVE_GEOM_COL
|
||||
CREATE TABLE t1(
|
||||
col0 BINARY NOT NULL,
|
||||
col2 TIMESTAMP,
|
||||
SPATIAL INDEX i1 (col0)
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
# Test other ways to add indices
|
||||
CREATE TABLE t1 (
|
||||
col0 BINARY NOT NULL,
|
||||
col2 TIMESTAMP
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
--error ER_SPATIAL_MUST_HAVE_GEOM_COL
|
||||
CREATE SPATIAL INDEX idx0 ON t1(col0);
|
||||
|
||||
--error ER_SPATIAL_MUST_HAVE_GEOM_COL
|
||||
ALTER TABLE t1 ADD SPATIAL INDEX i1 (col0);
|
||||
|
||||
CREATE TABLE t2 (
|
||||
col0 INTEGER NOT NULL,
|
||||
col1 POINT,
|
||||
col2 POINT
|
||||
);
|
||||
|
||||
--error ER_WRONG_ARGUMENTS
|
||||
CREATE SPATIAL INDEX idx0 ON t2 (col1, col2);
|
||||
|
||||
--error ER_WRONG_ARGUMENTS
|
||||
CREATE TABLE t3 (
|
||||
col0 INTEGER NOT NULL,
|
||||
col1 POINT,
|
||||
col2 LINESTRING,
|
||||
SPATIAL INDEX i1 (col1, col2)
|
||||
);
|
||||
|
||||
# cleanup
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
||||
|
|
|
@ -1176,3 +1176,22 @@ SELECT (SUM(DISTINCT a) + MAX(b)) FROM t2 GROUP BY a;
|
|||
DROP TABLE t1,t2;
|
||||
|
||||
--echo # end of WL#3220 tests
|
||||
|
||||
--echo #
|
||||
--echo # Bug#50539: Wrong result when loose index scan is used for an aggregate
|
||||
--echo # function with distinct
|
||||
--echo #
|
||||
CREATE TABLE t1 (
|
||||
f1 int(11) NOT NULL DEFAULT '0',
|
||||
f2 char(1) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (f1,f2)
|
||||
) ;
|
||||
insert into t1 values(1,'A'),(1 , 'B'), (1, 'C'), (2, 'A'),
|
||||
(3, 'A'), (3, 'B'), (3, 'C'), (3, 'D');
|
||||
|
||||
SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1;
|
||||
explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1;
|
||||
|
||||
drop table t1;
|
||||
--echo # End of test#50539.
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ static int gettimeofday(struct timeval *tv, void *tz)
|
|||
|
||||
ActiveTranx::ActiveTranx(pthread_mutex_t *lock,
|
||||
unsigned long trace_level)
|
||||
: Trace(trace_level),
|
||||
: Trace(trace_level), allocator_(max_connections),
|
||||
num_entries_(max_connections << 1), /* Transaction hash table size
|
||||
* is set to double the size
|
||||
* of max_connections */
|
||||
|
@ -115,25 +115,6 @@ unsigned int ActiveTranx::get_hash_value(const char *log_file_name,
|
|||
return (hash1 + hash2) % num_entries_;
|
||||
}
|
||||
|
||||
ActiveTranx::TranxNode* ActiveTranx::alloc_tranx_node()
|
||||
{
|
||||
MYSQL_THD thd= (MYSQL_THD)current_thd;
|
||||
/* The memory allocated for TranxNode will be automatically freed at
|
||||
the end of the command of current THD. And because
|
||||
ha_autocommit_or_rollback() will always be called before that, so
|
||||
we are sure that the node will be removed from the active list
|
||||
before it get freed. */
|
||||
TranxNode *trx_node = (TranxNode *)thd_alloc(thd, sizeof(TranxNode));
|
||||
if (trx_node)
|
||||
{
|
||||
trx_node->log_name_[0] = '\0';
|
||||
trx_node->log_pos_= 0;
|
||||
trx_node->next_= 0;
|
||||
trx_node->hash_next_= 0;
|
||||
}
|
||||
return trx_node;
|
||||
}
|
||||
|
||||
int ActiveTranx::compare(const char *log_file_name1, my_off_t log_file_pos1,
|
||||
const char *log_file_name2, my_off_t log_file_pos2)
|
||||
{
|
||||
|
@ -159,7 +140,7 @@ int ActiveTranx::insert_tranx_node(const char *log_file_name,
|
|||
|
||||
function_enter(kWho);
|
||||
|
||||
ins_node = alloc_tranx_node();
|
||||
ins_node = allocator_.allocate_node();
|
||||
if (!ins_node)
|
||||
{
|
||||
sql_print_error("%s: transaction node allocation failed for: (%s, %lu)",
|
||||
|
@ -271,6 +252,7 @@ int ActiveTranx::clear_active_tranx_nodes(const char *log_file_name,
|
|||
|
||||
/* Clear the hash table. */
|
||||
memset(trx_htb_, 0, num_entries_ * sizeof(TranxNode *));
|
||||
allocator_.free_all_nodes();
|
||||
|
||||
/* Clear the active transaction list. */
|
||||
if (trx_front_ != NULL)
|
||||
|
@ -311,6 +293,7 @@ int ActiveTranx::clear_active_tranx_nodes(const char *log_file_name,
|
|||
}
|
||||
|
||||
trx_front_ = new_front;
|
||||
allocator_.free_nodes_before(trx_front_);
|
||||
|
||||
if (trace_level_ & kTraceDetail)
|
||||
sql_print_information("%s: cleared %d nodes back until pos (%s, %lu)",
|
||||
|
|
|
@ -20,6 +20,267 @@
|
|||
|
||||
#include "semisync.h"
|
||||
|
||||
struct TranxNode {
|
||||
char log_name_[FN_REFLEN];
|
||||
my_off_t log_pos_;
|
||||
struct TranxNode *next_; /* the next node in the sorted list */
|
||||
struct TranxNode *hash_next_; /* the next node during hash collision */
|
||||
};
|
||||
|
||||
/**
|
||||
@class TranxNodeAllocator
|
||||
|
||||
This class provides memory allocating and freeing methods for
|
||||
TranxNode. The main target is performance.
|
||||
|
||||
@section ALLOCATE How to allocate a node
|
||||
The pointer of the first node after 'last_node' in current_block is
|
||||
returned. current_block will move to the next free Block when all nodes of
|
||||
it are in use. A new Block is allocated and is put into the rear of the
|
||||
Block link table if no Block is free.
|
||||
|
||||
The list starts up empty (ie, there is no allocated Block).
|
||||
|
||||
After some nodes are freed, there probably are some free nodes before
|
||||
the sequence of the allocated nodes, but we do not reuse it. It is better
|
||||
to keep the allocated nodes are in the sequence, for it is more efficient
|
||||
for allocating and freeing TranxNode.
|
||||
|
||||
@section FREENODE How to free nodes
|
||||
There are two methods for freeing nodes. They are free_all_nodes and
|
||||
free_nodes_before.
|
||||
|
||||
'A Block is free' means all of its nodes are free.
|
||||
@subsection free_nodes_before
|
||||
As all allocated nodes are in the sequence, 'Before one node' means all
|
||||
nodes before given node in the same Block and all Blocks before the Block
|
||||
which containing the given node. As such, all Blocks before the given one
|
||||
('node') are free Block and moved into the rear of the Block link table.
|
||||
The Block containing the given 'node', however, is not. For at least the
|
||||
given 'node' is still in use. This will waste at most one Block, but it is
|
||||
more efficient.
|
||||
*/
|
||||
#define BLOCK_TRANX_NODES 16
|
||||
class TranxNodeAllocator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@param reserved_nodes
|
||||
The number of reserved TranxNodes. It is used to set 'reserved_blocks'
|
||||
which can contain at least 'reserved_nodes' number of TranxNodes. When
|
||||
freeing memory, we will reserve at least reserved_blocks of Blocks not
|
||||
freed.
|
||||
*/
|
||||
TranxNodeAllocator(uint reserved_nodes) :
|
||||
reserved_blocks(reserved_nodes/BLOCK_TRANX_NODES +
|
||||
(reserved_nodes%BLOCK_TRANX_NODES > 1 ? 2 : 1)),
|
||||
first_block(NULL), last_block(NULL),
|
||||
current_block(NULL), last_node(-1), block_num(0) {}
|
||||
|
||||
~TranxNodeAllocator()
|
||||
{
|
||||
Block *block= first_block;
|
||||
while (block != NULL)
|
||||
{
|
||||
Block *next= block->next;
|
||||
free_block(block);
|
||||
block= next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
The pointer of the first node after 'last_node' in current_block is
|
||||
returned. current_block will move to the next free Block when all nodes of
|
||||
it are in use. A new Block is allocated and is put into the rear of the
|
||||
Block link table if no Block is free.
|
||||
|
||||
@return Return a TranxNode *, or NULL if an error occured.
|
||||
*/
|
||||
TranxNode *allocate_node()
|
||||
{
|
||||
TranxNode *trx_node;
|
||||
Block *block= current_block;
|
||||
|
||||
if (last_node == BLOCK_TRANX_NODES-1)
|
||||
{
|
||||
current_block= current_block->next;
|
||||
last_node= -1;
|
||||
}
|
||||
|
||||
if (current_block == NULL && allocate_block())
|
||||
{
|
||||
current_block= block;
|
||||
if (current_block)
|
||||
last_node= BLOCK_TRANX_NODES-1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
trx_node= &(current_block->nodes[++last_node]);
|
||||
trx_node->log_name_[0] = '\0';
|
||||
trx_node->log_pos_= 0;
|
||||
trx_node->next_= 0;
|
||||
trx_node->hash_next_= 0;
|
||||
return trx_node;
|
||||
}
|
||||
|
||||
/**
|
||||
All nodes are freed.
|
||||
|
||||
@return Return 0, or 1 if an error occured.
|
||||
*/
|
||||
int free_all_nodes()
|
||||
{
|
||||
current_block= first_block;
|
||||
last_node= -1;
|
||||
free_blocks();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
All Blocks before the given 'node' are free Block and moved into the rear
|
||||
of the Block link table.
|
||||
|
||||
@param node All nodes before 'node' will be freed
|
||||
|
||||
@return Return 0, or 1 if an error occured.
|
||||
*/
|
||||
int free_nodes_before(TranxNode* node)
|
||||
{
|
||||
Block *block;
|
||||
Block *prev_block;
|
||||
|
||||
block= first_block;
|
||||
while (block != current_block->next)
|
||||
{
|
||||
/* Find the Block containing the given node */
|
||||
if (&(block->nodes[0]) <= node && &(block->nodes[BLOCK_TRANX_NODES]) >= node)
|
||||
{
|
||||
/* All Blocks before the given node are put into the rear */
|
||||
if (first_block != block)
|
||||
{
|
||||
last_block->next= first_block;
|
||||
first_block= block;
|
||||
last_block= prev_block;
|
||||
last_block->next= NULL;
|
||||
free_blocks();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
prev_block= block;
|
||||
block= block->next;
|
||||
}
|
||||
|
||||
/* Node does not find should never happen */
|
||||
DBUG_ASSERT(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
private:
|
||||
uint reserved_blocks;
|
||||
|
||||
/**
|
||||
A sequence memory which contains BLOCK_TRANX_NODES TranxNodes.
|
||||
|
||||
BLOCK_TRANX_NODES The number of TranxNodes which are in a Block.
|
||||
|
||||
next Every Block has a 'next' pointer which points to the next Block.
|
||||
These linking Blocks constitute a Block link table.
|
||||
*/
|
||||
struct Block {
|
||||
Block *next;
|
||||
TranxNode nodes[BLOCK_TRANX_NODES];
|
||||
};
|
||||
|
||||
/**
|
||||
The 'first_block' is the head of the Block link table;
|
||||
*/
|
||||
Block *first_block;
|
||||
/**
|
||||
The 'last_block' is the rear of the Block link table;
|
||||
*/
|
||||
Block *last_block;
|
||||
|
||||
/**
|
||||
current_block always points the Block in the Block link table in
|
||||
which the last allocated node is. The Blocks before it are all in use
|
||||
and the Blocks after it are all free.
|
||||
*/
|
||||
Block *current_block;
|
||||
|
||||
/**
|
||||
It always points to the last node which has been allocated in the
|
||||
current_block.
|
||||
*/
|
||||
int last_node;
|
||||
|
||||
/**
|
||||
How many Blocks are in the Block link table.
|
||||
*/
|
||||
uint block_num;
|
||||
|
||||
/**
|
||||
Allocate a block and then assign it to current_block.
|
||||
*/
|
||||
int allocate_block()
|
||||
{
|
||||
Block *block= (Block *)my_malloc(sizeof(Block), MYF(0));
|
||||
if (block)
|
||||
{
|
||||
block->next= NULL;
|
||||
|
||||
if (first_block == NULL)
|
||||
first_block= block;
|
||||
else
|
||||
last_block->next= block;
|
||||
|
||||
/* New Block is always put into the rear */
|
||||
last_block= block;
|
||||
/* New Block is always the current_block */
|
||||
current_block= block;
|
||||
++block_num;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Free a given Block.
|
||||
@param block The Block will be freed.
|
||||
*/
|
||||
void free_block(Block *block)
|
||||
{
|
||||
my_free(block, MYF(0));
|
||||
--block_num;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
If there are some free Blocks and the total number of the Blocks in the
|
||||
Block link table is larger than the 'reserved_blocks', Some free Blocks
|
||||
will be freed until the total number of the Blocks is equal to the
|
||||
'reserved_blocks' or there is only one free Block behind the
|
||||
'current_block'.
|
||||
*/
|
||||
void free_blocks()
|
||||
{
|
||||
if (current_block == NULL || current_block->next == NULL)
|
||||
return;
|
||||
|
||||
/* One free Block is always kept behind the current block */
|
||||
Block *block= current_block->next->next;
|
||||
while (block_num > reserved_blocks && block != NULL)
|
||||
{
|
||||
Block *next= block->next;
|
||||
free_block(block);
|
||||
block= next;
|
||||
}
|
||||
current_block->next->next= block;
|
||||
if (block == NULL)
|
||||
last_block= current_block->next;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This class manages memory for active transaction list.
|
||||
|
||||
|
@ -31,13 +292,8 @@
|
|||
class ActiveTranx
|
||||
:public Trace {
|
||||
private:
|
||||
struct TranxNode {
|
||||
char log_name_[FN_REFLEN];
|
||||
my_off_t log_pos_;
|
||||
struct TranxNode *next_; /* the next node in the sorted list */
|
||||
struct TranxNode *hash_next_; /* the next node during hash collision */
|
||||
};
|
||||
|
||||
TranxNodeAllocator allocator_;
|
||||
/* These two record the active transaction list in sort order. */
|
||||
TranxNode *trx_front_, *trx_rear_;
|
||||
|
||||
|
@ -48,24 +304,22 @@ private:
|
|||
|
||||
inline void assert_lock_owner();
|
||||
|
||||
inline TranxNode* alloc_tranx_node();
|
||||
|
||||
inline unsigned int calc_hash(const unsigned char *key,unsigned int length);
|
||||
unsigned int get_hash_value(const char *log_file_name, my_off_t log_file_pos);
|
||||
|
||||
int compare(const char *log_file_name1, my_off_t log_file_pos1,
|
||||
const TranxNode *node2) {
|
||||
const TranxNode *node2) {
|
||||
return compare(log_file_name1, log_file_pos1,
|
||||
node2->log_name_, node2->log_pos_);
|
||||
node2->log_name_, node2->log_pos_);
|
||||
}
|
||||
int compare(const TranxNode *node1,
|
||||
const char *log_file_name2, my_off_t log_file_pos2) {
|
||||
const char *log_file_name2, my_off_t log_file_pos2) {
|
||||
return compare(node1->log_name_, node1->log_pos_,
|
||||
log_file_name2, log_file_pos2);
|
||||
log_file_name2, log_file_pos2);
|
||||
}
|
||||
int compare(const TranxNode *node1, const TranxNode *node2) {
|
||||
return compare(node1->log_name_, node1->log_pos_,
|
||||
node2->log_name_, node2->log_pos_);
|
||||
node2->log_name_, node2->log_pos_);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -88,7 +342,7 @@ public:
|
|||
* 0: success; non-zero: error
|
||||
*/
|
||||
int clear_active_tranx_nodes(const char *log_file_name,
|
||||
my_off_t log_file_pos);
|
||||
my_off_t log_file_pos);
|
||||
|
||||
/* Given a position, check to see whether the position is an active
|
||||
* transaction's ending position by probing the hash table.
|
||||
|
@ -99,7 +353,7 @@ public:
|
|||
* (file_name, file_position).
|
||||
*/
|
||||
static int compare(const char *log_file_name1, my_off_t log_file_pos1,
|
||||
const char *log_file_name2, my_off_t log_file_pos2);
|
||||
const char *log_file_name2, my_off_t log_file_pos2);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -4646,10 +4646,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
|
|||
thd->warning_info->opt_clear_warning_info(thd->query_id);
|
||||
|
||||
TABLE_LIST tables;
|
||||
bzero((char*) &tables,sizeof(tables));
|
||||
tables.db= thd->strmake(thd->db, thd->db_length);
|
||||
tables.alias = tables.table_name = (char*) table_name;
|
||||
tables.lock_type = TL_WRITE;
|
||||
tables.init_one_table(thd->db, table_name, TL_WRITE);
|
||||
tables.updating= 1;
|
||||
|
||||
// the table will be opened in mysql_load
|
||||
|
|
|
@ -10952,17 +10952,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::get_next()
|
|||
} while ((result == HA_ERR_KEY_NOT_FOUND || result == HA_ERR_END_OF_FILE) &&
|
||||
is_last_prefix != 0);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
/*
|
||||
Partially mimic the behavior of end_select_send. Copy the
|
||||
field data from Item_field::field into Item_field::result_field
|
||||
of each non-aggregated field (the group fields, and optionally
|
||||
other fields in non-ANSI SQL mode).
|
||||
*/
|
||||
copy_fields(&join->tmp_table_param);
|
||||
}
|
||||
else if (result == HA_ERR_KEY_NOT_FOUND)
|
||||
if (result == HA_ERR_KEY_NOT_FOUND)
|
||||
result= HA_ERR_END_OF_FILE;
|
||||
|
||||
DBUG_RETURN(result);
|
||||
|
|
|
@ -977,7 +977,7 @@ bool load_master_data(THD* thd)
|
|||
host was specified; there could have been a problem when replication
|
||||
started, which led to relay log's IO_CACHE to not be inited.
|
||||
*/
|
||||
if (flush_master_info(active_mi, 0))
|
||||
if (flush_master_info(active_mi, FALSE, FALSE))
|
||||
sql_print_error("Failed to flush master info file");
|
||||
}
|
||||
mysql_free_result(master_status_res);
|
||||
|
|
|
@ -190,8 +190,8 @@ int Trans_delegate::after_commit(THD *thd, bool all)
|
|||
{
|
||||
Trans_param param;
|
||||
bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
|
||||
if (is_real_trans)
|
||||
param.flags |= TRANS_IS_REAL_TRANS;
|
||||
|
||||
param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
|
||||
|
||||
Trans_binlog_info *log_info=
|
||||
my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
|
||||
|
@ -218,8 +218,8 @@ int Trans_delegate::after_rollback(THD *thd, bool all)
|
|||
{
|
||||
Trans_param param;
|
||||
bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
|
||||
if (is_real_trans)
|
||||
param.flags |= TRANS_IS_REAL_TRANS;
|
||||
|
||||
param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
|
||||
|
||||
Trans_binlog_info *log_info=
|
||||
my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
|
||||
|
@ -228,7 +228,7 @@ int Trans_delegate::after_rollback(THD *thd, bool all)
|
|||
param.log_pos= log_info ? log_info->log_pos : 0;
|
||||
|
||||
int ret= 0;
|
||||
FOREACH_OBSERVER(ret, after_commit, thd, (¶m));
|
||||
FOREACH_OBSERVER(ret, after_rollback, thd, (¶m));
|
||||
|
||||
/*
|
||||
This is the end of a real transaction or autocommit statement, we
|
||||
|
|
|
@ -387,7 +387,7 @@ file '%s')", fname);
|
|||
mi->rli.is_relay_log_recovery= FALSE;
|
||||
// now change cache READ -> WRITE - must do this before flush_master_info
|
||||
reinit_io_cache(&mi->file, WRITE_CACHE, 0L, 0, 1);
|
||||
if ((error=test(flush_master_info(mi, 1))))
|
||||
if ((error=test(flush_master_info(mi, TRUE, TRUE))))
|
||||
sql_print_error("Failed to flush master info file");
|
||||
pthread_mutex_unlock(&mi->data_lock);
|
||||
DBUG_RETURN(error);
|
||||
|
@ -413,7 +413,9 @@ err:
|
|||
1 - flush master info failed
|
||||
0 - all ok
|
||||
*/
|
||||
int flush_master_info(Master_info* mi, bool flush_relay_log_cache)
|
||||
int flush_master_info(Master_info* mi,
|
||||
bool flush_relay_log_cache,
|
||||
bool need_lock_relay_log)
|
||||
{
|
||||
IO_CACHE* file = &mi->file;
|
||||
char lbuf[22];
|
||||
|
@ -436,8 +438,19 @@ int flush_master_info(Master_info* mi, bool flush_relay_log_cache)
|
|||
*/
|
||||
if (flush_relay_log_cache)
|
||||
{
|
||||
pthread_mutex_t *log_lock= mi->rli.relay_log.get_log_lock();
|
||||
IO_CACHE *log_file= mi->rli.relay_log.get_log_file();
|
||||
if (flush_io_cache(log_file))
|
||||
|
||||
if (need_lock_relay_log)
|
||||
pthread_mutex_lock(log_lock);
|
||||
|
||||
safe_mutex_assert_owner(log_lock);
|
||||
err= flush_io_cache(log_file);
|
||||
|
||||
if (need_lock_relay_log)
|
||||
pthread_mutex_unlock(log_lock);
|
||||
|
||||
if (err)
|
||||
DBUG_RETURN(2);
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,9 @@ int init_master_info(Master_info* mi, const char* master_info_fname,
|
|||
bool abort_if_no_master_info_file,
|
||||
int thread_mask);
|
||||
void end_master_info(Master_info* mi);
|
||||
int flush_master_info(Master_info* mi, bool flush_relay_log_cache);
|
||||
int flush_master_info(Master_info* mi,
|
||||
bool flush_relay_log_cache,
|
||||
bool need_lock_relay_log);
|
||||
int change_master_server_id_cmp(ulong *id1, ulong *id2);
|
||||
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
|
|
@ -121,7 +121,7 @@ int init_relay_log_info(Relay_log_info* rli,
|
|||
/*
|
||||
The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE.
|
||||
Note that the I/O thread flushes it to disk after writing every
|
||||
event, in flush_master_info(mi, 1).
|
||||
event, in flush_master_info(mi, 1, ?).
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -6260,3 +6260,5 @@ ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
|
|||
eng "Field '%-.192s' is of a not allowed type for this type of partitioning"
|
||||
ER_PARTITION_FIELDS_TOO_LONG
|
||||
eng "The total length of the partitioning fields is too large"
|
||||
ER_SPATIAL_MUST_HAVE_GEOM_COL 42000
|
||||
eng "A SPATIAL index may only contain a geometrical type column"
|
||||
|
|
|
@ -1726,7 +1726,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi)
|
|||
" to the relay log, SHOW SLAVE STATUS may be"
|
||||
" inaccurate");
|
||||
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
||||
if (flush_master_info(mi, 1))
|
||||
if (flush_master_info(mi, TRUE, FALSE))
|
||||
sql_print_error("Failed to flush master info file");
|
||||
delete ev;
|
||||
}
|
||||
|
@ -3047,7 +3047,7 @@ Stopping slave I/O thread due to out-of-memory error from master");
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (flush_master_info(mi, 1))
|
||||
if (flush_master_info(mi, TRUE, TRUE))
|
||||
{
|
||||
sql_print_error("Failed to flush master info file");
|
||||
goto err;
|
||||
|
|
|
@ -47,6 +47,7 @@ const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
|||
{ C_STRING_WITH_LEN("FTPARSER") },
|
||||
{ C_STRING_WITH_LEN("DAEMON") },
|
||||
{ C_STRING_WITH_LEN("INFORMATION SCHEMA") },
|
||||
{ C_STRING_WITH_LEN("AUDIT") },
|
||||
{ C_STRING_WITH_LEN("REPLICATION") },
|
||||
};
|
||||
|
||||
|
@ -87,6 +88,7 @@ static int min_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
|||
MYSQL_FTPARSER_INTERFACE_VERSION,
|
||||
MYSQL_DAEMON_INTERFACE_VERSION,
|
||||
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
|
||||
0x0000, /* place holder for audit plugin */
|
||||
MYSQL_REPLICATION_INTERFACE_VERSION,
|
||||
};
|
||||
static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
||||
|
@ -96,6 +98,7 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
|||
MYSQL_FTPARSER_INTERFACE_VERSION,
|
||||
MYSQL_DAEMON_INTERFACE_VERSION,
|
||||
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
|
||||
0x0000, /* place holder for audit plugin */
|
||||
MYSQL_REPLICATION_INTERFACE_VERSION,
|
||||
};
|
||||
|
||||
|
@ -745,6 +748,14 @@ static bool plugin_add(MEM_ROOT *tmp_root,
|
|||
name_len))
|
||||
{
|
||||
struct st_plugin_int *tmp_plugin_ptr;
|
||||
|
||||
if (plugin->type == MYSQL_AUDIT_PLUGIN)
|
||||
{
|
||||
/* Bug#49894 */
|
||||
sql_print_error("Plugin type 'AUDIT' not supported by this server.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (*(int*)plugin->info <
|
||||
min_plugin_info_interface_version[plugin->type] ||
|
||||
((*(int*)plugin->info) >> 8) >
|
||||
|
|
|
@ -1535,7 +1535,7 @@ bool change_master(THD* thd, Master_info* mi)
|
|||
Relay log's IO_CACHE may not be inited, if rli->inited==0 (server was never
|
||||
a slave before).
|
||||
*/
|
||||
if (flush_master_info(mi, 0))
|
||||
if (flush_master_info(mi, FALSE, FALSE))
|
||||
{
|
||||
my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush master info file");
|
||||
ret= TRUE;
|
||||
|
|
|
@ -12301,6 +12301,12 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||
if (!end_of_records)
|
||||
{
|
||||
int error;
|
||||
if (join->tables &&
|
||||
join->join_tab->is_using_loose_index_scan())
|
||||
{
|
||||
/* Copy non-aggregated fields when loose index scan is used. */
|
||||
copy_fields(&join->tmp_table_param);
|
||||
}
|
||||
if (join->having && join->having->val_int() == 0)
|
||||
DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having
|
||||
error=0;
|
||||
|
|
|
@ -292,7 +292,8 @@ uint explain_filename(THD* thd,
|
|||
{
|
||||
if (explain_mode == EXPLAIN_ALL_VERBOSE)
|
||||
{
|
||||
to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
|
||||
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_DATABASE_NAME),
|
||||
end_p - to_p);
|
||||
*(to_p++)= ' ';
|
||||
to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
|
||||
to_p= strnmov(to_p, ", ", end_p - to_p);
|
||||
|
@ -305,7 +306,7 @@ uint explain_filename(THD* thd,
|
|||
}
|
||||
if (explain_mode == EXPLAIN_ALL_VERBOSE)
|
||||
{
|
||||
to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
|
||||
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TABLE_NAME), end_p - to_p);
|
||||
*(to_p++)= ' ';
|
||||
to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
|
||||
}
|
||||
|
@ -322,18 +323,22 @@ uint explain_filename(THD* thd,
|
|||
if (name_type != NORMAL)
|
||||
{
|
||||
if (name_type == TEMP)
|
||||
to_p= strnmov(to_p, ER(ER_TEMPORARY_NAME), end_p - to_p);
|
||||
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TEMPORARY_NAME),
|
||||
end_p - to_p);
|
||||
else
|
||||
to_p= strnmov(to_p, ER(ER_RENAMED_NAME), end_p - to_p);
|
||||
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_RENAMED_NAME),
|
||||
end_p - to_p);
|
||||
to_p= strnmov(to_p, " ", end_p - to_p);
|
||||
}
|
||||
to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
|
||||
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_PARTITION_NAME),
|
||||
end_p - to_p);
|
||||
*(to_p++)= ' ';
|
||||
to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
|
||||
if (subpart_name)
|
||||
{
|
||||
to_p= strnmov(to_p, ", ", end_p - to_p);
|
||||
to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
|
||||
to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_SUBPARTITION_NAME),
|
||||
end_p - to_p);
|
||||
*(to_p++)= ' ';
|
||||
to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
|
||||
}
|
||||
|
@ -3187,11 +3192,19 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||
{
|
||||
column->length*= sql_field->charset->mbmaxlen;
|
||||
|
||||
if (key->type == Key::SPATIAL && column->length)
|
||||
if (key->type == Key::SPATIAL)
|
||||
{
|
||||
my_error(ER_WRONG_SUB_KEY, MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (column->length)
|
||||
{
|
||||
my_error(ER_WRONG_SUB_KEY, MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (!f_is_geom(sql_field->pack_flag))
|
||||
{
|
||||
my_error(ER_SPATIAL_MUST_HAVE_GEOM_COL, MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
if (f_is_blob(sql_field->pack_flag) ||
|
||||
(f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL))
|
||||
|
@ -3286,22 +3299,21 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||
}
|
||||
}
|
||||
}
|
||||
// Catch invalid use of partial keys
|
||||
else if (!f_is_geom(sql_field->pack_flag) &&
|
||||
((column->length > length &&
|
||||
!Field::type_can_have_key_part (sql_field->sql_type)) ||
|
||||
((f_is_packed(sql_field->pack_flag) ||
|
||||
((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
|
||||
(key_info->flags & HA_NOSAME))) &&
|
||||
column->length != length)))
|
||||
{
|
||||
/* Catch invalid uses of partial keys.
|
||||
A key is identified as 'partial' if column->length != length.
|
||||
A partial key is invalid if they data type does
|
||||
not allow it, or the field is packed (as in MyISAM),
|
||||
or the storage engine doesn't allow prefixed search and
|
||||
the key is primary key.
|
||||
*/
|
||||
|
||||
// is the key partial?
|
||||
column->length != length &&
|
||||
// is prefix length bigger than field length?
|
||||
(column->length > length ||
|
||||
// can the field have a partial key?
|
||||
!Field::type_can_have_key_part (sql_field->sql_type) ||
|
||||
// a packed field can't be used in a partial key
|
||||
f_is_packed(sql_field->pack_flag) ||
|
||||
// does the storage engine allow prefixed search?
|
||||
((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
|
||||
// and is this a 'unique' key?
|
||||
(key_info->flags & HA_NOSAME))))
|
||||
{
|
||||
my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@
|
|||
#define ER(X) CURRENT_THD_ERRMSGS[(X) - ER_ERROR_FIRST]
|
||||
#define ER_DEFAULT(X) DEFAULT_ERRMSGS[(X) - ER_ERROR_FIRST]
|
||||
#define ER_SAFE(X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER(X) : "Invalid error code")
|
||||
#define ER_THD(thd,X) ((thd)->variables.lc_messages->errmsgs->errmsgs[(X) - \
|
||||
ER_ERROR_FIRST])
|
||||
#define ER_THD_OR_DEFAULT(thd,X) ((thd) ? ER_THD(thd, X) : ER_DEFAULT(X))
|
||||
|
||||
|
||||
#define ERRMAPP 1 /* Errormap f|r my_error */
|
||||
|
|
|
@ -87,12 +87,10 @@
|
|||
%{?_without_bundled_zlib:%define WITH_BUNDLED_ZLIB 0}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# use "rpmbuild --without innodb_plugin" or "rpm --define '_without_innodb_plugin 1'"
|
||||
# (for RPM 3.x) to not build the innodb plugin (on by default with innodb builds)
|
||||
# support optional "tcmalloc" stuff (experimental)
|
||||
# ----------------------------------------------------------------------
|
||||
%{!?_with_innodb_plugin: %{!?_without_innodb_plugin: %define WITH_INNODB_PLUGIN 1}}
|
||||
%{?_with_innodb_plugin:%define WITH_INNODB_PLUGIN 1}
|
||||
%{?_without_innodb_plugin:%define WITH_INNODB_PLUGIN 0}
|
||||
%{?malloc_lib_target:%define WITH_TCMALLOC 1}
|
||||
%{!?malloc_lib_target:%define WITH_TCMALLOC 0}
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# use "rpmbuild --with cluster" or "rpm --define '_with_cluster 1'" (for RPM 3.x)
|
||||
|
@ -419,13 +417,8 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \
|
|||
%endif
|
||||
%if %{INNODB_BUILD}
|
||||
--with-plugin-innobase \
|
||||
%if %{WITH_INNODB_PLUGIN}
|
||||
%else
|
||||
--without-plugin-innodb_plugin \
|
||||
%endif
|
||||
%else
|
||||
--without-plugin-innobase \
|
||||
--without-plugin-innodb_plugin \
|
||||
%endif
|
||||
%if %{PARTITION_BUILD}
|
||||
--with-plugin-partition \
|
||||
|
@ -579,13 +572,6 @@ $MBD/libtool --mode=execute install -m 755 \
|
|||
$RPM_BUILD_DIR/mysql-%{mysql_version}/mysql-debug-%{mysql_version}/sql/mysqld \
|
||||
$RBR%{_sbindir}/mysqld-debug
|
||||
|
||||
%if %{WITH_TCMALLOC}
|
||||
# Even though this is a shared library, put it under /usr/lib/mysql, so it
|
||||
# doesn't conflict with possible shared lib by the same name in /usr/lib. See
|
||||
# `mysql_config --variable=pkglibdir` and mysqld_safe for how this is used.
|
||||
install -m 644 "%{malloc_lib_source}" "$RBR%{_libdir}/mysql/%{malloc_lib_target}"
|
||||
%endif
|
||||
|
||||
# install saved perror binary with NDB support (BUG#13740)
|
||||
install -m 755 $MBD/extra/perror $RBR%{_bindir}/perror
|
||||
|
||||
|
@ -605,10 +591,17 @@ rm -fr $RBR%{_datadir}/sql-bench
|
|||
# will appreciate that, as all services usually offer this.
|
||||
ln -s %{_sysconfdir}/init.d/mysql $RBR%{_sbindir}/rcmysql
|
||||
|
||||
# Touch the place where the my.cnf config file might be located.
|
||||
# Just to make sure it's in the file list and marked as a config file.
|
||||
# Touch the place where the my.cnf config file might be located
|
||||
# Just to make sure it's in the file list and marked as a config file
|
||||
touch $RBR%{_sysconfdir}/my.cnf
|
||||
|
||||
%if %{WITH_TCMALLOC}
|
||||
# Even though this is a shared library, put it under /usr/lib/mysql, so it
|
||||
# doesn't conflict with possible shared lib by the same name in /usr/lib. See
|
||||
# `mysql_config --variable=pkglibdir` and mysqld_safe for how this is used.
|
||||
install -m 644 "%{malloc_lib_source}" "$RBR%{_libdir}/mysql/%{malloc_lib_target}"
|
||||
%endif
|
||||
|
||||
##############################################################################
|
||||
# Post processing actions, i.e. when installed
|
||||
##############################################################################
|
||||
|
@ -875,12 +868,13 @@ fi
|
|||
%attr(755, root, root) %{_sbindir}/mysqld
|
||||
%attr(755, root, root) %{_sbindir}/mysqld-debug
|
||||
%attr(755, root, root) %{_sbindir}/rcmysql
|
||||
%if %{INNODB_BUILD}
|
||||
%if %{WITH_INNODB_PLUGIN}
|
||||
%attr(755, root, root) %{_libdir}/mysql/plugin/ha_innodb_plugin.so*
|
||||
%endif
|
||||
%endif
|
||||
%attr(755, root, root) %{_libdir}/mysql/plugin/ha_example.so*
|
||||
%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so*
|
||||
%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so*
|
||||
|
||||
%if %{WITH_TCMALLOC}
|
||||
%attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target}
|
||||
%endif
|
||||
|
||||
%attr(644, root, root) %config(noreplace,missingok) %{_sysconfdir}/logrotate.d/mysql
|
||||
%attr(755, root, root) %{_sysconfdir}/init.d/mysql
|
||||
|
@ -905,6 +899,7 @@ fi
|
|||
%doc %attr(644, root, man) %{_mandir}/man1/msql2mysql.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/mysql.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/mysql_find_rows.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/mysql_waitpid.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/mysqlaccess.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/mysqladmin.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/mysqlbinlog.1*
|
||||
|
@ -976,6 +971,7 @@ fi
|
|||
%files devel
|
||||
%defattr(-, root, root, 0755)
|
||||
%doc mysql-release-%{mysql_version}/EXCEPTIONS-CLIENT
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/comp_err.1*
|
||||
%doc %attr(644, root, man) %{_mandir}/man1/mysql_config.1*
|
||||
%attr(755, root, root) %{_bindir}/mysql_config
|
||||
%dir %attr(755, root, root) %{_includedir}/mysql
|
||||
|
@ -1044,7 +1040,7 @@ fi
|
|||
# merging BK trees)
|
||||
##############################################################################
|
||||
%changelog
|
||||
* Fri Feb 05 2010 Joerg Bruehe <joerg.bruehe@sun.com>
|
||||
* Fri Feb 12 2010 Joerg Bruehe <joerg.bruehe@sun.com>
|
||||
|
||||
- Formatting changes:
|
||||
Have a consistent structure of separator lines and of indentation
|
||||
|
@ -1056,8 +1052,6 @@ fi
|
|||
in 5.1 since ages.
|
||||
- Introduce variables to control the handlers individually, as well
|
||||
as other options.
|
||||
- Handle the InnoDB plugin using a positive logic: "WITH_INNODB_PLUGIN",
|
||||
the old negative logic ("WITHOUT_INNODB_PLUGIN") was obfuscating.
|
||||
- Use the new "--with-plugin" notation for the table handlers.
|
||||
- Drop handling "/etc/rc.d/init.d/mysql", the switch to "/etc/init.d/mysql"
|
||||
was done back in 2002 already.
|
||||
|
|
Loading…
Reference in a new issue