Commit 6aedbf40 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-14494 Move set_param_xxx() in sql_prepare.cc to methods in Item_param and Type_handler

- sql_prepare.cc: Moving functions set_param_xxx() as
  methods to Item_param

- Replacing a pointer to a function Item_param::set_param_func
  to Type_handler based implementation:
  Item_param::value now derives from Type_handler_hybrid_field_type.
  Adding new virtual methods Type_handler::Item_param_setup_conversion()
  and Type_handler::Item_param_set_param_func()

- Moving declaration of some Item_param members  from "public:" to "private:"
  (CONVERSION_INFO, value, decimal_value)

- Adding a new method Item_param::set_limit_clause_param(),
  to share duplicate code, as well as to encapsulate
  Item_param::value.

- Adding Item_param::setup_conversion_string() and
  Item_param::setup_conversion_blob() to share
  the code for binding from a client value
  (mysql_stmt_bind_param), and for binding from
  an expression (Item).

- Removing two different functions set_param_str_or_null()
  and set_param_str(). Adding a common method Item_param::set_param_str().
  Item_param::m_empty_string_is_null, used by Item_param::set_param_str().

- Removing the call for setup_one_conversion_function() from
  insert_params_from_actual_params_with_log(). It's not needed,
  because the call for ps_param->save_in_param() makes sure
  to initialized all data type dependent members properly,
  by calling setup_conversion_string() from
  Type_handler_string_result::Item_param_set_from_value()
  and by calling setup_conversion_blob() from
  Type_handler_blob_common::Item_param_set_from_value()

- Cleanup: removing multiplication to MY_CHARSET_BIN_MB_MAXLEN
  in a few places. It's 1 anyway, and will never change.
