diff --git a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java index 4c535c14e3a2..16455ff2f622 100644 --- a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java +++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java @@ -1437,6 +1437,8 @@ public static SqlNode toSql(RexLiteral literal) { return SqlLiteral.createTimestamp(typeName, castNonNull(literal.getValueAs(TimestampString.class)), literal.getType().getPrecision(), POS); + case BINARY: + return SqlLiteral.createBinaryString(castNonNull(literal.getValueAs(byte[].class)), POS); case ANY: case NULL: switch (typeName) { 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 f78751841ed8..212336abf6f7 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 @@ -220,6 +220,20 @@ private static String toSql(RelNode root, SqlDialect dialect, .getSql(); } + /** + * Test for [CALCITE-5988] + * SqlImplementor.toSql cannot emit VARBINARY literals. + */ + @Test void testBinaryLiteral() { + String query = "SELECT x'ABCD'"; + String expected = "SELECT X'ABCD'"; + // We use Mysql here because using the default Calcite dialect + // the expected string is a bit too verbose: + // "SELECT *\nFROM (VALUES (X'ABCD')) AS \"t\" (\"EXPR$0\")" + sql(query).withMysql().ok(expected); + sql("SELECT cast(null as binary)").withMysql().ok("SELECT NULL"); + } + @Test void testGroupByBooleanLiteral() { String query = "select avg(\"salary\") from \"employee\" group by true"; String expectedRedshift = "SELECT AVG(\"employee\".\"salary\")\n"