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 eef1c386d59..48a566a84a5 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 9a1d165a1f8..65f089a5d48 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 964fa03f8f9..184ea90d161 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 b09f299f849..9af0ce098e9 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'";