`DROP TABLE if exists default.test_20221226 on cluster clickhouse;
CREATE TABLE default.test_20221226 on cluster clickhouse
(
   uid Int64,
   start Int64,
   end Int64,
   ck_insert_time DateTime default now()
)
ENGINE = ReplacingMergeTree(ck_insert_time)
ORDER BY (uid, start)
;

DROP TABLE if exists default.test_20221226_all on cluster clickhouse;
CREATE TABLE default.test_20221226_all on cluster clickhouse AS default.test_20221226
ENGINE = Distributed('clickhouse', 'default', 'test_20221226', cityHash64(uid))
;

DROP DICTIONARY if exists default.test_20221226_dict on cluster clickhouse;
CREATE DICTIONARY default.test_20221226_dict on cluster clickhouse
(
    uid Int64,
    start Int64,
    end Int64,
    ck_insert_time DateTime
)
PRIMARY KEY uid
SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' PASSWORD 'default' DB 'default' TABLE 'test_20221226_all' UPDATE_FIELD 'ck_insert_time' UPDATE_LAG 60))
LIFETIME(MIN 10 MAX 60)
LAYOUT(RANGE_HASHED())
RANGE(MIN start MAX end)
;

INSERT INTO default.test_20221226_all(uid,start,end) values (1, 0, 100),(1, 101,200),(2,0,999),(2,1000,10000);

select * from default.test_20221226_all ;
uid	start	end	ck_insert_time
1	0	100	2022-12-26 11:38:34
1	101	200	2022-12-26 11:38:34
2	0	999	2022-12-26 11:38:34
2	1000	10000	2022-12-26 11:38:34

select * from default.test_20221226_dict ;
uid	start	end	ck_insert_time
1	0	100	2022-12-26 11:38:34
1	101	200	2022-12-26 11:38:34
2	0	999	2022-12-26 11:38:34
2	1000	10000	2022-12-26 11:38:34

`

after the DICTIONARY update. (one minute later)

`
select * from default.test_20221226_all ;
uid	start	end	ck_insert_time
1	0	100	2022-12-26 11:38:34
1	101	200	2022-12-26 11:38:34
2	0	999	2022-12-26 11:38:34
2	1000	10000	2022-12-26 11:38:34

select * from default.test_20221226_dict ;
uid	start	end	ck_insert_time
1	101	200	2022-12-26 11:38:34
2	1000	10000	2022-12-26 11:38:34

`

the result in dict is wrong, missing the first range for each PRIMARY KEY.

somthing wrong in my create sql? or a bug for this version. because i have used this plan in version 21.11.4.14, that's greats on it,



const auto & attribute = attributes[attribute_index];
    
    Columns modified_key_columns = key_columns;
    const ColumnPtr & range_storage_column = key_columns.back();
    ColumnWithTypeAndName column_to_cast = {range_storage_column->convertToFullColumnIfConst(), key_types.back(), ""};
    modified_key_columns.back() = castColumnAccurate(column_to_cast, dict_struct.range_min->type);
    size_t keys_size = key_columns.front()->size();
    bool is_attribute_nullable = attribute.is_value_nullable.has_value();
    ColumnUInt8::MutablePtr col_null_map_to;
    ColumnUInt8::Container * vec_null_map_to = nullptr;
    if (is_attribute_nullable)
    {
        col_null_map_to = ColumnUInt8::create(keys_size, false);
        vec_null_map_to = &col_null_map_to->getData();
    }
    auto type_call = [&](const auto & dictionary_attribute_type)
    {
        using Type = std::decay_t<decltype(dictionary_attribute_type)>;
        using AttributeType = typename Type::AttributeType;
        using ValueType = DictionaryValueType<AttributeType>;
        using ColumnProvider = DictionaryAttributeColumnProvider<AttributeType>;
        DictionaryDefaultValueExtractor<AttributeType> default_value_extractor(dictionary_attribute.null_value, default_values_column);
        auto column = ColumnProvider::getColumn(dictionary_attribute, keys_size);
        if constexpr (std::is_same_v<ValueType, Array>)
        {
            auto * out = column.get();
            getItemsImpl<ValueType, false>(
                attribute,
                modified_key_columns,
                [&](size_t, const Array & value, bool)