Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Oracle: sum() of floats whose total is whole gives an int, 2 where Neo4j gives 2.0

已关闭
#189 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

已经有一个关联 PR 被合并了。

  • #197 来自 @jasperblues —— 已合并

评估

难度
4/5
预计耗时
3-5 天
新手友好度
48/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
postgresql, python, sql, sqlite
领域
backend, databases

调研方向

Start with drivine/cypher/sql/sql_cypher_compiler.py:4452-4453 and the Oracle compiler in drivine/cypher/sql/oracle_cypher_compiler.py; compare how sum is compiled with the unmerged drivine4j fix described in the issue. Port the two named tests from CypherQueryCrossEngineTest and CompiledSizeTest, then check the upcoming “Aggregates of floats” spec case in queries.yaml. Done when Oracle preserves float results for sums containing fractional values while integer sums, including empty sums, remain integers.

由索引模型根据 Issue 内容生成。

描述

Port of liberation-data/drivine4j#304.

On Oracle, UNWIND [0.5, 1.0, 0.5] AS x RETURN sum(x) gives 2, an int, where Neo4j, Postgres and SQLite give 2.0, a float. Oracle's NUMBER keeps no kind, so a sum of floats whose total is whole comes back as an integer. The same goes for sum over [1, 1.0], [1, 0.5, 0.5], sum(DISTINCT x) over [1.0, 1.0], a parameter list such as $xs = [0.5, 0.5], a stored float, and what is worked out from such a sum (toString(sum(x)) gives "2", sum(x) + 1 gives 3).

Here, sum compiles to COALESCE(sum(<number>), 0) on every store, in drivine/cypher/sql/sql_cypher_compiler.py:4452-4453, and the Oracle compiler (drivine/cypher/sql/oracle_cypher_compiler.py) doesn't override it.

The fix in drivine4j, not merged yet, makes sum a hook on the base compiler, which Oracle overrides:

CASE WHEN MAX(JSON_VALUE(x, '$?(@.type() == "double" || (@.type() == "number" && @.string() has substring "."))')) IS NOT NULL
THEN JSON_SCALAR(TO_BINARY_DOUBLE(sum(JSON_VALUE(x, '$?(@.type() != "string")' RETURNING NUMBER))))
ELSE JSON_SCALAR(COALESCE(sum(JSON_VALUE(x, '$?(@.type() != "string")' RETURNING NUMBER)), 0)) END

That gives a float where any value summed is a double or a number with a fraction, and an integer otherwise (0 over no rows). Each read is a single JSON path that tests the kind itself, because nothing is bound under an aggregate. So the statement reads each value three times, as number() does now, and doesn't grow under nested functions. Oracle's JSON path can't compare @ to @.floor() (ORA-40597), which is why the fraction test checks the number's text for a point.

avg, min and max already keep a float a float on Oracle. percentileDisc, percentileCont, stDev and stDevP aren't compiled to SQL.

Tests to port: drivine4j's an aggregate of floats gives a float, whole or not, and a sum of integers an integer in CypherQueryCrossEngineTest, and a sum reads each value it sums as often as an avg does, and grows under functions as an avg does in CompiledSizeTest. The spec case "Aggregates of floats" is coming to drivine-cypher-spec's queries.yaml.

主要语言
Python
星标
1
派生
0
平均合并
1 小时 19 分钟
30 天内合并 PR
122

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

liberation-data/drivine-python 的其他 Issue

查看 liberation-data/drivine-python 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。