mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
Added functions array{Rotate,Shift}{Left,Right}
Fixes #52755 and #52895
This commit is contained in:
parent
b074e44c1b
commit
a5eb1aa22f
@ -1794,6 +1794,330 @@ Return value type is always [Float64](../../sql-reference/data-types/float.md).
|
||||
└─────┴──────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## arrayRotateLeft
|
||||
|
||||
Rotates an [array](../../sql-reference/data-types/array.md) to the left by the specified number of elements.
|
||||
If the number of elements is negative, the array is rotated to the right.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
arrayRotateLeft(arr, n)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `arr` — [Array](../../sql-reference/data-types/array.md).
|
||||
- `n` — Number of elements to rotate.
|
||||
|
||||
**Returned value**
|
||||
|
||||
- An array rotated to the left by the specified number of elements.
|
||||
|
||||
Type: [Array](../../sql-reference/data-types/array.md).
|
||||
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateLeft([1,2,3,4,5,6], 2) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [3,4,5,6,1,2] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateLeft([1,2,3,4,5,6], -2) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [5,6,1,2,3,4] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateLeft(['a','b','c','d','e'], 3) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res───────────────────┐
|
||||
│ ['d','e','a','b','c'] │
|
||||
└───────────────────────┘
|
||||
```
|
||||
|
||||
## arrayRotateRight
|
||||
|
||||
Rotates an [array](../../sql-reference/data-types/array.md) to the right by the specified number of elements.
|
||||
If the number of elements is negative, the array is rotated to the left.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
arrayRotateRight(arr, n)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `arr` — [Array](../../sql-reference/data-types/array.md).
|
||||
- `n` — Number of elements to rotate.
|
||||
|
||||
**Returned value**
|
||||
|
||||
- An array rotated to the right by the specified number of elements.
|
||||
|
||||
Type: [Array](../../sql-reference/data-types/array.md).
|
||||
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateRight([1,2,3,4,5,6], 2) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [5,6,1,2,3,4] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateRight([1,2,3,4,5,6], -2) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [3,4,5,6,1,2] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateRight(['a','b','c','d','e'], 3) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res───────────────────┐
|
||||
│ ['c','d','e','a','b'] │
|
||||
└───────────────────────┘
|
||||
```
|
||||
|
||||
## arrayShiftLeft
|
||||
|
||||
Shifts an [array](../../sql-reference/data-types/array.md) to the left by the specified number of elements.
|
||||
New elements are filled with the provided argument or the default value of the array element type.
|
||||
If the number of elements is negative, the array is shifted to the right.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
arrayShiftLeft(arr, n[, default])
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `arr` — [Array](../../sql-reference/data-types/array.md).
|
||||
- `n` — Number of elements to shift.
|
||||
- `default` — Optional. Default value for new elements.
|
||||
|
||||
**Returned value**
|
||||
|
||||
- An array shifted to the left by the specified number of elements.
|
||||
|
||||
Type: [Array](../../sql-reference/data-types/array.md).
|
||||
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftLeft([1,2,3,4,5,6], 2) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [3,4,5,6,0,0] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftLeft([1,2,3,4,5,6], -2) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [0,0,1,2,3,4] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftLeft([1,2,3,4,5,6], 2, 42) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res─────────────┐
|
||||
│ [3,4,5,6,42,42] │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftLeft(['a','b','c','d','e','f'], 3, 'foo') as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res─────────────────────────────┐
|
||||
│ ['d','e','f','foo','foo','foo'] │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftLeft([1,2,3,4,5,6] :: Array(UInt16), 2, 4242) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res─────────────────┐
|
||||
│ [3,4,5,6,4242,4242] │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
## arrayShiftRight
|
||||
|
||||
Shifts an [array](../../sql-reference/data-types/array.md) to the right by the specified number of elements.
|
||||
New elements are filled with the provided argument or the default value of the array element type.
|
||||
If the number of elements is negative, the array is shifted to the left.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
arrayShiftRight(arr, n[, default])
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `arr` — [Array](../../sql-reference/data-types/array.md).
|
||||
- `n` — Number of elements to shift.
|
||||
- `default` — Optional. Default value for new elements.
|
||||
|
||||
**Returned value**
|
||||
|
||||
- An array shifted to the right by the specified number of elements.
|
||||
|
||||
Type: [Array](../../sql-reference/data-types/array.md).
|
||||
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftRight([1,2,3,4,5,6], 2) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [0,0,1,2,3,4] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftRight([1,2,3,4,5,6], -2) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [3,4,5,6,0,0] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftRight([1,2,3,4,5,6], 2, 42) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res─────────────┐
|
||||
│ [42,42,1,2,3,4] │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftRight(['a','b','c','d','e','f'], 3, 'foo') as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res─────────────────────────────┐
|
||||
│ ['foo','foo','foo','a','b','c'] │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftRight([1,2,3,4,5,6] :: Array(UInt16), 2, 4242) as res;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─res─────────────────┐
|
||||
│ [4242,4242,1,2,3,4] │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
## Distance functions
|
||||
|
||||
All supported functions are described in [distance functions documentation](../../sql-reference/functions/distance-functions.md).
|
||||
|
@ -1703,3 +1703,327 @@ SELECT arrayProduct([toDecimal64(1,8), toDecimal64(2,8), toDecimal64(3,8)]) as r
|
||||
│ 6 │ Float64 │
|
||||
└─────┴──────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## arrayRotateLeft
|
||||
|
||||
Поворачивает [массив](../../sql-reference/data-types/array.md) влево на заданное число элементов.
|
||||
Если количество элементов отрицательно, то массив поворачивается вправо.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
arrayRotateLeft(arr, n)
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
|
||||
- `arr` — [Массив](../../sql-reference/data-types/array.md).
|
||||
- `n` — Число элементов, на которое нужно повернуть массив.
|
||||
|
||||
**Возвращаемое значение**
|
||||
|
||||
- Массив, повернутый на заданное число элементов влево.
|
||||
|
||||
Тип: [Массив](../../sql-reference/data-types/array.md).
|
||||
|
||||
**Примеры**
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateLeft([1,2,3,4,5,6], 2) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [3,4,5,6,1,2] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateLeft([1,2,3,4,5,6], -2) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [5,6,1,2,3,4] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateLeft(['a','b','c','d','e'], 3) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res───────────────────┐
|
||||
│ ['d','e','a','b','c'] │
|
||||
└───────────────────────┘
|
||||
```
|
||||
|
||||
## arrayRotateRight
|
||||
|
||||
Поворачивает [массив](../../sql-reference/data-types/array.md) вправо на заданное число элементов.
|
||||
Если количество элементов отрицательно, то массив поворачивается влево.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
arrayRotateRight(arr, n)
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
|
||||
- `arr` — [Массив](../../sql-reference/data-types/array.md).
|
||||
- `n` — Число элементов, на которое нужно повернуть массив.
|
||||
|
||||
**Возвращаемое значение**
|
||||
|
||||
- Массив, повернутый на заданное число элементов вправо.
|
||||
|
||||
Тип: [Массив](../../sql-reference/data-types/array.md).
|
||||
|
||||
**Примеры**
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateRight([1,2,3,4,5,6], 2) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [5,6,1,2,3,4] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateRight([1,2,3,4,5,6], -2) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [3,4,5,6,1,2] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayRotateRight(['a','b','c','d','e'], 3) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res───────────────────┐
|
||||
│ ['c','d','e','a','b'] │
|
||||
└───────────────────────┘
|
||||
```
|
||||
|
||||
## arrayShiftLeft
|
||||
|
||||
Сдвигает [массив](../../sql-reference/data-types/array.md) влево на заданное число элементов.
|
||||
Новые элементы заполняются переданным аргументом или значением по умолчанию для типа элементов массива.
|
||||
Если количество элементов отрицательно, то массив сдвигается вправо.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
arrayShiftLeft(arr, n[, default])
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
|
||||
- `arr` — [Массив](../../sql-reference/data-types/array.md).
|
||||
- `n` — Число элементов, на которое нужно сдвинуть массив.
|
||||
- `default` — Опциональный. Значение по умолчанию для новых элементов.
|
||||
|
||||
**Возвращаемое значение**
|
||||
|
||||
- Массив, сдвинутый на заданное число элементов влево.
|
||||
|
||||
Тип: [Массив](../../sql-reference/data-types/array.md).
|
||||
|
||||
**Примеры**
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftLeft([1,2,3,4,5,6], 2) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [3,4,5,6,0,0] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftLeft([1,2,3,4,5,6], -2) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [0,0,1,2,3,4] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftLeft([1,2,3,4,5,6], 2, 42) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res─────────────┐
|
||||
│ [3,4,5,6,42,42] │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftLeft(['a','b','c','d','e','f'], 3, 'foo') as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res─────────────────────────────┐
|
||||
│ ['d','e','f','foo','foo','foo'] │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftLeft([1,2,3,4,5,6] :: Array(UInt16), 2, 4242) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res─────────────────┐
|
||||
│ [3,4,5,6,4242,4242] │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
## arrayShiftRight
|
||||
|
||||
Сдвигает [массив](../../sql-reference/data-types/array.md) вправо на заданное число элементов.
|
||||
Новые элементы заполняются переданным аргументом или значением по умолчанию для типа элементов массива.
|
||||
Если количество элементов отрицательно, то массив сдвигается влево.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
arrayShiftRight(arr, n[, default])
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
|
||||
- `arr` — [Массив](../../sql-reference/data-types/array.md).
|
||||
- `n` — Число элементов, на которое нужно сдвинуть массив.
|
||||
- `default` — Опциональный. Значение по умолчанию для новых элементов.
|
||||
|
||||
**Возвращаемое значение**
|
||||
|
||||
- Массив, сдвинутый на заданное число элементов вправо.
|
||||
|
||||
Тип: [Массив](../../sql-reference/data-types/array.md).
|
||||
|
||||
**Примеры**
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftRight([1,2,3,4,5,6], 2) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [0,0,1,2,3,4] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftRight([1,2,3,4,5,6], -2) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res───────────┐
|
||||
│ [3,4,5,6,0,0] │
|
||||
└───────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftRight([1,2,3,4,5,6], 2, 42) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res─────────────┐
|
||||
│ [42,42,1,2,3,4] │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftRight(['a','b','c','d','e','f'], 3, 'foo') as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res─────────────────────────────┐
|
||||
│ ['foo','foo','foo','a','b','c'] │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SELECT arrayShiftRight([1,2,3,4,5,6] :: Array(UInt16), 2, 4242) as res;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─res─────────────────┐
|
||||
│ [4242,4242,1,2,3,4] │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
399
src/Functions/array/arrayShiftRotate.cpp
Normal file
399
src/Functions/array/arrayShiftRotate.cpp
Normal file
@ -0,0 +1,399 @@
|
||||
#include <limits>
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <DataTypes/getLeastSupertype.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/FunctionHelpers.h>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <Interpreters/castColumn.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||
extern const int VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE;
|
||||
}
|
||||
|
||||
enum class ShiftRotateStrategy : uint8_t
|
||||
{
|
||||
Shift,
|
||||
Rotate
|
||||
};
|
||||
|
||||
enum class ShiftRotateDirection : uint8_t
|
||||
{
|
||||
Left,
|
||||
Right
|
||||
};
|
||||
|
||||
template <typename Impl, typename Name>
|
||||
class FunctionArrayShiftRotate : public IFunction
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = Name::name;
|
||||
static constexpr ShiftRotateStrategy strategy = Impl::strategy;
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionArrayShiftRotate>(); }
|
||||
|
||||
String getName() const override { return name; }
|
||||
|
||||
bool isVariadic() const override { return strategy == ShiftRotateStrategy::Shift; }
|
||||
size_t getNumberOfArguments() const override { return strategy == ShiftRotateStrategy::Rotate ? 2 : 0; }
|
||||
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
if constexpr (strategy == ShiftRotateStrategy::Shift)
|
||||
{
|
||||
if (arguments.size() < 2)
|
||||
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, "Function {} requires at least two arguments.", getName());
|
||||
|
||||
if (arguments.size() > 3)
|
||||
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, "Function {} requires at most three arguments.", getName());
|
||||
}
|
||||
|
||||
const DataTypePtr & first_arg = arguments[0];
|
||||
if (!isArray(first_arg))
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}, expected Array",
|
||||
arguments[0]->getName(),
|
||||
getName());
|
||||
|
||||
if (!isNativeInteger(arguments[1]))
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}, expected Native Integer",
|
||||
arguments[1]->getName(),
|
||||
getName());
|
||||
|
||||
const DataTypePtr & elem_type = static_cast<const DataTypeArray &>(*first_arg).getNestedType();
|
||||
if (arguments.size() == 3)
|
||||
{
|
||||
auto ret = tryGetLeastSupertype(DataTypes{elem_type, arguments[2]});
|
||||
// Note that this will fail if the default value does not fit into the array element type (e.g. UInt64 and Array(UInt8)).
|
||||
// In this case array should be converted to Array(UInt64) explicitly.
|
||||
if (!ret || !ret->equals(*elem_type))
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}, expected {}",
|
||||
arguments[2]->getName(),
|
||||
getName(),
|
||||
elem_type->getName());
|
||||
}
|
||||
|
||||
return std::make_shared<DataTypeArray>(elem_type);
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
|
||||
{
|
||||
ColumnPtr column_array_ptr = arguments[0].column;
|
||||
const auto * column_array = checkAndGetColumn<ColumnArray>(column_array_ptr.get());
|
||||
|
||||
if (!column_array)
|
||||
{
|
||||
const auto * column_const_array = checkAndGetColumnConst<ColumnArray>(column_array_ptr.get());
|
||||
if (!column_const_array)
|
||||
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Expected Array column, found {}", column_array_ptr->getName());
|
||||
|
||||
column_array_ptr = column_const_array->convertToFullColumn();
|
||||
column_array = assert_cast<const ColumnArray *>(column_array_ptr.get());
|
||||
}
|
||||
|
||||
ColumnPtr shift_num_column = arguments[1].column;
|
||||
|
||||
if constexpr (strategy == ShiftRotateStrategy::Shift)
|
||||
{
|
||||
ColumnPtr default_column;
|
||||
const auto elem_type = static_cast<const DataTypeArray &>(*result_type).getNestedType();
|
||||
|
||||
if (arguments.size() == 3)
|
||||
default_column = castColumn(arguments[2], elem_type);
|
||||
else
|
||||
default_column = elem_type->createColumnConstWithDefaultValue(input_rows_count);
|
||||
|
||||
default_column = default_column->convertToFullColumnIfConst();
|
||||
|
||||
return Impl::execute(*column_array, shift_num_column, default_column, input_rows_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Impl::execute(*column_array, shift_num_column, input_rows_count);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <ShiftRotateDirection direction>
|
||||
struct ArrayRotateImpl
|
||||
{
|
||||
static constexpr ShiftRotateStrategy strategy = ShiftRotateStrategy::Rotate;
|
||||
static ColumnPtr execute(const ColumnArray & array, ColumnPtr shift_num_column, size_t input_rows_count)
|
||||
{
|
||||
size_t batch_size = array.getData().size();
|
||||
|
||||
IColumn::Permutation permutation(batch_size);
|
||||
const IColumn::Offsets & offsets = array.getOffsets();
|
||||
|
||||
IColumn::Offset current_offset = 0;
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
const size_t offset = offsets[i];
|
||||
const size_t nested_size = offset - current_offset;
|
||||
Int64 shift_num_value = shift_num_column->getInt(i);
|
||||
|
||||
// Rotating left to -N is the same as rotating right to N.
|
||||
ShiftRotateDirection actual_direction = direction;
|
||||
if (shift_num_value < 0)
|
||||
{
|
||||
if (shift_num_value == std::numeric_limits<Int64>::min())
|
||||
throw Exception(ErrorCodes::VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE, "Shift number {} is out of range", shift_num_value);
|
||||
actual_direction = (direction == ShiftRotateDirection::Left) ? ShiftRotateDirection::Right : ShiftRotateDirection::Left;
|
||||
shift_num_value = -shift_num_value;
|
||||
}
|
||||
|
||||
size_t shift_num = static_cast<size_t>(shift_num_value);
|
||||
if (nested_size > 0 && shift_num >= nested_size)
|
||||
shift_num %= nested_size;
|
||||
|
||||
// Rotating left to N is the same as shifting right to (size - N).
|
||||
if (actual_direction == ShiftRotateDirection::Right)
|
||||
shift_num = nested_size - shift_num;
|
||||
|
||||
for (size_t j = 0; j < nested_size; ++j)
|
||||
permutation[current_offset + j] = current_offset + (j + shift_num) % nested_size;
|
||||
|
||||
current_offset = offset;
|
||||
}
|
||||
|
||||
return ColumnArray::create(array.getData().permute(permutation, 0), array.getOffsetsPtr());
|
||||
}
|
||||
};
|
||||
|
||||
template <ShiftRotateDirection direction>
|
||||
struct ArrayShiftImpl
|
||||
{
|
||||
static constexpr ShiftRotateStrategy strategy = ShiftRotateStrategy::Shift;
|
||||
|
||||
static ColumnPtr
|
||||
execute(const ColumnArray & array, ColumnPtr shift_column, ColumnPtr default_column, size_t input_column_rows)
|
||||
{
|
||||
const IColumn::Offsets & offsets = array.getOffsets();
|
||||
const IColumn & array_data = array.getData();
|
||||
const size_t data_size = array_data.size();
|
||||
|
||||
auto result_column = array.getData().cloneEmpty();
|
||||
result_column->reserve(data_size);
|
||||
|
||||
IColumn::Offset current_offset = 0;
|
||||
for (size_t i = 0; i < input_column_rows; ++i)
|
||||
{
|
||||
const size_t offset = offsets[i];
|
||||
const size_t nested_size = offset - current_offset;
|
||||
Int64 shift_num_value = shift_column->getInt(i);
|
||||
|
||||
// Shifting left to -N is the same as shifting right to N.
|
||||
ShiftRotateDirection actual_direction = direction;
|
||||
if (shift_num_value < 0)
|
||||
{
|
||||
if (shift_num_value == std::numeric_limits<Int64>::min())
|
||||
throw Exception(ErrorCodes::VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE, "Shift number {} is out of range", shift_num_value);
|
||||
actual_direction = (direction == ShiftRotateDirection::Left) ? ShiftRotateDirection::Right : ShiftRotateDirection::Left;
|
||||
shift_num_value = -shift_num_value;
|
||||
}
|
||||
|
||||
const size_t number_of_default_values = std::min(static_cast<size_t>(shift_num_value), nested_size);
|
||||
const size_t num_of_original_values = nested_size - number_of_default_values;
|
||||
|
||||
if (actual_direction == ShiftRotateDirection::Right)
|
||||
{
|
||||
result_column->insertManyFrom(*default_column, i, number_of_default_values);
|
||||
result_column->insertRangeFrom(array_data, current_offset, num_of_original_values);
|
||||
}
|
||||
else
|
||||
{
|
||||
result_column->insertRangeFrom(array_data, current_offset + number_of_default_values, num_of_original_values);
|
||||
result_column->insertManyFrom(*default_column, i, number_of_default_values);
|
||||
}
|
||||
|
||||
current_offset = offset;
|
||||
}
|
||||
|
||||
return ColumnArray::create(std::move(result_column), array.getOffsetsPtr());
|
||||
}
|
||||
};
|
||||
|
||||
struct NameArrayShiftLeft
|
||||
{
|
||||
static constexpr auto name = "arrayShiftLeft";
|
||||
};
|
||||
|
||||
struct NameArrayShiftRight
|
||||
{
|
||||
static constexpr auto name = "arrayShiftRight";
|
||||
};
|
||||
|
||||
struct NameArrayRotateLeft
|
||||
{
|
||||
static constexpr auto name = "arrayRotateLeft";
|
||||
};
|
||||
|
||||
struct NameArrayRotateRight
|
||||
{
|
||||
static constexpr auto name = "arrayRotateRight";
|
||||
};
|
||||
|
||||
using ArrayShiftLeftImpl = ArrayShiftImpl<ShiftRotateDirection::Left>;
|
||||
using FunctionArrayShiftLeft = FunctionArrayShiftRotate<ArrayShiftLeftImpl, NameArrayShiftLeft>;
|
||||
|
||||
using ArrayShiftRightImpl = ArrayShiftImpl<ShiftRotateDirection::Right>;
|
||||
using FunctionArrayShiftRight = FunctionArrayShiftRotate<ArrayShiftRightImpl, NameArrayShiftRight>;
|
||||
|
||||
using ArrayRotateLeftImpl = ArrayRotateImpl<ShiftRotateDirection::Left>;
|
||||
using FunctionArrayRotateLeft = FunctionArrayShiftRotate<ArrayRotateLeftImpl, NameArrayRotateLeft>;
|
||||
|
||||
using ArrayRotateRightImpl = ArrayRotateImpl<ShiftRotateDirection::Right>;
|
||||
using FunctionArrayRotateRight = FunctionArrayShiftRotate<ArrayRotateRightImpl, NameArrayRotateRight>;
|
||||
|
||||
|
||||
REGISTER_FUNCTION(ArrayShiftOrRotate)
|
||||
{
|
||||
factory.registerFunction<FunctionArrayRotateLeft>(
|
||||
FunctionDocumentation{
|
||||
.description = R"(
|
||||
Returns an array of the same size as the original array with elements rotated
|
||||
to the left by the specified number of positions.
|
||||
[example:simple_int]
|
||||
[example:overflow_int]
|
||||
[example:simple_string]
|
||||
[example:simple_array]
|
||||
[example:simple_nested_array]
|
||||
|
||||
Negative rotate values are treated as rotating to the right by the absolute
|
||||
value of the rotation.
|
||||
[example:negative_rotation_int]
|
||||
)",
|
||||
.examples{
|
||||
{"simple_int", "SELECT arrayRotateLeft([1, 2, 3, 4, 5], 3)", "[4, 5, 1, 2, 3]"},
|
||||
{"simple_string", "SELECT arrayRotateLeft(['a', 'b', 'c', 'd', 'e'], 3)", "['d', 'e', 'a', 'b', 'c']"},
|
||||
{"simple_array", "SELECT arrayRotateLeft([[1, 2], [3, 4], [5, 6]], 2)", "[[5, 6], [1, 2], [3, 4]]"},
|
||||
{"simple_nested_array",
|
||||
"SELECT arrayRotateLeft([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], 1)",
|
||||
"[[[5, 6], [7, 8]], [[1, 2], [3, 4]]]"},
|
||||
{"negative_rotation_int", "SELECT arrayRotateLeft([1, 2, 3, 4, 5], -3)", "[3, 4, 5, 1, 2]"},
|
||||
{"overflow_int", "SELECT arrayRotateLeft([1, 2, 3, 4, 5], 8)", "[4, 5, 1, 2, 3]"},
|
||||
|
||||
},
|
||||
.categories = {"Array"},
|
||||
});
|
||||
factory.registerFunction<FunctionArrayRotateRight>(
|
||||
FunctionDocumentation{
|
||||
.description = R"(
|
||||
Returns an array of the same size as the original array with elements rotated
|
||||
to the right by the specified number of positions.
|
||||
[example:simple_int]
|
||||
[example:overflow_int]
|
||||
[example:simple_string]
|
||||
[example:simple_array]
|
||||
[example:simple_nested_array]
|
||||
|
||||
Negative rotate values are treated as rotating to the left by the absolute
|
||||
value of the rotation.
|
||||
[example:negative_rotation_int]
|
||||
)",
|
||||
.examples{
|
||||
{"simple_int", "SELECT arrayRotateRight([1, 2, 3, 4, 5], 3)", "[3, 4, 5, 1, 2]"},
|
||||
{"simple_string", "SELECT arrayRotateRight(['a', 'b', 'c', 'd', 'e'], 3)", "['c', 'd', 'e', 'a', 'b']"},
|
||||
{"simple_array", "SELECT arrayRotateRight([[1, 2], [3, 4], [5, 6]], 2)", "[[3, 4], [5, 6], [1, 2]]"},
|
||||
{"simple_nested_array",
|
||||
"SELECT arrayRotateRight([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], 1)",
|
||||
"[[[7, 8], [1, 2]], [[3, 4], [5, 6]]]"},
|
||||
{"negative_rotation_int", "SELECT arrayRotateRight([1, 2, 3, 4, 5], -3)", "[4, 5, 1, 2, 3]"},
|
||||
{"overflow_int", "SELECT arrayRotateRight([1, 2, 3, 4, 5], 8)", "[4, 5, 1, 2, 3]"},
|
||||
},
|
||||
.categories = {"Array"},
|
||||
});
|
||||
factory.registerFunction<FunctionArrayShiftLeft>(
|
||||
FunctionDocumentation{
|
||||
.description = R"(
|
||||
Returns an array of the same size as the original array with elements shifted
|
||||
to the left by the specified number of positions. New elements are filled with
|
||||
provided default values or default values of the corresponding type.
|
||||
[example:simple_int]
|
||||
[example:overflow_int]
|
||||
[example:simple_string]
|
||||
[example:simple_array]
|
||||
[example:simple_nested_array]
|
||||
|
||||
Negative shift values are treated as shifting to the right by the absolute
|
||||
value of the shift.
|
||||
[example:negative_shift_int]
|
||||
|
||||
The default value must be of the same type as the array elements.
|
||||
[example:simple_int_with_default]
|
||||
[example:simple_string_with_default]
|
||||
[example:simple_array_with_default]
|
||||
[example:casted_array_with_default]
|
||||
)",
|
||||
.examples{
|
||||
{"simple_int", "SELECT arrayShiftLeft([1, 2, 3, 4, 5], 3)", "[4, 5, 0, 0, 0]"},
|
||||
{"negative_shift_int", "SELECT arrayShiftLeft([1, 2, 3, 4, 5], -3)", "[0, 0, 0, 1, 2]"},
|
||||
{"overflow_int", "SELECT arrayShiftLeft([1, 2, 3, 4, 5], 8)", "[0, 0, 0, 0, 0]"},
|
||||
{"simple_string", "SELECT arrayShiftLeft(['a', 'b', 'c', 'd', 'e'], 3)", "['d', 'e', '', '', '']"},
|
||||
{"simple_array", "SELECT arrayShiftLeft([[1, 2], [3, 4], [5, 6]], 2)", "[[5, 6], [], []]"},
|
||||
{"simple_nested_array", "SELECT arrayShiftLeft([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], 1)", "[[[5, 6], [7, 8]], []]"},
|
||||
{"simple_int_with_default", "SELECT arrayShiftLeft([1, 2, 3, 4, 5], 3, 7)", "[4, 5, 7, 7, 7]"},
|
||||
{"simple_string_with_default", "SELECT arrayShiftLeft(['a', 'b', 'c', 'd', 'e'], 3, 'foo')", "['d', 'e', 'foo', 'foo', 'foo']"},
|
||||
{"simple_array_with_default", "SELECT arrayShiftLeft([[1, 2], [3, 4], [5, 6]], 2, [7, 8])", "[[5, 6], [7, 8], [7, 8]]"},
|
||||
{"casted_array_with_default",
|
||||
"SELECT arrayShiftLeft(CAST('[1, 2, 3, 4, 5, 6]', 'Array(UInt16)'), 1, 1000)",
|
||||
"[2, 3, 4, 5, 6, 1000]"},
|
||||
},
|
||||
.categories = {"Array"},
|
||||
});
|
||||
factory.registerFunction<FunctionArrayShiftRight>(
|
||||
FunctionDocumentation{
|
||||
.description = R"(
|
||||
Returns an array of the same size as the original array with elements shifted
|
||||
to the right by the specified number of positions. New elements are filled with
|
||||
provided default values or default values of the corresponding type.
|
||||
[example:simple_int]
|
||||
[example:overflow_int]
|
||||
[example:simple_string]
|
||||
[example:simple_array]
|
||||
[example:simple_nested_array]
|
||||
|
||||
Negative shift values are treated as shifting to the left by the absolute
|
||||
value of the shift.
|
||||
[example:negative_shift_int]
|
||||
|
||||
The default value must be of the same type as the array elements.
|
||||
[example:simple_int_with_default]
|
||||
[example:simple_string_with_default]
|
||||
[example:simple_array_with_default]
|
||||
[example:casted_array_with_default]
|
||||
)",
|
||||
.examples{
|
||||
{"simple_int", "SELECT arrayShiftRight([1, 2, 3, 4, 5], 3)", "[0, 0, 0, 1, 2]"},
|
||||
{"negative_shift_int", "SELECT arrayShiftRight([1, 2, 3, 4, 5], -3)", "[4, 5, 0, 0, 0]"},
|
||||
{"overflow_int", "SELECT arrayShiftRight([1, 2, 3, 4, 5], 8)", "[0, 0, 0, 0, 0]"},
|
||||
{"simple_string", "SELECT arrayShiftRight(['a', 'b', 'c', 'd', 'e'], 3)", "['', '', '', 'a', 'b']"},
|
||||
{"simple_array", "SELECT arrayShiftRight([[1, 2], [3, 4], [5, 6]], 2)", "[[], [], [1, 2]]"},
|
||||
{"simple_nested_array", "SELECT arrayShiftRight([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], 1)", "[[], [[1, 2], [3, 4]]]"},
|
||||
{"simple_int_with_default", "SELECT arrayShiftRight([1, 2, 3, 4, 5], 3, 7)", "[7, 7, 7, 1, 2]"},
|
||||
{"simple_string_with_default",
|
||||
"SELECT arrayShiftRight(['a', 'b', 'c', 'd', 'e'], 3, 'foo')",
|
||||
"['foo', 'foo', 'foo', 'a', 'b']"},
|
||||
{"simple_array_with_default", "SELECT arrayShiftRight([[1, 2], [3, 4], [5, 6]], 2, [7, 8])", "[[7, 8], [7, 8], [1, 2]]"},
|
||||
{"casted_array_with_default",
|
||||
"SELECT arrayShiftRight(CAST('[1, 2, 3, 4, 5, 6]', 'Array(UInt16)'), 1, 1000)",
|
||||
"[1000, 1, 2, 3, 4, 5]"},
|
||||
},
|
||||
.categories = {"Array"},
|
||||
});
|
||||
}
|
||||
|
||||
}
|
115
tests/queries/0_stateless/02845_arrayShiftRotate.reference
Normal file
115
tests/queries/0_stateless/02845_arrayShiftRotate.reference
Normal file
@ -0,0 +1,115 @@
|
||||
== arrayRotateLeft
|
||||
[3,4,5,1,2]
|
||||
[4,5,1,2,3]
|
||||
[4,5,1,2,3]
|
||||
['l','l','o','H','e']
|
||||
[[[5,6],[7,8]],[[1,2],[3,4]]]
|
||||
|
||||
== arrayRotateRight
|
||||
[4,5,1,2,3]
|
||||
[3,4,5,1,2]
|
||||
[3,4,5,1,2]
|
||||
['l','o','H','e','l']
|
||||
[[[5,6],[7,8]],[[1,2],[3,4]]]
|
||||
|
||||
== arrayShiftLeft
|
||||
[4,5,0,0,0]
|
||||
[0,0,0,1,2]
|
||||
[0,0,0,0,0]
|
||||
['d','e','','','']
|
||||
[[5,6],[],[]]
|
||||
[[[5,6],[7,8]],[]]
|
||||
[4,5,7,7,7]
|
||||
['d','e','foo','foo','foo']
|
||||
[[5,6],[7,8],[7,8]]
|
||||
[2,3,4,5,6,1000]
|
||||
|
||||
== arrayShiftRight
|
||||
[0,0,0,1,2]
|
||||
[4,5,0,0,0]
|
||||
[0,0,0,0,0]
|
||||
['','','','a','b']
|
||||
[[],[],[1,2]]
|
||||
[[],[[1,2],[3,4]]]
|
||||
[7,7,7,1,2]
|
||||
['foo','foo','foo','a','b']
|
||||
[[7,8],[7,8],[1,2]]
|
||||
[1000,1,2,3,4,5]
|
||||
|
||||
== table
|
||||
== table with constants
|
||||
-- arrayRotateLeft
|
||||
[3,4,5,6,1,2]
|
||||
[3,4,5,6,1,2]
|
||||
[3,4,1,2]
|
||||
[15,16,23,42,4,8]
|
||||
[18,28,18,28,45,90,45,2,7]
|
||||
[159,26,5,3,14]
|
||||
-- arrayRotateRight
|
||||
[5,6,1,2,3,4]
|
||||
[5,6,1,2,3,4]
|
||||
[3,4,1,2]
|
||||
[23,42,4,8,15,16]
|
||||
[90,45,2,7,18,28,18,28,45]
|
||||
[26,5,3,14,159]
|
||||
-- arrayShiftLeft
|
||||
[4,5,6,0,0,0]
|
||||
[4,5,6,0,0,0]
|
||||
[4,0,0,0]
|
||||
[16,23,42,0,0,0]
|
||||
[28,18,28,45,90,45,0,0,0]
|
||||
[26,5,0,0,0]
|
||||
-- arrayShiftRight
|
||||
[0,0,0,1,2,3]
|
||||
[0,0,0,1,2,3]
|
||||
[0,0,0,1]
|
||||
[0,0,0,4,8,15]
|
||||
[0,0,0,2,7,18,28,18,28]
|
||||
[0,0,0,3,14]
|
||||
== table with constants and defaults
|
||||
-- arrayShiftLeft
|
||||
[4,5,6,7,7,7]
|
||||
[4,5,6,7,7,7]
|
||||
[4,7,7,7]
|
||||
[16,23,42,7,7,7]
|
||||
[28,18,28,45,90,45,7,7,7]
|
||||
[26,5,7,7,7]
|
||||
-- arrayShiftRight
|
||||
[7,7,7,1,2,3]
|
||||
[7,7,7,1,2,3]
|
||||
[7,7,7,1]
|
||||
[7,7,7,4,8,15]
|
||||
[7,7,7,2,7,18,28,18,28]
|
||||
[7,7,7,3,14]
|
||||
== table values
|
||||
-- arrayRotateLeft
|
||||
[3,4,5,6,1,2]
|
||||
[4,5,6,1,2,3]
|
||||
[4,1,2,3]
|
||||
[42,4,8,15,16,23]
|
||||
[90,45,2,7,18,28,18,28,45]
|
||||
[14,159,26,5,3]
|
||||
-- arrayRotateRight
|
||||
[5,6,1,2,3,4]
|
||||
[4,5,6,1,2,3]
|
||||
[2,3,4,1]
|
||||
[8,15,16,23,42,4]
|
||||
[18,28,18,28,45,90,45,2,7]
|
||||
[5,3,14,159,26]
|
||||
-- arrayShiftLeft
|
||||
[3,4,5,6,1,1]
|
||||
[4,5,6,2,2,2]
|
||||
[4,3,3,3]
|
||||
[42,4,4,4,4,4]
|
||||
[90,45,5,5,5,5,5,5,5]
|
||||
[6,6,6,6,6]
|
||||
-- arrayShiftRight
|
||||
[1,1,1,2,3,4]
|
||||
[2,2,2,1,2,3]
|
||||
[3,3,3,1]
|
||||
[4,4,4,4,4,4]
|
||||
[5,5,5,5,5,5,5,2,7]
|
||||
[6,6,6,6,6]
|
||||
== problematic cast cases
|
||||
[5]
|
||||
[[]]
|
78
tests/queries/0_stateless/02845_arrayShiftRotate.sql
Normal file
78
tests/queries/0_stateless/02845_arrayShiftRotate.sql
Normal file
@ -0,0 +1,78 @@
|
||||
select '== arrayRotateLeft';
|
||||
select arrayRotateLeft([1,2,3,4,5], 2);
|
||||
select arrayRotateLeft([1,2,3,4,5], -2);
|
||||
select arrayRotateLeft([1,2,3,4,5], 8);
|
||||
select arrayRotateLeft(['H', 'e', 'l', 'l', 'o'], 2);
|
||||
select arrayRotateLeft([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], 1);
|
||||
select '';
|
||||
|
||||
select '== arrayRotateRight';
|
||||
select arrayRotateRight([1,2,3,4,5], 2);
|
||||
select arrayRotateRight([1,2,3,4,5], -2);
|
||||
select arrayRotateRight([1,2,3,4,5], 8);
|
||||
select arrayRotateRight(['H', 'e', 'l', 'l', 'o'], 2);
|
||||
select arrayRotateRight([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], 1);
|
||||
select '';
|
||||
|
||||
select '== arrayShiftLeft';
|
||||
select arrayShiftLeft([1, 2, 3, 4, 5], 3);
|
||||
select arrayShiftLeft([1, 2, 3, 4, 5], -3);
|
||||
select arrayShiftLeft([1, 2, 3, 4, 5], 8);
|
||||
select arrayShiftLeft(['a', 'b', 'c', 'd', 'e'], 3);
|
||||
select arrayShiftLeft([[1, 2], [3, 4], [5, 6]], 2);
|
||||
select arrayShiftLeft([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], 1);
|
||||
select arrayShiftLeft([1, 2, 3, 4, 5], 3, 7);
|
||||
select arrayShiftLeft(['a', 'b', 'c', 'd', 'e'], 3, 'foo');
|
||||
select arrayShiftLeft([[1, 2], [3, 4], [5, 6]], 2, [7, 8]);
|
||||
select arrayShiftLeft(CAST('[1, 2, 3, 4, 5, 6]', 'Array(UInt16)'), 1, 1000);
|
||||
select '';
|
||||
|
||||
select '== arrayShiftRight';
|
||||
select arrayShiftRight([1, 2, 3, 4, 5], 3);
|
||||
select arrayShiftRight([1, 2, 3, 4, 5], -3);
|
||||
select arrayShiftRight([1, 2, 3, 4, 5], 8);
|
||||
select arrayShiftRight(['a', 'b', 'c', 'd', 'e'], 3);
|
||||
select arrayShiftRight([[1, 2], [3, 4], [5, 6]], 2);
|
||||
select arrayShiftRight([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], 1);
|
||||
select arrayShiftRight([1, 2, 3, 4, 5], 3, 7);
|
||||
select arrayShiftRight(['a', 'b', 'c', 'd', 'e'], 3, 'foo');
|
||||
select arrayShiftRight([[1, 2], [3, 4], [5, 6]], 2, [7, 8]);
|
||||
select arrayShiftRight(CAST('[1, 2, 3, 4, 5, 6]', 'Array(UInt16)'), 1, 1000);
|
||||
select '';
|
||||
|
||||
select '== table';
|
||||
drop table if exists t02845;
|
||||
create table t02845 (a Array(UInt8), s Int16, d UInt8) engine = MergeTree order by d;
|
||||
insert into t02845 values ([1,2,3,4,5,6], 2, 1),([1,2,3,4,5,6], 3, 2),([1,2,3,4], 3, 3),([4,8,15,16,23,42], 5, 4),([2, 7, 18, 28, 18, 28, 45, 90, 45], 7, 5),([3, 14, 159, 26, 5], 11, 6);
|
||||
|
||||
select '== table with constants';
|
||||
select '-- arrayRotateLeft';
|
||||
select arrayRotateLeft(a, 2) from t02845;
|
||||
select '-- arrayRotateRight';
|
||||
select arrayRotateRight(a, 2) from t02845;
|
||||
select '-- arrayShiftLeft';
|
||||
select arrayShiftLeft(a, 3) from t02845;
|
||||
select '-- arrayShiftRight';
|
||||
select arrayShiftRight(a, 3) from t02845;
|
||||
|
||||
select '== table with constants and defaults';
|
||||
select '-- arrayShiftLeft';
|
||||
select arrayShiftLeft(a, 3, 7) from t02845;
|
||||
select '-- arrayShiftRight';
|
||||
select arrayShiftRight(a, 3, 7) from t02845;
|
||||
|
||||
select '== table values';
|
||||
select '-- arrayRotateLeft';
|
||||
select arrayRotateLeft(a, s) from t02845;
|
||||
select '-- arrayRotateRight';
|
||||
select arrayRotateRight(a, s) from t02845;
|
||||
select '-- arrayShiftLeft';
|
||||
select arrayShiftLeft(a, s, d) from t02845;
|
||||
select '-- arrayShiftRight';
|
||||
select arrayShiftRight(a, s, d) from t02845;
|
||||
|
||||
select '== problematic cast cases';
|
||||
select arrayShiftLeft([30000], 3, 5);
|
||||
select arrayShiftLeft([[1]], 3, []);
|
||||
select arrayShiftLeft(['foo'], 3, 3); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
select arrayShiftLeft([1], 3, 'foo'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
@ -1063,6 +1063,10 @@ arrayReverse
|
||||
arrayReverseFill
|
||||
arrayReverseSort
|
||||
arrayReverseSplit
|
||||
arrayRotateLeft
|
||||
arrayRotateRight
|
||||
arrayShiftLeft
|
||||
arrayShiftRight
|
||||
arraySlice
|
||||
arraySort
|
||||
arraySplit
|
||||
|
Loading…
Reference in New Issue
Block a user