ugly version

This commit is contained in:
Persiyanov Dmitriy Andreevich 2018-11-21 13:10:22 +03:00
parent ff5629263b
commit b3e694e3eb
3 changed files with 62 additions and 3 deletions

View File

@ -128,7 +128,7 @@ struct PlusImpl
return static_cast<Result>(a) + b;
}
/// Apply operation and check overflow. It's used for Deciamal operations. @returns true if overflowed, false othervise.
/// Apply operation and check overflow. It's used for Decimal operations. @returns true if overflowed, false otherwise.
template <typename Result = ResultType>
static inline bool apply(A a, B b, Result & c)
{
@ -158,7 +158,7 @@ struct MultiplyImpl
return static_cast<Result>(a) * b;
}
/// Apply operation and check overflow. It's used for Deciamal operations. @returns true if overflowed, false othervise.
/// Apply operation and check overflow. It's used for Decimal operations. @returns true if overflowed, false otherwise.
template <typename Result = ResultType>
static inline bool apply(A a, B b, Result & c)
{
@ -187,7 +187,7 @@ struct MinusImpl
return static_cast<Result>(a) - b;
}
/// Apply operation and check overflow. It's used for Deciamal operations. @returns true if overflowed, false othervise.
/// Apply operation and check overflow. It's used for Decimal operations. @returns true if overflowed, false otherwise.
template <typename Result = ResultType>
static inline bool apply(A a, B b, Result & c)
{

View File

@ -9,6 +9,7 @@ void registerFunctionsRound(FunctionFactory & factory)
factory.registerFunction<FunctionRoundToExp2>();
factory.registerFunction<FunctionRoundDuration>();
factory.registerFunction<FunctionRoundAge>();
factory.registerFunction<FunctionRoundDown>();
factory.registerFunction<FunctionRound>("round", FunctionFactory::CaseInsensitive);
factory.registerFunction<FunctionFloor>("floor", FunctionFactory::CaseInsensitive);

View File

@ -21,6 +21,7 @@ namespace DB
namespace ErrorCodes
{
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int ILLEGAL_COLUMN;
}
@ -665,6 +666,63 @@ public:
};
class FunctionRoundDown : public IFunction {
public:
static constexpr auto name = "roundDown";
static FunctionPtr create(const Context &) { return std::make_shared<FunctionRounding>(); }
public:
String getName() const override
{
return name;
}
bool isVariadic() const override { return false; }
size_t getNumberOfArguments() const override { return 2; }
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; }
void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override {
const ColumnConst * array = checkAndGetColumnConst<ColumnArray>(block.getByPosition(arguments[1]).column.get());
if (!array)
throw Exception{"Second argument of function " + getName() + " must be constant array.", ErrorCodes::ILLEGAL_COLUMN};
const Array & boundaries = array->getValue<Array>();
const auto src = checkAndGetColumn<ColumnVector<Int32>>(block.getByPosition(arguments.front()).column.get())->getdata();
auto column_result = block.getByPosition(result).type->createColumn();
auto dst = checkAndGetColumn<ColumnVector<Int32>>(column_result.get())->getData();
size_t size = src.size();
size_t boundaries_size = boundaries.size();
dst.resize(size);
for (size_t i = 0; i < size; ++i)
{
if (src[i] < boundaries[0].get<Int32>())
{
dst[i] = boundaries[0].get<Int32>();
}
else if (src[i] >= boundaries.back().get<Int32>()) {
dst[i] = boundaries.back().get<Int32>();
}
else
{
for (size_t j = 1; j < boundaries_size; ++j) {
if (src[i] < boundaries[i].get<Int32>())
{
dst[i] = boundaries[i - 1].get<Int32>();
break;
}
}
}
}
block.getByPosition(result).column = std::move(column_result);
}
};
struct NameRoundToExp2 { static constexpr auto name = "roundToExp2"; };
struct NameRoundDuration { static constexpr auto name = "roundDuration"; };
struct NameRoundAge { static constexpr auto name = "roundAge"; };