diff options
author | unknown <sanja@montyprogram.com> | 2014-02-26 15:46:13 +0200 |
---|---|---|
committer | unknown <sanja@montyprogram.com> | 2014-02-26 15:46:13 +0200 |
commit | 982607508d865d02ddd87af4aaf7c301c47cbc7e (patch) | |
tree | a0caf1674339b234a1c72cc5fdc4c3aedbe485a2 /sql/field_conv.cc | |
parent | 9d918f41d3910ed79bb71fd5405206b3a34c2a4b (diff) | |
download | mariadb-git-982607508d865d02ddd87af4aaf7c301c47cbc7e.tar.gz |
MDEV-4309: DBT-3 Q1 benchmark: Benchmark + profile a patch
Removed repetative calls of virtual functions.
Removed check of posibility just copy field for every record.
Diffstat (limited to 'sql/field_conv.cc')
-rw-r--r-- | sql/field_conv.cc | 111 |
1 files changed, 74 insertions, 37 deletions
diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 97c82b9b7bf..f13694e2a13 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -823,40 +823,76 @@ Copy_field::get_copy_func(Field *to,Field *from) return do_field_eq; } +/** + Check if it is possible just copy value of the fields + + @param to The field to copy to + @param from The field to copy from + + @retval TRUE - it is possible to just copy value of 'from' to 'to'. + @retval FALSE - conversion is needed +*/ + +bool memcpy_field_possible(Field *to,Field *from) +{ + const enum_field_types to_real_type= to->real_type(); + const enum_field_types from_real_type= from->real_type(); + const enum_field_types to_type= from->type(); + return (to_real_type == from_real_type && + !(to->flags & BLOB_FLAG && to->table->copy_blobs) && + to->pack_length() == from->pack_length() && + !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && + to->decimals() == from->decimals() && + to_real_type != MYSQL_TYPE_ENUM && + to_real_type != MYSQL_TYPE_SET && + to_real_type != MYSQL_TYPE_BIT && + (to_real_type != MYSQL_TYPE_NEWDECIMAL || + to->field_length == from->field_length) && + from->charset() == to->charset() && + (!sql_mode_for_dates(to->table->in_use) || + (to_type != MYSQL_TYPE_DATE && + to_type != MYSQL_TYPE_DATETIME)) && + (from_real_type != MYSQL_TYPE_VARCHAR || + ((Field_varstring*)from)->length_bytes == + ((Field_varstring*)to)->length_bytes)); +} + /** Simple quick field convert that is called on insert. */ int field_conv(Field *to,Field *from) { - if (to->real_type() == from->real_type() && - !(to->flags & BLOB_FLAG && to->table->copy_blobs)) - { - if (to->pack_length() == from->pack_length() && - !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && - to->decimals() == from->decimals() && - to->real_type() != MYSQL_TYPE_ENUM && - to->real_type() != MYSQL_TYPE_SET && - to->real_type() != MYSQL_TYPE_BIT && - (to->real_type() != MYSQL_TYPE_NEWDECIMAL || - to->field_length == from->field_length) && - from->charset() == to->charset() && - (!sql_mode_for_dates(to->table->in_use) || - (to->type() != MYSQL_TYPE_DATE && - to->type() != MYSQL_TYPE_DATETIME)) && - (from->real_type() != MYSQL_TYPE_VARCHAR || - ((Field_varstring*)from)->length_bytes == - ((Field_varstring*)to)->length_bytes)) - { // Identical fields - /* - This may happen if one does 'UPDATE ... SET x=x' - The test is here mostly for valgrind, but can also be relevant - if memcpy() is implemented with prefetch-write - */ - if (to->ptr != from->ptr) - memcpy(to->ptr,from->ptr,to->pack_length()); - return 0; - } + if (memcpy_field_possible(to, from)) + { // Identical fields + /* + This may happen if one does 'UPDATE ... SET x=x' + The test is here mostly for valgrind, but can also be relevant + if memcpy() is implemented with prefetch-write + */ + if (to->ptr != from->ptr) + memcpy(to->ptr, from->ptr, to->pack_length()); + return 0; } + return field_conv_incompatible(to, from); +} + + +/** + Copy value of the field with conversion. + + @note Impossibility of simple copy should be checked before this call. + + @param to The field to copy to + @param from The field to copy from + + @retval TRUE ERROR + @retval FALSE OK +*/ + +int field_conv_incompatible(Field *to, Field *from) +{ + const enum_field_types to_real_type= to->real_type(); + const enum_field_types from_real_type= from->real_type(); if (to->flags & BLOB_FLAG) { // Be sure the value is stored Field_blob *blob=(Field_blob*) to; @@ -867,21 +903,22 @@ int field_conv(Field *to,Field *from) */ if (to->table->copy_blobs || (!blob->value.is_alloced() && - from->real_type() != MYSQL_TYPE_STRING && - from->real_type() != MYSQL_TYPE_VARCHAR)) + from_real_type != MYSQL_TYPE_STRING && + from_real_type != MYSQL_TYPE_VARCHAR)) blob->value.copy(); return blob->store(blob->value.ptr(),blob->value.length(),from->charset()); } - if (from->real_type() == MYSQL_TYPE_ENUM && - to->real_type() == MYSQL_TYPE_ENUM && + if (from_real_type == MYSQL_TYPE_ENUM && + to_real_type == MYSQL_TYPE_ENUM && from->val_int() == 0) { ((Field_enum *)(to))->store_type(0); return 0; } - if (from->result_type() == REAL_RESULT) + Item_result from_result_type= from->result_type(); + if (from_result_type == REAL_RESULT) return to->store(from->val_real()); - if (from->result_type() == DECIMAL_RESULT) + if (from_result_type == DECIMAL_RESULT) { my_decimal buff; return to->store_decimal(from->val_decimal(&buff)); @@ -894,10 +931,10 @@ int field_conv(Field *to,Field *from) else return to->store_time_dec(<ime, from->decimals()); } - if ((from->result_type() == STRING_RESULT && + if ((from_result_type == STRING_RESULT && (to->result_type() == STRING_RESULT || - (from->real_type() != MYSQL_TYPE_ENUM && - from->real_type() != MYSQL_TYPE_SET))) || + (from_real_type != MYSQL_TYPE_ENUM && + from_real_type != MYSQL_TYPE_SET))) || to->type() == MYSQL_TYPE_DECIMAL) { char buff[MAX_FIELD_WIDTH]; |