Commit 6b8d3611 authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

refs #5728 merge varchar fast updates to mainline

git-svn-id: file:///svn/mysql/tokudb-engine/tokudb-engine@51917 c7de825b-a66e-492c-adef-691d508d4ae1
parent 80fb5720
...@@ -115,16 +115,31 @@ static Field *find_field_by_name(TABLE *table, Item *item) { ...@@ -115,16 +115,31 @@ static Field *find_field_by_name(TABLE *table, Item *item) {
// Return the starting offset in the value for a particular index (selected by idx) of a // Return the starting offset in the value for a particular index (selected by idx) of a
// particular field (selected by expand_field_num). // particular field (selected by expand_field_num).
// This only works for fixed length fields // This only works for fixed length fields
static uint32_t update_field_offset(uint32_t null_bytes, KEY_AND_COL_INFO *kc_info, int idx, int expand_field_num) { static uint32_t fixed_field_offset(uint32_t null_bytes, KEY_AND_COL_INFO *kc_info, uint idx, uint expand_field_num) {
uint32_t offset = null_bytes; uint32_t offset = null_bytes;
for (int i = 0; i < expand_field_num; i++) { for (uint i = 0; i < expand_field_num; i++) {
if (bitmap_is_set(&kc_info->key_filters[idx], i)) // skip key fields if (bitmap_is_set(&kc_info->key_filters[idx], i))
continue; continue;
offset += kc_info->field_lengths[i]; offset += kc_info->field_lengths[i];
} }
return offset; return offset;
} }
static uint32_t var_field_index(TABLE *table, KEY_AND_COL_INFO *kc_info, uint idx, uint field_num) {
assert(field_num < table->s->fields);
uint v_index = 0;
for (uint i = 0; i < table->s->fields; i++) {
if (bitmap_is_set(&kc_info->key_filters[idx], i))
continue;
if (kc_info->length_bytes[i]) {
if (i == field_num)
break;
v_index++;
}
}
return v_index;
}
// Determine if an update operation can be offloaded to the storage engine. // Determine if an update operation can be offloaded to the storage engine.
// The update operation consists of a list of update expressions (fields[i] = values[i]), and a list // The update operation consists of a list of update expressions (fields[i] = values[i]), and a list
// of where conditions (conds). The function returns 0 if the update is handled in the storage engine. // of where conditions (conds). The function returns 0 if the update is handled in the storage engine.
...@@ -287,6 +302,10 @@ static bool check_simple_update_expression(Item *lhs_item, Item *rhs_item, TABLE ...@@ -287,6 +302,10 @@ static bool check_simple_update_expression(Item *lhs_item, Item *rhs_item, TABLE
if (rhs_type == Item::INT_ITEM || rhs_type == Item::STRING_ITEM) if (rhs_type == Item::INT_ITEM || rhs_type == Item::STRING_ITEM)
return true; return true;
break; break;
case MYSQL_TYPE_VARCHAR:
if (rhs_type == Item::STRING_ITEM)
return true;
break;
default: default:
break; break;
} }
...@@ -427,7 +446,7 @@ static bool is_strict_mode(THD *thd) { ...@@ -427,7 +446,7 @@ static bool is_strict_mode(THD *thd) {
// Check if an update operation can be handled by this storage engine. Return true if it can. // Check if an update operation can be handled by this storage engine. Return true if it can.
bool ha_tokudb::check_fast_update(THD *thd, List<Item> &fields, List<Item> &values, Item *conds) { bool ha_tokudb::check_fast_update(THD *thd, List<Item> &fields, List<Item> &values, Item *conds) {
// fast upserts disabled // fast updates disabled
if (!get_enable_fast_update(thd)) if (!get_enable_fast_update(thd))
return false; return false;
...@@ -450,10 +469,6 @@ bool ha_tokudb::check_fast_update(THD *thd, List<Item> &fields, List<Item> &valu ...@@ -450,10 +469,6 @@ bool ha_tokudb::check_fast_update(THD *thd, List<Item> &fields, List<Item> &valu
if (clustering_keys_exist(table)) if (clustering_keys_exist(table))
return false; return false;
// fast updates enabled with session variable
if (!get_enable_fast_update(thd))
return false;
if (!check_all_update_expressions(fields, values, table)) if (!check_all_update_expressions(fields, values, table))
return false; return false;
...@@ -465,11 +480,11 @@ bool ha_tokudb::check_fast_update(THD *thd, List<Item> &fields, List<Item> &valu ...@@ -465,11 +480,11 @@ bool ha_tokudb::check_fast_update(THD *thd, List<Item> &fields, List<Item> &valu
// Marshall a simple row descriptor to a buffer. // Marshall a simple row descriptor to a buffer.
static void marshall_simple_descriptor(tokudb::buffer &b, TABLE *table, KEY_AND_COL_INFO &kc_info, uint key_num) { static void marshall_simple_descriptor(tokudb::buffer &b, TABLE *table, KEY_AND_COL_INFO &kc_info, uint key_num) {
Simple_row_descriptor sd; tokudb::simple_row_descriptor sd;
sd.m_fixed_field_offset = table->s->null_bytes; sd.m_fixed_field_offset = table->s->null_bytes;
sd.m_var_field_offset = sd.m_fixed_field_offset + kc_info.mcp_info[key_num].fixed_field_size; sd.m_var_field_offset = sd.m_fixed_field_offset + kc_info.mcp_info[key_num].fixed_field_size;
sd.m_var_offset_bytes = kc_info.mcp_info[key_num].len_of_offsets; sd.m_var_offset_bytes = kc_info.mcp_info[key_num].len_of_offsets; // total length of the var offsets
sd.m_num_var_fields = sd.m_var_offset_bytes == 0 ? 0 : kc_info.mcp_info[key_num].len_of_offsets / sd.m_var_offset_bytes; sd.m_bytes_per_offset = sd.m_var_offset_bytes == 0 ? 0 : kc_info.num_offset_bytes; // bytes per var offset
sd.append(b); sd.append(b);
} }
...@@ -483,11 +498,12 @@ static void marshall_simple_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_ ...@@ -483,11 +498,12 @@ static void marshall_simple_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_
// compute the update info // compute the update info
uint32_t field_type; uint32_t field_type;
uint32_t field_num = lhs_field->field_index;
uint32_t field_null_num = 0; uint32_t field_null_num = 0;
if (lhs_field->real_maybe_null()) if (lhs_field->real_maybe_null()) {
uint32_t field_num = lhs_field->field_index;
field_null_num = (1<<31) + (field_num/8)*8 + get_null_bit_position(lhs_field->null_bit); field_null_num = (1<<31) + (field_num/8)*8 + get_null_bit_position(lhs_field->null_bit);
uint32_t offset = update_field_offset(table->s->null_bytes, &share->kc_info, table->s->primary_key, lhs_field->field_index); }
uint32_t offset;
void *v_ptr = NULL; void *v_ptr = NULL;
uint32_t v_length; uint32_t v_length;
uint32_t update_operation; uint32_t update_operation;
...@@ -502,6 +518,7 @@ static void marshall_simple_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_ ...@@ -502,6 +518,7 @@ static void marshall_simple_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_
case MYSQL_TYPE_LONGLONG: { case MYSQL_TYPE_LONGLONG: {
Field_num *lhs_num = static_cast<Field_num*>(lhs_field); Field_num *lhs_num = static_cast<Field_num*>(lhs_field);
field_type = lhs_num->unsigned_flag ? UPDATE_TYPE_UINT : UPDATE_TYPE_INT; field_type = lhs_num->unsigned_flag ? UPDATE_TYPE_UINT : UPDATE_TYPE_INT;
offset = fixed_field_offset(table->s->null_bytes, &share->kc_info, table->s->primary_key, lhs_field->field_index);
switch (rhs_item->type()) { switch (rhs_item->type()) {
case Item::INT_ITEM: { case Item::INT_ITEM: {
update_operation = '='; update_operation = '=';
...@@ -535,7 +552,8 @@ static void marshall_simple_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_ ...@@ -535,7 +552,8 @@ static void marshall_simple_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_
case MYSQL_TYPE_STRING: { case MYSQL_TYPE_STRING: {
update_operation = '='; update_operation = '=';
field_type = lhs_field->binary() ? UPDATE_TYPE_BINARY : UPDATE_TYPE_CHAR; field_type = lhs_field->binary() ? UPDATE_TYPE_BINARY : UPDATE_TYPE_CHAR;
offset = fixed_field_offset(table->s->null_bytes, &share->kc_info, table->s->primary_key, lhs_field->field_index);
v_str = *rhs_item->val_str(&v_str); v_str = *rhs_item->val_str(&v_str);
v_length = v_str.length(); v_length = v_str.length();
if (v_length >= lhs_field->pack_length()) { if (v_length >= lhs_field->pack_length()) {
...@@ -549,6 +567,20 @@ static void marshall_simple_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_ ...@@ -549,6 +567,20 @@ static void marshall_simple_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_
v_ptr = v_str.c_ptr(); v_ptr = v_str.c_ptr();
break; break;
} }
case MYSQL_TYPE_VARCHAR: {
update_operation = '=';
field_type = lhs_field->binary() ? UPDATE_TYPE_VARBINARY : UPDATE_TYPE_VARCHAR;
offset = var_field_index(table, &share->kc_info, table->s->primary_key, lhs_field->field_index);
v_str = *rhs_item->val_str(&v_str);
v_length = v_str.length();
if (v_length >= lhs_field->row_pack_length()) {
v_length = lhs_field->row_pack_length();
v_str.length(v_length); // truncate
}
v_ptr = v_str.c_ptr();
break;
}
default: default:
assert(0); assert(0);
} }
...@@ -556,7 +588,8 @@ static void marshall_simple_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_ ...@@ -556,7 +588,8 @@ static void marshall_simple_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_
// marshall the update fields into the buffer // marshall the update fields into the buffer
b.append(&update_operation, sizeof update_operation); b.append(&update_operation, sizeof update_operation);
b.append(&field_type, sizeof field_type); b.append(&field_type, sizeof field_type);
b.append(&field_num, sizeof field_num); uint32_t unused = 0;
b.append(&unused, sizeof unused);
b.append(&field_null_num, sizeof field_null_num); b.append(&field_null_num, sizeof field_null_num);
b.append(&offset, sizeof offset); b.append(&offset, sizeof offset);
b.append(&v_length, sizeof v_length); b.append(&v_length, sizeof v_length);
......
This diff is collapsed.
...@@ -145,7 +145,7 @@ static MYSQL_THDVAR_BOOL(enable_fast_update, ...@@ -145,7 +145,7 @@ static MYSQL_THDVAR_BOOL(enable_fast_update,
"enable fast update", "enable fast update",
NULL, // check NULL, // check
NULL, // update NULL, // update
false // default true // default
); );
static MYSQL_THDVAR_BOOL(disable_slow_update, static MYSQL_THDVAR_BOOL(disable_slow_update,
PLUGIN_VAR_THDLOCAL, PLUGIN_VAR_THDLOCAL,
...@@ -159,7 +159,7 @@ static MYSQL_THDVAR_BOOL(enable_fast_upsert, ...@@ -159,7 +159,7 @@ static MYSQL_THDVAR_BOOL(enable_fast_upsert,
"enable fast upsert", "enable fast upsert",
NULL, // check NULL, // check
NULL, // update NULL, // update
false // default true // default
); );
static MYSQL_THDVAR_BOOL(disable_slow_upsert, static MYSQL_THDVAR_BOOL(disable_slow_upsert,
PLUGIN_VAR_THDLOCAL, PLUGIN_VAR_THDLOCAL,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment