mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
SQL, IB: various refactoring [#337]
This commit is contained in:
committed by
Aleksey Midenkov
parent
4dd8736c15
commit
0cdc1164dc
@@ -198,7 +198,7 @@ enum enum_indicator_type
|
|||||||
#define VERS_SYS_END_FLAG (1 << 28) /* autogenerated column declared with
|
#define VERS_SYS_END_FLAG (1 << 28) /* autogenerated column declared with
|
||||||
`generated always as row end`
|
`generated always as row end`
|
||||||
(see II.a SQL Standard).*/
|
(see II.a SQL Standard).*/
|
||||||
#define VERS_OPTIMIZED_UPDATE_FLAG (1 << 29) /* column that doesn't support
|
#define VERS_UPDATE_UNVERSIONED_FLAG (1 << 29) /* column that doesn't support
|
||||||
system versioning when table
|
system versioning when table
|
||||||
itself supports it*/
|
itself supports it*/
|
||||||
#define HIDDEN_FLAG (1 << 31) /* hide from SELECT * */
|
#define HIDDEN_FLAG (1 << 31) /* hide from SELECT * */
|
||||||
|
@@ -1455,6 +1455,11 @@ public:
|
|||||||
return flags & (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG);
|
return flags & (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vers_update_unversioned() const
|
||||||
|
{
|
||||||
|
return flags & VERS_UPDATE_UNVERSIONED_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool vers_trx_id() const
|
virtual bool vers_trx_id() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@@ -6859,7 +6859,7 @@ bool Vers_parse_info::check_and_fix_implicit(
|
|||||||
!with_system_versioning) ||
|
!with_system_versioning) ||
|
||||||
f->versioning == Column_definition::WITHOUT_VERSIONING)
|
f->versioning == Column_definition::WITHOUT_VERSIONING)
|
||||||
{
|
{
|
||||||
f->flags|= VERS_OPTIMIZED_UPDATE_FLAG;
|
f->flags|= VERS_UPDATE_UNVERSIONED_FLAG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6999,7 +6999,7 @@ bool Vers_parse_info::check_and_fix_alter(THD *thd, Alter_info *alter_info,
|
|||||||
while (Create_field *f= it++)
|
while (Create_field *f= it++)
|
||||||
{
|
{
|
||||||
if (f->versioning == Column_definition::WITHOUT_VERSIONING)
|
if (f->versioning == Column_definition::WITHOUT_VERSIONING)
|
||||||
f->flags|= VERS_OPTIMIZED_UPDATE_FLAG;
|
f->flags|= VERS_UPDATE_UNVERSIONED_FLAG;
|
||||||
|
|
||||||
if (f->change.str && (start == f->change || end == f->change))
|
if (f->change.str && (start == f->change || end == f->change))
|
||||||
{
|
{
|
||||||
|
@@ -10384,7 +10384,7 @@ Item *Item_field::vers_optimized_fields_transformer(THD *thd, uchar *)
|
|||||||
if (!field)
|
if (!field)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (field->flags & VERS_OPTIMIZED_UPDATE_FLAG && context &&
|
if (field->vers_update_unversioned() && context &&
|
||||||
field->table->pos_in_table_list &&
|
field->table->pos_in_table_list &&
|
||||||
field->table->pos_in_table_list->vers_conditions)
|
field->table->pos_in_table_list->vers_conditions)
|
||||||
{
|
{
|
||||||
|
@@ -710,12 +710,6 @@ extern "C" void thd_kill_timeout(THD* thd)
|
|||||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Time_zone * thd_get_timezone(THD * thd)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(thd && thd->variables.time_zone);
|
|
||||||
return thd->variables.time_zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
void thd_vers_update_trt(THD * thd, bool value)
|
void thd_vers_update_trt(THD * thd, bool value)
|
||||||
{
|
{
|
||||||
thd->vers_update_trt= value;
|
thd->vers_update_trt= value;
|
||||||
|
@@ -155,6 +155,7 @@ extern bool volatile shutdown_in_progress;
|
|||||||
|
|
||||||
extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd);
|
extern "C" LEX_STRING * thd_query_string (MYSQL_THD thd);
|
||||||
extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen);
|
extern "C" size_t thd_query_safe(MYSQL_THD thd, char *buf, size_t buflen);
|
||||||
|
void thd_vers_update_trt(THD *thd, bool value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@class CSET_STRING
|
@class CSET_STRING
|
||||||
@@ -4564,6 +4565,8 @@ public:
|
|||||||
/* Handling of timeouts for commands */
|
/* Handling of timeouts for commands */
|
||||||
thr_timer_t query_timer;
|
thr_timer_t query_timer;
|
||||||
|
|
||||||
|
// Storage engine may set this to true is we want to write a row to
|
||||||
|
// transaction_registry table on transaction commit.
|
||||||
bool vers_update_trt;
|
bool vers_update_trt;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@@ -16743,7 +16743,7 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field,
|
|||||||
HIDDEN_FLAG |
|
HIDDEN_FLAG |
|
||||||
VERS_SYS_START_FLAG |
|
VERS_SYS_START_FLAG |
|
||||||
VERS_SYS_END_FLAG |
|
VERS_SYS_END_FLAG |
|
||||||
VERS_OPTIMIZED_UPDATE_FLAG));
|
VERS_UPDATE_UNVERSIONED_FLAG));
|
||||||
if (org_field->maybe_null() || (item && item->maybe_null))
|
if (org_field->maybe_null() || (item && item->maybe_null))
|
||||||
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
|
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
|
||||||
if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
|
if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
|
||||||
|
@@ -2188,7 +2188,7 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
|
|||||||
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
|
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field->flags & VERS_OPTIMIZED_UPDATE_FLAG)
|
if (field->vers_update_unversioned())
|
||||||
{
|
{
|
||||||
packet->append(STRING_WITH_LEN(" WITHOUT SYSTEM VERSIONING"));
|
packet->append(STRING_WITH_LEN(" WITHOUT SYSTEM VERSIONING"));
|
||||||
}
|
}
|
||||||
|
@@ -161,7 +161,7 @@ static bool check_has_vers_fields(List<Item> &items)
|
|||||||
while (Item *item= it++)
|
while (Item *item= it++)
|
||||||
{
|
{
|
||||||
if (Item_field *item_field= item->field_for_view_update())
|
if (Item_field *item_field= item->field_for_view_update())
|
||||||
if (!(item_field->field->flags & VERS_OPTIMIZED_UPDATE_FLAG))
|
if (!item_field->field->vers_update_unversioned())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@@ -2051,7 +2051,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
|||||||
{
|
{
|
||||||
uchar flags= *extra2_field_flags++;
|
uchar flags= *extra2_field_flags++;
|
||||||
if (flags & VERS_OPTIMIZED_UPDATE)
|
if (flags & VERS_OPTIMIZED_UPDATE)
|
||||||
reg_field->flags|= VERS_OPTIMIZED_UPDATE_FLAG;
|
reg_field->flags|= VERS_UPDATE_UNVERSIONED_FLAG;
|
||||||
if (flags & HIDDEN)
|
if (flags & HIDDEN)
|
||||||
reg_field->flags|= HIDDEN_FLAG;
|
reg_field->flags|= HIDDEN_FLAG;
|
||||||
}
|
}
|
||||||
@@ -8527,7 +8527,8 @@ void TR_table::store(uint field_id, timeval ts)
|
|||||||
|
|
||||||
void TR_table::store_data(ulonglong trx_id, ulonglong commit_id, timeval commit_ts)
|
void TR_table::store_data(ulonglong trx_id, ulonglong commit_id, timeval commit_ts)
|
||||||
{
|
{
|
||||||
timeval start_time= {thd->start_time, thd->start_time_sec_part};
|
timeval start_time= {static_cast<int>(thd->start_time),
|
||||||
|
static_cast<int>(thd->start_time_sec_part)};
|
||||||
store(FLD_TRX_ID, trx_id);
|
store(FLD_TRX_ID, trx_id);
|
||||||
store(FLD_COMMIT_ID, commit_id);
|
store(FLD_COMMIT_ID, commit_id);
|
||||||
store(FLD_BEGIN_TS, start_time);
|
store(FLD_BEGIN_TS, start_time);
|
||||||
|
94
sql/table.h
94
sql/table.h
@@ -2930,14 +2930,14 @@ inline void mark_as_null_row(TABLE *table)
|
|||||||
|
|
||||||
bool is_simple_order(ORDER *order);
|
bool is_simple_order(ORDER *order);
|
||||||
|
|
||||||
|
class Open_tables_backup;
|
||||||
|
|
||||||
/** Transaction Registry Table (TRT)
|
/** Transaction Registry Table (TRT)
|
||||||
|
|
||||||
This table holds transaction IDs, their corresponding times and other
|
This table holds transaction IDs, their corresponding times and other
|
||||||
transaction-related data which is used for transaction order resolution.
|
transaction-related data which is used for transaction order resolution.
|
||||||
When versioned table marks its records lifetime with transaction IDs,
|
When versioned table marks its records lifetime with transaction IDs,
|
||||||
TRT is used to get their actual timestamps. */
|
TRT is used to get their actual timestamps. */
|
||||||
|
|
||||||
class Open_tables_backup;
|
|
||||||
class TR_table: public TABLE_LIST
|
class TR_table: public TABLE_LIST
|
||||||
{
|
{
|
||||||
THD *thd;
|
THD *thd;
|
||||||
@@ -2952,33 +2952,111 @@ public:
|
|||||||
FLD_ISO_LEVEL,
|
FLD_ISO_LEVEL,
|
||||||
FIELD_COUNT
|
FIELD_COUNT
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
@param[in,out] Thread handle
|
||||||
|
@param[in] Current transaction is read-write.
|
||||||
|
*/
|
||||||
TR_table(THD *_thd, bool rw= false);
|
TR_table(THD *_thd, bool rw= false);
|
||||||
|
/**
|
||||||
|
Opens a transaction_registry table.
|
||||||
|
|
||||||
|
@retval true on error, false otherwise.
|
||||||
|
*/
|
||||||
bool open();
|
bool open();
|
||||||
~TR_table();
|
~TR_table();
|
||||||
|
/**
|
||||||
|
@retval current thd
|
||||||
|
*/
|
||||||
THD *get_thd() const { return thd; }
|
THD *get_thd() const { return thd; }
|
||||||
|
/**
|
||||||
|
Stores value to internal transaction_registry TABLE object.
|
||||||
|
|
||||||
|
@param[in] field number in a TABLE
|
||||||
|
@param[in] value to store
|
||||||
|
*/
|
||||||
void store(uint field_id, ulonglong val);
|
void store(uint field_id, ulonglong val);
|
||||||
|
/**
|
||||||
|
Stores value to internal transaction_registry TABLE object.
|
||||||
|
|
||||||
|
@param[in] field number in a TABLE
|
||||||
|
@param[in] value to store
|
||||||
|
*/
|
||||||
void store(uint field_id, timeval ts);
|
void store(uint field_id, timeval ts);
|
||||||
|
/**
|
||||||
|
Stores value to internal transaction_registry TABLE object.
|
||||||
|
|
||||||
|
@param[in] current (InnoDB) transaction id
|
||||||
|
@param[in] InnoDB transaction counter at the time of transaction commit
|
||||||
|
@param[in] transaction commit timestamp
|
||||||
|
*/
|
||||||
void store_data(ulonglong trx_id, ulonglong commit_id, timeval commit_ts);
|
void store_data(ulonglong trx_id, ulonglong commit_id, timeval commit_ts);
|
||||||
|
/**
|
||||||
|
Writes a row from internal TABLE object to transaction_registry table.
|
||||||
|
|
||||||
|
@retval true on error, false otherwise.
|
||||||
|
*/
|
||||||
bool update();
|
bool update();
|
||||||
// return true if found; false if not found or error
|
/**
|
||||||
|
Checks whether a row with specified transaction_id exists in a
|
||||||
|
transaction_registry table.
|
||||||
|
|
||||||
|
@param[in] transacton_id value
|
||||||
|
@retval true if exists, false it not exists or an error occured
|
||||||
|
*/
|
||||||
bool query(ulonglong trx_id);
|
bool query(ulonglong trx_id);
|
||||||
|
/**
|
||||||
|
Gets a row from transaction_registry with the closest commit_timestamp to
|
||||||
|
first argument. We can search for a value which a lesser or greater than
|
||||||
|
first argument. Also loads a row into an internal TABLE object.
|
||||||
|
|
||||||
|
@param[in] timestamp
|
||||||
|
@param[in] true if we search for a lesser timestamp, false if greater
|
||||||
|
@retval true if exists, false it not exists or an error occured
|
||||||
|
*/
|
||||||
bool query(MYSQL_TIME &commit_time, bool backwards);
|
bool query(MYSQL_TIME &commit_time, bool backwards);
|
||||||
// return true if error
|
/**
|
||||||
|
Checks whether transaction1 sees transaction0.
|
||||||
|
|
||||||
|
@param[out] true if transaction1 sees transaction0, undefined on error and
|
||||||
|
when transaction1=transaction0 and false otherwise
|
||||||
|
@param[in] transaction_id of transaction1
|
||||||
|
@param[in] transaction_id of transaction0
|
||||||
|
@param[in] commit time of transaction1 or 0 if we want it to be queried
|
||||||
|
@param[in] isolation level (from handler.h) of transaction1
|
||||||
|
@param[in] commit time of transaction0 or 0 if we want it to be queried
|
||||||
|
@retval true on error, false otherwise
|
||||||
|
*/
|
||||||
bool query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0,
|
bool query_sees(bool &result, ulonglong trx_id1, ulonglong trx_id0,
|
||||||
ulonglong commit_id1= 0, enum_tx_isolation iso_level1= ISO_READ_UNCOMMITTED,
|
ulonglong commit_id1= 0,
|
||||||
|
enum_tx_isolation iso_level1= ISO_READ_UNCOMMITTED,
|
||||||
ulonglong commit_id0= 0);
|
ulonglong commit_id0= 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@retval transaction isolation level of a row from internal TABLE object.
|
||||||
|
*/
|
||||||
enum_tx_isolation iso_level() const;
|
enum_tx_isolation iso_level() const;
|
||||||
|
/**
|
||||||
|
Stores transactioin isolation level to internal TABLE object.
|
||||||
|
*/
|
||||||
void store_iso_level(enum_tx_isolation iso_level)
|
void store_iso_level(enum_tx_isolation iso_level)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(iso_level <= ISO_SERIALIZABLE);
|
DBUG_ASSERT(iso_level <= ISO_SERIALIZABLE);
|
||||||
store(FLD_ISO_LEVEL, iso_level + 1);
|
store(FLD_ISO_LEVEL, iso_level + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Writes a message to MariaDB log about incorrect transaction_registry schema.
|
||||||
|
|
||||||
|
@param[in] a message explained what's incorrect in schema
|
||||||
|
*/
|
||||||
void warn_schema_incorrect(const char *reason);
|
void warn_schema_incorrect(const char *reason);
|
||||||
|
/**
|
||||||
|
Checks whether transaction_registry table has a correct schema.
|
||||||
|
|
||||||
|
@retval true if schema is incorrect and false otherwise
|
||||||
|
*/
|
||||||
bool check();
|
bool check();
|
||||||
|
|
||||||
public:
|
|
||||||
TABLE * operator-> () const
|
TABLE * operator-> () const
|
||||||
{
|
{
|
||||||
return table;
|
return table;
|
||||||
@@ -2992,13 +3070,13 @@ public:
|
|||||||
{
|
{
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
bool operator== (TABLE_LIST &subj) const
|
bool operator== (const TABLE_LIST &subj) const
|
||||||
{
|
{
|
||||||
if (0 != strcmp(db, subj.db))
|
if (0 != strcmp(db, subj.db))
|
||||||
return false;
|
return false;
|
||||||
return (0 == strcmp(table_name, subj.table_name));
|
return (0 == strcmp(table_name, subj.table_name));
|
||||||
}
|
}
|
||||||
bool operator!= (TABLE_LIST &subj) const
|
bool operator!= (const TABLE_LIST &subj) const
|
||||||
{
|
{
|
||||||
return !(*this == subj);
|
return !(*this == subj);
|
||||||
}
|
}
|
||||||
|
@@ -89,7 +89,5 @@ extern my_time_t sec_since_epoch_TIME(MYSQL_TIME *t);
|
|||||||
|
|
||||||
static const int MY_TZ_TABLES_COUNT= 4;
|
static const int MY_TZ_TABLES_COUNT= 4;
|
||||||
|
|
||||||
extern Time_zone* thd_get_timezone(THD* thd);
|
|
||||||
|
|
||||||
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */
|
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */
|
||||||
#endif /* TZTIME_INCLUDED */
|
#endif /* TZTIME_INCLUDED */
|
||||||
|
@@ -121,7 +121,7 @@ bool has_extra2_field_flags(List<Create_field> &create_fields)
|
|||||||
List_iterator<Create_field> it(create_fields);
|
List_iterator<Create_field> it(create_fields);
|
||||||
while (Create_field *f= it++)
|
while (Create_field *f= it++)
|
||||||
{
|
{
|
||||||
if (f->flags & (VERS_OPTIMIZED_UPDATE_FLAG | HIDDEN_FLAG))
|
if (f->flags & (VERS_UPDATE_UNVERSIONED_FLAG | HIDDEN_FLAG))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -356,7 +356,7 @@ LEX_CUSTRING build_frm_image(THD *thd, const char *table,
|
|||||||
while (Create_field *field= it++)
|
while (Create_field *field= it++)
|
||||||
{
|
{
|
||||||
uchar flags= 0;
|
uchar flags= 0;
|
||||||
if (field->flags & VERS_OPTIMIZED_UPDATE_FLAG)
|
if (field->flags & VERS_UPDATE_UNVERSIONED_FLAG)
|
||||||
flags|= VERS_OPTIMIZED_UPDATE;
|
flags|= VERS_OPTIMIZED_UPDATE;
|
||||||
if (field->flags & HIDDEN_FLAG)
|
if (field->flags & HIDDEN_FLAG)
|
||||||
flags|= HIDDEN;
|
flags|= HIDDEN;
|
||||||
|
@@ -861,3 +861,17 @@ dfield_t::clone(mem_heap_t* heap) const
|
|||||||
|
|
||||||
return(obj);
|
return(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Assuming field is sys_trx_end checks whether its value is not SYS_TRX_MAX.
|
||||||
|
@param dfield field to check
|
||||||
|
@return true for historical rows and false otherwise*/
|
||||||
|
bool
|
||||||
|
dfield_is_historical_sys_trx_end(const dfield_t* dfield)
|
||||||
|
{
|
||||||
|
static const trx_id_t MAX = TRX_ID_MAX;
|
||||||
|
ut_ad(dfield);
|
||||||
|
ut_ad(dfield->type.prtype & DATA_VERS_END);
|
||||||
|
const byte* data = static_cast<const byte*>(dfield_get_data(dfield));
|
||||||
|
ut_ad(dfield_get_len(dfield) == 8);
|
||||||
|
return(memcmp(data, &MAX, 8));
|
||||||
|
}
|
||||||
|
@@ -3623,10 +3623,9 @@ static const char* ha_innobase_exts[] = {
|
|||||||
NullS
|
NullS
|
||||||
};
|
};
|
||||||
|
|
||||||
void innodb_get_trt_data(TR_table &trt)
|
void innodb_get_trt_data(TR_table& trt) {
|
||||||
{
|
THD* thd = trt.get_thd();
|
||||||
THD *thd = trt.get_thd();
|
trx_t* trx = thd_to_trx(thd);
|
||||||
trx_t *trx = thd_to_trx(thd);
|
|
||||||
ut_a(trx);
|
ut_a(trx);
|
||||||
ut_a(trx->vers_update_trt);
|
ut_a(trx->vers_update_trt);
|
||||||
mutex_enter(&trx_sys->mutex);
|
mutex_enter(&trx_sys->mutex);
|
||||||
@@ -3637,8 +3636,7 @@ void innodb_get_trt_data(TR_table &trt)
|
|||||||
mutex_exit(&trx_sys->mutex);
|
mutex_exit(&trx_sys->mutex);
|
||||||
|
|
||||||
// silent downgrade cast warning on win64
|
// silent downgrade cast warning on win64
|
||||||
timeval commit_ts = {static_cast<int>(sec),
|
timeval commit_ts = {static_cast<int>(sec), static_cast<int>(usec)};
|
||||||
static_cast<int>(usec)};
|
|
||||||
trt.store_data(trx->id, commit_id, commit_ts);
|
trt.store_data(trx->id, commit_id, commit_ts);
|
||||||
trx->vers_update_trt = false;
|
trx->vers_update_trt = false;
|
||||||
}
|
}
|
||||||
@@ -6521,6 +6519,10 @@ no_such_table:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (table && m_prebuilt->table) {
|
||||||
|
ut_ad(table->versioned() == m_prebuilt->table->versioned());
|
||||||
|
}
|
||||||
|
|
||||||
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
|
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@@ -8365,17 +8367,18 @@ no_commit:
|
|||||||
|
|
||||||
innobase_srv_conc_enter_innodb(m_prebuilt);
|
innobase_srv_conc_enter_innodb(m_prebuilt);
|
||||||
|
|
||||||
vers_set_fields = (table->versioned_write() &&
|
vers_set_fields =
|
||||||
(sql_command != SQLCOM_CREATE_TABLE || table->s->vtmd))
|
(table->versioned_write()
|
||||||
?
|
&& (sql_command != SQLCOM_CREATE_TABLE || table->s->vtmd))
|
||||||
ROW_INS_VERSIONED :
|
? ROW_INS_VERSIONED
|
||||||
ROW_INS_NORMAL;
|
: ROW_INS_NORMAL;
|
||||||
|
|
||||||
/* Step-5: Execute insert graph that will result in actual insert. */
|
/* Step-5: Execute insert graph that will result in actual insert. */
|
||||||
error = row_insert_for_mysql((byte*) record, m_prebuilt, vers_set_fields);
|
error = row_insert_for_mysql((byte*) record, m_prebuilt, vers_set_fields);
|
||||||
|
|
||||||
if (m_prebuilt->trx->vers_update_trt)
|
if (m_prebuilt->trx->vers_update_trt) {
|
||||||
thd_vers_update_trt(m_user_thd, true);
|
thd_vers_update_trt(m_user_thd, true);
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_SYNC(m_user_thd, "ib_after_row_insert");
|
DEBUG_SYNC(m_user_thd, "ib_after_row_insert");
|
||||||
|
|
||||||
@@ -8626,6 +8629,7 @@ calc_row_difference(
|
|||||||
doc_id_t doc_id = FTS_NULL_DOC_ID;
|
doc_id_t doc_id = FTS_NULL_DOC_ID;
|
||||||
ulint num_v = 0;
|
ulint num_v = 0;
|
||||||
uint n_fields = mysql_fields(table);
|
uint n_fields = mysql_fields(table);
|
||||||
|
bool table_versioned = prebuilt->table->versioned();
|
||||||
|
|
||||||
ut_ad(!srv_read_only_mode);
|
ut_ad(!srv_read_only_mode);
|
||||||
|
|
||||||
@@ -8876,9 +8880,8 @@ calc_row_difference(
|
|||||||
}
|
}
|
||||||
n_changed++;
|
n_changed++;
|
||||||
|
|
||||||
if (!prebuilt->upd_node->versioned &&
|
if (table_versioned
|
||||||
prebuilt->table->versioned() &&
|
&& !field->vers_update_unversioned()) {
|
||||||
!(field->flags & VERS_OPTIMIZED_UPDATE_FLAG)) {
|
|
||||||
prebuilt->upd_node->versioned = true;
|
prebuilt->upd_node->versioned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8987,9 +8990,7 @@ calc_row_difference(
|
|||||||
|
|
||||||
++n_changed;
|
++n_changed;
|
||||||
|
|
||||||
if (!prebuilt->upd_node->versioned &&
|
if (table_versioned && !field->vers_update_unversioned()) {
|
||||||
prebuilt->table->versioned() &&
|
|
||||||
!(field->flags & VERS_OPTIMIZED_UPDATE_FLAG)) {
|
|
||||||
prebuilt->upd_node->versioned = true;
|
prebuilt->upd_node->versioned = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -9175,13 +9176,14 @@ ha_innobase::update_row(
|
|||||||
|
|
||||||
innobase_srv_conc_enter_innodb(m_prebuilt);
|
innobase_srv_conc_enter_innodb(m_prebuilt);
|
||||||
|
|
||||||
if (!table->versioned_write())
|
if (!table->versioned_write()) {
|
||||||
m_prebuilt->upd_node->versioned = false;
|
m_prebuilt->upd_node->versioned = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_prebuilt->upd_node->versioned) {
|
if (m_prebuilt->upd_node->versioned) {
|
||||||
vers_set_fields = true;
|
vers_set_fields = true;
|
||||||
if (thd_sql_command(m_user_thd) == SQLCOM_ALTER_TABLE && !table->s->vtmd)
|
if (thd_sql_command(m_user_thd) == SQLCOM_ALTER_TABLE
|
||||||
{
|
&& !table->s->vtmd) {
|
||||||
m_prebuilt->upd_node->vers_delete = true;
|
m_prebuilt->upd_node->vers_delete = true;
|
||||||
} else {
|
} else {
|
||||||
m_prebuilt->upd_node->vers_delete = false;
|
m_prebuilt->upd_node->vers_delete = false;
|
||||||
@@ -9192,12 +9194,14 @@ ha_innobase::update_row(
|
|||||||
error = row_update_for_mysql(m_prebuilt, vers_set_fields);
|
error = row_update_for_mysql(m_prebuilt, vers_set_fields);
|
||||||
|
|
||||||
if (error == DB_SUCCESS && vers_ins_row) {
|
if (error == DB_SUCCESS && vers_ins_row) {
|
||||||
if (trx->id != static_cast<trx_id_t>(table->vers_start_field()->val_int()))
|
if (trx->id != static_cast<trx_id_t>(table->vers_start_field()->val_int())) {
|
||||||
error = row_insert_for_mysql((byte*) old_row, m_prebuilt, ROW_INS_HISTORICAL);
|
error = row_insert_for_mysql((byte*) old_row, m_prebuilt, ROW_INS_HISTORICAL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_prebuilt->trx->vers_update_trt)
|
if (m_prebuilt->trx->vers_update_trt) {
|
||||||
thd_vers_update_trt(m_user_thd, true);
|
thd_vers_update_trt(m_user_thd, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (error == DB_SUCCESS && autoinc) {
|
if (error == DB_SUCCESS && autoinc) {
|
||||||
/* A value for an AUTO_INCREMENT column
|
/* A value for an AUTO_INCREMENT column
|
||||||
@@ -9313,13 +9317,13 @@ ha_innobase::delete_row(
|
|||||||
innobase_srv_conc_enter_innodb(m_prebuilt);
|
innobase_srv_conc_enter_innodb(m_prebuilt);
|
||||||
|
|
||||||
bool vers_set_fields =
|
bool vers_set_fields =
|
||||||
table->versioned_write() &&
|
table->versioned_write() && table->vers_end_field()->is_max();
|
||||||
table->vers_end_field()->is_max();
|
|
||||||
|
|
||||||
error = row_update_for_mysql(m_prebuilt, vers_set_fields);
|
error = row_update_for_mysql(m_prebuilt, vers_set_fields);
|
||||||
|
|
||||||
if (m_prebuilt->trx->vers_update_trt)
|
if (m_prebuilt->trx->vers_update_trt) {
|
||||||
thd_vers_update_trt(m_user_thd, true);
|
thd_vers_update_trt(m_user_thd, true);
|
||||||
|
}
|
||||||
|
|
||||||
innobase_srv_conc_exit_innodb(m_prebuilt);
|
innobase_srv_conc_exit_innodb(m_prebuilt);
|
||||||
|
|
||||||
@@ -11407,6 +11411,7 @@ create_table_info_t::create_table_def()
|
|||||||
for (i = 0; i < n_cols; i++) {
|
for (i = 0; i < n_cols; i++) {
|
||||||
ulint is_virtual;
|
ulint is_virtual;
|
||||||
bool is_stored = false;
|
bool is_stored = false;
|
||||||
|
|
||||||
Field* field = m_form->field[i];
|
Field* field = m_form->field[i];
|
||||||
ulint vers_row_start = 0;
|
ulint vers_row_start = 0;
|
||||||
ulint vers_row_end = 0;
|
ulint vers_row_end = 0;
|
||||||
|
@@ -586,8 +586,6 @@ bool thd_is_strict_mode(const MYSQL_THD thd);
|
|||||||
*/
|
*/
|
||||||
extern void mysql_bin_log_commit_pos(THD *thd, ulonglong *out_pos, const char **out_file);
|
extern void mysql_bin_log_commit_pos(THD *thd, ulonglong *out_pos, const char **out_file);
|
||||||
|
|
||||||
extern void thd_vers_update_trt(THD * thd, bool value);
|
|
||||||
|
|
||||||
/** Get the partition_info working copy.
|
/** Get the partition_info working copy.
|
||||||
@param thd Thread object.
|
@param thd Thread object.
|
||||||
@return NULL or pointer to partition_info working copy. */
|
@return NULL or pointer to partition_info working copy. */
|
||||||
|
@@ -631,9 +631,10 @@ instant_alter_column_possible(
|
|||||||
const Alter_inplace_info* ha_alter_info,
|
const Alter_inplace_info* ha_alter_info,
|
||||||
const TABLE* table)
|
const TABLE* table)
|
||||||
{
|
{
|
||||||
if (ha_alter_info->create_info->vers_info.with_system_versioning)
|
// Making table system-versioned instantly is not implemented yet.
|
||||||
|
if (ha_alter_info->create_info->vers_info.with_system_versioning) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (~ha_alter_info->handler_flags
|
if (~ha_alter_info->handler_flags
|
||||||
& Alter_inplace_info::ADD_STORED_BASE_COLUMN) {
|
& Alter_inplace_info::ADD_STORED_BASE_COLUMN) {
|
||||||
@@ -7086,8 +7087,9 @@ ok_exit:
|
|||||||
ctx->m_stage, add_v, eval_table,
|
ctx->m_stage, add_v, eval_table,
|
||||||
ha_alter_info->handler_flags & Alter_inplace_info::ALTER_DROP_HISTORICAL);
|
ha_alter_info->handler_flags & Alter_inplace_info::ALTER_DROP_HISTORICAL);
|
||||||
|
|
||||||
if (m_prebuilt->trx->vers_update_trt)
|
if (m_prebuilt->trx->vers_update_trt) {
|
||||||
thd_vers_update_trt(m_user_thd, true);
|
thd_vers_update_trt(m_user_thd, true);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
oom:
|
oom:
|
||||||
@@ -9753,7 +9755,6 @@ foreign_fail:
|
|||||||
DBUG_RETURN(false);
|
DBUG_RETURN(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@param thd the session
|
@param thd the session
|
||||||
@param start_value the lower bound
|
@param start_value the lower bound
|
||||||
|
@@ -508,6 +508,12 @@ dtuple_print(
|
|||||||
const dtuple_t* tuple) /*!< in: tuple */
|
const dtuple_t* tuple) /*!< in: tuple */
|
||||||
MY_ATTRIBUTE((nonnull));
|
MY_ATTRIBUTE((nonnull));
|
||||||
|
|
||||||
|
/** Assuming field is sys_trx_end checks whether its value is not SYS_TRX_MAX.
|
||||||
|
@param dfield field to check
|
||||||
|
@return true for historical rows and false otherwise*/
|
||||||
|
bool
|
||||||
|
dfield_is_historical_sys_trx_end(const dfield_t* dfield);
|
||||||
|
|
||||||
/** Print the contents of a tuple.
|
/** Print the contents of a tuple.
|
||||||
@param[out] o output stream
|
@param[out] o output stream
|
||||||
@param[in] field array of data fields
|
@param[in] field array of data fields
|
||||||
|
@@ -229,39 +229,4 @@ struct ins_node_t{
|
|||||||
#define INS_NODE_ALLOC_ROW_ID 2 /* row id should be allocated */
|
#define INS_NODE_ALLOC_ROW_ID 2 /* row id should be allocated */
|
||||||
#define INS_NODE_INSERT_ENTRIES 3 /* index entries should be built and
|
#define INS_NODE_INSERT_ENTRIES 3 /* index entries should be built and
|
||||||
inserted */
|
inserted */
|
||||||
|
|
||||||
UNIV_INLINE
|
|
||||||
void row_ins_set_tuple_col_8(
|
|
||||||
dtuple_t* tuple,
|
|
||||||
int col,
|
|
||||||
ib_uint64_t data,
|
|
||||||
byte* buf)
|
|
||||||
{
|
|
||||||
static const ulint fsize = sizeof(data);
|
|
||||||
dfield_t* dfield = dtuple_get_nth_field(tuple, col);
|
|
||||||
ut_ad(dfield->type.len == fsize);
|
|
||||||
if (dfield->len == UNIV_SQL_NULL) {
|
|
||||||
dfield_set_data(dfield, buf, fsize);
|
|
||||||
}
|
|
||||||
ut_ad(dfield->len == dfield->type.len && dfield->data);
|
|
||||||
mach_write_to_8(dfield->data, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
UNIV_INLINE
|
|
||||||
void row_ins_set_tuple_col_8(
|
|
||||||
dtuple_t* tuple,
|
|
||||||
int col,
|
|
||||||
timeval& data,
|
|
||||||
byte* buf)
|
|
||||||
{
|
|
||||||
dfield_t* dfield = dtuple_get_nth_field(tuple, col);
|
|
||||||
ut_ad(dfield->type.len == 8);
|
|
||||||
if (dfield->len == UNIV_SQL_NULL) {
|
|
||||||
dfield_set_data(dfield, buf, 8);
|
|
||||||
}
|
|
||||||
ut_ad(dfield->len == dfield->type.len && dfield->data);
|
|
||||||
mach_write_to_4(reinterpret_cast<byte*>(dfield->data), (ulint) data.tv_sec);
|
|
||||||
mach_write_to_4(reinterpret_cast<byte*>(dfield->data) + 4, (ulint) data.tv_usec);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -237,9 +237,12 @@ row_lock_table_for_mysql(
|
|||||||
|
|
||||||
/** System Versioning: row_insert_for_mysql() modes */
|
/** System Versioning: row_insert_for_mysql() modes */
|
||||||
enum ins_mode_t {
|
enum ins_mode_t {
|
||||||
ROW_INS_NORMAL = 0, ///< plain row (without versioning)
|
/* plain row (without versioning) */
|
||||||
ROW_INS_VERSIONED, ///< sys_trx_start = TRX_ID, sys_trx_end = MAX
|
ROW_INS_NORMAL = 0,
|
||||||
ROW_INS_HISTORICAL ///< sys_trx_end = TRX_ID
|
/* sys_trx_start = TRX_ID, sys_trx_end = MAX */
|
||||||
|
ROW_INS_VERSIONED,
|
||||||
|
/* sys_trx_end = TRX_ID */
|
||||||
|
ROW_INS_HISTORICAL
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Does an insert for MySQL.
|
/** Does an insert for MySQL.
|
||||||
|
@@ -429,7 +429,7 @@ row_ins_cascade_ancestor_updates_table(
|
|||||||
|
|
||||||
upd_node = static_cast<upd_node_t*>(parent);
|
upd_node = static_cast<upd_node_t*>(parent);
|
||||||
|
|
||||||
if (upd_node->table == table && upd_node->is_delete == FALSE
|
if (upd_node->table == table && !upd_node->is_delete
|
||||||
&& !upd_node->vers_delete) {
|
&& !upd_node->vers_delete) {
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
@@ -1573,18 +1573,19 @@ private:
|
|||||||
ulint& counter;
|
ulint& counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Reads sys_trx_end field from clustered index row.
|
||||||
Reads sys_trx_end field from clustered index row.
|
@param[in] rec clustered row
|
||||||
|
@param[in] offsets offsets
|
||||||
|
@param[in] index clustered index
|
||||||
@return trx_id_t */
|
@return trx_id_t */
|
||||||
static
|
static
|
||||||
trx_id_t
|
trx_id_t
|
||||||
row_ins_get_sys_trx_end(
|
row_ins_get_sys_trx_end(
|
||||||
/*===================================*/
|
const rec_t* rec,
|
||||||
const rec_t *rec, /*!< in: clustered row */
|
const ulint* offsets,
|
||||||
ulint *offsets, /*!< in: offsets */
|
const dict_index_t* index)
|
||||||
dict_index_t *index) /*!< in: clustered index */
|
|
||||||
{
|
{
|
||||||
ut_a(dict_index_is_clust(index));
|
ut_a(index->is_clust());
|
||||||
|
|
||||||
ulint len;
|
ulint len;
|
||||||
ulint nfield = dict_col_get_clust_pos(
|
ulint nfield = dict_col_get_clust_pos(
|
||||||
@@ -1594,51 +1595,46 @@ row_ins_get_sys_trx_end(
|
|||||||
return(mach_read_from_8(field));
|
return(mach_read_from_8(field));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Performs search at clustered index and returns sys_trx_end if row was found.
|
||||||
Performs search at clustered index and returns sys_trx_end if row was found.
|
|
||||||
@param[in] index secondary index of record
|
@param[in] index secondary index of record
|
||||||
@param[in] rec record in a secondary index
|
@param[in] rec record in a secondary index
|
||||||
@param[out] end_trx_id value from clustered index
|
@return sys_trx_end on success or 0 at failure */
|
||||||
@return DB_SUCCESS, DB_NO_REFERENCED_ROW */
|
|
||||||
static
|
static
|
||||||
dberr_t
|
trx_id_t
|
||||||
row_ins_search_sys_trx_end(
|
row_ins_search_sys_trx_end(
|
||||||
dict_index_t *index,
|
dict_index_t* index,
|
||||||
const rec_t *rec,
|
const rec_t* rec)
|
||||||
trx_id_t *end_trx_id)
|
|
||||||
{
|
{
|
||||||
ut_ad(!index->is_clust());
|
ut_ad(!index->is_clust());
|
||||||
|
|
||||||
bool found = false;
|
trx_id_t result = 0;
|
||||||
mem_heap_t *heap = mem_heap_create(256);
|
mem_heap_t* heap = NULL;
|
||||||
dict_index_t *clust_index = NULL;
|
dict_index_t* clust_index = NULL;
|
||||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||||
ulint *offsets = offsets_;
|
ulint* offsets = offsets_;
|
||||||
rec_offs_init(offsets_);
|
rec_offs_init(offsets_);
|
||||||
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
mtr_start(&mtr);
|
mtr.start();
|
||||||
|
|
||||||
rec_t *clust_rec =
|
rec_t* clust_rec =
|
||||||
row_get_clust_rec(BTR_SEARCH_LEAF, rec, index, &clust_index, &mtr);
|
row_get_clust_rec(BTR_SEARCH_LEAF, rec, index, &clust_index, &mtr);
|
||||||
if (!clust_rec)
|
if (clust_rec) {
|
||||||
goto not_found;
|
|
||||||
|
|
||||||
offsets = rec_get_offsets(clust_rec, clust_index, offsets, true,
|
offsets = rec_get_offsets(clust_rec, clust_index, offsets, true,
|
||||||
ULINT_UNDEFINED, &heap);
|
ULINT_UNDEFINED, &heap);
|
||||||
|
|
||||||
*end_trx_id = row_ins_get_sys_trx_end(clust_rec, offsets, clust_index);
|
result =
|
||||||
found = true;
|
row_ins_get_sys_trx_end(clust_rec, offsets, clust_index);
|
||||||
not_found:
|
} else {
|
||||||
mtr_commit(&mtr);
|
|
||||||
mem_heap_free(heap);
|
|
||||||
if (!found) {
|
|
||||||
ib::error() << "foreign constraints: secondary index is out of "
|
ib::error() << "foreign constraints: secondary index is out of "
|
||||||
"sync";
|
"sync";
|
||||||
ut_ad(false && "secondary index is out of sync");
|
ut_ad(!"secondary index is out of sync");
|
||||||
return(DB_NO_REFERENCED_ROW);
|
|
||||||
}
|
}
|
||||||
return(DB_SUCCESS);
|
mtr.commit();
|
||||||
|
if (heap) {
|
||||||
|
mem_heap_free(heap);
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************//**
|
/***************************************************************//**
|
||||||
@@ -1705,15 +1701,13 @@ row_ins_check_foreign_constraint(
|
|||||||
}
|
}
|
||||||
/* System Versioning: if sys_trx_end != Inf, we
|
/* System Versioning: if sys_trx_end != Inf, we
|
||||||
suppress the foreign key check */
|
suppress the foreign key check */
|
||||||
if (table->versioned() &&
|
if (dfield_get_type(field)->prtype & DATA_VERS_END) {
|
||||||
dfield_get_type(field)->prtype & DATA_VERS_END) {
|
ut_ad(table->versioned());
|
||||||
byte* data = static_cast<byte*>(dfield_get_data(field));
|
if (dfield_is_historical_sys_trx_end(field)) {
|
||||||
ut_ad(data);
|
|
||||||
trx_id_t end_trx_id = mach_read_from_8(data);
|
|
||||||
if (end_trx_id != TRX_ID_MAX)
|
|
||||||
goto exit_func;
|
goto exit_func;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (que_node_get_type(thr->run_node) == QUE_NODE_UPDATE) {
|
if (que_node_get_type(thr->run_node) == QUE_NODE_UPDATE) {
|
||||||
upd_node = static_cast<upd_node_t*>(thr->run_node);
|
upd_node = static_cast<upd_node_t*>(thr->run_node);
|
||||||
@@ -1844,19 +1838,20 @@ row_ins_check_foreign_constraint(
|
|||||||
if (check_table->versioned()) {
|
if (check_table->versioned()) {
|
||||||
trx_id_t end_trx_id = 0;
|
trx_id_t end_trx_id = 0;
|
||||||
|
|
||||||
if (dict_index_is_clust(check_index)) {
|
if (check_index->is_clust()) {
|
||||||
end_trx_id =
|
end_trx_id =
|
||||||
row_ins_get_sys_trx_end(
|
row_ins_get_sys_trx_end(
|
||||||
rec, offsets, check_index);
|
rec, offsets, check_index);
|
||||||
} else if (row_ins_search_sys_trx_end(
|
} else if (!(end_trx_id =
|
||||||
check_index, rec, &end_trx_id) !=
|
row_ins_search_sys_trx_end(
|
||||||
DB_SUCCESS) {
|
check_index, rec))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end_trx_id != TRX_ID_MAX)
|
if (end_trx_id != TRX_ID_MAX) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rec_get_deleted_flag(rec,
|
if (rec_get_deleted_flag(rec,
|
||||||
rec_offs_comp(offsets))) {
|
rec_offs_comp(offsets))) {
|
||||||
|
@@ -1743,6 +1743,8 @@ row_merge_read_clustered_index(
|
|||||||
ib_uint64_t read_rows = 0;
|
ib_uint64_t read_rows = 0;
|
||||||
ib_uint64_t table_total_rows = 0;
|
ib_uint64_t table_total_rows = 0;
|
||||||
ulonglong historic_auto_decrement = 0xffffffffffffffff;
|
ulonglong historic_auto_decrement = 0xffffffffffffffff;
|
||||||
|
char new_sys_trx_start[8];
|
||||||
|
char new_sys_trx_end[8];
|
||||||
|
|
||||||
DBUG_ENTER("row_merge_read_clustered_index");
|
DBUG_ENTER("row_merge_read_clustered_index");
|
||||||
|
|
||||||
@@ -1917,6 +1919,9 @@ row_merge_read_clustered_index(
|
|||||||
prev_fields = NULL;
|
prev_fields = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mach_write_to_8(new_sys_trx_start, trx->id);
|
||||||
|
mach_write_to_8(new_sys_trx_end, TRX_ID_MAX);
|
||||||
|
|
||||||
/* Scan the clustered index. */
|
/* Scan the clustered index. */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const rec_t* rec;
|
const rec_t* rec;
|
||||||
@@ -2242,13 +2247,10 @@ end_of_index:
|
|||||||
|
|
||||||
bool historical_row = false;
|
bool historical_row = false;
|
||||||
if (new_table->versioned()) {
|
if (new_table->versioned()) {
|
||||||
const dfield_t *dfield = dtuple_get_nth_field(
|
const dfield_t* dfield = dtuple_get_nth_field(
|
||||||
row, new_table->vers_end);
|
row, new_table->vers_end);
|
||||||
const byte *data = static_cast<const byte *>(
|
|
||||||
dfield_get_data(dfield));
|
|
||||||
ut_ad(dfield_get_len(dfield) == 8);
|
|
||||||
historical_row =
|
historical_row =
|
||||||
mach_read_from_8(data) != TRX_ID_MAX;
|
dfield_is_historical_sys_trx_end(dfield);
|
||||||
}
|
}
|
||||||
|
|
||||||
const dfield_t* dfield;
|
const dfield_t* dfield;
|
||||||
@@ -2272,10 +2274,11 @@ end_of_index:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ulonglong value;
|
ulonglong value;
|
||||||
if (likely(!historical_row))
|
if (likely(!historical_row)) {
|
||||||
value = sequence++;
|
value = sequence++;
|
||||||
else
|
} else {
|
||||||
value = historic_auto_decrement--;
|
value = historic_auto_decrement--;
|
||||||
|
}
|
||||||
|
|
||||||
switch (dtype_get_mtype(dtype)) {
|
switch (dtype_get_mtype(dtype)) {
|
||||||
case DATA_INT: {
|
case DATA_INT: {
|
||||||
@@ -2305,30 +2308,27 @@ end_of_index:
|
|||||||
|
|
||||||
if (old_table->versioned()) {
|
if (old_table->versioned()) {
|
||||||
if (!new_table->versioned() || drop_historical) {
|
if (!new_table->versioned() || drop_historical) {
|
||||||
const dict_col_t *col =
|
const dict_col_t* col =
|
||||||
&old_table->cols
|
&old_table->cols[old_table->vers_end];
|
||||||
[old_table->vers_end];
|
const ulint nfield =
|
||||||
const ulint nfield = dict_col_get_clust_pos(
|
dict_col_get_clust_pos(col, clust_index);
|
||||||
col, clust_index);
|
|
||||||
ulint len = 0;
|
ulint len = 0;
|
||||||
const rec_t *sys_trx_end = rec_get_nth_field(
|
const rec_t* sys_trx_end = rec_get_nth_field(
|
||||||
rec, offsets, nfield, &len);
|
rec, offsets, nfield, &len);
|
||||||
ut_ad(len == 8);
|
ut_ad(len == 8);
|
||||||
if (mach_read_from_8(sys_trx_end) != TRX_ID_MAX)
|
if (mach_read_from_8(sys_trx_end)
|
||||||
|
!= TRX_ID_MAX) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (new_table->versioned()) {
|
} else if (new_table->versioned()) {
|
||||||
void *sys_trx_start = mem_heap_alloc(row_heap, 8);
|
dfield_t* start =
|
||||||
void *sys_trx_end = mem_heap_alloc(row_heap, 8);
|
dtuple_get_nth_field(row, new_table->vers_start);
|
||||||
mach_write_to_8(sys_trx_start, trx->id);
|
dfield_t* end =
|
||||||
mach_write_to_8(sys_trx_end, TRX_ID_MAX);
|
dtuple_get_nth_field(row, new_table->vers_end);
|
||||||
dfield_t *start = dtuple_get_nth_field(
|
dfield_set_data(start, new_sys_trx_start, 8);
|
||||||
row, new_table->vers_start);
|
dfield_set_data(end, new_sys_trx_end, 8);
|
||||||
dfield_t *end = dtuple_get_nth_field(
|
trx->vers_update_trt = true;
|
||||||
row, new_table->vers_end);
|
|
||||||
dfield_set_data(start, sys_trx_start, 8);
|
|
||||||
dfield_set_data(end, sys_trx_end, 8);
|
|
||||||
trx->vers_update_trt= true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_buffers:
|
write_buffers:
|
||||||
|
@@ -1420,6 +1420,23 @@ row_mysql_get_table_status(
|
|||||||
return(err);
|
return(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Writes 8 bytes to nth tuple field
|
||||||
|
@param[in] tuple where to write
|
||||||
|
@param[in] nth index in tuple
|
||||||
|
@param[in] data what to write
|
||||||
|
@param[in] buf field data buffer */
|
||||||
|
static
|
||||||
|
void
|
||||||
|
set_tuple_col_8(dtuple_t* tuple, int col, uint64_t data, byte* buf) {
|
||||||
|
dfield_t* dfield = dtuple_get_nth_field(tuple, col);
|
||||||
|
ut_ad(dfield->type.len == 8);
|
||||||
|
if (dfield->len == UNIV_SQL_NULL) {
|
||||||
|
dfield_set_data(dfield, buf, 8);
|
||||||
|
}
|
||||||
|
ut_ad(dfield->len == dfield->type.len && dfield->data);
|
||||||
|
mach_write_to_8(dfield->data, data);
|
||||||
|
}
|
||||||
|
|
||||||
/** Does an insert for MySQL.
|
/** Does an insert for MySQL.
|
||||||
@param[in] mysql_rec row in the MySQL format
|
@param[in] mysql_rec row in the MySQL format
|
||||||
@param[in,out] prebuilt prebuilt struct in MySQL handle
|
@param[in,out] prebuilt prebuilt struct in MySQL handle
|
||||||
@@ -1504,14 +1521,14 @@ row_insert_for_mysql(
|
|||||||
ut_ad(t->mysql_col_len == 8);
|
ut_ad(t->mysql_col_len == 8);
|
||||||
|
|
||||||
if (ins_mode == ROW_INS_HISTORICAL) {
|
if (ins_mode == ROW_INS_HISTORICAL) {
|
||||||
row_ins_set_tuple_col_8(node->row, table->vers_end, trx->id, node->vers_end_buf);
|
set_tuple_col_8(node->row, table->vers_end, trx->id, node->vers_end_buf);
|
||||||
}
|
}
|
||||||
else /* ROW_INS_VERSIONED */ {
|
else /* ROW_INS_VERSIONED */ {
|
||||||
row_ins_set_tuple_col_8(node->row, table->vers_end, IB_UINT64_MAX, node->vers_end_buf);
|
set_tuple_col_8(node->row, table->vers_end, TRX_ID_MAX, node->vers_end_buf);
|
||||||
int8store(&mysql_rec[t->mysql_col_offset], IB_UINT64_MAX);
|
int8store(&mysql_rec[t->mysql_col_offset], TRX_ID_MAX);
|
||||||
t = &prebuilt->mysql_template[table->vers_start];
|
t = &prebuilt->mysql_template[table->vers_start];
|
||||||
ut_ad(t->mysql_col_len == 8);
|
ut_ad(t->mysql_col_len == 8);
|
||||||
row_ins_set_tuple_col_8(node->row, table->vers_start, trx->id, node->vers_start_buf);
|
set_tuple_col_8(node->row, table->vers_start, trx->id, node->vers_start_buf);
|
||||||
int8store(&mysql_rec[t->mysql_col_offset], trx->id);
|
int8store(&mysql_rec[t->mysql_col_offset], trx->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2129,8 +2146,8 @@ run_again:
|
|||||||
node->cascade_upd_nodes = cascade_upd_nodes;
|
node->cascade_upd_nodes = cascade_upd_nodes;
|
||||||
cascade_upd_nodes->pop_front();
|
cascade_upd_nodes->pop_front();
|
||||||
thr->fk_cascade_depth++;
|
thr->fk_cascade_depth++;
|
||||||
vers_set_fields = node->table->versioned() &&
|
vers_set_fields = node->table->versioned()
|
||||||
(node->is_delete || node->versioned);
|
&& (node->is_delete || node->versioned);
|
||||||
|
|
||||||
goto run_again;
|
goto run_again;
|
||||||
}
|
}
|
||||||
@@ -2210,11 +2227,12 @@ run_again:
|
|||||||
prebuilt->table->stat_modified_counter++;
|
prebuilt->table->stat_modified_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->table->versioned() &&
|
if (node->table->versioned()
|
||||||
(node->versioned || node->vers_delete ||
|
&& (node->versioned
|
||||||
|
|| node->vers_delete
|
||||||
// TODO: improve this check (check if we touch only
|
// TODO: improve this check (check if we touch only
|
||||||
// unversioned fields in foreigh table)
|
// unversioned fields in foreigh table)
|
||||||
node->foreign)) {
|
|| node->foreign)) {
|
||||||
trx->vers_update_trt = true;
|
trx->vers_update_trt = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user