Support for NULLs in function if: continued [#CLICKHOUSE-2873].

This commit is contained in:
Alexey Milovidov 2017-03-09 06:34:09 +03:00
parent 169fc988b7
commit f9a5902e76
28 changed files with 1665 additions and 1751 deletions

View File

@ -1,14 +1,7 @@
#pragma once
#include <string.h> // memcpy
#include <DB/Common/Exception.h>
#include <DB/Common/Arena.h>
#include <DB/Common/SipHash.h>
#include <DB/Columns/IColumn.h>
#include <DB/Columns/ColumnsNumber.h>
#include <DB/Columns/ColumnString.h>
#include <DB/Columns/ColumnVector.h>
namespace DB
@ -32,261 +25,35 @@ public:
using ColumnOffsets_t = ColumnVector<Offset_t>;
/** Создать пустой столбец массивов, с типом значений, как в столбце nested_column */
explicit ColumnArray(ColumnPtr nested_column, ColumnPtr offsets_column = nullptr)
: data(nested_column), offsets(offsets_column)
{
if (!offsets_column)
{
offsets = std::make_shared<ColumnOffsets_t>();
}
else
{
if (!typeid_cast<ColumnOffsets_t *>(&*offsets_column))
throw Exception("offsets_column must be a ColumnUInt64", ErrorCodes::ILLEGAL_COLUMN);
}
if (nested_column->isConst())
throw Exception{"ColumnArray cannot have constant nested column", ErrorCodes::LOGICAL_ERROR};
}
std::string getName() const override { return "ColumnArray(" + getData().getName() + ")"; }
ColumnPtr cloneResized(size_t size) const override
{
ColumnPtr new_col_holder = std::make_shared<ColumnArray>(getData().cloneEmpty());
if (size > 0)
{
auto & new_col = static_cast<ColumnArray &>(*new_col_holder);
size_t count = std::min(this->size(), size);
/// First create the offsets.
const auto & from_offsets = getOffsets();
auto & new_offsets = new_col.getOffsets();
new_offsets.resize(size);
new_offsets.assign(from_offsets.begin(), from_offsets.begin() + count);
if (size > count)
{
for (size_t i = count; i < size; ++i)
new_offsets[i] = new_offsets[i - 1];
}
/// Then store the data.
new_col.getData().insertRangeFrom(getData(), 0, count);
}
return new_col_holder;
}
size_t size() const override
{
return getOffsets().size();
}
Field operator[](size_t n) const override
{
size_t offset = offsetAt(n);
size_t size = sizeAt(n);
Array res(size);
for (size_t i = 0; i < size; ++i)
res[i] = getData()[offset + i];
return res;
}
void get(size_t n, Field & res) const override
{
size_t offset = offsetAt(n);
size_t size = sizeAt(n);
res = Array(size);
Array & res_arr = DB::get<Array &>(res);
for (size_t i = 0; i < size; ++i)
getData().get(offset + i, res_arr[i]);
}
StringRef getDataAt(size_t n) const override
{
/** Возвращает диапазон памяти, покрывающий все элементы массива.
* Работает для массивов значений фиксированной длины.
* Для массивов строк и массивов массивов полученный кусок памяти может не взаимно-однозначно соответствовать элементам,
* так как содержит лишь уложенные подряд данные, но не смещения.
*/
size_t array_size = sizeAt(n);
if (array_size == 0)
return StringRef();
size_t offset_of_first_elem = offsetAt(n);
StringRef first = getData().getDataAtWithTerminatingZero(offset_of_first_elem);
size_t offset_of_last_elem = getOffsets()[n] - 1;
StringRef last = getData().getDataAtWithTerminatingZero(offset_of_last_elem);
return StringRef(first.data, last.data + last.size - first.data);
}
void insertData(const char * pos, size_t length) override
{
/** Аналогично - только для массивов значений фиксированной длины.
*/
IColumn * data_ = data.get();
if (!data_->isFixed())
throw Exception("Method insertData is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED);
size_t field_size = data_->sizeOfField();
const char * end = pos + length;
size_t elems = 0;
for (; pos + field_size <= end; pos += field_size, ++elems)
data_->insertData(pos, field_size);
if (pos != end)
throw Exception("Incorrect length argument for method ColumnArray::insertData", ErrorCodes::BAD_ARGUMENTS);
getOffsets().push_back((getOffsets().size() == 0 ? 0 : getOffsets().back()) + elems);
}
StringRef serializeValueIntoArena(size_t n, Arena & arena, char const *& begin) const override
{
size_t array_size = sizeAt(n);
size_t offset = offsetAt(n);
char * pos = arena.allocContinue(sizeof(array_size), begin);
memcpy(pos, &array_size, sizeof(array_size));
size_t values_size = 0;
for (size_t i = 0; i < array_size; ++i)
values_size += getData().serializeValueIntoArena(offset + i, arena, begin).size;
return StringRef(begin, sizeof(array_size) + values_size);
}
const char * deserializeAndInsertFromArena(const char * pos) override
{
size_t array_size = *reinterpret_cast<const size_t *>(pos);
pos += sizeof(array_size);
for (size_t i = 0; i < array_size; ++i)
pos = getData().deserializeAndInsertFromArena(pos);
getOffsets().push_back((getOffsets().size() == 0 ? 0 : getOffsets().back()) + array_size);
return pos;
}
void updateHashWithValue(size_t n, SipHash & hash) const override
{
size_t array_size = sizeAt(n);
size_t offset = offsetAt(n);
hash.update(reinterpret_cast<const char *>(&array_size), sizeof(array_size));
for (size_t i = 0; i < array_size; ++i)
getData().updateHashWithValue(offset + i, hash);
}
explicit ColumnArray(ColumnPtr nested_column, ColumnPtr offsets_column = nullptr);
std::string getName() const override;
ColumnPtr cloneResized(size_t size) const override;
size_t size() const override;
Field operator[](size_t n) const override;
void get(size_t n, Field & res) const override;
StringRef getDataAt(size_t n) const override;
void insertData(const char * pos, size_t length) override;
StringRef serializeValueIntoArena(size_t n, Arena & arena, char const *& begin) const override;
const char * deserializeAndInsertFromArena(const char * pos) override;
void updateHashWithValue(size_t n, SipHash & hash) const override;
void insertRangeFrom(const IColumn & src, size_t start, size_t length) override;
void insert(const Field & x) override
{
const Array & array = DB::get<const Array &>(x);
size_t size = array.size();
for (size_t i = 0; i < size; ++i)
getData().insert(array[i]);
getOffsets().push_back((getOffsets().size() == 0 ? 0 : getOffsets().back()) + size);
}
void insertFrom(const IColumn & src_, size_t n) override
{
const ColumnArray & src = static_cast<const ColumnArray &>(src_);
size_t size = src.sizeAt(n);
size_t offset = src.offsetAt(n);
getData().insertRangeFrom(src.getData(), offset, size);
getOffsets().push_back((getOffsets().size() == 0 ? 0 : getOffsets().back()) + size);
}
void insertDefault() override
{
getOffsets().push_back(getOffsets().size() == 0 ? 0 : getOffsets().back());
}
void popBack(size_t n) override
{
auto & offsets = getOffsets();
size_t nested_n = offsets.back() - offsetAt(offsets.size() - n);
if (nested_n)
getData().popBack(nested_n);
offsets.resize_assume_reserved(offsets.size() - n);
}
void insert(const Field & x) override;
void insertFrom(const IColumn & src_, size_t n) override;
void insertDefault() override;
void popBack(size_t n) override;
ColumnPtr filter(const Filter & filt, ssize_t result_size_hint) const override;
ColumnPtr permute(const Permutation & perm, size_t limit) const override;
int compareAt(size_t n, size_t m, const IColumn & rhs_, int nan_direction_hint) const override
{
const ColumnArray & rhs = static_cast<const ColumnArray &>(rhs_);
/// Не оптимально
size_t lhs_size = sizeAt(n);
size_t rhs_size = rhs.sizeAt(m);
size_t min_size = std::min(lhs_size, rhs_size);
for (size_t i = 0; i < min_size; ++i)
if (int res = getData().compareAt(offsetAt(n) + i, rhs.offsetAt(m) + i, *rhs.data.get(), nan_direction_hint))
return res;
return lhs_size < rhs_size
? -1
: (lhs_size == rhs_size
? 0
: 1);
}
template <bool positive>
struct less
{
const ColumnArray & parent;
less(const ColumnArray & parent_) : parent(parent_) {}
bool operator()(size_t lhs, size_t rhs) const
{
if (positive)
return parent.compareAt(lhs, rhs, parent, 1) < 0;
else
return parent.compareAt(lhs, rhs, parent, -1) > 0;
}
};
int compareAt(size_t n, size_t m, const IColumn & rhs_, int nan_direction_hint) const override;
void getPermutation(bool reverse, size_t limit, Permutation & res) const override;
void reserve(size_t n) override;
size_t byteSize() const override;
size_t allocatedSize() const override;
ColumnPtr replicate(const Offsets_t & replicate_offsets) const override;
ColumnPtr convertToFullColumnIfConst() const override;
void getExtremes(Field & min, Field & max) const override;
void reserve(size_t n) override
{
getOffsets().reserve(n);
getData().reserve(n); /// Средний размер массивов тут никак не учитывается. Или считается, что он не больше единицы.
}
size_t byteSize() const override
{
return getData().byteSize() + getOffsets().size() * sizeof(getOffsets()[0]);
}
size_t allocatedSize() const override
{
return getData().allocatedSize() + getOffsets().allocated_size() * sizeof(getOffsets()[0]);
}
bool hasEqualOffsets(const ColumnArray & other) const
{
if (offsets == other.offsets)
return true;
const Offsets_t & offsets1 = getOffsets();
const Offsets_t & offsets2 = other.getOffsets();
return offsets1.size() == offsets2.size() && 0 == memcmp(&offsets1[0], &offsets2[0], sizeof(offsets1[0]) * offsets1.size());
}
bool hasEqualOffsets(const ColumnArray & other) const;
/** Более эффективные методы манипуляции */
IColumn & getData() { return *data.get(); }
@ -308,38 +75,11 @@ public:
ColumnPtr & getOffsetsColumn() { return offsets; }
const ColumnPtr & getOffsetsColumn() const { return offsets; }
ColumnPtr replicate(const Offsets_t & replicate_offsets) const override;
Columns scatter(ColumnIndex num_columns, const Selector & selector) const override
{
return scatterImpl<ColumnArray>(num_columns, selector);
}
ColumnPtr convertToFullColumnIfConst() const override
{
ColumnPtr new_data;
ColumnPtr new_offsets;
if (auto full_column = getData().convertToFullColumnIfConst())
new_data = full_column;
else
new_data = data;
if (auto full_column = offsets.get()->convertToFullColumnIfConst())
new_offsets = full_column;
else
new_offsets = offsets;
return std::make_shared<ColumnArray>(new_data, new_offsets);
}
void getExtremes(Field & min, Field & max) const override
{
min = Array();
max = Array();
}
private:
ColumnPtr data;
ColumnPtr offsets; /// Смещения могут быть разделяемыми для нескольких столбцов - для реализации вложенных структур данных.

View File

@ -2,10 +2,7 @@
#include <string.h>
#include <DB/Core/Defines.h>
#include <DB/Columns/IColumn.h>
#include <DB/Columns/ColumnsCommon.h>
#include <DB/Common/PODArray.h>
#include <DB/Common/Arena.h>
#include <DB/Common/SipHash.h>
@ -18,14 +15,7 @@ class Collator;
namespace DB
{
namespace ErrorCodes
{
extern const int PARAMETER_OUT_OF_BOUND;
extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;
}
/** Cтолбeц значений типа "строка".
/** Column for String values.
*/
class ColumnString final : public IColumn
{
@ -33,24 +23,25 @@ public:
using Chars_t = PaddedPODArray<UInt8>;
private:
/// По индексу i находится смещение до начала i + 1 -го элемента.
/// Maps i'th position to offset to i+1'th element. Last offset maps to the end of all chars (is the size of all chars).
Offsets_t offsets;
/// Байты строк, уложенные подряд. Строки хранятся с завершающим нулевым байтом.
/// Bytes of strings, placed contiguously.
/// For convenience, every string ends with terminating zero byte. Note that strings could contain zero bytes in the middle.
Chars_t chars;
size_t __attribute__((__always_inline__)) offsetAt(size_t i) const { return i == 0 ? 0 : offsets[i - 1]; }
/// Размер, включая завершающий нулевой байт.
/// Size of i-th element, including terminating zero.
size_t __attribute__((__always_inline__)) sizeAt(size_t i) const { return i == 0 ? offsets[0] : (offsets[i] - offsets[i - 1]); }
template <bool positive>
friend struct lessWithCollation;
struct less;
template <bool positive>
struct lessWithCollation;
public:
/** Создать пустой столбец строк */
ColumnString() {}
std::string getName() const override { return "ColumnString"; }
size_t size() const override
@ -68,48 +59,7 @@ public:
return chars.allocated_size() + offsets.allocated_size() * sizeof(offsets[0]);
}
ColumnPtr cloneResized(size_t to_size) const override
{
auto res = std::make_shared<ColumnString>();
if (to_size == 0)
return res;
size_t from_size = size();
if (to_size <= from_size)
{
/// Just cut column.
res->offsets.assign(offsets.begin(), offsets.begin() + to_size);
res->chars.assign(chars.begin(), chars.begin() + offsets[to_size - 1]);
}
else
{
/// Copy column and append empty strings for extra elements.
Offset_t offset = 0;
if (from_size > 0)
{
res->offsets.assign(offsets.begin(), offsets.end());
res->chars.assign(chars.begin(), chars.end());
offset = offsets.back();
}
/// Empty strings are just zero terminating bytes.
res->chars.resize_fill(res->chars.size() + to_size - from_size);
res->offsets.resize(to_size);
for (size_t i = from_size; i < to_size; ++i)
{
++offset;
res->offsets[i] = offset;
}
}
return res;
}
ColumnPtr cloneResized(size_t to_size) const override;
Field operator[](size_t n) const override
{
@ -246,101 +196,11 @@ public:
hash.update(reinterpret_cast<const char *>(&chars[offset]), string_size);
}
void insertRangeFrom(const IColumn & src, size_t start, size_t length) override
{
if (length == 0)
return;
void insertRangeFrom(const IColumn & src, size_t start, size_t length) override;
const ColumnString & src_concrete = static_cast<const ColumnString &>(src);
ColumnPtr filter(const Filter & filt, ssize_t result_size_hint) const override;
if (start + length > src_concrete.offsets.size())
throw Exception("Parameter out of bound in IColumnString::insertRangeFrom method.",
ErrorCodes::PARAMETER_OUT_OF_BOUND);
size_t nested_offset = src_concrete.offsetAt(start);
size_t nested_length = src_concrete.offsets[start + length - 1] - nested_offset;
size_t old_chars_size = chars.size();
chars.resize(old_chars_size + nested_length);
memcpy(&chars[old_chars_size], &src_concrete.chars[nested_offset], nested_length);
if (start == 0 && offsets.empty())
{
offsets.assign(src_concrete.offsets.begin(), src_concrete.offsets.begin() + length);
}
else
{
size_t old_size = offsets.size();
size_t prev_max_offset = old_size ? offsets.back() : 0;
offsets.resize(old_size + length);
for (size_t i = 0; i < length; ++i)
offsets[old_size + i] = src_concrete.offsets[start + i] - nested_offset + prev_max_offset;
}
}
ColumnPtr filter(const Filter & filt, ssize_t result_size_hint) const override
{
if (offsets.size() == 0)
return std::make_shared<ColumnString>();
auto res = std::make_shared<ColumnString>();
Chars_t & res_chars = res->chars;
Offsets_t & res_offsets = res->offsets;
filterArraysImpl<UInt8>(chars, offsets, res_chars, res_offsets, filt, result_size_hint);
return res;
}
ColumnPtr permute(const Permutation & perm, size_t limit) const override
{
size_t size = offsets.size();
if (limit == 0)
limit = size;
else
limit = std::min(size, limit);
if (perm.size() < limit)
throw Exception("Size of permutation is less than required.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
if (limit == 0)
return std::make_shared<ColumnString>();
std::shared_ptr<ColumnString> res = std::make_shared<ColumnString>();
Chars_t & res_chars = res->chars;
Offsets_t & res_offsets = res->offsets;
if (limit == size)
res_chars.resize(chars.size());
else
{
size_t new_chars_size = 0;
for (size_t i = 0; i < limit; ++i)
new_chars_size += sizeAt(perm[i]);
res_chars.resize(new_chars_size);
}
res_offsets.resize(limit);
Offset_t current_new_offset = 0;
for (size_t i = 0; i < limit; ++i)
{
size_t j = perm[i];
size_t string_offset = j == 0 ? 0 : offsets[j - 1];
size_t string_size = offsets[j] - string_offset;
memcpySmallAllowReadWriteOverflow15(&res_chars[current_new_offset], &chars[string_offset], string_size);
current_new_offset += string_size;
res_offsets[i] = current_new_offset;
}
return res;
}
ColumnPtr permute(const Permutation & perm, size_t limit) const override;
void insertDefault() override
{
@ -361,117 +221,30 @@ public:
reinterpret_cast<const char *>(&rhs.chars[rhs.offsetAt(m)]));
}
/// Версия compareAt для locale-sensitive сравнения строк
/// Variant of compareAt for string comparison with respect of collation.
int compareAtWithCollation(size_t n, size_t m, const IColumn & rhs_, const Collator & collator) const;
template <bool positive>
struct less
{
const ColumnString & parent;
less(const ColumnString & parent_) : parent(parent_) {}
bool operator()(size_t lhs, size_t rhs) const
{
int res = strcmp(
reinterpret_cast<const char *>(&parent.chars[parent.offsetAt(lhs)]),
reinterpret_cast<const char *>(&parent.chars[parent.offsetAt(rhs)]));
void getPermutation(bool reverse, size_t limit, Permutation & res) const override;
return positive ? (res < 0) : (res > 0);
}
};
void getPermutation(bool reverse, size_t limit, Permutation & res) const override
{
size_t s = offsets.size();
res.resize(s);
for (size_t i = 0; i < s; ++i)
res[i] = i;
if (limit >= s)
limit = 0;
if (limit)
{
if (reverse)
std::partial_sort(res.begin(), res.begin() + limit, res.end(), less<false>(*this));
else
std::partial_sort(res.begin(), res.begin() + limit, res.end(), less<true>(*this));
}
else
{
if (reverse)
std::sort(res.begin(), res.end(), less<false>(*this));
else
std::sort(res.begin(), res.end(), less<true>(*this));
}
}
/// Сортировка с учетом Collation
/// Sorting with respect of collation.
void getPermutationWithCollation(const Collator & collator, bool reverse, size_t limit, Permutation & res) const;
ColumnPtr replicate(const Offsets_t & replicate_offsets) const override
{
size_t col_size = size();
if (col_size != replicate_offsets.size())
throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
std::shared_ptr<ColumnString> res = std::make_shared<ColumnString>();
if (0 == col_size)
return res;
Chars_t & res_chars = res->chars;
Offsets_t & res_offsets = res->offsets;
res_chars.reserve(chars.size() / col_size * replicate_offsets.back());
res_offsets.reserve(replicate_offsets.back());
Offset_t prev_replicate_offset = 0;
Offset_t prev_string_offset = 0;
Offset_t current_new_offset = 0;
for (size_t i = 0; i < col_size; ++i)
{
size_t size_to_replicate = replicate_offsets[i] - prev_replicate_offset;
size_t string_size = offsets[i] - prev_string_offset;
for (size_t j = 0; j < size_to_replicate; ++j)
{
current_new_offset += string_size;
res_offsets.push_back(current_new_offset);
res_chars.resize(res_chars.size() + string_size);
memcpySmallAllowReadWriteOverflow15(
&res_chars[res_chars.size() - string_size], &chars[prev_string_offset], string_size);
}
prev_replicate_offset = replicate_offsets[i];
prev_string_offset = offsets[i];
}
return res;
}
ColumnPtr replicate(const Offsets_t & replicate_offsets) const override;
Columns scatter(ColumnIndex num_columns, const Selector & selector) const override
{
return scatterImpl<ColumnString>(num_columns, selector);
}
void reserve(size_t n) override
{
offsets.reserve(n);
chars.reserve(n * DBMS_APPROX_STRING_SIZE);
}
void reserve(size_t n) override;
void getExtremes(Field & min, Field & max) const override;
Chars_t & getChars() { return chars; }
const Chars_t & getChars() const { return chars; }
Offsets_t & getOffsets() { return offsets; }
const Offsets_t & getOffsets() const { return offsets; }
void getExtremes(Field & min, Field & max) const override
{
min = String();
max = String();
}
};

View File

@ -7,8 +7,10 @@
#include <DB/DataTypes/DataTypeArray.h>
#include <DB/Columns/ColumnVector.h>
#include <DB/Columns/ColumnArray.h>
#include <DB/Common/memcpySmall.h>
#include <DB/Functions/NumberTraits.h>
namespace DB
{

View File

@ -699,7 +699,6 @@ private:
}
public:
/// Получить имя функции.
String getName() const override
{
return name;
@ -707,7 +706,6 @@ public:
size_t getNumberOfArguments() const override { return 2; }
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
DataTypePtr type_res;
@ -730,7 +728,6 @@ public:
return type_res;
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (!( executeLeftType<DataTypeDate>(block, arguments, result)
@ -809,7 +806,6 @@ private:
}
public:
/// Получить имя функции.
String getName() const override
{
return name;
@ -818,7 +814,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
bool isInjective(const Block &) override { return is_injective; }
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
DataTypePtr result;
@ -839,7 +834,6 @@ public:
return result;
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (!( executeType<UInt8>(block, arguments, result)

View File

@ -73,14 +73,11 @@ public:
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override;
private:
/// Получить имя функции.
String getName() const override;
bool addField(DataTypePtr type_res, const Field & f, Array & arr) const;
@ -102,15 +99,12 @@ public:
static constexpr auto name = "arrayElement";
static FunctionPtr create(const Context & context);
/// Получить имя функции.
String getName() const override;
size_t getNumberOfArguments() const override { return 2; }
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override;
private:
@ -1178,15 +1172,12 @@ public:
static constexpr auto name = "arrayEnumerate";
static FunctionPtr create(const Context & context);
/// Получить имя функции.
String getName() const override;
size_t getNumberOfArguments() const override { return 1; }
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override;
};
@ -1199,16 +1190,13 @@ public:
static constexpr auto name = "arrayUniq";
static FunctionPtr create(const Context & context);
/// Получить имя функции.
String getName() const override;
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override;
private:
@ -1242,16 +1230,13 @@ public:
static constexpr auto name = "arrayEnumerateUniq";
static FunctionPtr create(const Context & context);
/// Получить имя функции.
String getName() const override;
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override;
private:
@ -1346,15 +1331,12 @@ public:
static constexpr auto name = "emptyArrayToSingle";
static FunctionPtr create(const Context & context);
/// Получить имя функции.
String getName() const override;
size_t getNumberOfArguments() const override { return 1; }
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override;
private:
@ -1387,15 +1369,12 @@ public:
static constexpr auto name = "reverse";
static FunctionPtr create(const Context & context);
/// Получить имя функции.
String getName() const override;
size_t getNumberOfArguments() const override { return 1; }
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override;
private:
@ -1434,7 +1413,6 @@ public:
static constexpr auto name = "arrayReduce";
static FunctionPtr create(const Context & context);
/// Получить имя функции.
String getName() const override;
bool isVariadic() const override { return true; }

View File

@ -640,7 +640,6 @@ public:
static constexpr auto name = "IPv4NumToString";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionIPv4NumToString>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -649,7 +648,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
bool isInjective(const Block &) override { return true; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeUInt32 *>(&*arguments[0]))
@ -693,7 +691,6 @@ public:
*(out++) = '\0';
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnPtr & column = block.safeGetByPosition(arguments[0]).column;
@ -744,7 +741,6 @@ public:
static constexpr auto name = "IPv4StringToNum";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionIPv4StringToNum>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -752,7 +748,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]))
@ -785,7 +780,6 @@ public:
return res;
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnPtr & column = block.safeGetByPosition(arguments[0]).column;
@ -827,7 +821,6 @@ public:
static constexpr auto name = "IPv4NumToStringClassC";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionIPv4NumToStringClassC>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -835,7 +828,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeUInt32 *>(&*arguments[0]))
@ -882,7 +874,6 @@ public:
*(out++) = '\0';
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnPtr & column = block.safeGetByPosition(arguments[0]).column;
@ -1272,7 +1263,6 @@ public:
static constexpr auto name = "hex";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionHex>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -1281,7 +1271,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
bool isInjective(const Block &) override { return true; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]) &&
@ -1491,7 +1480,6 @@ public:
}
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const IColumn * column = block.safeGetByPosition(arguments[0]).column.get();
@ -1518,7 +1506,6 @@ public:
static constexpr auto name = "unhex";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionUnhex>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -1527,7 +1514,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
bool isInjective(const Block &) override { return true; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]))
@ -1561,7 +1547,6 @@ public:
*(out++) = '\0';
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnPtr & column = block.safeGetByPosition(arguments[0]).column;
@ -1624,7 +1609,6 @@ public:
static constexpr auto name = "bitmaskToArray";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionBitmaskToArray>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -1633,7 +1617,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
bool isInjective(const Block &) override { return true; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeUInt8 *>(&*arguments[0]) &&
@ -1707,7 +1690,6 @@ public:
}
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const IColumn * in_column = block.safeGetByPosition(arguments[0]).column.get();
@ -1735,7 +1717,6 @@ public:
static constexpr auto name = "toStringCutToZero";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionToStringCutToZero>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -1743,7 +1724,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeFixedString *>(&*arguments[0]) &&
@ -1854,7 +1834,6 @@ public:
}
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const IColumn * column = block.safeGetByPosition(arguments[0]).column.get();

