From daf5a60fd4695e85fb152c589c83cd4c5a328f40 Mon Sep 17 00:00:00 2001 From: Grieve Date: Thu, 18 Jul 2024 14:47:07 +0800 Subject: [PATCH] Show original characters for string literals instead of escaping (#675) * Show original characters for string literals instead of escaping * Make TestWrenWithDuckDBTableFunction be single threaded to avoid concurrent issue --- .../io/trino/sql/ExpressionFormatter.java | 64 ++----------------- .../main/java/io/trino/sql/SqlFormatter.java | 36 +++++------ .../sql/parser/TestStatementBuilder.java | 11 ++-- .../TestWrenWithDuckDBTableFunction.java | 1 + 4 files changed, 31 insertions(+), 81 deletions(-) diff --git a/trino-parser/src/main/java/io/trino/sql/ExpressionFormatter.java b/trino-parser/src/main/java/io/trino/sql/ExpressionFormatter.java index 11bd68fc1..d9fb1ddc1 100644 --- a/trino-parser/src/main/java/io/trino/sql/ExpressionFormatter.java +++ b/trino-parser/src/main/java/io/trino/sql/ExpressionFormatter.java @@ -1,6 +1,5 @@ package io.trino.sql; -import com.google.common.base.CharMatcher; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import io.trino.sql.SqlFormatter.Dialect; @@ -92,7 +91,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import java.util.PrimitiveIterator; import java.util.function.Function; import java.util.stream.Collectors; @@ -237,13 +235,13 @@ protected String visitBooleanLiteral(BooleanLiteral node, Void context) @Override protected String visitStringLiteral(StringLiteral node, Void context) { - return formatStringLiteral(node.getValue(), dialect); + return formatStringLiteral(node.getValue()); } @Override protected String visitCharLiteral(CharLiteral node, Void context) { - return "CHAR " + formatStringLiteral(node.getValue(), dialect); + return "CHAR " + formatStringLiteral(node.getValue()); } @Override @@ -327,7 +325,7 @@ protected String visitDecimalLiteral(DecimalLiteral node, Void context) @Override protected String visitGenericLiteral(GenericLiteral node, Void context) { - return node.getType() + " " + formatStringLiteral(node.getValue(), dialect); + return node.getType() + " " + formatStringLiteral(node.getValue()); } @Override @@ -998,61 +996,9 @@ private String processDateDiffInBigQuery(FunctionCall node, Void context) } } - static String formatStringLiteral(String s, Dialect dialect) + static String formatStringLiteral(String s) { - if (dialect == BIGQUERY) { - s = s.replace("'", "\\'"); - } - else { - s = s.replace("'", "''"); - } - if (CharMatcher.inRange((char) 0x20, (char) 0x7E).matchesAllOf(s)) { - return "'" + s + "'"; - } - - StringBuilder builder = new StringBuilder(); - if (dialect == DEFAULT || dialect == DUCKDB || dialect == POSTGRES) { - builder.append("U&"); - } - builder.append("'"); - PrimitiveIterator.OfInt iterator = s.codePoints().iterator(); - while (iterator.hasNext()) { - int codePoint = iterator.nextInt(); - checkArgument(codePoint >= 0, "Invalid UTF-8 encoding in characters: %s", s); - if (isAsciiPrintable(codePoint)) { - char ch = (char) codePoint; - if (ch == '\\') { - builder.append(ch); - } - builder.append(ch); - } - else { - if (dialect == DEFAULT || dialect == DUCKDB || dialect == POSTGRES) { - if (codePoint <= 0xFFFF) { - builder.append('\\'); - builder.append(format("%04X", codePoint)); - } - else { - builder.append("\\+"); - builder.append(format("%06X", codePoint)); - } - } - else if (dialect == BIGQUERY) { - if (codePoint <= 0xFFFF) { - builder.append('\\'); - builder.append('u'); - builder.append(format("%04X", codePoint)); - } - else { - builder.append("\\"); - builder.append('U'); - builder.append(format("%08X", codePoint)); - } - } - } - } - builder.append("'"); - return builder.toString(); + return "'" + s.replace("'", "''") + "'"; } public static String formatOrderBy(OrderBy orderBy, Dialect dialect) diff --git a/trino-parser/src/main/java/io/trino/sql/SqlFormatter.java b/trino-parser/src/main/java/io/trino/sql/SqlFormatter.java index b9769d646..eb0845113 100644 --- a/trino-parser/src/main/java/io/trino/sql/SqlFormatter.java +++ b/trino-parser/src/main/java/io/trino/sql/SqlFormatter.java @@ -892,7 +892,7 @@ protected Void visitCreateView(CreateView node, Integer indent) node.getComment().ifPresent(comment -> builder .append(" COMMENT ") - .append(formatStringLiteral(comment, dialect))); + .append(formatStringLiteral(comment))); node.getSecurity().ifPresent(security -> builder .append(" SECURITY ") @@ -957,7 +957,7 @@ protected Void visitCreateMaterializedView(CreateMaterializedView node, Integer builder.append(formatName(node.getName(), dialect)); node.getComment().ifPresent(comment -> builder .append("\nCOMMENT ") - .append(formatStringLiteral(comment, dialect))); + .append(formatStringLiteral(comment))); builder.append(formatPropertiesMultiLine(node.getProperties())); builder.append(" AS\n"); @@ -1051,11 +1051,11 @@ protected Void visitShowCatalogs(ShowCatalogs node, Integer indent) node.getLikePattern().ifPresent(value -> builder .append(" LIKE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); node.getEscape().ifPresent(value -> builder .append(" ESCAPE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); return null; } @@ -1071,11 +1071,11 @@ protected Void visitShowSchemas(ShowSchemas node, Integer indent) node.getLikePattern().ifPresent(value -> builder .append(" LIKE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); node.getEscape().ifPresent(value -> builder .append(" ESCAPE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); return null; } @@ -1091,11 +1091,11 @@ protected Void visitShowTables(ShowTables node, Integer indent) node.getLikePattern().ifPresent(value -> builder .append(" LIKE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); node.getEscape().ifPresent(value -> builder .append(" ESCAPE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); return null; } @@ -1126,11 +1126,11 @@ protected Void visitShowColumns(ShowColumns node, Integer indent) node.getLikePattern().ifPresent(value -> builder .append(" LIKE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); node.getEscape().ifPresent(value -> builder .append(" ESCAPE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); return null; } @@ -1151,11 +1151,11 @@ protected Void visitShowFunctions(ShowFunctions node, Integer indent) node.getLikePattern().ifPresent(value -> builder .append(" LIKE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); node.getEscape().ifPresent(value -> builder .append(" ESCAPE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); return null; } @@ -1167,11 +1167,11 @@ protected Void visitShowSession(ShowSession node, Integer indent) node.getLikePattern().ifPresent(value -> builder .append(" LIKE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); node.getEscape().ifPresent(value -> builder .append(" ESCAPE ") - .append(formatStringLiteral(value, dialect))); + .append(formatStringLiteral(value))); return null; } @@ -1259,7 +1259,7 @@ protected Void visitCreateTableAsSelect(CreateTableAsSelect node, Integer indent node.getComment().ifPresent(comment -> builder .append("\nCOMMENT ") - .append(formatStringLiteral(comment, dialect))); + .append(formatStringLiteral(comment))); builder.append(formatPropertiesMultiLine(node.getProperties())); builder.append(" AS "); @@ -1310,7 +1310,7 @@ protected Void visitCreateTable(CreateTable node, Integer indent) node.getComment().ifPresent(comment -> builder .append("\nCOMMENT ") - .append(formatStringLiteral(comment, dialect))); + .append(formatStringLiteral(comment))); builder.append(formatPropertiesMultiLine(node.getProperties())); @@ -1351,7 +1351,7 @@ private String formatColumnDefinition(ColumnDefinition column) } column.getComment().ifPresent(comment -> builder .append(" COMMENT ") - .append(formatStringLiteral(comment, dialect))); + .append(formatStringLiteral(comment))); builder.append(formatPropertiesSingleLine(column.getProperties())); return builder.toString(); } @@ -1442,7 +1442,7 @@ private String joinProperties(List properties) protected Void visitComment(Comment node, Integer context) { String comment = node.getComment() - .map(str -> formatStringLiteral(str, dialect)) + .map(ExpressionFormatter::formatStringLiteral) .orElse("NULL"); switch (node.getType()) { diff --git a/trino-parser/src/test/java/io/trino/sql/parser/TestStatementBuilder.java b/trino-parser/src/test/java/io/trino/sql/parser/TestStatementBuilder.java index f7c8558ba..fec0906f6 100644 --- a/trino-parser/src/test/java/io/trino/sql/parser/TestStatementBuilder.java +++ b/trino-parser/src/test/java/io/trino/sql/parser/TestStatementBuilder.java @@ -331,11 +331,14 @@ public void testStatementBuilder() public void testStringFormatter() { assertSqlFormatter("U&'hello\\6d4B\\8Bd5\\+10FFFFworld\\7F16\\7801'", - "U&'hello\\6D4B\\8BD5\\+10FFFFworld\\7F16\\7801'"); + "'hello测试\uDBFF\uDFFFworld编码'"); assertSqlFormatter("'hello world'", "'hello world'"); - assertSqlFormatter("U&'!+10FFFF!6d4B!8Bd5ABC!6d4B!8Bd5' UESCAPE '!'", "U&'\\+10FFFF\\6D4B\\8BD5ABC\\6D4B\\8BD5'"); - assertSqlFormatter("U&'\\+10FFFF\\6D4B\\8BD5\\0041\\0042\\0043\\6D4B\\8BD5'", "U&'\\+10FFFF\\6D4B\\8BD5ABC\\6D4B\\8BD5'"); - assertSqlFormatter("U&'\\\\abc\\6D4B'''", "U&'\\\\abc\\6D4B'''"); + assertSqlFormatter("U&'!+10FFFF!6d4B!8Bd5ABC!6d4B!8Bd5' UESCAPE '!'", "'\uDBFF\uDFFF测试ABC测试'"); + assertSqlFormatter("U&'\\+10FFFF\\6D4B\\8BD5\\0041\\0042\\0043\\6D4B\\8BD5'", "'\uDBFF\uDFFF测试ABC测试'"); + assertSqlFormatter("U&'\\\\abc\\6D4B'''", "'\\abc测'''"); + assertSqlFormatter("'攻殻機動隊'", "'攻殻機動隊'"); + assertSqlFormatter("'😂'", "'😂'"); + assertSqlFormatter("'시험'", "'시험'"); } @Test diff --git a/wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDBTableFunction.java b/wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDBTableFunction.java index e8277f67b..4e42ce148 100644 --- a/wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDBTableFunction.java +++ b/wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDBTableFunction.java @@ -33,6 +33,7 @@ import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; +@Test(singleThreaded = true) public class TestWrenWithDuckDBTableFunction extends RequireWrenServer {