mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 10:14:19 +01:00
MDEV-24958 Server crashes in my_strtod ... with DEFAULT(blob)
Fixes also: MDEV-24942 Server crashes in _ma_rec_pack... with DEFAULT() on BLOB This was caused by two different bugs, both related to that the default value for the blob was not calculated before it was used: - There where now Item_default_value::..result() wrappers, which is needed as item in HAVING uses these. This causes crashes when using a reference to a DEFAULT(blob_field) in HAVING. It also caused wrong results when used with other fields with default value expressions that are not constants. - create_tmp_field() did not take into account that blob fields with default expressions are not yet initialized. Fixed by treating Item_default_value(blob) like a normal item expression.
This commit is contained in:
parent
6983ce704b
commit
415409579a
5 changed files with 129 additions and 5 deletions
|
@ -846,3 +846,36 @@ t r
|
|||
DROP TABLE t1;
|
||||
DROP FUNCTION next_seq_value;
|
||||
DROP TABLE series;
|
||||
#
|
||||
# MDEV-24958 Server crashes in my_strtod /
|
||||
# Value_source::Converter_strntod::Converter_strntod with DEFAULT(blob)
|
||||
#
|
||||
# MDEV-24942 Server crashes in _ma_rec_pack / _ma_write_blob_record with
|
||||
# DEFAULT() on BLOB
|
||||
#
|
||||
CREATE TABLE t1 (id INT, f MEDIUMTEXT NOT NULL DEFAULT 'A');
|
||||
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
|
||||
SELECT f FROM t1 GROUP BY id ORDER BY DEFAULT(f);
|
||||
f
|
||||
foo
|
||||
bar
|
||||
SELECT DEFAULT(f) AS h FROM t1 HAVING h > 5;
|
||||
h
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'A'
|
||||
SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 0;
|
||||
h
|
||||
A
|
||||
A
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect DOUBLE value: 'A'
|
||||
SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 'A';
|
||||
h
|
||||
A
|
||||
A
|
||||
alter table t1 add column b int default (rand()+1+3);
|
||||
select default(b) AS h FROM t1 HAVING h > "2";
|
||||
h
|
||||
#
|
||||
#
|
||||
drop table t1;
|
||||
|
|
|
@ -890,3 +890,23 @@ SELECT t, next_seq_value() r FROM t1 FORCE INDEX(t)
|
|||
DROP TABLE t1;
|
||||
DROP FUNCTION next_seq_value;
|
||||
DROP TABLE series;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-24958 Server crashes in my_strtod /
|
||||
--echo # Value_source::Converter_strntod::Converter_strntod with DEFAULT(blob)
|
||||
--echo #
|
||||
--echo # MDEV-24942 Server crashes in _ma_rec_pack / _ma_write_blob_record with
|
||||
--echo # DEFAULT() on BLOB
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (id INT, f MEDIUMTEXT NOT NULL DEFAULT 'A');
|
||||
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
|
||||
SELECT f FROM t1 GROUP BY id ORDER BY DEFAULT(f);
|
||||
SELECT DEFAULT(f) AS h FROM t1 HAVING h > 5;
|
||||
SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 0;
|
||||
SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 'A';
|
||||
|
||||
alter table t1 add column b int default (rand()+1+3);
|
||||
--replace_column 1 #
|
||||
select default(b) AS h FROM t1 HAVING h > "2";
|
||||
drop table t1;
|
||||
|
|
47
sql/item.cc
47
sql/item.cc
|
@ -9341,7 +9341,6 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
|
|||
}
|
||||
thd->column_usage= save_column_usage;
|
||||
|
||||
|
||||
real_arg= arg->real_item();
|
||||
if (real_arg->type() != FIELD_ITEM)
|
||||
{
|
||||
|
@ -9364,7 +9363,7 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
|
|||
def_field->reset_fields();
|
||||
// If non-constant default value expression or a blob
|
||||
if (def_field->default_value &&
|
||||
(def_field->default_value->flags || def_field->flags & BLOB_FLAG))
|
||||
(def_field->default_value->flags || (def_field->flags & BLOB_FLAG)))
|
||||
{
|
||||
uchar *newptr= (uchar*) thd->alloc(1+def_field->pack_length());
|
||||
if (!newptr)
|
||||
|
@ -9461,11 +9460,53 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
|
|||
return Item_field::save_in_field(field_arg, no_conversions);
|
||||
}
|
||||
|
||||
double Item_default_value::val_result()
|
||||
{
|
||||
calculate();
|
||||
return Item_field::val_result();
|
||||
}
|
||||
|
||||
longlong Item_default_value::val_int_result()
|
||||
{
|
||||
calculate();
|
||||
return Item_field::val_int_result();
|
||||
}
|
||||
|
||||
String *Item_default_value::str_result(String* tmp)
|
||||
{
|
||||
calculate();
|
||||
return Item_field::str_result(tmp);
|
||||
}
|
||||
|
||||
bool Item_default_value::val_bool_result()
|
||||
{
|
||||
calculate();
|
||||
return Item_field::val_bool_result();
|
||||
}
|
||||
|
||||
bool Item_default_value::is_null_result()
|
||||
{
|
||||
calculate();
|
||||
return Item_field::is_null_result();
|
||||
}
|
||||
|
||||
my_decimal *Item_default_value::val_decimal_result(my_decimal *decimal_value)
|
||||
{
|
||||
calculate();
|
||||
return Item_field::val_decimal_result(decimal_value);
|
||||
}
|
||||
|
||||
bool Item_default_value::get_date_result(MYSQL_TIME *ltime,ulonglong fuzzydate)
|
||||
{
|
||||
calculate();
|
||||
return Item_field::get_date_result(ltime, fuzzydate);
|
||||
}
|
||||
|
||||
table_map Item_default_value::used_tables() const
|
||||
{
|
||||
if (!field || !field->default_value)
|
||||
return static_cast<table_map>(0);
|
||||
if (!field->default_value->expr) // not fully parsed field
|
||||
if (!field->default_value->expr) // not fully parsed field
|
||||
return static_cast<table_map>(RAND_TABLE_BIT);
|
||||
return field->default_value->expr->used_tables();
|
||||
}
|
||||
|
|
10
sql/item.h
10
sql/item.h
|
@ -5859,6 +5859,16 @@ public:
|
|||
longlong val_int();
|
||||
my_decimal *val_decimal(my_decimal *decimal_value);
|
||||
bool get_date(MYSQL_TIME *ltime,ulonglong fuzzydate);
|
||||
|
||||
/* Result variants */
|
||||
double val_result();
|
||||
longlong val_int_result();
|
||||
String *str_result(String* tmp);
|
||||
my_decimal *val_decimal_result(my_decimal *val);
|
||||
bool val_bool_result();
|
||||
bool is_null_result();
|
||||
bool get_date_result(MYSQL_TIME *ltime,ulonglong fuzzydate);
|
||||
|
||||
bool send(Protocol *protocol, st_value *buffer);
|
||||
int save_in_field(Field *field_arg, bool no_conversions);
|
||||
bool save_in_param(THD *thd, Item_param *param)
|
||||
|
|
|
@ -17224,7 +17224,13 @@ Field *Item::create_field_for_schema(THD *thd, TABLE *table)
|
|||
the record in the original table.
|
||||
If modify_item is 0 then fill_record() will update
|
||||
the temporary table
|
||||
|
||||
@param table_cant_handle_bit_fields
|
||||
Set to 1 if the temporary table cannot handle bit
|
||||
fields. Only set for heap tables when the bit field
|
||||
is part of an index.
|
||||
@param make_copy_field
|
||||
Set when using with rollup when we want to have
|
||||
an exact copy of the field.
|
||||
@retval
|
||||
0 on error
|
||||
@retval
|
||||
|
@ -17261,8 +17267,22 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
|||
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
|
||||
return result;
|
||||
}
|
||||
case Item::FIELD_ITEM:
|
||||
case Item::DEFAULT_VALUE_ITEM:
|
||||
{
|
||||
Field *field= ((Item_default_value*) item)->field;
|
||||
if (field->default_value && (field->flags & BLOB_FLAG))
|
||||
{
|
||||
/*
|
||||
We have to use a copy function when using a blob with default value
|
||||
as the we have to calcuate the default value before we can use it.
|
||||
*/
|
||||
return create_tmp_field_from_item(thd, item, table,
|
||||
(make_copy_field ? 0 : copy_func),
|
||||
modify_item);
|
||||
}
|
||||
}
|
||||
/* Fall through */
|
||||
case Item::FIELD_ITEM:
|
||||
case Item::CONTEXTUALLY_TYPED_VALUE_ITEM:
|
||||
case Item::INSERT_VALUE_ITEM:
|
||||
case Item::TRIGGER_FIELD_ITEM:
|
||||
|
|
Loading…
Add table
Reference in a new issue