Skip to content

Commit daf5a60

Browse files
authored
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
1 parent d320c22 commit daf5a60

File tree

4 files changed

+31
-81
lines changed

4 files changed

+31
-81
lines changed

trino-parser/src/main/java/io/trino/sql/ExpressionFormatter.java

+5-59
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.trino.sql;
22

3-
import com.google.common.base.CharMatcher;
43
import com.google.common.base.Joiner;
54
import com.google.common.collect.ImmutableList;
65
import io.trino.sql.SqlFormatter.Dialect;
@@ -92,7 +91,6 @@
9291
import java.util.ArrayList;
9392
import java.util.List;
9493
import java.util.Locale;
95-
import java.util.PrimitiveIterator;
9694
import java.util.function.Function;
9795
import java.util.stream.Collectors;
9896

@@ -237,13 +235,13 @@ protected String visitBooleanLiteral(BooleanLiteral node, Void context)
237235
@Override
238236
protected String visitStringLiteral(StringLiteral node, Void context)
239237
{
240-
return formatStringLiteral(node.getValue(), dialect);
238+
return formatStringLiteral(node.getValue());
241239
}
242240

243241
@Override
244242
protected String visitCharLiteral(CharLiteral node, Void context)
245243
{
246-
return "CHAR " + formatStringLiteral(node.getValue(), dialect);
244+
return "CHAR " + formatStringLiteral(node.getValue());
247245
}
248246

249247
@Override
@@ -327,7 +325,7 @@ protected String visitDecimalLiteral(DecimalLiteral node, Void context)
327325
@Override
328326
protected String visitGenericLiteral(GenericLiteral node, Void context)
329327
{
330-
return node.getType() + " " + formatStringLiteral(node.getValue(), dialect);
328+
return node.getType() + " " + formatStringLiteral(node.getValue());
331329
}
332330

333331
@Override
@@ -998,61 +996,9 @@ private String processDateDiffInBigQuery(FunctionCall node, Void context)
998996
}
999997
}
1000998

1001-
static String formatStringLiteral(String s, Dialect dialect)
999+
static String formatStringLiteral(String s)
10021000
{
1003-
if (dialect == BIGQUERY) {
1004-
s = s.replace("'", "\\'");
1005-
}
1006-
else {
1007-
s = s.replace("'", "''");
1008-
}
1009-
if (CharMatcher.inRange((char) 0x20, (char) 0x7E).matchesAllOf(s)) {
1010-
return "'" + s + "'";
1011-
}
1012-
1013-
StringBuilder builder = new StringBuilder();
1014-
if (dialect == DEFAULT || dialect == DUCKDB || dialect == POSTGRES) {
1015-
builder.append("U&");
1016-
}
1017-
builder.append("'");
1018-
PrimitiveIterator.OfInt iterator = s.codePoints().iterator();
1019-
while (iterator.hasNext()) {
1020-
int codePoint = iterator.nextInt();
1021-
checkArgument(codePoint >= 0, "Invalid UTF-8 encoding in characters: %s", s);
1022-
if (isAsciiPrintable(codePoint)) {
1023-
char ch = (char) codePoint;
1024-
if (ch == '\\') {
1025-
builder.append(ch);
1026-
}
1027-
builder.append(ch);
1028-
}
1029-
else {
1030-
if (dialect == DEFAULT || dialect == DUCKDB || dialect == POSTGRES) {
1031-
if (codePoint <= 0xFFFF) {
1032-
builder.append('\\');
1033-
builder.append(format("%04X", codePoint));
1034-
}
1035-
else {
1036-
builder.append("\\+");
1037-
builder.append(format("%06X", codePoint));
1038-
}
1039-
}
1040-
else if (dialect == BIGQUERY) {
1041-
if (codePoint <= 0xFFFF) {
1042-
builder.append('\\');
1043-
builder.append('u');
1044-
builder.append(format("%04X", codePoint));
1045-
}
1046-
else {
1047-
builder.append("\\");
1048-
builder.append('U');
1049-
builder.append(format("%08X", codePoint));
1050-
}
1051-
}
1052-
}
1053-
}
1054-
builder.append("'");
1055-
return builder.toString();
1001+
return "'" + s.replace("'", "''") + "'";
10561002
}
10571003

10581004
public static String formatOrderBy(OrderBy orderBy, Dialect dialect)

