Skip to content

Commit b77199c

Browse files
committed
Issue #118 Fix identifier quoting
1 parent d944e58 commit b77199c

2 files changed

Lines changed: 34 additions & 18 deletions

File tree

PgBulkInsert/src/main/java/de/bytefish/pgbulkinsert/util/PostgreSqlUtils.java

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import de.bytefish.pgbulkinsert.exceptions.PgConnectionException;
66
import org.checkerframework.checker.nullness.qual.Nullable;
77
import org.postgresql.PGConnection;
8+
import org.postgresql.core.Utils;
89

910
import java.sql.Connection;
11+
import java.sql.SQLException;
1012
import java.util.Optional;
1113

1214
public final class PostgreSqlUtils {
@@ -44,10 +46,12 @@ private static Optional<PGConnection> tryUnwrapConnection(final Connection conne
4446
return Optional.empty();
4547
}
4648

47-
public static final char QuoteChar = '"';
48-
4949
public static String quoteIdentifier(String identifier) {
50-
return requiresQuoting(identifier) ? (QuoteChar + identifier + QuoteChar) : identifier;
50+
try {
51+
return Utils.escapeIdentifier(null, identifier).toString();
52+
} catch (SQLException e) {
53+
throw new IllegalArgumentException("Invalid identifier", e);
54+
}
5155
}
5256

5357
@SuppressWarnings("NullAway")
@@ -63,16 +67,4 @@ public static String getFullyQualifiedTableName(@Nullable String schemaName, Str
6367

6468
return String.format("%1$s.%2$s", schemaName, tableName);
6569
}
66-
67-
private static boolean requiresQuoting(String identifier) {
68-
69-
char first = identifier.charAt(0);
70-
char last = identifier.charAt(identifier.length() - 1);
71-
72-
if (first == QuoteChar && last == QuoteChar) {
73-
return false;
74-
}
75-
76-
return true;
77-
}
7870
}

PgBulkInsert/src/test/java/de/bytefish/pgbulkinsert/test/util/PostgresUtilsTest.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,34 @@ public void testUnquotedIdentifiers() {
1515
}
1616

1717
@Test
18-
public void testAlreadyQuotedIdentifier() {
19-
final String identifier = "\"binary\"";
18+
public void testOneDoubleQuote() {
19+
final String identifier = "\"";
2020
final String result = PostgreSqlUtils.quoteIdentifier(identifier);
2121

22-
Assert.assertEquals("\"binary\"", result);
22+
Assert.assertEquals("\"\"\"\"", result);
23+
}
24+
25+
@Test
26+
public void testTwoDoubleQuotes() {
27+
final String identifier = "\"\"";
28+
final String result = PostgreSqlUtils.quoteIdentifier(identifier);
29+
30+
Assert.assertEquals("\"\"\"\"\"\"", result);
31+
}
32+
33+
@Test
34+
public void testIdentifierWithQuotes() {
35+
final String identifier = "\"x\"";
36+
final String result = PostgreSqlUtils.quoteIdentifier(identifier);
37+
38+
Assert.assertEquals("\"\"\"x\"\"\"", result);
39+
}
40+
41+
@Test
42+
public void testIdentifierWithQuoteInTheMiddle() {
43+
final String identifier = "x\"y";
44+
final String result = PostgreSqlUtils.quoteIdentifier(identifier);
45+
46+
Assert.assertEquals("\"x\"\"y\"", result);
2347
}
2448
}

0 commit comments

Comments
 (0)