Commit 983fe77c authored by Jacob Mathew's avatar Jacob Mathew

Adding Full Text Search support to partitions.

Contains Spiral patches:
- Spiral Patch 007: 007_mariadb-10.2.0.partition_fulltext.diff  MDEV-7705
- Spiral Patch 038: 038_mariadb-10.2.0.partition_fulltext2.diff MDEV-7734

- This commit has the following differences compared to the original patches:
  - Added necessary full text search cleanup at the storage engine layer
    that was omitted in the original patch.
  - Added test case.
parent bb0e6753
This diff is collapsed.
......@@ -31,6 +31,18 @@ enum partition_keywords
#define PARTITION_BYTES_IN_POS 2
class ha_partition;
/* Partition Full Text Search info */
struct st_partition_ft_info
{
struct _ft_vft *please;
st_partition_ft_info *next;
ha_partition *file;
FT_INFO **part_ft_info;
};
typedef struct st_partition_bulk_access_info
{
uint sequence_num;
......@@ -1032,7 +1044,7 @@ class ha_partition :public handler
special file for handling names of partitions, engine types.
HA_REC_NOT_IN_SEQ is always set for partition handler since we cannot
guarantee that the records will be returned in sequence.
HA_CAN_FULLTEXT, HA_DUPLICATE_POS,
HA_DUPLICATE_POS,
HA_CAN_INSERT_DELAYED, HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is disabled
until further investigated.
*/
......@@ -1245,14 +1257,20 @@ class ha_partition :public handler
-------------------------------------------------------------------------
MODULE fulltext index
-------------------------------------------------------------------------
Fulltext stuff not yet.
-------------------------------------------------------------------------
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
virtual FT_INFO *ft_init_ext(uint flags,uint inx,const uchar *key,
uint keylen)
{ return NULL; }
virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
*/
st_partition_ft_info *ft_first;
st_partition_ft_info *ft_current;
bool m_ft_init_and_first;
virtual float ft_find_relevance(FT_INFO *handler,
uchar *record, uint length);
virtual float ft_get_relevance(FT_INFO *handler);
void ft_close_search(FT_INFO *handler);
virtual int ft_init();
virtual int pre_ft_init();
virtual void ft_end();
virtual int pre_ft_end();
virtual FT_INFO *ft_init_ext(uint flags, uint inx, String *key);
virtual int ft_read(uchar *buf);
/*
-------------------------------------------------------------------------
......
......@@ -3266,7 +3266,9 @@ class handler :public Sql_alloc
int compare_key(key_range *range);
int compare_key2(key_range *range);
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
void ft_end() { ft_handler=NULL; }
virtual int pre_ft_init() { return HA_ERR_WRONG_COMMAND; }
virtual void ft_end() { ha_ft_end(); }
virtual int pre_ft_end() { return 0; }
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
{ return NULL; }
private:
......@@ -3289,6 +3291,7 @@ class handler :public Sql_alloc
/* Same as above, but with statistics */
inline int ha_ft_read(uchar *buf);
inline void ha_ft_end() { ft_handler=NULL; }
int ha_rnd_next(uchar *buf);
int ha_rnd_pos(uchar *buf, uchar *pos);
inline int ha_rnd_pos_by_record(uchar *buf);
......
......@@ -11005,6 +11005,8 @@ ha_innobase::ft_end()
ib::info() << "ft_end()";
rnd_end();
ha_ft_end();
}
#ifdef WITH_WSREP
extern dict_index_t*
......
......@@ -7893,6 +7893,7 @@ void ha_spider::ft_end()
store_error_num = index_end();
}
ft_init_without_index_init = FALSE;
ha_ft_end();
DBUG_VOID_RETURN;
}
......
--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP
--let $MASTER_1_COMMENT_2_2= $MASTER_1_COMMENT_2_2_BACKUP
--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
--let $CHILD2_2_DROP_TABLES= $CHILD2_2_DROP_TABLES_BACKUP
--let $CHILD2_2_CREATE_TABLES= $CHILD2_2_CREATE_TABLES_BACKUP
--let $CHILD2_2_SELECT_TABLES= $CHILD2_2_SELECT_TABLES_BACKUP
--let $CHILD2_3_DROP_TABLES= $CHILD2_3_DROP_TABLES_BACKUP
--let $CHILD2_3_CREATE_TABLES= $CHILD2_3_CREATE_TABLES_BACKUP
--let $CHILD2_3_SELECT_TABLES= $CHILD2_3_SELECT_TABLES_BACKUP
--let $OUTPUT_CHILD_GROUP2= $OUTPUT_CHILD_GROUP2_BACKUP
--let $USE_GENERAL_LOG= $USE_GENERAL_LOG_BACKUP
--connection master_1
set session join_cache_level= @old_join_cache_level;
set session optimizer_switch= @old_optimizer_switch;
--disable_warnings
--disable_query_log
--disable_result_log
--source ../t/test_deinit.inc
--enable_result_log
--enable_query_log
--enable_warnings
--disable_warnings
--disable_query_log
--disable_result_log
--source ../t/test_init.inc
--enable_result_log
--enable_query_log
--enable_warnings
--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1
let $MASTER_1_COMMENT_2_1=
COMMENT='table "tbl_a", bka_mode "1"'
PARTITION BY KEY(pkey) (
PARTITION pt1 COMMENT='srv "s_2_1"',
PARTITION pt2 COMMENT='srv "s_2_2"',
PARTITION pt3 COMMENT='srv "s_2_3"'
);
--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
let $CHILD2_1_DROP_TABLES=
DROP TABLE IF EXISTS tbl_a;
--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
let $CHILD2_1_CREATE_TABLES=
CREATE TABLE tbl_a (
pkey int NOT NULL,
words text NOT NULL,
PRIMARY KEY (pkey),
FULLTEXT (words)
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
let $CHILD2_1_SELECT_TABLES=
SELECT pkey FROM tbl_a ORDER BY pkey;
let $CHILD2_1_SELECT_ARGUMENT1=
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
--let $CHILD2_2_DROP_TABLES_BACKUP= $CHILD2_2_DROP_TABLES
let $CHILD2_2_DROP_TABLES=
DROP TABLE IF EXISTS tbl_a;
--let $CHILD2_2_CREATE_TABLES_BACKUP= $CHILD2_2_CREATE_TABLES
let $CHILD2_2_CREATE_TABLES=
CREATE TABLE tbl_a (
pkey int NOT NULL,
words text NOT NULL,
PRIMARY KEY (pkey),
FULLTEXT (words)
) $CHILD2_2_ENGINE $CHILD2_2_CHARSET;
--let $CHILD2_2_SELECT_TABLES_BACKUP= $CHILD2_2_SELECT_TABLES
let $CHILD2_2_SELECT_TABLES=
SELECT pkey FROM tbl_a ORDER BY pkey;
let $CHILD2_2_SELECT_ARGUMENT1=
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
--let $CHILD2_3_DROP_TABLES_BACKUP= $CHILD2_3_DROP_TABLES
let $CHILD2_3_DROP_TABLES=
DROP TABLE IF EXISTS tbl_a;
--let $CHILD2_3_CREATE_TABLES_BACKUP= $CHILD2_3_CREATE_TABLES
let $CHILD2_3_CREATE_TABLES=
CREATE TABLE tbl_a (
pkey int NOT NULL,
words text NOT NULL,
PRIMARY KEY (pkey),
FULLTEXT (words)
) $CHILD2_3_ENGINE $CHILD2_3_CHARSET;
--let $CHILD2_3_SELECT_TABLES_BACKUP= $CHILD2_3_SELECT_TABLES
let $CHILD2_3_SELECT_TABLES=
SELECT pkey FROM tbl_a ORDER BY pkey;
let $CHILD2_3_SELECT_ARGUMENT1=
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
--let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2
--let $OUTPUT_CHILD_GROUP2= 1
--let $USE_GENERAL_LOG_BACKUP= $USE_GENERAL_LOG
--let $USE_GENERAL_LOG= 1
--connection master_1
set @old_join_cache_level= @@join_cache_level;
set session join_cache_level= 5;
set @old_optimizer_switch= @@optimizer_switch;
set session optimizer_switch= 'mrr=on';
for master_1
for child2
child2_1
child2_2
child2_3
for child3
child3_1
child3_2
child3_3
connection master_1;
set @old_join_cache_level= @@join_cache_level;
set session join_cache_level= 5;
set @old_optimizer_switch= @@optimizer_switch;
set session optimizer_switch= 'mrr=on';
drop and create databases
connection master_1;
DROP DATABASE IF EXISTS auto_test_local;
CREATE DATABASE auto_test_local;
USE auto_test_local;
connection child2_1;
SET @old_log_output = @@global.log_output;
SET GLOBAL log_output = 'TABLE,FILE';
DROP DATABASE IF EXISTS auto_test_remote;
CREATE DATABASE auto_test_remote;
USE auto_test_remote;
connection child2_2;
SET @old_log_output = @@global.log_output;
SET GLOBAL log_output = 'TABLE,FILE';
DROP DATABASE IF EXISTS auto_test_remote2;
CREATE DATABASE auto_test_remote2;
USE auto_test_remote2;
connection child2_3;
SET @old_log_output = @@global.log_output;
SET GLOBAL log_output = 'TABLE,FILE';
DROP DATABASE IF EXISTS auto_test_remote3;
CREATE DATABASE auto_test_remote3;
USE auto_test_remote3;
create table and insert
connection child2_1;
CHILD2_1_DROP_TABLES
CHILD2_1_CREATE_TABLES
TRUNCATE TABLE mysql.general_log;
connection child2_2;
CHILD2_2_DROP_TABLES
CHILD2_2_CREATE_TABLES
TRUNCATE TABLE mysql.general_log;
connection child2_3;
CHILD2_3_DROP_TABLES
CHILD2_3_CREATE_TABLES
TRUNCATE TABLE mysql.general_log;
connection master_1;
DROP TABLE IF EXISTS tbl_a;
DROP TABLE IF EXISTS tbl_b;
CREATE TABLE tbl_a (
pkey int NOT NULL,
words text NOT NULL,
PRIMARY KEY (pkey),
FULLTEXT (words)
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
INSERT INTO tbl_a (pkey, words) VALUES (0, 'abc'),(1, 'def'),(2, 'ghi'),(3, 'jkl'),(4, 'mno'),(5, 'pqr'),(6, 'stu'),(7, 'vwx');
select test
connection child2_1;
TRUNCATE TABLE mysql.general_log;
connection master_1;
SELECT pkey, words FROM tbl_a WHERE match(words) against('+ghi' in boolean mode);
pkey words
2 ghi
connection child2_1;
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
argument
select match(`words`)against('+ghi' in boolean mode),`pkey`,`words` from `auto_test_remote`.`tbl_a` where match(`words`)against('+ghi' in boolean mode) and (match(`words`)against('+ghi' in boolean mode))
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
SELECT pkey FROM tbl_a ORDER BY pkey;
pkey
4
5
connection child2_2;
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
argument
select match(`words`)against('+ghi' in boolean mode),`pkey`,`words` from `auto_test_remote2`.`tbl_a` where match(`words`)against('+ghi' in boolean mode) and (match(`words`)against('+ghi' in boolean mode))
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
SELECT pkey FROM tbl_a ORDER BY pkey;
pkey
0
1
6
7
connection child2_3;
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
argument
select match(`words`)against('+ghi' in boolean mode),`pkey`,`words` from `auto_test_remote3`.`tbl_a` where match(`words`)against('+ghi' in boolean mode) and (match(`words`)against('+ghi' in boolean mode))
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
SELECT pkey FROM tbl_a ORDER BY pkey;
pkey
2
3
deinit
connection master_1;
DROP DATABASE IF EXISTS auto_test_local;
connection child2_1;
DROP DATABASE IF EXISTS auto_test_remote;
SET GLOBAL log_output = @old_log_output;
connection child2_2;
DROP DATABASE IF EXISTS auto_test_remote2;
SET GLOBAL log_output = @old_log_output;
connection child2_3;
DROP DATABASE IF EXISTS auto_test_remote3;
SET GLOBAL log_output = @old_log_output;
connection master_1;
set session join_cache_level= @old_join_cache_level;
set session optimizer_switch= @old_optimizer_switch;
for master_1
for child2
child2_1
child2_2
child2_3
for child3
child3_1
child3_2
child3_3
end of test
--source ../include/partition_fulltext_init.inc
if (!$HAVE_PARTITION)
{
--source ../include/partition_fulltext_deinit.inc
skip Test requires partitioning;
}
--echo
--echo drop and create databases
--connection master_1
--disable_warnings
DROP DATABASE IF EXISTS auto_test_local;
CREATE DATABASE auto_test_local;
USE auto_test_local;
if ($USE_CHILD_GROUP2)
{
--connection child2_1
if ($USE_GENERAL_LOG)
{
SET @old_log_output = @@global.log_output;
SET GLOBAL log_output = 'TABLE,FILE';
}
DROP DATABASE IF EXISTS auto_test_remote;
CREATE DATABASE auto_test_remote;
USE auto_test_remote;
--connection child2_2
if ($USE_GENERAL_LOG)
{
SET @old_log_output = @@global.log_output;
SET GLOBAL log_output = 'TABLE,FILE';
}
DROP DATABASE IF EXISTS auto_test_remote2;
CREATE DATABASE auto_test_remote2;
USE auto_test_remote2;
--connection child2_3
if ($USE_GENERAL_LOG)
{
SET @old_log_output = @@global.log_output;
SET GLOBAL log_output = 'TABLE,FILE';
}
DROP DATABASE IF EXISTS auto_test_remote3;
CREATE DATABASE auto_test_remote3;
USE auto_test_remote3;
}
--enable_warnings
--echo
--echo create table and insert
if ($USE_CHILD_GROUP2)
{
if (!$OUTPUT_CHILD_GROUP2)
{
--disable_query_log
--disable_result_log
}
--connection child2_1
if ($OUTPUT_CHILD_GROUP2)
{
--disable_query_log
echo CHILD2_1_DROP_TABLES;
echo CHILD2_1_CREATE_TABLES;
}
--disable_warnings
eval $CHILD2_1_DROP_TABLES;
--enable_warnings
eval $CHILD2_1_CREATE_TABLES;
if ($OUTPUT_CHILD_GROUP2)
{
--enable_query_log
}
if ($USE_GENERAL_LOG)
{
TRUNCATE TABLE mysql.general_log;
}
--connection child2_2
if ($OUTPUT_CHILD_GROUP2)
{
--disable_query_log
echo CHILD2_2_DROP_TABLES;
echo CHILD2_2_CREATE_TABLES;
}
--disable_warnings
eval $CHILD2_2_DROP_TABLES;
--enable_warnings
eval $CHILD2_2_CREATE_TABLES;
if ($OUTPUT_CHILD_GROUP2)
{
--enable_query_log
}
if ($USE_GENERAL_LOG)
{
TRUNCATE TABLE mysql.general_log;
}
--connection child2_3
if ($OUTPUT_CHILD_GROUP2)
{
--disable_query_log
echo CHILD2_3_DROP_TABLES;
echo CHILD2_3_CREATE_TABLES;
}
--disable_warnings
eval $CHILD2_3_DROP_TABLES;
--enable_warnings
eval $CHILD2_3_CREATE_TABLES;
if ($OUTPUT_CHILD_GROUP2)
{
--enable_query_log
}
if ($USE_GENERAL_LOG)
{
TRUNCATE TABLE mysql.general_log;
}
if (!$OUTPUT_CHILD_GROUP2)
{
--enable_query_log
--enable_result_log
}
}
--connection master_1
--disable_warnings
DROP TABLE IF EXISTS tbl_a;
DROP TABLE IF EXISTS tbl_b;
--enable_warnings
--disable_query_log
echo CREATE TABLE tbl_a (
pkey int NOT NULL,
words text NOT NULL,
PRIMARY KEY (pkey),
FULLTEXT (words)
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
eval CREATE TABLE tbl_a (
pkey int NOT NULL,
words text NOT NULL,
PRIMARY KEY (pkey),
FULLTEXT (words)
) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
--enable_query_log
INSERT INTO tbl_a (pkey, words) VALUES (0, 'abc'),(1, 'def'),(2, 'ghi'),(3, 'jkl'),(4, 'mno'),(5, 'pqr'),(6, 'stu'),(7, 'vwx');
--echo
--echo select test
if ($USE_CHILD_GROUP2)
{
if (!$OUTPUT_CHILD_GROUP2)
{
--disable_query_log
--disable_result_log
}
--connection child2_1
if ($USE_GENERAL_LOG)
{
TRUNCATE TABLE mysql.general_log;
}
if (!$OUTPUT_CHILD_GROUP2)
{
--enable_query_log
--enable_result_log
}
}
--connection master_1
SELECT pkey, words FROM tbl_a WHERE match(words) against('+ghi' in boolean mode);
if ($USE_CHILD_GROUP2)
{
if (!$OUTPUT_CHILD_GROUP2)
{
--disable_query_log
--disable_result_log
}
--connection child2_1
if ($USE_GENERAL_LOG)
{
eval $CHILD2_1_SELECT_ARGUMENT1;
}
eval $CHILD2_1_SELECT_TABLES;
--connection child2_2
if ($USE_GENERAL_LOG)
{
eval $CHILD2_2_SELECT_ARGUMENT1;
}
eval $CHILD2_2_SELECT_TABLES;
--connection child2_3
if ($USE_GENERAL_LOG)
{
eval $CHILD2_3_SELECT_ARGUMENT1;
}
eval $CHILD2_3_SELECT_TABLES;
if (!$OUTPUT_CHILD_GROUP2)
{
--enable_query_log
--enable_result_log
}
}
--echo
--echo deinit
--disable_warnings
--connection master_1
DROP DATABASE IF EXISTS auto_test_local;
if ($USE_CHILD_GROUP2)
{
--connection child2_1
DROP DATABASE IF EXISTS auto_test_remote;
if ($USE_GENERAL_LOG)
{
SET GLOBAL log_output = @old_log_output;
}
--connection child2_2
DROP DATABASE IF EXISTS auto_test_remote2;
if ($USE_GENERAL_LOG)
{
SET GLOBAL log_output = @old_log_output;
}
--connection child2_3
DROP DATABASE IF EXISTS auto_test_remote3;
if ($USE_GENERAL_LOG)
{
SET GLOBAL log_output = @old_log_output;
}
}
--enable_warnings
--source ../include/partition_fulltext_deinit.inc
--echo
--echo end of test
......@@ -10824,6 +10824,8 @@ ha_innobase::ft_end()
fprintf(stderr, "ft_end()\n");
rnd_end();
ha_ft_end();
}
#ifdef WITH_WSREP
extern dict_index_t*
......
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