diff options
author | Alexander Barkov <bar@mariadb.com> | 2019-06-11 07:54:37 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2019-06-11 07:54:37 +0400 |
commit | f42bda6d7578297c016279abcc7e177237206724 (patch) | |
tree | 01db4eed8dfe737a85aa8a0bcecf89e0f09b5579 | |
parent | 163665640afb153c173d272eae98b0b63950cd83 (diff) | |
download | mariadb-git-f42bda6d7578297c016279abcc7e177237206724.tar.gz |
MDEV-19727 Add Type_handler::Key_part_spec_init_ft
-rw-r--r-- | mysql-test/main/column_compression.result | 16 | ||||
-rw-r--r-- | mysql-test/main/column_compression.test | 29 | ||||
-rw-r--r-- | mysql-test/main/type_varchar.result | 29 | ||||
-rw-r--r-- | mysql-test/main/type_varchar.test | 23 | ||||
-rw-r--r-- | sql/sql_string.h | 5 | ||||
-rw-r--r-- | sql/sql_table.cc | 67 | ||||
-rw-r--r-- | sql/sql_type.h | 12 |
7 files changed, 162 insertions, 19 deletions
diff --git a/mysql-test/main/column_compression.result b/mysql-test/main/column_compression.result index c783e7fd1e9..228b26dc67d 100644 --- a/mysql-test/main/column_compression.result +++ b/mysql-test/main/column_compression.result @@ -1486,3 +1486,19 @@ WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; COLUMN_TYPE varchar(1000) /*!100301 COMPRESSED*/ DROP TABLE t1; +# +# End of 10.3 tests +# +# +# Start of 10.5 tests +# +# +# MDEV-19727 Add Type_handler::Key_part_spec_init_ft +# +CREATE TABLE t1 (a VARCHAR(1000) COMPRESSED, FULLTEXT INDEX(a)); +ERROR HY000: Compressed column 'a' can't be used in key specification +CREATE TABLE t1 (a TEXT COMPRESSED, FULLTEXT INDEX(a)); +ERROR HY000: Compressed column 'a' can't be used in key specification +# +# End of 10.5 tests +# diff --git a/mysql-test/main/column_compression.test b/mysql-test/main/column_compression.test index c9d0014ab9e..183fc38151c 100644 --- a/mysql-test/main/column_compression.test +++ b/mysql-test/main/column_compression.test @@ -181,3 +181,32 @@ SHOW CREATE TABLE t1; SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'; DROP TABLE t1; + +--echo # +--echo # End of 10.3 tests +--echo # + + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-19727 Add Type_handler::Key_part_spec_init_ft +--echo # + +# +# Indexes on COMPRESSED columns are generally prohibited, so we don't have +# to override Type_handler_xxx_compressed::Key_part_spec_init_ft(). +# Note, we could support FULLTEXT indexes on compressed columns eventually. +# + +--error ER_COMPRESSED_COLUMN_USED_AS_KEY +CREATE TABLE t1 (a VARCHAR(1000) COMPRESSED, FULLTEXT INDEX(a)); + +--error ER_COMPRESSED_COLUMN_USED_AS_KEY +CREATE TABLE t1 (a TEXT COMPRESSED, FULLTEXT INDEX(a)); + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/main/type_varchar.result b/mysql-test/main/type_varchar.result index 8911d36a020..214fb0a5b0f 100644 --- a/mysql-test/main/type_varchar.result +++ b/mysql-test/main/type_varchar.result @@ -723,3 +723,32 @@ SET sql_mode=DEFAULT; # # End of 10.4 tests # +# +# Start of 10.5 tests +# +# +# MDEV-15592 Column COMPRESSED should select a 'high order' datatype +# +TRUNCATE TABLE vchar; +SHOW CREATE TABLE vchar; +Table Create Table +vchar CREATE TABLE `vchar` ( + `v` varchar(30)/*old*/ DEFAULT NULL, + `c` char(3) DEFAULT NULL, + `e` enum('abc','def','ghi') DEFAULT NULL, + `t` text DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE vchar ADD FULLTEXT INDEX(v); +SHOW CREATE TABLE vchar; +Table Create Table +vchar CREATE TABLE `vchar` ( + `v` varchar(30) DEFAULT NULL, + `c` char(3) DEFAULT NULL, + `e` enum('abc','def','ghi') DEFAULT NULL, + `t` text DEFAULT NULL, + FULLTEXT KEY `v` (`v`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE vchar; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/type_varchar.test b/mysql-test/main/type_varchar.test index 86f16afc56f..ab02549394a 100644 --- a/mysql-test/main/type_varchar.test +++ b/mysql-test/main/type_varchar.test @@ -359,3 +359,26 @@ SET sql_mode=DEFAULT; --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-15592 Column COMPRESSED should select a 'high order' datatype +--echo # + +# +# Old VARCHAR is automatically upgraded to new VARCHAR. +# So we don't have to override Type_handler_var_string::Key_part_spec_init_ft() +# +copy_file $MYSQL_TEST_DIR/std_data/vchar.frm $MYSQLD_DATADIR/test/vchar.frm; +TRUNCATE TABLE vchar; +SHOW CREATE TABLE vchar; +ALTER TABLE vchar ADD FULLTEXT INDEX(v); +SHOW CREATE TABLE vchar; +DROP TABLE vchar; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/sql/sql_string.h b/sql/sql_string.h index caefee7ec09..3c112c94fe9 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -138,6 +138,11 @@ public: CHARSET_INFO *charset() const { return m_charset; } uint mbminlen() const { return m_charset->mbminlen; } uint mbmaxlen() const { return m_charset->mbmaxlen; } + bool is_good_for_ft() const + { + // Binary and UCS2/UTF16/UTF32 are not supported + return m_charset != &my_charset_bin && m_charset->mbminlen == 1; + } size_t numchars(const char *str, const char *end) const { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a5c6f1336c5..65de2ff6b11 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3361,6 +3361,45 @@ mysql_add_invisible_index(THD *thd, List<Key> *key_list, key_list->push_back(key, thd->mem_root); return key; } + + +bool Type_handler_string::Key_part_spec_init_ft(Key_part_spec *part, + const Column_definition &def) + const +{ + /* + Set length to 0. It's set to the real column width later for CHAR. + It has to be the correct col width for CHAR, as its data are not + prefixed with length (unlike blobs). + */ + part->length= 0; + return !Charset(def.charset).is_good_for_ft(); +} + + +bool Type_handler_varchar::Key_part_spec_init_ft(Key_part_spec *part, + const Column_definition &def) + const +{ + part->length= 0; + return !Charset(def.charset).is_good_for_ft(); +} + + +bool +Type_handler_blob_common::Key_part_spec_init_ft(Key_part_spec *part, + const Column_definition &def) + const +{ + /* + Set keyseg length to 1 for blobs. + It's ignored in ft code: the data length is taken from the length prefix. + */ + part->length= 1; + return !Charset(def.charset).is_good_for_ft(); +} + + /* Preparation for table creation @@ -3894,28 +3933,18 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, cols2.rewind(); if (key->type == Key::FULLTEXT) { - if ((sql_field->real_field_type() != MYSQL_TYPE_STRING && - sql_field->real_field_type() != MYSQL_TYPE_VARCHAR && - !f_is_blob(sql_field->pack_flag)) || - sql_field->charset == &my_charset_bin || - sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet - (ft_key_charset && sql_field->charset != ft_key_charset)) - { - my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name.str); - DBUG_RETURN(-1); - } - ft_key_charset=sql_field->charset; - /* - for fulltext keys keyseg length is 1 for blobs (it's ignored in ft - code anyway, and 0 (set to column width later) for char's. it has - to be correct col width for char's, as char data are not prefixed - with length (unlike blobs, where ft code takes data length from a - data prefix, ignoring column->length). - */ - column->length= MY_TEST(f_is_blob(sql_field->pack_flag)); + if (sql_field->type_handler()->Key_part_spec_init_ft(column, + *sql_field) || + (ft_key_charset && sql_field->charset != ft_key_charset)) + { + my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name.str); + DBUG_RETURN(-1); + } + ft_key_charset=sql_field->charset; } else { + column->length*= sql_field->charset->mbmaxlen; if (key->type == Key::SPATIAL) diff --git a/sql/sql_type.h b/sql/sql_type.h index 7daefcb10d7..0376cd84443 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -34,6 +34,7 @@ C_MODE_END class Field; class Column_definition; class Column_definition_attributes; +class Key_part_spec; class Item; class Item_const; class Item_literal; @@ -3456,6 +3457,11 @@ public: virtual bool Column_definition_prepare_stage2(Column_definition *c, handler *file, ulonglong table_flags) const= 0; + virtual bool Key_part_spec_init_ft(Key_part_spec *part, + const Column_definition &def) const + { + return true; // Error + } virtual Field *make_table_field(const LEX_CSTRING *name, const Record_addr &addr, const Type_all_attributes &attr, @@ -6002,6 +6008,8 @@ public: bool Column_definition_prepare_stage2(Column_definition *c, handler *file, ulonglong table_flags) const; + bool Key_part_spec_init_ft(Key_part_spec *part, + const Column_definition &def) const; Field *make_table_field(const LEX_CSTRING *name, const Record_addr &addr, const Type_all_attributes &attr, @@ -6084,6 +6092,8 @@ public: bool Column_definition_prepare_stage2(Column_definition *c, handler *file, ulonglong table_flags) const; + bool Key_part_spec_init_ft(Key_part_spec *part, + const Column_definition &def) const; Field *make_table_field(const LEX_CSTRING *name, const Record_addr &addr, const Type_all_attributes &attr, @@ -6157,6 +6167,8 @@ public: bool Column_definition_prepare_stage2(Column_definition *c, handler *file, ulonglong table_flags) const; + bool Key_part_spec_init_ft(Key_part_spec *part, + const Column_definition &def) const; bool Item_hybrid_func_fix_attributes(THD *thd, const char *name, Type_handler_hybrid_field_type *, |