mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-12798 Item_param does not preserve exact field type in EXECUTE IMMEDIATE 'CREATE TABLE AS SELECT ?' USING POINT(1,1)
This commit is contained in:
@ -4300,5 +4300,23 @@ t2 CREATE TABLE `t2` (
|
|||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
#
|
#
|
||||||
|
# MDEV-12798 Item_param does not preserve exact field type in EXECUTE IMMEDIATE 'CREATE TABLE AS SELECT ?' USING POINT(1,1)
|
||||||
|
#
|
||||||
|
EXECUTE IMMEDIATE 'CREATE TABLE t1 AS SELECT ?' USING POINT(1,1);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`?` point NOT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
PREPARE stmt FROM 'CREATE OR REPLACE TABLE t1 AS SELECT ?';
|
||||||
|
EXECUTE stmt USING POINT(1,1);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`?` point NOT NULL
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
#
|
#
|
||||||
|
@ -2293,6 +2293,19 @@ CALL p1('multipolygon');
|
|||||||
CALL p1('geometrycollection');
|
CALL p1('geometrycollection');
|
||||||
DROP PROCEDURE p1;
|
DROP PROCEDURE p1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12798 Item_param does not preserve exact field type in EXECUTE IMMEDIATE 'CREATE TABLE AS SELECT ?' USING POINT(1,1)
|
||||||
|
--echo #
|
||||||
|
EXECUTE IMMEDIATE 'CREATE TABLE t1 AS SELECT ?' USING POINT(1,1);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
PREPARE stmt FROM 'CREATE OR REPLACE TABLE t1 AS SELECT ?';
|
||||||
|
EXECUTE stmt USING POINT(1,1);
|
||||||
|
SHOW CREATE TABLE t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
41
sql/item.cc
41
sql/item.cc
@ -3767,45 +3767,8 @@ bool Item_param::set_from_item(THD *thd, Item *item)
|
|||||||
struct st_value tmp;
|
struct st_value tmp;
|
||||||
if (!item->save_in_value(&tmp))
|
if (!item->save_in_value(&tmp))
|
||||||
{
|
{
|
||||||
unsigned_flag= item->unsigned_flag;
|
if (item->type_handler()->Item_param_set_from_value(thd, this, item, &tmp))
|
||||||
switch (item->cmp_type()) {
|
DBUG_RETURN(true);
|
||||||
case REAL_RESULT:
|
|
||||||
set_double(tmp.value.m_double);
|
|
||||||
set_handler(&type_handler_double);
|
|
||||||
break;
|
|
||||||
case INT_RESULT:
|
|
||||||
set_int(tmp.value.m_longlong, MY_INT64_NUM_DECIMAL_DIGITS);
|
|
||||||
set_handler(&type_handler_longlong);
|
|
||||||
break;
|
|
||||||
case STRING_RESULT:
|
|
||||||
{
|
|
||||||
value.cs_info.set(thd, item->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.
|
|
||||||
*/
|
|
||||||
set_handler(&type_handler_varchar);
|
|
||||||
|
|
||||||
if (set_str(tmp.m_string.ptr(), tmp.m_string.length()))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DECIMAL_RESULT:
|
|
||||||
{
|
|
||||||
set_decimal(&tmp.m_decimal, unsigned_flag);
|
|
||||||
set_handler(&type_handler_newdecimal);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TIME_RESULT:
|
|
||||||
{
|
|
||||||
set_time(&tmp.value.m_time, item->max_length, item->decimals);
|
|
||||||
set_handler(item->type_handler());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ROW_RESULT:
|
|
||||||
DBUG_ASSERT(0);
|
|
||||||
set_null();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
set_null();
|
set_null();
|
||||||
|
@ -2943,7 +2943,8 @@ public:
|
|||||||
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 Type_handler_hybrid_field_type,
|
||||||
|
public Type_geometry_attributes
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
NO_VALUE is a special value meaning that the parameter has not been
|
NO_VALUE is a special value meaning that the parameter has not been
|
||||||
@ -3075,6 +3076,9 @@ public:
|
|||||||
const Type_handler *type_handler() const
|
const Type_handler *type_handler() const
|
||||||
{ return Type_handler_hybrid_field_type::type_handler(); }
|
{ return Type_handler_hybrid_field_type::type_handler(); }
|
||||||
|
|
||||||
|
Field::geometry_type get_geometry_type() const
|
||||||
|
{ return Type_geometry_attributes::get_geometry_type(); };
|
||||||
|
|
||||||
Item_param(THD *thd, const LEX_CSTRING *name_arg,
|
Item_param(THD *thd, const LEX_CSTRING *name_arg,
|
||||||
uint pos_in_query_arg, uint len_in_query_arg);
|
uint pos_in_query_arg, uint len_in_query_arg);
|
||||||
|
|
||||||
|
@ -4180,6 +4180,104 @@ bool Type_handler_time_common::
|
|||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
bool Type_handler_row::
|
||||||
|
Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *val) const
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(0);
|
||||||
|
param->set_null();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_real_result::
|
||||||
|
Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *val) const
|
||||||
|
{
|
||||||
|
param->unsigned_flag= attr->unsigned_flag;
|
||||||
|
param->set_double(val->value.m_double);
|
||||||
|
param->set_handler(&type_handler_double);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_int_result::
|
||||||
|
Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
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);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_decimal_result::
|
||||||
|
Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *val) const
|
||||||
|
{
|
||||||
|
param->unsigned_flag= attr->unsigned_flag;
|
||||||
|
param->set_decimal(&val->m_decimal, attr->unsigned_flag);
|
||||||
|
param->set_handler(&type_handler_newdecimal);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_string_result::
|
||||||
|
Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *val) const
|
||||||
|
{
|
||||||
|
param->unsigned_flag= false;
|
||||||
|
param->value.cs_info.set(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.
|
||||||
|
*/
|
||||||
|
param->set_handler(&type_handler_varchar);
|
||||||
|
return param->set_str(val->m_string.ptr(), val->m_string.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Type_handler_temporal_result::
|
||||||
|
Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *val) const
|
||||||
|
{
|
||||||
|
param->unsigned_flag= attr->unsigned_flag;
|
||||||
|
param->set_time(&val->value.m_time, attr->max_length, attr->decimals);
|
||||||
|
param->set_handler(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_SPATIAL
|
||||||
|
bool Type_handler_geometry::
|
||||||
|
Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *val) const
|
||||||
|
{
|
||||||
|
param->unsigned_flag= false;
|
||||||
|
param->value.cs_info.set(thd, &my_charset_bin);
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
bool Type_handler_null::
|
bool Type_handler_null::
|
||||||
Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
class Field;
|
class Field;
|
||||||
class Item;
|
class Item;
|
||||||
|
class Item_param;
|
||||||
class Item_cache;
|
class Item_cache;
|
||||||
class Item_func_or_sum;
|
class Item_func_or_sum;
|
||||||
class Item_sum_hybrid;
|
class Item_sum_hybrid;
|
||||||
@ -698,6 +699,10 @@ public:
|
|||||||
|
|
||||||
virtual uint32 max_display_length(const Item *item) const= 0;
|
virtual uint32 max_display_length(const Item *item) const= 0;
|
||||||
virtual bool Item_save_in_value(Item *item, st_value *value) const= 0;
|
virtual bool Item_save_in_value(Item *item, st_value *value) const= 0;
|
||||||
|
virtual bool Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *value) const= 0;
|
||||||
virtual bool Item_send(Item *item, Protocol *p, st_value *buf) const= 0;
|
virtual bool Item_send(Item *item, Protocol *p, st_value *buf) const= 0;
|
||||||
virtual int Item_save_in_field(Item *item, Field *field,
|
virtual int Item_save_in_field(Item *item, Field *field,
|
||||||
bool no_conversions) const= 0;
|
bool no_conversions) const= 0;
|
||||||
@ -942,6 +947,10 @@ public:
|
|||||||
return DECIMAL_MAX_PRECISION;
|
return DECIMAL_MAX_PRECISION;
|
||||||
}
|
}
|
||||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
|
bool Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *value) const;
|
||||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
@ -1164,6 +1173,10 @@ public:
|
|||||||
SORT_FIELD_ATTR *attr) const;
|
SORT_FIELD_ATTR *attr) const;
|
||||||
uint Item_decimal_precision(const Item *item) const;
|
uint Item_decimal_precision(const Item *item) const;
|
||||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
|
bool Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
|
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
@ -1226,6 +1239,10 @@ public:
|
|||||||
uint32 max_display_length(const Item *item) const;
|
uint32 max_display_length(const Item *item) const;
|
||||||
uint Item_decimal_precision(const Item *item) const;
|
uint Item_decimal_precision(const Item *item) const;
|
||||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
|
bool Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *value) const;
|
||||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
return Item_send_str(item, protocol, buf);
|
return Item_send_str(item, protocol, buf);
|
||||||
@ -1288,6 +1305,10 @@ public:
|
|||||||
SORT_FIELD_ATTR *attr) const;
|
SORT_FIELD_ATTR *attr) const;
|
||||||
uint Item_decimal_precision(const Item *item) const;
|
uint Item_decimal_precision(const Item *item) const;
|
||||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
|
bool Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
|
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
@ -1343,6 +1364,10 @@ public:
|
|||||||
void sortlength(THD *thd,
|
void sortlength(THD *thd,
|
||||||
const Type_std_attributes *item,
|
const Type_std_attributes *item,
|
||||||
SORT_FIELD_ATTR *attr) const;
|
SORT_FIELD_ATTR *attr) const;
|
||||||
|
bool Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *value) const;
|
||||||
uint32 max_display_length(const Item *item) const;
|
uint32 max_display_length(const Item *item) const;
|
||||||
bool can_change_cond_ref_to_const(Item_bool_func2 *target,
|
bool can_change_cond_ref_to_const(Item_bool_func2 *target,
|
||||||
Item *target_expr, Item *target_value,
|
Item *target_expr, Item *target_value,
|
||||||
@ -1419,6 +1444,10 @@ public:
|
|||||||
}
|
}
|
||||||
uint Item_decimal_precision(const Item *item) const;
|
uint Item_decimal_precision(const Item *item) const;
|
||||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
|
bool Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *value) const;
|
||||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
return Item_send_str(item, protocol, buf);
|
return Item_send_str(item, protocol, buf);
|
||||||
@ -2182,6 +2211,10 @@ public:
|
|||||||
{
|
{
|
||||||
return false; // Materialization does not work with GEOMETRY columns
|
return false; // Materialization does not work with GEOMETRY columns
|
||||||
}
|
}
|
||||||
|
bool Item_param_set_from_value(THD *thd,
|
||||||
|
Item_param *param,
|
||||||
|
const Type_all_attributes *attr,
|
||||||
|
const st_value *value) const;
|
||||||
Field *make_conversion_table_field(TABLE *, uint metadata,
|
Field *make_conversion_table_field(TABLE *, uint metadata,
|
||||||
const Field *target) const;
|
const Field *target) const;
|
||||||
Field *make_table_field(const LEX_CSTRING *name,
|
Field *make_table_field(const LEX_CSTRING *name,
|
||||||
|
Reference in New Issue
Block a user