summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2017-04-19 16:34:36 +0300
committerAleksey Midenkov <midenok@gmail.com>2017-05-05 20:36:37 +0300
commit27a6ef0a9e3185db5bb59e2706fc3f3324c37b27 (patch)
treeabe3d96f45275bfceae970a7174052e836f45fb4 /storage
parent7d2ed77e31c18c28fa891699ae4dafcb3b087afe (diff)
downloadmariadb-git-27a6ef0a9e3185db5bb59e2706fc3f3324c37b27.tar.gz
IB,SQL: Innopart UPDATE [fixes #178]
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/handler/ha_innodb.cc8
-rw-r--r--storage/innobase/handler/ha_innodb.h5
-rw-r--r--storage/innobase/handler/ha_innopart.h40
3 files changed, 48 insertions, 5 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index ac3e2edf304..bd8eb6b4d88 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -8718,8 +8718,7 @@ no_commit:
innobase_srv_conc_enter_innodb(m_prebuilt);
vers_set_fields = table->versioned() && (
- (sql_command != SQLCOM_DELETE ||
- (m_int_table_flags & HA_INNOPART_DISABLED_TABLE_FLAGS)) &&
+ !is_innopart() &&
sql_command != SQLCOM_CREATE_TABLE) ?
ROW_INS_VERSIONED :
ROW_INS_NORMAL;
@@ -9527,8 +9526,7 @@ ha_innobase::update_row(
innobase_srv_conc_enter_innodb(m_prebuilt);
- vers_set_fields = m_prebuilt->upd_node->versioned &&
- (m_int_table_flags & HA_INNOPART_DISABLED_TABLE_FLAGS);
+ vers_set_fields = m_prebuilt->upd_node->versioned && !is_innopart();
error = row_update_for_mysql((byte*) old_row, m_prebuilt, vers_set_fields);
@@ -9652,7 +9650,7 @@ ha_innobase::delete_row(
bool vers_set_fields =
table->versioned() &&
- (m_int_table_flags & HA_INNOPART_DISABLED_TABLE_FLAGS) &&
+ !is_innopart() &&
table->vers_end_field()->is_max();
error = row_update_for_mysql(
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index f4600a6415b..94155fdf18b 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -519,6 +519,11 @@ protected:
/** If mysql has locked with external_lock() */
bool m_mysql_has_locked;
+
+ bool is_innopart()
+ {
+ return m_share == NULL;
+ }
};
diff --git a/storage/innobase/handler/ha_innopart.h b/storage/innobase/handler/ha_innopart.h
index ab445cf25ca..ef66420acb1 100644
--- a/storage/innobase/handler/ha_innopart.h
+++ b/storage/innobase/handler/ha_innopart.h
@@ -1119,6 +1119,19 @@ private:
write_row(
uchar* record)
{
+ if (table->versioned())
+ {
+ trx_t* trx = thd_to_trx(ha_thd());
+ if (!trx->id)
+ trx_start_if_not_started_xa(trx, true);
+ ut_a(trx->id);
+ ut_a(table->record[0] == record);
+ bitmap_set_bit(table->write_set, table->vers_start_field()->field_index);
+ bitmap_set_bit(table->write_set, table->vers_end_field()->field_index);
+ table->vers_start_field()->set_notnull();
+ table->vers_start_field()->store(trx->id, true);
+ table->vers_end_field()->set_max();
+ }
return(Partition_helper::ph_write_row(record));
}
@@ -1127,6 +1140,31 @@ private:
const uchar* old_record,
uchar* new_record)
{
+ int err;
+ if (table->versioned() && table->vers_end_field()->is_max()) {
+ trx_t* trx = thd_to_trx(ha_thd());
+ if (!trx->id)
+ trx_start_if_not_started_xa(trx, true);
+ ut_a(trx->id);
+ ut_a(table->record[0] == new_record);
+ ut_a(table->record[1] == old_record);
+ store_record(table, record[2]); // store new_record
+ restore_record(table, record[1]); // restore old_record
+ // modify and insert old_record
+ bitmap_set_bit(table->write_set, table->vers_end_field()->field_index);
+ table->vers_end_field()->set_notnull();
+ table->vers_end_field()->store(trx->id, true);
+ err = Partition_helper::ph_write_row(const_cast<uchar*>(table->record[0]));
+ restore_record(table, record[2]); // restore new_record
+ if (err)
+ return err;
+ table->vers_start_field()->store(trx->id, true);
+ }
+ if (unlikely(get_part_for_delete(old_record,
+ new_record,
+ m_part_info,
+ &m_last_part)))
+ return HA_ERR_INTERNAL_ERROR;
return(Partition_helper::ph_update_row(old_record, new_record));
}
@@ -1145,6 +1183,8 @@ private:
ut_a(table->record[0] == record);
store_record(table, record[1]);
ut_a(trx->id);
+ bitmap_set_bit(table->write_set, table->vers_end_field()->field_index);
+ table->vers_end_field()->set_notnull();
table->vers_end_field()->store(trx->id, true);
return Partition_helper::ph_update_row(table->record[1], table->record[0]);
}