View File

@ -776,7 +776,6 @@ private:
public:
/// Получить имя функции.
String getName() const override
{
return name;
@ -853,7 +852,6 @@ public:
return std::make_shared<DataTypeUInt8>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const auto & col_with_type_and_name_left = block.safeGetByPosition(arguments[0]);

View File

@ -1573,7 +1573,6 @@ private:
}
public:
/// Получить имя функции.
String getName() const override
{
return name;

View File

@ -670,7 +670,6 @@ public:
size_t getNumberOfArguments() const override { return 0; }
bool isInjective(const Block &) override { return std::is_same<Name, NameToString>::value; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return getReturnTypeInternal(arguments);
@ -891,7 +890,6 @@ public:
static constexpr auto name = "toFixedString";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionToFixedString>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -919,7 +917,6 @@ public:
out_return_type = std::make_shared<DataTypeFixedString>(n);
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, const size_t result) override
{
const auto n = getSize(block.safeGetByPosition(arguments[1]));

View File

@ -484,7 +484,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionDateOrDateTimeToSomething>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -493,7 +492,6 @@ public:
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() == 1)
@ -523,7 +521,6 @@ public:
return std::make_shared<ToDataType>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
IDataType * from_type = block.safeGetByPosition(arguments[0]).type.get();
@ -582,7 +579,6 @@ public:
static constexpr auto name = "now";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionNow>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -590,13 +586,11 @@ public:
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeDateTime>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
block.safeGetByPosition(result).column = std::make_shared<ColumnConstUInt32>(
@ -612,7 +606,6 @@ public:
static constexpr auto name = "today";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionToday>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -620,13 +613,11 @@ public:
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeDate>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
block.safeGetByPosition(result).column = std::make_shared<ColumnConstUInt16>(
@ -642,7 +633,6 @@ public:
static constexpr auto name = "yesterday";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionYesterday>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -650,13 +640,11 @@ public:
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeDate>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
block.safeGetByPosition(result).column = std::make_shared<ColumnConstUInt16>(
@ -672,7 +660,6 @@ public:
static constexpr auto name = "timeSlot";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionTimeSlot>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -680,7 +667,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeDateTime *>(arguments[0].get()))
@ -690,7 +676,6 @@ public:
return std::make_shared<DataTypeDateTime>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (const ColumnUInt32 * times = typeid_cast<const ColumnUInt32 *>(block.safeGetByPosition(arguments[0]).column.get()))
@ -805,7 +790,6 @@ public:
static constexpr auto name = "timeSlots";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionTimeSlots>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -813,7 +797,6 @@ public:
size_t getNumberOfArguments() const override { return 2; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeDateTime *>(arguments[0].get()))
@ -827,7 +810,6 @@ public:
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeDateTime>());
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnUInt32 * starts = typeid_cast<const ColumnUInt32 *>(block.safeGetByPosition(arguments[0]).column.get());

View File

@ -201,7 +201,6 @@ public:
throw Exception("Dictionaries was not loaded. You need to check configuration file.", ErrorCodes::DICTIONARIES_WAS_NOT_LOADED);
}
/// Получить имя функции.
String getName() const override
{
return name;
@ -210,7 +209,6 @@ public:
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() != 1 && arguments.size() != 2)
@ -231,7 +229,6 @@ public:
return arguments[0];
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
/// Ключ словаря, определяющий "точку зрения".
@ -297,7 +294,6 @@ public:
throw Exception("Dictionaries was not loaded. You need to check configuration file.", ErrorCodes::DICTIONARIES_WAS_NOT_LOADED);
}
/// Получить имя функции.
String getName() const override
{
return name;
@ -306,7 +302,6 @@ public:
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() != 2 && arguments.size() != 3)
@ -332,7 +327,6 @@ public:
return std::make_shared<DataTypeUInt8>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
/// Ключ словаря, определяющий "точку зрения".
@ -433,7 +427,6 @@ public:
throw Exception("Dictionaries was not loaded. You need to check configuration file.", ErrorCodes::DICTIONARIES_WAS_NOT_LOADED);
}
/// Получить имя функции.
String getName() const override
{
return name;
@ -442,7 +435,6 @@ public:
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() != 1 && arguments.size() != 2)
@ -463,7 +455,6 @@ public:
return std::make_shared<DataTypeArray>(arguments[0]);
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
/// Ключ словаря, определяющий "точку зрения".
@ -709,7 +700,6 @@ public:
throw Exception("Dictionaries was not loaded. You need to check configuration file.", ErrorCodes::DICTIONARIES_WAS_NOT_LOADED);
}
/// Получить имя функции.
String getName() const override
{
return name;
@ -722,7 +712,6 @@ public:
/// even in face of fact that there are many different cities named Moscow.
bool isInjective(const Block &) override { return true; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() != 1 && arguments.size() != 2)
@ -743,7 +732,6 @@ public:
return std::make_shared<DataTypeString>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
RegionsNames::Language language = RegionsNames::Language::RU;

View File

@ -24,8 +24,7 @@ public:
static constexpr auto name = "bitmaskToList";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionBitmaskToList>(); }
/// Получить основное имя функции.
virtual String getName() const override
String getName() const override
{
return name;
}
@ -33,8 +32,7 @@ public:
size_t getNumberOfArguments() const override { return 1; }
bool isInjective(const Block &) override { return true; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
virtual DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
const IDataType * type = &*arguments[0];
@ -51,7 +49,6 @@ public:
return std::make_shared<DataTypeString>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (!( executeType<UInt8>(block, arguments, result)
@ -135,16 +132,14 @@ public:
static constexpr auto name = "formatReadableSize";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionFormatReadableSize>(); }
/// Получить основное имя функции.
virtual String getName() const override
String getName() const override
{
return name;
}
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
virtual DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
const IDataType & type = *arguments[0];
@ -154,7 +149,6 @@ public:
return std::make_shared<DataTypeString>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (!( executeType<UInt8>(block, arguments, result)

View File

@ -173,7 +173,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionStringHash64>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -181,7 +180,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]))
@ -191,7 +189,6 @@ public:
return std::make_shared<DataTypeUInt64>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (const ColumnString * col_from = typeid_cast<const ColumnString *>(block.safeGetByPosition(arguments[0]).column.get()))
@ -231,7 +228,6 @@ public:
static constexpr auto name = Impl::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionStringHashFixedString>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -239,7 +235,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]))
@ -249,7 +244,6 @@ public:
return std::make_shared<DataTypeFixedString>(Impl::length);
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (const ColumnString * col_from = typeid_cast<const ColumnString *>(block.safeGetByPosition(arguments[0]).column.get()))
@ -326,7 +320,6 @@ private:
}
public:
/// Получить имя функции.
String getName() const override
{
return name;
@ -334,7 +327,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!arguments[0]->isNumeric())
@ -344,7 +336,6 @@ public:
return std::make_shared<typename DataTypeFromFieldType<typename Impl::ReturnType>::Type>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
IDataType * from_type = block.safeGetByPosition(arguments[0]).type.get();

