1
0
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:
Sergei Golubchik
2016-11-07 22:35:02 +01:00
parent 7fca91f2b4
commit 1cae1af6f9
65 changed files with 7367 additions and 1106 deletions

View File

@ -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;
}
}