mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
dbms: fixed error with higher order functions [#METR-16894].
This commit is contained in:
parent
0180cda4ef
commit
001ffdfa18
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <DB/Columns/IColumnDummy.h>
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||
|
||||
#include <DB/Columns/ColumnArray.h>
|
||||
#include <DB/Columns/ColumnReplicated.h>
|
||||
#include <DB/Columns/ColumnExpression.h>
|
||||
|
||||
#include <DB/Functions/IFunction.h>
|
||||
@ -580,7 +579,7 @@ public:
|
||||
ColumnWithNameAndType replicated_column = block.getByPosition(prerequisites[prerequisite_index]);
|
||||
|
||||
replicated_column.name = name;
|
||||
replicated_column.column = typeid_cast<ColumnReplicated &>(*replicated_column.column).getData();
|
||||
replicated_column.column = typeid_cast<ColumnArray &>(*replicated_column.column).getDataPtr();
|
||||
temp_block.insert(replicated_column);
|
||||
|
||||
++prerequisite_index;
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <DB/Columns/ColumnSet.h>
|
||||
#include <DB/Columns/ColumnTuple.h>
|
||||
#include <DB/Columns/ColumnArray.h>
|
||||
#include <DB/Columns/ColumnReplicated.h>
|
||||
#include <DB/Columns/ColumnAggregateFunction.h>
|
||||
#include <DB/Common/UnicodeBar.h>
|
||||
#include <DB/Functions/IFunction.h>
|
||||
@ -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<ColumnArray *>(&*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());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -326,6 +326,7 @@ void registerFunctionsMiscellaneous(FunctionFactory & factory)
|
||||
factory.registerFunction<FunctionMaterialize>();
|
||||
factory.registerFunction<FunctionIgnore>();
|
||||
factory.registerFunction<FunctionArrayJoin>();
|
||||
factory.registerFunction<FunctionReplicate>();
|
||||
factory.registerFunction<FunctionBar>();
|
||||
|
||||
factory.registerFunction<FunctionTuple>();
|
||||
|
@ -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']]
|
@ -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;
|
@ -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]
|
@ -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);
|
Loading…
Reference in New Issue
Block a user