feat: add math functions SIGN/CBRT/TRUNC#813
Merged
Leomrlin merged 3 commits intoJul 24, 2026
Merged
Conversation
- sign(x): returns -1 for negative, 0 for zero, 1 for positive - cbrt(x): returns the cube root of a number - trunc(x, d): truncates x to d decimal places (not round) Add UDF classes (Sign.java, Cbrt.java, Trunc.java) and register them in BuildInSqlFunctionTable. Add cbrt/trunc static methods to GeaFlowBuiltinFunctions. Add unit tests covering negative, zero, and null edge cases. Resolves apache#790 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Author
1 similar comment
Contributor
Author
Leomrlin
reviewed
Jul 20, 2026
| public class MathUdfTest { | ||
|
|
||
| @Test | ||
| public void testSign() { |
Contributor
There was a problem hiding this comment.
These tests verify the Java methods directly, but they do not exercise SQL registration, overload resolution, type inference, or runtime invocation.
Could we add an end-to-end SQL test for SIGN/CBRT/TRUNC there?
Contributor
Author
There was a problem hiding this comment.
已添加端到端 SQL 测试,通过完整查询管线验证函数的注册、重载解析、类型推断和运行时调用。测试在 geaflow-dsl-runtime 模块:
- MathSignCbrtTruncTest.java - 通过 QueryTester 驱动测试
- query/math_sign_cbrt_trunc_001.sql - 覆盖 sign(Double/Long/Integer)、cbrt(Double)、trunc(Double 带/不带 scale、Long、Integer)
- data/ + expect/ - 输入数据与期望输出
测试揭示了 Calcite 真实的重载解析行为:sign(bigint)/sign(int) 会被提升为 double,匹配 sign(Double) 重载(返回 1.0/-1.0);而
trunc(bigint)/trunc(int) 则精确匹配 Long/Integer 重载。期望输出里记录了这个差异。
已在本地验证通过(Tests run: 1, Failures: 0, Errors: 0)。
The existing MathUdfTest verifies the Java eval() methods directly but does not exercise SQL registration, overload resolution, type inference, or runtime invocation. Add an E2E SQL test via QueryTester that runs the functions through the full query pipeline. Covers: - SQL registration in BuildInSqlFunctionTable (sign/cbrt/trunc) - Overload resolution: sign(Double/Long/Integer), trunc(Double,Long/ Integer, with and without scale) - Type inference: each overload returns a distinct type, propagated un-cast to the sink schema - Runtime invocation through the query engine - Null-free boundary cases (zero, negative, positive, integer doubles) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use a relative forward-slash sink path instead of the ${target}
placeholder. QueryTester rewrites ${target} to an absolute path that on
Windows contains backslashes; injected into a SQL string literal those
backslashes get escaped (\t -> tab, \U/\s/\g dropped) and the sink path
is corrupted, so the test fails on Windows. A relative path avoids the
rewrite and resolves to the same target/ directory checkSinkResult()
reads, on both Windows and Linux.
Also align the expected output with the real Calcite overload resolution
behaviour: sign(bigint)/sign(int) are promoted to double and match
sign(Double) (Long/Integer overloads not selected), while trunc(bigint)
and trunc(int) select the Long/Integer overloads. This type-inference
difference is exactly what an end-to-end SQL test surfaces.
Verified locally: Tests run: 1, Failures: 0, Errors: 0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & Why
The math folder
udf/table/math/currently has only E, Log2, and Round — noticeably thin. Adding SIGN (the sign of anumber), CBRT (cube root), and TRUNC (truncate to N decimals) is a quick win that meaningfully fills out the SQL
toolbox.
Resolves #790
Changes
New UDF classes
sign(x)returns -1 for negative, 0 for zero, 1 for positive. Supports Double/Long/Integer input.cbrt(x)returns the cube root of x. Supports Double input.trunc(x, d)truncates x to d decimal places (not round). Supports Double/Long/Integer input withoptional scale parameter.
Registration
BuildInSqlFunctionTable.javacbrt(Double)andtrunc(Double, Integer)static methods toGeaFlowBuiltinFunctions.java(sign alreadyexisted)
Tests
MathUdfTest.java— unit tests for Sign, Cbrt, Trunc UDF classestestCbrt()andtestTrunc()toInternalFunctionsTest.javaTRUNC vs ROUND — key distinction
truncusesRoundingMode.DOWNwhileroundusesRoundingMode.HALF_UP: