summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-11-07 22:35:02 +0100
committerSergei Golubchik <serg@mariadb.org>2016-12-12 20:27:42 +0100
commit1cae1af6f9286ca6695206ce20c63bb639c60310 (patch)
tree3877547f579596add5d757059d1e2f10dd8ef429 /storage
parent7fca91f2b454db6e33d964a7484237793699f77d (diff)
downloadmariadb-git-1cae1af6f9286ca6695206ce20c63bb639c60310.tar.gz
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
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/handler/ha_innodb.cc567
-rw-r--r--storage/innobase/handler/ha_innodb.h18
-rw-r--r--storage/innobase/handler/handler0alter.cc422
-rw-r--r--storage/innobase/include/dict0dict.ic1
-rw-r--r--storage/innobase/include/dict0mem.h11
-rw-r--r--storage/innobase/include/ha_prototypes.h16
-rw-r--r--storage/innobase/log/log0log.cc7
-rw-r--r--storage/innobase/row/row0ins.cc6
-rw-r--r--storage/innobase/row/row0merge.cc5
-rw-r--r--storage/innobase/row/row0mysql.cc2
-rw-r--r--storage/innobase/row/row0purge.cc4
-rw-r--r--storage/innobase/row/row0sel.cc2
-rw-r--r--storage/innobase/row/row0upd.cc6
-rw-r--r--storage/innobase/row/row0vers.cc6
-rw-r--r--storage/innobase/srv/srv0srv.cc44
-rw-r--r--storage/mroonga/ha_mroonga.cpp4
-rw-r--r--storage/tokudb/ha_tokudb_alter_56.cc20
17 files changed, 548 insertions, 593 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 598047e31d6..a235195ae91 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -126,6 +126,14 @@ this program; if not, write to the Free Software Foundation, Inc.,
#define thd_get_trx_isolation(X) ((enum_tx_isolation)thd_tx_isolation(X))
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all);
+unsigned long long thd_get_query_id(const MYSQL_THD thd);
+TABLE *find_fk_open_table(THD *thd, const char *db, size_t db_len,
+ const char *table, size_t table_len);
+MYSQL_THD create_thd();
+void destroy_thd(MYSQL_THD thd);
+void reset_thd(MYSQL_THD thd);
+TABLE *open_purge_table(THD *thd, const char *db, size_t dblen,
+ const char *tb, size_t tblen);
#ifdef MYSQL_DYNAMIC_PLUGIN
#define tc_size 400
@@ -300,6 +308,45 @@ is_partition(
#endif /* _WIN32 */
}
+/** Service thread that waits for the server shutdown and stops purge threads.
+Purge workers have THDs that are needed to calculate virtual columns.
+This THDs must be destroyed rather early in the server shutdown sequence.
+This service thread creates a THD and idly waits for it to get a signal to
+die. Then it notifies all purge workers to shutdown.
+*/
+st_my_thread_var *thd_destructor_myvar= NULL;
+mysql_cond_t thd_destructor_cond;
+pthread_t thd_destructor_thread;
+
+pthread_handler_t
+thd_destructor_proxy(void *)
+{
+ mysql_mutex_t thd_destructor_mutex;
+
+ my_thread_init();
+ mysql_mutex_init(PSI_NOT_INSTRUMENTED, &thd_destructor_mutex, 0);
+ mysql_cond_init(PSI_NOT_INSTRUMENTED, &thd_destructor_cond, 0);
+
+ thd_destructor_myvar = _my_thread_var();
+ THD *thd= create_thd();
+
+ mysql_mutex_lock(&thd_destructor_mutex);
+ thd_destructor_myvar->current_mutex = &thd_destructor_mutex;
+ thd_destructor_myvar->current_cond = &thd_destructor_cond;
+ /* wait until the server wakes the THD to abort and die */
+ while (!thd_destructor_myvar->abort)
+ mysql_cond_wait(&thd_destructor_cond, &thd_destructor_mutex);
+ mysql_mutex_unlock(&thd_destructor_mutex);
+ thd_destructor_myvar = NULL;
+
+ srv_purge_wakeup();
+
+ destroy_thd(thd);
+ mysql_cond_destroy(&thd_destructor_cond);
+ mysql_mutex_destroy(&thd_destructor_mutex);
+ my_thread_end();
+ return 0;
+}
/** Return the InnoDB ROW_FORMAT enum value
@param[in] row_format row_format from "innodb_default_row_format"
@@ -473,6 +520,7 @@ static mysql_pfs_key_t innobase_share_mutex_key;
static mysql_pfs_key_t commit_cond_mutex_key;
static mysql_pfs_key_t commit_cond_key;
static mysql_pfs_key_t pending_checkpoint_mutex_key;
+static mysql_pfs_key_t thd_destructor_thread_key;
static PSI_mutex_info all_pthread_mutexes[] = {
PSI_KEY(commit_cond_mutex),
@@ -601,6 +649,7 @@ static PSI_thread_info all_innodb_threads[] = {
PSI_KEY(srv_purge_thread),
PSI_KEY(srv_worker_thread),
PSI_KEY(trx_rollback_clean_thread),
+ PSI_KEY(thd_destructor_thread),
};
# endif /* UNIV_PFS_THREAD */
@@ -1718,6 +1767,55 @@ thd_trx_is_read_only(
return(thd != 0 && thd_tx_is_read_only(thd));
}
+static MYSQL_THDVAR_BOOL(background_thread,
+ PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_NOSYSVAR,
+ "Internal (not user visible) flag to mark "
+ "background purge threads", NULL, NULL, 0);
+
+/** Create a MYSQL_THD for background purge threads and mark it as such.
+@returns new MYSQL_THD */
+MYSQL_THD
+innobase_create_background_thd()
+/*============================*/
+{
+ MYSQL_THD thd= create_thd();
+ THDVAR(thd, background_thread) = true;
+ return thd;
+}
+
+
+/** Destroy a background purge thread THD.
+@param[in] thd MYSQL_THD to destroy */
+void
+innobase_destroy_background_thd(
+/*============================*/
+ MYSQL_THD thd)
+{
+ /* need to close the connection explicitly, the server won't do it
+ if innodb is in the PLUGIN_IS_DYING state */
+ innobase_close_connection(innodb_hton_ptr, thd);
+ thd_set_ha_data(thd, innodb_hton_ptr, NULL);
+ destroy_thd(thd);
+}
+
+/** Close opened tables, free memory, delete items for a MYSQL_THD.
+@param[in] thd MYSQL_THD to reset */
+void
+innobase_reset_background_thd(MYSQL_THD thd)
+{
+ if (!thd) {
+ thd = current_thd;
+ }
+
+ ut_ad(thd);
+ ut_ad(THDVAR(thd, background_thread));
+
+ /* background purge thread */
+ reset_thd(thd);
+ thd_proc_info(thd, "");
+}
+
+
#if 0
/**
Check if the transaction can be rolled back
@@ -3252,6 +3350,7 @@ ha_innobase::ha_innobase(
| HA_CAN_VIRTUAL_COLUMNS
| HA_CAN_INDEX_BLOBS
| HA_CAN_SQL_HANDLER
+ | HA_REQUIRES_KEY_COLUMNS_FOR_DELETE
| HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
| HA_PRIMARY_KEY_IN_READ_INDEX
| HA_BINLOG_ROW_CAPABLE
@@ -4582,6 +4681,12 @@ innobase_change_buffering_inited_ok:
}
*/
+ if (!srv_read_only_mode) {
+ mysql_thread_create(thd_destructor_thread_key,
+ &thd_destructor_thread,
+ NULL, thd_destructor_proxy, NULL);
+ }
+
/* Since we in this module access directly the fields of a trx
struct, and due to different headers and flags it might happen that
ib_mutex_t has a different size in this module and in InnoDB
@@ -4716,6 +4821,13 @@ innobase_end(
#ifdef MYSQL_ENCRYPTION
mutex_free(&master_key_id_mutex);
#endif
+
+ if (!abort_loop && thd_destructor_myvar) {
+ // may be UNINSTALL PLUGIN statement
+ thd_destructor_myvar->abort = 1;
+ mysql_cond_broadcast(thd_destructor_myvar->current_cond);
+ }
+
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
err = 1;
}
@@ -5839,6 +5951,36 @@ ha_innobase::keys_to_use_for_scanning()
}
/****************************************************************//**
+Ensures that if there's a concurrent inplace ADD INDEX, being-indexed virtual
+columns are computed. They are not marked as indexed in the old table, so the
+server won't add them to the vcol_set automatically */
+void
+ha_innobase::column_bitmaps_signal()
+/*================================*/
+{
+ if (!table->vfield || table->current_lock != F_WRLCK) {
+ return;
+ }
+
+ dict_index_t* clust_index = dict_table_get_first_index(m_prebuilt->table);
+ uint num_v = 0;
+ for (uint j = 0; j < table->s->virtual_fields; j++) {
+ if (table->vfield[j]->stored_in_db()) {
+ continue;
+ }
+
+ dict_col_t* col = &m_prebuilt->table->v_cols[num_v].m_col;
+ if (col->ord_part ||
+ (dict_index_is_online_ddl(clust_index) &&
+ row_log_col_is_indexed(clust_index, num_v))) {
+ table->mark_virtual_col(table->vfield[j]);
+ }
+ num_v++;
+ }
+}
+
+
+/****************************************************************//**
Determines if table caching is supported.
@return HA_CACHE_TBL_ASKTRANSACT */
@@ -6168,7 +6310,6 @@ innobase_match_index_columns(
DBUG_RETURN(TRUE);
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
/** Build a template for a base column for a virtual column
@param[in] table MySQL TABLE
@param[in] clust_index InnoDB clustered index
@@ -6228,21 +6369,6 @@ innobase_vcol_build_templ(
templ->is_unsigned = col->prtype & DATA_UNSIGNED;
}
-/** callback used by MySQL server layer to initialize
-the table virtual columns' template
-@param[in] table MySQL TABLE
-@param[in,out] ib_table InnoDB table */
-void
-innobase_build_v_templ_callback(
- const TABLE* table,
- void* ib_table)
-{
- const dict_table_t* t_table = static_cast<dict_table_t*>(ib_table);
-
- innobase_build_v_templ(table, t_table, t_table->vc_templ, NULL,
- true, NULL);
-}
-
/** Build template for the virtual columns and their base columns. This
is done when the table first opened.
@param[in] table MySQL TABLE
@@ -6250,16 +6376,14 @@ is done when the table first opened.
@param[in,out] s_templ InnoDB template structure
@param[in] add_v new virtual columns added along with
add index call
-@param[in] locked true if dict_sys mutex is held
-@param[in] share_tbl_name original MySQL table name */
+@param[in] locked true if dict_sys mutex is held */
void
innobase_build_v_templ(
const TABLE* table,
const dict_table_t* ib_table,
dict_vcol_templ_t* s_templ,
const dict_add_v_col_t* add_v,
- bool locked,
- const char* share_tbl_name)
+ bool locked)
{
ulint ncol = ib_table->n_cols - DATA_N_SYS_COLS;
ulint n_v_col = ib_table->n_v_cols;
@@ -6291,15 +6415,8 @@ innobase_build_v_templ(
* sizeof *s_templ->vtempl));
s_templ->n_col = ncol;
s_templ->n_v_col = n_v_col;
- s_templ->rec_len = table->s->stored_rec_length;
- // JAN: MySQL 5.6
- // s_templ->default_rec = table->s->default_values;
-
- s_templ->default_rec = static_cast<byte*>(
- ut_malloc_nokey(table->s->stored_rec_length));
- memcpy(s_templ->default_rec, table->s->default_values,
- table->s->stored_rec_length);
-
+ s_templ->rec_len = table->s->reclength;
+ s_templ->default_rec = table->s->default_values;
/* Mark those columns could be base columns */
for (ulint i = 0; i < ib_table->n_v_cols; i++) {
@@ -6399,12 +6516,7 @@ innobase_build_v_templ(
s_templ->db_name = table->s->db.str;
s_templ->tb_name = table->s->table_name.str;
-
- if (share_tbl_name) {
- s_templ->share_name = share_tbl_name;
- }
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/*******************************************************************//**
This function builds a translation table in INNOBASE_SHARE
@@ -6774,14 +6886,14 @@ ha_innobase::open(
if (ib_table != NULL
&& ((!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID)
- && table->s->stored_fields != dict_table_get_n_tot_u_cols(ib_table))
+ && table->s->fields != dict_table_get_n_tot_u_cols(ib_table))
|| (DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID)
- && (table->s->stored_fields
+ && (table->s->fields
!= dict_table_get_n_tot_u_cols(ib_table) - 1)))) {
ib::warn() << "Table " << norm_name << " contains "
<< dict_table_get_n_user_cols(ib_table) << " user"
- " defined columns in InnoDB, but " << table->s->stored_fields
+ " defined columns in InnoDB, but " << table->s->fields
<< " columns in MariaDB. Please check"
" INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and " REFMAN
"innodb-troubleshooting.html for how to resolve the"
@@ -6927,7 +7039,7 @@ ha_innobase::open(
DBUG_RETURN(ret_err);
}
- m_prebuilt = row_create_prebuilt(ib_table, table->s->stored_rec_length);
+ m_prebuilt = row_create_prebuilt(ib_table, table->s->reclength);
m_prebuilt->default_rec = table->s->default_values;
ut_ad(m_prebuilt->default_rec);
@@ -6939,12 +7051,10 @@ ha_innobase::open(
key_used_on_scan = m_primary_key;
-#ifdef MYSQL_VIRTUAL_COLUMNS
if (ib_table->n_v_cols) {
mutex_enter(&dict_sys->mutex);
if (ib_table->vc_templ == NULL) {
ib_table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t());
- ib_table->vc_templ->vtempl = NULL;
} else if (ib_table->get_ref_count() == 1) {
/* Clean and refresh the template if no one else
get hold on it */
@@ -6955,12 +7065,11 @@ ha_innobase::open(
if (ib_table->vc_templ->vtempl == NULL) {
innobase_build_v_templ(
table, ib_table, ib_table->vc_templ, NULL,
- true, m_share->table_name);
+ true);
}
mutex_exit(&dict_sys->mutex);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
if (!innobase_build_index_translation(table, ib_table, m_share)) {
sql_print_error("Build InnoDB index translation table for"
@@ -8058,10 +8167,9 @@ build_template_needs_field(
dict_index_t* index, /*!< in: InnoDB index to use */
const TABLE* table, /*!< in: MySQL table object */
ulint i, /*!< in: field index in InnoDB table */
- ulint sql_idx, /*!< in: field index in SQL table */
ulint num_v) /*!< in: num virtual column so far */
{
- const Field* field = table->field[sql_idx];
+ const Field* field = table->field[i];
if (!index_contains) {
if (read_just_key) {
@@ -8076,8 +8184,8 @@ build_template_needs_field(
return(field);
}
- if (bitmap_is_set(table->read_set, static_cast<uint>(sql_idx))
- || bitmap_is_set(table->write_set, static_cast<uint>(sql_idx))) {
+ if (bitmap_is_set(table->read_set, static_cast<uint>(i))
+ || bitmap_is_set(table->write_set, static_cast<uint>(i))) {
/* This field is needed in the query */
return(field);
@@ -8259,10 +8367,10 @@ ha_innobase::build_template(
{
dict_index_t* index;
dict_index_t* clust_index;
- ulint n_stored_fields;
+ ulint n_fields;
ibool fetch_all_in_key = FALSE;
ibool fetch_primary_key_cols = FALSE;
- ulint i, sql_idx;
+ ulint i;
if (m_prebuilt->select_lock_type == LOCK_X) {
/* We always retrieve the whole clustered index record if we
@@ -8315,12 +8423,11 @@ ha_innobase::build_template(
/* Below we check column by column if we need to access
the clustered index. */
- /* number of stored columns */
- n_stored_fields= (ulint)table->s->stored_fields;
+ n_fields = (ulint) table->s->fields; /* number of columns */
if (!m_prebuilt->mysql_template) {
m_prebuilt->mysql_template = (mysql_row_templ_t*)
- ut_malloc_nokey(n_stored_fields * sizeof(mysql_row_templ_t));
+ ut_malloc_nokey(n_fields * sizeof(mysql_row_templ_t));
}
m_prebuilt->template_type = whole_row
@@ -8342,14 +8449,10 @@ ha_innobase::build_template(
ulint num_v = 0;
/* Push down an index condition or an end_range check. */
- for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
+ for (i = 0; i < n_fields; i++) {
ibool index_contains;
- while (!table->field[sql_idx]->stored_in_db()) {
- sql_idx++;
- }
-
- if (innobase_is_v_fld(table->field[sql_idx])) {
+ if (innobase_is_v_fld(table->field[i])) {
index_contains = dict_index_contains_col_or_prefix(
index, num_v, true);
} else {
@@ -8372,8 +8475,7 @@ ha_innobase::build_template(
the subset
field->part_of_key.is_set(active_index)
which would be acceptable if end_range==NULL. */
- bool is_v = innobase_is_v_fld(table->field[sql_idx]);
-
+ bool is_v = innobase_is_v_fld(table->field[i]);
if (build_template_needs_field_in_icp(
index, m_prebuilt, index_contains,
is_v ? num_v : i - num_v, is_v)) {
@@ -8382,17 +8484,17 @@ ha_innobase::build_template(
mysql_row_templ_t* templ;
if (whole_row) {
- field = table->field[sql_idx];
+ field = table->field[i];
} else {
field = build_template_needs_field(
index_contains,
m_prebuilt->read_just_key,
fetch_all_in_key,
fetch_primary_key_cols,
- index, table, i, sql_idx, num_v);
+ index, table, i, num_v);
if (!field) {
if (innobase_is_v_fld(
- table->field[sql_idx])) {
+ table->field[i])) {
num_v++;
}
continue;
@@ -8474,7 +8576,7 @@ ha_innobase::build_template(
< m_prebuilt->index->n_uniq);
*/
}
- if (innobase_is_v_fld(table->field[sql_idx])) {
+ if (innobase_is_v_fld(table->field[i])) {
num_v++;
}
}
@@ -8486,15 +8588,11 @@ ha_innobase::build_template(
/* Include the fields that are not needed in index condition
pushdown. */
- for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
+ for (i = 0; i < n_fields; i++) {
mysql_row_templ_t* templ;
ibool index_contains;
- while (!table->field[sql_idx]->stored_in_db()) {
- sql_idx++;
- }
-
- if (innobase_is_v_fld(table->field[sql_idx])) {
+ if (innobase_is_v_fld(table->field[i])) {
index_contains = dict_index_contains_col_or_prefix(
index, num_v, true);
} else {
@@ -8502,7 +8600,7 @@ ha_innobase::build_template(
index, i - num_v, false);
}
- bool is_v = innobase_is_v_fld(table->field[sql_idx]);
+ bool is_v = innobase_is_v_fld(table->field[i]);
if (!build_template_needs_field_in_icp(
index, m_prebuilt, index_contains,
@@ -8511,16 +8609,16 @@ ha_innobase::build_template(
const Field* field;
if (whole_row) {
- field = table->field[sql_idx];
+ field = table->field[i];
} else {
field = build_template_needs_field(
index_contains,
m_prebuilt->read_just_key,
fetch_all_in_key,
fetch_primary_key_cols,
- index, table, i, sql_idx, num_v);
+ index, table, i, num_v);
if (!field) {
- if (innobase_is_v_fld(table->field[sql_idx])) {
+ if (innobase_is_v_fld(table->field[i])) {
num_v++;
}
continue;
@@ -8544,13 +8642,9 @@ ha_innobase::build_template(
/* No index condition pushdown */
m_prebuilt->idx_cond = NULL;
- for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
+ for (i = 0; i < n_fields; i++) {
const Field* field;
- while (!table->field[sql_idx]->stored_in_db()) {
- sql_idx++;
- }
-
if (whole_row) {
/* Even this is whole_row, if the seach is
on a virtual column, and read_just_key is
@@ -8558,7 +8652,7 @@ ha_innobase::build_template(
will not try to fill the value since they
are not stored in such index nor in the
cluster index. */
- if (innobase_is_v_fld(table->field[sql_idx])
+ if (innobase_is_v_fld(table->field[i])
&& m_prebuilt->read_just_key
&& !dict_index_contains_col_or_prefix(
m_prebuilt->index, num_v, true))
@@ -8570,11 +8664,11 @@ ha_innobase::build_template(
continue;
}
- field = table->field[sql_idx];
+ field = table->field[i];
} else {
ibool contain;
- if (innobase_is_v_fld(table->field[sql_idx])) {
+ if (innobase_is_v_fld(table->field[i])) {
contain = dict_index_contains_col_or_prefix(
index, num_v, true);
} else {
@@ -8583,16 +8677,14 @@ ha_innobase::build_template(
false);
}
-
field = build_template_needs_field(
contain,
m_prebuilt->read_just_key,
fetch_all_in_key,
fetch_primary_key_cols,
- index, table, i, sql_idx, num_v);
-
+ index, table, i, num_v);
if (!field) {
- if (innobase_is_v_fld(table->field[sql_idx])) {
+ if (innobase_is_v_fld(table->field[i])) {
num_v++;
}
continue;
@@ -9177,7 +9269,7 @@ calc_row_difference(
ulint n_changed = 0;
dfield_t dfield;
dict_index_t* clust_index;
- uint sql_idx,i, innodb_idx= 0;
+ uint i;
ibool changes_fts_column = FALSE;
ibool changes_fts_doc_col = FALSE;
trx_t* trx = thd_to_trx(thd);
@@ -9192,19 +9284,15 @@ calc_row_difference(
/* We use upd_buff to convert changed fields */
buf = (byte*) upd_buff;
- for (sql_idx = 0,i=0; i < n_fields; i++, sql_idx++) {
- field = table->field[sql_idx];
+ for (i = 0; i < n_fields; i++) {
+ field = table->field[i];
bool is_virtual = innobase_is_v_fld(field);
dict_col_t* col;
- if (!field->stored_in_db()) {
- continue;
- }
-
if (is_virtual) {
col = &prebuilt->table->v_cols[num_v].m_col;
} else {
- col = &prebuilt->table->cols[innodb_idx - num_v];
+ col = &prebuilt->table->cols[i - num_v];
}
o_ptr = (const byte*) old_row + get_field_offset(table, field);
@@ -9419,7 +9507,7 @@ calc_row_difference(
num_v++;
} else {
ufield->field_no = dict_col_get_clust_pos(
- &prebuilt->table->cols[innodb_idx - num_v],
+ &prebuilt->table->cols[i - num_v],
clust_index);
ufield->old_v_val = NULL;
}
@@ -9465,10 +9553,6 @@ calc_row_difference(
ut_ad(col->ord_part || online_ord_part);
num_v++;
}
-
- if (field->stored_in_db()) {
- innodb_idx++;
- }
}
/* If the update changes a column with an FTS index on it, we
@@ -9669,12 +9753,11 @@ ha_innobase::update_row(
ut_ad(m_upd_buf_size == 0);
/* Create a buffer for packing the fields of a record. Why
- table->stored_rec_length did not work here? Obviously,
- because char fields when packed actually became 1 byte
- longer, when we also stored the string length as the first
- byte. */
+ table->reclength did not work here? Obviously, because char
+ fields when packed actually became 1 byte longer, when we also
+ stored the string length as the first byte. */
- m_upd_buf_size = table->s->stored_rec_length + table->s->max_key_length
+ m_upd_buf_size = table->s->reclength + table->s->max_key_length
+ MAX_REF_PARTS * 3;
m_upd_buf = reinterpret_cast<uchar*>(
@@ -11704,7 +11787,43 @@ create_table_check_doc_id_col(
return(false);
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
+
+/** Finds all base columns needed to compute a given generated column.
+This is returned as a bitmap, in field->table->tmp_set.
+Works for both dict_v_col_t and dict_s_col_t columns.
+@param[in] table InnoDB table
+@param[in] field MySQL field
+@param[in,out] col virtual or stored column */
+template <typename T>
+void
+prepare_vcol_for_base_setup(
+/*========================*/
+ const dict_table_t* table,
+ const Field* field,
+ T* col)
+{
+ ut_ad(col->num_base == 0);
+ ut_ad(col->base_col == NULL);
+
+ MY_BITMAP *old_read_set = field->table->read_set;
+ MY_BITMAP *old_vcol_set = field->table->vcol_set;
+
+ field->table->read_set = field->table->vcol_set = &field->table->tmp_set;
+
+ bitmap_clear_all(&field->table->tmp_set);
+ field->vcol_info->expr_item->walk(
+ &Item::register_field_in_read_map, 1, field->table);
+ col->num_base= bitmap_bits_set(&field->table->tmp_set);
+ if (col->num_base != 0) {
+ col->base_col = static_cast<dict_col_t**>(mem_heap_zalloc(
+ table->heap, col->num_base * sizeof(
+ * col->base_col)));
+ }
+ field->table->read_set= old_read_set;
+ field->table->vcol_set= old_vcol_set;
+}
+
+
/** Set up base columns for virtual column
@param[in] table InnoDB table
@param[in] field MySQL field
@@ -11717,10 +11836,12 @@ innodb_base_col_setup(
{
int n = 0;
+ prepare_vcol_for_base_setup(table, field, v_col);
+
for (uint i= 0; i < field->table->s->fields; ++i) {
const Field* base_field = field->table->field[i];
- if (!base_field->is_virtual_gcol()
- && bitmap_is_set(&field->gcol_info->base_columns_map, i)) {
+ if (base_field->stored_in_db()
+ && bitmap_is_set(&field->table->tmp_set, i)) {
ulint z;
for (z = 0; z < table->n_cols; z++) {
@@ -11738,10 +11859,9 @@ innodb_base_col_setup(
n++;
}
}
+ v_col->num_base= n;
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
-#ifdef MYSQL_VIRTUAL_COLUMNS
/** Set up base columns for stored column
@param[in] table InnoDB table
@param[in] field MySQL field
@@ -11754,12 +11874,14 @@ innodb_base_col_setup_for_stored(
{
ulint n = 0;
+ prepare_vcol_for_base_setup(table, field, s_col);
+
for (uint i= 0; i < field->table->s->fields; ++i) {
const Field* base_field = field->table->field[i];
if (!innobase_is_s_fld(base_field)
&& !innobase_is_v_fld(base_field)
- && bitmap_is_set(&field->gcol_info->base_columns_map,
+ && bitmap_is_set(&field->table->tmp_set,
i)) {
ulint z;
for (z = 0; z < table->n_cols; z++) {
@@ -11781,8 +11903,8 @@ innodb_base_col_setup_for_stored(
}
}
}
+ s_col->num_base= n;
}
-#endif
/** Create a table definition to an InnoDB database.
@return ER_* level error */
@@ -11792,7 +11914,6 @@ create_table_info_t::create_table_def()
{
dict_table_t* table;
ulint n_cols;
- ulint s_cols;
ulint col_type;
ulint col_len;
ulint nulls_allowed;
@@ -11801,6 +11922,7 @@ create_table_info_t::create_table_def()
ulint long_true_varchar;
ulint charset_no;
ulint i;
+ ulint j = 0;
ulint doc_id_col = 0;
ibool has_doc_id_col = FALSE;
mem_heap_t* heap;
@@ -11837,9 +11959,7 @@ create_table_info_t::create_table_def()
}
n_cols = m_form->s->fields;
- s_cols = m_form->s->stored_fields;
-#ifdef MYSQL_VIRTUAL_COLUMNS
/* Find out any virtual column */
for (i = 0; i < n_cols; i++) {
Field* field = m_form->field[i];
@@ -11848,7 +11968,6 @@ create_table_info_t::create_table_def()
num_v++;
}
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
ut_ad(trx_state_eq(m_trx, TRX_STATE_NOT_STARTED));
@@ -11874,8 +11993,7 @@ create_table_info_t::create_table_def()
}
/* Adjust the number of columns for the FTS hidden field */
- actual_n_cols = m_form->s->stored_fields;
-
+ actual_n_cols = n_cols;
if (m_flags2 & DICT_TF2_FTS && !has_doc_id_col) {
actual_n_cols += 1;
}
@@ -11886,7 +12004,7 @@ create_table_info_t::create_table_def()
/* Set the hidden doc_id column. */
if (m_flags2 & DICT_TF2_FTS) {
table->fts->doc_col = has_doc_id_col
- ? doc_id_col : s_cols;
+ ? doc_id_col : n_cols - num_v;
}
if (strlen(m_temp_path) != 0) {
@@ -11915,12 +12033,9 @@ create_table_info_t::create_table_def()
for (i = 0; i < n_cols; i++) {
ulint is_virtual;
- bool is_stored MY_ATTRIBUTE((unused));
- Field* field = m_form->field[i];
+ bool is_stored = false;
- if (!field->stored_in_db()) {
- continue;
- }
+ Field* field = m_form->field[i];
col_type = get_innobase_type_from_mysql_type(
&unsigned_type, field);
@@ -12019,7 +12134,6 @@ err_col:
charset_no),
col_len);
} else {
-#ifdef MYSQL_VIRTUAL_COLUMNS
dict_mem_table_add_v_col(table, heap,
field->field_name, col_type,
dtype_form_prtype(
@@ -12028,26 +12142,18 @@ err_col:
| binary_type | long_true_varchar
| is_virtual,
charset_no),
- col_len, i,
- 0);
-
- field->gcol_info->non_virtual_base_columns());
-#endif
- }
+ col_len, i, 0);
+ }
-#ifdef MYSQL_VIRTUAL_COLUMNS
if (is_stored) {
ut_ad(!is_virtual);
/* Added stored column in m_s_cols list. */
dict_mem_table_add_s_col(
- table,
- field->gcol_info->non_virtual_base_columns());
+ table, 0);
}
-#endif
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
+
if (num_v) {
- ulint j = 0;
for (i = 0; i < n_cols; i++) {
dict_v_col_t* v_col;
@@ -12088,7 +12194,6 @@ err_col:
}
}
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/* Add the FTS doc_id hidden column. */
if (m_flags2 & DICT_TF2_FTS && !has_doc_id_col) {
@@ -12121,7 +12226,6 @@ err_col:
my_error(ER_TABLESPACE_CANNOT_ENCRYPT, MYF(0));
err = DB_UNSUPPORTED;
dict_mem_table_free(table);
- */
} else {
#endif /* MYSQL_COMPRESSION */
/* Get a new table ID */
@@ -13833,6 +13937,30 @@ create_table_info_t::initialize()
}
+/** Check if a virtual column is part of a fulltext or spatial index. */
+bool
+create_table_info_t::gcols_in_fulltext_or_spatial()
+{
+ for (ulint i = 0; i < m_form->s->keys; i++) {
+ const KEY* key = m_form->key_info + i;
+ if (key->flags & (HA_SPATIAL | HA_FULLTEXT)) {
+ for (ulint j = 0; j < key->user_defined_key_parts; j++) {
+ const KEY_PART_INFO* key_part = key->key_part + j;
+
+ /* We do not support special (Fulltext or
+ Spatial) index on virtual columns */
+ if (innobase_is_v_fld(key_part->field)) {
+ my_error(ER_UNSUPPORTED_ACTION_ON_VIRTUAL_COLUMN, MYF(0));
+ return true;
+ }
+ }
+ }
+
+ }
+ return false;
+}
+
+
/** Prepare to create a new table to an InnoDB database.
@param[in] name Table name
@return error number */
@@ -13874,6 +14002,10 @@ create_table_info_t::prepare_create_table(
DBUG_RETURN(HA_ERR_TABLE_READONLY);
}
+ if (gcols_in_fulltext_or_spatial()) {
+ DBUG_RETURN(HA_ERR_UNSUPPORTED);
+ }
+
DBUG_RETURN(parse_table_name(name));
}
@@ -14040,19 +14172,15 @@ create_table_info_t::create_table()
" table where referencing columns appear"
" as the first columns.\n", m_table_name);
break;
-#ifdef MYSQL_VIRTUAL_COLUMNS
- case DB_NO_FK_ON_V_BASE_COL:
+ case DB_NO_FK_ON_S_BASE_COL:
push_warning_printf(
m_thd, Sql_condition::WARN_LEVEL_WARN,
HA_ERR_CANNOT_ADD_FOREIGN,
"Create table '%s' with foreign key constraint"
" failed. Cannot add foreign key constraint"
- " placed on the base column of indexed"
- " virtual column, or constraint placed"
- " on columns being part of virtual index.\n",
+ " placed on the base column of stored"
+ " column. \n",
m_table_name);
- break;
-#endif
default:
break;
}
@@ -14647,8 +14775,7 @@ validate_create_tablespace_info(
THD* thd,
st_alter_tablespace* alter_info)
{
-
- int error = 0;
+ ulint space_id;
/* The parser ensures that these fields are provided. */
ut_a(alter_info->tablespace_name);
@@ -15427,6 +15554,7 @@ ha_innobase::records(
DBUG_RETURN(HA_ERR_QUERY_INTERRUPTED);
}
+ *num_rows= n_rows;
DBUG_RETURN(0);
}
#endif /* MYSQL_57_SELECT_COUNT_OPTIMIZATION */
@@ -23203,6 +23331,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
#endif
MYSQL_SYSVAR(instrument_semaphores),
MYSQL_SYSVAR(buf_dump_status_frequency),
+ MYSQL_SYSVAR(background_thread),
NULL
};
@@ -23377,29 +23506,29 @@ innobase_index_cond(
return handler_index_cond_check(file);
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
-/** Get the computed value by supplying the base column values.
-@param[in,out] table the table whose virtual column template to be built */
-void
-innobase_init_vc_templ(
+
+/** Find or open a mysql table for the virtual column template
+@param[in] thd mysql thread handle
+@param[in,out] table InnoDB table whose virtual column template is to be updated
+@return TABLE if successful or NULL */
+static TABLE *
+innobase_find_mysql_table_for_vc(
+/*=============================*/
+ THD* thd,
dict_table_t* table)
{
- char dbname[MAX_DATABASE_NAME_LEN + 1];
- char tbname[MAX_TABLE_NAME_LEN + 1];
- char* name = table->name.m_name;
- ulint dbnamelen = dict_get_db_name_len(name);
- ulint tbnamelen = strlen(name) - dbnamelen - 1;
- char t_dbname[MAX_DATABASE_NAME_LEN + 1];
- char t_tbname[MAX_TABLE_NAME_LEN + 1];
-
- mutex_enter(&dict_sys->mutex);
-
- if (table->vc_templ != NULL) {
- mutex_exit(&dict_sys->mutex);
-
- return;
+ if (table->vc_templ->mysql_table_query_id == thd_get_query_id(thd)) {
+ return table->vc_templ->mysql_table;
}
+ char dbname[MAX_DATABASE_NAME_LEN + 1];
+ char tbname[MAX_TABLE_NAME_LEN + 1];
+ char* name = table->name.m_name;
+ uint dbnamelen = dict_get_db_name_len(name);
+ uint tbnamelen = strlen(name) - dbnamelen - 1;
+ char t_dbname[MAX_DATABASE_NAME_LEN + 1];
+ char t_tbname[MAX_TABLE_NAME_LEN + 1];
+
strncpy(dbname, name, dbnamelen);
dbname[dbnamelen] = 0;
strncpy(tbname, name + dbnamelen + 1, tbnamelen);
@@ -23407,32 +23536,53 @@ innobase_init_vc_templ(
/* For partition table, remove the partition name and use the
"main" table name to build the template */
- char* is_part = is_partition(tbname);
+ char* is_part = is_partition(tbname);
if (is_part != NULL) {
*is_part = '\0';
tbnamelen = is_part - tbname;
}
- table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t());
- table->vc_templ->vtempl = NULL;
-
dbnamelen = filename_to_tablename(dbname, t_dbname,
MAX_DATABASE_NAME_LEN + 1);
tbnamelen = filename_to_tablename(tbname, t_tbname,
MAX_TABLE_NAME_LEN + 1);
-#ifdef UNIV_DEBUG
- // bool ret =
-#endif /* UNIV_DEBUG */
+ TABLE *mysql_table = find_fk_open_table(thd, t_dbname, dbnamelen,
+ t_tbname, tbnamelen);
- /* JAN: TODO: MySQL: 5.7 virtual columsn
- handler::my_prepare_gcolumn_template(
- thd, t_dbname, t_tbname,
- &innobase_build_v_templ_callback,
- static_cast<void*>(table));
- ut_ad(!ret);
- */
+ if (!mysql_table && THDVAR(thd, background_thread)) {
+ /* only open the table in background purge threads */
+ mysql_table = open_purge_table(thd, t_dbname, dbnamelen,
+ t_tbname, tbnamelen);
+ }
+
+ table->vc_templ->mysql_table = mysql_table;
+ table->vc_templ->mysql_table_query_id = thd_get_query_id(thd);
+ return mysql_table;
+}
+
+/** Get the computed value by supplying the base column values.
+@param[in,out] table table whose virtual column template to be built */
+void
+innobase_init_vc_templ(
+ dict_table_t* table)
+{
+ if (table->vc_templ != NULL) {
+ return;
+ }
+
+ table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t());
+
+ TABLE *mysql_table= innobase_find_mysql_table_for_vc(current_thd, table);
+
+ ut_ad(mysql_table);
+ if (!mysql_table) {
+ return;
+ }
+
+ mutex_enter(&dict_sys->mutex);
+ innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, true);
mutex_exit(&dict_sys->mutex);
}
@@ -23542,7 +23692,6 @@ innobase_get_computed_value(
upd_t* parent_update,
dict_foreign_t* foreign)
{
- byte rec_buf1[REC_VERSION_56_MAX_INDEX_COL_LEN];
byte rec_buf2[REC_VERSION_56_MAX_INDEX_COL_LEN];
byte* mysql_rec;
byte* buf;
@@ -23568,15 +23717,20 @@ innobase_get_computed_value(
*local_heap = mem_heap_create(UNIV_PAGE_SIZE);
}
- mysql_rec = static_cast<byte*>(mem_heap_alloc(
- *local_heap, index->table->vc_templ->rec_len));
buf = static_cast<byte*>(mem_heap_alloc(
*local_heap, index->table->vc_templ->rec_len));
} else {
- mysql_rec = rec_buf1;
buf = rec_buf2;
}
+ if (!mysql_table) {
+ mysql_table = innobase_find_mysql_table_for_vc(thd, index->table);
+ }
+
+ ut_ad(mysql_table);
+
+ mysql_rec = mysql_table->record[0];
+
for (ulint i = 0; i < col->num_base; i++) {
dict_col_t* base_col = col->base_col[i];
const dfield_t* row_field = NULL;
@@ -23635,46 +23789,11 @@ innobase_get_computed_value(
field = dtuple_get_nth_v_field(row, col->v_pos);
- /* Bitmap for specifying which virtual columns the server
- should evaluate */
- MY_BITMAP column_map;
- my_bitmap_map col_map_storage[bitmap_buffer_size(REC_MAX_N_FIELDS)];
-
- bitmap_init(&column_map, col_map_storage, REC_MAX_N_FIELDS, false);
-
- /* Specify the column the server should evaluate */
- bitmap_set_bit(&column_map, col->m_col.ind);
-
- if (mysql_table == NULL) {
- if (vctempl->type == DATA_BLOB) {
- ulint max_len;
-
- if (vctempl->mysql_col_len - 8 == 1) {
- /* This is for TINYBLOB only, which needs
- only 1 byte, other BLOBs won't be affected */
- max_len = 255;
- } else {
- max_len = DICT_MAX_FIELD_LEN_BY_FORMAT(
- index->table) + 1;
- }
-
- byte* blob_mem = static_cast<byte*>(
- mem_heap_alloc(heap, max_len));
-
- row_mysql_store_blob_ref(
- mysql_rec + vctempl->mysql_col_offset,
- vctempl->mysql_col_len, blob_mem, max_len);
- }
-
- ret = handler::my_eval_gcolumn_expr_with_open(
- thd, index->table->vc_templ->db_name.c_str(),
- index->table->vc_templ->tb_name.c_str(), &column_map,
- (uchar *)mysql_rec);
- } else {
- ret = handler::my_eval_gcolumn_expr(
- thd, mysql_table, &column_map,
- (uchar *)mysql_rec);
- }
+ my_bitmap_map* old_write_set = dbug_tmp_use_all_columns(mysql_table, mysql_table->write_set);
+ my_bitmap_map* old_read_set = dbug_tmp_use_all_columns(mysql_table, mysql_table->read_set);
+ ret = mysql_table->update_virtual_field(mysql_table->field[col->m_col.ind]);
+ dbug_tmp_restore_column_map(mysql_table->read_set, old_read_set);
+ dbug_tmp_restore_column_map(mysql_table->write_set, old_write_set);
if (ret != 0) {
#ifdef INNODB_VIRTUAL_DEBUG
@@ -23725,7 +23844,7 @@ innobase_get_computed_value(
return(field);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
+
/** Attempt to push down an index condition.
@param[in] keyno MySQL key number
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index a78925d94e1..99d50d82fd1 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -119,6 +119,8 @@ public:
const key_map* keys_to_use_for_scanning();
+ void column_bitmaps_signal();
+
/** Opens dictionary table object using table name. For partition, we need to
try alternative lower/upper case names to support moving data files across
platforms.
@@ -781,6 +783,8 @@ public:
@return NULL if valid, string name of bad option if not. */
const char* create_options_are_invalid();
+ bool gcols_in_fulltext_or_spatial();
+
/** Validates engine specific table options not handled by
SQL-parser.
@return NULL if valid, string name of bad option if not. */
@@ -1037,13 +1041,9 @@ innodb_base_col_setup_for_stored(
dict_s_col_t* s_col);
/** whether this is a stored column */
-// JAN: TODO: MySQL 5.7 virtual fields
-//#define innobase_is_s_fld(field) ((field)->gcol_info && (field)->stored_in_db)
-#define innobase_is_s_fld(field) (field == NULL)
-// JAN: TODO: MySQL 5.7 virtual fields
+#define innobase_is_s_fld(field) ((field)->vcol_info && (field)->stored_in_db())
/** whether this is a computed virtual column */
-//#define innobase_is_v_fld(field) ((field)->gcol_info && !(field)->stored_in_db)
-#define innobase_is_v_fld(field) (field == NULL)
+#define innobase_is_v_fld(field) ((field)->vcol_info && !(field)->stored_in_db())
/** Release temporary latches.
Call this function when mysqld passes control to the client. That is to
@@ -1120,16 +1120,14 @@ innodb_rec_per_key(
@param[in,out] s_templ InnoDB template structure
@param[in] add_v new virtual columns added along with
add index call
-@param[in] locked true if innobase_share_mutex is held
-@param[in] share_tbl_name original MySQL table name */
+@param[in] locked true if innobase_share_mutex is held */
void
innobase_build_v_templ(
const TABLE* table,
const dict_table_t* ib_table,
dict_vcol_templ_t* s_templ,
const dict_add_v_col_t* add_v,
- bool locked,
- const char* share_tbl_name);
+ bool locked);
/** callback used by MySQL server layer to initialized
the table virtual columns' template
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 3da543d246e..51aef715ee2 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -59,6 +59,10 @@ Smart ALTER TABLE
#include <sql_acl.h> // PROCESS_ACL
#endif
+static const char *MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN=
+ "INPLACE ADD or DROP of virtual columns cannot be "
+ "combined with other ALTER TABLE actions";
+
/* For supporting Native InnoDB Partitioning. */
/* JAN: TODO: MySQL 5.7
#include "partition_info.h"
@@ -67,7 +71,8 @@ Smart ALTER TABLE
/** Operations for creating secondary indexes (no rebuild needed) */
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ONLINE_CREATE
= Alter_inplace_info::ADD_INDEX
- | Alter_inplace_info::ADD_UNIQUE_INDEX;
+ | Alter_inplace_info::ADD_UNIQUE_INDEX
+ | Alter_inplace_info::ADD_SPATIAL_INDEX;
/** Operations for rebuilding a table in place */
static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_REBUILD
@@ -77,17 +82,12 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_REBUILD
/* CHANGE_CREATE_OPTION needs to check innobase_need_rebuild() */
| Alter_inplace_info::ALTER_COLUMN_NULLABLE
| Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE
- | Alter_inplace_info::ALTER_COLUMN_ORDER
- | Alter_inplace_info::DROP_COLUMN
- | Alter_inplace_info::ADD_COLUMN
-#ifdef MYSQL_VIRTUAL_COLUMNS
| Alter_inplace_info::ALTER_STORED_COLUMN_ORDER
| Alter_inplace_info::DROP_STORED_COLUMN
| Alter_inplace_info::ADD_STORED_BASE_COLUMN
- | Alter_inplace_info::ALTER_STORED_COLUMN_TYPE
-#endif
| Alter_inplace_info::RECREATE_TABLE
/*
+ | Alter_inplace_info::ALTER_STORED_COLUMN_TYPE
*/
;
@@ -101,9 +101,7 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_INPLACE_IGNORE
| Alter_inplace_info::ALTER_PARTITIONED
| Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT
| Alter_inplace_info::ALTER_COLUMN_STORAGE_TYPE
-#ifdef MYSQL_VIRTUAL_COLUMNS
| Alter_inplace_info::ALTER_VIRTUAL_GCOL_EXPR
-#endif
| Alter_inplace_info::ALTER_RENAME;
/** Operations on foreign key definitions (changing the schema only) */
@@ -121,15 +119,12 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_NOREBUILD
| Alter_inplace_info::RENAME_INDEX
#endif
| Alter_inplace_info::ALTER_COLUMN_NAME
- | Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH;
-#ifdef MYSQL_VIRTUAL_COLUMNS
- | Alter_inplace_info::ALTER_INDEX_COMMENT
+ | Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH
+ //| Alter_inplace_info::ALTER_INDEX_COMMENT
| Alter_inplace_info::ADD_VIRTUAL_COLUMN
| Alter_inplace_info::DROP_VIRTUAL_COLUMN
- | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER
- | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_TYPE
-#endif
- ;
+ | Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER;
+
struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx
{
/** Dummy query graph */
@@ -453,7 +448,6 @@ innobase_need_rebuild(
return(!!(ha_alter_info->handler_flags & INNOBASE_ALTER_REBUILD));
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
/** Check if virtual column in old and new table are in order, excluding
those dropped column. This is needed because when we drop a virtual column,
ALTER_VIRTUAL_COLUMN_ORDER is also turned on, so we can't decide if this
@@ -484,7 +478,7 @@ check_v_col_in_order(
cf_it.rewind();
while (const Create_field* new_field = cf_it++) {
- if (!new_field->is_virtual_gcol()) {
+ if (!innobase_is_v_fld(new_field)) {
continue;
}
@@ -510,11 +504,9 @@ check_v_col_in_order(
}
for (ulint i = 0; i < table->s->fields; i++) {
- Field* field = table->s->field[i];
- bool dropped = false;
- Alter_drop* drop;
+ Field* field = table->field[i];
- if (field->stored_in_db) {
+ if (field->stored_in_db()) {
continue;
}
@@ -529,7 +521,7 @@ check_v_col_in_order(
while (j < altered_table->s->fields) {
Field* new_field = altered_table->s->field[j];
- if (new_field->stored_in_db) {
+ if (new_field->stored_in_db()) {
j++;
continue;
}
@@ -555,7 +547,6 @@ check_v_col_in_order(
return(true);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/** Check if InnoDB supports a particular alter table in-place
@param altered_table TABLE object for new version of table.
@@ -590,7 +581,7 @@ ha_innobase::check_if_supported_inplace_alter(
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
- if (altered_table->s->stored_fields > REC_MAX_N_USER_FIELDS) {
+ if (altered_table->s->fields > REC_MAX_N_USER_FIELDS) {
/* Deny the inplace ALTER TABLE. MySQL will try to
re-create the table and ha_innobase::create() will
return an error too. This is how we effectively
@@ -646,14 +637,11 @@ ha_innobase::check_if_supported_inplace_alter(
| INNOBASE_ALTER_NOREBUILD
| INNOBASE_ALTER_REBUILD)) {
-#ifdef MYSQL_VIRTUAL_COLUMNS
if (ha_alter_info->handler_flags
& Alter_inplace_info::ALTER_STORED_COLUMN_TYPE) {
ha_alter_info->unsupported_reason = innobase_get_err_msg(
ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE);
}
-#endif
-
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
@@ -794,8 +782,8 @@ ha_innobase::check_if_supported_inplace_alter(
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
- // JAN: TODO: MySQL 5.7 Virtual columns
+ bool add_drop_v_cols = false;
+
/* If there is add or drop virtual columns, we will support operations
with these 2 options alone with inplace interface for now */
@@ -812,8 +800,8 @@ ha_innobase::check_if_supported_inplace_alter(
| Alter_inplace_info::DROP_VIRTUAL_COLUMN
| Alter_inplace_info::ALTER_VIRTUAL_COLUMN_ORDER
| Alter_inplace_info::ALTER_VIRTUAL_GCOL_EXPR
+ | Alter_inplace_info::ALTER_COLUMN_VCOL
/*
- | Alter_inplace_info::ALTER_STORED_COLUMN_ORDER
| Alter_inplace_info::ADD_STORED_BASE_COLUMN
| Alter_inplace_info::DROP_STORED_COLUMN
| Alter_inplace_info::ALTER_STORED_COLUMN_ORDER
@@ -828,14 +816,12 @@ ha_innobase::check_if_supported_inplace_alter(
|| (!check_v_col_in_order(
this->table, altered_table, ha_alter_info))) {
ha_alter_info->unsupported_reason =
- innobase_get_err_msg(
- ER_UNSUPPORTED_ALTER_INPLACE_ON_VIRTUAL_COLUMN);
+ MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN;
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
add_drop_v_cols = true;
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/* We should be able to do the operation in-place.
See if we can do it online (LOCK=NONE). */
@@ -850,18 +836,15 @@ ha_innobase::check_if_supported_inplace_alter(
+ ha_alter_info->key_count;
new_key++) {
-#ifdef MYSQL_VIRTUAL_COLUMNS
/* Do not support adding/droping a virtual column, while
there is a table rebuild caused by adding a new FTS_DOC_ID */
if ((new_key->flags & HA_FULLTEXT) && add_drop_v_cols
&& !DICT_TF2_FLAG_IS_SET(m_prebuilt->table,
DICT_TF2_FTS_HAS_DOC_ID)) {
ha_alter_info->unsupported_reason =
- innobase_get_err_msg(
- ER_UNSUPPORTED_ALTER_INPLACE_ON_VIRTUAL_COLUMN);
+ MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN;
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
for (KEY_PART_INFO* key_part = new_key->key_part;
key_part < new_key->key_part + new_key->user_defined_key_parts;
@@ -928,31 +911,27 @@ ha_innobase::check_if_supported_inplace_alter(
online = false;
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
- if (key_part->field->is_virtual_gcol()) {
+ if (innobase_is_v_fld(key_part->field)) {
/* Do not support adding index on newly added
virtual column, while there is also a drop
virtual column in the same clause */
if (ha_alter_info->handler_flags
& Alter_inplace_info::DROP_VIRTUAL_COLUMN) {
ha_alter_info->unsupported_reason =
- innobase_get_err_msg(
- ER_UNSUPPORTED_ALTER_INPLACE_ON_VIRTUAL_COLUMN);
+ MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN;
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
ha_alter_info->unsupported_reason =
- innobase_get_err_msg(
- ER_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN);
+ MSG_UNSUPPORTED_ALTER_ONLINE_ON_VIRTUAL_COLUMN;
online = false;
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
}
}
DBUG_ASSERT(!m_prebuilt->table->fts || m_prebuilt->table->fts->doc_col
- <= table->s->stored_fields);
+ <= table->s->fields);
DBUG_ASSERT(!m_prebuilt->table->fts || m_prebuilt->table->fts->doc_col
< dict_table_get_n_user_cols(m_prebuilt->table));
@@ -1356,8 +1335,6 @@ next_rec:
return(NULL);
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
-
/** Check whether given column is a base of stored column.
@param[in] col_name column name
@param[in] table table
@@ -1419,7 +1396,6 @@ innobase_check_fk_stored(
return(false);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/** Create InnoDB foreign key structure from MySQL alter_info
@param[in] ha_alter_info alter table info
@@ -1667,13 +1643,14 @@ innobase_get_foreign_key_info(
goto err_exit;
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
if (innobase_check_fk_stored(
add_fk[num_fk], table, s_cols)) {
- my_error(ER_CANNOT_ADD_FOREIGN_BASE_COL_STORED, MYF(0));
+ my_printf_error(
+ HA_ERR_UNSUPPORTED,
+ "Cannot add foreign key on the base column "
+ "of stored column", MYF(0));
goto err_exit;
}
-#endif
num_fk++;
}
@@ -1794,24 +1771,19 @@ innobase_rec_to_mysql(
const ulint* offsets)/*!< in: rec_get_offsets(
rec, index, ...) */
{
- uint n_fields = table->s->stored_fields;
- uint sql_idx = 0;
+ uint n_fields = table->s->fields;
ut_ad(n_fields == dict_table_get_n_user_cols(index->table)
- !!(DICT_TF2_FLAG_IS_SET(index->table,
DICT_TF2_FTS_HAS_DOC_ID)));
- for (uint i = 0; i < n_fields; i++, sql_idx++) {
- Field* field;
+ for (uint i = 0; i < n_fields; i++) {
+ Field* field = table->field[i];
ulint ipos;
ulint ilen;
const uchar* ifield;
ulint prefix_col;
- while (!((field= table->field[sql_idx])->stored_in_db())) {
- sql_idx++;
- }
-
field->reset();
ipos = dict_index_get_nth_col_or_prefix_pos(
@@ -1852,8 +1824,7 @@ innobase_fields_to_mysql(
const dict_index_t* index, /*!< in: InnoDB index */
const dfield_t* fields) /*!< in: InnoDB index fields */
{
- uint n_fields = table->s->stored_fields;
- uint sql_idx = 0;
+ uint n_fields = table->s->fields;
ulint num_v = 0;
ut_ad(n_fields == dict_table_get_n_user_cols(index->table)
@@ -1861,16 +1832,12 @@ innobase_fields_to_mysql(
- !!(DICT_TF2_FLAG_IS_SET(index->table,
DICT_TF2_FTS_HAS_DOC_ID)));
- for (uint i = 0; i < n_fields; i++, sql_idx++) {
- Field* field;
+ for (uint i = 0; i < n_fields; i++) {
+ Field* field = table->field[i];
ulint ipos;
ulint col_n;
ulint prefix_col;
- while (!((field= table->field[sql_idx])->stored_in_db())) {
- sql_idx++;
- }
-
field->reset();
if (innobase_is_v_fld(field)) {
@@ -1914,9 +1881,8 @@ innobase_row_to_mysql(
const dict_table_t* itab, /*!< in: InnoDB table */
const dtuple_t* row) /*!< in: InnoDB row */
{
- uint n_fields = table->s->stored_fields;
- uint sql_idx = 0;
- uint num_v = 0;
+ uint n_fields = table->s->fields;
+ ulint num_v = 0;
/* The InnoDB row may contain an extra FTS_DOC_ID column at the end. */
ut_ad(row->n_fields == dict_table_get_n_cols(itab));
@@ -1924,12 +1890,8 @@ innobase_row_to_mysql(
+ dict_table_get_n_v_cols(itab)
- !!(DICT_TF2_FLAG_IS_SET(itab, DICT_TF2_FTS_HAS_DOC_ID)));
- for (uint i = 0; i < n_fields; i++, sql_idx++) {
- Field* field;
-
- while (!((field= table->field[sql_idx])->stored_in_db())) {
- sql_idx++;
- }
+ for (uint i = 0; i < n_fields; i++) {
+ Field* field = table->field[i];
field->reset();
@@ -1953,6 +1915,11 @@ innobase_row_to_mysql(
dfield_get_len(df), field);
}
}
+ if (table->vfield) {
+ my_bitmap_map* old_vcol_set = tmp_use_all_columns(table, table->vcol_set);
+ table->update_virtual_fields(VCOL_UPDATE_FOR_READ_WRITE);
+ tmp_restore_column_map(table->vcol_set, old_vcol_set);
+ }
}
/*************************************************************//**
@@ -2129,22 +2096,19 @@ name_ok:
is not being created
@param[in] key_part MySQL key definition
@param[in,out] index_field index field
-@param[in] new_clustered new cluster
-@param[in] fields MySQL table fields*/
+@param[in] new_clustered new cluster */
static
void
innobase_create_index_field_def(
const TABLE* altered_table,
const KEY_PART_INFO* key_part,
index_field_t* index_field,
- bool new_clustered,
- const Field** fields)
+ bool new_clustered)
{
const Field* field;
ibool is_unsigned;
ulint col_type;
ulint num_v = 0;
- ulint num_m_v = 0;
DBUG_ENTER("innobase_create_index_field_def");
@@ -2157,33 +2121,21 @@ innobase_create_index_field_def(
ut_a(field);
for (ulint i = 0; i < key_part->fieldnr; i++) {
- const Field* ifield = altered_table->field[i];
- if (innobase_is_v_fld(ifield)) {
+ if (innobase_is_v_fld(altered_table->field[i])) {
num_v++;
}
-
- if (!ifield->stored_in_db()) {
- num_m_v++;
- }
}
col_type = get_innobase_type_from_mysql_type(
&is_unsigned, field);
-#ifdef MYSQL_VIRTUAL_COLUMNS
- if (!field->stored_in_db && field->gcol_info) {
- if (!field->stored_in_db && false) {
- index_field->is_v_col = true;
- index_field->col_no = num_v;
- } else {
- index_field->is_v_col = false;
- index_field->col_no = key_part->fieldnr - num_v;
- }
+ if (innobase_is_v_fld(field)) {
+ index_field->is_v_col = true;
+ index_field->col_no = num_v;
+ } else {
+ index_field->is_v_col = false;
+ index_field->col_no = key_part->fieldnr - num_v;
}
-#else
- index_field->is_v_col = false;
- index_field->col_no = key_part->fieldnr - num_m_v;
-#endif /* MYSQL_VIRTUAL_COLUMNS */
if (DATA_LARGE_MTYPE(col_type)
|| (key_part->length < field->pack_length()
@@ -2218,8 +2170,7 @@ innobase_create_index_def(
bool new_clustered,
bool key_clustered,
index_def_t* index,
- mem_heap_t* heap,
- const Field** fields)
+ mem_heap_t* heap)
{
const KEY* key = &keys[key_number];
ulint i;
@@ -2298,21 +2249,16 @@ innobase_create_index_def(
index->fields[0].prefix_len = 0;
index->fields[0].is_v_col = false;
- #ifdef MYSQL_VIRTUAL_COLUMNS
- if (!key->key_part[0].field->stored_in_db
- && key->key_part[0].field->gcol_info) {
+ if (innobase_is_v_fld(key->key_part[0].field)) {
/* Currently, the spatial index cannot be created
on virtual columns. It is blocked in server
layer */
-
ut_ad(0);
index->fields[0].is_v_col = true;
} else {
-
index->fields[0].is_v_col = false;
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
} else {
index->ind_type = (key->flags & HA_NOSAME) ? DICT_UNIQUE : 0;
}
@@ -2321,7 +2267,7 @@ innobase_create_index_def(
for (i = 0; i < n_fields; i++) {
innobase_create_index_field_def(
altered_table, &key->key_part[i],
- &index->fields[i], new_clustered, fields);
+ &index->fields[i], new_clustered);
if (index->fields[i].is_v_col) {
index->ind_type |= DICT_VIRTUAL;
@@ -2352,18 +2298,13 @@ innobase_fts_check_doc_id_col(
{
*fts_doc_col_no = ULINT_UNDEFINED;
- const uint n_cols = altered_table->s->stored_fields;
- uint sql_idx = 0;
+ const uint n_cols = altered_table->s->fields;
ulint i;
*num_v = 0;
- for (i = 0; i < n_cols; i++, sql_idx++) {
- const Field* field;
-
- while (!((field= altered_table->field[sql_idx])->stored_in_db())) {
- sql_idx++;
- }
+ for (i = 0; i < n_cols; i++) {
+ const Field* field = altered_table->field[i];
if (innobase_is_v_fld(field)) {
(*num_v)++;
@@ -2676,7 +2617,7 @@ innobase_create_key_defs(
/* Create the PRIMARY key index definition */
innobase_create_index_def(
altered_table, key_info, primary_key_number,
- TRUE, TRUE, indexdef++, heap, (const Field **)altered_table->field);
+ true, true, indexdef++, heap);
created_clustered:
n_add = 1;
@@ -2688,7 +2629,7 @@ created_clustered:
/* Copy the index definitions. */
innobase_create_index_def(
altered_table, key_info, i, true,
- false, indexdef, heap, (const Field **)altered_table->field);
+ false, indexdef, heap);
if (indexdef->ind_type & DICT_FTS) {
n_fts_add++;
@@ -2705,8 +2646,7 @@ created_clustered:
&& !innobase_fts_check_doc_id_col(
NULL, altered_table,
&fts_doc_id_col, &num_v)) {
- fts_doc_id_col =
- altered_table->s->stored_fields;
+ fts_doc_id_col = altered_table->s->fields - num_v;
add_fts_doc_id = true;
}
@@ -2735,7 +2675,7 @@ created_clustered:
for (ulint i = 0; i < n_add; i++) {
innobase_create_index_def(
altered_table, key_info, add[i],
- false, false, indexdef, heap, (const Field **)altered_table->field);
+ false, false, indexdef, heap);
if (indexdef->ind_type & DICT_FTS) {
n_fts_add++;
@@ -3136,16 +3076,15 @@ innobase_build_col_map(
dtuple_t* add_cols,
mem_heap_t* heap)
{
- uint old_i, old_innobase_i;
DBUG_ENTER("innobase_build_col_map");
DBUG_ASSERT(altered_table != table);
DBUG_ASSERT(new_table != old_table);
DBUG_ASSERT(dict_table_get_n_cols(new_table)
+ dict_table_get_n_v_cols(new_table)
- >= altered_table->s->stored_fields + DATA_N_SYS_COLS);
+ >= altered_table->s->fields + DATA_N_SYS_COLS);
DBUG_ASSERT(dict_table_get_n_cols(old_table)
+ dict_table_get_n_v_cols(old_table)
- >= table->s->stored_fields + DATA_N_SYS_COLS);
+ >= table->s->fields + DATA_N_SYS_COLS);
DBUG_ASSERT(!!add_cols == !!(ha_alter_info->handler_flags
& Alter_inplace_info::ADD_COLUMN));
DBUG_ASSERT(!add_cols || dtuple_get_n_fields(add_cols)
@@ -3158,14 +3097,13 @@ innobase_build_col_map(
List_iterator_fast<Create_field> cf_it(
ha_alter_info->alter_info->create_list);
- uint i = 0, sql_idx = 0;
+ uint i = 0;
uint num_v = 0;
/* Any dropped columns will map to ULINT_UNDEFINED. */
- for (old_innobase_i = 0;
- old_innobase_i + DATA_N_SYS_COLS < old_table->n_cols;
- old_innobase_i++) {
- col_map[old_innobase_i] = ULINT_UNDEFINED;
+ for (uint old_i = 0; old_i + DATA_N_SYS_COLS < old_table->n_cols;
+ old_i++) {
+ col_map[old_i] = ULINT_UNDEFINED;
}
for (uint old_i = 0; old_i < old_table->n_v_cols; old_i++) {
@@ -3181,21 +3119,8 @@ innobase_build_col_map(
ulint num_old_v = 0;
- if (!new_field->stored_in_db())
- {
- sql_idx++;
- continue;
- }
-
- for (old_i = 0, old_innobase_i= 0;
- table->field[old_i];
- old_i++) {
+ for (uint old_i = 0; table->field[old_i]; old_i++) {
const Field* field = table->field[old_i];
-
- if (!table->field[old_i]->stored_in_db()) {
- continue;
- }
-
if (innobase_is_v_fld(field)) {
if (is_v && new_field->field == field) {
col_map[old_table->n_cols + num_v]
@@ -3208,30 +3133,27 @@ innobase_build_col_map(
}
if (new_field->field == field) {
- col_map[old_innobase_i] = i;
+ col_map[old_i - num_old_v] = i;
goto found_col;
}
- old_innobase_i++;
}
ut_ad(!is_v);
innobase_build_col_map_add(
heap, dtuple_get_nth_field(add_cols, i),
- altered_table->field[sql_idx],
+ altered_table->field[i + num_v],
dict_table_is_comp(new_table));
found_col:
if (is_v) {
num_v++;
} else {
i++;
- sql_idx++;
}
}
- DBUG_ASSERT(i == altered_table->s->stored_fields - num_v);
+ DBUG_ASSERT(i == altered_table->s->fields - num_v);
- i = table->s->stored_fields;
- //i = table->s->fields - old_table->n_v_cols;
+ i = table->s->fields - old_table->n_v_cols;
/* Add the InnoDB hidden FTS_DOC_ID column, if any. */
if (i + DATA_N_SYS_COLS < old_table->n_cols) {
@@ -3241,21 +3163,21 @@ found_col:
DICT_TF2_FTS_HAS_DOC_ID));
DBUG_ASSERT(i + DATA_N_SYS_COLS + 1 == old_table->n_cols);
DBUG_ASSERT(!strcmp(dict_table_get_col_name(
- old_table, table->s->stored_fields),
+ old_table, i),
FTS_DOC_ID_COL_NAME));
- if (altered_table->s->stored_fields + DATA_N_SYS_COLS
+ if (altered_table->s->fields + DATA_N_SYS_COLS
- new_table->n_v_cols
< new_table->n_cols) {
DBUG_ASSERT(DICT_TF2_FLAG_IS_SET(
new_table,
DICT_TF2_FTS_HAS_DOC_ID));
- DBUG_ASSERT(altered_table->s->stored_fields
+ DBUG_ASSERT(altered_table->s->fields
+ DATA_N_SYS_COLS + 1
- == new_table->n_cols);
- col_map[i] = altered_table->s->stored_fields;
- /* col_map[i] = altered_table->s->fields
+ == static_cast<ulint>(
+ new_table->n_cols
+ + new_table->n_v_cols));
+ col_map[i] = altered_table->s->fields
- new_table->n_v_cols;
- */
} else {
DBUG_ASSERT(!DICT_TF2_FLAG_IS_SET(
new_table,
@@ -3671,8 +3593,6 @@ innobase_check_gis_columns(
DBUG_RETURN(DB_SUCCESS);
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
-
/** Collect virtual column info for its addition
@param[in] ha_alter_info Data used during in-place alter
@param[in] altered_table MySQL table that is being altered to
@@ -3738,10 +3658,8 @@ prepare_inplace_add_virtual(
&is_unsigned, field);
- if (!field->gcol_info || field->stored_in_db) {
- my_error(ER_WRONG_KEY_COLUMN, MYF(0),
- field->field_name);
- return(true);
+ if (!innobase_is_v_fld(field)) {
+ continue;
}
col_len = field->pack_length();
@@ -3798,13 +3716,9 @@ prepare_inplace_add_virtual(
ctx->add_vcol[j].m_col.len = col_len;
ctx->add_vcol[j].m_col.ind = i - 1;
- /* ctx->add_vcol[j].num_base =
- field->gcol_info->non_virtual_base_columns();
- */
+ ctx->add_vcol[j].num_base = 0;
ctx->add_vcol_name[j] = field->field_name;
- ctx->add_vcol[j].base_col = static_cast<dict_col_t**>(
- mem_heap_alloc(ctx->heap, ctx->add_vcol[j].num_base
- * sizeof *(ctx->add_vcol[j].base_col)));
+ ctx->add_vcol[j].base_col = NULL;
ctx->add_vcol[j].v_pos = ctx->old_table->n_v_cols
- ctx->num_to_drop_vcol + j;
@@ -3833,12 +3747,17 @@ prepare_inplace_drop_virtual(
ha_innobase_inplace_ctx* ctx;
ulint i = 0;
ulint j = 0;
- Alter_drop *drop;
ctx = static_cast<ha_innobase_inplace_ctx*>
(ha_alter_info->handler_ctx);
- ctx->num_to_drop_vcol = ha_alter_info->alter_info->drop_list.elements;
+ ctx->num_to_drop_vcol = 0;
+ for (i = 0; table->field[i]; i++) {
+ const Field* field = table->field[i];
+ if (field->flags & FIELD_IS_DROPPED && !field->stored_in_db()) {
+ ctx->num_to_drop_vcol++;
+ }
+ }
ctx->drop_vcol = static_cast<dict_v_col_t*>(
mem_heap_alloc(ctx->heap, ctx->num_to_drop_vcol
@@ -3847,26 +3766,9 @@ prepare_inplace_drop_virtual(
mem_heap_alloc(ctx->heap, ctx->num_to_drop_vcol
* sizeof *ctx->drop_vcol_name));
- List_iterator_fast<Alter_drop> cf_it(
- ha_alter_info->alter_info->drop_list);
-
- while ((drop = (cf_it++)) != NULL) {
- const Field* field;
- ulint old_i;
-
- ut_ad(drop->type == Alter_drop::COLUMN);
-
- for (old_i = 0; table->field[old_i]; old_i++) {
- const Field* n_field = table->field[old_i];
- if (!my_strcasecmp(system_charset_info,
- n_field->field_name, drop->name)) {
- break;
- }
- }
-
- i++;
-
- if (!table->field[old_i]) {
+ for (i = 0; table->field[i]; i++) {
+ Field *field = table->field[i];
+ if (!(field->flags & FIELD_IS_DROPPED) || field->stored_in_db()) {
continue;
}
@@ -3875,19 +3777,10 @@ prepare_inplace_drop_virtual(
ulint field_type;
ulint charset_no;
- field = table->field[old_i];
-
ulint col_type
= get_innobase_type_from_mysql_type(
&is_unsigned, field);
-
- if (!field->gcol_info || field->stored_in_db) {
- my_error(ER_WRONG_KEY_COLUMN, MYF(0),
- field->field_name);
- return(true);
- }
-
col_len = field->pack_length();
field_type = (ulint) field->type();
@@ -3941,12 +3834,12 @@ prepare_inplace_drop_virtual(
ctx->drop_vcol[j].m_col.len = col_len;
- ctx->drop_vcol[j].m_col.ind = old_i;
+ ctx->drop_vcol[j].m_col.ind = i;
ctx->drop_vcol_name[j] = field->field_name;
dict_v_col_t* v_col = dict_table_get_nth_v_col_mysql(
- ctx->old_table, old_i);
+ ctx->old_table, i);
ctx->drop_vcol[j].v_pos = v_col->v_pos;
j++;
}
@@ -4404,7 +4297,7 @@ innodb_v_adjust_idx_col(
/* Found the field in the new table */
while (const Create_field* new_field = cf_it++) {
- if (!new_field->is_virtual_gcol()) {
+ if (!innobase_is_v_fld(new_field)) {
continue;
}
@@ -4424,7 +4317,7 @@ innodb_v_adjust_idx_col(
ut_a(0);
}
- ut_ad(field->is_virtual_gcol());
+ ut_ad(innobase_is_v_fld(field));
num_v = 0;
@@ -4438,7 +4331,7 @@ innodb_v_adjust_idx_col(
break;
}
- if (old_table->field[old_i]->is_virtual_gcol()) {
+ if (innobase_is_v_fld(old_table->field[old_i])) {
num_v++;
}
}
@@ -4446,7 +4339,6 @@ innodb_v_adjust_idx_col(
ut_ad(col_found);
}
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/** Update internal structures with concurrent writes blocked,
while preparing ALTER TABLE.
@@ -4511,7 +4403,6 @@ prepare_inplace_alter_table_dict(
trx_start_if_not_started_xa(ctx->prebuilt->trx, true);
-#ifdef MYSQL_VIRTUAL_COLUMNS
if (ha_alter_info->handler_flags
& Alter_inplace_info::DROP_VIRTUAL_COLUMN) {
if (prepare_inplace_drop_virtual(
@@ -4543,7 +4434,6 @@ prepare_inplace_alter_table_dict(
/* There should be no order change for virtual columns coming in
here */
ut_ad(check_v_col_in_order(old_table, altered_table, ha_alter_info));
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/* Create a background transaction for the operations on
the data dictionary tables. */
@@ -4658,9 +4548,9 @@ prepare_inplace_alter_table_dict(
ctx->new_table->id);
ulint n_cols = 0;
ulint n_v_cols = 0;
- ulint n_mv_cols = 0;
dtuple_t* add_cols;
ulint space_id = 0;
+ ulint z = 0;
ulint key_id = FIL_DEFAULT_ENCRYPTION_KEY;
fil_encryption_t mode = FIL_SPACE_ENCRYPTION_DEFAULT;
const char* compression=NULL;
@@ -4684,15 +4574,11 @@ prepare_inplace_alter_table_dict(
if (innobase_is_v_fld(field)) {
n_v_cols++;
} else {
- if (field->stored_in_db()) {
n_cols++;
- } else {
- n_mv_cols++;
- }
}
}
- ut_ad(n_cols + n_v_cols + n_mv_cols == altered_table->s->fields);
+ ut_ad(n_cols + n_v_cols == altered_table->s->fields);
if (add_fts_doc_id) {
n_cols++;
@@ -4744,21 +4630,17 @@ prepare_inplace_alter_table_dict(
user_table->data_dir_path);
}
- for (uint i = 0, sql_idx=0; i < altered_table->s->stored_fields; i++, sql_idx++) {
- Field* field;
+ for (uint i = 0; i < altered_table->s->fields; i++) {
+ const Field* field = altered_table->field[i];
ulint is_unsigned;
- ulint charset_no;
- ulint col_len;
-
- while (!((field= altered_table->field[sql_idx])->stored_in_db())) {
- sql_idx++;
- }
-
- ulint field_type = (ulint) field->type();
- bool is_virtual = innobase_is_v_fld(field);
+ ulint field_type
+ = (ulint) field->type();
ulint col_type
= get_innobase_type_from_mysql_type(
&is_unsigned, field);
+ ulint charset_no;
+ ulint col_len;
+ bool is_virtual = innobase_is_v_fld(field);
/* we assume in dtype_form_prtype() that this
fits in two bytes */
@@ -4825,7 +4707,6 @@ prepare_inplace_alter_table_dict(
}
if (is_virtual) {
-#ifdef MYSQL_VIRTUAL_COLUMNS
dict_mem_table_add_v_col(
ctx->new_table, ctx->heap,
field->field_name,
@@ -4833,9 +4714,7 @@ prepare_inplace_alter_table_dict(
dtype_form_prtype(
field_type, charset_no)
| DATA_VIRTUAL,
- col_len, i,
- field->gcol_info->non_virtual_base_columns());
-#endif /* MYSQL_VIRTUAL_COLUMNS */
+ col_len, i, 0);
} else {
dict_mem_table_add_col(
ctx->new_table, ctx->heap,
@@ -4847,9 +4726,6 @@ prepare_inplace_alter_table_dict(
}
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
- ulint z = 0;
-
if (n_v_cols) {
for (uint i = 0; i < altered_table->s->fields; i++) {
dict_v_col_t* v_col;
@@ -4865,15 +4741,12 @@ prepare_inplace_alter_table_dict(
ctx->new_table, field, v_col);
}
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
if (add_fts_doc_id) {
fts_add_doc_id_column(ctx->new_table, ctx->heap);
ctx->new_table->fts->doc_col = fts_doc_id_col;
ut_ad(fts_doc_id_col
- == altered_table->s->stored_fields - n_v_cols);
- ut_ad(fts_doc_id_col == altered_table->s->stored_fields);
-
+ == altered_table->s->fields - n_v_cols);
} else if (ctx->new_table->fts) {
ctx->new_table->fts->doc_col = fts_doc_id_col;
}
@@ -5023,14 +4896,12 @@ new_clustered_failed:
for (ulint a = 0; a < ctx->num_to_add_index; a++) {
-#ifdef MYSQL_VIRTUAL_COLUMNS
if (index_defs[a].ind_type & DICT_VIRTUAL
&& ctx->num_to_drop_vcol > 0 && !new_clustered) {
innodb_v_adjust_idx_col(ha_alter_info, old_table,
ctx->num_to_drop_vcol,
&index_defs[a]);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
ctx->add_index[a] = row_merge_create_index(
ctx->trx, ctx->new_table,
@@ -5601,7 +5472,6 @@ rename_indexes_in_cache(
}
#endif /* MYSQL_RENAME_INDEX */
-#ifdef MYSQL_VIRTUAL_COLUMNS
/** Fill the stored column information in s_cols list.
@param[in] altered_table mysql table object
@param[in] table innodb table object
@@ -5626,7 +5496,7 @@ alter_fill_stored_column(
continue;
}
- ulint num_base = field->gcol_info->non_virtual_base_columns();
+ ulint num_base = 0;
dict_col_t* col = dict_table_get_nth_col(table, i);
s_col.m_col = col;
@@ -5649,7 +5519,7 @@ alter_fill_stored_column(
(*s_cols)->push_back(s_col);
}
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
+
/** Allows InnoDB to update internal structures with concurrent
writes blocked (provided that check_if_supported_inplace_alter()
@@ -5790,6 +5660,12 @@ ha_innobase::prepare_inplace_alter_table(
info.set_tablespace_type(is_file_per_table);
+ if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_INDEX) {
+ if (info.gcols_in_fulltext_or_spatial()) {
+ goto err_exit_no_heap;
+ }
+ }
+
if (ha_alter_info->handler_flags
& Alter_inplace_info::CHANGE_CREATE_OPTION) {
const char* invalid_opt = info.create_options_are_invalid();
@@ -6228,10 +6104,9 @@ check_if_can_drop_indexes:
& Alter_inplace_info::ADD_FOREIGN_KEY) {
ut_ad(!m_prebuilt->trx->check_foreigns);
-#ifdef MYSQL_VIRTUAL_COLUMNS
alter_fill_stored_column(altered_table, m_prebuilt->table,
&s_cols, &s_heap);
-#endif
+
add_fk = static_cast<dict_foreign_t**>(
mem_heap_zalloc(
heap,
@@ -6302,7 +6177,6 @@ err_exit:
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
if ((ha_alter_info->handler_flags
& Alter_inplace_info::DROP_VIRTUAL_COLUMN)
&& prepare_inplace_drop_virtual(
@@ -6316,7 +6190,6 @@ err_exit:
ha_alter_info, altered_table, table)) {
DBUG_RETURN(true);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
DBUG_RETURN(false);
}
@@ -6332,7 +6205,7 @@ err_exit:
m_prebuilt->table,
altered_table, &fts_doc_col_no, &num_v)) {
- fts_doc_col_no = altered_table->s->stored_fields;
+ fts_doc_col_no = altered_table->s->fields - num_v;
add_fts_doc_id = true;
add_fts_doc_id_idx = true;
@@ -6360,36 +6233,24 @@ err_exit:
DBUG_ASSERT(
doc_col_no == fts_doc_col_no
|| doc_col_no == ULINT_UNDEFINED
- || (ha_alter_info->handler_flags));
- /* JAN: TODO: MySQL 5.7 Virtual columns
+ || (ha_alter_info->handler_flags
& (Alter_inplace_info::ALTER_STORED_COLUMN_ORDER
| Alter_inplace_info::DROP_STORED_COLUMN
- |
- Alter_inplace_info::ADD_STORED_COLUMN)));
- */
+ | Alter_inplace_info::ADD_STORED_BASE_COLUMN)));
}
}
/* See if an AUTO_INCREMENT column was added. */
- uint i = 0, innodb_idx= 0;
+ uint i = 0;
ulint num_v = 0;
List_iterator_fast<Create_field> cf_it(
ha_alter_info->alter_info->create_list);
while (const Create_field* new_field = cf_it++) {
const Field* field;
- if (!new_field->stored_in_db()) {
- i++;
- continue;
- }
DBUG_ASSERT(i < altered_table->s->fields);
- DBUG_ASSERT(innodb_idx < altered_table->s->stored_fields);
for (uint old_i = 0; table->field[old_i]; old_i++) {
- if (!table->field[old_i]->stored_in_db()) {
- continue;
- }
-
if (new_field->field == table->field[old_i]) {
goto found_col;
}
@@ -6413,12 +6274,10 @@ err_exit:
my_error(ER_WRONG_AUTO_KEY, MYF(0));
goto err_exit;
}
- add_autoinc_col_no = innodb_idx;
- /* JAN: TODO: MySQL 5.7
- autoinc_col_max_value =
- field->get_max_int_value();
- */
+ /* Get the col no of the old table non-virtual column array */
+ add_autoinc_col_no = i - num_v;
+
autoinc_col_max_value = innobase_get_int_col_max_value(field);
}
found_col:
@@ -6427,7 +6286,6 @@ found_col:
}
i++;
- innodb_idx++;
}
DBUG_ASSERT(heap);
@@ -6601,7 +6459,6 @@ ok_exit:
&& alter_templ_needs_rebuild(
altered_table, ha_alter_info, ctx->new_table));
-#ifdef MYSQL_VIRTUAL_COLUMNS
if ((ctx->new_table->n_v_cols > 0) && rebuild_templ) {
/* Save the templ if isn't NULL so as to restore the
original state in case of alter operation failures. */
@@ -6609,11 +6466,9 @@ ok_exit:
old_templ = ctx->new_table->vc_templ;
}
s_templ = UT_NEW_NOKEY(dict_vcol_templ_t());
- s_templ->vtempl = NULL;
innobase_build_v_templ(
- altered_table, ctx->new_table, s_templ,
- NULL, false, NULL);
+ altered_table, ctx->new_table, s_templ, NULL, false);
ctx->new_table->vc_templ = s_templ;
} else if (ctx->num_to_add_vcol > 0 && ctx->num_to_drop_vcol == 0) {
@@ -6630,11 +6485,8 @@ ok_exit:
add_v->v_col = ctx->add_vcol;
add_v->v_col_name = ctx->add_vcol_name;
- s_templ->vtempl = NULL;
-
innobase_build_v_templ(
- altered_table, ctx->new_table, s_templ,
- add_v, false, NULL);
+ altered_table, ctx->new_table, s_templ, add_v, false);
old_templ = ctx->new_table->vc_templ;
ctx->new_table->vc_templ = s_templ;
}
@@ -6645,7 +6497,6 @@ ok_exit:
if (!ctx->need_rebuild() && ctx->num_to_drop_vcol > 0) {
eval_table = table;
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/* Read the clustered index of the table and build
indexes based on this information using temporary
@@ -7452,14 +7303,13 @@ innobase_enlarge_columns_try(
List_iterator_fast<Create_field> cf_it(
ha_alter_info->alter_info->create_list);
ulint i = 0;
- bool is_v=false;
+ ulint num_v = 0;
+ bool is_v;
for (Field** fp = table->field; *fp; fp++, i++) {
ulint idx;
-#ifdef MYSQL_VIRTUAL_COLUMNS
- ulint num_v = 0;
- if ((*fp)->is_virtual_gcol()) {
+ if (innobase_is_v_fld(*fp)) {
is_v = true;
idx = num_v;
num_v++;
@@ -7467,10 +7317,6 @@ innobase_enlarge_columns_try(
idx = i - num_v;
is_v = false;
}
-#else
- idx = i;
- is_v = false;
-#endif
cf_it.rewind();
while (Create_field* cf = cf_it++) {
@@ -7614,8 +7460,6 @@ commit_get_autoinc(
ulonglong offset;
col_max_value = innobase_get_int_col_max_value(autoinc_field);
- // JAN: TODO: MySQL 5.7
- //col_max_value = autoinc_field->get_max_int_value();
offset = ctx->prebuilt->autoinc_offset;
max_autoinc = innobase_next_autoinc(
@@ -8213,7 +8057,6 @@ commit_try_norebuild(
}
#endif /* MYSQL_RENAME_INDEX */
-#ifdef MYSQL_VIRTUAL_COLUMNS
if ((ha_alter_info->handler_flags
& Alter_inplace_info::DROP_VIRTUAL_COLUMN)
&& innobase_drop_virtual_try(
@@ -8229,7 +8072,6 @@ commit_try_norebuild(
ctx->old_table, trx)) {
DBUG_RETURN(true);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
DBUG_RETURN(false);
}
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index 5e5fbae9081..c44dc156aaa 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -1984,7 +1984,6 @@ dict_free_vc_templ(
ut_free(vc_templ->vtempl[i]);
}
}
- ut_free(vc_templ->default_rec);
ut_free(vc_templ->vtempl);
vc_templ->vtempl = NULL;
}
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 019e20680e5..c81d893ed5a 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -1328,14 +1328,19 @@ struct dict_vcol_templ_t {
/** table name */
std::string tb_name;
- /** share->table_name */
- std::string share_name;
-
/** MySQL record length */
ulint rec_len;
/** default column value if any */
byte* default_rec;
+
+ /** cached MySQL TABLE object */
+ TABLE* mysql_table;
+
+ /** when mysql_table was cached */
+ uint64_t mysql_table_query_id;
+
+ dict_vcol_templ_t() : vtempl(0), mysql_table_query_id(-1) {}
};
/* This flag is for sync SQL DDL and memcached DML.
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index f3641f93681..116ca781726 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -52,7 +52,6 @@ struct fts_string_t;
#undef MYSQL_SPATIAL_INDEX
#undef MYSQL_STORE_FTS_DOC_ID
#undef MYSQL_TABLESPACES
-#undef MYSQL_VIRTUAL_COLUMNS
/*********************************************************************//**
Wrapper around MySQL's copy_and_convert function.
@@ -654,5 +653,20 @@ buffer pool size.
void
innodb_set_buf_pool_size(ulonglong buf_pool_size);
+/** Create a MYSQL_THD for background purge threads and mark it as such.
+@returns new MYSQL_THD */
+MYSQL_THD
+innobase_create_background_thd();
+
+/** Destroy a background purge thread THD.
+@param[in] thd MYSQL_THD to destroy */
+void
+innobase_destroy_background_thd(MYSQL_THD);
+
+/** Close opened tables, free memory, delete items for a MYSQL_THD.
+@param[in] thd MYSQL_THD to reset */
+void
+innobase_reset_background_thd(MYSQL_THD);
+
#endif /* !UNIV_HOTBACKUP && !UNIV_INNOCHECKSUM */
#endif /* HA_INNODB_PROTOTYPES_H */
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index bc421774320..0a5e3b27bc0 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -2195,6 +2195,13 @@ loop:
count = 0;
}
+ /* Wake up purge threads to die - they have MYSQL_THD's and
+ thus might keep open transactions. In particular, this is
+ needed in embedded server and when one uses UNINSTALL PLUGIN.
+ In the normal server shutdown purge threads should've been
+ already notified by the thd_destructor_proxy thread. */
+ srv_purge_wakeup();
+
goto loop;
}
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 20c64a4288c..271d70d4da9 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -931,7 +931,6 @@ row_ins_invalidate_query_cache(
innobase_invalidate_query_cache(thr_get_trx(thr), name, len);
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
/** Fill virtual column information in cascade node for the child table.
@param[out] cascade child update node
@@ -1042,7 +1041,6 @@ func_exit:
mem_heap_free(v_heap);
}
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
#ifdef WITH_WSREP
dberr_t wsrep_append_foreign_key(trx_t *trx,
@@ -1338,7 +1336,6 @@ row_ins_foreign_check_on_constraint(
cascade->fts_doc_id = doc_id;
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
if (foreign->v_cols != NULL
&& foreign->v_cols->size() > 0) {
row_ins_foreign_fill_virtual(
@@ -1349,7 +1346,6 @@ row_ins_foreign_check_on_constraint(
goto nonstandard_exit_func;
}
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
} else if (table->fts && cascade->is_delete) {
/* DICT_FOREIGN_ON_DELETE_CASCADE case */
for (i = 0; i < foreign->n_fields; i++) {
@@ -1379,7 +1375,6 @@ row_ins_foreign_check_on_constraint(
trx, &fts_col_affacted, cascade);
-#ifdef MYSQL_VIRTUAL_COLUMNS
if (foreign->v_cols != NULL
&& foreign->v_cols->size() > 0) {
row_ins_foreign_fill_virtual(
@@ -1390,7 +1385,6 @@ row_ins_foreign_check_on_constraint(
goto nonstandard_exit_func;
}
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
if (n_to_update == ULINT_UNDEFINED) {
err = DB_ROW_IS_REFERENCED;
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index d302b493f21..7a8b74279f5 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -655,13 +655,10 @@ row_merge_buf_add(
const dfield_t* row_field;
col = ifield->col;
-
-#ifdef MYSQL_VIRTUAL_COLUMNS
const dict_v_col_t* v_col = NULL;
if (dict_col_is_virtual(col)) {
v_col = reinterpret_cast<const dict_v_col_t*>(col);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
col_no = dict_col_get_no(col);
@@ -687,7 +684,6 @@ row_merge_buf_add(
} else {
/* Use callback to get the virtual column value */
if (dict_col_is_virtual(col)) {
- #ifdef MYSQL_VIRTUAL_COLUMN
dict_index_t* clust_index
= dict_table_get_first_index(new_table);
@@ -701,7 +697,6 @@ row_merge_buf_add(
DBUG_RETURN(0);
}
dfield_copy(field, row_field);
-#endif /* MYSQL_VIRTUAL_COLUMN */
} else {
row_field = dtuple_get_nth_field(row, col_no);
dfield_copy(field, row_field);
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 5b38b7c6c01..100e1bcb708 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -5034,14 +5034,12 @@ end:
goto funct_exit;
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
/* In case of copy alter, template db_name and
table_name should be renamed only for newly
created table. */
if (table->vc_templ != NULL && !new_is_tmp) {
innobase_rename_vc_templ(table);
}
-#endif
/* We only want to switch off some of the type checking in
an ALTER TABLE...ALGORITHM=COPY, not in a RENAME. */
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index bac55694056..23e08c38cdd 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -868,7 +868,6 @@ try_again:
goto err_exit;
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
if (node->table->n_v_cols && !node->table->vc_templ
&& dict_table_has_indexed_v_cols(node->table)) {
/* Need server fully up for virtual column computation */
@@ -886,7 +885,6 @@ try_again:
/* Initialize the template for the table */
innobase_init_vc_templ(node->table);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/* Disable purging for temp-tables as they are short-lived
and no point in re-organzing such short lived tables */
@@ -1120,6 +1118,8 @@ row_purge_step(
row_purge_end(thr);
}
+ innobase_reset_background_thd(thr_get_trx(thr)->mysql_thd);
+
return(thr);
}
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 62fd18d027b..5daa26319a5 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -221,7 +221,6 @@ row_sel_sec_rec_is_for_clust_rec(
/* For virtual column, its value will need to be
reconstructed from base column in cluster index */
if (is_virtual) {
-#ifdef MYSQL_VIRTUAL_COLUMNS
const dict_v_col_t* v_col;
const dtuple_t* row;
dfield_t* vfield;
@@ -243,7 +242,6 @@ row_sel_sec_rec_is_for_clust_rec(
clust_len = vfield->len;
clust_field = static_cast<byte*>(vfield->data);
-#endif /* MYSQL_VIRTUAL_COLUMNS */
} else {
clust_pos = dict_col_get_clust_pos(col, clust_index);
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 759bfb57428..2a990904242 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1076,7 +1076,6 @@ row_upd_build_difference_binary(
}
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
/* Check the virtual columns updates. Even if there is no non-virtual
column (base columns) change, we will still need to build the
indexed virtual column value so that undo log would log them (
@@ -1141,7 +1140,6 @@ row_upd_build_difference_binary(
mem_heap_free(v_heap);
}
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
update->n_fields = n_diff;
ut_ad(update->validate());
@@ -2061,7 +2059,6 @@ row_upd_eval_new_vals(
}
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
/** Stores to the heap the virtual columns that need for any indexes
@param[in,out] node row update node
@param[in] update an update vector if it is update
@@ -2140,7 +2137,6 @@ row_upd_store_v_row(
mem_heap_free(heap);
}
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/** Stores to the heap the row on which the node->pcur is positioned.
@param[in] node row update node
@@ -2190,12 +2186,10 @@ row_upd_store_row(
node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,
NULL, NULL, NULL, ext, node->heap);
-#ifdef MYSQL_VIRTUAL_COLUMNS
if (node->table->n_v_cols) {
row_upd_store_v_row(node, node->is_delete ? NULL : node->update,
thd, mysql_table);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
if (node->is_delete) {
node->upd_row = NULL;
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index fd17683fb48..f21b1ebbb85 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -467,7 +467,6 @@ row_vers_non_vc_match(
return(ret);
}
-#ifdef MYSQL_VIRTUAL_COLUMNS
/** build virtual column value from current cluster index record data
@param[in,out] row the cluster index row in dtuple form
@param[in] clust_index clustered index
@@ -841,7 +840,6 @@ row_vers_build_cur_vrow(
ULINT_UNDEFINED, &heap);
return(cur_vrow);
}
-#endif /* MYSQL_VIRTUAL_COLUMNS */
/*****************************************************************//**
Finds out if a version of the record, where the version >= the current
@@ -913,7 +911,6 @@ row_vers_old_has_index_entry(
if (dict_index_has_virtual(index)) {
-#ifdef MYSQL_VIRTUAL_COLUMNS
#ifdef DBUG_OFF
# define dbug_v_purge false
@@ -963,7 +960,6 @@ row_vers_old_has_index_entry(
}
clust_offsets = rec_get_offsets(rec, clust_index, NULL,
ULINT_UNDEFINED, &heap);
-#endif /* MYSQL_VIRTUAL_COLUMNS */
} else {
entry = row_build_index_entry(
@@ -1001,7 +997,6 @@ row_vers_old_has_index_entry(
}
}
} else if (dict_index_has_virtual(index)) {
-#ifdef MYSQL_VIRTUAL_COLUMNS
/* The current cluster index record could be
deleted, but the previous version of it might not. We will
need to get the virtual column data from undo record
@@ -1009,7 +1004,6 @@ row_vers_old_has_index_entry(
cur_vrow = row_vers_build_cur_vrow(
also_curr, rec, clust_index, &clust_offsets,
index, ientry, roll_ptr, trx_id, heap, v_heap, mtr);
-#endif /* MYSQL_VIRTUAL_COLUMNS */
}
version = rec;
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index d2f13ad9b37..2e9e3b7ea8a 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -2664,8 +2664,13 @@ Check if purge should stop.
static
bool
srv_purge_should_exit(
+ MYSQL_THD thd,
ulint n_purged) /*!< in: pages purged in last batch */
{
+ if (thd_kill_level(thd)) {
+ return(true);
+ }
+
switch (srv_shutdown_state) {
case SRV_SHUTDOWN_NONE:
/* Normal operation. */
@@ -2736,8 +2741,7 @@ DECLARE_THREAD(srv_worker_thread)(
ut_ad(!srv_read_only_mode);
ut_a(srv_force_recovery < SRV_FORCE_NO_BACKGROUND);
my_thread_init();
- // JAN: TODO: MySQL 5.7
- // THD *thd= create_thd(false, true, true);
+ THD* thd = innobase_create_background_thd();
#ifdef UNIV_DEBUG_THREAD_CREATION
ib::info() << "Worker thread starting, id "
@@ -2781,7 +2785,7 @@ DECLARE_THREAD(srv_worker_thread)(
ut_a(!purge_sys->running);
ut_a(purge_sys->state == PURGE_STATE_EXIT);
- ut_a(srv_shutdown_state > SRV_SHUTDOWN_NONE);
+ ut_a(srv_shutdown_state > SRV_SHUTDOWN_NONE || thd_kill_level(thd));
rw_lock_x_unlock(&purge_sys->latch);
@@ -2790,9 +2794,8 @@ DECLARE_THREAD(srv_worker_thread)(
<< os_thread_pf(os_thread_get_curr_id());
#endif /* UNIV_DEBUG_THREAD_CREATION */
- // JAN: TODO: MySQL 5.7
- // destroy_thd(thd);
- my_thread_end();
+ innobase_destroy_background_thd(thd);
+ my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit();
@@ -2807,6 +2810,7 @@ static
ulint
srv_do_purge(
/*=========*/
+ MYSQL_THD thd,
ulint n_threads, /*!< in: number of threads to use */
ulint* n_total_purged) /*!< in/out: total pages purged */
{
@@ -2877,7 +2881,7 @@ srv_do_purge(
*n_total_purged += n_pages_purged;
- } while (!srv_purge_should_exit(n_pages_purged)
+ } while (!srv_purge_should_exit(thd, n_pages_purged)
&& n_pages_purged > 0
&& purge_sys->state == PURGE_STATE_RUN);
@@ -2890,6 +2894,7 @@ static
void
srv_purge_coordinator_suspend(
/*==========================*/
+ MYSQL_THD thd,
srv_slot_t* slot, /*!< in/out: Purge coordinator
thread slot */
ulint rseg_history_len) /*!< in: history list length
@@ -2977,7 +2982,7 @@ srv_purge_coordinator_suspend(
}
}
- } while (stop);
+ } while (stop && !thd_kill_level(thd));
srv_sys_mutex_enter();
@@ -3001,8 +3006,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
required by os_thread_create */
{
my_thread_init();
- // JAN: TODO: MySQL 5.7
- // THD *thd= create_thd(false, true, true);
+ THD* thd = innobase_create_background_thd();
srv_slot_t* slot;
ulint n_total_purged = ULINT_UNDEFINED;
@@ -3036,13 +3040,14 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
purge didn't purge any records then wait for activity. */
if (srv_shutdown_state == SRV_SHUTDOWN_NONE
+ && !thd_kill_level(thd)
&& (purge_sys->state == PURGE_STATE_STOP
|| n_total_purged == 0)) {
- srv_purge_coordinator_suspend(slot, rseg_history_len);
+ srv_purge_coordinator_suspend(thd, slot, rseg_history_len);
}
- if (srv_purge_should_exit(n_total_purged)) {
+ if (srv_purge_should_exit(thd, n_total_purged)) {
ut_a(!slot->suspended);
break;
}
@@ -3050,14 +3055,14 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
n_total_purged = 0;
rseg_history_len = srv_do_purge(
- srv_n_purge_threads, &n_total_purged);
+ thd, srv_n_purge_threads, &n_total_purged);
- } while (!srv_purge_should_exit(n_total_purged));
+ } while (!srv_purge_should_exit(thd, n_total_purged));
/* Ensure that we don't jump out of the loop unless the
exit condition is satisfied. */
- ut_a(srv_purge_should_exit(n_total_purged));
+ ut_a(srv_purge_should_exit(thd, n_total_purged));
ulint n_pages_purged = ULINT_MAX;
@@ -3068,12 +3073,6 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
n_pages_purged = trx_purge(1, srv_purge_batch_size, false);
}
-#ifdef UNIV_DEBUG
- if (srv_fast_shutdown == 0) {
- trx_commit_disallowed = true;
- }
-#endif /* UNIV_DEBUG */
-
/* This trx_purge is called to remove any undo records (added by
background threads) after completion of the above loop. When
srv_fast_shutdown != 0, a large batch size can cause significant
@@ -3116,8 +3115,7 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
srv_release_threads(SRV_WORKER, srv_n_purge_threads - 1);
}
- // JAN: TODO: MYSQL 5.7
- // destroy_thd(thd);
+ innobase_destroy_background_thd(thd);
my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index cb902f976fa..27a3e7b3294 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -13969,8 +13969,8 @@ enum_alter_inplace_result ha_mroonga::wrapper_check_if_supported_inplace_alter(
(
Alter_inplace_info::ADD_COLUMN |
Alter_inplace_info::DROP_COLUMN |
- Alter_inplace_info::ALTER_COLUMN_TYPE |
- Alter_inplace_info::ALTER_COLUMN_ORDER |
+ Alter_inplace_info::ALTER_STORED_COLUMN_TYPE |
+ Alter_inplace_info::ALTER_STORED_COLUMN_ORDER |
Alter_inplace_info::ALTER_COLUMN_NULLABLE |
Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE |
Alter_inplace_info::ALTER_COLUMN_STORAGE_TYPE |
diff --git a/storage/tokudb/ha_tokudb_alter_56.cc b/storage/tokudb/ha_tokudb_alter_56.cc
index 00a4602b554..ba1afbf091a 100644
--- a/storage/tokudb/ha_tokudb_alter_56.cc
+++ b/storage/tokudb/ha_tokudb_alter_56.cc
@@ -216,11 +216,11 @@ static ulong fix_handler_flags(
handler_flags &= ~Alter_inplace_info::TOKU_ALTER_RENAME;
}
- // ALTER_COLUMN_TYPE may be set when no columns have been changed,
+ // ALTER_STORED_COLUMN_TYPE may be set when no columns have been changed,
// so turn off the flag
- if (handler_flags & Alter_inplace_info::ALTER_COLUMN_TYPE) {
+ if (handler_flags & Alter_inplace_info::ALTER_STORED_COLUMN_TYPE) {
if (all_fields_are_same_type(table, altered_table)) {
- handler_flags &= ~Alter_inplace_info::ALTER_COLUMN_TYPE;
+ handler_flags &= ~Alter_inplace_info::ALTER_STORED_COLUMN_TYPE;
}
}
@@ -358,7 +358,7 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter(
// but let's do some more checks
// we will only allow an hcr if there are no changes
- // in column positions (ALTER_COLUMN_ORDER is not set)
+ // in column positions (ALTER_STORED_COLUMN_ORDER is not set)
// now need to verify that one and only one column
// has changed only its name. If we find anything to
@@ -369,7 +369,7 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter(
table,
altered_table,
(ctx->handler_flags &
- Alter_inplace_info::ALTER_COLUMN_ORDER) != 0);
+ Alter_inplace_info::ALTER_STORED_COLUMN_ORDER) != 0);
if (cr_supported)
result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK;
}
@@ -377,7 +377,7 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter(
only_flags(
ctx->handler_flags,
Alter_inplace_info::ADD_COLUMN +
- Alter_inplace_info::ALTER_COLUMN_ORDER) &&
+ Alter_inplace_info::ALTER_STORED_COLUMN_ORDER) &&
setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) {
// add column
@@ -407,7 +407,7 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter(
only_flags(
ctx->handler_flags,
Alter_inplace_info::DROP_COLUMN +
- Alter_inplace_info::ALTER_COLUMN_ORDER) &&
+ Alter_inplace_info::ALTER_STORED_COLUMN_ORDER) &&
setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) {
// drop column
@@ -452,10 +452,10 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter(
ha_alter_info, ctx)) {
result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK;
}
- } else if ((ctx->handler_flags & Alter_inplace_info::ALTER_COLUMN_TYPE) &&
+ } else if ((ctx->handler_flags & Alter_inplace_info::ALTER_STORED_COLUMN_TYPE) &&
only_flags(
ctx->handler_flags,
- Alter_inplace_info::ALTER_COLUMN_TYPE +
+ Alter_inplace_info::ALTER_STORED_COLUMN_TYPE +
Alter_inplace_info::ALTER_COLUMN_DEFAULT) &&
table->s->fields == altered_table->s->fields &&
find_changed_fields(
@@ -1578,7 +1578,7 @@ static bool change_field_type_is_supported(
return false;
} else if (old_type == MYSQL_TYPE_VARCHAR) {
// varchar(X) -> varchar(Y) and varbinary(X) -> varbinary(Y) expansion
- // where X < 256 <= Y the ALTER_COLUMN_TYPE handler flag is set for
+ // where X < 256 <= Y the ALTER_STORED_COLUMN_TYPE handler flag is set for
// these cases
return change_varchar_length_is_supported(
old_field,