summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-04-22 14:01:58 +0400
committerAlexander Barkov <bar@mariadb.com>2019-04-22 14:01:58 +0400
commit279b50b4eb69f882510f069e79715c38dc13355e (patch)
tree115d0e09a5906c1673781fe7a3eba8556846ce6a
parentf4b27400185bab217da11f8781eebb09a8502304 (diff)
downloadmariadb-git-279b50b4eb69f882510f069e79715c38dc13355e.tar.gz
MDEV-14041 Server crashes in String::length on queries with functions and ROLLUP
-rw-r--r--mysql-test/r/olap.result40
-rw-r--r--mysql-test/t/olap.test22
-rw-r--r--sql/item.h39
-rw-r--r--sql/item_func.h11
4 files changed, 108 insertions, 4 deletions
diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result
index 84c54c0c3c7..df2d6416648 100644
--- a/mysql-test/r/olap.result
+++ b/mysql-test/r/olap.result
@@ -800,5 +800,45 @@ latin1
binary
DROP TABLE t;
#
+# MDEV-14041 Server crashes in String::length on queries with functions and ROLLUP
+#
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT GET_LOCK( 'foo', 0 );
+GET_LOCK( 'foo', 0 )
+1
+SELECT HEX( RELEASE_LOCK( 'foo' ) ) AS f FROM t1 GROUP BY f WITH ROLLUP;
+f
+NULL
+1
+NULL
+DROP TABLE t1;
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT i FROM t1 GROUP BY i WITH ROLLUP
+UNION ALL
+SELECT ELT( FOUND_ROWS(), 1 ) f FROM t1 GROUP BY f WITH ROLLUP;
+i
+1
+2
+NULL
+NULL
+NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT a FROM t1 GROUP BY NULLIF( CONVERT('', DATE), '2015-10-15' ) WITH ROLLUP;
+a
+1
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+Warning 1292 Incorrect datetime value: ''
+Warning 1292 Incorrect datetime value: ''
+Warning 1292 Incorrect datetime value: ''
+Warning 1292 Incorrect datetime value: ''
+Warning 1292 Incorrect datetime value: ''
+DROP TABLE t1;
+#
# End of 10.1 tests
#
diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test
index bb7806969d3..8d1951573b3 100644
--- a/mysql-test/t/olap.test
+++ b/mysql-test/t/olap.test
@@ -440,5 +440,27 @@ DROP TABLE t;
--echo #
+--echo # MDEV-14041 Server crashes in String::length on queries with functions and ROLLUP
+--echo #
+
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT GET_LOCK( 'foo', 0 );
+SELECT HEX( RELEASE_LOCK( 'foo' ) ) AS f FROM t1 GROUP BY f WITH ROLLUP;
+DROP TABLE t1;
+
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT i FROM t1 GROUP BY i WITH ROLLUP
+UNION ALL
+SELECT ELT( FOUND_ROWS(), 1 ) f FROM t1 GROUP BY f WITH ROLLUP;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT a FROM t1 GROUP BY NULLIF( CONVERT('', DATE), '2015-10-15' ) WITH ROLLUP;
+DROP TABLE t1;
+
+--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/sql/item.h b/sql/item.h
index 4b93d3f9164..5c432887ed9 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -663,6 +663,45 @@ protected:
SEL_TREE *get_mm_tree_for_const(RANGE_OPT_PARAM *param);
Field *create_tmp_field(bool group, TABLE *table, uint convert_int_length);
+ /* Helper methods, to get an Item value from another Item */
+ double val_real_from_item(Item *item)
+ {
+ DBUG_ASSERT(fixed == 1);
+ double value= item->val_real();
+ null_value= item->null_value;
+ return value;
+ }
+ longlong val_int_from_item(Item *item)
+ {
+ DBUG_ASSERT(fixed == 1);
+ longlong value= item->val_int();
+ null_value= item->null_value;
+ return value;
+ }
+ String *val_str_from_item(Item *item, String *str)
+ {
+ DBUG_ASSERT(fixed == 1);
+ String *res= item->val_str(str);
+ if (res)
+ res->set_charset(collation.collation);
+ if ((null_value= item->null_value))
+ res= NULL;
+ return res;
+ }
+ my_decimal *val_decimal_from_item(Item *item, my_decimal *decimal_value)
+ {
+ DBUG_ASSERT(fixed == 1);
+ my_decimal *value= item->val_decimal(decimal_value);
+ if ((null_value= item->null_value))
+ value= NULL;
+ return value;
+ }
+ bool get_date_from_item(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ bool rc= item->get_date(ltime, fuzzydate);
+ null_value= MY_TEST(rc || item->null_value);
+ return rc;
+ }
/*
This method is used if the item was not null but convertion to
TIME/DATE/DATETIME failed. We return a zero date if allowed,
diff --git a/sql/item_func.h b/sql/item_func.h
index 9700429d543..36a2f94b31d 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1120,10 +1120,13 @@ public:
name= a->name;
name_length= a->name_length;
}
- double val_real() { return args[0]->val_real(); }
- longlong val_int() { return args[0]->val_int(); }
- String *val_str(String *str) { return args[0]->val_str(str); }
- my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); }
+ double val_real() { return val_real_from_item(args[0]); }
+ longlong val_int() { return val_int_from_item(args[0]); }
+ String *val_str(String *str) { return val_str_from_item(args[0], str); }
+ my_decimal *val_decimal(my_decimal *dec)
+ { return val_decimal_from_item(args[0], dec); }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_item(args[0], ltime, fuzzydate); }
const char *func_name() const { return "rollup_const"; }
bool const_item() const { return 0; }
Item_result result_type() const { return args[0]->result_type(); }