Skip to content

feat(query): 补充数据处理函数与异常诊断 - #31

Merged
zhou-hao merged 22 commits into
masterfrom
codex/json-functions-plan
Jul 3, 2026
Merged

feat(query): 补充数据处理函数与异常诊断#31
zhou-hao merged 22 commits into
masterfrom
codex/json-functions-plan

Conversation

@zhou-ai-bot

@zhou-ai-bot zhou-ai-bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

目的

  • 在 ReactorQL 中补齐与 MySQL / PostgreSQL 常见行为对齐的 JSON 函数。
  • 补充适合大模型数据清洗、抽取、比较和聚合前处理的通用函数。
  • 修复 Java 21 下 JaCoCo 版本过旧导致的覆盖率采集失败,并保证覆盖率不低于 master 基准。
  • 修复 count(*) 在 JSqlParser 4.6 下被解析为 AllColumns 参数时未按全量计数处理的问题。
  • 保护高风险工具函数参数边界,并支持通过 metadata settings 在硬上限内调整默认限制。
  • 增加流式 ORDER BY 的资源保护与 Top-N 排序能力,避免大量数据无界收集。
  • 增加 ReactorQLMetadata#getSelectColumns(),在 SQL AST 释放后仍可结构化获取查询列。
  • 修复 format_datetime(l.timestamp, 'yyyy-MM-dd HH:mm:ss')cast(... as double) / DOUBLE PRECISION 等常见函数兼容问题。
  • 增加结构化异常诊断,提供错误码、行列、原因、建议、示例和中英文资源;用户可见建议只描述修复方式或支持用法。
  • 记录下一版本 Feature Registry / Policy 设计方向:安全函数与平台内部函数在 ReactorQL 构造时隔离,而不是查找时传参。

核心变动

  • 新增 JSONPath / JSON 数据处理函数,支持 JSONPath 读取、JSON 类型/校验/长度/keys、包含/路径存在、合并、集合比较等能力,并增加 json_path 作为 json_get 等价别名。
  • 注册 JSON、数值、字符串/正则、日期时间等常用数据处理函数,函数名按现有 metadata 规则大小写不敏感。
  • 静态 JSONPath 在 mapper 创建阶段编译,动态路径运行时校验;不使用全局 static cache,避免无界内存膨胀。
  • 对 JSONPath 增加长度与高风险语法限制,覆盖 ..、filter、函数调用、通配符等恶意或高成本构造。
  • json_merge/json_merge_preserve 按 MySQL 保留重复 key 语义处理,不简化为 Map.putAlljson_merge_patch 按 RFC 7396 处理 null 删除。
  • repeatreplaceregexp_replace、正则输入、JSON 文本/输出/深度/容器/路径等限制支持通过 metadata settings 调整,并通过硬上限防止 SQL hint 绕过保护。
  • count(*) 同时兼容 Function#isAllColumns() 和参数列表中的 AllColumns 形态,保持数据库常见语义。
  • 抽取 OrderBySupport:全局排序默认受 orderBy.maxRows 保护;ORDER BY ... LIMIT 使用 Top-N 候选窗口;orderBy.windowSize 仅表示显式窗口内局部排序。
  • 新增 ColumnSQLTypeReactorQLMetadata#getSelectColumns();支持普通 select item、聚合/函数/表达式、select *t.*、子查询、UNION 首个分支列、WITH 列别名等场景。
  • 新增 format_datetime 作为 date_format 等价别名;增强 CastFeature 类型归一化,支持 double precisionbigintnumeric(...)real/float4/float8 等常见类型别名。
  • 新增 ReactorQLException,保留 UnsupportedOperationException 兼容性,结构化承载错误码、表达式、行列、原因、建议、示例和 i18n 参数。
  • 将常见 SQL 解析、函数参数、JSON、时间格式、排序、分组、聚合、FROM 组合、merge_by_key 等错误收敛为结构化诊断异常。
  • 补充 i18n/reactorql/messages_zh.propertiesmessages_en.properties,用于默认中英文错误输出。
  • 统一收敛 regexp_replace('abc','a','$9') 这类非法替换分组异常,避免底层 JDK 异常直接泄漏为不可控错误。
  • 升级 jacoco-maven-plugin0.8.13,修复 Java 21 classfile instrumentation 问题。
  • 文档补充下一版本 FeatureRegistry / FeaturePolicy 方案:构造 ReactorQL 时绑定 registry/policy;工具类函数自控输入安全,平台内部访问类函数通过 policy 显式授权。

