From 67ded76153d41619ba09523697020d12a5b25a64 Mon Sep 17 00:00:00 2001 From: Jerome Haltom Date: Mon, 7 Sep 2026 19:26:51 -0500 Subject: [PATCH] [CALCITE-7768] SqlDialect has no way to unparse a UUID literal --- .../src/main/java/org/apache/calcite/sql/SqlDialect.java | 9 +++++++++ .../main/java/org/apache/calcite/sql/SqlUuidLiteral.java | 2 +- .../org/apache/calcite/sql/dialect/MssqlSqlDialect.java | 6 ++++++ .../calcite/rel/rel2sql/RelToSqlConverterTest.java | 9 +++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/apache/calcite/sql/SqlDialect.java b/core/src/main/java/org/apache/calcite/sql/SqlDialect.java index eef1c386d594..48a566a84a5b 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlDialect.java @@ -579,6 +579,15 @@ public void unparseTableScanHints(SqlWriter writer, SqlNodeList hints, int leftPrec, int rightPrec) { } + /** Converts a UUID literal to a SQL string. The default implementation + * returns strings such as + * UUID '123e4567-e89b-12d3-a456-426655440000'. A dialect whose + * product spells it differently should override this method. */ + public void unparseUuidLiteral(SqlWriter writer, + SqlUuidLiteral literal, int leftPrec, int rightPrec) { + writer.literal(literal.toString()); + } + /** * Returns whether the string contains any characters outside the * comfortable 7-bit ASCII range (32 through 127, plus linefeed (10) and diff --git a/core/src/main/java/org/apache/calcite/sql/SqlUuidLiteral.java b/core/src/main/java/org/apache/calcite/sql/SqlUuidLiteral.java index 9a1d165a1f8a..65f089a5d486 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlUuidLiteral.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlUuidLiteral.java @@ -58,6 +58,6 @@ public String toFormattedString() { SqlWriter writer, int leftPrec, int rightPrec) { - writer.literal(this.toString()); + writer.getDialect().unparseUuidLiteral(writer, this, leftPrec, rightPrec); } } diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java index 964fa03f8f91..184ea90d1615 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java @@ -38,6 +38,7 @@ import org.apache.calcite.sql.SqlOperator; import org.apache.calcite.sql.SqlSyntax; import org.apache.calcite.sql.SqlUtil; +import org.apache.calcite.sql.SqlUuidLiteral; import org.apache.calcite.sql.SqlWriter; import org.apache.calcite.sql.fun.SqlLibraryOperators; import org.apache.calcite.sql.fun.SqlStdOperatorTable; @@ -200,6 +201,11 @@ private static SqlNode createDatetimeCastSpec(String typeAlias, RelDataType type writer.literal("'" + literal.toFormattedString() + "'"); } + @Override public void unparseUuidLiteral(SqlWriter writer, + SqlUuidLiteral literal, int leftPrec, int rightPrec) { + writer.literal("'" + literal.toFormattedString() + "'"); + } + @Override public void unparseCall(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) { if (call.getOperator() == SqlStdOperatorTable.SUBSTRING) { diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java index b09f299f8493..9af0ce098e9b 100644 --- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java +++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java @@ -10988,6 +10988,15 @@ private void checkLiteral2(String expression, String expected) { sql(sql).ok(expected); } + /** Test case for [CALCITE-7768] + * SqlDialect has no way to unparse a UUID literal. */ + @Test void testUuidMssql() { + final String sql = "SELECT UUID '123e4567-e89b-12d3-a456-426655440000' AS x"; + final String expected = "SELECT *\n" + + "FROM (VALUES ('123e4567-e89b-12d3-a456-426655440000')) AS [t] ([X])"; + sql(sql).withMssql().ok(expected); + } + @Test void testUpdate() { final String sql0 = "update \"foodmart\".\"product\"\n" + "set \"product_name\" = 'calcite'";