blob: d2b9d99f114e859655e8f4fafbfce23810129f31 [file]
// 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.
#include "storage/segment/encoding_info.h"
#include <gen_cpp/olap_file.pb.h>
#include <gen_cpp/segment_v2.pb.h>
#include <array>
#include <iterator>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include "common/config.h"
#include "common/exception.h"
#include "runtime/exec_env.h"
#include "storage/olap_common.h"
#include "storage/segment/binary_dict_page.h"
#include "storage/segment/binary_dict_page_pre_decoder.h"
#include "storage/segment/binary_plain_page.h"
#include "storage/segment/binary_plain_page_char_strip_pre_decoder.h"
#include "storage/segment/binary_plain_page_v2.h"
#include "storage/segment/binary_plain_page_v2_pre_decoder.h"
#include "storage/segment/binary_plain_page_v3.h"
#include "storage/segment/binary_plain_page_v3_pre_decoder.h"
#include "storage/segment/binary_prefix_page.h"
#include "storage/segment/bitshuffle_page.h"
#include "storage/segment/bitshuffle_page_pre_decoder.h"
#include "storage/segment/frame_of_reference_page.h"
#include "storage/segment/options.h"
#include "storage/segment/plain_page.h"
#include "storage/segment/rle_page.h"
#include "storage/tablet/tablet_schema.h"
#include "storage/types.h"
namespace doris {
namespace segment_v2 {
template <FieldType type, typename CppType>
struct TypeEncodingTraits<type, PLAIN_ENCODING, CppType> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return PlainPageBuilder<type>::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new PlainPageDecoder<type>(data, opts);
return Status::OK();
}
};
template <FieldType type>
struct TypeEncodingTraits<type, PLAIN_ENCODING, Slice> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return BinaryPlainPageBuilder<type>::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new BinaryPlainPageDecoder<type>(data, opts);
return Status::OK();
}
};
template <FieldType type, typename CppType>
struct TypeEncodingTraits<type, PLAIN_ENCODING_V2, CppType> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return PlainPageBuilder<type>::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new PlainPageDecoder<type>(data, opts);
return Status::OK();
}
};
template <FieldType type>
struct TypeEncodingTraits<type, PLAIN_ENCODING_V2, Slice> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return BinaryPlainPageV2Builder<type>::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new BinaryPlainPageV2Decoder<type>(data, opts);
return Status::OK();
}
};
// PLAIN_ENCODING_V3 is a binary plain page, only registered for Slice (binary) types, so it
// has no non-Slice specialization (unlike PLAIN_ENCODING, which also serves numeric types).
template <FieldType type>
struct TypeEncodingTraits<type, PLAIN_ENCODING_V3, Slice> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return BinaryPlainPageV3Builder<type>::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new BinaryPlainPageV3Decoder<type>(data, opts);
return Status::OK();
}
};
template <FieldType type, typename CppType>
struct TypeEncodingTraits<type, BIT_SHUFFLE, CppType,
typename std::enable_if<!std::is_same<CppType, Slice>::value>::type> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return BitshufflePageBuilder<type>::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new BitShufflePageDecoder<type>(data, opts);
return Status::OK();
}
};
template <>
struct TypeEncodingTraits<FieldType::OLAP_FIELD_TYPE_BOOL, RLE, uint8_t> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return RlePageBuilder<FieldType::OLAP_FIELD_TYPE_BOOL>::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new RlePageDecoder<FieldType::OLAP_FIELD_TYPE_BOOL>(data, opts);
return Status::OK();
}
};
template <FieldType type>
struct TypeEncodingTraits<type, DICT_ENCODING, Slice> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return BinaryDictPageBuilder::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new BinaryDictPageDecoder(data, opts);
return Status::OK();
}
};
template <>
struct TypeEncodingTraits<FieldType::OLAP_FIELD_TYPE_DATE, FOR_ENCODING,
typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATE>::CppType> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return FrameOfReferencePageBuilder<FieldType::OLAP_FIELD_TYPE_DATE>::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new FrameOfReferencePageDecoder<FieldType::OLAP_FIELD_TYPE_DATE>(data, opts);
return Status::OK();
}
};
template <>
struct TypeEncodingTraits<FieldType::OLAP_FIELD_TYPE_DATEV2, FOR_ENCODING,
typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATEV2>::CppType> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return FrameOfReferencePageBuilder<FieldType::OLAP_FIELD_TYPE_DATEV2>::create(builder,
opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new FrameOfReferencePageDecoder<FieldType::OLAP_FIELD_TYPE_DATEV2>(data, opts);
return Status::OK();
}
};
template <>
struct TypeEncodingTraits<FieldType::OLAP_FIELD_TYPE_DATETIMEV2, FOR_ENCODING,
typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_DATETIMEV2>::CppType> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return FrameOfReferencePageBuilder<FieldType::OLAP_FIELD_TYPE_DATETIMEV2>::create(builder,
opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder =
new FrameOfReferencePageDecoder<FieldType::OLAP_FIELD_TYPE_DATETIMEV2>(data, opts);
return Status::OK();
}
};
template <>
struct TypeEncodingTraits<FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ, FOR_ENCODING,
typename CppTypeTraits<FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ>::CppType> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return FrameOfReferencePageBuilder<FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ>::create(builder,
opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder =
new FrameOfReferencePageDecoder<FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ>(data, opts);
return Status::OK();
}
};
template <FieldType type, typename CppType>
struct TypeEncodingTraits<type, FOR_ENCODING, CppType,
typename std::enable_if<IsIntegral<CppType>::value>::type> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return FrameOfReferencePageBuilder<type>::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new FrameOfReferencePageDecoder<type>(data, opts);
return Status::OK();
}
};
template <FieldType type>
struct TypeEncodingTraits<type, PREFIX_ENCODING, Slice> {
static Status create_page_builder(const PageBuilderOptions& opts, PageBuilder** builder) {
return BinaryPrefixPageBuilder::create(builder, opts);
}
static Status create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
PageDecoder** decoder) {
*decoder = new BinaryPrefixPageDecoder(data, opts);
return Status::OK();
}
};
EncodingInfoResolver::EncodingInfoResolver() {
// ===== Phase 1: register every supported (type, encoding) combination exactly once =====
// _register_supported_encoding CHECKs against duplicates; the Phase 2 calls below do not insert into _encoding_map,
// so every (type, encoding) used as a default must appear here first.
// signed integers
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_TINYINT, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_TINYINT, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_TINYINT, FOR_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_SMALLINT, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_SMALLINT, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_SMALLINT, FOR_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_INT, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_INT, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_INT, FOR_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_BIGINT, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_BIGINT, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_BIGINT, FOR_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_LARGEINT, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_LARGEINT, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_LARGEINT, FOR_ENCODING>();
// unsigned integers
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_UNSIGNED_BIGINT, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_UNSIGNED_INT, BIT_SHUFFLE>();
// FLOAT / DOUBLE
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_FLOAT, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_FLOAT, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DOUBLE, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DOUBLE, PLAIN_ENCODING>();
// binary types (CHAR/VARCHAR/STRING/JSONB/VARIANT)
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_CHAR, DICT_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_CHAR, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_CHAR, PLAIN_ENCODING_V2>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_CHAR, PLAIN_ENCODING_V3>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_CHAR, PREFIX_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_VARCHAR, DICT_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_VARCHAR, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_VARCHAR, PLAIN_ENCODING_V2>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_VARCHAR, PLAIN_ENCODING_V3>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_VARCHAR, PREFIX_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_STRING, DICT_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_STRING, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_STRING, PLAIN_ENCODING_V2>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_STRING, PLAIN_ENCODING_V3>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_STRING, PREFIX_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_JSONB, DICT_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_JSONB, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_JSONB, PLAIN_ENCODING_V2>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_JSONB, PLAIN_ENCODING_V3>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_JSONB, PREFIX_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_VARIANT, DICT_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_VARIANT, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_VARIANT, PLAIN_ENCODING_V2>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_VARIANT, PLAIN_ENCODING_V3>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_VARIANT, PREFIX_ENCODING>();
// BOOL
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_BOOL, RLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_BOOL, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_BOOL, PLAIN_ENCODING>();
// date / datetime
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATE, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATE, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATE, FOR_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATEV2, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATEV2, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATEV2, FOR_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATETIMEV2, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATETIMEV2, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATETIMEV2, FOR_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATETIME, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATETIME, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DATETIME, FOR_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ, FOR_ENCODING>();
// decimal
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DECIMAL, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DECIMAL, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DECIMAL32, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DECIMAL32, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DECIMAL64, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DECIMAL64, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DECIMAL128I, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DECIMAL128I, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DECIMAL256, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_DECIMAL256, PLAIN_ENCODING>();
// ip
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_IPV4, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_IPV4, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_IPV6, BIT_SHUFFLE>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_IPV6, PLAIN_ENCODING>();
// aggregate / binary-flavored types
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_HLL, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_HLL, PLAIN_ENCODING_V2>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_HLL, PLAIN_ENCODING_V3>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_BITMAP, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_BITMAP, PLAIN_ENCODING_V2>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_BITMAP, PLAIN_ENCODING_V3>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_QUANTILE_STATE, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_QUANTILE_STATE, PLAIN_ENCODING_V2>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_QUANTILE_STATE, PLAIN_ENCODING_V3>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_AGG_STATE, PLAIN_ENCODING>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_AGG_STATE, PLAIN_ENCODING_V2>();
_register_supported_encoding<FieldType::OLAP_FIELD_TYPE_AGG_STATE, PLAIN_ENCODING_V3>();
// ===== Phase 2a: V2 defaults (write path, V1/V2 segments) =====
_set_v2_default<FieldType::OLAP_FIELD_TYPE_TINYINT, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_SMALLINT, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_INT, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_BIGINT, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_LARGEINT, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_UNSIGNED_BIGINT, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_UNSIGNED_INT, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_FLOAT, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_DOUBLE, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_CHAR, DICT_ENCODING>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_VARCHAR, DICT_ENCODING>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_STRING, DICT_ENCODING>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_JSONB, DICT_ENCODING>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_VARIANT, DICT_ENCODING>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_BOOL, RLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_DATE, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_DATEV2, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_DATETIMEV2, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_DATETIME, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_DECIMAL, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_DECIMAL32, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_DECIMAL64, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_DECIMAL128I, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_DECIMAL256, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_IPV4, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_IPV6, BIT_SHUFFLE>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_HLL, PLAIN_ENCODING>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_BITMAP, PLAIN_ENCODING>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_QUANTILE_STATE, PLAIN_ENCODING>();
_set_v2_default<FieldType::OLAP_FIELD_TYPE_AGG_STATE, PLAIN_ENCODING>();
// ===== Phase 2b: V3 defaults (write path, V3 segments) =====
_set_v3_default<FieldType::OLAP_FIELD_TYPE_TINYINT, PLAIN_ENCODING>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_SMALLINT, PLAIN_ENCODING>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_INT, PLAIN_ENCODING>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_BIGINT, PLAIN_ENCODING>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_LARGEINT, PLAIN_ENCODING>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_UNSIGNED_BIGINT, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_UNSIGNED_INT, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_FLOAT, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_DOUBLE, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_CHAR, DICT_ENCODING>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_VARCHAR, DICT_ENCODING>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_STRING, DICT_ENCODING>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_JSONB, DICT_ENCODING>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_VARIANT, DICT_ENCODING>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_BOOL, RLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_DATE, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_DATEV2, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_DATETIMEV2, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_DATETIME, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_TIMESTAMPTZ, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_DECIMAL, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_DECIMAL32, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_DECIMAL64, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_DECIMAL128I, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_DECIMAL256, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_IPV4, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_IPV6, BIT_SHUFFLE>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_HLL, PLAIN_ENCODING_V3>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_BITMAP, PLAIN_ENCODING_V3>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_QUANTILE_STATE, PLAIN_ENCODING_V3>();
_set_v3_default<FieldType::OLAP_FIELD_TYPE_AGG_STATE, PLAIN_ENCODING_V3>();
// ===== Phase 2c: IndexedColumn (value-seek) defaults =====
// Only the PrimaryKeyIndexBuilder consults this map, and it hardcodes VARCHAR.
// Other types were registered historically (since #2308, 2019) for a generic
// "any IndexedColumn value-seek caller" use case that never materialized; they
// were removed to keep this map honest about what production actually needs.
_set_index_column_encoding<FieldType::OLAP_FIELD_TYPE_VARCHAR, PREFIX_ENCODING>();
}
EncodingInfoResolver::~EncodingInfoResolver() {
for (auto& it : _encoding_map) {
delete it.second;
}
_encoding_map.clear();
}
EncodingTypePB EncodingInfoResolver::get_v2_default_encoding(FieldType type) const {
return _lookup(_v2_default_map, type);
}
EncodingTypePB EncodingInfoResolver::get_v3_default_encoding(FieldType type) const {
return _lookup(_v3_default_map, type);
}
EncodingTypePB EncodingInfoResolver::get_index_column_encoding(FieldType type) const {
return _lookup(_index_column_encoding_map, type);
}
Status EncodingInfoResolver::get(FieldType data_type, EncodingTypePB encoding_type,
const EncodingInfo** out) {
auto key = std::make_pair(data_type, encoding_type);
auto it = _encoding_map.find(key);
if (it == std::end(_encoding_map)) {
return Status::InternalError("fail to find valid type encoding, type:{}, encoding:{}",
data_type, encoding_type);
}
*out = it->second;
return Status::OK();
}
template <typename TraitsClass>
EncodingInfo::EncodingInfo(TraitsClass traits)
: _create_builder_func(TraitsClass::create_page_builder),
_create_decoder_func(TraitsClass::create_page_decoder),
_type(TraitsClass::type),
_encoding(TraitsClass::encoding) {
if (_encoding == BIT_SHUFFLE) {
_data_page_pre_decoder = std::make_unique<BitShufflePagePreDecoder>();
} else if (_encoding == DICT_ENCODING) {
if constexpr (TraitsClass::type == FieldType::OLAP_FIELD_TYPE_CHAR) {
_data_page_pre_decoder = std::make_unique<BinaryDictPagePreDecoder<true>>();
} else {
_data_page_pre_decoder = std::make_unique<BinaryDictPagePreDecoder<false>>();
}
} else if (_encoding == PLAIN_ENCODING) {
// CHAR plain pages may contain trailing '\0' padding written by older
// BEs; strip it once at page load so the cached page is unpadded.
if constexpr (TraitsClass::type == FieldType::OLAP_FIELD_TYPE_CHAR) {
_data_page_pre_decoder = std::make_unique<BinaryPlainPageCharStripPreDecoder>();
}
} else if (_encoding == PLAIN_ENCODING_V2) {
// Only binary types (Slice) need the predecoder for PLAIN_ENCODING_V2 — it converts
// varint-encoded lengths to an offset-array format that downstream Slice decoders expect.
// CHAR pages additionally strip trailing '\0' padding written by the convertor; other
// Slice types use the non-CHAR specialization. All current (type, PLAIN_ENCODING_V2)
// registrations are Slice (CHAR/VARCHAR/STRING/JSONB/VARIANT/HLL/BITMAP/QUANTILE_STATE/
// AGG_STATE per storage/types.h). The else throws at construction time to fail loudly
// if a future non-Slice registration is added.
if constexpr (TraitsClass::type == FieldType::OLAP_FIELD_TYPE_CHAR) {
_data_page_pre_decoder = std::make_unique<BinaryPlainPageV2PreDecoder<true>>();
} else if constexpr (std::is_same_v<typename TraitsClass::CppType, Slice>) {
_data_page_pre_decoder = std::make_unique<BinaryPlainPageV2PreDecoder<false>>();
} else {
throw Exception(Status::FatalError(
"PLAIN_ENCODING_V2 is only supported for Slice (binary) types, but got "
"non-Slice type {}",
int(TraitsClass::type)));
}
} else if (_encoding == PLAIN_ENCODING_V3) {
// V3 binary plain pages store contiguous data followed by a contiguous varuint length
// block; the predecoder rewrites that into the V1 offset-array layout downstream Slice
// decoders expect. CHAR uses the IS_CHAR=true variant so the trailing '\0' padding of
// CHAR dictionary words (written with the VARCHAR builder) is stripped on read — mirroring
// PLAIN_ENCODING_V2. strnlen on a write-stripped CHAR page is a no-op, so the variant is
// also correct for direct CHAR plain V3 pages.
if constexpr (TraitsClass::type == FieldType::OLAP_FIELD_TYPE_CHAR) {
_data_page_pre_decoder = std::make_unique<BinaryPlainPageV3PreDecoder<true>>();
} else if constexpr (std::is_same_v<typename TraitsClass::CppType, Slice>) {
_data_page_pre_decoder = std::make_unique<BinaryPlainPageV3PreDecoder<false>>();
} else {
throw Exception(Status::FatalError(
"PLAIN_ENCODING_V3 is only supported for Slice (binary) types, but got "
"non-Slice type {}",
int(TraitsClass::type)));
}
}
}
#ifdef BE_TEST
static EncodingInfoResolver s_encoding_info_resolver;
#endif
Status EncodingInfo::get(FieldType type, EncodingTypePB encoding_type, const EncodingInfo** out) {
#ifdef BE_TEST
return s_encoding_info_resolver.get(type, encoding_type, out);
#else
auto* resolver = ExecEnv::GetInstance()->get_encoding_info_resolver();
if (resolver == nullptr) {
return Status::InternalError("EncodingInfoResolver not initialized");
}
return resolver->get(type, encoding_type, out);
#endif
}
EncodingTypePB EncodingInfo::get_v2_default_encoding(FieldType type) {
#ifdef BE_TEST
return s_encoding_info_resolver.get_v2_default_encoding(type);
#else
auto* resolver = ExecEnv::GetInstance()->get_encoding_info_resolver();
if (resolver == nullptr) {
return UNKNOWN_ENCODING;
}
return resolver->get_v2_default_encoding(type);
#endif
}
EncodingTypePB EncodingInfo::get_v3_default_encoding(FieldType type) {
#ifdef BE_TEST
return s_encoding_info_resolver.get_v3_default_encoding(type);
#else
auto* resolver = ExecEnv::GetInstance()->get_encoding_info_resolver();
if (resolver == nullptr) {
return UNKNOWN_ENCODING;
}
return resolver->get_v3_default_encoding(type);
#endif
}
EncodingTypePB EncodingInfo::get_index_column_encoding(FieldType type) {
#ifdef BE_TEST
return s_encoding_info_resolver.get_index_column_encoding(type);
#else
auto* resolver = ExecEnv::GetInstance()->get_encoding_info_resolver();
if (resolver == nullptr) {
return UNKNOWN_ENCODING;
}
return resolver->get_index_column_encoding(type);
#endif
}
EncodingTypePB EncodingInfo::resolve_default_encoding(TabletStorageFormatPB storage_format,
const TabletColumn& column) {
const bool is_v3 = (storage_format == TabletStorageFormatPB::TABLET_STORAGE_FORMAT_V3);
// Row store data is already serialized as a single blob. Keep it on plain pages to
// avoid introducing dictionary pages for the hidden row store column; V3 segments use
// the V3 binary plain layout.
if (column.is_row_store_column()) {
return is_v3 ? PLAIN_ENCODING_V3 : PLAIN_ENCODING;
}
return is_v3 ? get_v3_default_encoding(column.type()) : get_v2_default_encoding(column.type());
}
Status EncodingInfo::create_page_builder(const PageBuilderOptions& opts,
std::unique_ptr<PageBuilder>& builder) const {
PageBuilder* raw_builder = nullptr;
RETURN_IF_ERROR(_create_builder_func(opts, &raw_builder));
builder.reset(raw_builder);
return Status::OK();
}
Status EncodingInfo::create_page_decoder(const Slice& data, const PageDecoderOptions& opts,
std::unique_ptr<PageDecoder>& decoder) const {
PageDecoder* raw_decoder = nullptr;
RETURN_IF_ERROR(_create_decoder_func(data, opts, &raw_decoder));
decoder.reset(raw_decoder);
return Status::OK();
}
} // namespace segment_v2
} // namespace doris