diff --git a/be/src/storage/predicate/predicate_creator_in_list_impl.h b/be/src/storage/predicate/predicate_creator_in_list_impl.h new file mode 100644 index 00000000000000..3306abfd96c8d0 --- /dev/null +++ b/be/src/storage/predicate/predicate_creator_in_list_impl.h @@ -0,0 +1,117 @@ +// 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. + +// This header contains the shared implementation of create_in_list_predicate. +// It is included by predicate_creator_in_list_in.cpp and +// predicate_creator_in_list_not_in.cpp, which each provide one explicit +// instantiation so the two translation units can be compiled in parallel. + +#pragma once + +#include "common/exception.h" +#include "common/status.h" +#include "core/call_on_type_index.h" +#include "core/data_type/data_type_string.h" +#include "storage/predicate/in_list_predicate.h" +#include "storage/predicate/predicate_creator.h" + +namespace doris { + +template +static std::shared_ptr create_in_list_predicate_impl( + const uint32_t cid, const std::string col_name, const std::shared_ptr& set, + bool is_opposite, size_t char_length = 0) { + // Only string types construct their own HybridSetType in the constructor (to convert + // from DynamicContainer to FixedContainer), so N dispatch is only needed + // for them. All other types directly share the caller's hybrid_set. + if constexpr (!is_string_type(TYPE)) { + return InListPredicateBase::create_shared( + cid, col_name, set, is_opposite, char_length); + } else { + auto set_size = set->size(); + if (set_size == 1) { + return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, + char_length); + } else if (set_size == 2) { + return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, + char_length); + } else if (set_size == 3) { + return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, + char_length); + } else if (set_size == 4) { + return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, + char_length); + } else if (set_size == 5) { + return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, + char_length); + } else if (set_size == 6) { + return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, + char_length); + } else if (set_size == 7) { + return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, + char_length); + } else if (set_size == FIXED_CONTAINER_MAX_SIZE) { + return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, + char_length); + } else { + return InListPredicateBase::create_shared( + cid, col_name, set, is_opposite, char_length); + } + } +} + +template +std::shared_ptr create_in_list_predicate(const uint32_t cid, + const std::string col_name, + const DataTypePtr& data_type, + const std::shared_ptr set, + bool is_opposite) { + auto primitive_type = data_type->get_primitive_type(); + std::shared_ptr result; + + // Dispatch all scalar (non-string) types uniformly. dispatch_switch_scalar + // covers INT / FLOAT / DECIMAL / DATETIME / IP groups without collapsing the + // three distinct string PrimitiveTypes, so the string cases below can each + // keep their own template argument (TYPE_CHAR needs char_length too). + bool matched = dispatch_switch_scalar(primitive_type, [&](auto type_tag) { + constexpr PrimitiveType TYPE = decltype(type_tag)::PType; + result = create_in_list_predicate_impl(cid, col_name, set, is_opposite); + return true; + }); + if (matched) { + return result; + } + + // String types: CHAR carries a fixed char_length; VARCHAR and STRING are + // distinct predicate template arguments and cannot be collapsed. + switch (primitive_type) { + case TYPE_CHAR: + return create_in_list_predicate_impl( + cid, col_name, set, is_opposite, + assert_cast(remove_nullable(data_type).get())->len()); + case TYPE_VARCHAR: + return create_in_list_predicate_impl(cid, col_name, set, is_opposite); + case TYPE_STRING: + return create_in_list_predicate_impl(cid, col_name, set, is_opposite); + default: + throw Exception(Status::InternalError("Unsupported type {} for in_predicate", + type_to_string(primitive_type))); + return nullptr; + } +} + +} // namespace doris diff --git a/be/src/storage/predicate/predicate_creator_in_list_in.cpp b/be/src/storage/predicate/predicate_creator_in_list_in.cpp index e720da632a8ad4..0df056bb1866a7 100644 --- a/be/src/storage/predicate/predicate_creator_in_list_in.cpp +++ b/be/src/storage/predicate/predicate_creator_in_list_in.cpp @@ -15,160 +15,12 @@ // specific language governing permissions and limitations // under the License. -#include "common/exception.h" -#include "common/status.h" -#include "core/data_type/data_type_string.h" -#include "storage/predicate/in_list_predicate.h" -#include "storage/predicate/predicate_creator.h" +#include "storage/predicate/predicate_creator_in_list_impl.h" namespace doris { -template -static std::shared_ptr create_in_list_predicate_impl( - const uint32_t cid, const std::string col_name, const std::shared_ptr& set, - bool is_opposite, size_t char_length = 0) { - // Only string types construct their own HybridSetType in the constructor (to convert - // from DynamicContainer to FixedContainer), so N dispatch is only needed - // for them. All other types directly share the caller's hybrid_set. - if constexpr (!is_string_type(TYPE)) { - return InListPredicateBase::create_shared( - cid, col_name, set, is_opposite, char_length); - } else { - auto set_size = set->size(); - if (set_size == 1) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 2) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 3) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 4) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 5) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 6) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 7) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == FIXED_CONTAINER_MAX_SIZE) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else { - return InListPredicateBase::create_shared( - cid, col_name, set, is_opposite, char_length); - } - } -} - -template <> -std::shared_ptr create_in_list_predicate( - const uint32_t cid, const std::string col_name, const DataTypePtr& data_type, - const std::shared_ptr set, bool is_opposite) { - switch (data_type->get_primitive_type()) { - case TYPE_TINYINT: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_SMALLINT: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_INT: { - return create_in_list_predicate_impl(cid, col_name, set, - is_opposite); - } - case TYPE_BIGINT: { - return create_in_list_predicate_impl(cid, col_name, - set, is_opposite); - } - case TYPE_LARGEINT: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_FLOAT: { - return create_in_list_predicate_impl(cid, col_name, set, - is_opposite); - } - case TYPE_DOUBLE: { - return create_in_list_predicate_impl(cid, col_name, - set, is_opposite); - } - case TYPE_DECIMALV2: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DECIMAL32: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DECIMAL64: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DECIMAL128I: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DECIMAL256: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_CHAR: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite, - assert_cast(remove_nullable(data_type).get())->len()); - } - case TYPE_VARCHAR: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_STRING: { - return create_in_list_predicate_impl(cid, col_name, - set, is_opposite); - } - case TYPE_DATE: { - return create_in_list_predicate_impl(cid, col_name, set, - is_opposite); - } - case TYPE_DATEV2: { - return create_in_list_predicate_impl(cid, col_name, - set, is_opposite); - } - case TYPE_DATETIME: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DATETIMEV2: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_TIMESTAMPTZ: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_BOOLEAN: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_IPV4: { - return create_in_list_predicate_impl(cid, col_name, set, - is_opposite); - } - case TYPE_IPV6: { - return create_in_list_predicate_impl(cid, col_name, set, - is_opposite); - } - default: - throw Exception(Status::InternalError("Unsupported type {} for in_predicate", - type_to_string(data_type->get_primitive_type()))); - return nullptr; - } -} +template std::shared_ptr create_in_list_predicate( + const uint32_t, const std::string, const DataTypePtr&, const std::shared_ptr, + bool); } // namespace doris diff --git a/be/src/storage/predicate/predicate_creator_in_list_not_in.cpp b/be/src/storage/predicate/predicate_creator_in_list_not_in.cpp index 63e8eb37b186a3..cb2c393a223615 100644 --- a/be/src/storage/predicate/predicate_creator_in_list_not_in.cpp +++ b/be/src/storage/predicate/predicate_creator_in_list_not_in.cpp @@ -15,160 +15,12 @@ // specific language governing permissions and limitations // under the License. -#include "common/exception.h" -#include "common/status.h" -#include "core/data_type/data_type_string.h" -#include "storage/predicate/in_list_predicate.h" -#include "storage/predicate/predicate_creator.h" +#include "storage/predicate/predicate_creator_in_list_impl.h" namespace doris { -template -static std::shared_ptr create_in_list_predicate_impl( - const uint32_t cid, const std::string col_name, const std::shared_ptr& set, - bool is_opposite, size_t char_length = 0) { - // Only string types construct their own HybridSetType in the constructor (to convert - // from DynamicContainer to FixedContainer), so N dispatch is only needed - // for them. All other types directly share the caller's hybrid_set. - if constexpr (!is_string_type(TYPE)) { - return InListPredicateBase::create_shared( - cid, col_name, set, is_opposite, char_length); - } else { - auto set_size = set->size(); - if (set_size == 1) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 2) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 3) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 4) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 5) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 6) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == 7) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else if (set_size == FIXED_CONTAINER_MAX_SIZE) { - return InListPredicateBase::create_shared(cid, col_name, set, is_opposite, - char_length); - } else { - return InListPredicateBase::create_shared( - cid, col_name, set, is_opposite, char_length); - } - } -} - -template <> -std::shared_ptr create_in_list_predicate( - const uint32_t cid, const std::string col_name, const DataTypePtr& data_type, - const std::shared_ptr set, bool is_opposite) { - switch (data_type->get_primitive_type()) { - case TYPE_TINYINT: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_SMALLINT: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_INT: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_BIGINT: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_LARGEINT: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_FLOAT: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DOUBLE: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DECIMALV2: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DECIMAL32: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DECIMAL64: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DECIMAL128I: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DECIMAL256: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_CHAR: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite, - assert_cast(remove_nullable(data_type).get())->len()); - } - case TYPE_VARCHAR: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_STRING: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DATE: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DATEV2: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DATETIME: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_DATETIMEV2: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_TIMESTAMPTZ: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_BOOLEAN: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_IPV4: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - case TYPE_IPV6: { - return create_in_list_predicate_impl( - cid, col_name, set, is_opposite); - } - default: - throw Exception(Status::InternalError("Unsupported type {} for in_predicate", - type_to_string(data_type->get_primitive_type()))); - return nullptr; - } -} +template std::shared_ptr create_in_list_predicate( + const uint32_t, const std::string, const DataTypePtr&, const std::shared_ptr, + bool); } // namespace doris