| /* |
| * 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. |
| */ |
| |
| #pragma once |
| |
| #include <cstdint> |
| |
| namespace paimon { |
| |
| enum class VariantShreddingInferenceMode { |
| PER_FILE, |
| ADAPTIVE, |
| }; |
| |
| /// Constants of the Paimon Variant type and the Variant Binary Encoding, which follows the |
| /// parquet-format VariantEncoding.md specification (compatible with the Java / Spark |
| /// implementation). |
| /// |
| /// A variant is made up of 2 binaries: value and metadata. A variant value consists of a one-byte |
| /// header and a number of content bytes (can be zero). The header byte is divided into upper 6 |
| /// bits (called "type info") and lower 2 bits (called "basic type"). |
| /// |
| /// The variant metadata includes a version id and a dictionary of distinct strings |
| /// (case-sensitive). Its binary format is: |
| /// - Version: 1-byte unsigned integer. The only acceptable value is 1 currently. |
| /// - Dictionary size: `offset_size`-byte little-endian unsigned integer. The number of keys in the |
| /// dictionary. |
| /// - Offsets: (size + 1) * `offset_size`-byte little-endian unsigned integers. `offsets[i]` |
| /// represents the starting position of string i, counting starting from the address of |
| /// `offsets[0]`. Strings must be stored contiguously, so we don't need to store the string size, |
| /// instead, we compute it with `offset[i + 1] - offset[i]`. |
| /// - UTF-8 string data. |
| /// |
| /// A Variant field uses `struct<value: binary not null, metadata: binary not null>` as its |
| /// underlying physical storage in Apache Arrow Schema, and is marked as the Paimon Variant |
| /// extension type by attaching specific **KeyValueMetadata** on the outer field. |
| class VariantDefs { |
| public: |
| VariantDefs() = delete; |
| ~VariantDefs() = delete; |
| |
| /// Metadata key identifying a Paimon extension type field (shared with BLOB). |
| static constexpr char kExtensionTypeKey[] = "paimon.extension.type"; |
| /// Metadata value identifying a Paimon Variant extension type field. |
| static constexpr char kExtensionTypeValue[] = "paimon.type.variant"; |
| |
| /// Name of the binary child field holding the variant value. |
| static constexpr char kValueFieldName[] = "value"; |
| /// Name of the binary child field holding the variant metadata. |
| static constexpr char kMetadataFieldName[] = "metadata"; |
| /// Name of the typed child field of a shredded variant (parquet VariantShredding.md). |
| static constexpr char kTypedValueFieldName[] = "typed_value"; |
| /// Paimon field id of the `value` child field. |
| static constexpr int32_t kValueFieldId = 0; |
| /// Paimon field id of the `metadata` child field. |
| static constexpr int32_t kMetadataFieldId = 1; |
| |
| static constexpr int32_t kBasicTypeBits = 2; |
| static constexpr int32_t kBasicTypeMask = 0x3; |
| static constexpr int32_t kTypeInfoMask = 0x3F; |
| /// The inclusive maximum value of the type info value. It is the size limit of `kShortStr`. |
| static constexpr int32_t kMaxShortStrSize = 0x3F; |
| |
| /// Primitive value. The type info value must be one of the primitive type values below. |
| static constexpr int32_t kPrimitive = 0; |
| /// Short string value. The type info value is the string size, which must be in |
| /// `[0, kMaxShortStrSize]`. The string content bytes directly follow the header byte. |
| static constexpr int32_t kShortStr = 1; |
| /// Object value. The content contains a size, a list of field ids, a list of field offsets, |
| /// and the actual field data. The length of the id list is `size`, while the length of the |
| /// offset list is `size + 1`, where the last offset represents the total size of the field |
| /// data. The fields in an object must be sorted by the field name in alphabetical order. |
| /// Duplicate field names in one object are not allowed. |
| /// The type info is 0_b4_b3b2_b1b0 (MSB is 0), where: |
| /// - b4 specifies the type of size. When it is 0/1, `size` is a little-endian 1/4-byte |
| /// unsigned integer. |
| /// - b3b2/b1b0 specifies the integer type of id and offset. When the 2 bits are 0/1/2, the |
| /// list contains 1/2/3-byte little-endian unsigned integers. |
| static constexpr int32_t kObject = 2; |
| /// Array value. The content contains a size, a list of field offsets, and the actual element |
| /// data. It is similar to an object without the id list. The type info is 000_b2_b1b0: |
| /// - b2 specifies the type of size. |
| /// - b1b0 specifies the integer type of offset. |
| static constexpr int32_t kArray = 3; |
| |
| /// JSON null value. Empty content. |
| static constexpr int32_t kNull = 0; |
| /// True value. Empty content. |
| static constexpr int32_t kTrue = 1; |
| /// False value. Empty content. |
| static constexpr int32_t kFalse = 2; |
| /// 1-byte little-endian signed integer. |
| static constexpr int32_t kInt1 = 3; |
| /// 2-byte little-endian signed integer. |
| static constexpr int32_t kInt2 = 4; |
| /// 4-byte little-endian signed integer. |
| static constexpr int32_t kInt4 = 5; |
| /// 8-byte little-endian signed integer. |
| static constexpr int32_t kInt8 = 6; |
| /// 8-byte IEEE double. |
| static constexpr int32_t kDouble = 7; |
| /// 4-byte decimal. Content is 1-byte scale + 4-byte little-endian signed integer. |
| static constexpr int32_t kDecimal4 = 8; |
| /// 8-byte decimal. Content is 1-byte scale + 8-byte little-endian signed integer. |
| static constexpr int32_t kDecimal8 = 9; |
| /// 16-byte decimal. Content is 1-byte scale + 16-byte little-endian signed integer. |
| static constexpr int32_t kDecimal16 = 10; |
| /// Date value. Content is 4-byte little-endian signed integer that represents the number of |
| /// days from the Unix epoch. |
| static constexpr int32_t kDate = 11; |
| /// Timestamp value. Content is 8-byte little-endian signed integer that represents the number |
| /// of microseconds elapsed since the Unix epoch, 1970-01-01 00:00:00 UTC. It is displayed to |
| /// users in their local time zones and may be displayed differently depending on the |
| /// execution environment. |
| static constexpr int32_t kTimestamp = 12; |
| /// Timestamp_ntz value. It has the same content as `kTimestamp` but should always be |
| /// interpreted as if the local time zone is UTC. |
| static constexpr int32_t kTimestampNtz = 13; |
| /// 4-byte IEEE float. |
| static constexpr int32_t kFloat = 14; |
| /// Binary value. The content is (4-byte little-endian unsigned integer representing the |
| /// binary size) + (size bytes of binary content). |
| static constexpr int32_t kBinary = 15; |
| /// Long string value. The content is (4-byte little-endian unsigned integer representing the |
| /// string size) + (size bytes of string content). |
| static constexpr int32_t kLongStr = 16; |
| /// UUID, 16-byte big-endian. |
| static constexpr int32_t kUuid = 20; |
| |
| /// The only acceptable variant version. It is stored in the lower 4 bits of the first |
| /// metadata byte. |
| static constexpr uint8_t kVersion = 1; |
| static constexpr uint8_t kVersionMask = 0x0F; |
| |
| static constexpr int32_t kU8Max = 0xFF; |
| static constexpr int32_t kU16Max = 0xFFFF; |
| static constexpr int32_t kU24Max = 0xFFFFFF; |
| static constexpr int32_t kU24Size = 3; |
| static constexpr int32_t kU32Size = 4; |
| |
| /// Both variant value and variant metadata need to be no longer than 128MiB. |
| static constexpr int32_t kSizeLimit = 128 * 1024 * 1024; |
| |
| static constexpr int32_t kMaxDecimal4Precision = 9; |
| static constexpr int32_t kMaxDecimal8Precision = 18; |
| static constexpr int32_t kMaxDecimal16Precision = 38; |
| |
| /// Object field lookup switches from linear search to binary search when the object size |
| /// reaches this threshold. |
| static constexpr int32_t kBinarySearchThreshold = 32; |
| }; |
| |
| } // namespace paimon |