mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-11 17:02:25 +00:00
dbms: no exception on zero index, added to the test [METR-10798]
This commit is contained in:
parent
e48c3d7b5e
commit
a670bd654b
@ -189,7 +189,8 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
struct ArrayElementNumImpl
|
struct ArrayElementNumImpl
|
||||||
{
|
{
|
||||||
/** Если negative = false - передаётся индекс с начала массива, начиная с нуля.
|
/** Процедура для константного идекса
|
||||||
|
* Если negative = false - передаётся индекс с начала массива, начиная с нуля.
|
||||||
* Если negative = true - передаётся индекс с конца массива, начиная с нуля.
|
* Если negative = true - передаётся индекс с конца массива, начиная с нуля.
|
||||||
*/
|
*/
|
||||||
template <bool negative>
|
template <bool negative>
|
||||||
@ -215,6 +216,9 @@ struct ArrayElementNumImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Процедура для неконстантного идекса
|
||||||
|
* index_type - тип данных идекса
|
||||||
|
*/
|
||||||
template <typename index_type>
|
template <typename index_type>
|
||||||
static void vector(
|
static void vector(
|
||||||
const PODArray<T> & data, const ColumnArray::Offsets_t & offsets,
|
const PODArray<T> & data, const ColumnArray::Offsets_t & offsets,
|
||||||
@ -232,9 +236,7 @@ struct ArrayElementNumImpl
|
|||||||
if (index[i].getType() == Field::Types::UInt64)
|
if (index[i].getType() == Field::Types::UInt64)
|
||||||
{
|
{
|
||||||
UInt64 cur_id = safeGet<UInt64>(index[i]);
|
UInt64 cur_id = safeGet<UInt64>(index[i]);
|
||||||
if (cur_id == 0)
|
if (cur_id > 0 && cur_id <= array_size)
|
||||||
throw Exception("Array indices is 1-based", ErrorCodes::ZERO_ARRAY_OR_TUPLE_INDEX);
|
|
||||||
else if (cur_id <= array_size)
|
|
||||||
result[i] = data[current_offset + cur_id - 1];
|
result[i] = data[current_offset + cur_id - 1];
|
||||||
else
|
else
|
||||||
result[i] = T();
|
result[i] = T();
|
||||||
@ -242,9 +244,7 @@ struct ArrayElementNumImpl
|
|||||||
else if (index[i].getType() == Field::Types::Int64)
|
else if (index[i].getType() == Field::Types::Int64)
|
||||||
{
|
{
|
||||||
Int64 cur_id = safeGet<Int64>(index[i]);
|
Int64 cur_id = safeGet<Int64>(index[i]);
|
||||||
if (cur_id == 0)
|
if (cur_id > 0 && cur_id <= array_size)
|
||||||
throw Exception("Array indices is 1-based", ErrorCodes::ZERO_ARRAY_OR_TUPLE_INDEX);
|
|
||||||
else if (cur_id > 0 && cur_id <= array_size)
|
|
||||||
result[i] = data[current_offset + cur_id - 1];
|
result[i] = data[current_offset + cur_id - 1];
|
||||||
else if (cur_id < 0 && -cur_id <= array_size)
|
else if (cur_id < 0 && -cur_id <= array_size)
|
||||||
result[i] = data[offsets[i] + cur_id];
|
result[i] = data[offsets[i] + cur_id];
|
||||||
@ -261,6 +261,10 @@ struct ArrayElementNumImpl
|
|||||||
|
|
||||||
struct ArrayElementStringImpl
|
struct ArrayElementStringImpl
|
||||||
{
|
{
|
||||||
|
/** Процедура для константного идекса
|
||||||
|
* Если negative = false - передаётся индекс с начала массива, начиная с нуля.
|
||||||
|
* Если negative = true - передаётся индекс с конца массива, начиная с нуля.
|
||||||
|
*/
|
||||||
template <bool negative>
|
template <bool negative>
|
||||||
static void vectorConst(
|
static void vectorConst(
|
||||||
const ColumnString::Chars_t & data, const ColumnArray::Offsets_t & offsets, const ColumnString::Offsets_t & string_offsets,
|
const ColumnString::Chars_t & data, const ColumnArray::Offsets_t & offsets, const ColumnString::Offsets_t & string_offsets,
|
||||||
@ -305,6 +309,9 @@ struct ArrayElementStringImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Процедура для неконстантного идекса
|
||||||
|
* index_type - тип данных идекса
|
||||||
|
*/
|
||||||
template <typename index_type>
|
template <typename index_type>
|
||||||
static void vector(
|
static void vector(
|
||||||
const ColumnString::Chars_t & data, const ColumnArray::Offsets_t & offsets, const ColumnString::Offsets_t & string_offsets,
|
const ColumnString::Chars_t & data, const ColumnArray::Offsets_t & offsets, const ColumnString::Offsets_t & string_offsets,
|
||||||
@ -325,10 +332,10 @@ struct ArrayElementStringImpl
|
|||||||
if (index[i].getType() == Field::Types::UInt64)
|
if (index[i].getType() == Field::Types::UInt64)
|
||||||
{
|
{
|
||||||
UInt64 cur_id = safeGet<UInt64>(index[i]);
|
UInt64 cur_id = safeGet<UInt64>(index[i]);
|
||||||
if (cur_id == 0)
|
if (cur_id > 0 && cur_id <= array_size)
|
||||||
adjusted_index = array_size; /// Индекс не вписывается в рамки массива, заменяем заведомо слишком большим
|
|
||||||
else
|
|
||||||
adjusted_index = cur_id - 1;
|
adjusted_index = cur_id - 1;
|
||||||
|
else
|
||||||
|
adjusted_index = array_size; /// Индекс не вписывается в рамки массива, заменяем заведомо слишком большим
|
||||||
}
|
}
|
||||||
else if (index[i].getType() == Field::Types::Int64)
|
else if (index[i].getType() == Field::Types::Int64)
|
||||||
{
|
{
|
||||||
@ -577,7 +584,6 @@ private:
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const
|
||||||
|
@ -3,23 +3,28 @@
|
|||||||
13
|
13
|
||||||
11
|
11
|
||||||
0
|
0
|
||||||
|
0
|
||||||
12
|
12
|
||||||
0
|
0
|
||||||
11
|
11
|
||||||
0
|
0
|
||||||
|
0
|
||||||
Df
|
Df
|
||||||
|
|
||||||
ERT
|
ERT
|
||||||
Ab
|
Ab
|
||||||
|
|
||||||
|
|
||||||
Df
|
Df
|
||||||
|
|
||||||
ABC
|
ABC
|
||||||
|
|
||||||
|
|
||||||
[1,2,3] 2
|
[1,2,3] 2
|
||||||
[1,2,3] 1
|
[1,2,3] 1
|
||||||
[1,2,3] 0
|
[1,2,3] 0
|
||||||
[1,2,3] 3
|
[1,2,3] 3
|
||||||
|
[1,2,3] 0
|
||||||
[1,2,3] 2
|
[1,2,3] 2
|
||||||
[1,2,3] 1
|
[1,2,3] 1
|
||||||
[1,2,3] 0
|
[1,2,3] 0
|
||||||
@ -28,3 +33,4 @@ ABC
|
|||||||
[1,2,3] 3
|
[1,2,3] 3
|
||||||
[1,2,3] 0
|
[1,2,3] 0
|
||||||
[1,2,3] 1
|
[1,2,3] 1
|
||||||
|
[1,2,3] 0
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
DROP TABLE IF EXISTS array_element_test;
|
DROP TABLE IF EXISTS array_element_test;
|
||||||
CREATE TABLE array_element_test (arr Array(Int32), id Int32) ENGINE = Memory;
|
CREATE TABLE array_element_test (arr Array(Int32), id Int32) ENGINE = Memory;
|
||||||
insert into array_element_test VALUES ([11,12,13], 2), ([11,12], 3), ([11,12,13], -1), ([11,12], -2), ([11,12], -3);
|
insert into array_element_test VALUES ([11,12,13], 2), ([11,12], 3), ([11,12,13], -1), ([11,12], -2), ([11,12], -3), ([11], 0);
|
||||||
select arr[id] from array_element_test;
|
select arr[id] from array_element_test;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS array_element_test;
|
DROP TABLE IF EXISTS array_element_test;
|
||||||
CREATE TABLE array_element_test (arr Array(Int32), id UInt32) ENGINE = Memory;
|
CREATE TABLE array_element_test (arr Array(Int32), id UInt32) ENGINE = Memory;
|
||||||
insert into array_element_test VALUES ([11,12,13], 2), ([11,12], 3), ([11,12,13], 1), ([11,12], 4);
|
insert into array_element_test VALUES ([11,12,13], 2), ([11,12], 3), ([11,12,13], 1), ([11,12], 4), ([11], 0);
|
||||||
select arr[id] from array_element_test;
|
select arr[id] from array_element_test;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS array_element_test;
|
DROP TABLE IF EXISTS array_element_test;
|
||||||
CREATE TABLE array_element_test (arr Array(String), id Int32) ENGINE = Memory;
|
CREATE TABLE array_element_test (arr Array(String), id Int32) ENGINE = Memory;
|
||||||
insert into array_element_test VALUES (['Abc','Df','Q'], 2), (['Abc','DEFQ'], 3), (['ABC','Q','ERT'], -1), (['Ab','ber'], -2), (['AB','asd'], -3);
|
insert into array_element_test VALUES (['Abc','Df','Q'], 2), (['Abc','DEFQ'], 3), (['ABC','Q','ERT'], -1), (['Ab','ber'], -2), (['AB','asd'], -3), (['A'], 0);
|
||||||
select arr[id] from array_element_test;
|
select arr[id] from array_element_test;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS array_element_test;
|
DROP TABLE IF EXISTS array_element_test;
|
||||||
CREATE TABLE array_element_test (arr Array(String), id UInt32) ENGINE = Memory;
|
CREATE TABLE array_element_test (arr Array(String), id UInt32) ENGINE = Memory;
|
||||||
insert into array_element_test VALUES (['Abc','Df','Q'], 2), (['Abc','DEFQ'], 3), (['ABC','Q','ERT'], 1), (['Ab','ber'], 4);
|
insert into array_element_test VALUES (['Abc','Df','Q'], 2), (['Abc','DEFQ'], 3), (['ABC','Q','ERT'], 1), (['Ab','ber'], 4), (['A'], 0);
|
||||||
select arr[id] from array_element_test;
|
select arr[id] from array_element_test;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS array_element_test;
|
DROP TABLE IF EXISTS array_element_test;
|
||||||
CREATE TABLE array_element_test (id UInt32) ENGINE = Memory;
|
CREATE TABLE array_element_test (id UInt32) ENGINE = Memory;
|
||||||
insert into array_element_test VALUES (2), (1), (4), (3);
|
insert into array_element_test VALUES (2), (1), (4), (3), (0);
|
||||||
select [1, 2, 3] as arr, arr[id] from array_element_test;
|
select [1, 2, 3] as arr, arr[id] from array_element_test;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS array_element_test;
|
DROP TABLE IF EXISTS array_element_test;
|
||||||
CREATE TABLE array_element_test (id Int32) ENGINE = Memory;
|
CREATE TABLE array_element_test (id Int32) ENGINE = Memory;
|
||||||
insert into array_element_test VALUES (-2), (1), (-4), (3), (2), (-1), (4), (-3);
|
insert into array_element_test VALUES (-2), (1), (-4), (3), (2), (-1), (4), (-3), (0);
|
||||||
select [1, 2, 3] as arr, arr[id] from array_element_test;
|
select [1, 2, 3] as arr, arr[id] from array_element_test;
|
||||||
|
|
||||||
DROP TABLE IF EXISTS array_element_test;
|
DROP TABLE IF EXISTS array_element_test;
|
||||||
|
Loading…
Reference in New Issue
Block a user