Repository: ClickHouse/ClickHouse
File: src/Storages/MergeTree/KeyCondition.cpp (C++)

Code before:
                Int64 value = (*result_column)[0].safeGet<DateTime64>().getValue();
                if (value < 0)
                    return false;

                UInt32 scale = assert_cast<const DataTypeDateTime64 &>(*arg_type_inner).getScale();
                Int64 seconds = value / intExp10OfSize<Int64>(scale);

                if (isDate(result_type_inner) && seconds >= static_cast<Int64>(DATE_LUT_MAX_DAY_NUM) * 86400)
                    return false;
                if (isDateTime(result_type_inner) && seconds >= DATE_LUT_MAX)
                    return false;
            }
            else if (isDate32(arg_type_inner))
            {
                auto value = (*result_column)[0].safeGet<Int32>();
                if (value < 0)
                    return false;
                if (isDate(result_type_inner) && value > DATE_LUT_MAX_DAY_NUM)
                    return false;
            }
        }

        result_column = func->execute({{result_column, argument_type, ""}}, func_result_type, result_column->size(), /* dry_run = */ false);
        result_column = result_column->convertToFullColumnIfLowCardinality();
        result_type = removeLowCardinality(func_result_type);

        /// at the type boundary the next value wraps, so pruning is unsafe
        if (isDate(result_type_inner))
        {
            if (result_column->getUInt(0) >= DATE_LUT_MAX_DAY_NUM)
                return false;
        }
        else if (isDateTime(result_type_inner))
        {
            if (result_column->get64(0) >= DATE_LUT_MAX)
                return false;
        }

        /// Transforming nullable columns to the nested ones, in case no nulls found
        if (result_column->isNullable())
        {
            const auto & result_column_nullable = assert_cast<const ColumnNullable &>(*result_column);
            const auto & null_map_data = result_column_nullable.getNullMapData();
            for (char8_t i : null_map_data)
            {
                if (i != 0)
                    return false;
            }
            result_column = result_column_nullable.getNestedColumnPtr();
            result_type = removeNullable(result_type);
        }

Review comment (performance):
I think we can revert back to the `master` version where we have type unwrapping inside the `if` condition so that we do not pay it all the time. It's not a big save on performance but saves few RTTI checks.

Code after:
        if (isDate(result_type_inner) || isDateTime(result_type_inner))
        {
            auto arg_type_inner = removeLowCardinality(removeNullable(argument_type));
            if (isDateTime64(arg_type_inner))
            {
                Int64 value = (*result_column)[0].safeGet<DateTime64>().getValue();

                /// negative timestamps after cast -> large unsigned values
                if (value < 0)
                    return false;

                UInt32 scale = assert_cast<const DataTypeDateTime64 &>(*arg_type_inner).getScale();
                Int64 seconds = value / intExp10OfSize<Int64>(scale);

                /// timestamps beyond the target range -> small values
                if (isDate(result_type_inner) && seconds >= static_cast<Int64>(DATE_LUT_MAX_DAY_NUM) * 86400)
                    return false;
                if (isDateTime(result_type_inner) && seconds >= DATE_LUT_MAX)
                    return false;
            }
            else if (isDate32(arg_type_inner))
            {
                /// day numbers as Int32 -> Date only fits [0, 65535],
                /// DateTime only fits seconds up to DATE_LUT_MAX
                auto value = (*result_column)[0].safeGet<Int32>();
                if (value < 0)
                    return false;
                if (isDate(result_type_inner) && value > DATE_LUT_MAX_DAY_NUM)
                    return false;
                if (isDateTime(result_type_inner) && value * 86400LL >= DATE_LUT_MAX)
                    return false;
            }
        }

        result_column = func->execute({{result_column, argument_type, ""}}, func_result_type, result_column->size(), /* dry_run = */ false);
        result_column = result_column->convertToFullColumnIfLowCardinality();
        result_type = removeLowCardinality(func_result_type);

        /// the result itself sits at the type's max — next value wraps so any >= / <= condition on
        /// it would give wrong partition ranges -> this catches timezone edge cases that pre-execution check might miss
        if (isDate(result_type_inner))
        {
            if (result_column->getUInt(0) >= DATE_LUT_MAX_DAY_NUM)
                return false;
        }
        else if (isDateTime(result_type_inner))
        {
            if (result_column->get64(0) >= DATE_LUT_MAX)
                return false;
        }