Fixes and documentation

This commit is contained in:
Mikhail Gorshkov 2024-05-28 13:09:41 +00:00
parent 5034efc566
commit 1f31f19da5
3 changed files with 176 additions and 114 deletions

View File

@ -415,8 +415,8 @@ Alias: `power(x, y)`
**Arguments** **Arguments**
- `x` - [(U)Int8/16/32/64](../../sql-reference/data-types/int-uint.md) or [Float*](../../sql-reference/data-types/float.md) - `x` - [(U)Int8/16/32/64](../../sql-reference/data-types/int-uint.md), [Float*](../../sql-reference/data-types/float.md) or [Decimal*](../../sql-reference/data-types/decimal.md)
- `y` - [(U)Int8/16/32/64](../../sql-reference/data-types/int-uint.md) or [Float*](../../sql-reference/data-types/float.md) - `y` - [(U)Int8/16/32/64](../../sql-reference/data-types/int-uint.md), [Float*](../../sql-reference/data-types/float.md) or [Decimal*](../../sql-reference/data-types/decimal.md)
**Returned value** **Returned value**
@ -635,8 +635,8 @@ atan2(y, x)
**Arguments** **Arguments**
- `y` — y-coordinate of the point through which the ray passes. [(U)Int*](../../sql-reference/data-types/int-uint.md), [Float*](../../sql-reference/data-types/float.md). - `y` — y-coordinate of the point through which the ray passes. [(U)Int*](../../sql-reference/data-types/int-uint.md), [Float*](../../sql-reference/data-types/float.md) or [Decimal*](../../sql-reference/data-types/decimal.md).
- `x` — x-coordinate of the point through which the ray passes. [(U)Int*](../../sql-reference/data-types/int-uint.md), [Float*](../../sql-reference/data-types/float.md). - `x` — x-coordinate of the point through which the ray passes. [(U)Int*](../../sql-reference/data-types/int-uint.md), [Float*](../../sql-reference/data-types/float.md) or [Decimal*](../../sql-reference/data-types/decimal.md).
**Returned value** **Returned value**
@ -670,8 +670,8 @@ hypot(x, y)
**Arguments** **Arguments**
- `x` — The first cathetus of a right-angle triangle. [(U)Int*](../../sql-reference/data-types/int-uint.md), [Float*](../../sql-reference/data-types/float.md). - `x` — The first cathetus of a right-angle triangle. [(U)Int*](../../sql-reference/data-types/int-uint.md), [Float*](../../sql-reference/data-types/float.md) or [Decimal*](../../sql-reference/data-types/decimal.md).
- `y` — The second cathetus of a right-angle triangle. [(U)Int*](../../sql-reference/data-types/int-uint.md), [Float*](../../sql-reference/data-types/float.md). - `y` — The second cathetus of a right-angle triangle. [(U)Int*](../../sql-reference/data-types/int-uint.md), [Float*](../../sql-reference/data-types/float.md) or [Decimal*](../../sql-reference/data-types/decimal.md).
**Returned value** **Returned value**

View File

