mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-9215 Detect cmp_type() and result_type() from field_type()
Part5: Derive Item_param from Type_handler_hybrid_field_type
This commit is contained in:
22
sql/item.cc
22
sql/item.cc
@@ -2977,13 +2977,12 @@ default_set_param_func(Item_param *param,
|
|||||||
|
|
||||||
|
|
||||||
Item_param::Item_param(THD *thd, uint pos_in_query_arg):
|
Item_param::Item_param(THD *thd, uint pos_in_query_arg):
|
||||||
|
Type_handler_hybrid_field_type(MYSQL_TYPE_VARCHAR),
|
||||||
Item_basic_value(thd),
|
Item_basic_value(thd),
|
||||||
Rewritable_query_parameter(pos_in_query_arg, 1),
|
Rewritable_query_parameter(pos_in_query_arg, 1),
|
||||||
state(NO_VALUE),
|
state(NO_VALUE),
|
||||||
item_result_type(STRING_RESULT),
|
|
||||||
/* Don't pretend to be a literal unless value for this item is set. */
|
/* Don't pretend to be a literal unless value for this item is set. */
|
||||||
item_type(PARAM_ITEM),
|
item_type(PARAM_ITEM),
|
||||||
param_type(MYSQL_TYPE_VARCHAR),
|
|
||||||
set_param_func(default_set_param_func),
|
set_param_func(default_set_param_func),
|
||||||
m_out_param_info(NULL)
|
m_out_param_info(NULL)
|
||||||
{
|
{
|
||||||
@@ -3183,25 +3182,25 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
|
|||||||
DBUG_ENTER("Item_param::set_from_user_var");
|
DBUG_ENTER("Item_param::set_from_user_var");
|
||||||
if (entry && entry->value)
|
if (entry && entry->value)
|
||||||
{
|
{
|
||||||
item_result_type= entry->type;
|
|
||||||
unsigned_flag= entry->unsigned_flag;
|
unsigned_flag= entry->unsigned_flag;
|
||||||
if (limit_clause_param)
|
if (limit_clause_param)
|
||||||
{
|
{
|
||||||
bool unused;
|
bool unused;
|
||||||
set_int(entry->val_int(&unused), MY_INT64_NUM_DECIMAL_DIGITS);
|
set_int(entry->val_int(&unused), MY_INT64_NUM_DECIMAL_DIGITS);
|
||||||
item_type= Item::INT_ITEM;
|
item_type= Item::INT_ITEM;
|
||||||
|
set_handler_by_result_type(entry->type);
|
||||||
DBUG_RETURN(!unsigned_flag && value.integer < 0 ? 1 : 0);
|
DBUG_RETURN(!unsigned_flag && value.integer < 0 ? 1 : 0);
|
||||||
}
|
}
|
||||||
switch (item_result_type) {
|
switch (entry->type) {
|
||||||
case REAL_RESULT:
|
case REAL_RESULT:
|
||||||
set_double(*(double*)entry->value);
|
set_double(*(double*)entry->value);
|
||||||
item_type= Item::REAL_ITEM;
|
item_type= Item::REAL_ITEM;
|
||||||
param_type= MYSQL_TYPE_DOUBLE;
|
set_handler_by_field_type(MYSQL_TYPE_DOUBLE);
|
||||||
break;
|
break;
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
set_int(*(longlong*)entry->value, MY_INT64_NUM_DECIMAL_DIGITS);
|
set_int(*(longlong*)entry->value, MY_INT64_NUM_DECIMAL_DIGITS);
|
||||||
item_type= Item::INT_ITEM;
|
item_type= Item::INT_ITEM;
|
||||||
param_type= MYSQL_TYPE_LONGLONG;
|
set_handler_by_field_type(MYSQL_TYPE_LONGLONG);
|
||||||
break;
|
break;
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
{
|
{
|
||||||
@@ -3224,7 +3223,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
|
|||||||
charset of connection, so we have to set it later.
|
charset of connection, so we have to set it later.
|
||||||
*/
|
*/
|
||||||
item_type= Item::STRING_ITEM;
|
item_type= Item::STRING_ITEM;
|
||||||
param_type= MYSQL_TYPE_VARCHAR;
|
set_handler_by_field_type(MYSQL_TYPE_VARCHAR);
|
||||||
|
|
||||||
if (set_str((const char *)entry->value, entry->length))
|
if (set_str((const char *)entry->value, entry->length))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
@@ -3240,7 +3239,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
|
|||||||
my_decimal_precision_to_length_no_truncation(ent_value->precision(),
|
my_decimal_precision_to_length_no_truncation(ent_value->precision(),
|
||||||
decimals, unsigned_flag);
|
decimals, unsigned_flag);
|
||||||
item_type= Item::DECIMAL_ITEM;
|
item_type= Item::DECIMAL_ITEM;
|
||||||
param_type= MYSQL_TYPE_NEWDECIMAL;
|
set_handler_by_field_type(MYSQL_TYPE_NEWDECIMAL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
@@ -3665,10 +3664,9 @@ void
|
|||||||
Item_param::set_param_type_and_swap_value(Item_param *src)
|
Item_param::set_param_type_and_swap_value(Item_param *src)
|
||||||
{
|
{
|
||||||
Type_std_attributes::set(src);
|
Type_std_attributes::set(src);
|
||||||
param_type= src->param_type;
|
set_handler(src->type_handler());
|
||||||
set_param_func= src->set_param_func;
|
set_param_func= src->set_param_func;
|
||||||
item_type= src->item_type;
|
item_type= src->item_type;
|
||||||
item_result_type= src->item_result_type;
|
|
||||||
|
|
||||||
maybe_null= src->maybe_null;
|
maybe_null= src->maybe_null;
|
||||||
null_value= src->null_value;
|
null_value= src->null_value;
|
||||||
@@ -3756,7 +3754,7 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
item_result_type= arg->result_type();
|
set_handler_by_result_type(arg->result_type());
|
||||||
item_type= arg->type();
|
item_type= arg->type();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -3775,7 +3773,7 @@ void
|
|||||||
Item_param::set_out_param_info(Send_field *info)
|
Item_param::set_out_param_info(Send_field *info)
|
||||||
{
|
{
|
||||||
m_out_param_info= info;
|
m_out_param_info= info;
|
||||||
param_type= m_out_param_info->type;
|
set_handler_by_field_type(m_out_param_info->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
34
sql/item.h
34
sql/item.h
@@ -2594,11 +2594,22 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Item represents one placeholder ('?') of prepared statement */
|
/*
|
||||||
|
Item represents one placeholder ('?') of prepared statement
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Item_param::field_type() is used when this item is in a temporary table.
|
||||||
|
This is NOT placeholder metadata sent to client, as this value
|
||||||
|
is assigned after sending metadata (in setup_one_conversion_function).
|
||||||
|
For example in case of 'SELECT ?' you'll get MYSQL_TYPE_STRING both
|
||||||
|
in result set and placeholders metadata, no matter what type you will
|
||||||
|
supply for this placeholder in mysql_stmt_execute.
|
||||||
|
*/
|
||||||
|
|
||||||
class Item_param :public Item_basic_value,
|
class Item_param :public Item_basic_value,
|
||||||
private Settable_routine_parameter,
|
private Settable_routine_parameter,
|
||||||
public Rewritable_query_parameter
|
public Rewritable_query_parameter,
|
||||||
|
public Type_handler_hybrid_field_type
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum enum_item_param_state
|
enum enum_item_param_state
|
||||||
@@ -2645,25 +2656,18 @@ public:
|
|||||||
MYSQL_TIME time;
|
MYSQL_TIME time;
|
||||||
} value;
|
} value;
|
||||||
|
|
||||||
/* Cached values for virtual methods to save us one switch. */
|
|
||||||
enum Item_result item_result_type;
|
|
||||||
enum Type item_type;
|
enum Type item_type;
|
||||||
|
|
||||||
/*
|
enum_field_types field_type() const
|
||||||
Used when this item is used in a temporary table.
|
{ return Type_handler_hybrid_field_type::field_type(); }
|
||||||
This is NOT placeholder metadata sent to client, as this value
|
enum Item_result result_type () const
|
||||||
is assigned after sending metadata (in setup_one_conversion_function).
|
{ return Type_handler_hybrid_field_type::result_type(); }
|
||||||
For example in case of 'SELECT ?' you'll get MYSQL_TYPE_STRING both
|
enum Item_result cmp_type () const
|
||||||
in result set and placeholders metadata, no matter what type you will
|
{ return Type_handler_hybrid_field_type::cmp_type(); }
|
||||||
supply for this placeholder in mysql_stmt_execute.
|
|
||||||
*/
|
|
||||||
enum enum_field_types param_type;
|
|
||||||
|
|
||||||
Item_param(THD *thd, uint pos_in_query_arg);
|
Item_param(THD *thd, uint pos_in_query_arg);
|
||||||
|
|
||||||
enum Item_result result_type () const { return item_result_type; }
|
|
||||||
enum Type type() const { return item_type; }
|
enum Type type() const { return item_type; }
|
||||||
enum_field_types field_type() const { return param_type; }
|
|
||||||
|
|
||||||
double val_real();
|
double val_real();
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
|
@@ -718,54 +718,44 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
|
|||||||
case MYSQL_TYPE_TINY:
|
case MYSQL_TYPE_TINY:
|
||||||
param->set_param_func= set_param_tiny;
|
param->set_param_func= set_param_tiny;
|
||||||
param->item_type= Item::INT_ITEM;
|
param->item_type= Item::INT_ITEM;
|
||||||
param->item_result_type= INT_RESULT;
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_SHORT:
|
case MYSQL_TYPE_SHORT:
|
||||||
param->set_param_func= set_param_short;
|
param->set_param_func= set_param_short;
|
||||||
param->item_type= Item::INT_ITEM;
|
param->item_type= Item::INT_ITEM;
|
||||||
param->item_result_type= INT_RESULT;
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_LONG:
|
case MYSQL_TYPE_LONG:
|
||||||
param->set_param_func= set_param_int32;
|
param->set_param_func= set_param_int32;
|
||||||
param->item_type= Item::INT_ITEM;
|
param->item_type= Item::INT_ITEM;
|
||||||
param->item_result_type= INT_RESULT;
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_LONGLONG:
|
case MYSQL_TYPE_LONGLONG:
|
||||||
param->set_param_func= set_param_int64;
|
param->set_param_func= set_param_int64;
|
||||||
param->item_type= Item::INT_ITEM;
|
param->item_type= Item::INT_ITEM;
|
||||||
param->item_result_type= INT_RESULT;
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_FLOAT:
|
case MYSQL_TYPE_FLOAT:
|
||||||
param->set_param_func= set_param_float;
|
param->set_param_func= set_param_float;
|
||||||
param->item_type= Item::REAL_ITEM;
|
param->item_type= Item::REAL_ITEM;
|
||||||
param->item_result_type= REAL_RESULT;
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_DOUBLE:
|
case MYSQL_TYPE_DOUBLE:
|
||||||
param->set_param_func= set_param_double;
|
param->set_param_func= set_param_double;
|
||||||
param->item_type= Item::REAL_ITEM;
|
param->item_type= Item::REAL_ITEM;
|
||||||
param->item_result_type= REAL_RESULT;
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_DECIMAL:
|
case MYSQL_TYPE_DECIMAL:
|
||||||
case MYSQL_TYPE_NEWDECIMAL:
|
case MYSQL_TYPE_NEWDECIMAL:
|
||||||
param->set_param_func= set_param_decimal;
|
param->set_param_func= set_param_decimal;
|
||||||
param->item_type= Item::DECIMAL_ITEM;
|
param->item_type= Item::DECIMAL_ITEM;
|
||||||
param->item_result_type= DECIMAL_RESULT;
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_TIME:
|
case MYSQL_TYPE_TIME:
|
||||||
param->set_param_func= set_param_time;
|
param->set_param_func= set_param_time;
|
||||||
param->item_type= Item::STRING_ITEM;
|
param->item_type= Item::STRING_ITEM;
|
||||||
param->item_result_type= STRING_RESULT;
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_DATE:
|
case MYSQL_TYPE_DATE:
|
||||||
param->set_param_func= set_param_date;
|
param->set_param_func= set_param_date;
|
||||||
param->item_type= Item::STRING_ITEM;
|
param->item_type= Item::STRING_ITEM;
|
||||||
param->item_result_type= STRING_RESULT;
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_DATETIME:
|
case MYSQL_TYPE_DATETIME:
|
||||||
case MYSQL_TYPE_TIMESTAMP:
|
case MYSQL_TYPE_TIMESTAMP:
|
||||||
param->set_param_func= set_param_datetime;
|
param->set_param_func= set_param_datetime;
|
||||||
param->item_type= Item::STRING_ITEM;
|
param->item_type= Item::STRING_ITEM;
|
||||||
param->item_result_type= STRING_RESULT;
|
|
||||||
break;
|
break;
|
||||||
case MYSQL_TYPE_TINY_BLOB:
|
case MYSQL_TYPE_TINY_BLOB:
|
||||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||||
@@ -778,7 +768,6 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
|
|||||||
DBUG_ASSERT(thd->variables.character_set_client);
|
DBUG_ASSERT(thd->variables.character_set_client);
|
||||||
param->value.cs_info.final_character_set_of_str_value= &my_charset_bin;
|
param->value.cs_info.final_character_set_of_str_value= &my_charset_bin;
|
||||||
param->item_type= Item::STRING_ITEM;
|
param->item_type= Item::STRING_ITEM;
|
||||||
param->item_result_type= STRING_RESULT;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
@@ -808,10 +797,9 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
|
|||||||
charset of connection, so we have to set it later.
|
charset of connection, so we have to set it later.
|
||||||
*/
|
*/
|
||||||
param->item_type= Item::STRING_ITEM;
|
param->item_type= Item::STRING_ITEM;
|
||||||
param->item_result_type= STRING_RESULT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
param->param_type= (enum enum_field_types) param_type;
|
param->set_handler_by_field_type((enum enum_field_types) param_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
@@ -823,8 +811,8 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
|
|||||||
*/
|
*/
|
||||||
inline bool is_param_long_data_type(Item_param *param)
|
inline bool is_param_long_data_type(Item_param *param)
|
||||||
{
|
{
|
||||||
return ((param->param_type >= MYSQL_TYPE_TINY_BLOB) &&
|
return ((param->field_type() >= MYSQL_TYPE_TINY_BLOB) &&
|
||||||
(param->param_type <= MYSQL_TYPE_STRING));
|
(param->field_type() <= MYSQL_TYPE_STRING));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1213,7 +1201,7 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
|
|||||||
the parameter's members that might be needed further
|
the parameter's members that might be needed further
|
||||||
(e.g. value.cs_info.character_set_client is used in the query_val_str()).
|
(e.g. value.cs_info.character_set_client is used in the query_val_str()).
|
||||||
*/
|
*/
|
||||||
setup_one_conversion_function(thd, param, param->param_type);
|
setup_one_conversion_function(thd, param, param->field_type());
|
||||||
if (param->set_from_user_var(thd, entry))
|
if (param->set_from_user_var(thd, entry))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
|
@@ -318,6 +318,10 @@ public:
|
|||||||
enum_field_types field_type() const { return m_type_handler->field_type(); }
|
enum_field_types field_type() const { return m_type_handler->field_type(); }
|
||||||
Item_result result_type() const { return m_type_handler->result_type(); }
|
Item_result result_type() const { return m_type_handler->result_type(); }
|
||||||
Item_result cmp_type() const { return m_type_handler->cmp_type(); }
|
Item_result cmp_type() const { return m_type_handler->cmp_type(); }
|
||||||
|
void set_handler(const Type_handler *other)
|
||||||
|
{
|
||||||
|
m_type_handler= other;
|
||||||
|
}
|
||||||
const Type_handler *set_handler_by_result_type(Item_result type)
|
const Type_handler *set_handler_by_result_type(Item_result type)
|
||||||
{
|
{
|
||||||
return (m_type_handler= get_handler_by_result_type(type));
|
return (m_type_handler= get_handler_by_result_type(type));
|
||||||
|
Reference in New Issue
Block a user