设计与测试目标

  • 设计稿:docs/plans/json-functions-support.mddocs/plans/streaming-order-by.mddocs/plans/reactorql-exception-diagnostics.md
  • 用户确认:已确认按当前 PR 范围实现;Feature Registry / Policy 纳入下一版本,不在本 PR 扩公共 API。
  • 测试目标:真实场景、真实数据、正常路径、异常路径、回归路径和边界路径均已覆盖;新增覆盖 count(*)、非法正则替换分组、JSON 错误结构/恶意路径、FunctionMapFeature 兼容分支、流式排序资源边界、查询列解析、format_datetimecast 类型别名、结构化异常诊断和 i18n 资源。
  • 注释 / 公共契约:新增 ColumnSQLTypeReactorQLMetadata#getSelectColumns() 公共契约注释;SelectColumnParserOrderBySupport、JSON 函数抽象与 helper 已说明职责、边界与数据库兼容语义;关键 merge 行为、metadata settings 硬上限、非法正则替换收敛、异常诊断边界保留代码或设计文档说明。
  • 数据权限:不适用;未涉及 JetLinks AssetsHolder 或业务数据权限。
  • 数据库兼容与性能:未引入数据库方言 SQL,仅模拟常见数据库 JSON / CAST / 日期格式函数行为;流式 ORDER BY 通过最大行数、Top-N 和局部窗口排序避免无界内存风险。
  • 链路追踪:不适用;表达式函数、异常诊断与排序为本地计算,无外部 I/O 或关键业务链路。
  • MBean 运维可观测性:不适用;未引入常驻任务、缓存、队列或后台执行器。

测试结果

  • 命令:mvn -q test
  • 新增/更新测试:
    • ReactorQLExceptionTest:覆盖结构化异常字段、兼容性、语法错误、函数参数错误、JSON 非安全路径、ORDER BY 资源限制、日期格式、窗口参数、i18n 资源键和建议文案边界。
    • ReactorQLTest#testCount:覆盖 count(*)sum(*) 星号聚合参数回归场景。
    • ReactorQLTest#testOrderByMaxRowstestOrderByLimitUseBoundedTopNtestOrderByDynamicLimitUseBoundedTopNtestOrderByTopNBufferLimittestOrderByWindowSizetestOrderByMultipleColumnsAndNullOrderingtestOrderByInvalidSettings:覆盖排序资源限制、Top-N、动态 limit、窗口排序、多列/null 排序与非法设置。
    • ReactorQLTest#testFormatDatetimeAndCastWithTableAlias:覆盖 format_datetime(l.timestamp, ...)cast(l.value as double)DOUBLE PRECISIONBIGINT
    • ReactorQLTest#testJsonPathFunctionstestJsonInvalidAndMaliciousInputs:覆盖 json_path 等价别名、错误结构数据、恶意路径和动态路径保护。
    • MergeByKeyFeatureTest:覆盖 merge_by_key 参数、排序、重复键、资源限制和结构化异常。
    • DefaultReactorQLMetadataTest#testSelectColumns*:覆盖普通列、聚合、函数、表达式、通配列、子查询、UNIONt.*、WITH 列别名、lateral/parenthesis/subJoin 以及 SQL AST release 后查询列缓存。
    • JsonFunctionCoverageTest:覆盖 JSON 集合操作负向/嵌套分支、JSON 校验与参数保护分支。
    • CommonFunctionCoverageTest:覆盖常用字符串/正则/日期边界函数与安全失败场景。
    • FunctionMapFeatureCompatibilityTest:覆盖 legacy protected apply、metadata mapper、无参/defaultValue、参数保护、distinct/unique wrapper、异步参数顺序分支。
  • 单元测试:260 passed, 0 failed, 0 errors, 0 skipped
  • 集成测试:不适用;本 PR 未涉及数据库、消息、事件、协议、跨模块边界、外部依赖或启动装配。
  • 压力测试:不适用;未引入复杂数据库 SQL、原生 SQL、数据库分页或批量写入。本地性能烟测:json_get 静态路径 20000 行约 392ms;通用数据函数 20000 行约 1468ms。
  • 当前本地 JaCoCo 覆盖率:
    • Instruction:93.57%
    • Branch:81.43%
    • Line:94.52%
  • master 基准覆盖率:
    • Instruction:90.97%
    • Branch:78.94%
    • Line:93.31%
  • 结论:当前 Instruction / Branch / Line 覆盖率均不低于 master 基准。
  • PR CI:最新提交已推送,GitHub 检查以最新 CI 结果为准。

