mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Adding Full Text Search support to partitions
Contains Spiral patches: 007_mariadb-10.2.0.partition_fulltext.diff MDEV-7705 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. - A lot of code cleanups to make the code notable smaller. - Changed SQL code to use ha_ft_end() instead of ft_end() Original author: Kentoku SHIBA First reviewer: Jacob Mathew Second reviewer: Michael Widenius
This commit is contained in:
@@ -74,7 +74,6 @@
|
|||||||
HA_REC_NOT_IN_SEQ | \
|
HA_REC_NOT_IN_SEQ | \
|
||||||
HA_CAN_REPAIR)
|
HA_CAN_REPAIR)
|
||||||
#define PARTITION_DISABLED_TABLE_FLAGS (HA_CAN_GEOMETRY | \
|
#define PARTITION_DISABLED_TABLE_FLAGS (HA_CAN_GEOMETRY | \
|
||||||
HA_CAN_FULLTEXT | \
|
|
||||||
HA_DUPLICATE_POS | \
|
HA_DUPLICATE_POS | \
|
||||||
HA_CAN_INSERT_DELAYED | \
|
HA_CAN_INSERT_DELAYED | \
|
||||||
HA_READ_BEFORE_WRITE_REMOVAL |\
|
HA_READ_BEFORE_WRITE_REMOVAL |\
|
||||||
@@ -126,7 +125,6 @@ static void init_partition_psi_keys(void)
|
|||||||
|
|
||||||
static int partition_initialize(void *p)
|
static int partition_initialize(void *p)
|
||||||
{
|
{
|
||||||
|
|
||||||
handlerton *partition_hton;
|
handlerton *partition_hton;
|
||||||
partition_hton= (handlerton *)p;
|
partition_hton= (handlerton *)p;
|
||||||
|
|
||||||
@@ -245,12 +243,19 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share)
|
|||||||
:handler(hton, share)
|
:handler(hton, share)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("ha_partition::ha_partition(table)");
|
DBUG_ENTER("ha_partition::ha_partition(table)");
|
||||||
init_alloc_root(&m_mem_root, 512, 512, MYF(0));
|
ha_partition_init();
|
||||||
init_handler_variables();
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize all partition variables */
|
||||||
|
|
||||||
|
void ha_partition::ha_partition_init()
|
||||||
|
{
|
||||||
|
init_alloc_root(&m_mem_root, 512, 512, MYF(0));
|
||||||
|
init_handler_variables();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Constructor method
|
Constructor method
|
||||||
|
|
||||||
@@ -267,8 +272,7 @@ ha_partition::ha_partition(handlerton *hton, partition_info *part_info)
|
|||||||
{
|
{
|
||||||
DBUG_ENTER("ha_partition::ha_partition(part_info)");
|
DBUG_ENTER("ha_partition::ha_partition(part_info)");
|
||||||
DBUG_ASSERT(part_info);
|
DBUG_ASSERT(part_info);
|
||||||
init_alloc_root(&m_mem_root, 512, 512, MYF(0));
|
ha_partition_init();
|
||||||
init_handler_variables();
|
|
||||||
m_part_info= part_info;
|
m_part_info= part_info;
|
||||||
m_create_handler= TRUE;
|
m_create_handler= TRUE;
|
||||||
m_is_sub_partitioned= m_part_info->is_sub_partitioned();
|
m_is_sub_partitioned= m_part_info->is_sub_partitioned();
|
||||||
@@ -294,8 +298,7 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share,
|
|||||||
:handler(hton, share)
|
:handler(hton, share)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("ha_partition::ha_partition(clone)");
|
DBUG_ENTER("ha_partition::ha_partition(clone)");
|
||||||
init_alloc_root(&m_mem_root, 512, 512, MYF(0));
|
ha_partition_init();
|
||||||
init_handler_variables();
|
|
||||||
m_part_info= part_info_arg;
|
m_part_info= part_info_arg;
|
||||||
m_create_handler= TRUE;
|
m_create_handler= TRUE;
|
||||||
m_is_sub_partitioned= m_part_info->is_sub_partitioned();
|
m_is_sub_partitioned= m_part_info->is_sub_partitioned();
|
||||||
@@ -383,6 +386,9 @@ void ha_partition::init_handler_variables()
|
|||||||
m_pre_calling= FALSE;
|
m_pre_calling= FALSE;
|
||||||
m_pre_call_use_parallel= FALSE;
|
m_pre_call_use_parallel= FALSE;
|
||||||
|
|
||||||
|
ft_first= ft_current= NULL;
|
||||||
|
bulk_access_executing= FALSE; // For future
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Clear bitmaps to allow on one to call my_bitmap_free() on them at any time
|
Clear bitmaps to allow on one to call my_bitmap_free() on them at any time
|
||||||
*/
|
*/
|
||||||
@@ -3759,14 +3765,20 @@ int ha_partition::close(void)
|
|||||||
bool first= TRUE;
|
bool first= TRUE;
|
||||||
handler **file;
|
handler **file;
|
||||||
uint i;
|
uint i;
|
||||||
|
st_partition_ft_info *tmp_ft_info;
|
||||||
DBUG_ENTER("ha_partition::close");
|
DBUG_ENTER("ha_partition::close");
|
||||||
|
|
||||||
DBUG_ASSERT(table->s == table_share);
|
DBUG_ASSERT(table->s == table_share);
|
||||||
DBUG_ASSERT(m_part_info);
|
DBUG_ASSERT(m_part_info);
|
||||||
|
|
||||||
destroy_record_priority_queue();
|
destroy_record_priority_queue();
|
||||||
free_partition_bitmaps();
|
free_partition_bitmaps();
|
||||||
|
|
||||||
|
for (; ft_first ; ft_first= tmp_ft_info)
|
||||||
|
{
|
||||||
|
tmp_ft_info= ft_first->next;
|
||||||
|
my_free(ft_first);
|
||||||
|
}
|
||||||
|
|
||||||
/* Free active mrr_ranges */
|
/* Free active mrr_ranges */
|
||||||
for (i= 0; i < m_tot_parts; i++)
|
for (i= 0; i < m_tot_parts; i++)
|
||||||
{
|
{
|
||||||
@@ -6460,6 +6472,450 @@ int ha_partition::multi_range_read_explain_info(uint mrr_mode, char *str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find and retrieve the Full Text Search relevance ranking for a search string
|
||||||
|
in a full text index.
|
||||||
|
|
||||||
|
@param handler Full Text Search handler
|
||||||
|
@param record Search string
|
||||||
|
@param length Length of the search string
|
||||||
|
|
||||||
|
@retval Relevance value
|
||||||
|
*/
|
||||||
|
|
||||||
|
float partition_ft_find_relevance(FT_INFO *handler,
|
||||||
|
uchar *record, uint length)
|
||||||
|
{
|
||||||
|
st_partition_ft_info *info= (st_partition_ft_info *)handler;
|
||||||
|
uint m_last_part= ((ha_partition*) info->file)->last_part();
|
||||||
|
FT_INFO *m_handler= info->part_ft_info[m_last_part];
|
||||||
|
DBUG_ENTER("partition_ft_find_relevance");
|
||||||
|
if (!m_handler)
|
||||||
|
DBUG_RETURN((float)-1.0);
|
||||||
|
DBUG_RETURN(m_handler->please->find_relevance(m_handler, record, length));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieve the Full Text Search relevance ranking for the current
|
||||||
|
full text search.
|
||||||
|
|
||||||
|
@param handler Full Text Search handler
|
||||||
|
|
||||||
|
@retval Relevance value
|
||||||
|
*/
|
||||||
|
|
||||||
|
float partition_ft_get_relevance(FT_INFO *handler)
|
||||||
|
{
|
||||||
|
st_partition_ft_info *info= (st_partition_ft_info *)handler;
|
||||||
|
uint m_last_part= ((ha_partition*) info->file)->last_part();
|
||||||
|
FT_INFO *m_handler= info->part_ft_info[m_last_part];
|
||||||
|
DBUG_ENTER("partition_ft_get_relevance");
|
||||||
|
if (!m_handler)
|
||||||
|
DBUG_RETURN((float)-1.0);
|
||||||
|
DBUG_RETURN(m_handler->please->get_relevance(m_handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free the memory for a full text search handler.
|
||||||
|
|
||||||
|
@param handler Full Text Search handler
|
||||||
|
*/
|
||||||
|
|
||||||
|
void partition_ft_close_search(FT_INFO *handler)
|
||||||
|
{
|
||||||
|
st_partition_ft_info *info= (st_partition_ft_info *)handler;
|
||||||
|
info->file->ft_close_search(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free the memory for a full text search handler.
|
||||||
|
|
||||||
|
@param handler Full Text Search handler
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ha_partition::ft_close_search(FT_INFO *handler)
|
||||||
|
{
|
||||||
|
uint i;
|
||||||
|
st_partition_ft_info *info= (st_partition_ft_info *)handler;
|
||||||
|
DBUG_ENTER("ha_partition::ft_close_search");
|
||||||
|
|
||||||
|
for (i= 0; i < m_tot_parts; i++)
|
||||||
|
{
|
||||||
|
FT_INFO *m_handler= info->part_ft_info[i];
|
||||||
|
DBUG_ASSERT(!m_handler ||
|
||||||
|
(m_handler->please && m_handler->please->close_search));
|
||||||
|
if (m_handler &&
|
||||||
|
m_handler->please &&
|
||||||
|
m_handler->please->close_search)
|
||||||
|
m_handler->please->close_search(m_handler);
|
||||||
|
}
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Partition Full Text search function table */
|
||||||
|
_ft_vft partition_ft_vft =
|
||||||
|
{
|
||||||
|
NULL, // partition_ft_read_next
|
||||||
|
partition_ft_find_relevance,
|
||||||
|
partition_ft_close_search,
|
||||||
|
partition_ft_get_relevance,
|
||||||
|
NULL // partition_ft_reinit_search
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize a full text search.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ha_partition::ft_init()
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
uint i= 0;
|
||||||
|
uint32 part_id;
|
||||||
|
DBUG_ENTER("ha_partition::ft_init");
|
||||||
|
DBUG_PRINT("info", ("partition this: %p", this));
|
||||||
|
|
||||||
|
/*
|
||||||
|
For operations that may need to change data, we may need to extend
|
||||||
|
read_set.
|
||||||
|
*/
|
||||||
|
if (get_lock_type() == F_WRLCK)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If write_set contains any of the fields used in partition and
|
||||||
|
subpartition expression, we need to set all bits in read_set because
|
||||||
|
the row may need to be inserted in a different [sub]partition. In
|
||||||
|
other words update_row() can be converted into write_row(), which
|
||||||
|
requires a complete record.
|
||||||
|
*/
|
||||||
|
if (bitmap_is_overlapping(&m_part_info->full_part_field_set,
|
||||||
|
table->write_set))
|
||||||
|
bitmap_set_all(table->read_set);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Some handlers only read fields as specified by the bitmap for the
|
||||||
|
read set. For partitioned handlers we always require that the
|
||||||
|
fields of the partition functions are read such that we can
|
||||||
|
calculate the partition id to place updated and deleted records.
|
||||||
|
*/
|
||||||
|
bitmap_union(table->read_set, &m_part_info->full_part_field_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we see what the index of our first important partition is */
|
||||||
|
DBUG_PRINT("info", ("m_part_info->read_partitions: %p",
|
||||||
|
(void *) m_part_info->read_partitions.bitmap));
|
||||||
|
part_id= bitmap_get_first_set(&(m_part_info->read_partitions));
|
||||||
|
DBUG_PRINT("info", ("m_part_spec.start_part %d", part_id));
|
||||||
|
|
||||||
|
if (part_id == MY_BIT_NONE)
|
||||||
|
{
|
||||||
|
error= 0;
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("ft_init on partition %d", part_id));
|
||||||
|
/*
|
||||||
|
ft_end() is needed for partitioning to reset internal data if scan
|
||||||
|
is already in use
|
||||||
|
*/
|
||||||
|
if (m_pre_calling)
|
||||||
|
{
|
||||||
|
if ((error= pre_ft_end()))
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ft_end();
|
||||||
|
m_index_scan_type= partition_ft_read;
|
||||||
|
for (i= part_id; i < m_tot_parts; i++)
|
||||||
|
{
|
||||||
|
if (bitmap_is_set(&(m_part_info->read_partitions), i))
|
||||||
|
{
|
||||||
|
error= m_pre_calling ? m_file[i]->pre_ft_init() : m_file[i]->ft_init();
|
||||||
|
if (error)
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_scan_value= 1;
|
||||||
|
m_part_spec.start_part= part_id;
|
||||||
|
m_part_spec.end_part= m_tot_parts - 1;
|
||||||
|
m_ft_init_and_first= TRUE;
|
||||||
|
DBUG_PRINT("info", ("m_scan_value: %d", m_scan_value));
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
|
err2:
|
||||||
|
late_extra_no_cache(part_id);
|
||||||
|
while ((int)--i >= (int)part_id)
|
||||||
|
{
|
||||||
|
if (bitmap_is_set(&(m_part_info->read_partitions), i))
|
||||||
|
{
|
||||||
|
if (m_pre_calling)
|
||||||
|
m_file[i]->pre_ft_end();
|
||||||
|
else
|
||||||
|
m_file[i]->ft_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err1:
|
||||||
|
m_scan_value= 2;
|
||||||
|
m_part_spec.start_part= NO_CURRENT_PART_ID;
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize a full text search during a bulk access request.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ha_partition::pre_ft_init()
|
||||||
|
{
|
||||||
|
bool save_m_pre_calling;
|
||||||
|
int error;
|
||||||
|
DBUG_ENTER("ha_partition::pre_ft_init");
|
||||||
|
save_m_pre_calling= m_pre_calling;
|
||||||
|
m_pre_calling= TRUE;
|
||||||
|
error= ft_init();
|
||||||
|
m_pre_calling= save_m_pre_calling;
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Terminate a full text search.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ha_partition::ft_end()
|
||||||
|
{
|
||||||
|
handler **file;
|
||||||
|
DBUG_ENTER("ha_partition::ft_end");
|
||||||
|
DBUG_PRINT("info", ("partition this: %p", this));
|
||||||
|
|
||||||
|
switch (m_scan_value) {
|
||||||
|
case 2: // Error
|
||||||
|
break;
|
||||||
|
case 1: // Table scan
|
||||||
|
if (NO_CURRENT_PART_ID != m_part_spec.start_part)
|
||||||
|
late_extra_no_cache(m_part_spec.start_part);
|
||||||
|
file= m_file;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (bitmap_is_set(&(m_part_info->read_partitions), (uint)(file - m_file)))
|
||||||
|
{
|
||||||
|
if (m_pre_calling)
|
||||||
|
(*file)->pre_ft_end();
|
||||||
|
else
|
||||||
|
(*file)->ft_end();
|
||||||
|
}
|
||||||
|
} while (*(++file));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_scan_value= 2;
|
||||||
|
m_part_spec.start_part= NO_CURRENT_PART_ID;
|
||||||
|
ft_current= 0;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Terminate a full text search during a bulk access request.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ha_partition::pre_ft_end()
|
||||||
|
{
|
||||||
|
bool save_m_pre_calling;
|
||||||
|
DBUG_ENTER("ha_partition::pre_ft_end");
|
||||||
|
save_m_pre_calling= m_pre_calling;
|
||||||
|
m_pre_calling= TRUE;
|
||||||
|
ft_end();
|
||||||
|
m_pre_calling= save_m_pre_calling;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize a full text search using the extended API.
|
||||||
|
|
||||||
|
@param flags Search flags
|
||||||
|
@param inx Key number
|
||||||
|
@param key Key value
|
||||||
|
|
||||||
|
@return FT_INFO structure if successful
|
||||||
|
NULL otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
FT_INFO *ha_partition::ft_init_ext(uint flags, uint inx, String *key)
|
||||||
|
{
|
||||||
|
FT_INFO *ft_handler;
|
||||||
|
handler **file;
|
||||||
|
st_partition_ft_info *ft_target, **parent;
|
||||||
|
DBUG_ENTER("ha_partition::ft_init_ext");
|
||||||
|
|
||||||
|
if (ft_current)
|
||||||
|
parent= &ft_current->next;
|
||||||
|
else
|
||||||
|
parent= &ft_first;
|
||||||
|
|
||||||
|
if (!(ft_target= *parent))
|
||||||
|
{
|
||||||
|
FT_INFO **tmp_ft_info;
|
||||||
|
if (!(ft_target= (st_partition_ft_info *)
|
||||||
|
my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
|
||||||
|
&ft_target,
|
||||||
|
sizeof(st_partition_ft_info),
|
||||||
|
&tmp_ft_info,
|
||||||
|
sizeof(FT_INFO *) * m_tot_parts,
|
||||||
|
NullS)))
|
||||||
|
{
|
||||||
|
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
|
}
|
||||||
|
ft_target->part_ft_info= tmp_ft_info;
|
||||||
|
(*parent)= ft_target;
|
||||||
|
}
|
||||||
|
|
||||||
|
ft_current= ft_target;
|
||||||
|
file= m_file;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (bitmap_is_set(&(m_part_info->read_partitions), (uint)(file - m_file)))
|
||||||
|
{
|
||||||
|
if ((ft_handler= (*file)->ft_init_ext(flags, inx, key)))
|
||||||
|
(*file)->ft_handler= ft_handler;
|
||||||
|
else
|
||||||
|
(*file)->ft_handler= NULL;
|
||||||
|
ft_target->part_ft_info[file - m_file]= ft_handler;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*file)->ft_handler= NULL;
|
||||||
|
ft_target->part_ft_info[file - m_file]= NULL;
|
||||||
|
}
|
||||||
|
} while (*(++file));
|
||||||
|
|
||||||
|
ft_target->please= &partition_ft_vft;
|
||||||
|
ft_target->file= this;
|
||||||
|
DBUG_RETURN((FT_INFO*)ft_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the next record from the FT result set during an ordered index
|
||||||
|
pre-scan
|
||||||
|
|
||||||
|
@param use_parallel Is it a parallel search
|
||||||
|
|
||||||
|
@return >0 Error code
|
||||||
|
0 Success
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ha_partition::pre_ft_read(bool use_parallel)
|
||||||
|
{
|
||||||
|
bool save_m_pre_calling;
|
||||||
|
int error;
|
||||||
|
DBUG_ENTER("ha_partition::pre_ft_read");
|
||||||
|
DBUG_PRINT("info", ("partition this: %p", this));
|
||||||
|
save_m_pre_calling= m_pre_calling;
|
||||||
|
m_pre_calling= TRUE;
|
||||||
|
m_pre_call_use_parallel= use_parallel;
|
||||||
|
error= ft_read(table->record[0]);
|
||||||
|
m_pre_calling= save_m_pre_calling;
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the first or next record in a full text search.
|
||||||
|
|
||||||
|
@param buf Buffer where the record should be returned
|
||||||
|
|
||||||
|
@return >0 Error code
|
||||||
|
0 Success
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ha_partition::ft_read(uchar *buf)
|
||||||
|
{
|
||||||
|
handler *file;
|
||||||
|
int result= HA_ERR_END_OF_FILE, error;
|
||||||
|
uint part_id= m_part_spec.start_part;
|
||||||
|
DBUG_ENTER("ha_partition::ft_read");
|
||||||
|
DBUG_PRINT("info", ("partition this: %p", this));
|
||||||
|
DBUG_PRINT("info", ("part_id: %u", part_id));
|
||||||
|
|
||||||
|
if (part_id == NO_CURRENT_PART_ID)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The original set of partitions to scan was empty and thus we report
|
||||||
|
the result here.
|
||||||
|
*/
|
||||||
|
DBUG_PRINT("info", ("NO_CURRENT_PART_ID"));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_ASSERT(m_scan_value == 1);
|
||||||
|
|
||||||
|
if (m_ft_init_and_first) // First call to ft_read()
|
||||||
|
{
|
||||||
|
m_ft_init_and_first= FALSE;
|
||||||
|
if (!bulk_access_executing)
|
||||||
|
{
|
||||||
|
error= handle_pre_scan(FALSE, check_parallel_search());
|
||||||
|
if (m_pre_calling || error)
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
late_extra_cache(part_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
file= m_file[part_id];
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
if (!(result= file->ft_read(buf)))
|
||||||
|
{
|
||||||
|
/* Found row: remember position and return it. */
|
||||||
|
m_part_spec.start_part= m_last_part= part_id;
|
||||||
|
table->status= 0;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if we get here, then the current partition ft_next returned failure
|
||||||
|
*/
|
||||||
|
if (result == HA_ERR_RECORD_DELETED)
|
||||||
|
continue; // Probably MyISAM
|
||||||
|
|
||||||
|
if (result != HA_ERR_END_OF_FILE)
|
||||||
|
goto end_dont_reset_start_part; // Return error
|
||||||
|
|
||||||
|
/* End current partition */
|
||||||
|
late_extra_no_cache(part_id);
|
||||||
|
DBUG_PRINT("info", ("stopping using partition %d", part_id));
|
||||||
|
|
||||||
|
/* Shift to next partition */
|
||||||
|
while (++part_id < m_tot_parts &&
|
||||||
|
!bitmap_is_set(&(m_part_info->read_partitions), part_id))
|
||||||
|
;
|
||||||
|
if (part_id >= m_tot_parts)
|
||||||
|
{
|
||||||
|
result= HA_ERR_END_OF_FILE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_part_spec.start_part= m_last_part= part_id;
|
||||||
|
file= m_file[part_id];
|
||||||
|
DBUG_PRINT("info", ("now using partition %d", part_id));
|
||||||
|
late_extra_cache(part_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
m_part_spec.start_part= NO_CURRENT_PART_ID;
|
||||||
|
end_dont_reset_start_part:
|
||||||
|
table->status= STATUS_NOT_FOUND;
|
||||||
|
DBUG_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Common routine to set up index scans
|
Common routine to set up index scans
|
||||||
|
|
||||||
|
@@ -67,6 +67,17 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Partition specific Handler_share.
|
Partition specific Handler_share.
|
||||||
@@ -164,6 +175,8 @@ private:
|
|||||||
partition_info *m_part_info; // local reference to partition
|
partition_info *m_part_info; // local reference to partition
|
||||||
Field **m_part_field_array; // Part field array locally to save acc
|
Field **m_part_field_array; // Part field array locally to save acc
|
||||||
uchar *m_ordered_rec_buffer; // Row and key buffer for ord. idx scan
|
uchar *m_ordered_rec_buffer; // Row and key buffer for ord. idx scan
|
||||||
|
st_partition_ft_info *ft_first;
|
||||||
|
st_partition_ft_info *ft_current;
|
||||||
/*
|
/*
|
||||||
Current index.
|
Current index.
|
||||||
When used in key_rec_cmp: If clustered pk, index compare
|
When used in key_rec_cmp: If clustered pk, index compare
|
||||||
@@ -229,6 +242,7 @@ private:
|
|||||||
bool m_is_sub_partitioned; // Is subpartitioned
|
bool m_is_sub_partitioned; // Is subpartitioned
|
||||||
bool m_ordered_scan_ongoing;
|
bool m_ordered_scan_ongoing;
|
||||||
bool m_rnd_init_and_first;
|
bool m_rnd_init_and_first;
|
||||||
|
bool m_ft_init_and_first;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If set, this object was created with ha_partition::clone and doesn't
|
If set, this object was created with ha_partition::clone and doesn't
|
||||||
@@ -283,6 +297,9 @@ private:
|
|||||||
enum_monotonicity_info m_part_func_monotonicity_info;
|
enum_monotonicity_info m_part_func_monotonicity_info;
|
||||||
bool m_pre_calling;
|
bool m_pre_calling;
|
||||||
bool m_pre_call_use_parallel;
|
bool m_pre_call_use_parallel;
|
||||||
|
/* Keep track of bulk access requests */
|
||||||
|
bool bulk_access_executing;
|
||||||
|
|
||||||
/** keep track of locked partitions */
|
/** keep track of locked partitions */
|
||||||
MY_BITMAP m_locked_partitions;
|
MY_BITMAP m_locked_partitions;
|
||||||
/** Stores shared auto_increment etc. */
|
/** Stores shared auto_increment etc. */
|
||||||
@@ -333,6 +350,7 @@ public:
|
|||||||
ha_partition *clone_arg,
|
ha_partition *clone_arg,
|
||||||
MEM_ROOT *clone_mem_root_arg);
|
MEM_ROOT *clone_mem_root_arg);
|
||||||
~ha_partition();
|
~ha_partition();
|
||||||
|
void ha_partition_init();
|
||||||
/*
|
/*
|
||||||
A partition handler has no characteristics in itself. It only inherits
|
A partition handler has no characteristics in itself. It only inherits
|
||||||
those from the underlying handlers. Here we set-up those constants to
|
those from the underlying handlers. Here we set-up those constants to
|
||||||
@@ -693,7 +711,7 @@ public:
|
|||||||
virtual int multi_range_read_next(range_id_t *range_info);
|
virtual int multi_range_read_next(range_id_t *range_info);
|
||||||
virtual int multi_range_read_explain_info(uint mrr_mode, char *str,
|
virtual int multi_range_read_explain_info(uint mrr_mode, char *str,
|
||||||
size_t size);
|
size_t size);
|
||||||
|
uint last_part() { return m_last_part; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool init_record_priority_queue();
|
bool init_record_priority_queue();
|
||||||
@@ -992,7 +1010,7 @@ public:
|
|||||||
special file for handling names of partitions, engine types.
|
special file for handling names of partitions, engine types.
|
||||||
HA_REC_NOT_IN_SEQ is always set for partition handler since we cannot
|
HA_REC_NOT_IN_SEQ is always set for partition handler since we cannot
|
||||||
guarantee that the records will be returned in sequence.
|
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
|
HA_CAN_INSERT_DELAYED, HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is disabled
|
||||||
until further investigated.
|
until further investigated.
|
||||||
*/
|
*/
|
||||||
@@ -1205,14 +1223,15 @@ public:
|
|||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
MODULE fulltext index
|
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; }
|
|
||||||
*/
|
*/
|
||||||
|
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);
|
||||||
|
virtual int pre_ft_read(bool use_parallel);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
@@ -3312,7 +3312,9 @@ public:
|
|||||||
int compare_key(key_range *range);
|
int compare_key(key_range *range);
|
||||||
int compare_key2(key_range *range) const;
|
int compare_key2(key_range *range) const;
|
||||||
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
|
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() {}
|
||||||
|
virtual int pre_ft_end() { return 0; }
|
||||||
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
|
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
|
||||||
{ return NULL; }
|
{ return NULL; }
|
||||||
private:
|
private:
|
||||||
@@ -3335,6 +3337,7 @@ public:
|
|||||||
|
|
||||||
/* Same as above, but with statistics */
|
/* Same as above, but with statistics */
|
||||||
inline int ha_ft_read(uchar *buf);
|
inline int ha_ft_read(uchar *buf);
|
||||||
|
inline void ha_ft_end() { ft_end(); ft_handler=NULL; }
|
||||||
int ha_rnd_next(uchar *buf);
|
int ha_rnd_next(uchar *buf);
|
||||||
int ha_rnd_pos(uchar *buf, uchar *pos);
|
int ha_rnd_pos(uchar *buf, uchar *pos);
|
||||||
inline int ha_rnd_pos_by_record(uchar *buf);
|
inline int ha_rnd_pos_by_record(uchar *buf);
|
||||||
|
@@ -22144,7 +22144,7 @@ create_sort_index(THD *thd, JOIN *join, JOIN_TAB *tab, Filesort *fsort)
|
|||||||
|
|
||||||
table->file->ha_end_keyread();
|
table->file->ha_end_keyread();
|
||||||
if (tab->type == JT_FT)
|
if (tab->type == JT_FT)
|
||||||
table->file->ft_end();
|
table->file->ha_ft_end();
|
||||||
else
|
else
|
||||||
table->file->ha_index_or_rnd_end();
|
table->file->ha_index_or_rnd_end();
|
||||||
|
|
||||||
|
@@ -0,0 +1,23 @@
|
|||||||
|
--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
|
@@ -0,0 +1,72 @@
|
|||||||
|
--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';
|
126
storage/spider/mysql-test/spider/r/partition_fulltext.result
Normal file
126
storage/spider/mysql-test/spider/r/partition_fulltext.result
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
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
|
223
storage/spider/mysql-test/spider/t/partition_fulltext.test
Normal file
223
storage/spider/mysql-test/spider/t/partition_fulltext.test
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
--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
|
Reference in New Issue
Block a user