TO_PROTOBUF

功能概述

把 STRUCT 编码为 Protobuf 二进制数据,是 FROM_PROTOBUF 的逆操作。适合把表中的数据按约定的 proto 格式编码后写入 Kafka、对象存储,供下游服务直接反序列化。

语法

TO_PROTOBUF(<struct>, <message_name>, <descriptor> [, <options>])

参数说明

  • <struct>
    <struct>
    :STRUCT 类型,要编码的数据。STRUCT 字段按名称匹配消息中的字段,常用
    NAMED_STRUCT
    NAMED_STRUCT
    构造。为 NULL 时返回 NULL。

  • <message_name>
    <message_name>
    :STRING 常量,消息类型名,如
    'test.SimpleMsg'
    'test.SimpleMsg'
    。

  • <descriptor>
    <descriptor>
    :BINARY 常量,
    protoc --descriptor_set_out
    protoc --descriptor_set_out
    生成的
    FileDescriptorSet
    FileDescriptorSet
    ,生成方法见 Protobuf 函数。

  • <options>
    <options>
    :可选,
    MAP<STRING, STRING>
    MAP<STRING, STRING>
    常量,支持
    max.descriptor.bytes
    max.descriptor.bytes
    (描述符大小上限,默认 1 MB)。

返回 BINARY 类型。

使用示例

以下示例使用这个 proto 定义编译出的描述符:

syntax = "proto3"; package test; message SimpleMsg { int32 id = 1; string name = 2; double score = 3; bool active = 4; int64 ts = 5; float ratio = 6; bytes data = 7; }

编码一行数据,再用

FROM_PROTOBUF
FROM_PROTOBUF
解码,确认往返一致:

SELECT from_protobuf( to_protobuf( named_struct('id', 42, 'name', 'hello', 'score', 3.14D, 'active', true, 'ts', 1700000000000L, 'ratio', CAST(2.5 AS FLOAT), 'data', CAST(x'010203' AS BINARY)), 'test.SimpleMsg', x'0a89010a0a746573742e70726f746f120474657374226d0a0953696d706c654d7367120a0a026964180120012805120c0a046e616d65180220012809120d0a0573636f7265180320012801120e0a06616374697665180420012808120a0a027473180520012803120d0a05726174696f180620012802120c0a046461746118072001280c620670726f746f33' ), 'test.SimpleMsg', x'0a89010a0a746573742e70726f746f120474657374226d0a0953696d706c654d7367120a0a026964180120012805120c0a046e616d65180220012809120d0a0573636f7265180320012801120e0a06616374697665180420012808120a0a027473180520012803120d0a05726174696f180620012802120c0a046461746118072001280c620670726f746f33' ) AS roundtrip;

{"id":42,"name":"hello","score":3.14,"active":true,"ts":1700000000000,"ratio":2.5,"data":[01 02 03]}

只设置部分字段,编码结果只包含这些字段:

SELECT hex(to_protobuf( named_struct('id', 42, 'name', 'hello'), 'test.SimpleMsg', x'0a89010a0a746573742e70726f746f120474657374226d0a0953696d706c654d7367120a0a026964180120012805120c0a046e616d65180220012809120d0a0573636f7265180320012801120e0a06616374697665180420012808120a0a027473180520012803120d0a05726174696f180620012802120c0a046461746118072001280c620670726f746f33' )) AS encoded;

encoded
082A120568656C6C6F

08 2A
08 2A
是字段 1(id = 42),
12 05 68656C6C6F
12 05 68656C6C6F
是字段 2(name = "hello")。

注意事项

  • STRUCT 字段按名称匹配 proto 字段,STRUCT 中没有的字段不会写入编码结果。
  • 消息类型名和描述符必须是常量。

相关文档

联系我们
预约咨询
微信咨询
电话咨询
邮件咨询