// Copyright 2023 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include #include #include #include #include #include #include #include #include #include namespace DB { /// Methods, that helps dispatching over real column types. template const Type * checkAndGetDataType(const IDataType * data_type) { return typeid_cast(data_type); } template bool checkDataType(const IDataType * data_type) { return checkAndGetDataType(data_type); } template bool checkDataTypeArray(const IDataType * data_type) { const auto * array_type = checkAndGetDataType(data_type); if unlikely (!array_type) return false; const DataTypePtr & inner_type = array_type->getNestedType(); return checkDataType(inner_type.get()); } template const Type * checkAndGetColumn(const IColumn * column) { return typeid_cast(column); } template bool checkColumn(const IColumn * column) { return checkAndGetColumn(column); } template const Type * checkAndGetNestedColumn(const IColumn * column) { if (!column || !column->isColumnNullable()) return {}; const auto * data_column = &static_cast(column)->getNestedColumn(); return checkAndGetColumn(data_column); } template const ColumnConst * checkAndGetColumnConst(const IColumn * column, bool maybe_nullable_column = false) { if (!column || !column->isColumnConst()) return {}; const auto * res = static_cast(column); const auto * data_column = &res->getDataColumn(); if (maybe_nullable_column && data_column->isColumnNullable()) data_column = &typeid_cast(data_column)->getNestedColumn(); if (!checkColumn(data_column)) return {}; return res; } template const Type * checkAndGetColumnConstData(const IColumn * column) { const ColumnConst * res = checkAndGetColumnConst(column); if (!res) return {}; return static_cast(&res->getDataColumn()); } template bool checkColumnConst(const IColumn * column) { return checkAndGetColumnConst(column); } /// Returns non-nullptr if column is ColumnConst with ColumnString or ColumnFixedString inside. const ColumnConst * checkAndGetColumnConstStringOrFixedString(const IColumn * column); /// Transform anything to Field. template inline std::enable_if_t, Field> toField(const T & x) { return Field(typename NearestFieldType::Type(x)); } template inline std::enable_if_t, Field> toField(const T & x, UInt32 scale) { return DecimalField(x, scale); } Columns convertConstTupleToConstantElements(const ColumnConst & column); /// Returns the copy of a given block in which each column specified in /// the "arguments" parameter is replaced with its respective nested /// column if it is nullable. Block createBlockWithNestedColumns(const Block & block, const ColumnNumbers & args); /// Similar function as above. Additionally transform the result type if needed. Block createBlockWithNestedColumns(const Block & block, const ColumnNumbers & args, size_t result); bool functionIsInOperator(const String & name); bool functionIsInOrGlobalInOperator(const String & name); template struct IGetVecHelper { static_assert(std::is_arithmetic_v); virtual T get(size_t) const = 0; virtual ~IGetVecHelper() = default; static std::unique_ptr getHelper(const ColumnVector * p); static std::unique_ptr getHelper(const ColumnConst * p); }; template struct GetVecHelper : public IGetVecHelper { explicit GetVecHelper(const ColumnVector * p_) : p(p_) {} T get(size_t i) const override { return p->getElement(i); } private: const ColumnVector * p; }; template struct GetConstVecHelper : public IGetVecHelper { explicit GetConstVecHelper(const ColumnConst * p_) : value(p_->getValue()) {} T get(size_t) const override { return value; } private: T value; }; template std::unique_ptr> IGetVecHelper::getHelper(const ColumnVector * p) { return std::unique_ptr>{new GetVecHelper{p}}; } template std::unique_ptr> IGetVecHelper::getHelper(const ColumnConst * p) { return std::unique_ptr>{new GetConstVecHelper{p}}; } static Field FIELD_NULL = toField(Null{}); static Field FIELD_INT8_1 = toField(Int8(1)); static Field FIELD_INT8_0 = toField(Int8(0)); } // namespace DB