mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-5800 InnoDB support for indexed vcols
* remove old 5.2+ InnoDB support for virtual columns * enable corresponding parts of the innodb-5.7 sources * copy corresponding test cases from 5.7 * copy detailed Alter_inplace_info::HA_ALTER_FLAGS flags from 5.7 - and more detailed detection of changes in fill_alter_inplace_info() * more "innodb compatibility hooks" in sql_class.cc to - create/destroy/reset a THD (used by background purge threads) - find a prelocked table by name - open a table (from a background purge thread) * different from 5.7: - new service thread "thd_destructor_proxy" to make sure all THDs are destroyed at the correct point in time during the server shutdown - proper opening/closing of tables for vcol evaluations in + FK checks (use already opened prelocked tables) + purge threads (open the table, MDLock it, add it to tdc, close when not needed) - cache open tables in vc_templ - avoid unnecessary allocations, reuse table->record[0] and table->s->default_values - not needed in 5.7, because it overcalculates: + tell the server to calculate vcols for an on-going inline ADD INDEX + calculate vcols for correct error messages * update other engines (mroonga/tokudb) accordingly
This commit is contained in:
141
sql/sql_table.cc
141
sql/sql_table.cc
@ -6216,17 +6216,6 @@ static int compare_uint(const uint *s, const uint *t)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check if the column is computed and either
|
||||
is stored or is used in the partitioning expression.
|
||||
*/
|
||||
static bool vcol_affecting_storage(const Virtual_column_info* vcol,
|
||||
bool indexed)
|
||||
{
|
||||
return vcol &&
|
||||
(vcol->is_stored() || vcol->is_in_partitioning_expr() || indexed);
|
||||
}
|
||||
|
||||
/**
|
||||
Compare original and new versions of a table and fill Alter_inplace_info
|
||||
describing differences between those versions.
|
||||
@ -6291,11 +6280,6 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
alter_info->key_list.elements)))
|
||||
DBUG_RETURN(true);
|
||||
|
||||
/* First we setup ha_alter_flags based on what was detected by parser. */
|
||||
if (alter_info->flags & Alter_info::ALTER_ADD_COLUMN)
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::ADD_COLUMN;
|
||||
if (alter_info->flags & Alter_info::ALTER_DROP_COLUMN)
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::DROP_COLUMN;
|
||||
/*
|
||||
Comparing new and old default values of column is cumbersome.
|
||||
So instead of using such a comparison for detecting if default
|
||||
@ -6343,7 +6327,7 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
upgrading VARCHAR column types.
|
||||
*/
|
||||
if (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar)
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_TYPE;
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_STORED_COLUMN_TYPE;
|
||||
|
||||
/*
|
||||
Go through fields in old version of table and detect changes to them.
|
||||
@ -6357,20 +6341,23 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
about nature of changes than those provided from parser.
|
||||
*/
|
||||
bool maybe_alter_vcol= false;
|
||||
for (f_ptr= table->field; (field= *f_ptr); f_ptr++)
|
||||
uint field_stored_index= 0;
|
||||
for (f_ptr= table->field; (field= *f_ptr); f_ptr++,
|
||||
field_stored_index+= field->stored_in_db())
|
||||
{
|
||||
/* Clear marker for renamed or dropped field
|
||||
which we are going to set later. */
|
||||
field->flags&= ~(FIELD_IS_RENAMED | FIELD_IS_DROPPED);
|
||||
|
||||
/* Use transformed info to evaluate flags for storage engine. */
|
||||
uint new_field_index= 0;
|
||||
uint new_field_index= 0, new_field_stored_index= 0;
|
||||
new_field_it.init(alter_info->create_list);
|
||||
while ((new_field= new_field_it++))
|
||||
{
|
||||
if (new_field->field == field)
|
||||
break;
|
||||
new_field_index++;
|
||||
new_field_stored_index+= new_field->stored_in_db();
|
||||
}
|
||||
|
||||
if (new_field)
|
||||
@ -6385,7 +6372,12 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
{
|
||||
case IS_EQUAL_NO:
|
||||
/* New column type is incompatible with old one. */
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_TYPE;
|
||||
if (field->stored_in_db())
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ALTER_STORED_COLUMN_TYPE;
|
||||
else
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ALTER_VIRTUAL_COLUMN_TYPE;
|
||||
if (table->s->tmp_table == NO_TMP_TABLE)
|
||||
{
|
||||
delete_statistics_for_column(thd, table, field);
|
||||
@ -6430,31 +6422,57 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
/* Safety. */
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_TYPE;
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ALTER_STORED_COLUMN_TYPE;
|
||||
}
|
||||
|
||||
if (vcol_affecting_storage(field->vcol_info,
|
||||
field->flags & PART_KEY_FLAG) ||
|
||||
vcol_affecting_storage(new_field->vcol_info, false))
|
||||
if (field->vcol_info || new_field->vcol_info)
|
||||
{
|
||||
if (is_equal == IS_EQUAL_NO ||
|
||||
!field->vcol_info || !new_field->vcol_info ||
|
||||
!field->vcol_info->is_equal(new_field->vcol_info))
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL;
|
||||
else
|
||||
/* base <-> virtual or stored <-> virtual */
|
||||
if (field->stored_in_db() != new_field->stored_in_db())
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ALTER_STORED_COLUMN_TYPE |
|
||||
Alter_inplace_info::ALTER_VIRTUAL_COLUMN_TYPE;
|
||||
if (field->vcol_info && new_field->vcol_info)
|
||||
{
|
||||
if (!(ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_VCOL) &&
|
||||
(ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_DEFAULT))
|
||||
bool value_changes= is_equal == IS_EQUAL_NO;
|
||||
Alter_inplace_info::HA_ALTER_FLAGS alter_expr= field->stored_in_db()
|
||||
? Alter_inplace_info::ALTER_STORED_GCOL_EXPR
|
||||
: Alter_inplace_info::ALTER_VIRTUAL_GCOL_EXPR;
|
||||
if (!field->vcol_info->is_equal(new_field->vcol_info))
|
||||
{
|
||||
ha_alter_info->handler_flags|= alter_expr;
|
||||
value_changes= true;
|
||||
}
|
||||
|
||||
if ((ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_DEFAULT)
|
||||
&& !(ha_alter_info->handler_flags & alter_expr))
|
||||
{ /*
|
||||
a DEFAULT value of a some column was changed.
|
||||
see if this vcol uses DEFAULT() function
|
||||
a DEFAULT value of a some column was changed. see if this vcol
|
||||
uses DEFAULT() function. The check is kind of expensive, so don't
|
||||
do it if ALTER_COLUMN_VCOL is already set.
|
||||
*/
|
||||
if (field->vcol_info->expr_item->walk(
|
||||
&Item::check_func_default_processor, 0, 0))
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL;
|
||||
{
|
||||
ha_alter_info->handler_flags|= alter_expr;
|
||||
value_changes= true;
|
||||
}
|
||||
}
|
||||
|
||||
if (field->vcol_info->is_in_partitioning_expr() ||
|
||||
field->flags & PART_KEY_FLAG)
|
||||
{
|
||||
if (value_changes)
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ALTER_COLUMN_VCOL;
|
||||
else
|
||||
maybe_alter_vcol= true;
|
||||
}
|
||||
}
|
||||
maybe_alter_vcol= true;
|
||||
else /* base <-> stored */
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ALTER_STORED_COLUMN_TYPE;
|
||||
}
|
||||
|
||||
/* Check if field was renamed */
|
||||
@ -6487,8 +6505,18 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
/*
|
||||
Detect changes in column order.
|
||||
*/
|
||||
if (field->field_index != new_field_index)
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_ORDER;
|
||||
if (field->stored_in_db())
|
||||
{
|
||||
if (field_stored_index != new_field_stored_index)
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ALTER_STORED_COLUMN_ORDER;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (field->field_index != new_field_index)
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER;
|
||||
}
|
||||
|
||||
/* Detect changes in storage type of column */
|
||||
if (new_field->field_storage_type() != field->field_storage_type())
|
||||
@ -6511,12 +6539,12 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Field is not present in new version of table and therefore was dropped.
|
||||
Corresponding storage engine flag should be already set.
|
||||
*/
|
||||
DBUG_ASSERT(ha_alter_info->handler_flags & Alter_inplace_info::DROP_COLUMN);
|
||||
// Field is not present in new version of table and therefore was dropped.
|
||||
field->flags|= FIELD_IS_DROPPED;
|
||||
if (field->stored_in_db())
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::DROP_STORED_COLUMN;
|
||||
else
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::DROP_VIRTUAL_COLUMN;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6529,9 +6557,10 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
column was altered.
|
||||
*/
|
||||
if (ha_alter_info->handler_flags &
|
||||
( Alter_inplace_info::ALTER_COLUMN_TYPE
|
||||
| Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE
|
||||
| Alter_inplace_info::ALTER_COLUMN_OPTION ))
|
||||
( Alter_inplace_info::ALTER_STORED_COLUMN_TYPE
|
||||
| Alter_inplace_info::ALTER_VIRTUAL_COLUMN_TYPE
|
||||
| Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE
|
||||
| Alter_inplace_info::ALTER_COLUMN_OPTION ))
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL;
|
||||
}
|
||||
|
||||
@ -6540,17 +6569,17 @@ static bool fill_alter_inplace_info(THD *thd,
|
||||
{
|
||||
if (! new_field->field)
|
||||
{
|
||||
/*
|
||||
Field is not present in old version of table and therefore was added.
|
||||
Again corresponding storage engine flag should be already set.
|
||||
*/
|
||||
DBUG_ASSERT(ha_alter_info->handler_flags & Alter_inplace_info::ADD_COLUMN);
|
||||
|
||||
if (new_field->vcol_info &&
|
||||
(new_field->stored_in_db() || new_field->vcol_info->is_in_partitioning_expr()))
|
||||
{
|
||||
ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL;
|
||||
}
|
||||
// Field is not present in old version of table and therefore was added.
|
||||
if (new_field->vcol_info)
|
||||
if (new_field->stored_in_db())
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ADD_STORED_GENERATED_COLUMN;
|
||||
else
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ADD_VIRTUAL_COLUMN;
|
||||
else
|
||||
ha_alter_info->handler_flags|=
|
||||
Alter_inplace_info::ADD_STORED_BASE_COLUMN;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user