summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-12-12 13:46:06 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2018-12-12 13:46:06 +0200
commit839cf16bb2de078d5000bcb2f9b3151f1ebda708 (patch)
tree52deb93bd818156b0168601aefc9afbc537b1dbf
parentdce2cc1c6a82d1ed9f4db9c39bc9cb1d3815a019 (diff)
parent91173f986373e4f5f134a2351a80d8763e5157e8 (diff)
downloadmariadb-git-839cf16bb2de078d5000bcb2f9b3151f1ebda708.tar.gz
Merge 10.2 into 10.3
-rw-r--r--mysql-test/main/partition.result100
-rw-r--r--mysql-test/main/partition.test62
-rw-r--r--mysql-test/suite/innodb/r/data_types.result13
-rw-r--r--mysql-test/suite/innodb/r/innodb-index.result27
-rw-r--r--mysql-test/suite/innodb/r/truncate.result12
-rw-r--r--mysql-test/suite/innodb/t/data_types.test13
-rw-r--r--mysql-test/suite/innodb/t/innodb-index.test25
-rw-r--r--mysql-test/suite/innodb/t/truncate.test12
-rw-r--r--sql/opt_range.cc19
-rw-r--r--sql/partition_info.cc17
-rw-r--r--sql/partition_info.h1
-rw-r--r--sql/sql_statistics.cc45
-rw-r--r--sql/sql_statistics.h1
-rw-r--r--storage/innobase/btr/btr0cur.cc19
-rw-r--r--storage/innobase/handler/handler0alter.cc5
-rw-r--r--storage/innobase/include/fts0types.ic26
16 files changed, 347 insertions, 50 deletions
diff --git a/mysql-test/main/partition.result b/mysql-test/main/partition.result
index fd76da09d78..bf5d45846a5 100644
--- a/mysql-test/main/partition.result
+++ b/mysql-test/main/partition.result
@@ -2649,6 +2649,106 @@ Note 1517 Duplicate partition name p2
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
#
+# MDEV-17032: Estimates are higher for partitions of a table with @@use_stat_tables= PREFERABLY
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2 (
+part_key int,
+a int,
+b int
+) partition by list(part_key) (
+partition p0 values in (0),
+partition p1 values in (1),
+partition p2 values in (2),
+partition p3 values in (3),
+partition p4 values in (4)
+);
+insert into t2
+select mod(a,5), a/100, mod(a,5) from t1;
+set @save_use_stat_tables= @@use_stat_tables;
+set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity;
+#
+# Tests using stats provided by the storage engine
+#
+explain extended select * from t2 where part_key=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 200 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`part_key` AS `part_key`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`part_key` = 1
+explain partitions select * from t2 where part_key=1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 p1 ALL NULL NULL NULL NULL 200 Using where
+explain extended select * from t2 where part_key in (1,2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 400 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`part_key` AS `part_key`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`part_key` in (1,2)
+explain partitions select * from t2 where part_key in (1,2);
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 p1,p2 ALL NULL NULL NULL NULL 400 Using where
+explain extended select * from t2 where b=5;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1000 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`part_key` AS `part_key`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` = 5
+explain partitions select * from t2 where b=5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 1000 Using where
+explain extended select * from t2 partition(p0) where b=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 200 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`part_key` AS `part_key`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` PARTITION (`p0`) where `test`.`t2`.`b` = 1
+set @save_histogram_size=@@histogram_size;
+set @@histogram_size=100;
+set @@use_stat_tables= PREFERABLY;
+set @@optimizer_use_condition_selectivity=4;
+analyze table t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status Engine-independent statistics collected
+test.t2 analyze status OK
+#
+# Tests using EITS
+#
+# filtered should be 100
+explain extended select * from t2 where part_key=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 200 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`part_key` AS `part_key`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`part_key` = 1
+explain partitions select * from t2 where part_key=1;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 p1 ALL NULL NULL NULL NULL 200 Using where
+# filtered should be 100
+explain extended select * from t2 where part_key in (1,2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 400 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`part_key` AS `part_key`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`part_key` in (1,2)
+explain partitions select * from t2 where part_key in (1,2);
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 p1,p2 ALL NULL NULL NULL NULL 400 Using where
+explain extended select * from t2 where b=5;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1000 19.80 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`part_key` AS `part_key`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where `test`.`t2`.`b` = 5
+explain partitions select * from t2 where b=5;
+id select_type table partitions type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 p0,p1,p2,p3,p4 ALL NULL NULL NULL NULL 1000 Using where
+explain extended select * from t2 partition(p0) where b=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 200 19.80 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`part_key` AS `part_key`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` PARTITION (`p0`) where `test`.`t2`.`b` = 1
+set @@use_stat_tables= @save_use_stat_tables;
+set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
+set @@histogram_size= @save_histogram_size;
+drop table t0,t1,t2;
+#
# End of 10.0 tests
#
#
diff --git a/mysql-test/main/partition.test b/mysql-test/main/partition.test
index 7b7d1457426..42929796f6b 100644
--- a/mysql-test/main/partition.test
+++ b/mysql-test/main/partition.test
@@ -2901,6 +2901,68 @@ DEALLOCATE PREPARE stmt;
DROP TABLE t1;
--echo #
+--echo # MDEV-17032: Estimates are higher for partitions of a table with @@use_stat_tables= PREFERABLY
+--echo #
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1(a int);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+
+
+create table t2 (
+ part_key int,
+ a int,
+ b int
+) partition by list(part_key) (
+ partition p0 values in (0),
+ partition p1 values in (1),
+ partition p2 values in (2),
+ partition p3 values in (3),
+ partition p4 values in (4)
+);
+insert into t2
+select mod(a,5), a/100, mod(a,5) from t1;
+
+set @save_use_stat_tables= @@use_stat_tables;
+set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity;
+--echo #
+--echo # Tests using stats provided by the storage engine
+--echo #
+explain extended select * from t2 where part_key=1;
+explain partitions select * from t2 where part_key=1;
+explain extended select * from t2 where part_key in (1,2);
+explain partitions select * from t2 where part_key in (1,2);
+explain extended select * from t2 where b=5;
+explain partitions select * from t2 where b=5;
+explain extended select * from t2 partition(p0) where b=1;
+
+
+set @save_histogram_size=@@histogram_size;
+set @@histogram_size=100;
+set @@use_stat_tables= PREFERABLY;
+set @@optimizer_use_condition_selectivity=4;
+analyze table t2;
+--echo #
+--echo # Tests using EITS
+--echo #
+--echo # filtered should be 100
+explain extended select * from t2 where part_key=1;
+explain partitions select * from t2 where part_key=1;
+--echo # filtered should be 100
+explain extended select * from t2 where part_key in (1,2);
+explain partitions select * from t2 where part_key in (1,2);
+explain extended select * from t2 where b=5;
+explain partitions select * from t2 where b=5;
+explain extended select * from t2 partition(p0) where b=1;
+
+set @@use_stat_tables= @save_use_stat_tables;
+set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
+set @@histogram_size= @save_histogram_size;
+drop table t0,t1,t2;
+
+--echo #
--echo # End of 10.0 tests
--echo #
diff --git a/mysql-test/suite/innodb/r/data_types.result b/mysql-test/suite/innodb/r/data_types.result
index 446d37527e5..4e919e37cee 100644
--- a/mysql-test/suite/innodb/r/data_types.result
+++ b/mysql-test/suite/innodb/r/data_types.result
@@ -75,10 +75,13 @@ t1_VARCHAR_10_BINARY VARCHAR(10) BINARY,
t1_VARCHAR_500 VARCHAR(500),
t1_VARCHAR_500_BINARY VARCHAR(500) BINARY,
t1_YEAR_2 YEAR(2),
-t1_YEAR_4 YEAR(4)
+t1_YEAR_4 YEAR(4),
+t1_CHAR_0 CHAR(0),
+t1_MYSQL_0 CHAR(0) CHARACTER SET utf8
) ENGINE=InnoDB;
Warnings:
Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead
+INSERT INTO t1 () VALUES ();
SELECT
name,
CASE mtype
@@ -109,6 +112,7 @@ t1_BINARY_100 DATA_FIXBINARY
t1_BIT_2 DATA_FIXBINARY UNSIGNED
t1_BIT_20 DATA_FIXBINARY UNSIGNED
t1_BLOB DATA_BLOB
+t1_CHAR_0 DATA_CHAR
t1_CHAR_100 DATA_CHAR
t1_CHAR_100_BINARY DATA_MYSQL
t1_DATE DATA_INT
@@ -131,6 +135,7 @@ t1_MEDIUMBLOB DATA_BLOB
t1_MEDIUMINT DATA_INT
t1_MEDIUMINT_UNSIGNED DATA_INT UNSIGNED
t1_MEDIUMTEXT DATA_BLOB
+t1_MYSQL_0 DATA_MYSQL
t1_SET DATA_INT UNSIGNED
t1_SET_9 DATA_INT UNSIGNED
t1_SET_BINARY DATA_INT UNSIGNED
@@ -153,3 +158,9 @@ t1_VARCHAR_500_BINARY DATA_VARMYSQL
t1_YEAR_2 DATA_INT UNSIGNED
t1_YEAR_4 DATA_INT UNSIGNED
DROP TABLE t1;
+#
+# MDEV-17815 Assertion failed in btr_node_ptr_max_size for CHAR(0)
+#
+CREATE TABLE t1 (c CHAR(0), KEY(c)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('');
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result
index df27769b810..8d7dcb84486 100644
--- a/mysql-test/suite/innodb/r/innodb-index.result
+++ b/mysql-test/suite/innodb/r/innodb-index.result
@@ -1184,6 +1184,33 @@ t2c CREATE TABLE `t2c` (
KEY `t2a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1,t2,t2c,t2i;
+CREATE TABLE t1 (c VARCHAR(1024),
+c1 CHAR(255) NOT NULL,c2 CHAR(255) NOT NULL,c3 CHAR(255) NOT NULL,
+c4 CHAR(255) NOT NULL,c5 CHAR(255) NOT NULL,c6 CHAR(255) NOT NULL,
+c7 CHAR(255) NOT NULL,c8 CHAR(255) NOT NULL,c9 CHAR(255) NOT NULL,
+ca CHAR(255) NOT NULL,cb CHAR(255) NOT NULL,cc CHAR(255) NOT NULL,
+cd CHAR(255) NOT NULL,ce CHAR(255) NOT NULL,cf CHAR(255) NOT NULL,
+d0 CHAR(255) NOT NULL,d1 CHAR(255) NOT NULL,d2 CHAR(255) NOT NULL,
+d3 CHAR(255) NOT NULL,d4 CHAR(255) NOT NULL,d5 CHAR(255) NOT NULL,
+d6 CHAR(255) NOT NULL,d7 CHAR(255) NOT NULL,d8 CHAR(255) NOT NULL,
+d9 CHAR(255) NOT NULL,da CHAR(255) NOT NULL,db CHAR(255) NOT NULL,
+dc CHAR(255) NOT NULL,dd CHAR(255) NOT NULL,de CHAR(255) NOT NULL,
+UNIQUE KEY(c))
+ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES
+(repeat('a',999),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','',''),
+(CONCAT(repeat('a',999),'b'),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=inplace;
+ERROR HY000: Index column size too large. The maximum column size is 767 bytes
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=copy;
+ERROR HY000: Index column size too large. The maximum column size is 767 bytes
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+2
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
#
# Bug #17657223 EXCESSIVE TEMPORARY FILE USAGE IN ALTER TABLE
#
diff --git a/mysql-test/suite/innodb/r/truncate.result b/mysql-test/suite/innodb/r/truncate.result
index f584ffadc05..52fe1e28948 100644
--- a/mysql-test/suite/innodb/r/truncate.result
+++ b/mysql-test/suite/innodb/r/truncate.result
@@ -7,18 +7,6 @@ TRUNCATE TABLE t;
disconnect dml;
DROP TABLE t;
#
-# MDEV-17816 Crash in TRUNCATE TABLE when table creation fails
-#
-CREATE TABLE t1 (c VARCHAR(1024), KEY(c)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
-INSERT INTO t1 SET c='character';
-ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
-TRUNCATE TABLE t1;
-ERROR HY000: Index column size too large. The maximum column size is 767 bytes
-SELECT * FROM t1;
-c
-character
-DROP TABLE t1;
-#
# MDEV-17831 TRUNCATE TABLE removes ROW_FORMAT=COMPRESSED
#
CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB KEY_BLOCK_SIZE=4;
diff --git a/mysql-test/suite/innodb/t/data_types.test b/mysql-test/suite/innodb/t/data_types.test
index 0978146361c..c8e80c9db27 100644
--- a/mysql-test/suite/innodb/t/data_types.test
+++ b/mysql-test/suite/innodb/t/data_types.test
@@ -88,9 +88,13 @@ CREATE TABLE t1
t1_VARCHAR_500 VARCHAR(500),
t1_VARCHAR_500_BINARY VARCHAR(500) BINARY,
t1_YEAR_2 YEAR(2),
- t1_YEAR_4 YEAR(4)
+ t1_YEAR_4 YEAR(4),
+ t1_CHAR_0 CHAR(0),
+ t1_MYSQL_0 CHAR(0) CHARACTER SET utf8
) ENGINE=InnoDB;
+INSERT INTO t1 () VALUES ();
+
SELECT
name,
CASE mtype
@@ -116,3 +120,10 @@ WHERE name LIKE "t1\_%"
ORDER BY name;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-17815 Assertion failed in btr_node_ptr_max_size for CHAR(0)
+--echo #
+CREATE TABLE t1 (c CHAR(0), KEY(c)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('');
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-index.test b/mysql-test/suite/innodb/t/innodb-index.test
index e575cff4774..f199da54031 100644
--- a/mysql-test/suite/innodb/t/innodb-index.test
+++ b/mysql-test/suite/innodb/t/innodb-index.test
@@ -549,6 +549,31 @@ show create table t2c;
--disable_info
DROP TABLE t1,t2,t2c,t2i;
+
+CREATE TABLE t1 (c VARCHAR(1024),
+c1 CHAR(255) NOT NULL,c2 CHAR(255) NOT NULL,c3 CHAR(255) NOT NULL,
+c4 CHAR(255) NOT NULL,c5 CHAR(255) NOT NULL,c6 CHAR(255) NOT NULL,
+c7 CHAR(255) NOT NULL,c8 CHAR(255) NOT NULL,c9 CHAR(255) NOT NULL,
+ca CHAR(255) NOT NULL,cb CHAR(255) NOT NULL,cc CHAR(255) NOT NULL,
+cd CHAR(255) NOT NULL,ce CHAR(255) NOT NULL,cf CHAR(255) NOT NULL,
+d0 CHAR(255) NOT NULL,d1 CHAR(255) NOT NULL,d2 CHAR(255) NOT NULL,
+d3 CHAR(255) NOT NULL,d4 CHAR(255) NOT NULL,d5 CHAR(255) NOT NULL,
+d6 CHAR(255) NOT NULL,d7 CHAR(255) NOT NULL,d8 CHAR(255) NOT NULL,
+d9 CHAR(255) NOT NULL,da CHAR(255) NOT NULL,db CHAR(255) NOT NULL,
+dc CHAR(255) NOT NULL,dd CHAR(255) NOT NULL,de CHAR(255) NOT NULL,
+UNIQUE KEY(c))
+ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES
+(repeat('a',999),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','',''),
+(CONCAT(repeat('a',999),'b'),'','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');
+--error ER_INDEX_COLUMN_TOO_LONG
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=inplace;
+--error ER_INDEX_COLUMN_TOO_LONG
+ALTER TABLE t1 ROW_FORMAT=REDUNDANT, algorithm=copy;
+SELECT COUNT(*) FROM t1;
+CHECK TABLE t1;
+DROP TABLE t1;
+
--echo #
--echo # Bug #17657223 EXCESSIVE TEMPORARY FILE USAGE IN ALTER TABLE
--echo #
diff --git a/mysql-test/suite/innodb/t/truncate.test b/mysql-test/suite/innodb/t/truncate.test
index 5a80f7c49e3..6c573cf42d4 100644
--- a/mysql-test/suite/innodb/t/truncate.test
+++ b/mysql-test/suite/innodb/t/truncate.test
@@ -17,18 +17,6 @@ disconnect dml;
DROP TABLE t;
--echo #
---echo # MDEV-17816 Crash in TRUNCATE TABLE when table creation fails
---echo #
-CREATE TABLE t1 (c VARCHAR(1024), KEY(c)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
-INSERT INTO t1 SET c='character';
-# FIXME: MDEV-17833 ALTER TABLE is not enforcing prefix index size limit
-ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
---error ER_INDEX_COLUMN_TOO_LONG
-TRUNCATE TABLE t1;
-SELECT * FROM t1;
-DROP TABLE t1;
-
---echo #
--echo # MDEV-17831 TRUNCATE TABLE removes ROW_FORMAT=COMPRESSED
--echo #
CREATE TABLE t1 (a SERIAL) ENGINE=InnoDB KEY_BLOCK_SIZE=4;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index ed7fba2caa9..0c6c585bff6 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2730,14 +2730,17 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param,
{
Field **field_ptr;
TABLE *table= param->table;
+ partition_info *part_info= NULL;
+ #ifdef WITH_PARTITION_STORAGE_ENGINE
+ part_info= table->part_info;
+ #endif
uint parts= 0;
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
- Column_statistics* col_stats= (*field_ptr)->read_stats;
- if (bitmap_is_set(used_fields, (*field_ptr)->field_index)
- && col_stats && !col_stats->no_stat_values_provided()
- && !((*field_ptr)->type() == MYSQL_TYPE_GEOMETRY))
+ Field *field= *field_ptr;
+ if (bitmap_is_set(used_fields, field->field_index) &&
+ is_eits_usable(field))
parts++;
}
@@ -2755,12 +2758,10 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param,
uint max_key_len= 0;
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
- if (bitmap_is_set(used_fields, (*field_ptr)->field_index))
+ Field *field= *field_ptr;
+ if (bitmap_is_set(used_fields, field->field_index))
{
- Field *field= *field_ptr;
- Column_statistics* col_stats= field->read_stats;
- if (field->type() == MYSQL_TYPE_GEOMETRY ||
- !col_stats || col_stats->no_stat_values_provided())
+ if (!is_eits_usable(field))
continue;
uint16 store_length;
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index f09bde6a965..e24038f96ab 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -2626,6 +2626,23 @@ void partition_info::print_debug(const char *str, uint *value)
DBUG_PRINT("info", ("parser: %s", str));
DBUG_VOID_RETURN;
}
+
+bool partition_info::field_in_partition_expr(Field *field) const
+{
+ uint i;
+ for (i= 0; i < num_part_fields; i++)
+ {
+ if (field->eq(part_field_array[i]))
+ return TRUE;
+ }
+ for (i= 0; i < num_subpart_fields; i++)
+ {
+ if (field->eq(subpart_field_array[i]))
+ return TRUE;
+ }
+ return FALSE;
+}
+
#else /* WITH_PARTITION_STORAGE_ENGINE */
/*
For builds without partitioning we need to define these functions
diff --git a/sql/partition_info.h b/sql/partition_info.h
index e00a2c44341..95700dac517 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -392,6 +392,7 @@ private:
public:
bool set_read_partitions(List<char> *partition_names);
bool has_unique_name(partition_element *element);
+ bool field_in_partition_expr(Field *field) const;
bool vers_init_info(THD *thd);
bool vers_set_interval(Item *item, interval_type int_type, my_time_t start)
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 04806f07b3b..8a0c1554869 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -31,6 +31,7 @@
#include "uniques.h"
#include "my_atomic.h"
#include "sql_show.h"
+#include "sql_partition.h"
/*
The system variable 'use_stat_tables' can take one of the
@@ -3725,6 +3726,22 @@ void set_statistics_for_table(THD *thd, TABLE *table)
(use_stat_table_mode <= COMPLEMENTARY ||
!table->stats_is_read || read_stats->cardinality_is_null) ?
table->file->stats.records : read_stats->cardinality;
+
+ /*
+ For partitioned table, EITS statistics is based on data from all partitions.
+
+ On the other hand, Partition Pruning figures which partitions will be
+ accessed and then computes the estimate of rows in used_partitions.
+
+ Use the estimate from Partition Pruning as it is typically more precise.
+ Ideally, EITS should provide per-partition statistics but this is not
+ implemented currently.
+ */
+ #ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (table->part_info)
+ table->used_stat_records= table->file->stats.records;
+ #endif
+
KEY *key_info, *key_info_end;
for (key_info= table->key_info, key_info_end= key_info+table->s->keys;
key_info < key_info_end; key_info++)
@@ -4043,3 +4060,31 @@ bool is_stat_table(const LEX_CSTRING *db, LEX_CSTRING *table)
}
return false;
}
+
+/*
+ Check wheter we can use EITS statistics for a field or not
+
+ TRUE : Use EITS for the columns
+ FALSE: Otherwise
+*/
+
+bool is_eits_usable(Field *field)
+{
+ partition_info *part_info= NULL;
+ #ifdef WITH_PARTITION_STORAGE_ENGINE
+ part_info= field->table->part_info;
+ #endif
+ /*
+ (1): checks if we have EITS statistics for a particular column
+ (2): Don't use EITS for GEOMETRY columns
+ (3): Disabling reading EITS statistics for columns involved in the
+ partition list of a table. We assume the selecticivity for
+ such columns would be handled during partition pruning.
+ */
+ Column_statistics* col_stats= field->read_stats;
+ if (col_stats && !col_stats->no_stat_values_provided() && //(1)
+ field->type() != MYSQL_TYPE_GEOMETRY && //(2)
+ (!part_info || !part_info->field_in_partition_expr(field))) //(3)
+ return TRUE;
+ return FALSE;
+}
diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h
index 39cddf95188..89758f002ca 100644
--- a/sql/sql_statistics.h
+++ b/sql/sql_statistics.h
@@ -112,6 +112,7 @@ double get_column_range_cardinality(Field *field,
key_range *max_endp,
uint range_flag);
bool is_stat_table(const LEX_CSTRING *db, LEX_CSTRING *table);
+bool is_eits_usable(Field* field);
class Histogram
{
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 2ba311fce7b..b8f9a55b148 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -967,6 +967,25 @@ static ulint btr_node_ptr_max_size(const dict_index_t* index)
field_max_size = dict_col_get_max_size(col);
if (UNIV_UNLIKELY(!field_max_size)) {
+ switch (col->mtype) {
+ case DATA_CHAR:
+ case DATA_MYSQL:
+ /* CHAR(0) is a possible data type.
+ The InnoDB internal SQL parser maps
+ CHAR to DATA_VARCHAR, so DATA_CHAR (or
+ DATA_MYSQL) is only coming from the
+ MariaDB SQL layer. */
+ if (comp) {
+ /* Add a length byte, because
+ fixed-length empty field are
+ encoded as variable-length.
+ For ROW_FORMAT=REDUNDANT,
+ these bytes were added to
+ rec_max_size before this loop. */
+ rec_max_size++;
+ }
+ continue;
+ }
/* SYS_FOREIGN.ID is defined as CHAR in the
InnoDB internal SQL parser, which translates
into the incorrect VARCHAR(0). InnoDB does
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 104e16d1688..1e9e6dbda12 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -6463,9 +6463,8 @@ check_if_ok_to_rename:
/* Check each index's column length to make sure they do not
exceed limit */
- for (ulint i = 0; i < ha_alter_info->index_add_count; i++) {
- const KEY* key = &ha_alter_info->key_info_buffer[
- ha_alter_info->index_add_buffer[i]];
+ for (ulint i = 0; i < ha_alter_info->key_count; i++) {
+ const KEY* key = &ha_alter_info->key_info_buffer[i];
if (key->flags & HA_FULLTEXT) {
/* The column length does not matter for
diff --git a/storage/innobase/include/fts0types.ic b/storage/innobase/include/fts0types.ic
index 486f8c2f109..1091e48a467 100644
--- a/storage/innobase/include/fts0types.ic
+++ b/storage/innobase/include/fts0types.ic
@@ -108,19 +108,21 @@ innobase_strnxfrm(
@param[in] cs charset
@retval true if the charset is cjk
@retval false if not. */
-UNIV_INLINE
-bool
-fts_is_charset_cjk(
- const CHARSET_INFO* cs)
+inline bool fts_is_charset_cjk(const CHARSET_INFO* cs)
{
- return cs == &my_charset_gb2312_chinese_ci
- || cs == &my_charset_gbk_chinese_ci
- || cs == &my_charset_big5_chinese_ci
- || cs == &my_charset_ujis_japanese_ci
- || cs == &my_charset_sjis_japanese_ci
- || cs == &my_charset_cp932_japanese_ci
- || cs == &my_charset_eucjpms_japanese_ci
- || cs == &my_charset_euckr_korean_ci;
+ switch (cs->number) {
+ case 24: /* my_charset_gb2312_chinese_ci */
+ case 28: /* my_charset_gbk_chinese_ci */
+ case 1: /* my_charset_big5_chinese_ci */
+ case 12: /* my_charset_ujis_japanese_ci */
+ case 13: /* my_charset_sjis_japanese_ci */
+ case 95: /* my_charset_cp932_japanese_ci */
+ case 97: /* my_charset_eucjpms_japanese_ci */
+ case 19: /* my_charset_euckr_korean_ci */
+ return true;
+ default:
+ return false;
+ }
}
/** Select the FTS auxiliary index for the given character by range.