You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-01 06:46:55 +03:00
MCOL-4728 Query with unusual use of aggregate functions on ColumnStore table crashes MariaDB Server
After an AggreateColumn corresponding to SUM(1+1) is created, it is pushed to the list: gwi.count_asterisk_list.push_back(ac) Later, in getSelectPlan(), the expression SUM(1+1) was erroneously treated as a constant: if (!hasNonSupportItem && !nonConstFunc(ifp) && !(parseInfo & AF_BIT) && tmpVec.size() == 0) { srcp.reset(buildReturnedColumn(item, gwi, gwi.fatalParseError)); This code freed the original AggregateColumn and replaced to a ConstantColumn. But gwi.count_asterisk_list still pointer to the freed AggregateColumn(). The expression SUM(1+1) was treated as a constant because tmpVec was empty due to a bug in this code: // special handling for count(*). This should not be treated as constant. if (isp->argument_count() == 1 && ( sfitempp[0]->type() == Item::CONST_ITEM && (sfitempp[0]->cmp_type() == INT_RESULT || sfitempp[0]->cmp_type() == STRING_RESULT || sfitempp[0]->cmp_type() == REAL_RESULT || sfitempp[0]->cmp_type() == DECIMAL_RESULT) ) ) { field_vec.push_back((Item_field*)item); //dummy Notice, it handles only aggregate functions with explicit literals passed as an argument, while it does not handle constant expressions such as 1+1. Fix: - Adding new classes ConstantColumnNull, ConstantColumnString, ConstantColumnNum, ConstantColumnUInt, ConstantColumnSInt, ConstantColumnReal, ValStrStdString, to reuse the code easier. - Moving a part of the code from the case branch handling CONST_ITEM in buildReturnedColumn() into a new function newConstantColumnNotNullUsingValNativeNoTz(). This makes the code easier to read and to reuse in the future. - Adding a new function newConstantColumnMaybeNullFromValStrNoTz(). Removing dulplicate code from !!!four!!! places, using the new function instead. - Adding a function isSupportedAggregateWithOneConstArg() to properly catch all constant expressions. Using the new function parse_item() in the code commented as "special handling for count(*)". Now it pushes all constant expressions to field_vec, not only explicit literals. - Moving a part of the code from buildAggregateColumn() to a helper function processAggregateColumnConstArg(). Using processAggregateColumnConstArg() in the CONST_ITEM and NULL_ITEM branches. - Adding a new branch in buildReturnedColumn() handling FUNC_ITEM. If a function has constant arguments, a ConstantColumn() is immediately created, without going to buildArithmeticColumn()/buildFunctionColumn(). - Reusing isSupportedAggregateWithOneConstArg() and processAggregateColumnConstArg() in buildAggregateColumn(). A new branch catches aggregate function has only one constant argument and immediately creates a single ConstantColumn without traversing to the argument sub-components.
This commit is contained in:
63
mysql-test/columnstore/bugfixes/mcol-4728.result
Normal file
63
mysql-test/columnstore/bugfixes/mcol-4728.result
Normal file
@ -0,0 +1,63 @@
|
||||
DROP DATABASE IF EXISTS mcol_4728;
|
||||
CREATE DATABASE mcol_4728;
|
||||
USE mcol_4728;
|
||||
SET columnstore_select_handler=ON;
|
||||
CREATE TABLE t1 (a INT) ENGINE=ColumnStore;
|
||||
SELECT SUM(0+0)-SUM(0+0) FROM t1;
|
||||
SUM(0+0)-SUM(0+0)
|
||||
NULL
|
||||
SELECT SUM(0) FROM t1;
|
||||
SUM(0)
|
||||
NULL
|
||||
SELECT COUNT(0) FROM t1;
|
||||
COUNT(0)
|
||||
0
|
||||
SELECT COUNT(NULL) FROM t1;
|
||||
COUNT(NULL)
|
||||
0
|
||||
SELECT COUNT(COALESCE(NULL)) FROM t1;
|
||||
COUNT(COALESCE(NULL))
|
||||
0
|
||||
SELECT MAX(0) FROM t1;
|
||||
MAX(0)
|
||||
NULL
|
||||
SELECT SUM(1)+1 FROM t1;
|
||||
SUM(1)+1
|
||||
NULL
|
||||
SELECT SUM(COALESCE(1))+1 FROM t1;
|
||||
SUM(COALESCE(1))+1
|
||||
NULL
|
||||
SELECT sum(rand(0))+1 FROM t1;
|
||||
sum(rand(0))+1
|
||||
NULL
|
||||
INSERT INTO t1 VALUES (100);
|
||||
SELECT SUM(0+0)-SUM(0+0) FROM t1;
|
||||
SUM(0+0)-SUM(0+0)
|
||||
0
|
||||
SELECT SUM(0) FROM t1;
|
||||
SUM(0)
|
||||
0
|
||||
SELECT COUNT(0) FROM t1;
|
||||
COUNT(0)
|
||||
1
|
||||
SELECT COUNT(NULL) FROM t1;
|
||||
COUNT(NULL)
|
||||
0
|
||||
SELECT COUNT(COALESCE(NULL)) FROM t1;
|
||||
COUNT(COALESCE(NULL))
|
||||
0
|
||||
SELECT MAX(0) FROM t1;
|
||||
MAX(0)
|
||||
0
|
||||
SELECT SUM(1)+1 FROM t1;
|
||||
SUM(1)+1
|
||||
2
|
||||
SELECT SUM(COALESCE(1))+1 FROM t1;
|
||||
SUM(COALESCE(1))+1
|
||||
2
|
||||
SELECT sum(rand(0))+1 FROM t1;
|
||||
sum(rand(0))+1
|
||||
1.1552204276949358
|
||||
DROP TABLE t1;
|
||||
DROP DATABASE mcol_4728;
|
||||
USE test;
|
38
mysql-test/columnstore/bugfixes/mcol-4728.test
Normal file
38
mysql-test/columnstore/bugfixes/mcol-4728.test
Normal file
@ -0,0 +1,38 @@
|
||||
--source ../include/have_columnstore.inc
|
||||
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS mcol_4728;
|
||||
--enable_warnings
|
||||
|
||||
CREATE DATABASE mcol_4728;
|
||||
USE mcol_4728;
|
||||
|
||||
SET columnstore_select_handler=ON;
|
||||
CREATE TABLE t1 (a INT) ENGINE=ColumnStore;
|
||||
|
||||
SELECT SUM(0+0)-SUM(0+0) FROM t1;
|
||||
SELECT SUM(0) FROM t1;
|
||||
SELECT COUNT(0) FROM t1;
|
||||
SELECT COUNT(NULL) FROM t1;
|
||||
SELECT COUNT(COALESCE(NULL)) FROM t1;
|
||||
SELECT MAX(0) FROM t1;
|
||||
SELECT SUM(1)+1 FROM t1;
|
||||
SELECT SUM(COALESCE(1))+1 FROM t1;
|
||||
SELECT sum(rand(0))+1 FROM t1;
|
||||
|
||||
INSERT INTO t1 VALUES (100);
|
||||
|
||||
SELECT SUM(0+0)-SUM(0+0) FROM t1;
|
||||
SELECT SUM(0) FROM t1;
|
||||
SELECT COUNT(0) FROM t1;
|
||||
SELECT COUNT(NULL) FROM t1;
|
||||
SELECT COUNT(COALESCE(NULL)) FROM t1;
|
||||
SELECT MAX(0) FROM t1;
|
||||
SELECT SUM(1)+1 FROM t1;
|
||||
SELECT SUM(COALESCE(1))+1 FROM t1;
|
||||
SELECT sum(rand(0))+1 FROM t1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
DROP DATABASE mcol_4728;
|
||||
USE test;
|
1
mysql-test/columnstore/bugfixes/suite.opt
Normal file
1
mysql-test/columnstore/bugfixes/suite.opt
Normal file
@ -0,0 +1 @@
|
||||
--plugin-load-add=$HA_COLUMNSTORE_SO
|
23
mysql-test/columnstore/bugfixes/suite.pm
Normal file
23
mysql-test/columnstore/bugfixes/suite.pm
Normal file
@ -0,0 +1,23 @@
|
||||
package My::Suite::ColumnStore;
|
||||
|
||||
@ISA = qw(My::Suite);
|
||||
|
||||
my $mcs_bin_dir_compiled=$::bindir . '/storage/columnstore/columnstore/bin';
|
||||
my $mcs_ins_dir_installed=$::bindir . '/bin';
|
||||
|
||||
if (-d $mcs_bin_dir_compiled)
|
||||
{
|
||||
$ENV{MCS_MCSSETCONFIG}=$mcs_bin_dir_compiled . "/mcsSetConfig";
|
||||
$ENV{MCS_CPIMPORT}=$mcs_bin_dir_compiled . "/cpimport";
|
||||
$ENV{MCS_SYSCATALOG_MYSQL_SQL}=$::mysqld_variables{'basedir'} . "/storage/columnstore/columnstore/dbcon/mysql/syscatalog_mysql.sql";
|
||||
}
|
||||
elsif (-d $mcs_ins_dir_installed)
|
||||
{
|
||||
$ENV{MCS_MCSSETCONFIG}=$mcs_ins_dir_installed . "/mcsSetConfig";
|
||||
$ENV{MCS_CPIMPORT}=$mcs_ins_dir_installed . "/cpimport";
|
||||
$ENV{MCS_SYSCATALOG_MYSQL_SQL}=$::mysqld_variables{'basedir'} . "/share/columnstore/syscatalog_mysql.sql";
|
||||
}
|
||||
|
||||
sub is_default { 0 }
|
||||
|
||||
bless { };
|
Reference in New Issue
Block a user