文档同步情况

  • 已同步:docs/plans/json-functions-support.md 已从计划更新为实现状态与测试结论,补充 settings 可配置限制、JSON 函数实现拆分与下一版本 Feature Registry / Policy 设计。
  • 已同步:docs/plans/streaming-order-by.md 记录流式 ORDER BY 的资源边界、Top-N 策略、窗口排序语义与测试计划。
  • 已同步:docs/plans/reactorql-exception-diagnostics.md 记录结构化异常模型、错误码、公开输出边界、落地范围和测试要求。
  • 未同步:README 未更新;本次不改变仓库长期总览。
  • 说明:测试证据放 PR / CI,未新增独立任务流水文档。

风险与说明

  • 影响范围:ReactorQL 内置表达式函数、聚合函数解析、排序处理、metadata 查询列解析和用户可见异常;不涉及持久化数据结构或外部 API 破坏性变更。
  • 注释 / 公共契约:已补查询列公共契约、排序策略、JSON 函数抽象、关键数据库兼容语义、metadata settings 硬上限与异常收敛注释;异常诊断的用户可见文案边界已写入设计文档并补测试约束。
  • 链路追踪 / 可观测性:不涉及;本地纯函数计算、异常诊断与内存排序无外部 I/O。
  • MBean / 运维可观测性:不涉及;未引入常驻任务、缓存、队列或后台执行器。
  • 未覆盖场景:正则函数仍使用 Java 正则语义,复杂恶意正则的超时隔离不在本 PR 范围内。getSelectColumns() 对普通表 select * 无外部 schema 时仍保留通配列,不凭空推断表结构。
  • 已知限制:JSONPath 安全边界当前采用白名单式限制常见高风险语法;如后续需要 filter/通配符/递归扫描,应单独评估性能与资源上限。metadata settings 允许调节默认限制,但保留硬上限,不允许通过 SQL hint 将限制调成无界或危险值。Feature Registry / Policy 已纳入下一版本设计,不在本 PR 改公共 API,避免扩大兼容面。

@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.23668% with 309 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.17%. Comparing base (d68bf1d) to head (8a70c63).

Files with missing lines Patch % Lines
.../reactor/ql/supports/DefaultReactorQLMetadata.java 90.70% 19 Missing and 27 partials ⚠️
...tlinks/reactor/ql/supports/SelectColumnParser.java 80.21% 14 Missing and 22 partials ⚠️
...ks/reactor/ql/supports/from/MergeByKeyFeature.java 92.36% 13 Missing and 17 partials ⚠️
...links/reactor/ql/exception/ReactorQLException.java 82.99% 15 Missing and 10 partials ⚠️
...s/reactor/ql/supports/map/JsonFunctionSupport.java 86.03% 14 Missing and 11 partials ⚠️
...ctor/ql/supports/map/JsonCollectionOperations.java 84.05% 1 Missing and 21 partials ⚠️
...eactor/ql/supports/map/JsonOperatorMapFeature.java 76.74% 5 Missing and 15 partials ⚠️
...g/jetlinks/reactor/ql/supports/SqlParserUtils.java 85.71% 4 Missing and 13 partials ⚠️
...n/java/org/jetlinks/reactor/ql/OrderBySupport.java 89.20% 4 Missing and 11 partials ⚠️
...inks/reactor/ql/supports/map/JsonValueSupport.java 93.37% 5 Missing and 6 partials ⚠️
... and 22 more
Additional details and impacted files
@@             Coverage Diff              @@
##             master      #31      +/-   ##
============================================
+ Coverage     86.96%   88.17%   +1.21%     
- Complexity      962     1832     +870     
============================================
  Files            63       77      +14     
  Lines          2586     4898    +2312     
  Branches        360      765     +405     
