From 286baa8611e277736a9fa149beb080a048b13fa9 Mon Sep 17 00:00:00 2001 From: Alexey Arno Date: Wed, 4 May 2016 02:19:14 +0300 Subject: [PATCH] Merge --- dbms/CMakeLists.txt | 8 +- dbms/include/DB/DataTypes/DataTypeArray.h | 7 +- .../DB/DataTypes/DataTypesNumberFixed.h | 11 +- dbms/include/DB/DataTypes/IDataTypeNumber.h | 21 + .../DB/DataTypes/IDataTypeNumberFixed.h | 14 + .../DB/Functions/Conditional/ArrayEvaluator.h | 20 +- .../DB/Functions/Conditional/CondException.h | 48 + .../Functions/Conditional/NumericEvaluator.h | 19 +- .../include/DB/Functions/Conditional/common.h | 76 - .../DB/Functions/Conditional/getArrayType.h | 17 + .../Functions/DataTypeFromFieldTypeOrError.h | 26 - dbms/include/DB/Functions/DataTypeTraits.h | 137 + .../DB/Functions/EnrichedDataTypePtr.h | 18 + dbms/include/DB/Functions/FunctionsArray.h | 158 +- .../DB/Functions/FunctionsConditional.h | 266 +- .../include/DB/Functions/FunctionsTransform.h | 279 +- dbms/include/DB/Functions/NumberTraits.h | 681 +- dbms/include/DB/Parsers/ASTFunction.h | 59 +- dbms/include/DB/Parsers/ParserCase.h | 21 + dbms/src/Core/ErrorCodes.cpp | 1 + dbms/src/DataTypes/DataTypeArray.cpp | 8 +- dbms/src/Functions/Conditional/ArgsInfo.cpp | 303 +- dbms/src/Functions/Conditional/CondSource.cpp | 6 +- .../Conditional/NumericPerformer.cpp | 264 +- .../Functions/Conditional/StringEvaluator.cpp | 1 + .../Functions/Conditional/getArrayType.cpp | 144 + dbms/src/Functions/FunctionsTransform.cpp | 110 +- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 36 +- dbms/src/Parsers/ASTFunction.cpp | 139 + dbms/src/Parsers/ExpressionElementParsers.cpp | 7 +- dbms/src/Parsers/ParserCase.cpp | 164 + .../0_stateless/00326_function_multi_if.sql | 9 +- .../00328_case_construction.reference | 25415 ++++++++++++++++ .../0_stateless/00328_case_construction.sql | 2601 ++ 34 files changed, 30013 insertions(+), 1081 deletions(-) create mode 100644 dbms/include/DB/Functions/Conditional/CondException.h create mode 100644 dbms/include/DB/Functions/Conditional/getArrayType.h delete mode 100644 dbms/include/DB/Functions/DataTypeFromFieldTypeOrError.h create mode 100644 dbms/include/DB/Functions/DataTypeTraits.h create mode 100644 dbms/include/DB/Functions/EnrichedDataTypePtr.h create mode 100644 dbms/include/DB/Parsers/ParserCase.h create mode 100644 dbms/src/Functions/Conditional/getArrayType.cpp create mode 100644 dbms/src/Parsers/ParserCase.cpp create mode 100644 dbms/tests/queries/0_stateless/00328_case_construction.reference create mode 100644 dbms/tests/queries/0_stateless/00328_case_construction.sql diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt index a02cd2966f9..66181589541 100644 --- a/dbms/CMakeLists.txt +++ b/dbms/CMakeLists.txt @@ -28,7 +28,9 @@ add_library (dbms include/DB/Functions/FunctionsString.h include/DB/Functions/FunctionsRound.h include/DB/Functions/FunctionsTransform.h + include/DB/Functions/Conditional/CondException.h include/DB/Functions/Conditional/common.h + include/DB/Functions/Conditional/getArrayType.h include/DB/Functions/Conditional/ArgsInfo.h include/DB/Functions/Conditional/CondSource.h include/DB/Functions/Conditional/NumericPerformer.h @@ -51,7 +53,8 @@ add_library (dbms include/DB/Functions/IFunction.h include/DB/Functions/FunctionsFormatting.h include/DB/Functions/NumberTraits.h - include/DB/Functions/DataTypeFromFieldTypeOrError.h + include/DB/Functions/DataTypeTraits.h + include/DB/Functions/EnrichedDataTypePtr.h include/DB/TableFunctions/TableFunctionRemote.h include/DB/TableFunctions/TableFunctionFactory.h include/DB/TableFunctions/TableFunctionMerge.h @@ -114,6 +117,7 @@ add_library (dbms include/DB/Parsers/IParser.h include/DB/Parsers/ASTSampleRatio.h include/DB/Parsers/ParserSampleRatio.h + include/DB/Parsers/ParserCase.h include/DB/AggregateFunctions/AggregateFunctionMerge.h include/DB/AggregateFunctions/AggregateFunctionUniqUpTo.h include/DB/AggregateFunctions/AggregateFunctionIf.h @@ -761,6 +765,7 @@ add_library (dbms src/Parsers/ParserAlterQuery.cpp src/Parsers/ParserCheckQuery.cpp src/Parsers/ParserSampleRatio.cpp + src/Parsers/ParserCase.cpp src/Parsers/formatAST.cpp src/Parsers/parseQuery.cpp src/Parsers/queryToString.cpp @@ -827,6 +832,7 @@ add_library (dbms src/Functions/FunctionsMath.cpp src/Functions/FunctionsMiscellaneous.cpp src/Functions/FunctionsTransform.cpp + src/Functions/Conditional/getArrayType.cpp src/Functions/Conditional/ArgsInfo.cpp src/Functions/Conditional/CondSource.cpp src/Functions/Conditional/NumericPerformer.cpp diff --git a/dbms/include/DB/DataTypes/DataTypeArray.h b/dbms/include/DB/DataTypes/DataTypeArray.h index 7b9aaef2f34..c04a264f39d 100644 --- a/dbms/include/DB/DataTypes/DataTypeArray.h +++ b/dbms/include/DB/DataTypes/DataTypeArray.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace DB @@ -12,6 +13,8 @@ using Poco::SharedPtr; class DataTypeArray final : public IDataType { private: + /// Расширенный тип элементов массивов. + DataTypeTraits::EnrichedDataTypePtr enriched_nested; /// Тип элементов массивов. DataTypePtr nested; /// Тип смещений. @@ -19,6 +22,7 @@ private: public: DataTypeArray(DataTypePtr nested_); + DataTypeArray(DataTypeTraits::EnrichedDataTypePtr enriched_nested_); std::string getName() const override { @@ -27,7 +31,7 @@ public: DataTypePtr clone() const override { - return new DataTypeArray(nested); + return new DataTypeArray(enriched_nested); } void serializeBinary(const Field & field, WriteBuffer & ostr) const override; @@ -82,6 +86,7 @@ public: } const DataTypePtr & getNestedType() const { return nested; } + const DataTypeTraits::EnrichedDataTypePtr & getEnrichedNestedType() const { return enriched_nested; } const DataTypePtr & getOffsetsType() const { return offsets; } }; diff --git a/dbms/include/DB/DataTypes/DataTypesNumberFixed.h b/dbms/include/DB/DataTypes/DataTypesNumberFixed.h index 6626d11fb26..0669c31dfbf 100644 --- a/dbms/include/DB/DataTypes/DataTypesNumberFixed.h +++ b/dbms/include/DB/DataTypes/DataTypesNumberFixed.h @@ -40,9 +40,18 @@ DEFINE_DATA_TYPE_NUMBER_FIXED(Float64); /// The following type is not a real column data type. It is used in the multiIf /// function implementation for argument type checking. + +class DataTypeVoid : public IDataTypeNumberFixed +{ +public: + DataTypeVoid() = default; + std::string getName() const override { return "void"; } + DataTypePtr clone() const override { return new DataTypeVoid; } +}; + template <> struct DataTypeFromFieldType { - typedef void Type; + typedef DataTypeVoid Type; }; } diff --git a/dbms/include/DB/DataTypes/IDataTypeNumber.h b/dbms/include/DB/DataTypes/IDataTypeNumber.h index 420da7f5036..c65fdf7acae 100644 --- a/dbms/include/DB/DataTypes/IDataTypeNumber.h +++ b/dbms/include/DB/DataTypes/IDataTypeNumber.h @@ -108,6 +108,27 @@ public: } }; +template <> +class IDataTypeNumber : public IDataType +{ +public: + using FieldType = void; + + bool isNumeric() const override { return true; } + bool behavesAsNumber() const override { return true; } + void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override {} + void serializeTextEscaped(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override {} + void deserializeTextEscaped(IColumn & column, ReadBuffer & istr) const override {} + void serializeTextQuoted(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override {} + void deserializeTextQuoted(IColumn & column, ReadBuffer & istr) const override {} + void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override {} + void deserializeTextJSON(IColumn & column, ReadBuffer & istr) const override {} + void serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override {} + void deserializeTextCSV(IColumn & column, ReadBuffer & istr, const char delimiter) const override {} + size_t getSizeOfField() const override { return 0; } + Field getDefault() const override { return {}; } +}; + template inline void IDataTypeNumber::serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr) const { serializeText(column, row_num, ostr); diff --git a/dbms/include/DB/DataTypes/IDataTypeNumberFixed.h b/dbms/include/DB/DataTypes/IDataTypeNumberFixed.h index 8d96815ecbd..82cc4cc4c91 100644 --- a/dbms/include/DB/DataTypes/IDataTypeNumberFixed.h +++ b/dbms/include/DB/DataTypes/IDataTypeNumberFixed.h @@ -83,5 +83,19 @@ public: } }; +template <> +class IDataTypeNumberFixed : public IDataTypeNumber +{ +public: + void serializeBinary(const Field & field, WriteBuffer & ostr) const override {} + void deserializeBinary(Field & field, ReadBuffer & istr) const override {} + void serializeBinary(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override {} + void deserializeBinary(IColumn & column, ReadBuffer & istr) const override {} + void serializeBinary(const IColumn & column, WriteBuffer & ostr, size_t offset = 0, size_t limit = 0) const override {} + void deserializeBinary(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const override {} + ColumnPtr createColumn() const override { return {}; } + ColumnPtr createConstColumn(size_t size, const Field & field) const override { return {}; } +}; + } diff --git a/dbms/include/DB/Functions/Conditional/ArrayEvaluator.h b/dbms/include/DB/Functions/Conditional/ArrayEvaluator.h index 6cf6f0b54fa..e7228b21f96 100644 --- a/dbms/include/DB/Functions/Conditional/ArrayEvaluator.h +++ b/dbms/include/DB/Functions/Conditional/ArrayEvaluator.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -13,7 +14,6 @@ namespace ErrorCodes { extern const int LOGICAL_ERROR; -extern const int ILLEGAL_TYPE_OF_ARGUMENT; } @@ -317,10 +317,6 @@ public: } } -private: - template - using ConcreteArraySourceCreator = ArraySourceCreator; - private: /// Create accessors for condition values. static CondSources createConds(const Block & block, const ColumnNumbers & args) @@ -342,7 +338,16 @@ private: for (const auto & br : branches) { - if (!NumericTypeDispatcher::apply(sources, block, args, br)) + if (! (ArraySourceCreator::execute(sources, block, args, br) + || ArraySourceCreator::execute(sources, block, args, br) + || ArraySourceCreator::execute(sources, block, args, br) + || ArraySourceCreator::execute(sources, block, args, br) + || ArraySourceCreator::execute(sources, block, args, br) + || ArraySourceCreator::execute(sources, block, args, br) + || ArraySourceCreator::execute(sources, block, args, br) + || ArraySourceCreator::execute(sources, block, args, br) + || ArraySourceCreator::execute(sources, block, args, br) + || ArraySourceCreator::execute(sources, block, args, br))) throw Exception{"Internal error", ErrorCodes::LOGICAL_ERROR}; } @@ -393,8 +398,7 @@ class ArrayEvaluator public: static void perform(const Branches & branches, Block & block, const ColumnNumbers & args, size_t result) { - throw Exception{"Internal logic error: one or more arguments of function " - "multiIf have invalid types", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; + throw CondException{CondErrorCodes::ARRAY_EVALUATOR_INVALID_TYPES}; } }; diff --git a/dbms/include/DB/Functions/Conditional/CondException.h b/dbms/include/DB/Functions/Conditional/CondException.h new file mode 100644 index 00000000000..07ba26ec17f --- /dev/null +++ b/dbms/include/DB/Functions/Conditional/CondException.h @@ -0,0 +1,48 @@ +#pragma once + +#include + +namespace DB +{ + +namespace Conditional +{ + +enum class CondErrorCodes +{ + TYPE_DEDUCER_ILLEGAL_COLUMN_TYPE, + TYPE_DEDUCER_UPSCALING_ERROR, + NUMERIC_PERFORMER_ILLEGAL_COLUMN, + COND_SOURCE_ILLEGAL_COLUMN, + NUMERIC_EVALUATOR_ILLEGAL_ARGUMENT, + ARRAY_EVALUATOR_INVALID_TYPES +}; + +/// Since the building blocks of the multiIf function may be called +/// in various contexts, their error management must be achieved in +/// a context-free manner. Hence the need for the following class. +class CondException : public DB::Exception +{ +public: + CondException(CondErrorCodes code_, const std::string & msg1_ = "", const std::string & msg2_ = "") + : code{code_}, msg1{msg1_}, msg2{msg2_} + { + } + + const char * name() const throw() override { return "DB::Conditional::Exception"; } + const char * className() const throw() override { return "DB::Conditional::Exception"; } + CondException * clone() const override { return new CondException{*this}; } + void rethrow() const override { throw *this; } + CondErrorCodes getCode() const { return code; } + std::string getMsg1() const { return msg1; } + std::string getMsg2() const { return msg2; } + +private: + CondErrorCodes code; + std::string msg1; + std::string msg2; +}; + +} + +} diff --git a/dbms/include/DB/Functions/Conditional/NumericEvaluator.h b/dbms/include/DB/Functions/Conditional/NumericEvaluator.h index 1945a4e4198..374bd3869fa 100644 --- a/dbms/include/DB/Functions/Conditional/NumericEvaluator.h +++ b/dbms/include/DB/Functions/Conditional/NumericEvaluator.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -161,10 +162,6 @@ public: } } -private: - template - using ConcreteNumericSourceCreator = NumericSourceCreator; - private: /// Create the result column. static PaddedPODArray & createSink(Block & block, size_t result, size_t size) @@ -200,9 +197,17 @@ private: { NumericSourcePtr source; - if (!NumericTypeDispatcher::apply(source, block, args, br)) - throw Exception{"Illegal type of argument " + toString(br.index) + " of function multiIf", - ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; + if (! (NumericSourceCreator::execute(source, block, args, br) + || NumericSourceCreator::execute(source, block, args, br) + || NumericSourceCreator::execute(source, block, args, br) + || NumericSourceCreator::execute(source, block, args, br) + || NumericSourceCreator::execute(source, block, args, br) + || NumericSourceCreator::execute(source, block, args, br) + || NumericSourceCreator::execute(source, block, args, br) + || NumericSourceCreator::execute(source, block, args, br) + || NumericSourceCreator::execute(source, block, args, br) + || NumericSourceCreator::execute(source, block, args, br))) + throw CondException{CondErrorCodes::NUMERIC_EVALUATOR_ILLEGAL_ARGUMENT, toString(br.index)}; sources.push_back(std::move(source)); } diff --git a/dbms/include/DB/Functions/Conditional/common.h b/dbms/include/DB/Functions/Conditional/common.h index 98bf5ae4cbb..41a43db0ad0 100644 --- a/dbms/include/DB/Functions/Conditional/common.h +++ b/dbms/include/DB/Functions/Conditional/common.h @@ -1,87 +1,11 @@ #pragma once -#include - namespace DB { namespace Conditional { -/// Execute a given parametrized predicate for each type from a given list of -/// types until it returns true for one of these types. -template