1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-14467 Item_param: replace {INT|DECIMAL|REAL|STRING|TIME}_VALUE with Type_handler

1. Removing data type specific constants from enum_item_param_state,
   adding SHORT_DATA_VALUE instead.
2. Replacing tests for Item_param::state for the removed constants to
   tests for Type_handler::cmp_type() against {INT|REAL|TIME|DECIAML}_RESULT.
   Deriving Item_param::PValue from Type_handler_hybrid_field_type,
   to store the data type handler of the current value of the parameter.

3. Moving Item_param::decimal_value and Item_param::str_value_ptr
   to Item_param::PValue. Adding Item_param::PValue::m_string
   and changing Item_param to use it to store string values,
   instead of Item::str_value. The intent is to replace Item_param::value
   to a st_value based implementation in the future, to avoid duplicate code.
   Adding a sub-class Item::PValue_simple, to implement
   Item_param::PValue::swap() easier.
   Remaming Item_basic_value::fix_charset_and_length_from_str_value()
   to fix_charset_and_length() and adding the "CHARSET_INFO" pointer
   parameter, instead of getting it directly from item->str_value.charset().
   Changing Item_param to pass value.m_string.charset() instead
   of str_value.charset().
   Adding a String argument to the overloaded
   fix_charset_and_length_from_str_value() and changing Item_param
   to pass value.m_string instead of str_value.

4. Replacing the case in Item_param::save_in_field() to a call
   for Type_handler::Item_save_in_field().

5. Adding new methods into Item_param::PValue:
   val_real(), val_int(), val_decimal(), val_str().
   Changing the corresponding Item_param methods
   to use these new Item_param::PValue methods
   internally. Adding a helper method
   Item_param::can_return_value() and removing
   duplicate code in Item_param::val_xxx().

6. Removing value.set_handler() from Item_param::set_conversion()
   and Type_handler_xxx::Item_param_set_from_value().
   It's now done inside Item_param::set_param_func(),
   Item_param::set_value() and Item_param::set_limit_clause_param().

7. Changing Type_handler_int_result::Item_param_set_from_value()
   to set max_length using attr->max_length instead of
   MY_INT64_NUM_DECIMAL_DIGITS, to preserve the data type
   of the assigned expression more precisely.

8. Adding Type_handler_hybrid_field_type::swap(),
   using it in Item_param::PValue::swap().

9. Moving the data-type specific code from
   Item_param::query_val_str(), Item_param::eq(),
   Item_param::clone_item() to
   Item_param::value_query_type_str(),
   Item_param::value_eq(), Item_param::value_clone_item(),
   to split the "state" dependent code and
   the data type dependent code.
   Later we'll split the data type related code further
   and add new methods in Type_handler. This will be done
   after we replace Item_param::PValue to st_value.

10. Adding asserts into set_int(), set_double(), set_decimal(),
   set_time(), set_str(), set_longdata() to make sure that
   the value set to Item_param corresponds to the previously
   set data type handler.

11. Adding tests into t/ps.test and suite/binlog/t/binlog_stm_ps.test,
   to cover Item_param::print() and Item_param::append_for_log()
   for LIMIT clause parameters.
   Note, the patch does not change the behavior covered by the new
   tests. Adding for better code coverage.

12. Adding tests for more precise integer data type in queries like this:
    EXECUTE IMMEDIATE
     'CREATE OR REPLACE TABLE t1 AS SELECT 999999999 AS a,? AS b'
      USING 999999999;
    The explicit integer literal and the same integer literal
    passed as a PS parameter now produce columns of the same data type.
    Re-recording old results in ps.result, gis.result, func_hybrid_type.result
    accordingly.
This commit is contained in:
Alexander Barkov
2017-11-29 10:03:51 +04:00
parent 590400f743
commit e01d33d773
11 changed files with 497 additions and 245 deletions

View File

@ -5015,7 +5015,6 @@ bool Type_handler_real_result::
{
param->unsigned_flag= attr->unsigned_flag;
param->set_double(val->value.m_double);
param->set_handler(&type_handler_double);
return false;
}
@ -5027,8 +5026,7 @@ bool Type_handler_int_result::
const st_value *val) const
{
param->unsigned_flag= attr->unsigned_flag;
param->set_int(val->value.m_longlong, MY_INT64_NUM_DECIMAL_DIGITS);
param->set_handler(&type_handler_longlong);
param->set_int(val->value.m_longlong, attr->max_length);
return false;
}
@ -5041,7 +5039,6 @@ bool Type_handler_decimal_result::
{
param->unsigned_flag= attr->unsigned_flag;
param->set_decimal(&val->m_decimal, attr->unsigned_flag);
param->set_handler(&type_handler_newdecimal);
return false;
}
@ -5058,7 +5055,6 @@ bool Type_handler_string_result::
Exact value of max_length is not known unless data is converted to
charset of connection, so we have to set it later.
*/
param->set_handler(&type_handler_varchar);
return param->set_str(val->m_string.ptr(), val->m_string.length(),
attr->collation.collation,
attr->collation.collation);
@ -5073,7 +5069,6 @@ bool Type_handler_temporal_result::
{
param->unsigned_flag= attr->unsigned_flag;
param->set_time(&val->value.m_time, attr->max_length, attr->decimals);
param->set_handler(this);
return false;
}
@ -5087,7 +5082,6 @@ bool Type_handler_geometry::
{
param->unsigned_flag= false;
param->setup_conversion_blob(thd);
param->set_handler(&type_handler_geometry);
param->set_geometry_type(attr->uint_geometry_type());
return param->set_str(val->m_string.ptr(), val->m_string.length(),
&my_charset_bin, &my_charset_bin);