============================================
+ Hits           2249     4319    +2070     
- Misses          172      259      +87     
- Partials        165      320     +155     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@zhou-hao zhou-hao changed the title docs(json): 制定常用 JSON 函数支持计划 feat(json): 补充数据库兼容 JSON 与数据处理函数 Jul 1, 2026
.as(wrapper);
}

private Object evaluate(JsonLimits limits, List<Object> args, JsonPath path1, JsonPath path2, JsonPath path3, List<JsonPath> restPaths) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不应该每次switch吧? 在createMapper 时就可以确定行为了啊. 而且这个类膨胀太大了, 单独封装一个抽象json path, 然后每个行为单独继承?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已处理:JsonPathFunctionMapFeature 现在只负责参数校验、静态路径预编译和参数流装配;具体行为拆到 JsonPathFunctionFeatures 的各函数实现,运行期不再按函数名 switch。同时拆出 JsonFunctionSupportJsonValueSupportJsonCollectionOperations,降低单类膨胀。CI build / Codacy / Codecov 均已通过。

@zhou-hao
zhou-hao force-pushed the codex/json-functions-plan branch from 97eafd1 to bc6f050 Compare July 2, 2026 01:19
@zhou-hao
zhou-hao force-pushed the codex/json-functions-plan branch from c97b241 to c52143e Compare July 2, 2026 02:24
@zhou-hao
zhou-hao marked this pull request as ready for review July 2, 2026 04:29
@zhou-hao
zhou-hao requested a review from Copilot July 2, 2026 04:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends ReactorQL’s built-in function set to better match common MySQL/PostgreSQL JSON behaviors and adds general-purpose data processing functions (string/regex/date), while tightening safety limits via metadata settings, fixing count(*) parsing compatibility, and updating build tooling for Java 21 coverage collection.

Changes:

  • Add a JSONPath-based JSON function stack (path compilation, normalization, collection ops) plus MySQL/PostgreSQL-compatible JSON function names.
  • Register a broader set of common numeric/string/regex/date processing functions with configurable hard-limited safety settings.
  • Fix count(*) handling for JSqlParser 4.6 AllColumns, and upgrade JaCoCo to support Java 21.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/test/resources/logback-test.xml Adds test Logback config and reduces JsonPath logger noise.