trino-parser/src/main/java/io/trino/sql/SqlFormatter.java

+18-18
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,7 @@ protected Void visitCreateView(CreateView node, Integer indent)
892892

893893
node.getComment().ifPresent(comment -> builder
894894
.append(" COMMENT ")
895-
.append(formatStringLiteral(comment, dialect)));
895+
.append(formatStringLiteral(comment)));
896896

897897
node.getSecurity().ifPresent(security -> builder
898898
.append(" SECURITY ")
@@ -957,7 +957,7 @@ protected Void visitCreateMaterializedView(CreateMaterializedView node, Integer
957957
builder.append(formatName(node.getName(), dialect));
958958
node.getComment().ifPresent(comment -> builder
959959
.append("\nCOMMENT ")
960-
.append(formatStringLiteral(comment, dialect)));
960+
.append(formatStringLiteral(comment)));
961961
builder.append(formatPropertiesMultiLine(node.getProperties()));
962962
builder.append(" AS\n");
963963

@@ -1051,11 +1051,11 @@ protected Void visitShowCatalogs(ShowCatalogs node, Integer indent)
10511051

10521052
node.getLikePattern().ifPresent(value -> builder
10531053
.append(" LIKE ")
1054-
.append(formatStringLiteral(value, dialect)));
1054+
.append(formatStringLiteral(value)));
10551055

10561056
node.getEscape().ifPresent(value -> builder
10571057
.append(" ESCAPE ")
1058-
.append(formatStringLiteral(value, dialect)));
1058+
.append(formatStringLiteral(value)));
10591059

10601060
return null;
10611061
}
@@ -1071,11 +1071,11 @@ protected Void visitShowSchemas(ShowSchemas node, Integer indent)
10711071

10721072
node.getLikePattern().ifPresent(value -> builder
10731073
.append(" LIKE ")
1074-
.append(formatStringLiteral(value, dialect)));
1074+
.append(formatStringLiteral(value)));
10751075

10761076
node.getEscape().ifPresent(value -> builder
10771077
.append(" ESCAPE ")
1078-
.append(formatStringLiteral(value, dialect)));
1078+
.append(formatStringLiteral(value)));
10791079

10801080
return null;
10811081
}
@@ -1091,11 +1091,11 @@ protected Void visitShowTables(ShowTables node, Integer indent)
10911091

10921092
node.getLikePattern().ifPresent(value -> builder
10931093
.append(" LIKE ")
1094-
.append(formatStringLiteral(value, dialect)));
1094+
.append(formatStringLiteral(value)));
10951095

10961096
node.getEscape().ifPresent(value -> builder
10971097
.append(" ESCAPE ")
1098-
.append(formatStringLiteral(value, dialect)));
1098+
.append(formatStringLiteral(value)));
10991099

11001100
return null;
11011101
}
@@ -1126,11 +1126,11 @@ protected Void visitShowColumns(ShowColumns node, Integer indent)
11261126

11271127
node.getLikePattern().ifPresent(value -> builder
11281128
.append(" LIKE ")
1129-
.append(formatStringLiteral(value, dialect)));
1129+
.append(formatStringLiteral(value)));
11301130

11311131
node.getEscape().ifPresent(value -> builder
11321132
.append(" ESCAPE ")
1133-
.append(formatStringLiteral(value, dialect)));
1133+
.append(formatStringLiteral(value)));
11341134

11351135
return null;
11361136
}
@@ -1151,11 +1151,11 @@ protected Void visitShowFunctions(ShowFunctions node, Integer indent)
11511151

11521152
node.getLikePattern().ifPresent(value -> builder
11531153
.append(" LIKE ")
1154-
.append(formatStringLiteral(value, dialect)));
1154+
.append(formatStringLiteral(value)));
11551155

11561156
node.getEscape().ifPresent(value -> builder
11571157
.append(" ESCAPE ")
1158-
.append(formatStringLiteral(value, dialect)));
1158+
.append(formatStringLiteral(value)));
11591159

11601160
return null;
11611161
}
@@ -1167,11 +1167,11 @@ protected Void visitShowSession(ShowSession node, Integer indent)
11671167

11681168
node.getLikePattern().ifPresent(value -> builder
11691169
.append(" LIKE ")
1170-
.append(formatStringLiteral(value, dialect)));
1170+
.append(formatStringLiteral(value)));
11711171