@ -304,8 +304,8 @@ atan2(y, x)
**Аргументы** **Аргументы**
- `y` — координата y точки, в которую проведена линия. [Float64](../../sql-reference/data-types/float.md#float32-float64). - `y` — координата y точки, в которую проведена линия. [Float64](../../sql-reference/data-types/float.md#float32-float64) или [Decimal](../../sql-reference/data-types/decimal.md).
- `x` — координата х точки, в которую проведена линия. [Float64](../../sql-reference/data-types/float.md#float32-float64). - `x` — координата х точки, в которую проведена линия. [Float64](../../sql-reference/data-types/float.md#float32-float64) или [Decimal](../../sql-reference/data-types/decimal.md).
**Возвращаемое значение** **Возвращаемое значение**
@ -341,8 +341,8 @@ hypot(x, y)
**Аргументы** **Аргументы**
- `x` — первый катет прямоугольного треугольника. [Float64](../../sql-reference/data-types/float.md#float32-float64). - `x` — первый катет прямоугольного треугольника. [Float64](../../sql-reference/data-types/float.md#float32-float64) или [Decimal](../../sql-reference/data-types/decimal.md).
- `y` — второй катет прямоугольного треугольника. [Float64](../../sql-reference/data-types/float.md#float32-float64). - `y` — второй катет прямоугольного треугольника. [Float64](../../sql-reference/data-types/float.md#float32-float64) или [Decimal](../../sql-reference/data-types/decimal.md).
**Возвращаемое значение** **Возвращаемое значение**

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#include <Core/callOnTypeIndex.h>
#include <DataTypes/DataTypesNumber.h>
#include <DataTypes/DataTypesDecimal.h>
#include <Columns/ColumnsNumber.h>
#include <Columns/ColumnDecimal.h>
#include <Columns/ColumnConst.h> #include <Columns/ColumnConst.h>
#include <Functions/IFunction.h> #include <Columns/ColumnDecimal.h>
#include <Columns/ColumnsNumber.h>
#include <Core/callOnTypeIndex.h>
#include <DataTypes/DataTypesDecimal.h>
#include <DataTypes/DataTypesNumber.h>
#include <Functions/FunctionHelpers.h> #include <Functions/FunctionHelpers.h>
#include <Functions/IFunction.h>
#include "config.h" #include "config.h"
@ -42,8 +42,8 @@ private:
const auto check_argument_type = [this](const IDataType * arg) const auto check_argument_type = [this](const IDataType * arg)
{ {
if (!isNativeNumber(arg) && !isDecimal(arg)) if (!isNativeNumber(arg) && !isDecimal(arg))
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type {} of argument of function {}", throw Exception(
arg->getName(), getName()); ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type {} of argument of function {}", arg->getName(), getName());
}; };
check_argument_type(arguments.front().get()); check_argument_type(arguments.front().get());
@ -52,6 +52,60 @@ private:
return std::make_shared<DataTypeFloat64>(); return std::make_shared<DataTypeFloat64>();
} }
template <typename LeftType, typename RightType>
static void executeInIterationsStaticLeft(const LeftType left_src_data[Impl::rows_per_iteration], const RightType * right_src_data, Float64 * dst_data, size_t src_size)
{
const auto rows_remaining = src_size % Impl::rows_per_iteration;
const auto rows_size = src_size - rows_remaining;
for (size_t i = 0; i < rows_size; i += Impl::rows_per_iteration)
Impl::execute(left_src_data, &right_src_data[i], &dst_data[i]);
if (rows_remaining != 0)
{
RightType right_src_remaining[Impl::rows_per_iteration];
memcpy(right_src_remaining, &right_src_data[rows_size], rows_remaining * sizeof(RightType));
memset(right_src_remaining + rows_remaining, 0, (Impl::rows_per_iteration - rows_remaining) * sizeof(RightType));
Float64 dst_remaining[Impl::rows_per_iteration];
Impl::execute(left_src_data, right_src_remaining, dst_remaining);
if constexpr (is_big_int_v<LeftType> || std::is_same_v<LeftType, Decimal256> || is_big_int_v<RightType> || std::is_same_v<RightType, Decimal256>)
for (size_t i = 0; i < rows_remaining; ++i)
dst_data[rows_size + i] = dst_remaining[i];
else
memcpy(&dst_data[rows_size], dst_remaining, rows_remaining * sizeof(Float64));
}
}
template <typename LeftType, typename RightType>
static void executeInIterationsStaticRight(const LeftType* left_src_data, const RightType right_src_data[Impl::rows_per_iteration], Float64 * dst_data, size_t src_size)
{
const auto rows_remaining = src_size % Impl::rows_per_iteration;
const auto rows_size = src_size - rows_remaining;
for (size_t i = 0; i < rows_size; i += Impl::rows_per_iteration)
Impl::execute(&left_src_data[i], right_src_data, &dst_data[i]);
if (rows_remaining != 0)
{
RightType left_src_remaining[Impl::rows_per_iteration];
memcpy(left_src_remaining, &left_src_data[rows_size], rows_remaining * sizeof(LeftType));
memset(left_src_remaining + rows_remaining, 0, (Impl::rows_per_iteration - rows_remaining) * sizeof(LeftType));
Float64 dst_remaining[Impl::rows_per_iteration];
Impl::execute(left_src_remaining, right_src_data, dst_remaining);
if constexpr (is_big_int_v<LeftType> || std::is_same_v<LeftType, Decimal256> || is_big_int_v<RightType> || std::is_same_v<RightType, Decimal256>)
for (size_t i = 0; i < rows_remaining; ++i)
dst_data[rows_size + i] = dst_remaining[i];
else
memcpy(&dst_data[rows_size], dst_remaining, rows_remaining * sizeof(Float64));
}
}
template <typename LeftType, typename RightType> template <typename LeftType, typename RightType>
static void executeInIterations(const LeftType * left_src_data, const RightType * right_src_data, Float64 * dst_data, size_t src_size) static void executeInIterations(const LeftType * left_src_data, const RightType * right_src_data, Float64 * dst_data, size_t src_size)
{ {
@ -59,9 +113,7 @@ private:
const auto rows_size = src_size - rows_remaining; const auto rows_size = src_size - rows_remaining;
for (size_t i = 0; i < rows_size; i += Impl::rows_per_iteration) for (size_t i = 0; i < rows_size; i += Impl::rows_per_iteration)
{
Impl::execute(&left_src_data[i], &right_src_data[i], &dst_data[i]); Impl::execute(&left_src_data[i], &right_src_data[i], &dst_data[i]);
}
if (rows_remaining != 0) if (rows_remaining != 0)
{ {
@ -77,6 +129,10 @@ private:
Impl::execute(left_src_remaining, right_src_remaining, dst_remaining); Impl::execute(left_src_remaining, right_src_remaining, dst_remaining);
if constexpr (is_big_int_v<LeftType> || std::is_same_v<LeftType, Decimal256> || is_big_int_v<RightType> || std::is_same_v<RightType, Decimal256>)
for (size_t i = 0; i < rows_remaining; ++i)
dst_data[rows_size + i] = dst_remaining[i];
else
memcpy(&dst_data[rows_size], dst_remaining, rows_remaining * sizeof(Float64)); memcpy(&dst_data[rows_size], dst_remaining, rows_remaining * sizeof(Float64));
} }
} }
@ -87,48 +143,49 @@ private:
if (const auto right_arg_typed = checkAndGetColumn<ColumnVectorOrDecimal<RightType>>(right_arg)) if (const auto right_arg_typed = checkAndGetColumn<ColumnVectorOrDecimal<RightType>>(right_arg))
{ {
auto dst = ColumnVector<Float64>::create(); auto dst = ColumnVector<Float64>::create();
auto & dst_data = dst->getData();
LeftType left_src_data[Impl::rows_per_iteration];
std::fill(std::begin(left_src_data), std::end(left_src_data), left_arg->template getValue<LeftType>());
const auto & right_src_data = right_arg_typed->getData(); const auto & right_src_data = right_arg_typed->getData();
const auto src_size = right_src_data.size(); const auto src_size = right_src_data.size();
auto & dst_data = dst->getData();
dst_data.resize(src_size); dst_data.resize(src_size);
if constexpr (is_decimal<LeftType> && is_decimal<RightType>) if constexpr (is_decimal<LeftType>)
{ {
Float64 left_src_data[Impl::rows_per_iteration];
const auto left_arg_typed = checkAndGetColumn<ColumnVectorOrDecimal<LeftType>>(left_arg->getDataColumnPtr().get()); const auto left_arg_typed = checkAndGetColumn<ColumnVectorOrDecimal<LeftType>>(left_arg->getDataColumnPtr().get());
Float64 left_src_data_local[Impl::rows_per_iteration];
UInt32 left_scale = left_arg_typed->getScale(); UInt32 left_scale = left_arg_typed->getScale();
for (size_t i = 0; i < src_size; ++i) for (size_t i = 0; i < src_size; ++i)
left_src_data_local[i] = DecimalUtils::convertTo<Float64>(left_src_data[i], left_scale); left_src_data[i] = DecimalUtils::convertTo<Float64>(left_arg->template getValue<LeftType>(), left_scale);
UInt32 right_scale = right_arg_typed->getScale(); if constexpr (is_decimal<RightType>)
Float64 right_src_data_local[Impl::rows_per_iteration];
for (size_t i = 0; i < src_size; ++i)
right_src_data_local[i] = DecimalUtils::convertTo<Float64>(right_src_data[i], right_scale);
executeInIterations(left_src_data_local, right_src_data_local, dst_data.data(), src_size);
}
else if constexpr (is_decimal<LeftType>)
{ {
Float64 left_src_data_local[Impl::rows_per_iteration];
const auto left_arg_typed = checkAndGetColumn<ColumnVectorOrDecimal<LeftType>>(left_arg->getDataColumnPtr().get());
UInt32 left_scale = left_arg_typed->getScale();
for (size_t i = 0; i < src_size; ++i)
left_src_data_local[i] = DecimalUtils::convertTo<Float64>(left_src_data[i], left_scale);
executeInIterations(left_src_data_local, right_src_data.data(), dst_data.data(), src_size);
}
else if constexpr (is_decimal<RightType>)
{
Float64 right_src_data_local[Impl::rows_per_iteration];
UInt32 right_scale = right_arg_typed->getScale(); UInt32 right_scale = right_arg_typed->getScale();
for (size_t i = 0; i < src_size; ++i) for (size_t i = 0; i < src_size; ++i)
right_src_data_local[i] = DecimalUtils::convertTo<Float64>(right_src_data[i], right_scale); dst_data[i] = DecimalUtils::convertTo<Float64>(right_src_data[i], right_scale);
executeInIterations(left_src_data, right_src_data_local, dst_data.data(), src_size);
executeInIterationsStaticLeft(left_src_data, dst_data.data(), dst_data.data(), src_size);
} }
else else
{ {
executeInIterations(left_src_data, right_src_data.data(), dst_data.data(), src_size); executeInIterationsStaticLeft(left_src_data, right_src_data.data(), dst_data.data(), src_size);
}
}
else
{
LeftType left_src_data[Impl::rows_per_iteration];
std::fill(std::begin(left_src_data), std::end(left_src_data), left_arg->template getValue<LeftType>());
if constexpr (is_decimal<RightType>)
{
UInt32 right_scale = right_arg_typed->getScale();
for (size_t i = 0; i < src_size; ++i)
dst_data[i] = DecimalUtils::convertTo<Float64>(right_src_data[i], right_scale);
executeInIterationsStaticLeft(left_src_data, dst_data.data(), dst_data.data(), src_size);
}
else
{
executeInIterationsStaticLeft(left_src_data, right_src_data.data(), dst_data.data(), src_size);
}
} }
return dst; return dst;
} }
@ -144,38 +201,40 @@ private:
const auto & left_src_data = left_arg->getData(); const auto & left_src_data = left_arg->getData();
const auto & right_src_data = right_arg_typed->getData(); const auto & right_src_data = right_arg_typed->getData();
const auto src_size = left_src_data.size();
auto & dst_data = dst->getData(); auto & dst_data = dst->getData();
const auto src_size = left_src_data.size();
dst_data.resize(src_size); dst_data.resize(src_size);
Float64 left_src_data_local[Impl::rows_per_iteration];
Float64 right_src_data_local[Impl::rows_per_iteration];
if constexpr (is_decimal<LeftType>)
{
UInt32 scale = left_arg->getScale();
for (size_t i = 0; i < src_size; ++i)
left_src_data_local[i] = DecimalUtils::convertTo<Float64>(left_src_data[i], scale);
}
if constexpr (is_decimal<RightType>)
{
UInt32 scale = right_arg_typed->getScale();
for (size_t i = 0; i < src_size; ++i)
right_src_data_local[i] = DecimalUtils::convertTo<Float64>(right_src_data[i], scale);
}
if constexpr (is_decimal<LeftType> && is_decimal<RightType>) if constexpr (is_decimal<LeftType> && is_decimal<RightType>)
{ {
executeInIterations(left_src_data_local, right_src_data_local, dst_data.data(), src_size); auto left = ColumnVector<Float64>::create();
auto & left_data = left->getData();
left_data.resize(src_size);
UInt32 left_scale = left_arg->getScale();
UInt32 right_scale = right_arg_typed->getScale();
for (size_t i = 0; i < src_size; ++i)
{
left_data[i] = DecimalUtils::convertTo<Float64>(left_src_data[i], left_scale);
dst_data[i] = DecimalUtils::convertTo<Float64>(right_src_data[i], right_scale);
}
executeInIterations(left_data.data(), dst_data.data(), dst_data.data(), src_size);
} }
else if constexpr (!is_decimal<LeftType> && is_decimal<RightType>) else if constexpr (!is_decimal<LeftType> && is_decimal<RightType>)
{ {
executeInIterations(left_src_data.data(), right_src_data_local, dst_data.data(), src_size); UInt32 scale = right_arg_typed->getScale();
for (size_t i = 0; i < src_size; ++i)
dst_data[i] = DecimalUtils::convertTo<Float64>(right_src_data[i], scale);
executeInIterations(left_src_data.data(), dst_data.data(), dst_data.data(), src_size);
} }
else if constexpr (is_decimal<LeftType> && !is_decimal<RightType>) else if constexpr (is_decimal<LeftType> && !is_decimal<RightType>)
{ {
executeInIterations(left_src_data_local, right_src_data.data(), dst_data.data(), src_size); UInt32 scale = left_arg->getScale();
for (size_t i = 0; i < src_size; ++i)
dst_data[i] = DecimalUtils::convertTo<Float64>(left_src_data[i], scale);
executeInIterations(dst_data.data(), right_src_data.data(), dst_data.data(), src_size);
} }
else else
{ {
@ -189,44 +248,48 @@ private:
auto dst = ColumnVector<Float64>::create(); auto dst = ColumnVector<Float64>::create();
const auto & left_src_data = left_arg->getData(); const auto & left_src_data = left_arg->getData();
RightType right_src_data[Impl::rows_per_iteration];
std::fill(std::begin(right_src_data), std::end(right_src_data), right_arg_typed->template getValue<RightType>());
const auto src_size = left_src_data.size();
auto & dst_data = dst->getData(); auto & dst_data = dst->getData();
const auto src_size = left_src_data.size();
dst_data.resize(src_size); dst_data.resize(src_size);
if constexpr (is_decimal<LeftType> && is_decimal<RightType>) if constexpr (is_decimal<RightType>)
{
Float64 right_src_data[Impl::rows_per_iteration];
UInt32 right_scale
= checkAndGetColumn<ColumnVectorOrDecimal<RightType>>(right_arg_typed->getDataColumnPtr().get())->getScale();
for (size_t i = 0; i < src_size; ++i)
right_src_data[i] = DecimalUtils::convertTo<Float64>(right_arg_typed->template getValue<RightType>(), right_scale);
if constexpr (is_decimal<LeftType>)
{ {
Float64 left_src_data_local[Impl::rows_per_iteration];
UInt32 left_scale = left_arg->getScale(); UInt32 left_scale = left_arg->getScale();
for (size_t i = 0; i < src_size; ++i) for (size_t i = 0; i < src_size; ++i)
left_src_data_local[i] = DecimalUtils::convertTo<Float64>(left_src_data[i], left_scale); dst_data[i] = DecimalUtils::convertTo<Float64>(left_src_data[i], left_scale);
UInt32 right_scale = checkAndGetColumn<ColumnVectorOrDecimal<RightType>>(right_arg_typed->getDataColumnPtr().get())->getScale(); executeInIterationsStaticRight(dst_data.data(), right_src_data, dst_data.data(), src_size);
Float64 right_src_data_local[Impl::rows_per_iteration];
for (size_t i = 0; i < src_size; ++i)
right_src_data_local[i] = DecimalUtils::convertTo<Float64>(right_src_data[i], right_scale);
executeInIterations(left_src_data_local, right_src_data_local, dst_data.data(), src_size);
}
else if constexpr (is_decimal<LeftType>)
{
Float64 left_src_data_local[Impl::rows_per_iteration];
UInt32 scale = left_arg->getScale();
for (size_t i = 0; i < src_size; ++i)
left_src_data_local[i] = DecimalUtils::convertTo<Float64>(left_src_data[i], scale);
executeInIterations(left_src_data_local, right_src_data, dst_data.data(), src_size);
}
else if constexpr (is_decimal<RightType>)
{
Float64 right_src_data_local[Impl::rows_per_iteration];
UInt32 right_scale = checkAndGetColumn<ColumnVectorOrDecimal<RightType>>(right_arg_typed->getDataColumnPtr().get())->getScale();
for (size_t i = 0; i < src_size; ++i)
right_src_data_local[i] = DecimalUtils::convertTo<Float64>(right_src_data[i], right_scale);
executeInIterations(left_src_data.data(), right_src_data_local, dst_data.data(), src_size);
} }
else else
{ {
executeInIterations(left_src_data.data(), right_src_data, dst_data.data(), src_size); executeInIterationsStaticRight(left_src_data.data(), right_src_data, dst_data.data(), src_size);
}
}
else
{
RightType right_src_data[Impl::rows_per_iteration];
std::fill(std::begin(right_src_data), std::end(right_src_data), right_arg_typed->template getValue<RightType>());
if constexpr (is_decimal<LeftType>)
{
UInt32 left_scale = left_arg->getScale();
for (size_t i = 0; i < src_size; ++i)
dst_data[i] = DecimalUtils::convertTo<Float64>(left_src_data[i], left_scale);
executeInIterationsStaticRight(dst_data.data(), right_src_data, dst_data.data(), src_size);
}
else
{
executeInIterationsStaticRight(left_src_data.data(), right_src_data, dst_data.data(), src_size);
}
} }
return dst; return dst;
@ -255,16 +318,16 @@ private:
if ((res = executeTyped<LeftType, RightType>(left_arg_typed, right_arg))) if ((res = executeTyped<LeftType, RightType>(left_arg_typed, right_arg)))
return true; return true;
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of second argument of function {}", throw Exception(
right_arg->getName(), getName()); ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of second argument of function {}", right_arg->getName(), getName());
} }
if (const auto left_arg_typed = checkAndGetColumnConst<ColVecLeft>(left_arg)) if (const auto left_arg_typed = checkAndGetColumnConst<ColVecLeft>(left_arg))
{ {
if ((res = executeTyped<LeftType, RightType>(left_arg_typed, right_arg))) if ((res = executeTyped<LeftType, RightType>(left_arg_typed, right_arg)))
return true; return true;
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of second argument of function {}", throw Exception(
right_arg->getName(), getName()); ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of second argument of function {}", right_arg->getName(), getName());
} }
return false; return false;
@ -274,8 +337,8 @@ private:
TypeIndex right_index = col_right.type->getTypeId(); TypeIndex right_index = col_right.type->getTypeId();
if (!callOnBasicTypes<true, true, true, false>(left_index, right_index, call)) if (!callOnBasicTypes<true, true, true, false>(left_index, right_index, call))
throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of argument of function {}", throw Exception(
col_left.column->getName(), getName()); ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of argument of function {}", col_left.column->getName(), getName());
return res; return res;
} }
@ -288,11 +351,10 @@ struct BinaryFunctionVectorized
static constexpr auto rows_per_iteration = 1; static constexpr auto rows_per_iteration = 1;
template <typename T1, typename T2> template <typename T1, typename T2>
static void execute(const T1 * src_left, const T2 * src_right, Float64 * dst) static void execute(const T1 * __restrict src_left, const T2 * __restrict src_right, Float64 * __restrict dst)
{ {
dst[0] = Function(static_cast<Float64>(src_left[0]), static_cast<Float64>(src_right[0])); *dst = Function(static_cast<Float64>(*src_left), static_cast<Float64>(*src_right));
} }
}; };
} }