Commit f42bda6d authored by Alexander Barkov's avatar Alexander Barkov

MDEV-19727 Add Type_handler::Key_part_spec_init_ft

parent 16366564
......@@ -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
#
......@@ -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 #
......@@ -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
#
......@@ -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 #
......@@ -138,6 +138,11 @@ class Charset
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
{
......
......@@ -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)
......
......@@ -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 @@ class Type_handler
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 @@ class Type_handler_string: public Type_handler_longstr
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 @@ class Type_handler_varchar: public Type_handler_longstr
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 @@ class Type_handler_blob_common: public Type_handler_longstr
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 *,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment