mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Merge stella.local:/home2/mydev/mysql-5.1-amain
into stella.local:/home2/mydev/mysql-5.1-axmrg
This commit is contained in:
@@ -360,6 +360,17 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[
|
|||||||
AC_MSG_ERROR([cannot disable mandatory plugin])
|
AC_MSG_ERROR([cannot disable mandatory plugin])
|
||||||
fi
|
fi
|
||||||
[mysql_plugin_]$2=yes
|
[mysql_plugin_]$2=yes
|
||||||
|
],[
|
||||||
|
case "$with_mysqld_ldflags " in
|
||||||
|
*"-all-static "*)
|
||||||
|
# No need to build shared plugins when mysqld is linked with
|
||||||
|
# -all-static as it won't be able to load them.
|
||||||
|
if test "X[$mysql_plugin_]$2" != Xyes -a \
|
||||||
|
"X[$with_plugin_]$2" != Xyes; then
|
||||||
|
[with_plugin_]$2=no
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
])
|
])
|
||||||
if test "X[$with_plugin_]$2" = Xno; then
|
if test "X[$with_plugin_]$2" = Xno; then
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
|
13
configure.in
13
configure.in
@@ -1750,7 +1750,18 @@ then
|
|||||||
LDFLAGS="$LDFLAGS -rdynamic"
|
LDFLAGS="$LDFLAGS -rdynamic"
|
||||||
AC_MSG_RESULT("-rdynamic")
|
AC_MSG_RESULT("-rdynamic")
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT("none")
|
case "$SYSTEM_TYPE$with_mysqld_ldflags " in
|
||||||
|
*freebsd*"-all-static "*|*dragonfly*"-all-static "*)
|
||||||
|
AC_MSG_RESULT("none")
|
||||||
|
;;
|
||||||
|
*freebsd*|*dragonfly*)
|
||||||
|
MYSQLD_EXTRA_LDFLAGS="$MYSQLD_EXTRA_LDFLAGS -export-dynamic"
|
||||||
|
AC_MSG_RESULT("-export-dynamic")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
AC_MSG_RESULT("none")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
@@ -13,20 +13,20 @@ CREATE TABLE t2 (p POINT, INDEX(p));
|
|||||||
INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)'));
|
INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)'));
|
||||||
INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)'));
|
INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)'));
|
||||||
|
|
||||||
-- no index, returns 1 as expected
|
# no index, returns 1 as expected
|
||||||
SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)');
|
SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)');
|
||||||
|
|
||||||
-- with index, returns 1 as expected
|
# with index, returns 1 as expected
|
||||||
-- EXPLAIN shows that the index is not used though
|
# EXPLAIN shows that the index is not used though
|
||||||
-- due to the "most rows covered anyway, so a scan is more effective" rule
|
# due to the "most rows covered anyway, so a scan is more effective" rule
|
||||||
EXPLAIN
|
EXPLAIN
|
||||||
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
|
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
|
||||||
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
|
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
|
||||||
|
|
||||||
-- adding another row to the table so that
|
# adding another row to the table so that
|
||||||
-- the "most rows covered" rule doesn't kick in anymore
|
# the "most rows covered" rule doesn't kick in anymore
|
||||||
-- now EXPLAIN shows the index used on the table
|
# now EXPLAIN shows the index used on the table
|
||||||
-- and we're getting the wrong result again
|
# and we're getting the wrong result again
|
||||||
INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)'));
|
INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)'));
|
||||||
INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)'));
|
INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)'));
|
||||||
EXPLAIN
|
EXPLAIN
|
||||||
|
@@ -1163,7 +1163,7 @@ CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256))
|
|||||||
ENGINE = $engine_type;
|
ENGINE = $engine_type;
|
||||||
INSERT INTO t1 VALUES (1,2);
|
INSERT INTO t1 VALUES (1,2);
|
||||||
|
|
||||||
--#echo 1. test for locking:
|
--echo # 1. test for locking:
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
--enable_info
|
--enable_info
|
||||||
|
@@ -811,6 +811,12 @@ quote(name)
|
|||||||
????????
|
????????
|
||||||
????????????????
|
????????????????
|
||||||
drop table bug20536;
|
drop table bug20536;
|
||||||
|
CREATE TABLE t1(a TEXT CHARSET ucs2 COLLATE ucs2_unicode_ci);
|
||||||
|
INSERT INTO t1 VALUES('abcd');
|
||||||
|
SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abcd' IN BOOLEAN MODE);
|
||||||
|
a
|
||||||
|
abcd
|
||||||
|
DROP TABLE t1;
|
||||||
End of 4.1 tests
|
End of 4.1 tests
|
||||||
CREATE TABLE t1 (a varchar(64) character set ucs2, b decimal(10,3));
|
CREATE TABLE t1 (a varchar(64) character set ucs2, b decimal(10,3));
|
||||||
INSERT INTO t1 VALUES ("1.1", 0), ("2.1", 0);
|
INSERT INTO t1 VALUES ("1.1", 0), ("2.1", 0);
|
||||||
|
@@ -476,6 +476,12 @@ ALTER TABLE t1 DISABLE KEYS;
|
|||||||
SELECT * FROM t1 WHERE MATCH(a) AGAINST('test');
|
SELECT * FROM t1 WHERE MATCH(a) AGAINST('test');
|
||||||
ERROR HY000: Can't find FULLTEXT index matching the column list
|
ERROR HY000: Can't find FULLTEXT index matching the column list
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(a TEXT);
|
||||||
|
INSERT INTO t1 VALUES(' aaaaa aaaa');
|
||||||
|
SELECT * FROM t1 WHERE MATCH(a) AGAINST ('"aaaa"' IN BOOLEAN MODE);
|
||||||
|
a
|
||||||
|
aaaaa aaaa
|
||||||
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1(a VARCHAR(20), FULLTEXT(a));
|
CREATE TABLE t1(a VARCHAR(20), FULLTEXT(a));
|
||||||
INSERT INTO t1 VALUES('Offside'),('City Of God');
|
INSERT INTO t1 VALUES('Offside'),('City Of God');
|
||||||
SELECT a FROM t1 WHERE MATCH a AGAINST ('+city of*' IN BOOLEAN MODE);
|
SELECT a FROM t1 WHERE MATCH a AGAINST ('+city of*' IN BOOLEAN MODE);
|
||||||
|
@@ -1426,6 +1426,7 @@ SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
|||||||
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256))
|
CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256))
|
||||||
ENGINE = InnoDB;
|
ENGINE = InnoDB;
|
||||||
INSERT INTO t1 VALUES (1,2);
|
INSERT INTO t1 VALUES (1,2);
|
||||||
|
# 1. test for locking:
|
||||||
BEGIN;
|
BEGIN;
|
||||||
UPDATE t1 SET b = 12 WHERE a = 1;
|
UPDATE t1 SET b = 12 WHERE a = 1;
|
||||||
affected rows: 1
|
affected rows: 1
|
||||||
|
@@ -1987,3 +1987,28 @@ Table Op Msg_type Msg_text
|
|||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE INDEX (c1), INDEX (c2)) ENGINE=MYISAM;
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
|
t1 MyISAM 10 Fixed 0 # # # 1024 # # # # # # #
|
||||||
|
INSERT INTO t1 VALUES (1,1);
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
|
t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
|
||||||
|
ALTER TABLE t1 DISABLE KEYS;
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
|
t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
|
||||||
|
ALTER TABLE t1 ENABLE KEYS;
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
|
t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
|
||||||
|
ALTER TABLE t1 DISABLE KEYS;
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
|
t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
|
||||||
|
ALTER TABLE t1 ENABLE KEYS;
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
|
t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
|
||||||
|
DROP TABLE t1;
|
||||||
|
@@ -1,4 +1,32 @@
|
|||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
d DATE NOT NULL
|
||||||
|
)
|
||||||
|
PARTITION BY RANGE( YEAR(d) ) (
|
||||||
|
PARTITION p0 VALUES LESS THAN (1960),
|
||||||
|
PARTITION p1 VALUES LESS THAN (1970),
|
||||||
|
PARTITION p2 VALUES LESS THAN (1980),
|
||||||
|
PARTITION p3 VALUES LESS THAN (1990)
|
||||||
|
);
|
||||||
|
ALTER TABLE t1 ADD PARTITION (
|
||||||
|
PARTITION `p5` VALUES LESS THAN (2010)
|
||||||
|
COMMENT 'APSTART \' APEND'
|
||||||
|
);
|
||||||
|
SELECT * FROM t1 LIMIT 1;
|
||||||
|
d
|
||||||
|
DROP TABLE t1;
|
||||||
|
create table t1 (id int auto_increment, s1 int, primary key (id));
|
||||||
|
insert into t1 values (null,1);
|
||||||
|
insert into t1 values (null,6);
|
||||||
|
select * from t1;
|
||||||
|
id s1
|
||||||
|
1 1
|
||||||
|
2 6
|
||||||
|
alter table t1 partition by range (id) (
|
||||||
|
partition p0 values less than (3),
|
||||||
|
partition p1 values less than maxvalue
|
||||||
|
);
|
||||||
|
drop table t1;
|
||||||
create table t1 (a int)
|
create table t1 (a int)
|
||||||
partition by key(a)
|
partition by key(a)
|
||||||
partitions 0.2+e1;
|
partitions 0.2+e1;
|
||||||
|
@@ -547,6 +547,14 @@ select quote(name) from bug20536;
|
|||||||
|
|
||||||
drop table bug20536;
|
drop table bug20536;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#31159 - fulltext search on ucs2 column crashes server
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a TEXT CHARSET ucs2 COLLATE ucs2_unicode_ci);
|
||||||
|
INSERT INTO t1 VALUES('abcd');
|
||||||
|
SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abcd' IN BOOLEAN MODE);
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 4.1 tests
|
--echo End of 4.1 tests
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@@ -399,6 +399,14 @@ ALTER TABLE t1 DISABLE KEYS;
|
|||||||
SELECT * FROM t1 WHERE MATCH(a) AGAINST('test');
|
SELECT * FROM t1 WHERE MATCH(a) AGAINST('test');
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG#11392 - fulltext search bug
|
||||||
|
#
|
||||||
|
CREATE TABLE t1(a TEXT);
|
||||||
|
INSERT INTO t1 VALUES(' aaaaa aaaa');
|
||||||
|
SELECT * FROM t1 WHERE MATCH(a) AGAINST ('"aaaa"' IN BOOLEAN MODE);
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# BUG#29445 - match ... against () never returns
|
# BUG#29445 - match ... against () never returns
|
||||||
#
|
#
|
||||||
|
@@ -1256,3 +1256,29 @@ CHECK TABLE t1;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
#
|
||||||
|
# Bug#4692 - DISABLE/ENABLE KEYS waste a space
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (c1 INT, c2 INT, UNIQUE INDEX (c1), INDEX (c2)) ENGINE=MYISAM;
|
||||||
|
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
INSERT INTO t1 VALUES (1,1);
|
||||||
|
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
ALTER TABLE t1 DISABLE KEYS;
|
||||||
|
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
ALTER TABLE t1 ENABLE KEYS;
|
||||||
|
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
ALTER TABLE t1 DISABLE KEYS;
|
||||||
|
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
ALTER TABLE t1 ENABLE KEYS;
|
||||||
|
--replace_column 6 # 7 # 8 # 10 # 11 # 12 # 13 # 14 # 15 # 16 #
|
||||||
|
SHOW TABLE STATUS LIKE 't1';
|
||||||
|
#--exec ls -log var/master-data/test/t1.MYI
|
||||||
|
#--exec myisamchk -dvv var/master-data/test/t1.MYI
|
||||||
|
#--exec myisamchk -iev var/master-data/test/t1.MYI
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
@@ -14,6 +14,50 @@
|
|||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #30695: An apostrophe ' in the comment of the ADD PARTITION causes the Server to crash.
|
||||||
|
#
|
||||||
|
# To verify the fix for crashing (on unix-type OS)
|
||||||
|
# uncomment the exec and error rows!
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
d DATE NOT NULL
|
||||||
|
)
|
||||||
|
PARTITION BY RANGE( YEAR(d) ) (
|
||||||
|
PARTITION p0 VALUES LESS THAN (1960),
|
||||||
|
PARTITION p1 VALUES LESS THAN (1970),
|
||||||
|
PARTITION p2 VALUES LESS THAN (1980),
|
||||||
|
PARTITION p3 VALUES LESS THAN (1990)
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE t1 ADD PARTITION (
|
||||||
|
PARTITION `p5` VALUES LESS THAN (2010)
|
||||||
|
COMMENT 'APSTART \' APEND'
|
||||||
|
);
|
||||||
|
#--exec sed 's/APSTART \\/APSTART /' var/master-data/test/t1.frm > tmpt1.frm && mv tmpt1.frm var/master-data/test/t1.frm
|
||||||
|
#--error 1064
|
||||||
|
SELECT * FROM t1 LIMIT 1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug 30878: crashing when alter an auto_increment non partitioned
|
||||||
|
# table to partitioned
|
||||||
|
|
||||||
|
create table t1 (id int auto_increment, s1 int, primary key (id));
|
||||||
|
|
||||||
|
insert into t1 values (null,1);
|
||||||
|
insert into t1 values (null,6);
|
||||||
|
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
alter table t1 partition by range (id) (
|
||||||
|
partition p0 values less than (3),
|
||||||
|
partition p1 values less than maxvalue
|
||||||
|
);
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug 15890: Strange number of partitions accepted
|
# Bug 15890: Strange number of partitions accepted
|
||||||
#
|
#
|
||||||
|
@@ -161,7 +161,7 @@ select * from information_schema.session_variables where variable_name like 'net
|
|||||||
set net_buffer_length=1;
|
set net_buffer_length=1;
|
||||||
show variables like 'net_buffer_length';
|
show variables like 'net_buffer_length';
|
||||||
select * from information_schema.session_variables where variable_name like 'net_buffer_length';
|
select * from information_schema.session_variables where variable_name like 'net_buffer_length';
|
||||||
--warning 1292
|
#warning 1292
|
||||||
set net_buffer_length=2000000000;
|
set net_buffer_length=2000000000;
|
||||||
show variables like 'net_buffer_length';
|
show variables like 'net_buffer_length';
|
||||||
select * from information_schema.session_variables where variable_name like 'net_buffer_length';
|
select * from information_schema.session_variables where variable_name like 'net_buffer_length';
|
||||||
|
@@ -90,12 +90,14 @@ TARGET_LINK_LIBRARIES(mysqld
|
|||||||
|
|
||||||
SET_TARGET_PROPERTIES(mysqld PROPERTIES OUTPUT_NAME mysqld${MYSQLD_EXE_SUFFIX})
|
SET_TARGET_PROPERTIES(mysqld PROPERTIES OUTPUT_NAME mysqld${MYSQLD_EXE_SUFFIX})
|
||||||
|
|
||||||
|
IF(cmake_version EQUAL 20406)
|
||||||
# Work around for 2.4.6 bug, OUTPUT_NAME will not set the right .PDB
|
# Work around for 2.4.6 bug, OUTPUT_NAME will not set the right .PDB
|
||||||
# file name. Note that COMPILE_FLAGS set some temporary pdb during build,
|
# file name. Note that COMPILE_FLAGS set some temporary pdb during build,
|
||||||
# LINK_FLAGS sets the real one.
|
# LINK_FLAGS sets the real one.
|
||||||
SET_TARGET_PROPERTIES(mysqld PROPERTIES
|
SET_TARGET_PROPERTIES(mysqld PROPERTIES
|
||||||
COMPILE_FLAGS "/Fd${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb"
|
COMPILE_FLAGS "/Fd${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb"
|
||||||
LINK_FLAGS "/PDB:${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb")
|
LINK_FLAGS "/PDB:${CMAKE_CFG_INTDIR}/mysqld${MYSQLD_EXE_SUFFIX}.pdb")
|
||||||
|
ENDIF(cmake_version EQUAL 20406)
|
||||||
|
|
||||||
IF(EMBED_MANIFESTS)
|
IF(EMBED_MANIFESTS)
|
||||||
MYSQL_EMBED_MANIFEST("mysqld" "asInvoker")
|
MYSQL_EMBED_MANIFEST("mysqld" "asInvoker")
|
||||||
|
@@ -2678,7 +2678,8 @@ int ha_partition::write_row(uchar * buf)
|
|||||||
uint32 part_id;
|
uint32 part_id;
|
||||||
int error;
|
int error;
|
||||||
longlong func_value;
|
longlong func_value;
|
||||||
bool autoincrement_lock= false;
|
bool autoincrement_lock= FALSE;
|
||||||
|
my_bitmap_map *old_map;
|
||||||
#ifdef NOT_NEEDED
|
#ifdef NOT_NEEDED
|
||||||
uchar *rec0= m_rec0;
|
uchar *rec0= m_rec0;
|
||||||
#endif
|
#endif
|
||||||
@@ -2705,8 +2706,17 @@ int ha_partition::write_row(uchar * buf)
|
|||||||
use autoincrement_lock variable to avoid unnecessary locks.
|
use autoincrement_lock variable to avoid unnecessary locks.
|
||||||
Probably not an ideal solution.
|
Probably not an ideal solution.
|
||||||
*/
|
*/
|
||||||
autoincrement_lock= true;
|
if (table_share->tmp_table == NO_TMP_TABLE)
|
||||||
pthread_mutex_lock(&table_share->mutex);
|
{
|
||||||
|
/*
|
||||||
|
Bug#30878 crash when alter table from non partitioned table
|
||||||
|
to partitioned.
|
||||||
|
Checking if tmp table then there is no need to lock,
|
||||||
|
and the table_share->mutex may not be initialised.
|
||||||
|
*/
|
||||||
|
autoincrement_lock= TRUE;
|
||||||
|
pthread_mutex_lock(&table_share->mutex);
|
||||||
|
}
|
||||||
error= update_auto_increment();
|
error= update_auto_increment();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2715,10 +2725,10 @@ int ha_partition::write_row(uchar * buf)
|
|||||||
the correct partition. We must check and fail if neccessary.
|
the correct partition. We must check and fail if neccessary.
|
||||||
*/
|
*/
|
||||||
if (error)
|
if (error)
|
||||||
DBUG_RETURN(error);
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
|
old_map= dbug_tmp_use_all_columns(table, table->read_set);
|
||||||
#ifdef NOT_NEEDED
|
#ifdef NOT_NEEDED
|
||||||
if (likely(buf == rec0))
|
if (likely(buf == rec0))
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1856,6 +1856,20 @@ static int add_uint(File fptr, ulonglong number)
|
|||||||
return add_string(fptr, buff);
|
return add_string(fptr, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Must escape strings in partitioned tables frm-files,
|
||||||
|
parsing it later with mysql_unpack_partition will fail otherwise.
|
||||||
|
*/
|
||||||
|
static int add_quoted_string(File fptr, const char *quotestr)
|
||||||
|
{
|
||||||
|
String orgstr(quotestr, system_charset_info);
|
||||||
|
String escapedstr;
|
||||||
|
int err= add_string(fptr, "'");
|
||||||
|
err+= append_escaped(&escapedstr, &orgstr);
|
||||||
|
err+= add_string(fptr, escapedstr.c_ptr());
|
||||||
|
return err + add_string(fptr, "'");
|
||||||
|
}
|
||||||
|
|
||||||
static int add_keyword_string(File fptr, const char *keyword,
|
static int add_keyword_string(File fptr, const char *keyword,
|
||||||
bool should_use_quotes,
|
bool should_use_quotes,
|
||||||
const char *keystr)
|
const char *keystr)
|
||||||
@@ -1866,10 +1880,9 @@ static int add_keyword_string(File fptr, const char *keyword,
|
|||||||
err+= add_equal(fptr);
|
err+= add_equal(fptr);
|
||||||
err+= add_space(fptr);
|
err+= add_space(fptr);
|
||||||
if (should_use_quotes)
|
if (should_use_quotes)
|
||||||
err+= add_string(fptr, "'");
|
err+= add_quoted_string(fptr, keystr);
|
||||||
err+= add_string(fptr, keystr);
|
else
|
||||||
if (should_use_quotes)
|
err+= add_string(fptr, keystr);
|
||||||
err+= add_string(fptr, "'");
|
|
||||||
return err + add_space(fptr);
|
return err + add_space(fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6492,7 +6492,7 @@ bool_pri:
|
|||||||
{ $$= (*$2)(0)->create($1,$3); }
|
{ $$= (*$2)(0)->create($1,$3); }
|
||||||
| bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
|
| bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
|
||||||
{ $$= all_any_subquery_creator($1, $2, $3, $5); }
|
{ $$= all_any_subquery_creator($1, $2, $3, $5); }
|
||||||
| predicate ;
|
| predicate
|
||||||
;
|
;
|
||||||
|
|
||||||
predicate:
|
predicate:
|
||||||
|
@@ -1784,7 +1784,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||||||
outparam, is_create_table,
|
outparam, is_create_table,
|
||||||
share->default_part_db_type,
|
share->default_part_db_type,
|
||||||
&work_part_info_used);
|
&work_part_info_used);
|
||||||
outparam->part_info->is_auto_partitioned= share->auto_partitioned;
|
if (!tmp)
|
||||||
|
outparam->part_info->is_auto_partitioned= share->auto_partitioned;
|
||||||
DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
|
DBUG_PRINT("info", ("autopartitioned: %u", share->auto_partitioned));
|
||||||
/* we should perform the fix_partition_func in either local or
|
/* we should perform the fix_partition_func in either local or
|
||||||
caller's arena depending on work_part_info_used value
|
caller's arena depending on work_part_info_used value
|
||||||
|
@@ -1376,6 +1376,139 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
|
|||||||
} /* chk_data_link */
|
} /* chk_data_link */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Drop all indexes
|
||||||
|
|
||||||
|
@param[in] param check parameters
|
||||||
|
@param[in] info MI_INFO handle
|
||||||
|
@param[in] force if to force drop all indexes
|
||||||
|
|
||||||
|
@return status
|
||||||
|
@retval 0 OK
|
||||||
|
@retval != 0 Error
|
||||||
|
|
||||||
|
@note
|
||||||
|
Once allocated, index blocks remain part of the key file forever.
|
||||||
|
When indexes are disabled, no block is freed. When enabling indexes,
|
||||||
|
no block is freed either. The new indexes are create from new
|
||||||
|
blocks. (Bug #4692)
|
||||||
|
|
||||||
|
Before recreating formerly disabled indexes, the unused blocks
|
||||||
|
must be freed. There are two options to do this:
|
||||||
|
- Follow the tree of disabled indexes, add all blocks to the
|
||||||
|
deleted blocks chain. Would require a lot of random I/O.
|
||||||
|
- Drop all blocks by clearing all index root pointers and all
|
||||||
|
delete chain pointers and resetting key_file_length to the end
|
||||||
|
of the index file header. This requires to recreate all indexes,
|
||||||
|
even those that may still be intact.
|
||||||
|
The second method is probably faster in most cases.
|
||||||
|
|
||||||
|
When disabling indexes, MySQL disables either all indexes or all
|
||||||
|
non-unique indexes. When MySQL [re-]enables disabled indexes
|
||||||
|
(T_CREATE_MISSING_KEYS), then we either have "lost" blocks in the
|
||||||
|
index file, or there are no non-unique indexes. In the latter case,
|
||||||
|
mi_repair*() would not be called as there would be no disabled
|
||||||
|
indexes.
|
||||||
|
|
||||||
|
If there would be more unique indexes than disabled (non-unique)
|
||||||
|
indexes, we could do the first method. But this is not implemented
|
||||||
|
yet. By now we drop and recreate all indexes when repair is called.
|
||||||
|
|
||||||
|
However, there is an exception. Sometimes MySQL disables non-unique
|
||||||
|
indexes when the table is empty (e.g. when copying a table in
|
||||||
|
mysql_alter_table()). When enabling the non-unique indexes, they
|
||||||
|
are still empty. So there is no index block that can be lost. This
|
||||||
|
optimization is implemented in this function.
|
||||||
|
|
||||||
|
Note that in normal repair (T_CREATE_MISSING_KEYS not set) we
|
||||||
|
recreate all enabled indexes unconditonally. We do not change the
|
||||||
|
key_map. Otherwise we invert the key map temporarily (outside of
|
||||||
|
this function) and recreate the then "seemingly" enabled indexes.
|
||||||
|
When we cannot use the optimization, and drop all indexes, we
|
||||||
|
pretend that all indexes were disabled. By the inversion, we will
|
||||||
|
then recrate all indexes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int mi_drop_all_indexes(MI_CHECK *param, MI_INFO *info, my_bool force)
|
||||||
|
{
|
||||||
|
MYISAM_SHARE *share= info->s;
|
||||||
|
MI_STATE_INFO *state= &share->state;
|
||||||
|
uint i;
|
||||||
|
int error;
|
||||||
|
DBUG_ENTER("mi_drop_all_indexes");
|
||||||
|
|
||||||
|
/*
|
||||||
|
If any of the disabled indexes has a key block assigned, we must
|
||||||
|
drop and recreate all indexes to avoid losing index blocks.
|
||||||
|
|
||||||
|
If we want to recreate disabled indexes only _and_ all of these
|
||||||
|
indexes are empty, we don't need to recreate the existing indexes.
|
||||||
|
*/
|
||||||
|
if (!force && (param->testflag & T_CREATE_MISSING_KEYS))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("repair", ("creating missing indexes"));
|
||||||
|
for (i= 0; i < share->base.keys; i++)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("repair", ("index #: %u key_root: 0x%lx active: %d",
|
||||||
|
i, (long) state->key_root[i],
|
||||||
|
mi_is_key_active(state->key_map, i)));
|
||||||
|
if ((state->key_root[i] != HA_OFFSET_ERROR) &&
|
||||||
|
!mi_is_key_active(state->key_map, i))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
This index has at least one key block and it is disabled.
|
||||||
|
We would lose its block(s) if would just recreate it.
|
||||||
|
So we need to drop and recreate all indexes.
|
||||||
|
*/
|
||||||
|
DBUG_PRINT("repair", ("nonempty and disabled: recreate all"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i >= share->base.keys)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
All of the disabled indexes are empty. We can just recreate them.
|
||||||
|
Flush dirty blocks of this index file from key cache and remove
|
||||||
|
all blocks of this index file from key cache.
|
||||||
|
*/
|
||||||
|
DBUG_PRINT("repair", ("all disabled are empty: create missing"));
|
||||||
|
error= flush_key_blocks(share->key_cache, share->kfile,
|
||||||
|
FLUSH_FORCE_WRITE);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
We do now drop all indexes and declare them disabled. With the
|
||||||
|
T_CREATE_MISSING_KEYS flag, mi_repair*() will recreate all
|
||||||
|
disabled indexes and enable them.
|
||||||
|
*/
|
||||||
|
mi_clear_all_keys_active(state->key_map);
|
||||||
|
DBUG_PRINT("repair", ("declared all indexes disabled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove all key blocks of this index file from key cache. */
|
||||||
|
if ((error= flush_key_blocks(share->key_cache, share->kfile,
|
||||||
|
FLUSH_IGNORE_CHANGED)))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Clear index root block pointers. */
|
||||||
|
for (i= 0; i < share->base.keys; i++)
|
||||||
|
state->key_root[i]= HA_OFFSET_ERROR;
|
||||||
|
|
||||||
|
/* Clear the delete chains. */
|
||||||
|
for (i= 0; i < state->header.max_block_size_index; i++)
|
||||||
|
state->key_del[i]= HA_OFFSET_ERROR;
|
||||||
|
|
||||||
|
/* Reset index file length to end of index file header. */
|
||||||
|
info->state->key_file_length= share->base.keystart;
|
||||||
|
|
||||||
|
DBUG_PRINT("repair", ("dropped all indexes"));
|
||||||
|
/* error= 0; set by last (error= flush_key_bocks()). */
|
||||||
|
|
||||||
|
end:
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Recover old table by reading each record and writing all keys */
|
/* Recover old table by reading each record and writing all keys */
|
||||||
/* Save new datafile-name in temp_filename */
|
/* Save new datafile-name in temp_filename */
|
||||||
|
|
||||||
@@ -1383,7 +1516,6 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
|
|||||||
char * name, int rep_quick)
|
char * name, int rep_quick)
|
||||||
{
|
{
|
||||||
int error,got_error;
|
int error,got_error;
|
||||||
uint i;
|
|
||||||
ha_rows start_records,new_header_length;
|
ha_rows start_records,new_header_length;
|
||||||
my_off_t del;
|
my_off_t del;
|
||||||
File new_file;
|
File new_file;
|
||||||
@@ -1487,25 +1619,10 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
|
|||||||
|
|
||||||
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
||||||
|
|
||||||
/*
|
/* This function always recreates all enabled indexes. */
|
||||||
Clear all keys. Note that all key blocks allocated until now remain
|
|
||||||
"dead" parts of the key file. (Bug #4692)
|
|
||||||
*/
|
|
||||||
for (i=0 ; i < info->s->base.keys ; i++)
|
|
||||||
share->state.key_root[i]= HA_OFFSET_ERROR;
|
|
||||||
|
|
||||||
/* Drop the delete chain. */
|
|
||||||
for (i=0 ; i < share->state.header.max_block_size_index ; i++)
|
|
||||||
share->state.key_del[i]= HA_OFFSET_ERROR;
|
|
||||||
|
|
||||||
/*
|
|
||||||
If requested, activate (enable) all keys in key_map. In this case,
|
|
||||||
all indexes will be (re-)built.
|
|
||||||
*/
|
|
||||||
if (param->testflag & T_CREATE_MISSING_KEYS)
|
if (param->testflag & T_CREATE_MISSING_KEYS)
|
||||||
mi_set_all_keys_active(share->state.key_map, share->base.keys);
|
mi_set_all_keys_active(share->state.key_map, share->base.keys);
|
||||||
|
mi_drop_all_indexes(param, info, TRUE);
|
||||||
info->state->key_file_length=share->base.keystart;
|
|
||||||
|
|
||||||
lock_memory(param); /* Everything is alloced */
|
lock_memory(param); /* Everything is alloced */
|
||||||
|
|
||||||
@@ -2106,8 +2223,9 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||||||
ulong *rec_per_key_part;
|
ulong *rec_per_key_part;
|
||||||
char llbuff[22];
|
char llbuff[22];
|
||||||
SORT_INFO sort_info;
|
SORT_INFO sort_info;
|
||||||
ulonglong key_map=share->state.key_map;
|
ulonglong key_map;
|
||||||
DBUG_ENTER("mi_repair_by_sort");
|
DBUG_ENTER("mi_repair_by_sort");
|
||||||
|
LINT_INIT(key_map);
|
||||||
|
|
||||||
start_records=info->state->records;
|
start_records=info->state->records;
|
||||||
got_error=1;
|
got_error=1;
|
||||||
@@ -2180,25 +2298,14 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
||||||
if (!(param->testflag & T_CREATE_MISSING_KEYS))
|
|
||||||
|
/* Optionally drop indexes and optionally modify the key_map. */
|
||||||
|
mi_drop_all_indexes(param, info, FALSE);
|
||||||
|
key_map= share->state.key_map;
|
||||||
|
if (param->testflag & T_CREATE_MISSING_KEYS)
|
||||||
{
|
{
|
||||||
/*
|
/* Invert the copied key_map to recreate all disabled indexes. */
|
||||||
Flush key cache for this file if we are calling this outside
|
key_map= ~key_map;
|
||||||
myisamchk
|
|
||||||
*/
|
|
||||||
flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED);
|
|
||||||
/* Clear the pointers to the given rows */
|
|
||||||
for (i=0 ; i < share->base.keys ; i++)
|
|
||||||
share->state.key_root[i]= HA_OFFSET_ERROR;
|
|
||||||
for (i=0 ; i < share->state.header.max_block_size_index ; i++)
|
|
||||||
share->state.key_del[i]= HA_OFFSET_ERROR;
|
|
||||||
info->state->key_file_length=share->base.keystart;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (flush_key_blocks(share->key_cache,share->kfile, FLUSH_FORCE_WRITE))
|
|
||||||
goto err;
|
|
||||||
key_map= ~key_map; /* Create the missing keys */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sort_info.info=info;
|
sort_info.info=info;
|
||||||
@@ -2242,6 +2349,10 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||||||
sort_param.read_cache=param->read_cache;
|
sort_param.read_cache=param->read_cache;
|
||||||
sort_param.keyinfo=share->keyinfo+sort_param.key;
|
sort_param.keyinfo=share->keyinfo+sort_param.key;
|
||||||
sort_param.seg=sort_param.keyinfo->seg;
|
sort_param.seg=sort_param.keyinfo->seg;
|
||||||
|
/*
|
||||||
|
Skip this index if it is marked disabled in the copied
|
||||||
|
(and possibly inverted) key_map.
|
||||||
|
*/
|
||||||
if (! mi_is_key_active(key_map, sort_param.key))
|
if (! mi_is_key_active(key_map, sort_param.key))
|
||||||
{
|
{
|
||||||
/* Remember old statistics for key */
|
/* Remember old statistics for key */
|
||||||
@@ -2249,6 +2360,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||||||
(char*) (share->state.rec_per_key_part +
|
(char*) (share->state.rec_per_key_part +
|
||||||
(uint) (rec_per_key_part - param->rec_per_key_part)),
|
(uint) (rec_per_key_part - param->rec_per_key_part)),
|
||||||
sort_param.keyinfo->keysegs*sizeof(*rec_per_key_part));
|
sort_param.keyinfo->keysegs*sizeof(*rec_per_key_part));
|
||||||
|
DBUG_PRINT("repair", ("skipping seemingly disabled index #: %u",
|
||||||
|
sort_param.key));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2329,8 +2442,11 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||||||
if (param->testflag & T_STATISTICS)
|
if (param->testflag & T_STATISTICS)
|
||||||
update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique,
|
update_key_parts(sort_param.keyinfo, rec_per_key_part, sort_param.unique,
|
||||||
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
|
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
|
||||||
sort_param.notnull: NULL,(ulonglong) info->state->records);
|
sort_param.notnull: NULL,
|
||||||
|
(ulonglong) info->state->records);
|
||||||
|
/* Enable this index in the permanent (not the copied) key_map. */
|
||||||
mi_set_key_active(share->state.key_map, sort_param.key);
|
mi_set_key_active(share->state.key_map, sort_param.key);
|
||||||
|
DBUG_PRINT("repair", ("set enabled index #: %u", sort_param.key));
|
||||||
|
|
||||||
if (sort_param.fix_datafile)
|
if (sort_param.fix_datafile)
|
||||||
{
|
{
|
||||||
@@ -2531,9 +2647,10 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||||||
IO_CACHE new_data_cache; /* For non-quick repair. */
|
IO_CACHE new_data_cache; /* For non-quick repair. */
|
||||||
IO_CACHE_SHARE io_share;
|
IO_CACHE_SHARE io_share;
|
||||||
SORT_INFO sort_info;
|
SORT_INFO sort_info;
|
||||||
ulonglong key_map=share->state.key_map;
|
ulonglong key_map;
|
||||||
pthread_attr_t thr_attr;
|
pthread_attr_t thr_attr;
|
||||||
DBUG_ENTER("mi_repair_parallel");
|
DBUG_ENTER("mi_repair_parallel");
|
||||||
|
LINT_INIT(key_map);
|
||||||
|
|
||||||
start_records=info->state->records;
|
start_records=info->state->records;
|
||||||
got_error=1;
|
got_error=1;
|
||||||
@@ -2635,25 +2752,14 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
|
||||||
if (!(param->testflag & T_CREATE_MISSING_KEYS))
|
|
||||||
|
/* Optionally drop indexes and optionally modify the key_map. */
|
||||||
|
mi_drop_all_indexes(param, info, FALSE);
|
||||||
|
key_map= share->state.key_map;
|
||||||
|
if (param->testflag & T_CREATE_MISSING_KEYS)
|
||||||
{
|
{
|
||||||
/*
|
/* Invert the copied key_map to recreate all disabled indexes. */
|
||||||
Flush key cache for this file if we are calling this outside
|
key_map= ~key_map;
|
||||||
myisamchk
|
|
||||||
*/
|
|
||||||
flush_key_blocks(share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED);
|
|
||||||
/* Clear the pointers to the given rows */
|
|
||||||
for (i=0 ; i < share->base.keys ; i++)
|
|
||||||
share->state.key_root[i]= HA_OFFSET_ERROR;
|
|
||||||
for (i=0 ; i < share->state.header.max_block_size_index ; i++)
|
|
||||||
share->state.key_del[i]= HA_OFFSET_ERROR;
|
|
||||||
info->state->key_file_length=share->base.keystart;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (flush_key_blocks(share->key_cache,share->kfile, FLUSH_FORCE_WRITE))
|
|
||||||
goto err;
|
|
||||||
key_map= ~key_map; /* Create the missing keys */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sort_info.info=info;
|
sort_info.info=info;
|
||||||
@@ -2709,6 +2815,10 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||||||
sort_param[i].key=key;
|
sort_param[i].key=key;
|
||||||
sort_param[i].keyinfo=share->keyinfo+key;
|
sort_param[i].keyinfo=share->keyinfo+key;
|
||||||
sort_param[i].seg=sort_param[i].keyinfo->seg;
|
sort_param[i].seg=sort_param[i].keyinfo->seg;
|
||||||
|
/*
|
||||||
|
Skip this index if it is marked disabled in the copied
|
||||||
|
(and possibly inverted) key_map.
|
||||||
|
*/
|
||||||
if (! mi_is_key_active(key_map, key))
|
if (! mi_is_key_active(key_map, key))
|
||||||
{
|
{
|
||||||
/* Remember old statistics for key */
|
/* Remember old statistics for key */
|
||||||
|
Reference in New Issue
Block a user