From b650ecf0c08fb8a40133c7369267b5e2eeab29a4 Mon Sep 17 00:00:00 2001 From: Mryange Date: Wed, 3 Jun 2026 15:16:43 +0800 Subject: [PATCH] [refactor](be) Guard redundant column and typeid casts ### What problem does this PR solve? Issue Number: close #xxx Related PR: #xxx Problem Summary: Add compile-time checks to reject redundant same-type typeid_cast and check_and_get_column usage. This keeps dynamic column probing available for IColumn-derived source types while making already-concrete same-type calls fail at compile time instead of silently adding unnecessary casts. ### Release note None ### Check List (For Author) - Test: Manual test - sh run-be-ut.sh --clean -j 48 - Behavior changed: No - Does this need documentation: No --- be/src/core/column/column.h | 54 +++++++++++++++++++++++++------------ be/src/core/typeid_cast.h | 24 +++++++++++++++++ 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/be/src/core/column/column.h b/be/src/core/column/column.h index 06934c4c712d8b..49e13e242c87db 100644 --- a/be/src/core/column/column.h +++ b/be/src/core/column/column.h @@ -795,33 +795,53 @@ struct IsMutableColumns<> { }; // prefer assert_cast than check_and_get -template -const Type* check_and_get_column(const IColumn& column) { - return typeid_cast(&column); +template +const Type* check_and_get_column(const From& column) { + using FromType = std::remove_cv_t; + static_assert(std::is_base_of_v, + "check_and_get_column requires an IColumn-derived source type"); + static_assert(!std::is_same_v, FromType>, + "check_and_get_column is redundant for the same column type"); + return typeid_cast(static_cast(&column)); } -template -Type* check_and_get_column(IColumn& column) { - return typeid_cast(&column); +template +Type* check_and_get_column(From& column) { + using FromType = std::remove_cv_t; + static_assert(std::is_base_of_v, + "check_and_get_column requires an IColumn-derived source type"); + static_assert(!std::is_same_v, FromType>, + "check_and_get_column is redundant for the same column type"); + return typeid_cast(static_cast(&column)); } -template -const Type* check_and_get_column(const IColumn* column) { - return typeid_cast(column); +template +const Type* check_and_get_column(const From* column) { + using FromType = std::remove_cv_t; + static_assert(std::is_base_of_v, + "check_and_get_column requires an IColumn-derived source type"); + static_assert(!std::is_same_v, FromType>, + "check_and_get_column is redundant for the same column type"); + return typeid_cast(static_cast(column)); } -template -Type* check_and_get_column(IColumn* column) { - return typeid_cast(column); +template +Type* check_and_get_column(From* column) { + using FromType = std::remove_cv_t; + static_assert(std::is_base_of_v, + "check_and_get_column requires an IColumn-derived source type"); + static_assert(!std::is_same_v, FromType>, + "check_and_get_column is redundant for the same column type"); + return typeid_cast(static_cast(column)); } -template -bool is_column(const IColumn& column) { - return check_and_get_column(&column); +template +bool is_column(const From& column) { + return check_and_get_column(column); } -template -bool is_column(const IColumn* column) { +template +bool is_column(const From* column) { return check_and_get_column(column); } diff --git a/be/src/core/typeid_cast.h b/be/src/core/typeid_cast.h index 3f81586a707c33..bfa6cc01f59ead 100644 --- a/be/src/core/typeid_cast.h +++ b/be/src/core/typeid_cast.h @@ -26,6 +26,22 @@ #include "common/exception.h" #include "common/status.h" +template +struct TypeIdCastNormalizedType { + using no_ref_t = std::remove_reference_t; + using no_cv_t = std::remove_cv_t; + using type = + std::conditional_t, + std::add_pointer_t>>, + no_cv_t>; +}; + +template +using TypeIdCastNormalizedType_t = typename TypeIdCastNormalizedType::type; + +template +using TypeIdCastClassType_t = std::remove_pointer_t>; + /** Checks type by comparing typeid. * The exact match of the type is checked. That is, cast to the ancestor will be unsuccessful. * In the rest, behaves like a dynamic_cast. @@ -33,6 +49,14 @@ template To typeid_cast(From* from) { + static_assert(!std::is_same_v, TypeIdCastNormalizedType_t>, + "typeid_cast is redundant for the same type after removing cv/ref qualifiers"); + static_assert(std::is_class_v> && + std::is_class_v>, + "typeid_cast requires casting between class pointer types"); + static_assert(std::is_base_of_v, TypeIdCastClassType_t>, + "typeid_cast only supports downcast from a base type to a derived type"); + #ifndef NDEBUG try { if (typeid(*from) == typeid(std::remove_pointer_t)) {