View File

@ -601,7 +601,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionArrayMapped>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -689,17 +688,17 @@ public:
/// Попросим добавить в блок все столбцы, упоминаемые в выражении, размноженные в массив, параллельный обрабатываемому.
const ExpressionActions & expression = *column_expression->getExpression();
Names required_columns = expression.getRequiredColumns();
const NamesAndTypesList & required_columns = expression.getRequiredColumnsWithTypes();
Names argument_name_vector = column_expression->getArgumentNames();
NameSet argument_names(argument_name_vector.begin(), argument_name_vector.end());
for (size_t i = 0; i < required_columns.size(); ++i)
for (const auto & required_column : required_columns)
{
if (argument_names.count(required_columns[i]))
if (argument_names.count(required_column.name))
continue;
Names replicate_arguments;
replicate_arguments.push_back(required_columns[i]);
replicate_arguments.push_back(required_column.name);
replicate_arguments.push_back(arguments[1].name);
out_prerequisites.push_back(ExpressionAction::applyFunction(std::make_shared<FunctionReplicate>(), replicate_arguments));
}
@ -715,7 +714,6 @@ public:
}
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, const ColumnNumbers & prerequisites, size_t result) override
{
if (arguments.size() == 1)

View File

@ -241,7 +241,6 @@ private:
}
public:
/// Получить имя функции.
String getName() const override
{
return name;
@ -270,7 +269,6 @@ public:
return std::make_shared<DataTypeUInt8>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
ColumnPlainPtrs in(arguments.size());
@ -398,7 +396,6 @@ private:
}
public:
/// Получить имя функции.
String getName() const override
{
return name;
@ -406,7 +403,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!arguments[0]->isNumeric())
@ -418,7 +414,6 @@ public:
return std::make_shared<DataTypeUInt8>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (!( executeType<UInt8>(block, arguments, result)

View File

@ -120,7 +120,6 @@ public:
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeString>();
@ -149,7 +148,6 @@ public:
return true;
}
/// Получить имя функции.
String getName() const override
{
return name;
@ -157,13 +155,11 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeUInt64>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override;
};
@ -187,13 +183,11 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeString>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
block.safeGetByPosition(result).column = std::make_shared<ColumnConstString>(
@ -240,7 +234,6 @@ public:
static constexpr auto name = "blockSize";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionBlockSize>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -250,13 +243,11 @@ public:
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeUInt64>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
size_t size = block.rows();
@ -271,7 +262,6 @@ public:
static constexpr auto name = "rowNumberInBlock";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionRowNumberInBlock>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -281,13 +271,11 @@ public:
bool isDeterministicInScopeOfQuery() override { return false; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeUInt64>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
size_t size = block.rows();
@ -312,7 +300,6 @@ public:
static constexpr auto name = "blockNumber";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionBlockNumber>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -322,13 +309,11 @@ public:
bool isDeterministicInScopeOfQuery() override { return false; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeUInt64>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
size_t current_block_number = block_number++;
@ -347,7 +332,6 @@ public:
static constexpr auto name = "rowNumberInAllBlocks";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionRowNumberInAllBlocks>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -357,13 +341,11 @@ public:
bool isDeterministicInScopeOfQuery() override { return false; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeUInt64>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
size_t rows_in_block = block.rows();
@ -386,7 +368,6 @@ public:
static constexpr auto name = "sleep";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionSleep>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -397,7 +378,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeFloat64 *>(&*arguments[0]) &&
@ -412,7 +392,6 @@ public:
return std::make_shared<DataTypeUInt8>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
IColumn * col = block.safeGetByPosition(arguments[0]).column.get();
@ -456,7 +435,6 @@ public:
static constexpr auto name = "materialize";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionMaterialize>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -464,13 +442,11 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return arguments[0];
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const auto & src = block.safeGetByPosition(arguments[0]).column;
@ -501,13 +477,11 @@ public:
size_t getNumberOfArguments() const override { return 2; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return std::make_shared<DataTypeUInt8>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
/// Second argument must be ColumnSet.
@ -552,7 +526,6 @@ public:
bool hasSpecialSupportForNulls() const override { return true; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() < 1)
@ -561,7 +534,6 @@ public:
return std::make_shared<DataTypeTuple>(arguments);
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
Block tuple_block;
@ -647,7 +619,6 @@ public:
out_return_type = elems[index - 1]->clone();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnTuple * tuple_col = typeid_cast<const ColumnTuple *>(block.safeGetByPosition(arguments[0]).column.get());
@ -697,7 +668,6 @@ public:
String getName() const override { return name; }
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override { return std::make_shared<DataTypeUInt8>(); }
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
block.safeGetByPosition(result).column = std::make_shared<ColumnConstUInt8>(block.rows(), 0);
@ -731,7 +701,6 @@ public:
String getName() const override { return name; }
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override { return std::make_shared<DataTypeUInt8>(); }
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
block.safeGetByPosition(result).column = std::make_shared<ColumnConstUInt8>(block.rows(), 1);
@ -745,7 +714,6 @@ public:
static constexpr auto name = "identity";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionIdentity>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -753,13 +721,11 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
return arguments.front()->clone();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
block.safeGetByPosition(result).column = block.safeGetByPosition(arguments.front()).column;
@ -773,8 +739,6 @@ public:
static constexpr auto name = "arrayJoin";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionArrayJoin>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -785,7 +749,6 @@ public:
/** It could return many different values for single argument. */
bool isDeterministicInScopeOfQuery() override { return false; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
const DataTypeArray * arr = typeid_cast<const DataTypeArray *>(&*arguments[0]);
@ -795,7 +758,6 @@ public:
return arr->getNestedType()->clone();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
throw Exception("Function " + getName() + " must not be executed directly.", ErrorCodes::FUNCTION_IS_SPECIAL);
@ -815,7 +777,6 @@ public:
static constexpr auto name = "replicate";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionReplicate>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -823,7 +784,6 @@ public:
size_t getNumberOfArguments() const override { return 2; }
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
const DataTypeArray * array_type = typeid_cast<const DataTypeArray *>(&*arguments[1]);
@ -833,7 +793,6 @@ public:
return std::make_shared<DataTypeArray>(arguments[0]->clone());
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
ColumnPtr first_column = block.safeGetByPosition(arguments[0]).column;
@ -873,7 +832,6 @@ public:
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() != 3 && arguments.size() != 4)
@ -888,7 +846,6 @@ public:
return std::make_shared<DataTypeString>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
Int64 min = extractConstant<Int64>(block, arguments, 1, "Second"); /// Уровень значения, при котором полоска имеет нулевую длину.

View File

@ -152,7 +152,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionRandom>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -162,7 +161,6 @@ public:
size_t getNumberOfArguments() const override { return 0; }
bool isDeterministicInScopeOfQuery() override { return false; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() > 1)
@ -173,7 +171,6 @@ public:
return std::make_shared<typename DataTypeFromFieldType<typename Impl::ReturnType>::Type>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
auto col_to = std::make_shared<ColumnVector<ToType>>();
@ -202,7 +199,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionRandomConstant>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -211,7 +207,6 @@ public:
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() > 1)
@ -222,7 +217,6 @@ public:
return std::make_shared<typename DataTypeFromFieldType<typename Impl::ReturnType>::Type>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (!is_initialized)

View File

@ -26,7 +26,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionReinterpretAsStringImpl>(); };
/// Получить имя функции.
String getName() const override
{
return name;
@ -34,7 +33,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
const IDataType * type = &*arguments[0];
@ -93,7 +91,6 @@ public:
return true;
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (!( executeType<UInt8>(block, arguments, result)
@ -121,7 +118,6 @@ public:
using ToFieldType = typename ToDataType::FieldType;
/// Получить имя функции.
String getName() const override
{
return name;
@ -129,7 +125,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
const IDataType * type = &*arguments[0];
@ -140,7 +135,6 @@ public:
return std::make_shared<ToDataType>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (ColumnString * col_from = typeid_cast<ColumnString *>(block.safeGetByPosition(arguments[0]).column.get()))

View File

@ -13,7 +13,7 @@
namespace DB
{
/** Функции округления:
/** Функции округления:
* roundToExp2 - вниз до ближайшей степени двойки;
* roundDuration - вниз до ближайшего из: 0, 1, 10, 30, 60, 120, 180, 240, 300, 600, 1200, 1800, 3600, 7200, 18000, 36000;
* roundAge - вниз до ближайшего из: 0, 18, 25, 35, 45.
@ -28,42 +28,42 @@ namespace DB
* - N = 0: округлять до целого числа
*/
template<typename A>
struct RoundToExp2Impl
{
template<typename A>
struct RoundToExp2Impl
{
using ResultType = A;
static inline A apply(A x)
{
return x <= 0 ? static_cast<A>(0) : (static_cast<A>(1) << static_cast<UInt64>(log2(static_cast<double>(x))));
}
};
};
template<>
struct RoundToExp2Impl<Float32>
{
template<>
struct RoundToExp2Impl<Float32>
{
using ResultType = Float32;
static inline Float32 apply(Float32 x)
{
return static_cast<Float32>(x < 1 ? 0. : pow(2., floor(log2(x))));
}
};
};
template<>
struct RoundToExp2Impl<Float64>
{
template<>
struct RoundToExp2Impl<Float64>
{
using ResultType = Float64;
static inline Float64 apply(Float64 x)
{
return x < 1 ? 0. : pow(2., floor(log2(x)));
}
};
};
template<typename A>
struct RoundDurationImpl
{
template<typename A>
struct RoundDurationImpl
{
using ResultType = UInt16;
static inline ResultType apply(A x)
@ -85,11 +85,11 @@ namespace DB
: (x < 36000 ? 18000
: 36000))))))))))))));
}
};
};
template<typename A>
struct RoundAgeImpl
{
template<typename A>
struct RoundAgeImpl
{
using ResultType = UInt8;
static inline ResultType apply(A x)
@ -101,18 +101,18 @@ namespace DB
: (x < 45 ? 35
: 45))));
}
};
};
/** Быстрое вычисление остатка от деления для применения к округлению целых чисел.
/** Быстрое вычисление остатка от деления для применения к округлению целых чисел.
* Без проверки, потому что делитель всегда положительный.
*/
template<typename T, typename Enable = void>
struct FastModulo;
template<typename T, typename Enable = void>
struct FastModulo;
template<typename T>
struct FastModulo<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
private:
template<typename T>
struct FastModulo<T, typename std::enable_if<std::is_integral<T>::value>::type>
{
private:
template<typename InputType, typename Enable = void>
struct Extend;
@ -142,7 +142,7 @@ namespace DB
using U = typename Extend<T>::Type;
public:
public:
using Divisor = std::pair<size_t, typename libdivide::divider<U> >;
static inline Divisor prepare(size_t b)
@ -156,34 +156,34 @@ namespace DB
U rem = val - (val / divisor.second) * static_cast<U>(divisor.first);
return static_cast<T>(rem);
}
};
};
/** Этот параметр контролирует поведение функций округления.
/** Этот параметр контролирует поведение функций округления.
*/
enum ScaleMode
{
enum ScaleMode
{
PositiveScale, // округлять до числа с N десятичными знаками после запятой
NegativeScale, // окурглять до целого числа с N нулевыми знаками
ZeroScale, // округлять до целого числа
NullScale // возвращать нулевое значение
};
};
#if !defined(_MM_FROUND_NINT)
#define _MM_FROUND_NINT 0
#define _MM_FROUND_FLOOR 1
#define _MM_FROUND_CEIL 2
#define _MM_FROUND_NINT 0
#define _MM_FROUND_FLOOR 1
#define _MM_FROUND_CEIL 2
#endif
/** Реализация низкоуровневых функций округления для целочисленных значений.
/** Реализация низкоуровневых функций округления для целочисленных значений.
*/
template<typename T, int rounding_mode, ScaleMode scale_mode, typename Enable = void>
struct IntegerRoundingComputation;
template<typename T, int rounding_mode, ScaleMode scale_mode, typename Enable = void>
struct IntegerRoundingComputation;
template<typename T, int rounding_mode, ScaleMode scale_mode>
struct IntegerRoundingComputation<T, rounding_mode, scale_mode,
template<typename T, int rounding_mode, ScaleMode scale_mode>
struct IntegerRoundingComputation<T, rounding_mode, scale_mode,
typename std::enable_if<std::is_integral<T>::value
&& ((scale_mode == PositiveScale) || (scale_mode == ZeroScale))>::type>
{
{
using Divisor = int;
static inline Divisor prepare(size_t scale)
@ -195,12 +195,12 @@ namespace DB
{
return in;
}
};
};
template<typename T>
struct IntegerRoundingComputation<T, _MM_FROUND_NINT, NegativeScale,
template<typename T>
struct IntegerRoundingComputation<T, _MM_FROUND_NINT, NegativeScale,
typename std::enable_if<std::is_integral<T>::value>::type>
{
{
using Op = FastModulo<T>;
using Divisor = typename Op::Divisor;
@ -222,12 +222,12 @@ namespace DB
res = in + scale.first;
return factor * res;
}
};
};
template<typename T>
struct IntegerRoundingComputation<T, _MM_FROUND_CEIL, NegativeScale,
template<typename T>
struct IntegerRoundingComputation<T, _MM_FROUND_CEIL, NegativeScale,
typename std::enable_if<std::is_integral<T>::value>::type>
{
{
using Op = FastModulo<T>;
using Divisor = typename Op::Divisor;
@ -244,12 +244,12 @@ namespace DB
T res = in - rem + scale.first;
return factor * res;
}
};
};
template<typename T>
struct IntegerRoundingComputation<T, _MM_FROUND_FLOOR, NegativeScale,
template<typename T>
struct IntegerRoundingComputation<T, _MM_FROUND_FLOOR, NegativeScale,
typename std::enable_if<std::is_integral<T>::value>::type>
{
{
using Op = FastModulo<T>;
using Divisor = typename Op::Divisor;
@ -266,20 +266,20 @@ namespace DB
T res = in - rem;
return factor * res;
}
};
};
#if __SSE4_1__
template <typename T>
class BaseFloatRoundingComputation;
template <typename T>
class BaseFloatRoundingComputation;
template <>
class BaseFloatRoundingComputation<Float32>
{
public:
template <>
class BaseFloatRoundingComputation<Float32>
{
public:
using Scale = __m128;
static const size_t data_count = 4;
protected:
protected:
/// Предотвратить появление отрицательных нолей определённых в стандарте IEEE-754.
static inline void normalize(__m128 & val, const __m128 & mask)
{
@ -308,16 +308,16 @@ namespace DB
static const __m128 two = _mm_set1_ps(2.0);
return two;
}
};
};
template <>
class BaseFloatRoundingComputation<Float64>
{
public:
template <>
class BaseFloatRoundingComputation<Float64>
{
public:
using Scale = __m128d;
static const size_t data_count = 2;
protected:
protected:
/// Предотвратить появление отрицательных нолей определённых в стандарте IEEE-754.
static inline void normalize(__m128d & val, const __m128d & mask)
{
@ -346,18 +346,18 @@ namespace DB
static const __m128d two = _mm_set1_pd(2.0);
return two;
}
};
};
/** Реализация низкоуровневых функций округления для значений с плавающей точкой.
/** Реализация низкоуровневых функций округления для значений с плавающей точкой.
*/
template<typename T, int rounding_mode, ScaleMode scale_mode>
class FloatRoundingComputation;
template<typename T, int rounding_mode, ScaleMode scale_mode>
class FloatRoundingComputation;
template<int rounding_mode>
class FloatRoundingComputation<Float32, rounding_mode, PositiveScale>
template<int rounding_mode>
class FloatRoundingComputation<Float32, rounding_mode, PositiveScale>
: public BaseFloatRoundingComputation<Float32>
{
public:
{
public:
static inline void prepare(size_t scale, Scale & mm_scale)
{
Float32 fscale = static_cast<Float32>(scale);
@ -377,13 +377,13 @@ namespace DB
normalize(val, mask);
_mm_storeu_ps(out, val);
}
};
};
template<int rounding_mode>
class FloatRoundingComputation<Float32, rounding_mode, NegativeScale>
template<int rounding_mode>
class FloatRoundingComputation<Float32, rounding_mode, NegativeScale>
: public BaseFloatRoundingComputation<Float32>
{
public:
{
public:
static inline void prepare(size_t scale, Scale & mm_scale)
{
Float32 fscale = static_cast<Float32>(scale);
@ -415,19 +415,19 @@ namespace DB
_mm_storeu_ps(out, val);
}
private:
private:
static inline const __m128 & getOneTenth()
{
static const __m128 one_tenth = _mm_set1_ps(0.1);
return one_tenth;
}
};
};
template<int rounding_mode>
class FloatRoundingComputation<Float32, rounding_mode, ZeroScale>
template<int rounding_mode>
class FloatRoundingComputation<Float32, rounding_mode, ZeroScale>
: public BaseFloatRoundingComputation<Float32>
{
public:
{
public:
static inline void prepare(size_t scale, Scale & mm_scale)
{
}
@ -442,13 +442,13 @@ namespace DB
normalize(val, mask);
_mm_storeu_ps(out, val);
}
};
};
template<int rounding_mode>
class FloatRoundingComputation<Float64, rounding_mode, PositiveScale>
template<int rounding_mode>
class FloatRoundingComputation<Float64, rounding_mode, PositiveScale>
: public BaseFloatRoundingComputation<Float64>
{
public:
{
public:
static inline void prepare(size_t scale, Scale & mm_scale)
{
Float64 fscale = static_cast<Float64>(scale);
@ -468,13 +468,13 @@ namespace DB
normalize(val, mask);
_mm_storeu_pd(out, val);
}
};
};
template<int rounding_mode>
class FloatRoundingComputation<Float64, rounding_mode, NegativeScale>
template<int rounding_mode>
class FloatRoundingComputation<Float64, rounding_mode, NegativeScale>
: public BaseFloatRoundingComputation<Float64>
{
public:
{
public:
static inline void prepare(size_t scale, Scale & mm_scale)
{
Float64 fscale = static_cast<Float64>(scale);
@ -506,19 +506,19 @@ namespace DB
_mm_storeu_pd(out, val);
}
private:
private:
static inline const __m128d & getOneTenth()
{
static const __m128d one_tenth = _mm_set1_pd(0.1);
return one_tenth;
}
};
};
template<int rounding_mode>
class FloatRoundingComputation<Float64, rounding_mode, ZeroScale>
template<int rounding_mode>
class FloatRoundingComputation<Float64, rounding_mode, ZeroScale>
: public BaseFloatRoundingComputation<Float64>
{
public:
{
public:
static inline void prepare(size_t scale, Scale & mm_scale)
{
}
@ -533,32 +533,32 @@ namespace DB
normalize(val, mask);
_mm_storeu_pd(out, val);
}
};
};
#else
/// Реализация для ARM. Не векторизована. Не исправляет отрицательные нули.
/// Реализация для ARM. Не векторизована. Не исправляет отрицательные нули.
template <int mode>
float roundWithMode(float x)
{
template <int mode>
float roundWithMode(float x)
{
if (mode == _MM_FROUND_NINT) return roundf(x);
if (mode == _MM_FROUND_FLOOR) return floorf(x);
if (mode == _MM_FROUND_CEIL) return ceilf(x);
__builtin_unreachable();
}
}
template <int mode>
double roundWithMode(double x)
{
template <int mode>
double roundWithMode(double x)
{
if (mode == _MM_FROUND_NINT) return round(x);
if (mode == _MM_FROUND_FLOOR) return floor(x);
if (mode == _MM_FROUND_CEIL) return ceil(x);
__builtin_unreachable();
}
}
template <typename T>
class BaseFloatRoundingComputation
{
public:
template <typename T>
class BaseFloatRoundingComputation
{
public:
using Scale = T;
static const size_t data_count = 1;
@ -566,38 +566,38 @@ namespace DB
{
mm_scale = static_cast<T>(scale);
}
};
};
template <typename T, int rounding_mode, ScaleMode scale_mode>
class FloatRoundingComputation;
template <typename T, int rounding_mode, ScaleMode scale_mode>
class FloatRoundingComputation;
template <typename T, int rounding_mode>
class FloatRoundingComputation<T, rounding_mode, PositiveScale>
template <typename T, int rounding_mode>
class FloatRoundingComputation<T, rounding_mode, PositiveScale>
: public BaseFloatRoundingComputation<T>
{
public:
{
public:
static inline void compute(const T * __restrict in, const T & scale, T * __restrict out)
{
out[0] = roundWithMode<rounding_mode>(in[0] * scale) / scale;
}
};
};
template <typename T, int rounding_mode>
class FloatRoundingComputation<T, rounding_mode, NegativeScale>
template <typename T, int rounding_mode>
class FloatRoundingComputation<T, rounding_mode, NegativeScale>
: public BaseFloatRoundingComputation<T>
{
public:
{
public:
static inline void compute(const T * __restrict in, const T & scale, T * __restrict out)
{
out[0] = roundWithMode<rounding_mode>(in[0] / scale) * scale;
}
};
};
template <typename T, int rounding_mode>
class FloatRoundingComputation<T, rounding_mode, ZeroScale>
template <typename T, int rounding_mode>
class FloatRoundingComputation<T, rounding_mode, ZeroScale>
: public BaseFloatRoundingComputation<T>
{
public:
{
public:
static inline void prepare(size_t scale, T & mm_scale)
{
}
@ -606,25 +606,25 @@ namespace DB
{
out[0] = roundWithMode<rounding_mode>(in[0]);
}
};
};
#endif
/** Реализация высокоуровневых функций округления.
/** Реализация высокоуровневых функций округления.
*/
template<typename T, int rounding_mode, ScaleMode scale_mode, typename Enable = void>
struct FunctionRoundingImpl;
template<typename T, int rounding_mode, ScaleMode scale_mode, typename Enable = void>
struct FunctionRoundingImpl;
/** Реализация высокоуровневых функций округления для целочисленных значений.
/** Реализация высокоуровневых функций округления для целочисленных значений.
*/
template<typename T, int rounding_mode, ScaleMode scale_mode>
struct FunctionRoundingImpl<T, rounding_mode, scale_mode,
template<typename T, int rounding_mode, ScaleMode scale_mode>
struct FunctionRoundingImpl<T, rounding_mode, scale_mode,
typename std::enable_if<std::is_integral<T>::value && (scale_mode != NullScale)>::type>
{
private:
{
private:
using Op = IntegerRoundingComputation<T, rounding_mode, scale_mode>;
public:
public:
static inline void apply(const PaddedPODArray<T> & in, size_t scale, typename ColumnVector<T>::Container_t & out)
{
auto divisor = Op::prepare(scale);
@ -645,20 +645,20 @@ namespace DB
auto divisor = Op::prepare(scale);
return Op::compute(val, divisor);
}
};
};
/** Реализация высокоуровневых функций округления для значений с плавающей точкой.
/** Реализация высокоуровневых функций округления для значений с плавающей точкой.
*/
template<typename T, int rounding_mode, ScaleMode scale_mode>
struct FunctionRoundingImpl<T, rounding_mode, scale_mode,
template<typename T, int rounding_mode, ScaleMode scale_mode>
struct FunctionRoundingImpl<T, rounding_mode, scale_mode,
typename std::enable_if<std::is_floating_point<T>::value && (scale_mode != NullScale)>::type>
{
private:
{
private:
using Op = FloatRoundingComputation<T, rounding_mode, scale_mode>;
using Data = std::array<T, Op::data_count>;
using Scale = typename Op::Scale;
public:
public:
static inline void apply(const PaddedPODArray<T> & in, size_t scale, typename ColumnVector<T>::Container_t & out)
{
Scale mm_scale;
@ -725,15 +725,15 @@ namespace DB
return res[0];
}
}
};
};
/** Реализация высокоуровневых функций округления в том случае, когда возвращается нулевое значение.
/** Реализация высокоуровневых функций округления в том случае, когда возвращается нулевое значение.
*/
template<typename T, int rounding_mode, ScaleMode scale_mode>
struct FunctionRoundingImpl<T, rounding_mode, scale_mode,
template<typename T, int rounding_mode, ScaleMode scale_mode>
struct FunctionRoundingImpl<T, rounding_mode, scale_mode,
typename std::enable_if<scale_mode == NullScale>::type>
{
public:
{
public:
static inline void apply(const PaddedPODArray<T> & in, size_t scale, typename ColumnVector<T>::Container_t & out)
{
::memset(reinterpret_cast<T *>(&out[0]), 0, in.size() * sizeof(T));
@ -743,9 +743,9 @@ namespace DB
{
return 0;
}
};
};
/// Следующий код генерирует во время сборки таблицу степеней числа 10.
/// Следующий код генерирует во время сборки таблицу степеней числа 10.
namespace
{
@ -764,50 +764,50 @@ namespace
};
}
/// Объявление и определение контейнера содержащего таблицу степеней числа 10.
/// Объявление и определение контейнера содержащего таблицу степеней числа 10.
template<size_t... TArgs>
struct TableContainer
{
template<size_t... TArgs>
struct TableContainer
{
static const std::array<size_t, sizeof...(TArgs)> values;
};
};
template<size_t... TArgs>
const std::array<size_t, sizeof...(TArgs)> TableContainer<TArgs...>::values {{ TArgs... }};
template<size_t... TArgs>
const std::array<size_t, sizeof...(TArgs)> TableContainer<TArgs...>::values {{ TArgs... }};
/// Генератор первых N степеней.
/// Генератор первых N степеней.
template<size_t N, size_t... TArgs>
struct FillArrayImpl
{
template<size_t N, size_t... TArgs>
struct FillArrayImpl
{
using result = typename FillArrayImpl<N - 1, PowerOf10<N>::value, TArgs...>::result;
};
};
template<size_t... TArgs>
struct FillArrayImpl<0, TArgs...>
{
template<size_t... TArgs>
struct FillArrayImpl<0, TArgs...>
{
using result = TableContainer<PowerOf10<0>::value, TArgs...>;
};
};
template<size_t N>
struct FillArray
{
template<size_t N>
struct FillArray
{
using result = typename FillArrayImpl<N - 1>::result;
};
};
/** Этот шаблон определяет точность, которую используют функции round/ceil/floor,
/** Этот шаблон определяет точность, которую используют функции round/ceil/floor,
* затем преобразовывает её в значение, которое можно использовать в операциях
* умножения и деления. Поэтому оно называется масштабом.
*/
template<typename T, typename U, typename Enable = void>
struct ScaleForRightType;
template<typename T, typename U, typename Enable = void>
struct ScaleForRightType;
template<typename T, typename U>
struct ScaleForRightType<T, U,
template<typename T, typename U>
struct ScaleForRightType<T, U,
typename std::enable_if<
std::is_floating_point<T>::value
&& std::is_signed<U>::value>::type>
{
{
static inline bool apply(const ColumnPtr & column, ScaleMode & scale_mode, size_t & scale)
{
using PowersOf10 = typename FillArray<std::numeric_limits<T>::digits10 + 1>::result;
@ -846,14 +846,14 @@ namespace
return true;
}
};
};
template<typename T, typename U>
struct ScaleForRightType<T, U,
template<typename T, typename U>
struct ScaleForRightType<T, U,
typename std::enable_if<
std::is_floating_point<T>::value
&& std::is_unsigned<U>::value>::type>
{
{
static inline bool apply(const ColumnPtr & column, ScaleMode & scale_mode, size_t & scale)
{
using PowersOf10 = typename FillArray<std::numeric_limits<T>::digits10 + 1>::result;
@ -879,14 +879,14 @@ namespace
return true;
}
};
};
template<typename T, typename U>
struct ScaleForRightType<T, U,
template<typename T, typename U>
struct ScaleForRightType<T, U,
typename std::enable_if<
std::is_integral<T>::value
&& std::is_signed<U>::value>::type>
{
{
static inline bool apply(const ColumnPtr & column, ScaleMode & scale_mode, size_t & scale)
{
using PowersOf10 = typename FillArray<std::numeric_limits<T>::digits10 + 1>::result;
@ -918,14 +918,14 @@ namespace
return true;
}
};
};
template<typename T, typename U>
struct ScaleForRightType<T, U,
template<typename T, typename U>
struct ScaleForRightType<T, U,
typename std::enable_if<
std::is_integral<T>::value
&& std::is_unsigned<U>::value>::type>
{
{
static inline bool apply(const ColumnPtr & column, ScaleMode & scale_mode, size_t & scale)
{
using ColumnType = ColumnConst<U>;
@ -939,13 +939,13 @@ namespace
return true;
}
};
};
/** Превратить параметр точности в масштаб.
/** Превратить параметр точности в масштаб.
*/
template<typename T>
struct ScaleForLeftType
{
template<typename T>
struct ScaleForLeftType
{
static inline void apply(const ColumnPtr & column, ScaleMode & scale_mode, size_t & scale)
{
if (!( ScaleForRightType<T, UInt8>::apply(column, scale_mode, scale)
@ -963,13 +963,13 @@ namespace
throw Exception("Internal error", ErrorCodes::LOGICAL_ERROR);
}
}
};
};
/** Главный шаблон применяющий функцию округления к значению или столбцу.
/** Главный шаблон применяющий функцию округления к значению или столбцу.
*/
template<typename T, int rounding_mode, ScaleMode scale_mode>
struct Cruncher
{
template<typename T, int rounding_mode, ScaleMode scale_mode>
struct Cruncher
{
using Op = FunctionRoundingImpl<T, rounding_mode, scale_mode>;
static inline void apply(Block & block, ColumnVector<T> * col, const ColumnNumbers & arguments, size_t result, size_t scale)
@ -992,13 +992,13 @@ namespace
auto col_res = std::make_shared<ColumnConst<T>>(col->size(), res);
block.safeGetByPosition(result).column = col_res;
}
};
};
/** Выбрать подходящий алгоритм обработки в зависимости от масштаба.
/** Выбрать подходящий алгоритм обработки в зависимости от масштаба.
*/
template<typename T, template <typename> class U, int rounding_mode>
struct Dispatcher
{
template<typename T, template <typename> class U, int rounding_mode>
struct Dispatcher
{
static inline void apply(Block & block, U<T> * col, const ColumnNumbers & arguments, size_t result)
{
ScaleMode scale_mode;
@ -1023,20 +1023,20 @@ namespace
else
throw Exception("Illegal operation", ErrorCodes::LOGICAL_ERROR);
}
};
};
/** Шаблон для функций, которые округляют значение входного параметра типа
/** Шаблон для функций, которые округляют значение входного параметра типа
* (U)Int8/16/32/64 или Float32/64, и принимают дополнительный необязятельный
* параметр (по умолчанию - 0).
*/
template<typename Name, int rounding_mode>
class FunctionRounding : public IFunction
{
public:
template<typename Name, int rounding_mode>
class FunctionRounding : public IFunction
{
public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionRounding>(); }
private:
private:
template<typename T>
bool checkType(const IDataType * type) const
{
@ -1060,8 +1060,7 @@ namespace
return false;
}
public:
/// Получить имя функции.
public:
String getName() const override
{
return name;
@ -1105,7 +1104,6 @@ namespace
return arguments[0];
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
if (!( executeForType<UInt8>(block, arguments, result)
@ -1134,34 +1132,35 @@ namespace
{
return { true };
}
};
};
struct NameRoundToExp2 { static constexpr auto name = "roundToExp2"; };
struct NameRoundDuration { static constexpr auto name = "roundDuration"; };
struct NameRoundAge { static constexpr auto name = "roundAge"; };
struct NameRound { static constexpr auto name = "round"; };
struct NameCeil { static constexpr auto name = "ceil"; };
struct NameFloor { static constexpr auto name = "floor"; };
struct NameRoundToExp2 { static constexpr auto name = "roundToExp2"; };
struct NameRoundDuration { static constexpr auto name = "roundDuration"; };
struct NameRoundAge { static constexpr auto name = "roundAge"; };
struct NameRound { static constexpr auto name = "round"; };
struct NameCeil { static constexpr auto name = "ceil"; };
struct NameFloor { static constexpr auto name = "floor"; };
using FunctionRoundToExp2 = FunctionUnaryArithmetic<RoundToExp2Impl, NameRoundToExp2, false>;
using FunctionRoundDuration = FunctionUnaryArithmetic<RoundDurationImpl, NameRoundDuration, false>;
using FunctionRoundAge = FunctionUnaryArithmetic<RoundAgeImpl, NameRoundAge, false>;
using FunctionRoundToExp2 = FunctionUnaryArithmetic<RoundToExp2Impl, NameRoundToExp2, false>;
using FunctionRoundDuration = FunctionUnaryArithmetic<RoundDurationImpl, NameRoundDuration, false>;
using FunctionRoundAge = FunctionUnaryArithmetic<RoundAgeImpl, NameRoundAge, false>;
using FunctionRound = FunctionRounding<NameRound, _MM_FROUND_NINT>;
using FunctionFloor = FunctionRounding<NameFloor, _MM_FROUND_FLOOR>;
using FunctionCeil = FunctionRounding<NameCeil, _MM_FROUND_CEIL>;
using FunctionRound = FunctionRounding<NameRound, _MM_FROUND_NINT>;
using FunctionFloor = FunctionRounding<NameFloor, _MM_FROUND_FLOOR>;
using FunctionCeil = FunctionRounding<NameCeil, _MM_FROUND_CEIL>;
struct PositiveMonotonicity
{
struct PositiveMonotonicity
{
static bool has() { return true; }
static IFunction::Monotonicity get(const Field & left, const Field & right)
{
return { true };
}
};
};
template <> struct FunctionUnaryArithmeticMonotonicity<NameRoundToExp2> : PositiveMonotonicity {};
template <> struct FunctionUnaryArithmeticMonotonicity<NameRoundDuration> : PositiveMonotonicity {};
template <> struct FunctionUnaryArithmeticMonotonicity<NameRoundAge> : PositiveMonotonicity {};
template <> struct FunctionUnaryArithmeticMonotonicity<NameRoundToExp2> : PositiveMonotonicity {};
template <> struct FunctionUnaryArithmeticMonotonicity<NameRoundDuration> : PositiveMonotonicity {};
template <> struct FunctionUnaryArithmeticMonotonicity<NameRoundAge> : PositiveMonotonicity {};
}

View File

@ -772,7 +772,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionStringOrArrayToT>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -780,7 +779,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]) && !typeid_cast<const DataTypeFixedString *>(&*arguments[0])
@ -791,7 +789,6 @@ public:
return std::make_shared<typename DataTypeFromFieldType<ResultType>::Type>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnPtr column = block.safeGetByPosition(arguments[0]).column;
@ -865,7 +862,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionStringToString>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -874,7 +870,6 @@ public:
size_t getNumberOfArguments() const override { return 1; }
bool isInjective(const Block &) override { return is_injective; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]) && !typeid_cast<const DataTypeFixedString *>(&*arguments[0]))
@ -884,7 +879,6 @@ public:
return arguments[0]->clone();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnPtr column = block.safeGetByPosition(arguments[0]).column;
@ -924,14 +918,12 @@ public:
static constexpr auto name = "reverse";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionReverse>(); }
/// Получить имя функции.
String getName() const override;
size_t getNumberOfArguments() const override { return 1; }
bool isInjective(const Block &) override { return true; }
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override;
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override;
};
@ -943,7 +935,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<ConcatImpl>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -953,7 +944,6 @@ public:
size_t getNumberOfArguments() const override { return 0; }
bool isInjective(const Block &) override { return is_injective; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() < 2)
@ -1426,7 +1416,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionStringNumNumToString>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -1434,7 +1423,6 @@ public:
size_t getNumberOfArguments() const override { return 3; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]) && !typeid_cast<const DataTypeFixedString *>(&*arguments[0]))
@ -1448,7 +1436,6 @@ public:
return std::make_shared<DataTypeString>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnPtr column_string = block.safeGetByPosition(arguments[0]).column;

