/** Determine if a table belongs to innobase_system_databases[] @param[in]namedatabase_name/table_name
@return whether the database_name is in innobase_system_databases[] */ staticbool dict_mem_table_is_system(constchar *name)
{ /* table has the following format: database/table
and some system table are of the form SYS_* */ if (!strchr(name, '/')) { returntrue;
}
size_t table_len = strlen(name); constchar *system_db; int i = 0; while ((system_db = innobase_system_databases[i++])
&& (system_db != NullS)) {
size_t len = strlen(system_db); if (table_len > len && !strncmp(name, system_db, len)) { returntrue;
}
} returnfalse;
}
/** Display an identifier. @param[in,out]soutputstream @param[in]id_nameSQLidentifier(otherthantablename)
@return the output stream */
std::ostream& operator<<(
std::ostream& s, const id_name_t& id_name)
{ constchar q = '`'; constchar* c = id_name;
s << q; for (; *c != 0; c++) { if (*c == q) {
s << *c;
}
s << *c;
}
s << q; return(s);
}
/* Clean up virtual index info structures that are registered
with virtual columns */ for (ulint i = 0; i < table->n_v_def; i++) {
dict_table_get_nth_v_col(table, i)->~dict_v_col_t();
}
UT_DELETE(table->s_cols);
mem_heap_free(table->heap);
}
/****************************************************************//**
Append 'name' to 'col_names'. @see dict_table_t::col_names
@returnnew column names array */ static constchar*
dict_add_col_name( /*==============*/ constchar* col_names, /*!< in: existing column names, or
NULL */
ulint cols, /*!< in: number of existing columns */ constchar* name, /*!< in: new column name */
mem_heap_t* heap) /*!< in: heap */
{
ulint old_len;
ulint new_len;
ulint total_len; char* res;
ut_ad(!cols == !col_names);
/* Find out length of existing array. */ if (col_names) { constchar* s = col_names;
ulint i;
for (i = 0; i < cols; i++) {
s += strlen(s) + 1;
}
if (name) { if (table->n_def == table->n_cols) {
heap = table->heap;
} if (i && !table->col_names) { /* All preceding column names are empty. */ char* s = static_cast<char*>(
mem_heap_zalloc(heap, table->n_def));
table->col_names = s;
}
table->col_names = dict_add_col_name(table->col_names,
i, name, heap);
}
col = dict_table_get_nth_col(table, i);
dict_mem_fill_column_struct(col, i, mtype, prtype, len);
switch (prtype & DATA_VERSIONED) { case DATA_VERS_START:
ut_ad(!table->vers_start);
table->vers_start = i & dict_index_t::MAX_N_FIELDS; break; case DATA_VERS_END:
ut_ad(!table->vers_end);
table->vers_end = i & dict_index_t::MAX_N_FIELDS;
}
}
/* Initialize the index list for virtual columns */
ut_ad(v_col->v_indexes.empty());
return(v_col);
}
/** Adds a stored column definition to a table. @param[in]tabletable
@param[in] num_base number of base columns. */ void
dict_mem_table_add_s_col(
dict_table_t* table,
ulint num_base)
{ unsigned i = unsigned(table->n_def) - 1;
dict_col_t* col = dict_table_get_nth_col(table, i);
dict_s_col_t s_col;
ut_ad(col != NULL);
if (table->s_cols == NULL) {
table->s_cols = UT_NEW_NOKEY(dict_s_col_list());
}
s_col.m_col = col;
s_col.s_pos = i + table->n_v_def;
/**********************************************************************//**
Renames a column of a table in the data dictionary cache. */ static MY_ATTRIBUTE((nonnull)) void
dict_mem_table_col_rename_low( /*==========================*/
dict_table_t* table, /*!< in/out: table */ unsigned i, /*!< in: column offset corresponding to s */ constchar* to, /*!< in: new column name */ constchar* s, /*!< in: pointer to table->col_names */ bool is_virtual) /*!< in: if this is a virtual column */
{ char* t_col_names = const_cast<char*>(
is_virtual ? table->v_col_names : table->col_names);
ulint n_col = is_virtual ? table->n_v_def : table->n_def;
char from[NAME_LEN + 1];
strncpy(from, s, sizeof from - 1);
from[sizeof from - 1] = '\0';
if (from_len == to_len) { /* The easy case: simply replace the column name in
table->col_names. */
strcpy(const_cast<char*>(s), to);
} else { /* We need to adjust all affected index->field pointers,asindict_index_add_col().First,copy
table->col_names. */
ulint prefix_len = ulint(s - t_col_names);
/* Replace the field names in every index. */ for (dict_index_t* index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
ulint n_fields = dict_index_get_n_fields(index);
for (ulint i = 0; i < n_fields; i++) {
dict_field_t* field
= dict_index_get_nth_field(
index, i);
ut_ad(!field->name
== field->col->is_dropped()); if (!field->name) { /* dropped columns lack a name */
ut_ad(index->is_instant()); continue;
}
/* if is_virtual and that in field->col does
not match, continue */ if ((!is_virtual) !=
(!field->col->is_virtual())) { continue;
}
/* Virtual columns are not allowed for foreign key */ if (is_virtual) { return;
}
dict_foreign_t* foreign;
/* Replace the field names in every foreign key constraint. */ for (dict_foreign_set::iterator it = table->foreign_set.begin();
it != table->foreign_set.end();
++it) {
foreign = *it;
if (foreign->foreign_index == NULL) { /* We may go here when we set foreign_key_checks to 0, andthentrytorenameacolumnandmodifythe correspondingforeignkeyconstraint.Theindex wouldhavebeendropped,wehavetofindanequivalent
one */ for (unsigned f = 0; f < foreign->n_fields; f++) { if (strcmp(foreign->foreign_col_names[f], from)
== 0) {
if (to_len <= strlen(*rc)) {
memcpy(*rc, to, to_len + 1);
} else {
*rc = static_cast<char*>(
mem_heap_dup(
foreign->heap,
to,
to_len + 1));
}
}
}
/* New index can be null if InnoDB already dropped theforeignindexwhenFOREIGN_KEY_CHECKSis
disabled */
foreign->foreign_index = dict_foreign_find_index(
foreign->foreign_table, NULL,
foreign->foreign_col_names,
foreign->n_fields, NULL, true, false,
NULL, NULL, NULL);
} else {
for (unsigned f = 0; f < foreign->n_fields; f++) { /* These can point straight to table->col_names,becausetheforeignkey constraintswillbefreedatthesametime
when the table object is freed. */
foreign->foreign_col_names[f]
= dict_index_get_nth_field(
foreign->foreign_index,
f)->name;
}
}
}
for (dict_foreign_set::iterator it = table->referenced_set.begin();
it != table->referenced_set.end();
++it) {
foreign = *it;
if (!foreign->referenced_index) { /* Referenced index could have been dropped whenforeign_key_checksisdisabled.Inthatcase, renamethecorrespondingreferenced_col_namesand
find the equivalent referenced index also */ for (unsigned f = 0; f < foreign->n_fields; f++) {
constchar*& rc =
foreign->referenced_col_names[f]; if (strcmp(rc, from)) { continue;
}
if (to_len <= strlen(rc)) {
memcpy(const_cast<char*>(rc), to,
to_len + 1);
} else {
rc = static_cast<char*>(
mem_heap_dup(
foreign->heap,
to, to_len + 1));
}
}
/* New index can be null if InnoDB already dropped thereferencedindexwhenFOREIGN_KEY_CHECKSis
disabled */
foreign->referenced_index = dict_foreign_find_index(
foreign->referenced_table, NULL,
foreign->referenced_col_names,
foreign->n_fields, NULL, true, false,
NULL, NULL, NULL); return;
}
for (unsigned f = 0; f < foreign->n_fields; f++) { /* foreign->referenced_col_names[] need to be copies,becausetheconstraintmaybecome orphanwhenforeign_key_checks=0andthe
parent table is dropped. */
/**********************************************************************//**
Renames a column of a table in the data dictionary cache. */ void
dict_mem_table_col_rename( /*======================*/
dict_table_t* table, /*!< in/out: table */
ulint nth_col,/*!< in: column index */ const LEX_CSTRING &from,/*!< in: old column name */ const LEX_CSTRING &to, /*!< in: new column name */ bool is_virtual) /*!< in: if this is a virtual column */
{ constchar* s = is_virtual ? table->v_col_names : table->col_names;
/** Duplicate a string to a memory heap, with lower-case conversion @paramheapmemoryheapwherestringisallocated @paramcsthecharactersetofthestring @paramstrthesourcestring
@return own: a NUL-terminated lower-cased copy of str */ static LEX_STRING mem_heap_alloc_casedn_z(mem_heap_t *heap,
CHARSET_INFO *cs, const LEX_CSTRING &str) noexcept
{
size_t nbytes= str.length * cs->casedn_multiply() + 1;
LEX_STRING res;
res.str= static_cast<char*>(mem_heap_alloc(heap, nbytes));
res.length= cs->casedn_z(str.str, str.length, res.str, nbytes); return res;
}
/**********************************************************************//**
Sets the foreign_table_name_lookup pointer based on the value of
lower_case_table_names. If that is 0or1, foreign_table_name_lookup
will point to foreign_table_name. If2, then another string is
allocated from foreign->heap and set to lower case. */ void
dict_foreign_t::foreign_table_name_lookup_set()
{ if (lower_case_table_names == 2) {
LEX_STRING str= mem_heap_alloc_casedn_z(heap,
system_charset_info,
Lex_cstring_strlen(foreign_table_name));
foreign_table_name_lookup= str.str;
} else {
foreign_table_name_lookup = foreign_table_name;
}
}
/**********************************************************************//**
Sets the referenced_table_name_lookup pointer based on the value of
lower_case_table_names. If that is 0or1, referenced_table_name_lookup
will point to referenced_table_name. If2, then another string is
allocated from foreign->heap and set to lower case. */ void
dict_foreign_t::referenced_table_name_lookup_set()
{ if (lower_case_table_names == 2) {
LEX_STRING str= mem_heap_alloc_casedn_z(heap,
system_charset_info,
Lex_cstring_strlen(referenced_table_name));
referenced_table_name_lookup = str.str;
} else {
referenced_table_name_lookup = referenced_table_name;
}
}
/** Fill the virtual column set with virtual column information presentinthegivenvirtualindex. @param[in]indexvirtualindex
@param[out] v_cols virtual column set. */ static void
dict_mem_fill_vcol_has_index( const dict_index_t* index,
dict_vcol_set** v_cols)
{ for (ulint i = 0; i < index->table->n_v_cols; i++) {
dict_v_col_t* v_col = dict_table_get_nth_v_col(
index->table, i); if (!v_col->m_col.ord_part) { continue;
}
for (constauto& v_idx : v_col->v_indexes) { if (v_idx.index != index) { continue;
}
if (*v_cols == NULL) {
*v_cols = UT_NEW_NOKEY(dict_vcol_set());
}
(*v_cols)->insert(v_col);
}
}
}
/** Fill the virtual column set with the virtual column of the index iftheindexcontainsgivencolumnname. @param[in]col_namecolumnname @param[in]tableinnodbtableobject
@param[out] v_cols set of virtual column information. */ static void
dict_mem_fill_vcol_from_v_indexes( constchar* col_name, const dict_table_t* table,
dict_vcol_set** v_cols)
{ /* virtual column can't be Primary Key, so start with
secondary index */ for (dict_index_t* index = dict_table_get_next_index(
dict_table_get_first_index(table));
index;
index = dict_table_get_next_index(index)) {
/* Skip if the index have newly added virtualcolumnbecausefieldnameisNULL. Latervirtualcolumnsetwillbe
refreshed during loading of table. */ if (!dict_index_has_virtual(index)
|| index->has_new_v_col()) { continue;
}
for (ulint i = 0; i < index->n_fields; i++) {
dict_field_t* field =
dict_index_get_nth_field(index, i);
/** Fill the virtual column set with virtual columns which have base columns asthegivencol_name @param[in]col_namecolumnname @param[in]tabletableobject
@param[out] v_cols set of virtual columns. */ static void
dict_mem_fill_vcol_set_for_base_col( constchar* col_name, const dict_table_t* table,
dict_vcol_set** v_cols)
{ for (ulint i = 0; i < table->n_v_cols; i++) {
dict_v_col_t* v_col = dict_table_get_nth_v_col(table, i);
if (!v_col->m_col.ord_part) { continue;
}
for (ulint j = 0; j < unsigned{v_col->num_base}; j++) { if (strcmp(col_name, dict_table_get_col_name(
table,
v_col->base_col[j]->ind).str) == 0) {
if (*v_cols == NULL) {
*v_cols = UT_NEW_NOKEY(dict_vcol_set());
}
(*v_cols)->insert(v_col);
}
}
}
}
/** Fills the dependent virtual columns in a set. Reasonforbeingdependentare 1)FKcanbepresentonbasecolumnofvirtualcolumns 2)FKcanbepresentoncolumnwhichisapartofvirtualindex
@param[in,out] foreign foreign key information. */ void
dict_mem_foreign_fill_vcol_set(
dict_foreign_t* foreign)
{
ulint type = foreign->type;
if (type == 0) { return;
}
for (ulint i = 0; i < foreign->n_fields; i++) { /** FK can be present on base columns
of virtual columns. */
dict_mem_fill_vcol_set_for_base_col(
foreign->foreign_col_names[i],
foreign->foreign_table,
&foreign->v_cols);
/** FK can be present on the columns
which can be a part of virtual index. */
dict_mem_fill_vcol_from_v_indexes(
foreign->foreign_col_names[i],
foreign->foreign_table,
&foreign->v_cols);
}
}
/** Fill virtual columns set in each fk constraint present in the table.
@param[in,out] table innodb table object. */ void
dict_mem_table_fill_foreign_vcol_set(
dict_table_t* table)
{
dict_foreign_set fk_set = table->foreign_set;
dict_foreign_t* foreign;
dict_foreign_set::iterator it; for (it = fk_set.begin(); it != fk_set.end(); ++it) {
foreign = *it;
dict_mem_foreign_fill_vcol_set(foreign);
}
}
/** Free the vcol_set from all foreign key constraint on the table.
@param[in,out] table innodb table object. */ void
dict_mem_table_free_foreign_vcol_set(
dict_table_t* table)
{
dict_foreign_set fk_set = table->foreign_set;
dict_foreign_t* foreign;
dict_foreign_set::iterator it; for (it = fk_set.begin(); it != fk_set.end(); ++it) {
/** Validate the search order in the foreign key set. @param[in]fk_settheforeignkeysettobevalidated
@return true if search order is fine in the set, false otherwise. */ bool
dict_foreign_set_validate( const dict_foreign_set& fk_set)
{
dict_foreign_not_exists not_exists(fk_set);
dict_foreign_set::const_iterator it = std::find_if(
fk_set.begin(), fk_set.end(), not_exists);
/** Validate the search order in the foreign key sets of the table (foreign_setandreferenced_set). @param[in]tabletablewhoseforeignkeysetsaretobevalidated
@return true if foreign key sets are fine, false otherwise. */ bool
dict_foreign_set_validate( const dict_table_t& table)
{ return(dict_foreign_set_validate(table.foreign_set)
&& dict_foreign_set_validate(table.referenced_set));
}
/** Check if record in clustered index is historical row. @param[in,out]mtrmini-transaction @param[in]recclusteredrow @param[in]offsetsoffsets
@return true if row is historical */ bool dict_index_t::vers_history_row(const rec_t *rec, const rec_offs *offsets)
{
ut_ad(is_primary());
/** Check if record in secondary index is historical row. @param[in,out]mtrmini-transaction @param[in]recrecordinasecondaryindex @param[out]history_rowtrueifrowishistorical
@return true on error */ bool
dict_index_t::vers_history_row(
mtr_t* mtr, const rec_t* rec, bool &history_row)
{
ut_ad(!is_primary());
history_row = clust_index->vers_history_row(clust_rec, offsets); if (heap) {
mem_heap_free(heap);
}
} else {
ib::error() << "foreign constraints: secondary index is out of " "sync";
ut_ad("secondary index is out of sync" == 0);
error = true;
}
mtr->rollback_to_savepoint(sp); return(error);
}
/** Checks whether the file name belongs to a partition of a table. @paramfile_namefilename @returnpointertotheendofthetablenamepartofthefilename
@retval nullptr if the file name does not belong to a partition. */ constchar *dict_is_partition(constchar *file_name)
{ /* We look for pattern #P# to see if the table is partitioned MariaDBtable.Wealsolookfor#p#pattern,becauseitwas
previously used on Windows. */ for (constchar *p= file_name;; p++)
{
p= strchr(p, '#'); if (!p) break; if ((p[1] == 'P' || p[1] == 'p') && p[2] == '#') return p;
} return nullptr;
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.23 Sekunden
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.