Implement Spark-compatible `xpath_double` / `xpath_number`
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
调研方向
Start in crates/spark/src/function/xml/ and confirm whether the shared evaluator from the xpath issue already exists; this issue only adds evaluate_number(xml, path) -> Option<f64> on top of it, plus registration of xpath_number as an alias. Cross-read Spark's XPathDoubleEvaluator/UDFXPathUtil.evalNumber for the number() conversion rules, then write crates/sqllogictest/test_files/xml/xpath_double.slt covering the node-set, boolean, NaN/Infinity, -0 and NULL cases listed here. Done means both names pass the slt file and the function carries a #[user_doc] entry.
由索引模型根据 Issue 内容生成。
描述
Part of #271 and apache/datafusion-comet#7300.
What the function does
xpath_double(xml, path) evaluates an XPath 1.0 expression, converts the result with the XPath number()
rules (XPathConstants.NUMBER, a Java Double), and returns it as DOUBLE. xpath_number is a registered
alias of the same expression: expression[XPathDouble]("xpath_number", true), and its pretty name is
xpath_number. Both arguments are strings (collation-aware from 4.0), and path must be foldable. The result
is always nullable. Available since Spark 2.0.0.
Parsing, DTD and entity handling, namespaces, NULL and empty-string handling, invalid-XML and invalid-path
errors, and lazy path compilation are shared with the family. They are specified in the xpath issue, and
this function should reuse that evaluator. This issue covers only the numeric conversion. xpath_float,
xpath_int, xpath_long and xpath_short take the same double and narrow it.
Examples
SELECT xpath_double('<a><b>1</b><b>2</b></a>', 'sum(a/b)');
-- 3.0
SELECT xpath_double('<a>this is not a number</a>', 'a');
-- NaN
SELECT xpath_double('<a>this 2 is not a number</a>', 'a');
-- NaN
SELECT xpath_double('<a><b>2000000000</b><c>40000000000</c></a>', 'a/b * a/c');
-- 8.0E19
SELECT xpath_double('<a>try a boolean</a>', 'a = 10');
-- 0.0
SELECT xpath_double('<a><b class="odd">1</b><b class="even">2</b><b class="odd">4</b><c>8</c></a>', 'a/b');
-- 1.0
SELECT xpath_double('<a><b class="odd">1</b><b class="even">2</b><b class="odd">4</b><c>8</c></a>', 'sum(a/*)');
-- 15.0
SELECT xpath_double('<a><b class="odd">1</b><b class="even">2</b><b class="odd">4</b><c>8</c></a>', 'sum(a/b[@class="odd"])');
-- 5.0
SELECT xpath_number('<a><b>1.0</b><b>2.1</b></a>', 'sum(a/b)');
-- 3.1
These come from the ExpressionDescription, the Hive udf_xpath_double golden files run by
HiveCompatibilitySuite, XPathExpressionSuite and XPathFunctionsSuite. In UDFXPathUtilSuite, a/c[2]
on <c>-77</c> gives -77.0, and an attribute k="foo" gives NaN.
Edge cases to test
- Conversion rules from XPath 1.0
number():- a node-set uses the string value of its first node in document order (
a/babove gives1.0, not the sum); - a boolean gives
1.0or0.0(a = 10above); - a string is parsed with XPath's grammar. Surrounding whitespace is allowed, as are an optional leading
-
and digits with an optional.. There is no exponent and no leading+. Anything else isNaN, for
example'1e3','+1','1,000','Infinity'and'0x10'.
- a node-set uses the string value of its first node in document order (
- Empty node-set. The usage string says "zero if no match is found", but XPath 1.0 converts an empty node-set
throughnumber(''), which isNaN. Verifyxpath_double('<a/>', 'a/b')against Spark before asserting
either value (the integer variants mapNaNto 0 anyway). NaN,Infinityand-Infinitycan be produced by arithmetic (0 div 0,1 div 0,-1 div 0) and must
come back as the IEEE values.-0(-0 * 1) should keep its sign bit.- Large and imprecise values:
8.0E19above, andsum()over many decimal strings, which uses double
arithmetic (1.0 + 2.1gives3.1in the suite). NULLor''for either argument gives NULL. A non-literalpathgivesDATATYPE_MISMATCH.NON_FOLDABLE_INPUT.
Malformed XML and an invalid path raise runtime errors (see thexpathissue). ANSI mode has no effect.xpath_numbermust return the same values and showxpath_numberas its display name.
Differences across Spark versions
None found beyond the shared ones in the xpath issue.
Implementation notes
- Spark:
XPathDoubleinsql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/xml/xpath.scala.
It callsXPathDoubleEvaluator(.../xml/XmlExpressionEvalUtils.scala), which calls
UDFXPathUtil.evalNumber. Thexpath_numberalias is inFunctionRegistry.scala. - DataFusion core has no equivalent.
- Build it on the shared evaluator from the
xpathissue incrates/spark/src/function/xml/. A single
evaluate_number(xml, path) -> Option<f64>helper can servexpath_double,xpath_float,xpath_int,
xpath_longandxpath_short. Registerxpath_numberas an alias. - Tests:
crates/sqllogictest/test_files/xml/xpath_double.slt, which also coversxpath_number. Document
the function with#[user_doc].
This issue was generated by an LLM (Claude) from the Apache Spark source code and tests. Examples come from Spark's ExpressionDescription examples, test suites and .sql.out golden files, but please verify them against Spark before relying on them.
- 主要语言
- Rust
- 星标
- 7
- 派生
- 15
- 平均合并
- 16 小时 43 分钟
- 30 天内合并 PR
- 26
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
apache/datafusion-spark 的其他 Issue
-
enhancement
难度 2/5 1-3 小时 新手友好度 70/100
apache/datafusion-spark#287 ·
维护者通常 1 天内回复
-
enhancement good first issue
难度 2/5 1-3 小时 新手友好度 80/100
apache/datafusion-spark#266 ·
维护者通常 1 天内回复
-
[Bug] make_dt_interval returns NULL for more than about 1.49 million days, Spark returns the interval可能已有人在做 @Subodh-17 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
apache/datafusion-spark#109 ·
维护者通常 1 天内回复
-
enhancement
难度 5/5 一周以上 新手友好度 18/100
apache/datafusion-spark#299 ·
维护者通常 1 天内回复
-
enhancement
难度 4/5 3-5 天 新手友好度 35/100
apache/datafusion-spark#298 ·
维护者通常 1 天内回复
查看 apache/datafusion-spark 的全部 Issue
相似的 Issue
-
comp-rbac
难度 2/5 1-3 小时 新手友好度 68/100
ClickHouse/ClickHouse#131875 ·
维护者通常 1 天内回复
-
bug(python): read_transaction raises TypeError on a Rewrite with rewritten indices可能已有人在做 @Borg93 今天认领。 未关闭bug
难度 2/5 1-3 小时 新手友好度 75/100
lance-format/lance#11117 ·
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
storytold/photocraft#15232 · 1 条评论 ·
维护者通常 1 天内回复
-
forge: fork preflight reads still send `requireCanonical: false`, which Rootstock rejects (-32603)可能已有人在做 @Ynyesto 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 72/100
foundry-rs/foundry#18485 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
bondybondbond/rushcut#238 · 1 条评论 ·