View File

@ -310,7 +310,6 @@ public:
static constexpr auto name = Generator::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionTokens>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -318,7 +317,6 @@ public:
size_t getNumberOfArguments() const override { return Generator::getNumberOfArguments(); }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
Generator::checkArguments(arguments);
@ -326,7 +324,6 @@ public:
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeString>());
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
Generator generator;
@ -477,7 +474,6 @@ public:
static constexpr auto name = "arrayStringConcat";
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionArrayStringConcat>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -486,7 +482,6 @@ public:
bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (arguments.size() != 1 && arguments.size() != 2)
@ -505,7 +500,6 @@ public:
return std::make_shared<DataTypeString>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
String delimiter;

View File

@ -1038,7 +1038,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionStringReplace>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -1046,7 +1045,6 @@ public:
size_t getNumberOfArguments() const override { return 3; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]) && !typeid_cast<const DataTypeFixedString *>(&*arguments[0]))
@ -1064,7 +1062,6 @@ public:
return std::make_shared<DataTypeString>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnPtr column_src = block.safeGetByPosition(arguments[0]).column;
@ -1122,7 +1119,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionsStringSearch>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -1130,7 +1126,6 @@ public:
size_t getNumberOfArguments() const override { return 2; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]))
@ -1144,7 +1139,6 @@ public:
return std::make_shared<typename DataTypeFromFieldType<typename Impl::ResultType>::Type>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
using ResultType = typename Impl::ResultType;
@ -1204,7 +1198,6 @@ public:
static constexpr auto name = Name::name;
static FunctionPtr create(const Context & context) { return std::make_shared<FunctionsStringSearchToString>(); }
/// Получить имя функции.
String getName() const override
{
return name;
@ -1212,7 +1205,6 @@ public:
size_t getNumberOfArguments() const override { return 2; }
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
{
if (!typeid_cast<const DataTypeString *>(&*arguments[0]))
@ -1226,7 +1218,6 @@ public:
return std::make_shared<DataTypeString>();
}
/// Выполнить функцию над блоком.
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) override
{
const ColumnPtr column = block.safeGetByPosition(arguments[0]).column;

View File

@ -135,7 +135,10 @@ private:
ClusterPtr getCluster() const;
private:
/// Get monotonically increasing string to name files with data to be written to remote servers.
String getMonotonicFileName();
String name;
NamesAndTypesListPtr columns;
String remote_database;

View File

@ -1,10 +1,337 @@
#include <string.h> // memcpy
#include <DB/Columns/ColumnArray.h>
#include <DB/Columns/ColumnsNumber.h>
#include <DB/Columns/ColumnString.h>
#include <DB/Columns/ColumnsCommon.h>
#include <DB/Common/Exception.h>
#include <DB/Common/Arena.h>
#include <DB/Common/SipHash.h>
namespace DB
{
namespace ErrorCodes
{
extern const int ILLEGAL_COLUMN;
extern const int NOT_IMPLEMENTED;
extern const int BAD_ARGUMENTS;
}
ColumnArray::ColumnArray(ColumnPtr nested_column, ColumnPtr offsets_column)
: data(nested_column), offsets(offsets_column)
{
if (!offsets_column)
{
offsets = std::make_shared<ColumnOffsets_t>();
}
else
{
if (!typeid_cast<ColumnOffsets_t *>(&*offsets_column))
throw Exception("offsets_column must be a ColumnUInt64", ErrorCodes::ILLEGAL_COLUMN);
}
/** NOTE
* Arrays with constant value are possible and used in implementation of higher order functions and in ARRAY JOIN.
* But in most cases, arrays with constant value are unexpected and code will work wrong. Use with caution.
*/
}
std::string ColumnArray::getName() const { return "ColumnArray(" + getData().getName() + ")"; }
ColumnPtr ColumnArray::cloneResized(size_t to_size) const
{
auto res = std::make_shared<ColumnArray>(getData().cloneEmpty());
if (to_size == 0)
return res;
size_t from_size = size();
if (to_size <= from_size)
{
/// Just cut column.
res->getOffsets().assign(getOffsets().begin(), getOffsets().begin() + to_size);
res->getData().insertRangeFrom(getData(), 0, getOffsets()[to_size - 1]);
}
else
{
/// Copy column and append empty arrays for extra elements.
Offset_t offset = 0;
if (from_size > 0)
{
res->getOffsets().assign(getOffsets().begin(), getOffsets().end());
res->getDataPtr() = getData().clone();
offset = getOffsets().back();
}
res->getOffsets().resize(to_size);
for (size_t i = from_size; i < to_size; ++i)
{
++offset;
res->getOffsets()[i] = offset;
}
}
return res;
}
size_t ColumnArray::size() const
{
return getOffsets().size();
}
Field ColumnArray::operator[](size_t n) const
{
size_t offset = offsetAt(n);
size_t size = sizeAt(n);
Array res(size);
for (size_t i = 0; i < size; ++i)
res[i] = getData()[offset + i];
return res;
}
void ColumnArray::get(size_t n, Field & res) const
{
size_t offset = offsetAt(n);
size_t size = sizeAt(n);
res = Array(size);
Array & res_arr = DB::get<Array &>(res);
for (size_t i = 0; i < size; ++i)
getData().get(offset + i, res_arr[i]);
}
StringRef ColumnArray::getDataAt(size_t n) const
{
/** Возвращает диапазон памяти, покрывающий все элементы массива.
* Работает для массивов значений фиксированной длины.
* Для массивов строк и массивов массивов полученный кусок памяти может не взаимно-однозначно соответствовать элементам,
* так как содержит лишь уложенные подряд данные, но не смещения.
*/
size_t array_size = sizeAt(n);
if (array_size == 0)
return StringRef();
size_t offset_of_first_elem = offsetAt(n);
StringRef first = getData().getDataAtWithTerminatingZero(offset_of_first_elem);
size_t offset_of_last_elem = getOffsets()[n] - 1;
StringRef last = getData().getDataAtWithTerminatingZero(offset_of_last_elem);
return StringRef(first.data, last.data + last.size - first.data);
}
void ColumnArray::insertData(const char * pos, size_t length)
{
/** Аналогично - только для массивов значений фиксированной длины.
*/
IColumn * data_ = data.get();
if (!data_->isFixed())
throw Exception("Method insertData is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED);
size_t field_size = data_->sizeOfField();
const char * end = pos + length;
size_t elems = 0;
for (; pos + field_size <= end; pos += field_size, ++elems)
data_->insertData(pos, field_size);
if (pos != end)
throw Exception("Incorrect length argument for method ColumnArray::insertData", ErrorCodes::BAD_ARGUMENTS);
getOffsets().push_back((getOffsets().size() == 0 ? 0 : getOffsets().back()) + elems);
}
StringRef ColumnArray::serializeValueIntoArena(size_t n, Arena & arena, char const *& begin) const
{
size_t array_size = sizeAt(n);
size_t offset = offsetAt(n);
char * pos = arena.allocContinue(sizeof(array_size), begin);
memcpy(pos, &array_size, sizeof(array_size));
size_t values_size = 0;
for (size_t i = 0; i < array_size; ++i)
values_size += getData().serializeValueIntoArena(offset + i, arena, begin).size;
return StringRef(begin, sizeof(array_size) + values_size);
}
const char * ColumnArray::deserializeAndInsertFromArena(const char * pos)
{
size_t array_size = *reinterpret_cast<const size_t *>(pos);
pos += sizeof(array_size);
for (size_t i = 0; i < array_size; ++i)
pos = getData().deserializeAndInsertFromArena(pos);
getOffsets().push_back((getOffsets().size() == 0 ? 0 : getOffsets().back()) + array_size);
return pos;
}
void ColumnArray::updateHashWithValue(size_t n, SipHash & hash) const
{
size_t array_size = sizeAt(n);
size_t offset = offsetAt(n);
hash.update(reinterpret_cast<const char *>(&array_size), sizeof(array_size));
for (size_t i = 0; i < array_size; ++i)
getData().updateHashWithValue(offset + i, hash);
}
void ColumnArray::insert(const Field & x)
{
const Array & array = DB::get<const Array &>(x);
size_t size = array.size();
for (size_t i = 0; i < size; ++i)
getData().insert(array[i]);
getOffsets().push_back((getOffsets().size() == 0 ? 0 : getOffsets().back()) + size);
}
void ColumnArray::insertFrom(const IColumn & src_, size_t n)
{
const ColumnArray & src = static_cast<const ColumnArray &>(src_);
size_t size = src.sizeAt(n);
size_t offset = src.offsetAt(n);
getData().insertRangeFrom(src.getData(), offset, size);
getOffsets().push_back((getOffsets().size() == 0 ? 0 : getOffsets().back()) + size);
}
void ColumnArray::insertDefault()
{
getOffsets().push_back(getOffsets().size() == 0 ? 0 : getOffsets().back());
}
void ColumnArray::popBack(size_t n)
{
auto & offsets = getOffsets();
size_t nested_n = offsets.back() - offsetAt(offsets.size() - n);
if (nested_n)
getData().popBack(nested_n);
offsets.resize_assume_reserved(offsets.size() - n);
}
int ColumnArray::compareAt(size_t n, size_t m, const IColumn & rhs_, int nan_direction_hint) const
{
const ColumnArray & rhs = static_cast<const ColumnArray &>(rhs_);
/// Не оптимально
size_t lhs_size = sizeAt(n);
size_t rhs_size = rhs.sizeAt(m);
size_t min_size = std::min(lhs_size, rhs_size);
for (size_t i = 0; i < min_size; ++i)
if (int res = getData().compareAt(offsetAt(n) + i, rhs.offsetAt(m) + i, *rhs.data.get(), nan_direction_hint))
return res;
return lhs_size < rhs_size
? -1
: (lhs_size == rhs_size
? 0
: 1);
}
namespace
{
template <bool positive>
struct less
{
const ColumnArray & parent;
less(const ColumnArray & parent_) : parent(parent_) {}
bool operator()(size_t lhs, size_t rhs) const
{
if (positive)
return parent.compareAt(lhs, rhs, parent, 1) < 0;
else
return parent.compareAt(lhs, rhs, parent, -1) > 0;
}
};
}
void ColumnArray::reserve(size_t n)
{
getOffsets().reserve(n);
getData().reserve(n); /// Средний размер массивов тут никак не учитывается. Или считается, что он не больше единицы.
}
size_t ColumnArray::byteSize() const
{
return getData().byteSize() + getOffsets().size() * sizeof(getOffsets()[0]);
}
size_t ColumnArray::allocatedSize() const
{
return getData().allocatedSize() + getOffsets().allocated_size() * sizeof(getOffsets()[0]);
}
bool ColumnArray::hasEqualOffsets(const ColumnArray & other) const
{
if (offsets == other.offsets)
return true;
const Offsets_t & offsets1 = getOffsets();
const Offsets_t & offsets2 = other.getOffsets();
return offsets1.size() == offsets2.size() && 0 == memcmp(&offsets1[0], &offsets2[0], sizeof(offsets1[0]) * offsets1.size());
}
ColumnPtr ColumnArray::convertToFullColumnIfConst() const
{
ColumnPtr new_data;
ColumnPtr new_offsets;
if (auto full_column = getData().convertToFullColumnIfConst())
new_data = full_column;
else
new_data = data;
if (auto full_column = offsets.get()->convertToFullColumnIfConst())
new_offsets = full_column;
else
new_offsets = offsets;
return std::make_shared<ColumnArray>(new_data, new_offsets);
}
void ColumnArray::getExtremes(Field & min, Field & max) const
{
min = Array();
max = Array();
}
void ColumnArray::insertRangeFrom(const IColumn & src, size_t start, size_t length)
{

View File

@ -1,10 +1,262 @@
#include <DB/Core/Defines.h>
#include <DB/Common/Collator.h>
#include <DB/Columns/ColumnString.h>
#include <DB/Columns/ColumnsCommon.h>
namespace DB
{
namespace ErrorCodes
{
extern const int PARAMETER_OUT_OF_BOUND;
extern const int SIZES_OF_COLUMNS_DOESNT_MATCH;
}
ColumnPtr ColumnString::cloneResized(size_t to_size) const
{
auto res = std::make_shared<ColumnString>();
if (to_size == 0)
return res;
size_t from_size = size();
if (to_size <= from_size)
{
/// Just cut column.
res->offsets.assign(offsets.begin(), offsets.begin() + to_size);
res->chars.assign(chars.begin(), chars.begin() + offsets[to_size - 1]);
}
else
{
/// Copy column and append empty strings for extra elements.
Offset_t offset = 0;
if (from_size > 0)
{
res->offsets.assign(offsets.begin(), offsets.end());
res->chars.assign(chars.begin(), chars.end());
offset = offsets.back();
}
/// Empty strings are just zero terminating bytes.
res->chars.resize_fill(res->chars.size() + to_size - from_size);
res->offsets.resize(to_size);
for (size_t i = from_size; i < to_size; ++i)
{
++offset;
res->offsets[i] = offset;
}
}
return res;
}
void ColumnString::insertRangeFrom(const IColumn & src, size_t start, size_t length)
{
if (length == 0)
return;
const ColumnString & src_concrete = static_cast<const ColumnString &>(src);
if (start + length > src_concrete.offsets.size())
throw Exception("Parameter out of bound in IColumnString::insertRangeFrom method.",
ErrorCodes::PARAMETER_OUT_OF_BOUND);
size_t nested_offset = src_concrete.offsetAt(start);
size_t nested_length = src_concrete.offsets[start + length - 1] - nested_offset;
size_t old_chars_size = chars.size();
chars.resize(old_chars_size + nested_length);
memcpy(&chars[old_chars_size], &src_concrete.chars[nested_offset], nested_length);
if (start == 0 && offsets.empty())
{
offsets.assign(src_concrete.offsets.begin(), src_concrete.offsets.begin() + length);
}
else
{
size_t old_size = offsets.size();
size_t prev_max_offset = old_size ? offsets.back() : 0;
offsets.resize(old_size + length);
for (size_t i = 0; i < length; ++i)
offsets[old_size + i] = src_concrete.offsets[start + i] - nested_offset + prev_max_offset;
}
}
ColumnPtr ColumnString::filter(const Filter & filt, ssize_t result_size_hint) const
{
if (offsets.size() == 0)
return std::make_shared<ColumnString>();
auto res = std::make_shared<ColumnString>();
Chars_t & res_chars = res->chars;
Offsets_t & res_offsets = res->offsets;
filterArraysImpl<UInt8>(chars, offsets, res_chars, res_offsets, filt, result_size_hint);
return res;
}
ColumnPtr ColumnString::permute(const Permutation & perm, size_t limit) const
{
size_t size = offsets.size();
if (limit == 0)
limit = size;
else
limit = std::min(size, limit);
if (perm.size() < limit)
throw Exception("Size of permutation is less than required.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
if (limit == 0)
return std::make_shared<ColumnString>();
std::shared_ptr<ColumnString> res = std::make_shared<ColumnString>();
Chars_t & res_chars = res->chars;
Offsets_t & res_offsets = res->offsets;
if (limit == size)
res_chars.resize(chars.size());
else
{
size_t new_chars_size = 0;
for (size_t i = 0; i < limit; ++i)
new_chars_size += sizeAt(perm[i]);
res_chars.resize(new_chars_size);
}
res_offsets.resize(limit);
Offset_t current_new_offset = 0;
for (size_t i = 0; i < limit; ++i)
{
size_t j = perm[i];
size_t string_offset = j == 0 ? 0 : offsets[j - 1];
size_t string_size = offsets[j] - string_offset;
memcpySmallAllowReadWriteOverflow15(&res_chars[current_new_offset], &chars[string_offset], string_size);
current_new_offset += string_size;
res_offsets[i] = current_new_offset;
}
return res;
}
template <bool positive>
struct ColumnString::less
{
const ColumnString & parent;
less(const ColumnString & parent_) : parent(parent_) {}
bool operator()(size_t lhs, size_t rhs) const
{
int res = strcmp(
reinterpret_cast<const char *>(&parent.chars[parent.offsetAt(lhs)]),
reinterpret_cast<const char *>(&parent.chars[parent.offsetAt(rhs)]));
return positive ? (res < 0) : (res > 0);
}
};
void ColumnString::getPermutation(bool reverse, size_t limit, Permutation & res) const
{
size_t s = offsets.size();
res.resize(s);
for (size_t i = 0; i < s; ++i)
res[i] = i;
if (limit >= s)
limit = 0;
if (limit)
{
if (reverse)
std::partial_sort(res.begin(), res.begin() + limit, res.end(), less<false>(*this));
else
std::partial_sort(res.begin(), res.begin() + limit, res.end(), less<true>(*this));
}
else
{
if (reverse)
std::sort(res.begin(), res.end(), less<false>(*this));
else
std::sort(res.begin(), res.end(), less<true>(*this));
}
}
ColumnPtr ColumnString::replicate(const Offsets_t & replicate_offsets) const
{
size_t col_size = size();
if (col_size != replicate_offsets.size())
throw Exception("Size of offsets doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
std::shared_ptr<ColumnString> res = std::make_shared<ColumnString>();
if (0 == col_size)
return res;
Chars_t & res_chars = res->chars;
Offsets_t & res_offsets = res->offsets;
res_chars.reserve(chars.size() / col_size * replicate_offsets.back());
res_offsets.reserve(replicate_offsets.back());
Offset_t prev_replicate_offset = 0;
Offset_t prev_string_offset = 0;
Offset_t current_new_offset = 0;
for (size_t i = 0; i < col_size; ++i)
{
size_t size_to_replicate = replicate_offsets[i] - prev_replicate_offset;
size_t string_size = offsets[i] - prev_string_offset;
for (size_t j = 0; j < size_to_replicate; ++j)
{
current_new_offset += string_size;
res_offsets.push_back(current_new_offset);
res_chars.resize(res_chars.size() + string_size);
memcpySmallAllowReadWriteOverflow15(
&res_chars[res_chars.size() - string_size], &chars[prev_string_offset], string_size);
}
prev_replicate_offset = replicate_offsets[i];
prev_string_offset = offsets[i];
}
return res;
}
void ColumnString::reserve(size_t n)
{
offsets.reserve(n);
chars.reserve(n * DBMS_APPROX_STRING_SIZE);
}
void ColumnString::getExtremes(Field & min, Field & max) const
{
min = String();
max = String();
}
int ColumnString::compareAtWithCollation(size_t n, size_t m, const IColumn & rhs_, const Collator & collator) const
{
const ColumnString & rhs = static_cast<const ColumnString &>(rhs_);
@ -16,7 +268,7 @@ int ColumnString::compareAtWithCollation(size_t n, size_t m, const IColumn & rhs
template <bool positive>
struct lessWithCollation
struct ColumnString::lessWithCollation
{
const ColumnString & parent;
const Collator & collator;
@ -33,7 +285,6 @@ struct lessWithCollation
}
};
void ColumnString::getPermutationWithCollation(const Collator & collator, bool reverse, size_t limit, Permutation & res) const
{
size_t s = offsets.size();

View File

@ -1068,7 +1068,6 @@ DataTypePtr FunctionArrayElement::getReturnTypeImpl(const DataTypes & arguments)
return array_type->getNestedType();
}
/// Выполнить функцию над блоком.
void FunctionArrayElement::executeImpl(Block & block, const ColumnNumbers & arguments, size_t result)
{
/// Check nullability.
@ -1599,7 +1598,6 @@ FunctionPtr FunctionArrayEnumerateUniq::create(const Context & context)
return std::make_shared<FunctionArrayEnumerateUniq>();
}
/// Получить имя функции.
String FunctionArrayEnumerateUniq::getName() const
{
return name;

View File

@ -184,7 +184,6 @@ private:
}
public:
/// Получить имя функции.
String getName() const override
{
return Name::get();
@ -213,7 +212,6 @@ public:
return std::make_shared<DataTypeUInt8>();
}
/// Выполнить функцию над блоком.
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
{
//Stopwatch sw;

View File

@ -98,6 +98,7 @@ StorageDistributed::StorageDistributed(
createDirectoryMonitors();
}
StorageDistributed::StorageDistributed(
const std::string & name_,
NamesAndTypesListPtr columns_,
@ -121,6 +122,7 @@ StorageDistributed::StorageDistributed(
createDirectoryMonitors();
}
StoragePtr StorageDistributed::create(
const std::string & name_,
NamesAndTypesListPtr columns_,
@ -162,6 +164,7 @@ StoragePtr StorageDistributed::create(
return res;
}
BlockInputStreams StorageDistributed::read(
const Names & column_names,
ASTPtr query,
@ -203,6 +206,7 @@ BlockInputStreams StorageDistributed::read(
context, settings, enable_shard_multiplexing}.execute();
}
BlockOutputStreamPtr StorageDistributed::write(ASTPtr query, const Settings & settings)
{
auto cluster = context.getCluster(cluster_name);
@ -214,14 +218,14 @@ BlockOutputStreamPtr StorageDistributed::write(ASTPtr query, const Settings & se
throw Exception{
"Method write is not supported by storage " + getName() +
" with more than one shard and no sharding key provided",
ErrorCodes::STORAGE_REQUIRES_PARAMETER
};
ErrorCodes::STORAGE_REQUIRES_PARAMETER};
/// DistributedBlockOutputStream will not own cluster, but will own ConnectionPools of the cluster
return std::make_shared<DistributedBlockOutputStream>(
*this, rewriteInsertQuery(query, remote_database, remote_table), cluster);
}
void StorageDistributed::alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context)
{
for (const auto & param : params)
@ -236,11 +240,13 @@ void StorageDistributed::alter(const AlterCommands & params, const String & data
*columns, materialized_columns, alias_columns, column_defaults, {});
}
void StorageDistributed::shutdown()
{
directory_monitors.clear();
}
void StorageDistributed::reshardPartitions(ASTPtr query, const String & database_name,
const Field & first_partition, const Field & last_partition,
const WeightedZooKeeperPaths & weighted_zookeeper_paths,
@ -383,6 +389,7 @@ void StorageDistributed::reshardPartitions(ASTPtr query, const String & database
}
}
BlockInputStreams StorageDistributed::describe(const Context & context, const Settings & settings)
{
/// Создать запрос DESCRIBE TABLE.
@ -406,6 +413,7 @@ BlockInputStreams StorageDistributed::describe(const Context & context, const Se
context, settings, enable_shard_multiplexing}.execute();
}
NameAndTypePair StorageDistributed::getColumn(const String & column_name) const
{
if (const auto & type = VirtualColumnFactory::tryGetType(column_name))
@ -414,16 +422,19 @@ NameAndTypePair StorageDistributed::getColumn(const String & column_name) const
return getRealColumn(column_name);
}
bool StorageDistributed::hasColumn(const String & column_name) const
{
return VirtualColumnFactory::hasColumn(column_name) || IStorage::hasColumn(column_name);
}
void StorageDistributed::createDirectoryMonitor(const std::string & name)
{
directory_monitors.emplace(name, std::make_unique<StorageDistributedDirectoryMonitor>(*this, name));
}
void StorageDistributed::createDirectoryMonitors()
{
if (path.empty())
@ -437,6 +448,7 @@ void StorageDistributed::createDirectoryMonitors()
createDirectoryMonitor(it.name());
}
void StorageDistributed::requireDirectoryMonitor(const std::string & name)
{
if (!directory_monitors.count(name))
@ -448,6 +460,7 @@ size_t StorageDistributed::getShardCount() const
return getCluster()->getRemoteShardCount();
}
ClusterPtr StorageDistributed::getCluster() const
{
return (owned_cluster) ? owned_cluster : context.getCluster(cluster_name);