Commit e5145a5a authored by Alexander Barkov's avatar Alexander Barkov

MDEV-12546 Wrong metadata or data type for string user variables

parent 90f06818
...@@ -21,7 +21,7 @@ a b c d ...@@ -21,7 +21,7 @@ a b c d
DROP TABLE t1; DROP TABLE t1;
SELECT LAST_VALUE(@last_a:=1,@last_b:=1); SELECT LAST_VALUE(@last_a:=1,@last_b:=1);
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def LAST_VALUE(@last_a:=1,@last_b:=1) 8 1 1 N 32897 0 63 def LAST_VALUE(@last_a:=1,@last_b:=1) 3 1 1 N 32897 0 63
LAST_VALUE(@last_a:=1,@last_b:=1) LAST_VALUE(@last_a:=1,@last_b:=1)
1 1
select @last_b; select @last_b;
...@@ -46,7 +46,7 @@ LAST_VALUE(@last_a:=1,@last_b:="hello") ...@@ -46,7 +46,7 @@ LAST_VALUE(@last_a:=1,@last_b:="hello")
hello hello
select @last_b; select @last_b;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def @last_b 250 16777215 5 Y 0 39 8 def @last_b 251 16777215 5 Y 0 39 8
@last_b @last_b
hello hello
SELECT date(LAST_VALUE(@last_a:=1,@last_b:="2001-02-03")); SELECT date(LAST_VALUE(@last_a:=1,@last_b:="2001-02-03"));
...@@ -56,7 +56,7 @@ date(LAST_VALUE(@last_a:=1,@last_b:="2001-02-03")) ...@@ -56,7 +56,7 @@ date(LAST_VALUE(@last_a:=1,@last_b:="2001-02-03"))
2001-02-03 2001-02-03
select @last_b; select @last_b;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def @last_b 250 16777215 10 Y 0 39 8 def @last_b 251 16777215 10 Y 0 39 8
@last_b @last_b
2001-02-03 2001-02-03
SELECT LAST_VALUE(@last_a:=1,@last_b:="2001-02-03",NULL); SELECT LAST_VALUE(@last_a:=1,@last_b:="2001-02-03",NULL);
...@@ -66,7 +66,7 @@ LAST_VALUE(@last_a:=1,@last_b:="2001-02-03",NULL) ...@@ -66,7 +66,7 @@ LAST_VALUE(@last_a:=1,@last_b:="2001-02-03",NULL)
NULL NULL
select @last_b; select @last_b;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def @last_b 250 16777215 10 Y 0 39 8 def @last_b 251 16777215 10 Y 0 39 8
@last_b @last_b
2001-02-03 2001-02-03
SELECT LAST_VALUE(); SELECT LAST_VALUE();
......
...@@ -772,3 +772,33 @@ def ROUND(11111111) 3 8 0 N 32897 0 63 ...@@ -772,3 +772,33 @@ def ROUND(11111111) 3 8 0 N 32897 0 63
def ROUND(111111111) 3 9 0 N 32897 0 63 def ROUND(111111111) 3 9 0 N 32897 0 63
def ROUND(1111111111) 8 10 0 N 32897 0 63 def ROUND(1111111111) 8 10 0 N 32897 0 63
ROUND(1) ROUND(11) ROUND(111) ROUND(1111) ROUND(11111) ROUND(111111) ROUND(1111111) ROUND(11111111) ROUND(111111111) ROUND(1111111111) ROUND(1) ROUND(11) ROUND(111) ROUND(1111) ROUND(11111) ROUND(111111) ROUND(1111111) ROUND(11111111) ROUND(111111111) ROUND(1111111111)
#
# MDEV-12546 Wrong metadata or data type for string user variables
#
SET @a='test';
SELECT @a;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def @a 251 16777215 4 Y 0 39 8
@a
test
CREATE TABLE t1 AS SELECT @a;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@a` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
SELECT @b1:=10, @b2:=@b2:=111111111111;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def @b1:=10 3 2 2 N 32897 0 63
def @b2:=@b2:=111111111111 8 12 12 N 32897 0 63
@b1:=10 @b2:=@b2:=111111111111
10 111111111111
CREATE TABLE t1 AS SELECT @b1:=10, @b2:=111111111111;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@b1:=10` int(2) NOT NULL,
`@b2:=111111111111` bigint(12) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -465,3 +465,21 @@ SELECT ...@@ -465,3 +465,21 @@ SELECT
ROUND(1111111111) LIMIT 0; ROUND(1111111111) LIMIT 0;
--disable_metadata --disable_metadata
--echo #
--echo # MDEV-12546 Wrong metadata or data type for string user variables
--echo #
SET @a='test';
--enable_metadata
SELECT @a;
--disable_metadata
CREATE TABLE t1 AS SELECT @a;
SHOW CREATE TABLE t1;
DROP TABLE t1;
--enable_metadata
SELECT @b1:=10, @b2:=@b2:=111111111111;
--disable_metadata
CREATE TABLE t1 AS SELECT @b1:=10, @b2:=111111111111;
SHOW CREATE TABLE t1;
DROP TABLE t1;
...@@ -566,6 +566,15 @@ class Item: public Value_source, ...@@ -566,6 +566,15 @@ class Item: public Value_source,
SEL_TREE *get_mm_tree_for_const(RANGE_OPT_PARAM *param); SEL_TREE *get_mm_tree_for_const(RANGE_OPT_PARAM *param);
/**
Create a field based on the exact data type handler.
*/
Field *create_table_field_from_handler(TABLE *table)
{
const Type_handler *h= type_handler();
return h->make_and_init_table_field(&name, Record_addr(maybe_null),
*this, table);
}
/** /**
Create a field based on field_type of argument. Create a field based on field_type of argument.
This is used to create a field for This is used to create a field for
......
...@@ -4351,8 +4351,27 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref) ...@@ -4351,8 +4351,27 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
m_var_entry->set_charset(args[0]->collation.derivation == DERIVATION_NUMERIC ? m_var_entry->set_charset(args[0]->collation.derivation == DERIVATION_NUMERIC ?
default_charset() : args[0]->collation.collation); default_charset() : args[0]->collation.collation);
collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT); collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT);
set_handler_by_result_type(args[0]->result_type(), switch (args[0]->result_type()) {
max_length, collation.collation); case STRING_RESULT:
case TIME_RESULT:
set_handler(type_handler_long_blob.
type_handler_adjusted_to_max_octet_length(max_length,
collation.collation));
break;
case REAL_RESULT:
set_handler(&type_handler_double);
break;
case INT_RESULT:
set_handler(Type_handler::type_handler_long_or_longlong(max_char_length()));
break;
case DECIMAL_RESULT:
set_handler(&type_handler_newdecimal);
break;
case ROW_RESULT:
DBUG_ASSERT(0);
set_handler(&type_handler_row);
break;
}
if (thd->lex->current_select) if (thd->lex->current_select)
{ {
/* /*
...@@ -5258,7 +5277,6 @@ void Item_func_get_user_var::fix_length_and_dec() ...@@ -5258,7 +5277,6 @@ void Item_func_get_user_var::fix_length_and_dec()
break; break;
case STRING_RESULT: case STRING_RESULT:
max_length= MAX_BLOB_WIDTH - 1; max_length= MAX_BLOB_WIDTH - 1;
set_handler(&type_handler_medium_blob);
break; break;
case DECIMAL_RESULT: case DECIMAL_RESULT:
fix_char_length(DECIMAL_MAX_STR_LENGTH); fix_char_length(DECIMAL_MAX_STR_LENGTH);
......
...@@ -2242,9 +2242,9 @@ class Item_func_user_var :public Item_hybrid_func ...@@ -2242,9 +2242,9 @@ class Item_func_user_var :public Item_hybrid_func
:Item_hybrid_func(thd, item), :Item_hybrid_func(thd, item),
m_var_entry(item->m_var_entry), name(item->name) { } m_var_entry(item->m_var_entry), name(item->name) { }
Field *create_tmp_field(bool group, TABLE *table) Field *create_tmp_field(bool group, TABLE *table)
{ return Item::create_tmp_field(group, table); } { return create_table_field_from_handler(table); }
Field *create_field_for_create_select(TABLE *table) Field *create_field_for_create_select(TABLE *table)
{ return Item::create_field_for_create_select(table); } { return create_table_field_from_handler(table); }
bool check_vcol_func_processor(void *arg); bool check_vcol_func_processor(void *arg);
}; };
...@@ -2347,14 +2347,6 @@ class Item_func_get_user_var :public Item_func_user_var, ...@@ -2347,14 +2347,6 @@ class Item_func_get_user_var :public Item_func_user_var,
my_decimal *val_decimal(my_decimal*); my_decimal *val_decimal(my_decimal*);
String *val_str(String* str); String *val_str(String* str);
void fix_length_and_dec(); void fix_length_and_dec();
Field *create_field_for_create_select(TABLE *table)
{
return Type_handler_hybrid_field_type::cmp_type() == STRING_RESULT ?
type_handler_long_blob.make_and_init_table_field(&(Item::name),
Record_addr(maybe_null),
*this, table) :
create_tmp_field(false, table);
}
virtual void print(String *str, enum_query_type query_type); virtual void print(String *str, enum_query_type query_type);
/* /*
We must always return variables as strings to guard against selects of type We must always return variables as strings to guard against selects of type
......
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