跳到主要内容
版本:Candidate-4.1

VARIANT

自 4.0 版本起,StarRocks 支持 VARIANT 数据类型,用于查询 Parquet 格式的 Iceberg 表中的半结构化数据。本文介绍 VARIANT 的基本概念,以及 StarRocks 如何查询 VARIANT 类型数据并通过 variant 函数进行处理。

什么是 VARIANT

VARIANT 是一种半结构化数据类型,可以存储不同数据类型的值,包括基本类型(整数、浮点数、字符串、布尔值、日期、时间戳)和复杂类型(结构体、映射、数组)。VARIANT 数据以二进制格式编码,以实现高效的存储和查询。

VARIANT 类型在处理来自 Apache Iceberg 表的数据时特别有用,这些表使用带有 variant 编码的 Parquet 格式,允许灵活的模式演化和异构数据的高效存储。

有关 Parquet variant 编码格式的更多信息,请参阅 Parquet Variant 编码规范

使用 VARIANT 数据

从 Iceberg 表查询 VARIANT 类型数据

StarRocks 支持从以 Parquet 格式存储的 Iceberg 表中查询 VARIANT 类型数据。查询使用 Parquet variant 编码的 Iceberg 表时,会自动识别 VARIANT 列。

查询包含 VARIANT 列的 Iceberg 表示例:


-- 查询包含 VARIANT 列的表
SELECT
id,
variant_col
FROM iceberg_catalog.db.table_with_variants;

从 VARIANT 数据提取值

StarRocks 提供了多个函数来从 VARIANT 数据中提取类型化的值:

示例 1:使用类型化的 getter 函数提取基本值。

SELECT
get_variant_int(variant_col, '$') AS int_value,
get_variant_string(variant_col, '$') AS string_value,
get_variant_bool(variant_col, '$') AS bool_value,
get_variant_double(variant_col, '$') AS double_value
FROM iceberg_catalog.db.table_with_variants;

示例 2:使用 JSON 路径表达式导航嵌套结构。

SELECT
get_variant_string(variant_col, '$.user.name') AS user_name,
get_variant_int(variant_col, '$.user.age') AS user_age,
get_variant_string(variant_col, '$.address.city') AS city
FROM iceberg_catalog.db.table_with_variants;

示例 3:访问数组元素。

SELECT
get_variant_int(variant_col, '$.scores[0]') AS first_score,
get_variant_int(variant_col, '$.scores[1]') AS second_score
FROM iceberg_catalog.db.table_with_variants;

示例 4:查询嵌套的 variant 数据并返回 VARIANT 类型。

SELECT
variant_query(variant_col, '$.metadata') AS metadata,
variant_query(variant_col, '$.items[0]') AS first_item
FROM iceberg_catalog.db.table_with_variants;

示例 5:检查 VARIANT 值的类型。

SELECT
variant_typeof(variant_col) AS root_type,
variant_typeof(variant_query(variant_col, '$.data')) AS data_type
FROM iceberg_catalog.db.table_with_variants;

将 JSON 转换为 VARIANT

StarRocks 支持将 JSON 值转换为 VARIANT。如果输入是 STRING,请先转换为 JSON。

SELECT
CAST(parse_json('{"id": 1, "flags": {"active": true}, "scores": [1.5, null]}') AS VARIANT) AS variant_value;
SELECT
CAST(json_col AS VARIANT) AS variant_value
FROM db.table_with_json;

将 VARIANT 数据转换为 SQL 类型

您可以使用 CAST 函数将 VARIANT 数据转换为标准 SQL 类型:

SELECT
CAST(variant_query(variant_col, '$.count') AS INT) AS count,
CAST(variant_query(variant_col, '$.price') AS DECIMAL(10, 2)) AS price,
CAST(variant_query(variant_col, '$.active') AS BOOLEAN) AS is_active,
CAST(variant_query(variant_col, '$.name') AS STRING) AS name
FROM iceberg_catalog.db.table_with_variants;

复杂类型也可以从 VARIANT 转换:

SELECT
CAST(variant_col AS STRUCT<id INT, name STRING>) AS user_struct,
CAST(variant_col AS MAP<STRING, INT>) AS config_map,
CAST(variant_col AS ARRAY<DOUBLE>) AS values_array
FROM iceberg_catalog.db.table_with_variants;

将 SQL 类型转换为 VARIANT

您可以将 SQL 值转换为 VARIANT。支持的输入类型包括 BOOLEAN、整数类型、FLOAT/DOUBLE、DECIMAL、STRING/CHAR/VARCHAR、JSON、DATE/DATETIME/TIME,以及复杂类型(ARRAY、MAP、STRUCT)。对于 MAP,编码时会将键转换为字符串。HLL、BITMAP、PERCENTILE 和 VARBINARY 暂不支持。

SELECT
CAST(123 AS VARIANT) AS v_int,
CAST(3.14 AS VARIANT) AS v_double,
CAST(DECIMAL(10, 2) '12.34' AS VARIANT) AS v_decimal,
CAST('hello' AS VARIANT) AS v_string,
CAST(PARSE_JSON('{"k":1}') AS VARIANT) AS v_json;

VARIANT 函数

VARIANT 函数可用于查询和提取 VARIANT 列中的数据。有关详细信息,请参阅各个函数的文档:

  • variant_query:查询 VARIANT 值中的路径并返回 VARIANT
  • get_variant:从 VARIANT 提取类型化的值(整数、布尔值、双精度浮点数、字符串)
  • variant_typeof:返回 VARIANT 值的类型名称

VARIANT 路径表达式

VARIANT 函数使用 JSON 路径表达式来导航数据结构。路径语法类似于 JSON 路径:

  • $ 表示 VARIANT 值的根
  • . 用于访问对象字段
  • [index] 用于访问数组元素(基于 0 的索引)
  • 包含特殊字符(如点)的字段名可以用引号括起来:$.\"field.name\"

路径表达式示例:

$                      -- 根元素
$.field -- 对象字段访问
$.nested.field -- 嵌套字段访问
$.\"field.with.dots\" -- 带引号的字段名
$[0] -- 第一个数组元素
$.array[1] -- 数组字段的第二个元素
$.users[0].name -- 嵌套数组访问
$.config[\"key\"] -- Map 风格访问

数据类型转换

当从带有 variant 编码的 Parquet 文件读取数据时,支持以下类型转换:

Parquet Variant 类型StarRocks VARIANT 类型
INT8, INT16, INT32, INT64int8, int16, int32, int64
FLOAT, DOUBLEfloat, double
BOOLEANboolean
STRINGstring
DATEDate
TIMESTAMP, TIMESTAMP_NTZTimestamp
DECIMALDecimal, float, double
STRUCTObject
MAPObject
ARRAYArray

限制和注意事项

  • VARIANT 类型支持从带有 variant 编码的 Parquet 格式 Iceberg 表中读取数据,并支持通过 StarRocks 文件写入器写出 Parquet 文件(未分片的 variant 编码)。
  • VARIANT 值的大小限制为 16 MB。
  • 当前仅支持读写未分片的 variant 值。
  • VARIANT 可通过 JSON 值或支持的 SQL 类型(包括 ARRAY、MAP、STRUCT)转换生成。
  • 嵌套结构的最大深度取决于底层 Parquet 文件结构。
Rocky the happy otterStarRocks Assistant

AI generated answers are based on docs and other sources. Please test answers in non-production environments.