StarRocks positive() 数学函数详解:语法、数据类型支持与源码实现原理
2026/9/18 12:06:39 网站建设 项目流程

StarRocks positive() 数学函数详解:语法、数据类型支持与源码实现原理

【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks

positive(x)是 StarRocks 提供的一元数学函数,功能是将输入值原样返回,不做任何数学变换。本文以官方函数文档为主体,结合 StarRocks 开源仓库中的函数注册表与 BE 端向量化实现源码,深入讲解positive()的语法、参数类型约束、返回值规则、使用示例及其底层实现原理,并与其姊妹函数negative()进行对照,帮助你准确理解这一恒等(identity)运算在查询中的真实行为与适用场景。

函数概述

positive(x)返回参数x本身的值,属于一元恒等函数。从语义上看,它不改变数值的大小与符号,其作用更偏向于"显式声明数值为正"或在泛型/模板化查询中保持某种数值类型路径的一致。

在官方文档(positive.md)中,其定位被描述为:

Returnsxas a value.

即:返回x作为一个值。

语法

POSITIVE(x);
  • 函数名大小写不敏感,positivePOSITIVE等价;
  • 参数个数固定为 1,传入多于或少于一个参数都会导致语法或函数匹配错误;
  • 该函数同时适用于列、常量字面量以及表达式,例如positive(column_a)positive(3)positive(1 + 2)均合法。

参数与数据类型支持

参数x支持以下 6 种数据类型:

数据类型说明
BIGINT64 位有符号整数
DOUBLE双精度浮点数
DECIMALV2StarRocks 传统高精度定点数类型
DECIMAL3232 位精度定点数
DECIMAL6464 位精度定点数
DECIMAL128128 位精度定点数

这一支持范围在 FE 端的函数注册表中有完整的对应记录。在 gensrc/script/functions.py 中,positive函数注册了 6 个重载(函数 ID 10260 ~ 102622),分别映射到 BE 端MathFunctions::positive模板的不同实例化:

  • positive(DOUBLE) -> DOUBLE
  • positive(BIGINT) -> BIGINT
  • positive(DECIMALV2) -> DECIMALV2
  • positive(DECIMAL32) -> DECIMAL32
  • positive(DECIMAL64) -> DECIMAL64
  • positive(DECIMAL128) -> DECIMAL128

需要注意:positive不支持INTSMALLINTTINYINTFLOATLARGEINT等其他数值类型。若直接对这些类型调用positive(),StarRocks 会因找不到匹配的函数签名而报错。此时需要先使用CAST显式转换为上述 6 种类型之一,例如positive(cast(int_col as bigint))

返回值

positive(x)返回一个值与x的数据类型完全相同,即函数不改变数值的精度与标度(scale),是严格的一元恒等变换。

这与函数底层实现是一致的:在 BE 端向量化实现中,positive对输入列直接进行"可变引用返回",不做任何逐元素计算(详见下文"源码实现原理"一节)。

示例

以下示例来自官方文档,可直接在 StarRocks 的 MySQL 客户端中执行验证。

示例一:BIGINT 常量

mysql> select positive(3); +-------------+ | positive(3) | +-------------+ | 3 | +-------------+ 1 row in set (0.01 sec)

positive(3)将整数3原样返回。

示例二:DECIMALV2 常量

mysql> select positive(cast(3.14 as decimalv2)); +--------------------------------------+ | positive(CAST(3.14 AS DECIMAL(9,0))) | +--------------------------------------+ | 3.14 | +--------------------------------------+ 1 row in set (0.01 sec)

可以看到,虽然 FE 端在结果列标题中按照 DECIMALV2 的默认显示形式将CAST(3.14 AS DECIMALV2)展示为DECIMAL(9,0),但函数实际返回的数值仍完整保留为3.14,小数部分未丢失、符号未改变,进一步印证了positive保持输入类型与数值原样返回的特性。

与 negative() 的对照

理解positive的最好方式是与它的镜像函数negative()对照,两者的文档结构、类型支持完全对称:

  • negative(x)返回x的相反数,例如negative(3)的结果为-3
  • positive(x)返回x本身,例如positive(3)的结果为3
  • 两者支持完全相同的数据类型集合(BIGINT、DOUBLE、DECIMALV2、DECIMAL32、DECIMAL64、DECIMAL128)。