11721172
node.getEscape().ifPresent(value -> builder
11731173
.append(" ESCAPE ")
1174-
.append(formatStringLiteral(value, dialect)));
1174+
.append(formatStringLiteral(value)));
11751175

11761176
return null;
11771177
}
@@ -1259,7 +1259,7 @@ protected Void visitCreateTableAsSelect(CreateTableAsSelect node, Integer indent
12591259

12601260
node.getComment().ifPresent(comment -> builder
12611261
.append("\nCOMMENT ")
1262-
.append(formatStringLiteral(comment, dialect)));
1262+
.append(formatStringLiteral(comment)));
12631263
builder.append(formatPropertiesMultiLine(node.getProperties()));
12641264

12651265
builder.append(" AS ");
@@ -1310,7 +1310,7 @@ protected Void visitCreateTable(CreateTable node, Integer indent)
13101310

13111311
node.getComment().ifPresent(comment -> builder
13121312
.append("\nCOMMENT ")
1313-
.append(formatStringLiteral(comment, dialect)));
1313+
.append(formatStringLiteral(comment)));
13141314

13151315
builder.append(formatPropertiesMultiLine(node.getProperties()));
13161316

@@ -1351,7 +1351,7 @@ private String formatColumnDefinition(ColumnDefinition column)
13511351
}
13521352
column.getComment().ifPresent(comment -> builder
13531353
.append(" COMMENT ")
1354-
.append(formatStringLiteral(comment, dialect)));
1354+
.append(formatStringLiteral(comment)));
13551355
builder.append(formatPropertiesSingleLine(column.getProperties()));
13561356
return builder.toString();
13571357
}
@@ -1442,7 +1442,7 @@ private String joinProperties(List<Property> properties)
14421442
protected Void visitComment(Comment node, Integer context)
14431443
{
14441444
String comment = node.getComment()
1445-
.map(str -> formatStringLiteral(str, dialect))
1445+
.map(ExpressionFormatter::formatStringLiteral)
14461446
.orElse("NULL");
14471447

14481448
switch (node.getType()) {

trino-parser/src/test/java/io/trino/sql/parser/TestStatementBuilder.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,14 @@ public void testStatementBuilder()
331331
public void testStringFormatter()
332332
{
333333
assertSqlFormatter("U&'hello\\6d4B\\8Bd5\\+10FFFFworld\\7F16\\7801'",
334-
"U&'hello\\6D4B\\8BD5\\+10FFFFworld\\7F16\\7801'");
334+
"'hello测试\uDBFF\uDFFFworld编码'");
335335
assertSqlFormatter("'hello world'", "'hello world'");
336-
assertSqlFormatter("U&'!+10FFFF!6d4B!8Bd5ABC!6d4B!8Bd5' UESCAPE '!'", "U&'\\+10FFFF\\6D4B\\8BD5ABC\\6D4B\\8BD5'");
337-
assertSqlFormatter("U&'\\+10FFFF\\6D4B\\8BD5\\0041\\0042\\0043\\6D4B\\8BD5'", "U&'\\+10FFFF\\6D4B\\8BD5ABC\\6D4B\\8BD5'");
338-
assertSqlFormatter("U&'\\\\abc\\6D4B'''", "U&'\\\\abc\\6D4B'''");
336+
assertSqlFormatter("U&'!+10FFFF!6d4B!8Bd5ABC!6d4B!8Bd5' UESCAPE '!'", "'\uDBFF\uDFFF测试ABC测试'");
337+
assertSqlFormatter("U&'\\+10FFFF\\6D4B\\8BD5\\0041\\0042\\0043\\6D4B\\8BD5'", "'\uDBFF\uDFFF测试ABC测试'");
338+
assertSqlFormatter("U&'\\\\abc\\6D4B'''", "'\\abc测'''");
339+
assertSqlFormatter("'攻殻機動隊'", "'攻殻機動隊'");
340+
assertSqlFormatter("'😂'", "'😂'");
341+
assertSqlFormatter("'시험'", "'시험'");
339342
}
340343

341344
@Test

wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDBTableFunction.java

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import static java.util.Objects.requireNonNull;
3434
import static org.assertj.core.api.Assertions.assertThat;
3535

36+
@Test(singleThreaded = true)
3637
public class TestWrenWithDuckDBTableFunction
3738
extends RequireWrenServer
3839
{

0 commit comments

Comments
 (0)