This is an automated email from the ASF dual-hosted git repository.
mihaibudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new a191d32005 [CALCITE-7599] Enhance parser to allow numeric literals as
values in k/v hints as suggested by documentation
a191d32005 is described below
commit a191d3200581f7ac9c19ca7c8810aea2327ebda6
Author: Chris Dennis <[email protected]>
AuthorDate: Wed Jun 10 15:00:41 2026 -0400
[CALCITE-7599] Enhance parser to allow numeric literals as values in k/v
hints as suggested by documentation
Signed-off-by: Chris Dennis <[email protected]>
---
core/src/main/codegen/templates/Parser.jj | 2 ++
core/src/main/java/org/apache/calcite/sql/SqlHint.java | 7 ++++---
.../java/org/apache/calcite/test/SqlHintsConverterTest.java | 8 +++++++-
.../org/apache/calcite/test/SqlHintsConverterTest.xml | 13 ++++++++++++-
site/_docs/reference.md | 4 +++-
.../java/org/apache/calcite/sql/parser/SqlParserTest.java | 7 ++++++-
6 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/core/src/main/codegen/templates/Parser.jj
b/core/src/main/codegen/templates/Parser.jj
index 5519dd566d..c5d392e2fb 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -1296,6 +1296,8 @@ void AddKeyValueOption(List<SqlNode> list) :
)
<EQ>
(
+ value = NumericLiteral()
+ |
value = StringLiteral()
|
value = SimpleIdentifier()
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlHint.java
b/core/src/main/java/org/apache/calcite/sql/SqlHint.java
index 38f54636eb..8c61828dae 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlHint.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlHint.java
@@ -197,18 +197,19 @@ public enum HintOptionFormat implements Symbolizable {
* The hint options are list of key-value pairs.
* For each pair,
* the key is a simple identifier or string literal,
- * the value is a string literal.
+ * the value is a string or numeric literal.
*/
KV_LIST
}
//~ Tools ------------------------------------------------------------------
- private static String getOptionAsString(SqlNode node) {
+ private String getOptionAsString(SqlNode node) {
assert node instanceof SqlIdentifier || SqlUtil.isLiteral(node);
if (node instanceof SqlIdentifier) {
return ((SqlIdentifier) node).getSimple();
}
- return ((SqlLiteral) node).getValueAs(String.class);
+ return requireNonNull(((SqlLiteral) node).toValue(),
+ () -> "null hint literal in " + options);
}
}
diff --git
a/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
b/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
index 9183134cd4..346e0c57e6 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlHintsConverterTest.java
@@ -172,7 +172,7 @@ public final Fixture sql(String sql) {
/** Test case for <a
href="https://issues.apache.org/jira/browse/CALCITE-7498">[CALCITE-7498]
* The parser rejects the example hints from the documentation</a>. */
@Test void testDocumentationExample() {
- final String sql = "SELECT /*+ hint1, hint2(a='1', b='2') */ *\n"
+ final String sql = "SELECT /*+ hint1, hint2(a=1, b=2) */ *\n"
+ "FROM emp /*+ hint3(5, 'x') */\n"
+ "JOIN dept /*+ hint4(c=id), hint5 */\n"
+ "ON emp.deptno = dept.deptno";
@@ -201,6 +201,12 @@ public final Fixture sql(String sql) {
sql(sql).ok();
}
+ @Test void testQueryHintWithKeyValueNumericLiteralOptions() {
+ final String sql = "select /*+ hint2(a=1, b=-1, c=1.1, d=-1.1, e=1e3,
f=-1e-4) */ *\n"
+ + "from emp";
+ sql(sql).ok();
+ }
+
@Test void testNestedQueryHint() {
final String sql = "select /*+ resource(parallelism='3'), repartition(10)
*/ empno\n"
+ "from (select /*+ resource(mem='20Mb')*/ empno, ename from emp)";
diff --git
a/core/src/test/resources/org/apache/calcite/test/SqlHintsConverterTest.xml
b/core/src/test/resources/org/apache/calcite/test/SqlHintsConverterTest.xml
index e2cd95622d..d06db165d0 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlHintsConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlHintsConverterTest.xml
@@ -60,7 +60,7 @@ Correlate:[[USE_HASH_JOIN inheritPath:[0] options:[ORDERS,
PRODUCTS_TEMPORAL]]]
</TestCase>
<TestCase name="testDocumentationExample">
<Resource name="sql">
- <![CDATA[SELECT /*+ hint1, hint2(a='1', b='2') */ *
+ <![CDATA[SELECT /*+ hint1, hint2(a=1, b=2) */ *
FROM emp /*+ hint3(5, 'x') */
JOIN dept /*+ hint4(c=id), hint5 */
ON emp.deptno = dept.deptno]]>
@@ -350,6 +350,17 @@ LogicalJoin:[[NO_HASH_JOIN inheritPath:[0, 0]]]
TableScan:[[PROPERTIES inheritPath:[0, 0, 0] options:{K1=v1, K2=v2}], [INDEX
inheritPath:[0, 0, 0] options:[ENAME]]]
TableScan:[[PROPERTIES inheritPath:[0, 0, 1] options:{K1=v1, K2=v2}], [INDEX
inheritPath:[0, 0, 1] options:[ENAME]]]
TableScan:[[PROPERTIES inheritPath:[0, 1, 0] options:{K1=v1, K2=v2}], [INDEX
inheritPath:[0, 1, 0] options:[ENAME]]]
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testQueryHintWithKeyValueNumericLiteralOptions">
+ <Resource name="sql">
+ <![CDATA[select /*+ hint2(a=1, b=-1, c=1.1, d=-1.1, e=1e3, f=-1e-4) */ *
+from emp]]>
+ </Resource>
+ <Resource name="hints">
+ <![CDATA[
+Project:[[HINT2 inheritPath:[] options:{A=1, B=-1, C=1.1, D=-1.1, E=1E3,
F=-1E-4}]]
]]>
</Resource>
</TestCase>
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 6250a6d639..064d6fb95e 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -3647,11 +3647,13 @@ #### Syntax
optionVal:
simpleIdentifier
+ | numericLiteral
| stringLiteral
hintOption:
simpleIdentifier
- | stringLiteral
+ | numericLiteral
+ | stringLiteral
{% endhighlight %}
It is experimental in Calcite, and yet not fully implemented, what we have
implemented are:
diff --git
a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
index 591278ebfa..bb7566c990 100644
--- a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -9845,7 +9845,12 @@ private static Consumer<List<? extends Throwable>>
checkWarnings(
final String sql1 = "select "
+ "/*+ properties(^k1^=123, k2='v2'), no_hash_join() */ "
+ "empno, ename, deptno from emps";
- sql(sql1).fails("(?s).*Encountered \"k1 = 123\" at .*");
+ // Allow numeric literal k/v values.
+ final String expected1 = "SELECT\n"
+ + "/*+ `PROPERTIES`(`K1` = 123, `K2` = 'v2'), `NO_HASH_JOIN` */\n"
+ + "`EMPNO`, `ENAME`, `DEPTNO`\n"
+ + "FROM `EMPS`";
+ sql(sql1).ok(expected1);
final String sql2 = "select "
+ "/*+ properties(k1, k2^=^'v2'), no_hash_join */ "
+ "empno, ename, deptno from emps";