在 gensrc/script/functions.py 中,negative的 6 个重载(函数 ID 10270 ~ 102722)紧邻positive注册,一一对应;官方文档 negative.md 亦与之呼应。

源码实现原理

1. FE 端函数注册

positive是一个内建标量函数,其函数签名(function signature)在 gensrc/script/functions.py 中集中注册,构建时通过 StarRocks 的代码生成管线产出 FE 与 BE 两侧的函数元数据。每种支持的类型各对应一个独立的函数 ID 与 BE 实现入口,例如:

[10260, "positive", True, False, "DOUBLE", ["DOUBLE"], "MathFunctions::positive<TYPE_DOUBLE>"], [10261, "positive", True, False, "BIGINT", ["BIGINT"], "MathFunctions::positive<TYPE_BIGINT>"], [10262, "positive", True, False, "DECIMALV2", ["DECIMALV2"], "MathFunctions::positive<TYPE_DECIMALV2>"], [102620, "positive", True, False, "DECIMAL32", ["DECIMAL32"], "MathFunctions::positive<TYPE_DECIMAL32>"], [102621, "positive", True, False, "DECIMAL64", ["DECIMAL64"], "MathFunctions::positive<TYPE_DECIMAL64>"], [102622, "positive", True, False, "DECIMAL128", ["DECIMAL128"], "MathFunctions::positive<TYPE_DECIMAL128>"],

上述每一行都声明了"入参类型 -> 返回类型"完全一致,这正是文档中"返回类型与输入类型相同"这一规则在实现层面的直接体现。

2. BE 端向量化实现

在 BE 端,positive的向量化实现位于 be/src/exprs/math_functions.h:

template <LogicalType Type> DEFINE_VECTORIZED_FN(positive) { return std::move(*columns[0]).mutate(); }

其实现极为精简:std::move(*columns[0]).mutate()直接取得输入列columns[0]的所有权并返回其可变版本,不执行任何数值运算。也就是说,positive在 StarRocks 的向量化执行引擎中是一个零开销的恒等操作(identity operation),不会引入额外的计算或数据拷贝开销。

与之对照,同一文件中的negative实现则不同:

template <LogicalType Type> DEFINE_VECTORIZED_FN(negative) { if constexpr (lt_is_decimal<Type>) { const auto& type = context->get_return_type(); return VectorizedStrictUnaryFunction<negativeImpl>::evaluate<Type>(VECTORIZED_FN_ARGS(0), type.precision, type.scale); } else { return VectorizedStrictUnaryFunction<negativeImpl>::evaluate<Type>(VECTORIZED_FN_ARGS(0)); } }

negative通过negativeImpl对每个元素取相反数;对于定点数类型还会传入precisionscale,以保证负数转换时精度与标度不被破坏。而positive连这一步都省去了——从源码结构可以推断,positive本质上是一个为保持"一元函数调用形态一致性"而提供的语义占位符,它在执行层直接透传数据。

典型使用场景与注意事项

  • 类型保持的显式声明:在需要明确"数值为正"语义或希望与其他一元数学函数保持调用形式一致时,可使用positive(col)
  • 通用函数/模板化 SQL 的占位:在自动生成的 SQL 或函数包装层中,positive可作为恒等映射占位,避免对"正数情况"单独写分支;
  • 类型约束:仅支持文档列出的 6 种类型,使用其他数值类型前需显式CAST
  • 性能:由于 BE 端实现为直接透传列,positive对查询性能几乎无影响,可以放心用于大数据量列;
  • NULL 语义positive为恒等函数,输入NULL时结果仍为NULL(与大多数标量函数保持一致),实际使用时建议结合COALESCEIFNULL处理空值场景。

延伸阅读

  • StarRocks 数学函数索引:查看完整的数学函数清单;
  • negative 函数文档:positive的镜像函数,返回输入值的相反数;
  • 函数注册表实现:positive/negative等内建标量函数的签名定义来源;
  • BE 端数学函数向量化实现:包含positivenegative及大量其他数学函数的底层执行逻辑。

【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询