diff --git a/src/Functions/if.cpp b/src/Functions/if.cpp index 3be4848f1ff..614bfcf700e 100644 --- a/src/Functions/if.cpp +++ b/src/Functions/if.cpp @@ -532,7 +532,7 @@ private: return nullptr; } - ColumnPtr executeTuple(const ColumnsWithTypeAndName & arguments, size_t input_rows_count) const + ColumnPtr executeTuple(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const { /// Calculate function for each corresponding elements of tuples. @@ -558,6 +558,7 @@ private: const DataTypeTuple & type1 = static_cast(*arg1.type); const DataTypeTuple & type2 = static_cast(*arg2.type); + const DataTypeTuple & tuple_result = static_cast(*result_type); ColumnsWithTypeAndName temporary_columns(3); temporary_columns[0] = arguments[0]; @@ -570,7 +571,7 @@ private: temporary_columns[1] = {col1_contents[i], type1.getElements()[i], {}}; temporary_columns[2] = {col2_contents[i], type2.getElements()[i], {}}; - tuple_columns[i] = executeImpl(temporary_columns, std::make_shared(), input_rows_count); + tuple_columns[i] = executeImpl(temporary_columns, tuple_result.getElements()[i], input_rows_count); } return ColumnTuple::create(tuple_columns); @@ -988,7 +989,7 @@ public: || (res = executeTyped(cond_col, arguments, result_type, input_rows_count)) || (res = executeString(cond_col, arguments, result_type)) || (res = executeGenericArray(cond_col, arguments, result_type)) - || (res = executeTuple(arguments, input_rows_count)))) + || (res = executeTuple(arguments, result_type, input_rows_count)))) { return executeGeneric(cond_col, arguments, input_rows_count); } diff --git a/tests/queries/0_stateless/01701_if_tuple_segfault.reference b/tests/queries/0_stateless/01701_if_tuple_segfault.reference new file mode 100644 index 00000000000..001e50da954 --- /dev/null +++ b/tests/queries/0_stateless/01701_if_tuple_segfault.reference @@ -0,0 +1,3 @@ +2020-10-01 19:20:30 hello ([0],45) 45 ([0,1,2,3,4,5,6,7,8,9,10,11,12],[45,55,65,75,85,95,105,115,125,135,145,155,165]) +([3],4) +2020-10-01 19:20:30 hello ([0],45) 5 ([0,1,2,3,4,5,6,7,8,9,10,11,12],[22,27,32,37,42,47,52,57,62,67,72,77,82]) diff --git a/tests/queries/0_stateless/01701_if_tuple_segfault.sql b/tests/queries/0_stateless/01701_if_tuple_segfault.sql new file mode 100644 index 00000000000..93b28c578a9 --- /dev/null +++ b/tests/queries/0_stateless/01701_if_tuple_segfault.sql @@ -0,0 +1,33 @@ +DROP TABLE IF EXISTS agg_table; + +CREATE TABLE IF NOT EXISTS agg_table +( + time DateTime CODEC(DoubleDelta, LZ4), + xxx String, + two_values Tuple(Array(UInt16), UInt32), + agg_simple SimpleAggregateFunction(sum, UInt64), + agg SimpleAggregateFunction(sumMap, Tuple(Array(Int16), Array(UInt64))) +) +ENGINE = AggregatingMergeTree() +ORDER BY (xxx, time); + +INSERT INTO agg_table SELECT toDateTime('2020-10-01 19:20:30'), 'hello', ([any(number)], sum(number)), sum(number), + sumMap((arrayMap(i -> toString(i), range(13)), arrayMap(i -> (number + i), range(13)))) FROM numbers(10); + +SELECT * FROM agg_table; + +SELECT if(xxx = 'x', ([2], 3), ([3], 4)) FROM agg_table; + +SELECT if(xxx = 'x', ([2], 3), ([3], 4, 'q', 'w', 7)) FROM agg_table; --{ serverError 386 } + +ALTER TABLE agg_table UPDATE two_values = (two_values.1, two_values.2) WHERE time BETWEEN toDateTime('2020-08-01 00:00:00') AND toDateTime('2020-12-01 00:00:00') SETTINGS mutations_sync = 2; + +ALTER TABLE agg_table UPDATE agg_simple = 5 WHERE time BETWEEN toDateTime('2020-08-01 00:00:00') AND toDateTime('2020-12-01 00:00:00') SETTINGS mutations_sync = 2; + +ALTER TABLE agg_table UPDATE agg = (agg.1, agg.2) WHERE time BETWEEN toDateTime('2020-08-01 00:00:00') AND toDateTime('2020-12-01 00:00:00') SETTINGS mutations_sync = 2; + +ALTER TABLE agg_table UPDATE agg = (agg.1, arrayMap(x -> toUInt64(x / 2), agg.2)) WHERE time BETWEEN toDateTime('2020-08-01 00:00:00') AND toDateTime('2020-12-01 00:00:00') SETTINGS mutations_sync = 2; + +SELECT * FROM agg_table; + +DROP TABLE IF EXISTS agg_table;