mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV 7701 extra() calls for VP engine
Added Spider patches: 003_mariadb-10.0.15.vp.diff 060_mariadb-10.2.0.partition_reset_top_table_fields.diff - Support HA_EXTRA_ADD_CHILDREN_LIST,HA_EXTRA_ATTACH_CHILDREN, HA_EXTRA_IS_ATTACHED_CHILDREN and HA_EXTRA_DETACH_CHILDREN in partition handler for handlers that has HA_CAN_MULTISTEPL_MERGE flag - Added HA_CAN_MULTISTEPL_MERGE to MERGE handler. - Added handler::get_child_handlers() - Change m_num_lock to contain total number of locks. This was needed as we now adjust number of locks when extra(HA_EXTRA_ATTACH_CHILDREN) is called.
This commit is contained in:
@@ -3536,6 +3536,13 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
|
|||||||
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
|
name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
|
||||||
} while (*(++file));
|
} while (*(++file));
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
We want to know the upper bound for locks, to allocate enough memory.
|
||||||
|
There is no performance lost if we simply return in lock_count() the
|
||||||
|
maximum number locks needed, only some minor over allocation of memory
|
||||||
|
in get_lock_data().
|
||||||
|
*/
|
||||||
|
m_num_locks*= m_tot_parts;
|
||||||
|
|
||||||
file= m_file;
|
file= m_file;
|
||||||
ref_length= (*file)->ref_length;
|
ref_length= (*file)->ref_length;
|
||||||
@@ -3977,25 +3984,14 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
|
|||||||
@returns Number of locks returned in call to store_lock
|
@returns Number of locks returned in call to store_lock
|
||||||
|
|
||||||
@desc
|
@desc
|
||||||
Returns the number of store locks needed in call to store lock.
|
Returns the maxinum possible number of store locks needed in call to
|
||||||
We return number of partitions we will lock multiplied with number of
|
store lock.
|
||||||
locks needed by each partition. Assists the above functions in allocating
|
|
||||||
sufficient space for lock structures.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint ha_partition::lock_count() const
|
uint ha_partition::lock_count() const
|
||||||
{
|
{
|
||||||
DBUG_ENTER("ha_partition::lock_count");
|
DBUG_ENTER("ha_partition::lock_count");
|
||||||
/*
|
DBUG_RETURN(m_num_locks);
|
||||||
The caller want to know the upper bound, to allocate enough memory.
|
|
||||||
There is no performance lost if we simply return maximum number locks
|
|
||||||
needed, only some minor over allocation of memory in get_lock_data().
|
|
||||||
|
|
||||||
Also notice that this may be called for another thread != table->in_use,
|
|
||||||
when mysql_lock_abort_for_thread() is called. So this is more safe, then
|
|
||||||
using number of partitions after pruning.
|
|
||||||
*/
|
|
||||||
DBUG_RETURN(m_tot_parts * m_num_locks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -7253,19 +7249,36 @@ int ha_partition::extra(enum ha_extra_function operation)
|
|||||||
}
|
}
|
||||||
/* Category 9) Operations only used by MERGE */
|
/* Category 9) Operations only used by MERGE */
|
||||||
case HA_EXTRA_ADD_CHILDREN_LIST:
|
case HA_EXTRA_ADD_CHILDREN_LIST:
|
||||||
|
DBUG_RETURN(loop_extra(operation));
|
||||||
case HA_EXTRA_ATTACH_CHILDREN:
|
case HA_EXTRA_ATTACH_CHILDREN:
|
||||||
case HA_EXTRA_IS_ATTACHED_CHILDREN:
|
|
||||||
case HA_EXTRA_DETACH_CHILDREN:
|
|
||||||
{
|
{
|
||||||
/* Special actions for MERGE tables. Ignore. */
|
int result;
|
||||||
|
uint num_locks= 0;
|
||||||
|
handler **file;
|
||||||
|
if ((result = loop_extra(operation)))
|
||||||
|
DBUG_RETURN(result);
|
||||||
|
|
||||||
|
/* Recalculate lock count as each child may have different set of locks */
|
||||||
|
num_locks = 0;
|
||||||
|
file = m_file;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
num_locks+= (*file)->lock_count();
|
||||||
|
} while (*(++file));
|
||||||
|
|
||||||
|
m_num_locks= num_locks;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case HA_EXTRA_IS_ATTACHED_CHILDREN:
|
||||||
|
DBUG_RETURN(loop_extra(operation));
|
||||||
|
case HA_EXTRA_DETACH_CHILDREN:
|
||||||
|
DBUG_RETURN(loop_extra(operation));
|
||||||
|
case HA_EXTRA_MARK_AS_LOG_TABLE:
|
||||||
/*
|
/*
|
||||||
http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html
|
http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html
|
||||||
says we no longer support logging to partitioned tables, so we fail
|
says we no longer support logging to partitioned tables, so we fail
|
||||||
here.
|
here.
|
||||||
*/
|
*/
|
||||||
case HA_EXTRA_MARK_AS_LOG_TABLE:
|
|
||||||
DBUG_RETURN(ER_UNSUPORTED_LOG_ENGINE);
|
DBUG_RETURN(ER_UNSUPORTED_LOG_ENGINE);
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@@ -9139,6 +9152,22 @@ const COND *ha_partition::cond_push(const COND *cond)
|
|||||||
COND *res_cond = NULL;
|
COND *res_cond = NULL;
|
||||||
DBUG_ENTER("ha_partition::cond_push");
|
DBUG_ENTER("ha_partition::cond_push");
|
||||||
|
|
||||||
|
if (set_top_table_fields)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We want to do this in a separate loop to not come into a situation
|
||||||
|
where we have only done cond_push() to some of the tables
|
||||||
|
*/
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (((*file)->set_top_table_and_fields(top_table,
|
||||||
|
top_table_field,
|
||||||
|
top_table_fields)))
|
||||||
|
DBUG_RETURN(cond); // Abort cond push, no error
|
||||||
|
} while (*(++file));
|
||||||
|
file= m_file;
|
||||||
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if ((*file)->pushed_cond != cond)
|
if ((*file)->pushed_cond != cond)
|
||||||
@@ -9165,6 +9194,23 @@ void ha_partition::cond_pop()
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ha_partition::clear_top_table_fields()
|
||||||
|
{
|
||||||
|
handler **file;
|
||||||
|
DBUG_ENTER("ha_partition::clear_top_table_fields");
|
||||||
|
|
||||||
|
if (set_top_table_fields)
|
||||||
|
{
|
||||||
|
set_top_table_fields= FALSE;
|
||||||
|
top_table= NULL;
|
||||||
|
top_table_field= NULL;
|
||||||
|
top_table_fields= 0;
|
||||||
|
for (file= m_file; *file; file++)
|
||||||
|
(*file)->clear_top_table_fields();
|
||||||
|
}
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct st_mysql_storage_engine partition_storage_engine=
|
struct st_mysql_storage_engine partition_storage_engine=
|
||||||
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
|
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
|
||||||
|
@@ -271,6 +271,10 @@ private:
|
|||||||
MY_BITMAP m_key_not_found_partitions;
|
MY_BITMAP m_key_not_found_partitions;
|
||||||
bool m_key_not_found;
|
bool m_key_not_found;
|
||||||
public:
|
public:
|
||||||
|
handler **get_child_handlers()
|
||||||
|
{
|
||||||
|
return m_file;
|
||||||
|
}
|
||||||
Partition_share *get_part_share() { return part_share; }
|
Partition_share *get_part_share() { return part_share; }
|
||||||
handler *clone(const char *name, MEM_ROOT *mem_root);
|
handler *clone(const char *name, MEM_ROOT *mem_root);
|
||||||
virtual void set_part_info(partition_info *part_info)
|
virtual void set_part_info(partition_info *part_info)
|
||||||
@@ -1205,6 +1209,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual const COND *cond_push(const COND *cond);
|
virtual const COND *cond_push(const COND *cond);
|
||||||
virtual void cond_pop();
|
virtual void cond_pop();
|
||||||
|
virtual void clear_top_table_fields();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, uint flags);
|
int handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt, uint flags);
|
||||||
|
@@ -6000,6 +6000,7 @@ int handler::ha_reset()
|
|||||||
/* Reset information about pushed engine conditions */
|
/* Reset information about pushed engine conditions */
|
||||||
cancel_pushed_idx_cond();
|
cancel_pushed_idx_cond();
|
||||||
/* Reset information about pushed index conditions */
|
/* Reset information about pushed index conditions */
|
||||||
|
clear_top_table_fields();
|
||||||
DBUG_RETURN(reset());
|
DBUG_RETURN(reset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,6 +286,9 @@ enum enum_alter_inplace_result {
|
|||||||
*/
|
*/
|
||||||
#define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
|
#define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
|
||||||
|
|
||||||
|
/* The following is for partition handler */
|
||||||
|
#define HA_CAN_MULTISTEP_MERGE (1LL << 53)
|
||||||
|
|
||||||
/* bits in index_flags(index_number) for what you can do with index */
|
/* bits in index_flags(index_number) for what you can do with index */
|
||||||
#define HA_READ_NEXT 1 /* TODO really use this flag */
|
#define HA_READ_NEXT 1 /* TODO really use this flag */
|
||||||
#define HA_READ_PREV 2 /* supports ::index_prev */
|
#define HA_READ_PREV 2 /* supports ::index_prev */
|
||||||
@@ -1413,6 +1416,7 @@ handlerton *ha_default_tmp_handlerton(THD *thd);
|
|||||||
#define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
|
#define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
|
||||||
#define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
|
#define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
|
||||||
#define HTON_NO_PARTITION (1 << 8) //Not partition of these tables
|
#define HTON_NO_PARTITION (1 << 8) //Not partition of these tables
|
||||||
|
#define HTON_CAN_MULTISTEP_MERGE (1 << 9) //You can merge mearged tables
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This flag should be set when deciding that the engine does not allow
|
This flag should be set when deciding that the engine does not allow
|
||||||
@@ -2774,6 +2778,11 @@ public:
|
|||||||
virtual void unbind_psi();
|
virtual void unbind_psi();
|
||||||
virtual void rebind_psi();
|
virtual void rebind_psi();
|
||||||
|
|
||||||
|
bool set_top_table_fields;
|
||||||
|
struct TABLE *top_table;
|
||||||
|
Field **top_table_field;
|
||||||
|
uint top_table_fields;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
The lock type set by when calling::ha_external_lock(). This is
|
The lock type set by when calling::ha_external_lock(). This is
|
||||||
@@ -2808,7 +2817,9 @@ public:
|
|||||||
pushed_idx_cond(NULL),
|
pushed_idx_cond(NULL),
|
||||||
pushed_idx_cond_keyno(MAX_KEY),
|
pushed_idx_cond_keyno(MAX_KEY),
|
||||||
auto_inc_intervals_count(0),
|
auto_inc_intervals_count(0),
|
||||||
m_psi(NULL), m_lock_type(F_UNLCK), ha_share(NULL)
|
m_psi(NULL), set_top_table_fields(FALSE), top_table(0),
|
||||||
|
top_table_field(0), top_table_fields(0),
|
||||||
|
m_lock_type(F_UNLCK), ha_share(NULL)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
|
("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
|
||||||
@@ -3657,6 +3668,36 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void cond_pop() { return; };
|
virtual void cond_pop() { return; };
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function is used to get correlating of a parent (table/column)
|
||||||
|
and children (table/column). When conditions are pushed down to child
|
||||||
|
table (like child of myisam_merge), child table needs to know about
|
||||||
|
which table/column is my parent for understanding conditions.
|
||||||
|
*/
|
||||||
|
virtual int set_top_table_and_fields(TABLE *top_table,
|
||||||
|
Field **top_table_field,
|
||||||
|
uint top_table_fields)
|
||||||
|
{
|
||||||
|
if (!set_top_table_fields)
|
||||||
|
{
|
||||||
|
set_top_table_fields= TRUE;
|
||||||
|
this->top_table= top_table;
|
||||||
|
this->top_table_field= top_table_field;
|
||||||
|
this->top_table_fields= top_table_fields;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
virtual void clear_top_table_fields()
|
||||||
|
{
|
||||||
|
if (set_top_table_fields)
|
||||||
|
{
|
||||||
|
set_top_table_fields= FALSE;
|
||||||
|
top_table= NULL;
|
||||||
|
top_table_field= NULL;
|
||||||
|
top_table_fields= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Push down an index condition to the handler.
|
Push down an index condition to the handler.
|
||||||
|
|
||||||
|
@@ -1096,14 +1096,32 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
|||||||
|
|
||||||
table= table->find_table_for_update();
|
table= table->find_table_for_update();
|
||||||
|
|
||||||
if (table->table && table->table->file->ht->db_type == DB_TYPE_MRG_MYISAM)
|
if (table->table &&
|
||||||
|
table->table->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
|
||||||
{
|
{
|
||||||
TABLE_LIST *child;
|
TABLE_LIST *child;
|
||||||
dup= NULL;
|
dup= NULL;
|
||||||
/* Check duplicates of all merge children. */
|
/* Check duplicates of all merge children. */
|
||||||
for (child= table->next_global; child && child->parent_l == table;
|
for (child= table->next_global; child;
|
||||||
child= child->next_global)
|
child= child->next_global)
|
||||||
{
|
{
|
||||||
|
if (child->table &&
|
||||||
|
child->table->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ensure that the child has one parent that is the table that is
|
||||||
|
updated.
|
||||||
|
*/
|
||||||
|
TABLE_LIST *tmp_parent= child;
|
||||||
|
while ((tmp_parent= tmp_parent->parent_l))
|
||||||
|
{
|
||||||
|
if (tmp_parent == table)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!tmp_parent)
|
||||||
|
break;
|
||||||
|
|
||||||
if ((dup= find_dup_table(thd, child, child->next_global, check_alias)))
|
if ((dup= find_dup_table(thd, child, child->next_global, check_alias)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1112,6 +1130,8 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
|||||||
dup= find_dup_table(thd, table, table_list, check_alias);
|
dup= find_dup_table(thd, table, table_list, check_alias);
|
||||||
return dup;
|
return dup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Issue correct error message in case we found 2 duplicate tables which
|
Issue correct error message in case we found 2 duplicate tables which
|
||||||
prevent some update operation
|
prevent some update operation
|
||||||
@@ -4089,7 +4109,7 @@ restart:
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Schema tables may not have a TABLE object here. */
|
/* Schema tables may not have a TABLE object here. */
|
||||||
if (tbl->file->ht->db_type == DB_TYPE_MRG_MYISAM)
|
if (tbl->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
|
||||||
{
|
{
|
||||||
/* MERGE tables need to access parent and child TABLE_LISTs. */
|
/* MERGE tables need to access parent and child TABLE_LISTs. */
|
||||||
DBUG_ASSERT(tbl->pos_in_table_list == tables);
|
DBUG_ASSERT(tbl->pos_in_table_list == tables);
|
||||||
@@ -4636,7 +4656,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
|
|||||||
*/
|
*/
|
||||||
DBUG_ASSERT(table_list->table);
|
DBUG_ASSERT(table_list->table);
|
||||||
table= table_list->table;
|
table= table_list->table;
|
||||||
if (table->file->ht->db_type == DB_TYPE_MRG_MYISAM)
|
if (table->file->ha_table_flags() & HA_CAN_MULTISTEP_MERGE)
|
||||||
{
|
{
|
||||||
/* A MERGE table must not come here. */
|
/* A MERGE table must not come here. */
|
||||||
/* purecov: begin tested */
|
/* purecov: begin tested */
|
||||||
|
@@ -91,7 +91,7 @@ public:
|
|||||||
HA_ANY_INDEX_MAY_BE_UNIQUE | HA_CAN_BIT_FIELD |
|
HA_ANY_INDEX_MAY_BE_UNIQUE | HA_CAN_BIT_FIELD |
|
||||||
HA_HAS_RECORDS | HA_CAN_EXPORT |
|
HA_HAS_RECORDS | HA_CAN_EXPORT |
|
||||||
HA_NO_COPY_ON_ALTER |
|
HA_NO_COPY_ON_ALTER |
|
||||||
HA_DUPLICATE_POS);
|
HA_DUPLICATE_POS | HA_CAN_MULTISTEP_MERGE);
|
||||||
}
|
}
|
||||||
ulong index_flags(uint inx, uint part, bool all_parts) const
|
ulong index_flags(uint inx, uint part, bool all_parts) const
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user