mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
21
sql/item.cc
21
sql/item.cc
@ -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);
|
||||
|
65
sql/item.h
65
sql/item.h
@ -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 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
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 @@ private:
|
||||
*/
|
||||
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 @@ public:
|
||||
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);
|
||||
|
@ -489,24 +489,23 @@ static ulong get_param_length(uchar **packet, ulong len)
|
||||
(i.e. when input types altered) and for all subsequent executions
|
||||
we don't read any values for this.
|
||||
|
||||
@param param parameter item
|
||||
@param pos input data buffer
|
||||
@param len length of data in the buffer
|
||||
*/
|
||||
|
||||
static void set_param_tiny(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_tiny(uchar **pos, ulong len)
|
||||
{
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (len < 1)
|
||||
return;
|
||||
#endif
|
||||
int8 value= (int8) **pos;
|
||||
param->set_int(param->unsigned_flag ? (longlong) ((uint8) value) :
|
||||
(longlong) value, 4);
|
||||
set_int(unsigned_flag ? (longlong) ((uint8) value) :
|
||||
(longlong) value, 4);
|
||||
*pos+= 1;
|
||||
}
|
||||
|
||||
static void set_param_short(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_short(uchar **pos, ulong len)
|
||||
{
|
||||
int16 value;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@ -516,12 +515,12 @@ static void set_param_short(Item_param *param, uchar **pos, ulong len)
|
||||
#else
|
||||
shortget(value, *pos);
|
||||
#endif
|
||||
param->set_int(param->unsigned_flag ? (longlong) ((uint16) value) :
|
||||
(longlong) value, 6);
|
||||
set_int(unsigned_flag ? (longlong) ((uint16) value) :
|
||||
(longlong) value, 6);
|
||||
*pos+= 2;
|
||||
}
|
||||
|
||||
static void set_param_int32(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_int32(uchar **pos, ulong len)
|
||||
{
|
||||
int32 value;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@ -531,12 +530,12 @@ static void set_param_int32(Item_param *param, uchar **pos, ulong len)
|
||||
#else
|
||||
longget(value, *pos);
|
||||
#endif
|
||||
param->set_int(param->unsigned_flag ? (longlong) ((uint32) value) :
|
||||
(longlong) value, 11);
|
||||
set_int(unsigned_flag ? (longlong) ((uint32) value) :
|
||||
(longlong) value, 11);
|
||||
*pos+= 4;
|
||||
}
|
||||
|
||||
static void set_param_int64(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_int64(uchar **pos, ulong len)
|
||||
{
|
||||
longlong value;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@ -546,11 +545,11 @@ static void set_param_int64(Item_param *param, uchar **pos, ulong len)
|
||||
#else
|
||||
longlongget(value, *pos);
|
||||
#endif
|
||||
param->set_int(value, 21);
|
||||
set_int(value, 21);
|
||||
*pos+= 8;
|
||||
}
|
||||
|
||||
static void set_param_float(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_float(uchar **pos, ulong len)
|
||||
{
|
||||
float data;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@ -560,11 +559,11 @@ static void set_param_float(Item_param *param, uchar **pos, ulong len)
|
||||
#else
|
||||
floatget(data, *pos);
|
||||
#endif
|
||||
param->set_double((double) data);
|
||||
set_double((double) data);
|
||||
*pos+= 4;
|
||||
}
|
||||
|
||||
static void set_param_double(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_double(uchar **pos, ulong len)
|
||||
{
|
||||
double data;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@ -574,14 +573,14 @@ static void set_param_double(Item_param *param, uchar **pos, ulong len)
|
||||
#else
|
||||
doubleget(data, *pos);
|
||||
#endif
|
||||
param->set_double((double) data);
|
||||
set_double((double) data);
|
||||
*pos+= 8;
|
||||
}
|
||||
|
||||
static void set_param_decimal(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_decimal(uchar **pos, ulong len)
|
||||
{
|
||||
ulong length= get_param_length(pos, len);
|
||||
param->set_decimal((char*)*pos, length);
|
||||
set_decimal((char*)*pos, length);
|
||||
*pos+= length;
|
||||
}
|
||||
|
||||
@ -597,7 +596,7 @@ static void set_param_decimal(Item_param *param, uchar **pos, ulong len)
|
||||
@todo
|
||||
Add warning 'Data truncated' here
|
||||
*/
|
||||
static void set_param_time(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_time(uchar **pos, ulong len)
|
||||
{
|
||||
MYSQL_TIME tm;
|
||||
ulong length= get_param_length(pos, len);
|
||||
@ -624,11 +623,11 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len)
|
||||
}
|
||||
else
|
||||
set_zero_time(&tm, MYSQL_TIMESTAMP_TIME);
|
||||
param->set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_FULL_WIDTH);
|
||||
set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_FULL_WIDTH);
|
||||
*pos+= length;
|
||||
}
|
||||
|
||||
static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_datetime(uchar **pos, ulong len)
|
||||
{
|
||||
MYSQL_TIME tm;
|
||||
ulong length= get_param_length(pos, len);
|
||||
@ -654,13 +653,12 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len)
|
||||
}
|
||||
else
|
||||
set_zero_time(&tm, MYSQL_TIMESTAMP_DATETIME);
|
||||
param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
|
||||
MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
|
||||
set_time(&tm, MYSQL_TIMESTAMP_DATETIME, MAX_DATETIME_WIDTH);
|
||||
*pos+= length;
|
||||
}
|
||||
|
||||
|
||||
static void set_param_date(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_date(uchar **pos, ulong len)
|
||||
{
|
||||
MYSQL_TIME tm;
|
||||
ulong length= get_param_length(pos, len);
|
||||
@ -679,8 +677,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
|
||||
}
|
||||
else
|
||||
set_zero_time(&tm, MYSQL_TIMESTAMP_DATE);
|
||||
param->set_time(&tm, MYSQL_TIMESTAMP_DATE,
|
||||
MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
|
||||
set_time(&tm, MYSQL_TIMESTAMP_DATE, MAX_DATE_WIDTH);
|
||||
*pos+= length;
|
||||
}
|
||||
|
||||
@ -689,7 +686,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len)
|
||||
@todo
|
||||
Add warning 'Data truncated' here
|
||||
*/
|
||||
void set_param_time(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_time(uchar **pos, ulong len)
|
||||
{
|
||||
MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
|
||||
tm.hour+= tm.day * 24;
|
||||
@ -701,36 +698,29 @@ void set_param_time(Item_param *param, uchar **pos, ulong len)
|
||||
tm.minute= 59;
|
||||
tm.second= 59;
|
||||
}
|
||||
param->set_time(&tm, MYSQL_TIMESTAMP_TIME,
|
||||
MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
|
||||
|
||||
set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_WIDTH);
|
||||
}
|
||||
|
||||
void set_param_datetime(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_datetime(uchar **pos, ulong len)
|
||||
{
|
||||
MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
|
||||
tm.neg= 0;
|
||||
|
||||
param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
|
||||
MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
|
||||
set_time(&tm, MYSQL_TIMESTAMP_DATETIME, MAX_DATETIME_WIDTH);
|
||||
}
|
||||
|
||||
void set_param_date(Item_param *param, uchar **pos, ulong len)
|
||||
void Item_param::set_param_date(uchar **pos, ulong len)
|
||||
{
|
||||
MYSQL_TIME *to= (MYSQL_TIME*)*pos;
|
||||
|
||||
param->set_time(to, MYSQL_TIMESTAMP_DATE,
|
||||
MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
|
||||
set_time(to, MYSQL_TIMESTAMP_DATE, MAX_DATE_WIDTH);
|
||||
}
|
||||
#endif /*!EMBEDDED_LIBRARY*/
|
||||
|
||||
|
||||
static void set_param_str_or_null(Item_param *param, uchar **pos, ulong len,
|
||||
bool empty_string_is_null)
|
||||
void Item_param::set_param_str(uchar **pos, ulong len)
|
||||
{
|
||||
ulong length= get_param_length(pos, len);
|
||||
if (length == 0 && empty_string_is_null)
|
||||
param->set_null();
|
||||
if (length == 0 && m_empty_string_is_null)
|
||||
set_null();
|
||||
else
|
||||
{
|
||||
if (length > len)
|
||||
@ -740,112 +730,50 @@ static void set_param_str_or_null(Item_param *param, uchar **pos, ulong len,
|
||||
sets will be done in Item_param::convert_str_value(), after the
|
||||
original value is appended to the query used for logging.
|
||||
*/
|
||||
param->set_str((const char *) *pos, length,
|
||||
&my_charset_bin, &my_charset_bin);
|
||||
set_str((const char *) *pos, length, &my_charset_bin, &my_charset_bin);
|
||||
*pos+= length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void set_param_str(Item_param *param, uchar **pos, ulong len)
|
||||
{
|
||||
set_param_str_or_null(param, pos, len, false);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
set_param_str_empty_is_null : bind empty string as null value
|
||||
when sql_mode=MODE_EMPTY_STRING_IS_NULL
|
||||
*/
|
||||
static void set_param_str_empty_is_null(Item_param *param, uchar **pos,
|
||||
ulong len)
|
||||
{
|
||||
set_param_str_or_null(param, pos, len, true);
|
||||
}
|
||||
|
||||
|
||||
#undef get_param_length
|
||||
|
||||
static void setup_one_conversion_function(THD *thd, Item_param *param,
|
||||
uchar param_type)
|
||||
|
||||
void Item_param::setup_conversion(THD *thd, uchar param_type)
|
||||
{
|
||||
switch (param_type) {
|
||||
case MYSQL_TYPE_TINY:
|
||||
param->set_param_func= set_param_tiny;
|
||||
break;
|
||||
case MYSQL_TYPE_SHORT:
|
||||
param->set_param_func= set_param_short;
|
||||
break;
|
||||
case MYSQL_TYPE_LONG:
|
||||
param->set_param_func= set_param_int32;
|
||||
break;
|
||||
case MYSQL_TYPE_LONGLONG:
|
||||
param->set_param_func= set_param_int64;
|
||||
break;
|
||||
case MYSQL_TYPE_FLOAT:
|
||||
param->set_param_func= set_param_float;
|
||||
break;
|
||||
case MYSQL_TYPE_DOUBLE:
|
||||
param->set_param_func= set_param_double;
|
||||
break;
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
case MYSQL_TYPE_NEWDECIMAL:
|
||||
param->set_param_func= set_param_decimal;
|
||||
break;
|
||||
case MYSQL_TYPE_TIME:
|
||||
param->set_param_func= set_param_time;
|
||||
break;
|
||||
case MYSQL_TYPE_DATE:
|
||||
param->set_param_func= set_param_date;
|
||||
break;
|
||||
case MYSQL_TYPE_DATETIME:
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
param->set_param_func= set_param_datetime;
|
||||
break;
|
||||
case MYSQL_TYPE_TINY_BLOB:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
case MYSQL_TYPE_LONG_BLOB:
|
||||
case MYSQL_TYPE_BLOB:
|
||||
param->set_param_func= set_param_str;
|
||||
param->value.cs_info.character_set_of_placeholder= &my_charset_bin;
|
||||
param->value.cs_info.character_set_client=
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
The client library ensures that we won't get any other typecodes
|
||||
except typecodes above and typecodes for string types. Marking
|
||||
label as 'default' lets us to handle malformed packets as well.
|
||||
*/
|
||||
{
|
||||
CHARSET_INFO *fromcs= thd->variables.character_set_client;
|
||||
CHARSET_INFO *tocs= thd->variables.collation_connection;
|
||||
uint32 dummy_offset;
|
||||
const Type_handler *h=
|
||||
Type_handler::get_handler_by_field_type((enum_field_types) param_type);
|
||||
/*
|
||||
The client library ensures that we won't get any unexpected typecodes
|
||||
in the bound parameter. Translating unknown typecodes to
|
||||
&type_handler_string lets us to handle malformed packets as well.
|
||||
*/
|
||||
if (!h)
|
||||
h= &type_handler_string;
|
||||
set_handler(h);
|
||||
value.set_handler(h);
|
||||
h->Item_param_setup_conversion(thd, this);
|
||||
}
|
||||
|
||||
param->value.cs_info.character_set_of_placeholder= fromcs;
|
||||
param->value.cs_info.character_set_client= fromcs;
|
||||
|
||||
/*
|
||||
Setup source and destination character sets so that they
|
||||
are different only if conversion is necessary: this will
|
||||
make later checks easier.
|
||||
*/
|
||||
param->value.cs_info.final_character_set_of_str_value=
|
||||
String::needs_conversion(0, fromcs, tocs, &dummy_offset) ?
|
||||
tocs : fromcs;
|
||||
void Item_param::setup_conversion_blob(THD *thd)
|
||||
{
|
||||
value.cs_info.character_set_of_placeholder= &my_charset_bin;
|
||||
value.cs_info.character_set_client= thd->variables.character_set_client;
|
||||
DBUG_ASSERT(thd->variables.character_set_client);
|
||||
value.cs_info.final_character_set_of_str_value= &my_charset_bin;
|
||||
m_empty_string_is_null= thd->variables.sql_mode & MODE_EMPTY_STRING_IS_NULL;
|
||||
}
|
||||
|
||||
param->set_param_func=
|
||||
(thd->variables.sql_mode & MODE_EMPTY_STRING_IS_NULL) ?
|
||||
set_param_str_empty_is_null : set_param_str;
|
||||
/*
|
||||
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_by_field_type((enum enum_field_types) param_type);
|
||||
|
||||
void Item_param::setup_conversion_string(THD *thd, CHARSET_INFO *fromcs)
|
||||
{
|
||||
value.cs_info.set(thd, fromcs);
|
||||
m_empty_string_is_null= thd->variables.sql_mode & MODE_EMPTY_STRING_IS_NULL;
|
||||
/*
|
||||
Exact value of max_length is not known unless data is converted to
|
||||
charset of connection, so we have to set it later.
|
||||
*/
|
||||
}
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@ -909,14 +837,13 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
|
||||
{
|
||||
if (read_pos >= data_end)
|
||||
DBUG_RETURN(1);
|
||||
param->set_param_func(param, &read_pos, (uint) (data_end - read_pos));
|
||||
param->set_param_func(&read_pos, (uint) (data_end - read_pos));
|
||||
if (param->has_no_value())
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (param->limit_clause_param && !param->has_int_value())
|
||||
{
|
||||
param->set_int(param->val_int(), MY_INT64_NUM_DECIMAL_DIGITS);
|
||||
if (!param->unsigned_flag && param->value.integer < 0)
|
||||
if (param->set_limit_clause_param(param->val_int()))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
@ -964,7 +891,7 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
|
||||
{
|
||||
if (read_pos >= data_end)
|
||||
DBUG_RETURN(1);
|
||||
param->set_param_func(param, &read_pos, (uint) (data_end - read_pos));
|
||||
param->set_param_func(&read_pos, (uint) (data_end - read_pos));
|
||||
if (param->has_no_value())
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
@ -1008,7 +935,7 @@ static bool insert_bulk_params(Prepared_statement *stmt,
|
||||
case STMT_INDICATOR_NONE:
|
||||
if ((*read_pos) >= data_end)
|
||||
DBUG_RETURN(1);
|
||||
param->set_param_func(param, read_pos, (uint) (data_end - (*read_pos)));
|
||||
param->set_param_func(read_pos, (uint) (data_end - (*read_pos)));
|
||||
if (param->has_no_value())
|
||||
DBUG_RETURN(1);
|
||||
if (param->convert_str_value(stmt->thd))
|
||||
@ -1054,7 +981,7 @@ static bool set_conversion_functions(Prepared_statement *stmt,
|
||||
typecode= sint2korr(read_pos);
|
||||
read_pos+= 2;
|
||||
(**it).unsigned_flag= MY_TEST(typecode & signed_bit);
|
||||
setup_one_conversion_function(thd, *it, (uchar) (typecode & 0xff));
|
||||
(*it)->setup_conversion(thd, (uchar) (typecode & 0xff));
|
||||
}
|
||||
*data= read_pos;
|
||||
DBUG_RETURN(0);
|
||||
@ -1109,7 +1036,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query)
|
||||
for (; it < end; ++it, ++client_param)
|
||||
{
|
||||
Item_param *param= *it;
|
||||
setup_one_conversion_function(thd, param, client_param->buffer_type);
|
||||
param->setup_conversion(thd, client_param->buffer_type);
|
||||
if (!param->has_long_data_value())
|
||||
{
|
||||
if (*client_param->is_null)
|
||||
@ -1118,7 +1045,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query)
|
||||
{
|
||||
uchar *buff= (uchar*) client_param->buffer;
|
||||
param->unsigned_flag= client_param->is_unsigned;
|
||||
param->set_param_func(param, &buff,
|
||||
param->set_param_func(&buff,
|
||||
client_param->length ?
|
||||
*client_param->length :
|
||||
client_param->buffer_length);
|
||||
@ -1145,7 +1072,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt, String *query)
|
||||
for (; it < end; ++it, ++client_param)
|
||||
{
|
||||
Item_param *param= *it;
|
||||
setup_one_conversion_function(thd, param, client_param->buffer_type);
|
||||
param->setup_conversion(thd, client_param->buffer_type);
|
||||
if (!param->has_long_data_value())
|
||||
{
|
||||
if (*client_param->is_null)
|
||||
@ -1154,7 +1081,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt, String *query)
|
||||
{
|
||||
uchar *buff= (uchar*)client_param->buffer;
|
||||
param->unsigned_flag= client_param->is_unsigned;
|
||||
param->set_param_func(param, &buff,
|
||||
param->set_param_func(&buff,
|
||||
client_param->length ?
|
||||
*client_param->length :
|
||||
client_param->buffer_length);
|
||||
@ -1287,12 +1214,6 @@ insert_params_from_actual_params_with_log(Prepared_statement *stmt,
|
||||
{
|
||||
Item_param *param= *it;
|
||||
Item *ps_param= param_it++;
|
||||
/*
|
||||
We have to call the setup_one_conversion_function() here to set
|
||||
the parameter's members that might be needed further
|
||||
(e.g. value.cs_info.character_set_client is used in the query_val_str()).
|
||||
*/
|
||||
setup_one_conversion_function(thd, param, param->field_type());
|
||||
if (ps_param->save_in_param(thd, param))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
|
140
sql/sql_type.cc
140
sql/sql_type.cc
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
}
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
{
|
||||
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 @@ public:
|
||||
const handler *file,
|
||||
const Schema_specification_st *schema)
|
||||
const;
|
||||
void Item_param_set_param_func(Item_param *param,
|
||||
uchar **pos, ulong len) const;
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user