parent a18f6009
......@@ -3708,20 +3708,6 @@ Item *Item_null::clone_item(THD *thd)
/*********************** Item_param related ******************************/
/**
Default function of Item_param::set_param_func, so in case
of malformed packet the server won't SIGSEGV.
*/
static void
default_set_param_func(Item_param *param,
uchar **pos __attribute__((unused)),
ulong len __attribute__((unused)))
{
param->set_null();
}
Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg,
uint pos_in_query_arg, uint len_in_query_arg):
Item_basic_value(thd),
......@@ -3739,8 +3725,8 @@ Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg,
state(NO_VALUE),
/* Don't pretend to be a literal unless value for this item is set. */
item_type(PARAM_ITEM),
m_empty_string_is_null(false),
indicator(STMT_INDICATOR_NONE),
set_param_func(default_set_param_func),
m_out_param_info(NULL),
/*
Set m_is_settable_routine_parameter to "true" by default.
......@@ -4025,9 +4011,8 @@ bool Item_param::set_from_item(THD *thd, Item *item)
else
{
unsigned_flag= item->unsigned_flag;
set_int(val, MY_INT64_NUM_DECIMAL_DIGITS);
set_handler_by_result_type(item->result_type());
DBUG_RETURN(!unsigned_flag && value.integer < 0 ? 1 : 0);
DBUG_RETURN(set_limit_clause_param(val));
}
}
struct st_value tmp;
......@@ -4535,7 +4520,6 @@ Item_param::set_param_type_and_swap_value(Item_param *src)
{
Type_std_attributes::set(src);
set_handler(src->type_handler());
set_param_func= src->set_param_func;
item_type= src->item_type;
maybe_null= src->maybe_null;
......@@ -4544,6 +4528,7 @@ Item_param::set_param_type_and_swap_value(Item_param *src)
fixed= src->fixed;
value= src->value;
value.set_handler(src->value.type_handler());
decimal_value.swap(src->decimal_value);
str_value.swap(src->str_value);
str_value_ptr.swap(src->str_value_ptr);
......
......@@ -3128,7 +3128,6 @@ class Item_param :public Item_basic_value,
void fix_temporal(uint32 max_length_arg, uint decimals_arg);
public:
struct CONVERSION_INFO
{
/*
......@@ -3170,12 +3169,6 @@ class Item_param :public Item_basic_value,
}
};
/*
Used for bulk protocol only.
*/
enum enum_indicator_type indicator;
private:
/*
A buffer for string and long data values. Historically all allocated
values returned from val_str() were treated as eligible to
......@@ -3188,15 +3181,30 @@ class Item_param :public Item_basic_value,
*/
String str_value_ptr;
public:
my_decimal decimal_value;
union
bool m_empty_string_is_null;
class PValue: public Type_handler_hybrid_field_type
{
longlong integer;
double real;
CONVERSION_INFO cs_info;
MYSQL_TIME time;
} value;
public:
PValue(): Type_handler_hybrid_field_type(&type_handler_null) {}
union
{
longlong integer;
double real;
CONVERSION_INFO cs_info;
MYSQL_TIME time;
};
};
PValue value;
my_decimal decimal_value;
public:
/*
Used for bulk protocol only.
*/
enum enum_indicator_type indicator;
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
......@@ -3237,14 +3245,39 @@ class Item_param :public Item_basic_value,
void set_time(const MYSQL_TIME *tm, uint32 max_length_arg, uint decimals_arg);
bool set_from_item(THD *thd, Item *item);
void reset();
void set_param_tiny(uchar **pos, ulong len);
void set_param_short(uchar **pos, ulong len);
void set_param_int32(uchar **pos, ulong len);
void set_param_int64(uchar **pos, ulong len);
void set_param_float(uchar **pos, ulong len);
void set_param_double(uchar **pos, ulong len);
void set_param_decimal(uchar **pos, ulong len);
void set_param_time(uchar **pos, ulong len);
void set_param_datetime(uchar **pos, ulong len);
void set_param_date(uchar **pos, ulong len);
void set_param_str(uchar **pos, ulong len);
void setup_conversion(THD *thd, uchar param_type);
void setup_conversion_blob(THD *thd);
void setup_conversion_string(THD *thd, CHARSET_INFO *fromcs);
/*
Assign placeholder value from bind data.
Note, that 'len' has different semantics in embedded library (as we
don't need to check that packet is not broken there). See
sql_prepare.cc for details.
*/
void (*set_param_func)(Item_param *param, uchar **pos, ulong len);
void set_param_func(uchar **pos, ulong len)
{
value.type_handler()->Item_param_set_param_func(this, pos, len);
}
bool set_limit_clause_param(longlong nr)
{
set_int(nr, MY_INT64_NUM_DECIMAL_DIGITS);
return !unsigned_flag && value.integer < 0;
}
const String *query_val_str(THD *thd, String *str) const;
bool convert_str_value(THD *thd);
......
This diff is collapsed.
......@@ -5053,7 +5053,7 @@ bool Type_handler_string_result::
const st_value *val) const
{
param->unsigned_flag= false;
param->value.cs_info.set(thd, attr->collation.collation);
param->setup_conversion_string(thd, attr->collation.collation);
/*
Exact value of max_length is not known unless data is converted to
charset of connection, so we have to set it later.
......@@ -5086,7 +5086,7 @@ bool Type_handler_geometry::
const st_value *val) const
{
param->unsigned_flag= false;
param->value.cs_info.set(thd, &my_charset_bin);
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(),
......@@ -5476,3 +5476,139 @@ Item *Type_handler_long_blob::
}
/***************************************************************************/
void Type_handler_string_result::Item_param_setup_conversion(THD *thd,
Item_param *param)
const
{
param->setup_conversion_string(thd, thd->variables.character_set_client);
}
void Type_handler_blob_common::Item_param_setup_conversion(THD *thd,
Item_param *param)
const
{
param->setup_conversion_blob(thd);
}
void Type_handler_tiny::Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const
{
param->set_param_tiny(pos, len);
}
void Type_handler_short::Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const
{
param->set_param_short(pos, len);
}
void Type_handler_long::Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const
{
param->set_param_int32(pos, len);
}
void Type_handler_longlong::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_param_int64(pos, len);
}
void Type_handler_float::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_param_float(pos, len);
}
void Type_handler_double::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_param_double(pos, len);
}
void Type_handler_decimal_result::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_param_decimal(pos, len);
}
void Type_handler_string_result::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_param_str(pos, len);
}
void Type_handler_time_common::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_param_time(pos, len);
}
void Type_handler_date_common::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_param_date(pos, len);
}
void Type_handler_datetime_common::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_param_datetime(pos, len);
}
void Type_handler_timestamp_common::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_param_datetime(pos, len);
}
void Type_handler::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_null(); // Not possible type code in the client-server protocol
}
void Type_handler_typelib::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_null(); // Not possible type code in the client-server protocol
}
#ifdef HAVE_SPATIAL
void Type_handler_geometry::Item_param_set_param_func(Item_param *param,
uchar **pos,
ulong len) const
{
param->set_null(); // Not possible type code in the client-server protocol
}
#endif
/***************************************************************************/
......@@ -805,6 +805,9 @@ class Type_handler
virtual uint32 max_display_length(const Item *item) const= 0;
virtual uint32 calc_pack_length(uint32 length) const= 0;
virtual bool Item_save_in_value(Item *item, st_value *value) const= 0;
virtual void Item_param_setup_conversion(THD *thd, Item_param *) const {}
virtual void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
virtual bool Item_param_set_from_value(THD *thd,
Item_param *param,
const Type_all_attributes *attr,
......@@ -1423,6 +1426,8 @@ class Type_handler_decimal_result: public Type_handler_numeric
const Type_cast_attributes &attr) const;
uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
bool Item_param_set_from_value(THD *thd,
Item_param *param,
const Type_all_attributes *attr,
......@@ -1659,6 +1664,9 @@ class Type_handler_string_result: public Type_handler
}
uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const;
void Item_param_setup_conversion(THD *thd, Item_param *) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
bool Item_param_set_from_value(THD *thd,
Item_param *param,
const Type_all_attributes *attr,
......@@ -1785,6 +1793,8 @@ class Type_handler_tiny: public Type_handler_general_purpose_int
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
......@@ -1812,6 +1822,8 @@ class Type_handler_short: public Type_handler_general_purpose_int
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
......@@ -1842,6 +1854,8 @@ class Type_handler_long: public Type_handler_general_purpose_int
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
......@@ -1873,6 +1887,8 @@ class Type_handler_longlong: public Type_handler_general_purpose_int
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
......@@ -1996,6 +2012,8 @@ class Type_handler_float: public Type_handler_real_result
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
......@@ -2026,6 +2044,8 @@ class Type_handler_double: public Type_handler_real_result
const Record_addr &addr,
const Type_all_attributes &attr,
TABLE *table) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
......@@ -2070,6 +2090,8 @@ class Type_handler_time_common: public Type_handler_temporal_result
bool set_comparator_func(Arg_comparator *cmp) const;
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
......@@ -2153,6 +2175,8 @@ class Type_handler_date_common: public Type_handler_temporal_with_date
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
class Type_handler_date: public Type_handler_date_common
......@@ -2227,6 +2251,8 @@ class Type_handler_datetime_common: public Type_handler_temporal_with_date
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
......@@ -2307,6 +2333,8 @@ class Type_handler_timestamp_common: public Type_handler_temporal_with_date
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
......@@ -2567,6 +2595,7 @@ class Type_handler_blob_common: public Type_handler_longstr
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
Item **items, uint nitems) const;
void Item_param_setup_conversion(THD *thd, Item_param *) const;
};
......@@ -2660,6 +2689,8 @@ class Type_handler_geometry: public Type_handler_string_result
{
return false; // Materialization does not work with GEOMETRY columns
}
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
bool Item_param_set_from_value(THD *thd,
Item_param *param,
const Type_all_attributes *attr,
......@@ -2739,6 +2770,8 @@ class Type_handler_typelib: public Type_handler_general_purpose_string
const handler *file,
const Schema_specification_st *schema)
const;
void Item_param_set_param_func(Item_param *param,
uchar **pos, ulong len) const;
};
......
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