Skip to content

Commit 279b50b

Browse files
committed
MDEV-14041 Server crashes in String::length on queries with functions and ROLLUP
1 parent f4b2740 commit 279b50b

File tree

4 files changed

+108
-4
lines changed

4 files changed

+108
-4
lines changed

mysql-test/r/olap.result

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,5 +800,45 @@ latin1
800800
binary
801801
DROP TABLE t;
802802
#
803+
# MDEV-14041 Server crashes in String::length on queries with functions and ROLLUP
804+
#
805+
CREATE TABLE t1 (i INT);
806+
INSERT INTO t1 VALUES (1),(2);
807+
SELECT GET_LOCK( 'foo', 0 );
808+
GET_LOCK( 'foo', 0 )
809+
1
810+
SELECT HEX( RELEASE_LOCK( 'foo' ) ) AS f FROM t1 GROUP BY f WITH ROLLUP;
811+
f
812+
NULL
813+
1
814+
NULL
815+
DROP TABLE t1;
816+
CREATE TABLE t1 (i INT);
817+
INSERT INTO t1 VALUES (1),(2);
818+
SELECT i FROM t1 GROUP BY i WITH ROLLUP
819+
UNION ALL
820+
SELECT ELT( FOUND_ROWS(), 1 ) f FROM t1 GROUP BY f WITH ROLLUP;
821+
i
822+
1
823+
2
824+
NULL
825+
NULL
826+
NULL
827+
DROP TABLE t1;
828+
CREATE TABLE t1 (a INT);
829+
INSERT INTO t1 VALUES (1),(2);
830+
SELECT a FROM t1 GROUP BY NULLIF( CONVERT('', DATE), '2015-10-15' ) WITH ROLLUP;
831+
a
832+
1
833+
1
834+
Warnings:
835+
Warning 1292 Incorrect datetime value: ''
836+
Warning 1292 Incorrect datetime value: ''
837+
Warning 1292 Incorrect datetime value: ''
838+
Warning 1292 Incorrect datetime value: ''
839+
Warning 1292 Incorrect datetime value: ''
840+
Warning 1292 Incorrect datetime value: ''
841+
DROP TABLE t1;
842+
#
803843
# End of 10.1 tests
804844
#

mysql-test/t/olap.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,28 @@ SELECT CHARSET(d) AS f FROM t GROUP BY d WITH ROLLUP;
439439
DROP TABLE t;
440440

441441

442+
--echo #
443+
--echo # MDEV-14041 Server crashes in String::length on queries with functions and ROLLUP
444+
--echo #
445+
446+
CREATE TABLE t1 (i INT);
447+
INSERT INTO t1 VALUES (1),(2);
448+
SELECT GET_LOCK( 'foo', 0 );
449+
SELECT HEX( RELEASE_LOCK( 'foo' ) ) AS f FROM t1 GROUP BY f WITH ROLLUP;
450+
DROP TABLE t1;
451+
452+
CREATE TABLE t1 (i INT);
453+
INSERT INTO t1 VALUES (1),(2);
454+
SELECT i FROM t1 GROUP BY i WITH ROLLUP
455+
UNION ALL
456+
SELECT ELT( FOUND_ROWS(), 1 ) f FROM t1 GROUP BY f WITH ROLLUP;
457+
DROP TABLE t1;
458+
459+
CREATE TABLE t1 (a INT);
460+
INSERT INTO t1 VALUES (1),(2);
461+
SELECT a FROM t1 GROUP BY NULLIF( CONVERT('', DATE), '2015-10-15' ) WITH ROLLUP;
462+
DROP TABLE t1;
463+
442464
--echo #
443465
--echo # End of 10.1 tests
444466
--echo #

sql/item.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,45 @@ class Item: public Value_source,
663663
SEL_TREE *get_mm_tree_for_const(RANGE_OPT_PARAM *param);
664664

665665
Field *create_tmp_field(bool group, TABLE *table, uint convert_int_length);
666+
/* Helper methods, to get an Item value from another Item */
667+
double val_real_from_item(Item *item)
668+
{
669+
DBUG_ASSERT(fixed == 1);
670+
double value= item->val_real();
671+
null_value= item->null_value;
672+
return value;
673+
}
674+
longlong val_int_from_item(Item *item)
675+
{
676+
DBUG_ASSERT(fixed == 1);
677+
longlong value= item->val_int();
678+
null_value= item->null_value;
679+
return value;
680+
}
681+
String *val_str_from_item(Item *item, String *str)
682+
{
683+
DBUG_ASSERT(fixed == 1);
684+
String *res= item->val_str(str);
685+
if (res)
686+
res->set_charset(collation.collation);
687+
if ((null_value= item->null_value))
688+
res= NULL;
689+
return res;
690+
}
691+
my_decimal *val_decimal_from_item(Item *item, my_decimal *decimal_value)
692+
{
693+
DBUG_ASSERT(fixed == 1);
694+
my_decimal *value= item->val_decimal(decimal_value);
695+
if ((null_value= item->null_value))
696+
value= NULL;
697+
return value;
698+
}
699+
bool get_date_from_item(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate)
700+
{
701+
bool rc= item->get_date(ltime, fuzzydate);
702+
null_value= MY_TEST(rc || item->null_value);
703+
return rc;
704+
}
666705
/*
667706
This method is used if the item was not null but convertion to
668707
TIME/DATE/DATETIME failed. We return a zero date if allowed,

sql/item_func.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,10 +1120,13 @@ class Item_func_rollup_const :public Item_func
11201120
name= a->name;
11211121
name_length= a->name_length;
11221122
}
1123-
double val_real() { return args[0]->val_real(); }
1124-
longlong val_int() { return args[0]->val_int(); }
1125-
String *val_str(String *str) { return args[0]->val_str(str); }
1126-
my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); }
1123+
double val_real() { return val_real_from_item(args[0]); }
1124+
longlong val_int() { return val_int_from_item(args[0]); }
1125+
String *val_str(String *str) { return val_str_from_item(args[0], str); }
1126+
my_decimal *val_decimal(my_decimal *dec)
1127+
{ return val_decimal_from_item(args[0], dec); }
1128+
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
1129+
{ return get_date_from_item(args[0], ltime, fuzzydate); }
11271130
const char *func_name() const { return "rollup_const"; }
11281131
bool const_item() const { return 0; }
11291132
Item_result result_type() const { return args[0]->result_type(); }

0 commit comments

Comments
 (0)