// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you 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 "exprs/hybrid_set.h" #include "exprs/minmax_predicate.h" #include "function_filter.h" #include "olap/bitmap_filter_predicate.h" #include "olap/bloom_filter_predicate.h" #include "olap/column_predicate.h" #include "olap/in_list_predicate.h" #include "olap/like_column_predicate.h" #include "runtime/define_primitive_type.h" namespace doris { class MinmaxFunctionTraits { public: using BasePtr = MinMaxFuncBase*; template static BasePtr get_function() { return new MinMaxNumFunc::CppType>(); } }; class HybridSetTraits { public: using BasePtr = HybridSetBase*; template static BasePtr get_function() { using CppType = typename PrimitiveTypeTraits::CppType; if constexpr (N >= 1 && N <= FIXED_CONTAINER_MAX_SIZE) { using Set = std::conditional_t< std::is_same_v, StringSet<>, HybridSet::CppType, N>>>; return new Set(); } else { using Set = std::conditional_t< std::is_same_v, StringSet<>, HybridSet::CppType>>>; return new Set(); } } }; class BloomFilterTraits { public: using BasePtr = BloomFilterFuncBase*; template static BasePtr get_function() { return new BloomFilterFunc(); } }; class BitmapFilterTraits { public: using BasePtr = BitmapFilterFuncBase*; template static BasePtr get_function() { return new BitmapFilterFunc(); } }; template class PredicateFunctionCreator { public: template static typename Traits::BasePtr create() { return Traits::template get_function(); } }; #define APPLY_FOR_PRIMTYPE(M) \ M(TYPE_TINYINT) \ M(TYPE_SMALLINT) \ M(TYPE_INT) \ M(TYPE_BIGINT) \ M(TYPE_LARGEINT) \ M(TYPE_FLOAT) \ M(TYPE_DOUBLE) \ M(TYPE_DATE) \ M(TYPE_DATETIME) \ M(TYPE_DATEV2) \ M(TYPE_DATETIMEV2) \ M(TYPE_CHAR) \ M(TYPE_VARCHAR) \ M(TYPE_STRING) \ M(TYPE_DECIMAL32) \ M(TYPE_DECIMAL64) \ M(TYPE_DECIMAL128I) \ M(TYPE_DECIMAL256) \ M(TYPE_IPV4) \ M(TYPE_IPV6) template typename Traits::BasePtr create_predicate_function(PrimitiveType type) { using Creator = PredicateFunctionCreator; switch (type) { case TYPE_BOOLEAN: { return Creator::template create(); } case TYPE_DECIMALV2: { return Creator::template create(); } #define M(NAME) \ case NAME: { \ return Creator::template create(); \ } APPLY_FOR_PRIMTYPE(M) #undef M default: throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, "predicate with type " + type_to_string(type)); } return nullptr; } template typename Traits::BasePtr create_bitmap_predicate_function(PrimitiveType type) { using Creator = PredicateFunctionCreator; switch (type) { case TYPE_TINYINT: return Creator::template create(); case TYPE_SMALLINT: return Creator::template create(); case TYPE_INT: return Creator::template create(); case TYPE_BIGINT: return Creator::template create(); default: DCHECK(false) << "Invalid type: " << type_to_string(type); } return nullptr; } inline auto create_minmax_filter(PrimitiveType type) { return create_predicate_function(type); } template inline auto create_set(PrimitiveType type) { return create_predicate_function(type); } inline auto create_set(PrimitiveType type, size_t size) { if (size == 0) { return create_set<0>(type); } else if (size == 1) { return create_set<1>(type); } else if (size == 2) { return create_set<2>(type); } else if (size == 3) { return create_set<3>(type); } else if (size == 4) { return create_set<4>(type); } else if (size == 5) { return create_set<5>(type); } else if (size == 6) { return create_set<6>(type); } else if (size == 7) { return create_set<7>(type); } else if (size == FIXED_CONTAINER_MAX_SIZE) { return create_set(type); } else { return create_set(type); } } template inline HybridSetBase* create_string_value_set() { if constexpr (N >= 1 && N <= FIXED_CONTAINER_MAX_SIZE) { return new StringValueSet>(); } else { return new StringValueSet(); } } inline HybridSetBase* create_string_value_set(size_t size) { if (size == 1) { return create_string_value_set<1>(); } else if (size == 2) { return create_string_value_set<2>(); } else if (size == 3) { return create_string_value_set<3>(); } else if (size == 4) { return create_string_value_set<4>(); } else if (size == 5) { return create_string_value_set<5>(); } else if (size == 6) { return create_string_value_set<6>(); } else if (size == 7) { return create_string_value_set<7>(); } else if (size == FIXED_CONTAINER_MAX_SIZE) { return create_string_value_set(); } else { return create_string_value_set(); } } inline auto create_bloom_filter(PrimitiveType type) { return create_predicate_function(type); } inline auto create_bitmap_filter(PrimitiveType type) { return create_bitmap_predicate_function(type); } template ColumnPredicate* create_olap_column_predicate(uint32_t column_id, const std::shared_ptr& filter, int be_exec_version, const TabletColumn*) { std::shared_ptr filter_olap; filter_olap.reset(create_bloom_filter(PT)); filter_olap->light_copy(filter.get()); return new BloomFilterColumnPredicate(column_id, filter); } template ColumnPredicate* create_olap_column_predicate(uint32_t column_id, const std::shared_ptr& filter, int be_exec_version, const TabletColumn*) { if constexpr (PT == TYPE_TINYINT || PT == TYPE_SMALLINT || PT == TYPE_INT || PT == TYPE_BIGINT) { std::shared_ptr filter_olap; filter_olap.reset(create_bitmap_filter(PT)); filter_olap->light_copy(filter.get()); return new BitmapFilterColumnPredicate(column_id, filter, be_exec_version); } else { return nullptr; } } template ColumnPredicate* create_olap_column_predicate(uint32_t column_id, const std::shared_ptr& filter, int, const TabletColumn* column = nullptr) { return create_in_list_predicate(column_id, filter, column->length()); } template ColumnPredicate* create_olap_column_predicate(uint32_t column_id, const std::shared_ptr& filter, int, const TabletColumn* column = nullptr) { // currently only support like predicate if constexpr (PT == TYPE_CHAR || PT == TYPE_VARCHAR || PT == TYPE_STRING) { if constexpr (PT == TYPE_CHAR) { return new LikeColumnPredicate(filter->_opposite, column_id, filter->_fn_ctx, filter->_string_param); } else { return new LikeColumnPredicate(filter->_opposite, column_id, filter->_fn_ctx, filter->_string_param); } } else { return nullptr; } } template ColumnPredicate* create_column_predicate(uint32_t column_id, const std::shared_ptr& filter, FieldType type, int be_exec_version, const TabletColumn* column = nullptr) { switch (type) { #define M(NAME) \ case FieldType::OLAP_FIELD_##NAME: { \ return create_olap_column_predicate(column_id, filter, be_exec_version, column); \ } APPLY_FOR_PRIMTYPE(M) #undef M case FieldType::OLAP_FIELD_TYPE_DECIMAL: { return create_olap_column_predicate(column_id, filter, be_exec_version, column); } case FieldType::OLAP_FIELD_TYPE_BOOL: { return create_olap_column_predicate(column_id, filter, be_exec_version, column); } default: return nullptr; } } } // namespace doris