summaryrefslogtreecommitdiff
path: root/sql/ha_innodb.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/ha_innodb.cc')
-rw-r--r--sql/ha_innodb.cc73
1 files changed, 67 insertions, 6 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 6eae315e443..9f14e22ce38 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -750,6 +750,8 @@ ha_innobase::init_table_handle_for_HANDLER(void)
prebuilt->read_just_key = FALSE;
prebuilt->used_in_HANDLER = TRUE;
+
+ prebuilt->keep_other_fields_on_keyread = FALSE;
}
/*************************************************************************
@@ -2052,12 +2054,15 @@ build_template(
update field->query_id so that the formula
thd->query_id == field->query_id did not work. */
- if (templ_type == ROW_MYSQL_REC_FIELDS
- && !(fetch_all_in_key
- && dict_index_contains_col_or_prefix(index, i))
- && !(fetch_primary_key_cols
- && dict_table_col_in_clustered_key(index->table, i))
- && thd->query_id != field->query_id) {
+ ibool index_contains_field=
+ dict_index_contains_col_or_prefix(index, i);
+
+ if (templ_type == ROW_MYSQL_REC_FIELDS &&
+ ((prebuilt->read_just_key && !index_contains_field) ||
+ (!(fetch_all_in_key && index_contains_field) &&
+ !(fetch_primary_key_cols &&
+ dict_table_col_in_clustered_key(index->table, i)) &&
+ thd->query_id != field->query_id))) {
/* This field is not needed in the query, skip it */
@@ -4559,9 +4564,11 @@ ha_innobase::extra(
if (prebuilt->blob_heap) {
row_mysql_prebuilt_free_blob_heap(prebuilt);
}
+ prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0;
break;
case HA_EXTRA_RESET_STATE:
+ prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0;
break;
case HA_EXTRA_NO_KEYREAD:
@@ -4580,6 +4587,9 @@ ha_innobase::extra(
case HA_EXTRA_KEYREAD:
prebuilt->read_just_key = 1;
break;
+ case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
+ prebuilt->keep_other_fields_on_keyread = 1;
+ break;
default:/* Do nothing */
;
}
@@ -4628,6 +4638,7 @@ ha_innobase::start_stmt(
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
prebuilt->read_just_key = 0;
+ prebuilt->keep_other_fields_on_keyread = FALSE;
if (!prebuilt->mysql_has_locked) {
/* This handle is for a temporary table created inside
@@ -4720,6 +4731,7 @@ ha_innobase::external_lock(
prebuilt->hint_need_to_fetch_extra_cols = 0;
prebuilt->read_just_key = 0;
+ prebuilt->keep_other_fields_on_keyread = FALSE;
if (lock_type == F_WRLCK) {
@@ -5188,6 +5200,55 @@ innobase_store_binlog_offset_and_flush_log(
log_buffer_flush_to_disk();
}
+
+int
+ha_innobase::cmp_ref(
+ const mysql_byte *ref1,
+ const mysql_byte *ref2)
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ enum_field_types mysql_type;
+ Field* field;
+ int result;
+
+ if (prebuilt->clust_index_was_generated)
+ return memcmp(ref1, ref2, DATA_ROW_ID_LEN);
+
+ /* Do type-aware comparison of Primary Key members. PK members
+ are always NOT NULL, so no checks for NULL are performed */
+ KEY_PART_INFO *key_part= table->key_info[table->primary_key].key_part;
+ KEY_PART_INFO *key_part_end=
+ key_part + table->key_info[table->primary_key].key_parts;
+ for (; key_part != key_part_end; ++key_part) {
+ field = key_part->field;
+ mysql_type = field->type();
+ if (mysql_type == FIELD_TYPE_TINY_BLOB
+ || mysql_type == FIELD_TYPE_MEDIUM_BLOB
+ || mysql_type == FIELD_TYPE_BLOB
+ || mysql_type == FIELD_TYPE_LONG_BLOB) {
+
+ ut_a(!ref1[1]);
+ ut_a(!ref2[1]);
+ byte len1= *ref1;
+ byte len2= *ref2;
+ ref1 += 2;
+ ref2 += 2;
+ result =
+ ((Field_blob*)field)->cmp((const char*)ref1, len1,
+ (const char*)ref2, len2);
+ } else {
+ result =
+ field->cmp((const char*)ref1, (const char*)ref2);
+ }
+
+ if (result)
+ return result;
+ ref1 += key_part->length;
+ ref2 += key_part->length;
+ }
+ return 0;
+}
+
char *ha_innobase::get_mysql_bin_log_name()
{
return trx_sys_mysql_bin_log_name;