src/test/java/org/jetlinks/reactor/ql/supports/map/FunctionMapFeatureCompatibilityTest.java Adds tests ensuring legacy FunctionMapFeature behavior remains compatible with metadata-aware mappers.
src/test/java/org/jetlinks/reactor/ql/ReactorQLTest.java Expands functional coverage for count(*), common SQL-like functions, regex functions, and JSON function behaviors/limits.
src/test/java/org/jetlinks/reactor/ql/JsonFunctionPerformanceTest.java Adds performance smoke tests for JSON/static-path and common function pipelines.
src/test/java/org/jetlinks/reactor/ql/JsonFunctionCoverageTest.java Adds extensive JSON edge/negative/security coverage for new JSON functions.
src/test/java/org/jetlinks/reactor/ql/CommonFunctionCoverageTest.java Adds boundary/safety tests for new string/regex/date functions and settings.
src/main/java/org/jetlinks/reactor/ql/supports/map/JsonValueSupport.java Implements JSON value normalization, validation, depth/container/text/output limits, and scalar helpers.
src/main/java/org/jetlinks/reactor/ql/supports/map/JsonPathFunctionMapFeature.java Introduces a JSONPath function base class with static path compilation and argument assembly.
src/main/java/org/jetlinks/reactor/ql/supports/map/JsonPathFunctionFeatures.java Implements per-function JSON behaviors without runtime name dispatch.
src/main/java/org/jetlinks/reactor/ql/supports/map/JsonFunctionSupport.java Centralizes settings parsing, JSONPath safety checks, and shared JSON function logic.
src/main/java/org/jetlinks/reactor/ql/supports/map/JsonFunctionContext.java Adds a per-evaluation context carrying args, limits, and compiled static paths.
src/main/java/org/jetlinks/reactor/ql/supports/map/JsonCollectionOperations.java Adds deep-equals, contains/overlaps, set ops, and merge semantics (including MySQL preserve/patch behavior).
src/main/java/org/jetlinks/reactor/ql/supports/map/FunctionMapFeature.java Adds metadata-aware mapper support while preserving the legacy protected apply(record, mappers) override chain.
src/main/java/org/jetlinks/reactor/ql/supports/DefaultReactorQLMetadata.java Registers common data processing functions + JSON functions and enforces configurable hard-limited safety bounds.
src/main/java/org/jetlinks/reactor/ql/supports/agg/CountAggFeature.java Fixes count(*) for both isAllColumns() and parameter-list AllColumns forms.
pom.xml Upgrades JaCoCo plugin and adds com.jayway.jsonpath:json-path.
docs/plans/json-functions-support.md Documents implemented function set, limits, and next-step registry/policy direction.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +188 to +191
addGlobal(JsonPathFunctionMapFeature.jsonGet("json_get", 2, 999, false));
addGlobal(JsonPathFunctionMapFeature.jsonExtract("json_extract", 2, 999));
addGlobal(JsonPathFunctionMapFeature.jsonGet("json_value", 2, 999, true));
addGlobal(JsonPathFunctionMapFeature.jsonGet("json_query", 2, 999, false));
Comment thread src/main/java/org/jetlinks/reactor/ql/supports/DefaultReactorQLMetadata.java Outdated
Comment thread src/main/java/org/jetlinks/reactor/ql/supports/DefaultReactorQLMetadata.java Outdated
Comment thread src/main/java/org/jetlinks/reactor/ql/supports/DefaultReactorQLMetadata.java Outdated
Comment thread docs/plans/json-functions-support.md Outdated
- `json_unquote(value)`:结构化值转 JSON 字符串,普通标量转字符串。
- `json_valid(value)`:非字符串对象视为合法 JSON;字符串必须能解析为 JSON 才返回 `true`。
- `json_type` / `json_typeof(value)`:返回 `object`、`array`、`string`、`integer`、`double`、`boolean`、`null`。
- `json_length(json[, path])`:对象返回 key 数,数组返回元素数,标量返回 1,空值返回 0。
Comment on lines +18 to +28
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;

import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

class JsonFunctionPerformanceTest {

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Comment on lines +129 to +140
private Flux<Object> createParameterStream(ReactorQLRecord record,
List<Function<ReactorQLRecord, Publisher<Object>>> mappers) {
return Flux.fromIterable(mappers)
.flatMap(mp -> {
if (defaultValue != null) {
return Mono
.fromDirect(mp.apply(record))
.defaultIfEmpty(defaultValue);
}
return mp.apply(record);
});
}
Comment on lines +341 to +346
private static String toPathSegment(String key) {
if (INTEGER.matcher(key).matches()) {
return "[" + key + "]";
}
return "['" + key.replace("'", "\\'") + "']";
}
@zhou-hao
zhou-hao requested a review from Copilot July 2, 2026 07:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

zhou-hao added 5 commits July 2, 2026 20:21
- 补充 JSON、时间、字符串等常用函数与 select 列解析场景
- 引入结构化 ReactorQLException 和中英文资源,统一用户可见错误建议
- 增强 ORDER BY、merge_by_key、窗口、聚合、JSON 等异常与安全限制测试
@zhou-hao zhou-hao changed the title feat(json): 补充数据库兼容 JSON 与数据处理函数 feat(query): 补充数据处理函数与异常诊断 Jul 3, 2026
@zhou-hao
zhou-hao merged commit 8c99f80 into master Jul 3, 2026
4 checks passed
@zhou-hao
zhou-hao deleted the codex/json-functions-plan branch July 3, 2026 03:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants