diff --git a/dbms/include/DB/Columns/ColumnReplicated.h b/dbms/include/DB/Columns/ColumnReplicated.h deleted file mode 100644 index 32abf953c67..00000000000 --- a/dbms/include/DB/Columns/ColumnReplicated.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include - - -namespace DB -{ - -/** Содержит промежуточные данные для вычисления выражений в функциях высшего порядка. - * Это - вложенный столбец произвольного размера. - * Сам ColumnReplicated притворяется, как столбец указанного в конструкторе размера. - */ -class ColumnReplicated final : public IColumnDummy -{ -public: - ColumnReplicated(size_t s_, ColumnPtr nested_) : IColumnDummy(s_), nested(nested_) {} - std::string getName() const override { return "ColumnReplicated"; } - ColumnPtr cloneDummy(size_t s_) const override { return new ColumnReplicated(s_, nested); } - - ColumnPtr & getData() { return nested; } -private: - ColumnPtr nested; -}; - -} diff --git a/dbms/include/DB/Columns/IColumnDummy.h b/dbms/include/DB/Columns/IColumnDummy.h index 509c56b14a8..d9c559f68f8 100644 --- a/dbms/include/DB/Columns/IColumnDummy.h +++ b/dbms/include/DB/Columns/IColumnDummy.h @@ -41,12 +41,7 @@ public: ColumnPtr filter(const Filter & filt) const override { - size_t new_size = 0; - for (Filter::const_iterator it = filt.begin(); it != filt.end(); ++it) - if (*it) - ++new_size; - - return cloneDummy(new_size); + return cloneDummy(countBytesInFilter(filt)); } ColumnPtr permute(const Permutation & perm, size_t limit) const override diff --git a/dbms/include/DB/Functions/FunctionsHigherOrder.h b/dbms/include/DB/Functions/FunctionsHigherOrder.h index 1194a849855..d04bf89620f 100644 --- a/dbms/include/DB/Functions/FunctionsHigherOrder.h +++ b/dbms/include/DB/Functions/FunctionsHigherOrder.h @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -580,7 +579,7 @@ public: ColumnWithNameAndType replicated_column = block.getByPosition(prerequisites[prerequisite_index]); replicated_column.name = name; - replicated_column.column = typeid_cast(*replicated_column.column).getData(); + replicated_column.column = typeid_cast(*replicated_column.column).getDataPtr(); temp_block.insert(replicated_column); ++prerequisite_index; diff --git a/dbms/include/DB/Functions/FunctionsMiscellaneous.h b/dbms/include/DB/Functions/FunctionsMiscellaneous.h index de7d94274dd..06320362501 100644 --- a/dbms/include/DB/Functions/FunctionsMiscellaneous.h +++ b/dbms/include/DB/Functions/FunctionsMiscellaneous.h @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -51,9 +50,8 @@ namespace DB * arrayJoin(arr) - особая функция - выполнить её напрямую нельзя; * используется только чтобы получить тип результата соответствующего выражения. * - * replicate(x, arr) - копирует x столько раз, сколько элементов в массиве arr; - * например: replicate(1, ['a', 'b', 'c']) = 1, 1, 1. - * не предназначена для пользователя, а используется только как prerequisites для функций высшего порядка. + * replicate(x, arr) - создаёт массив такого же размера как arr, все элементы которого равны x; + * например: replicate(1, ['a', 'b', 'c']) = [1, 1, 1]. * * sleep(n) - спит n секунд каждый блок. * @@ -570,18 +568,15 @@ public: }; -/** Размножает столбец (первый аргумент) по количеству элементов в массиве (втором аргументе). - * Не предназначена для внешнего использования. - * Так как возвращаемый столбец будет иметь несовпадающий размер с исходными, - * то результат не может быть потом использован в том же блоке, что и аргументы. +/** Создаёт массив, размножая столбец (первый аргумент) по количеству элементов в массиве (втором аргументе). * Используется только в качестве prerequisites для функций высшего порядка. */ class FunctionReplicate : public IFunction { +public: static constexpr auto name = "replicate"; static IFunction * create(const Context & context) { return new FunctionReplicate; } - /// Получить имя функции. String getName() const { @@ -600,7 +595,7 @@ class FunctionReplicate : public IFunction if (!array_type) throw Exception("Second argument for function " + getName() + " must be array.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - return arguments[0]->clone(); + return new DataTypeArray(arguments[0]->clone()); } /// Выполнить функцию над блоком. @@ -620,7 +615,9 @@ class FunctionReplicate : public IFunction array_column = typeid_cast(&*temp_column); } - block.getByPosition(result).column = new ColumnReplicated(first_column->size(), first_column->replicate(array_column->getOffsets())); + block.getByPosition(result).column = new ColumnArray( + first_column->replicate(array_column->getOffsets()), + array_column->getOffsetsColumn()); } }; diff --git a/dbms/src/Functions/FunctionsMiscellaneous.cpp b/dbms/src/Functions/FunctionsMiscellaneous.cpp index 59dd89481f1..e2a478933c1 100644 --- a/dbms/src/Functions/FunctionsMiscellaneous.cpp +++ b/dbms/src/Functions/FunctionsMiscellaneous.cpp @@ -326,6 +326,7 @@ void registerFunctionsMiscellaneous(FunctionFactory & factory) factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); + factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); diff --git a/dbms/tests/queries/0_stateless/00178_function_replicate.reference b/dbms/tests/queries/0_stateless/00178_function_replicate.reference new file mode 100644 index 00000000000..4fdec92dcf3 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00178_function_replicate.reference @@ -0,0 +1,10 @@ +0 [] [] [] [] [] +1 [0] [1] ['1'] [[0]] [['0']] +2 [0,1] [2,2] ['2','2'] [[0,1],[0,1]] [['0','1'],['0','1']] +3 [0,1,2] [3,3,3] ['3','3','3'] [[0,1,2],[0,1,2],[0,1,2]] [['0','1','2'],['0','1','2'],['0','1','2']] +4 [0,1,2,3] [4,4,4,4] ['4','4','4','4'] [[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,2,3]] [['0','1','2','3'],['0','1','2','3'],['0','1','2','3'],['0','1','2','3']] +5 [0,1,2,3,4] [5,5,5,5,5] ['5','5','5','5','5'] [[0,1,2,3,4],[0,1,2,3,4],[0,1,2,3,4],[0,1,2,3,4],[0,1,2,3,4]] [['0','1','2','3','4'],['0','1','2','3','4'],['0','1','2','3','4'],['0','1','2','3','4'],['0','1','2','3','4']] +6 [0,1,2,3,4,5] [6,6,6,6,6,6] ['6','6','6','6','6','6'] [[0,1,2,3,4,5],[0,1,2,3,4,5],[0,1,2,3,4,5],[0,1,2,3,4,5],[0,1,2,3,4,5],[0,1,2,3,4,5]] [['0','1','2','3','4','5'],['0','1','2','3','4','5'],['0','1','2','3','4','5'],['0','1','2','3','4','5'],['0','1','2','3','4','5'],['0','1','2','3','4','5']] +7 [0,1,2,3,4,5,6] [7,7,7,7,7,7,7] ['7','7','7','7','7','7','7'] [[0,1,2,3,4,5,6],[0,1,2,3,4,5,6],[0,1,2,3,4,5,6],[0,1,2,3,4,5,6],[0,1,2,3,4,5,6],[0,1,2,3,4,5,6],[0,1,2,3,4,5,6]] [['0','1','2','3','4','5','6'],['0','1','2','3','4','5','6'],['0','1','2','3','4','5','6'],['0','1','2','3','4','5','6'],['0','1','2','3','4','5','6'],['0','1','2','3','4','5','6'],['0','1','2','3','4','5','6']] +8 [0,1,2,3,4,5,6,7] [8,8,8,8,8,8,8,8] ['8','8','8','8','8','8','8','8'] [[0,1,2,3,4,5,6,7],[0,1,2,3,4,5,6,7],[0,1,2,3,4,5,6,7],[0,1,2,3,4,5,6,7],[0,1,2,3,4,5,6,7],[0,1,2,3,4,5,6,7],[0,1,2,3,4,5,6,7],[0,1,2,3,4,5,6,7]] [['0','1','2','3','4','5','6','7'],['0','1','2','3','4','5','6','7'],['0','1','2','3','4','5','6','7'],['0','1','2','3','4','5','6','7'],['0','1','2','3','4','5','6','7'],['0','1','2','3','4','5','6','7'],['0','1','2','3','4','5','6','7'],['0','1','2','3','4','5','6','7']] +9 [0,1,2,3,4,5,6,7,8] [9,9,9,9,9,9,9,9,9] ['9','9','9','9','9','9','9','9','9'] [[0,1,2,3,4,5,6,7,8],[0,1,2,3,4,5,6,7,8],[0,1,2,3,4,5,6,7,8],[0,1,2,3,4,5,6,7,8],[0,1,2,3,4,5,6,7,8],[0,1,2,3,4,5,6,7,8],[0,1,2,3,4,5,6,7,8],[0,1,2,3,4,5,6,7,8],[0,1,2,3,4,5,6,7,8]] [['0','1','2','3','4','5','6','7','8'],['0','1','2','3','4','5','6','7','8'],['0','1','2','3','4','5','6','7','8'],['0','1','2','3','4','5','6','7','8'],['0','1','2','3','4','5','6','7','8'],['0','1','2','3','4','5','6','7','8'],['0','1','2','3','4','5','6','7','8'],['0','1','2','3','4','5','6','7','8'],['0','1','2','3','4','5','6','7','8']] diff --git a/dbms/tests/queries/0_stateless/00178_function_replicate.sql b/dbms/tests/queries/0_stateless/00178_function_replicate.sql new file mode 100644 index 00000000000..13ce1c24364 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00178_function_replicate.sql @@ -0,0 +1,9 @@ +SELECT + number, + range(number) AS arr, + replicate(number, arr), + replicate(toString(number), arr), + replicate(range(number), arr), + replicate(arrayMap(x -> toString(x), range(number)), arr) +FROM system.numbers +LIMIT 10; diff --git a/dbms/tests/queries/0_stateless/00179_lambdas_with_common_expressions_and_filter.reference b/dbms/tests/queries/0_stateless/00179_lambdas_with_common_expressions_and_filter.reference new file mode 100644 index 00000000000..eb4ff6138fd --- /dev/null +++ b/dbms/tests/queries/0_stateless/00179_lambdas_with_common_expressions_and_filter.reference @@ -0,0 +1,5 @@ +[0] +[0,1,2] +[0,1,2,3,4] +[0,1,2,3,4,5,6] +[0,1,2,3,4,5,6,7,8] diff --git a/dbms/tests/queries/0_stateless/00179_lambdas_with_common_expressions_and_filter.sql b/dbms/tests/queries/0_stateless/00179_lambdas_with_common_expressions_and_filter.sql new file mode 100644 index 00000000000..b5eefa57a9f --- /dev/null +++ b/dbms/tests/queries/0_stateless/00179_lambdas_with_common_expressions_and_filter.sql @@ -0,0 +1,3 @@ +SELECT arrayMap(x -> number != -1 ? x : 0, arr) +FROM (SELECT number, range(number) AS arr FROM system.numbers LIMIT 10) +WHERE number % 2 = 1 AND arrayExists(x -> number != -1, arr);