Skip to content

Commit 73c55fd

Browse files
feat: Quoted Identifiers can contain double-quotes (PostgreSQL)
- `SELECT "test""column""name"` - fixes #1335
1 parent 5263b91 commit 73c55fd

File tree

5 files changed

+42
-6
lines changed

5 files changed

+42
-6
lines changed

src/main/java/net/sf/jsqlparser/statement/Statements.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public void accept(StatementVisitor statementVisitor) {
3030
statementVisitor.visit(this);
3131
}
3232

33+
public <E extends Statement> E get(Class<E> type, int index) {
34+
return type.cast(get(index));
35+
}
36+
3337
@Override
3438
public String toString() {
3539
StringBuilder b = new StringBuilder();

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ TOKEN:
554554
input_stream.backup(image.length() - matchedToken.image.length() );
555555
}
556556
}
557-
| < S_QUOTED_IDENTIFIER: "\"" (~["\n","\r","\""])* "\"" | "$$" (~["$"])* "$$" | ("`" (~["\n","\r","`"])+ "`") | ( "[" (~["\n","\r","]"])* "]" ) >
557+
| < S_QUOTED_IDENTIFIER: "\"" ( "\"\"" | ~["\n","\r","\""])* "\"" | "$$" (~["$"])* "$$" | ("`" (~["\n","\r","`"])+ "`") | ( "[" (~["\n","\r","]"])* "]" ) >
558558
{
559559
if ( !configuration.getAsBoolean(Feature.allowSquareBracketQuotation) && matchedToken.image.charAt(0) == '[' ) {
560560
matchedToken.image = "[";

src/test/java/net/sf/jsqlparser/expression/JsonExpressionTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
package net.sf.jsqlparser.expression;
1111

1212
import net.sf.jsqlparser.JSQLParserException;
13-
import net.sf.jsqlparser.test.TestUtils;
1413
import org.junit.jupiter.api.Test;
1514

1615
import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
@@ -21,19 +20,19 @@ class JsonExpressionTest {
2120
void testIssue1792() throws JSQLParserException, InterruptedException {
2221
String sqlStr =
2322
"SELECT ''::JSON -> 'obj'::TEXT";
24-
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
23+
assertSqlCanBeParsedAndDeparsed(sqlStr, true);
2524

2625
sqlStr =
2726
"SELECT ('{\"obj\":{\"field\": \"value\"}}'::JSON -> 'obj'::TEXT ->> 'field'::TEXT)";
28-
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
27+
assertSqlCanBeParsedAndDeparsed(sqlStr, true);
2928

3029
sqlStr =
3130
"SELECT\n"
3231
+ " CASE\n"
3332
+ " WHEN true\n"
3433
+ " THEN (SELECT ((('{\"obj\":{\"field\": \"value\"}}'::JSON -> 'obj'::TEXT ->> 'field'::TEXT))))\n"
3534
+ " END";
36-
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
35+
assertSqlCanBeParsedAndDeparsed(sqlStr, true);
3736
}
3837

3938
@Test

src/test/java/net/sf/jsqlparser/statement/UnsupportedStatementTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void testAlter() throws JSQLParserException {
8585
String sqlStr =
8686
"ALTER INDEX idx_t_fa RENAME TO idx_t_fb";
8787
Statement statement = TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
88-
Assertions.assertTrue(statement instanceof UnsupportedStatement);
88+
assertTrue(statement instanceof UnsupportedStatement);
8989
}
9090

9191
@Test

src/test/java/net/sf/jsqlparser/statement/select/PostgresTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,16 @@
1111

1212
import net.sf.jsqlparser.JSQLParserException;
1313
import net.sf.jsqlparser.expression.JsonExpression;
14+
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
15+
import net.sf.jsqlparser.schema.Column;
16+
import net.sf.jsqlparser.statement.Statements;
17+
import net.sf.jsqlparser.statement.insert.Insert;
1418
import net.sf.jsqlparser.test.TestUtils;
1519
import org.junit.jupiter.api.Assertions;
1620
import org.junit.jupiter.api.Test;
1721

22+
import java.util.List;
23+
1824
import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
1925

2026
public class PostgresTest {
@@ -62,4 +68,31 @@ public void testJSonOperatorIssue1571() throws JSQLParserException {
6268
"select visit_hour,json_array_elements(into_sex_json)->>'name',json_array_elements(into_sex_json)->>'value' from period_market";
6369
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
6470
}
71+
72+
@Test
73+
void testPostgresQuotingIssue1335() throws JSQLParserException {
74+
String sqlStr =
75+
"INSERT INTO \"table\"\"with\"\"quotes\" (\"column\"\"with\"\"quotes\")\n"
76+
+ "VALUES ('1'), ('2'), ('3');\n"
77+
+ "\n"
78+
+ "UPDATE \"table\"\"with\"\"quotes\" SET \"column\"\"with\"\"quotes\" = '1.0' \n"
79+
+ "WHERE \"column\"\"with\"\"quotes\" = '1';\n"
80+
+ "\n"
81+
+ "SELECT \"column\"\"with\"\"quotes\" FROM \"table\"\"with\"\"quotes\"\n"
82+
+ "WHERE \"column\"\"with\"\"quotes\" IS NOT NULL;";
83+
84+
Statements statements = CCJSqlParserUtil.parseStatements(sqlStr);
85+
Assertions.assertEquals(3, statements.size());
86+
87+
Insert insert = statements.get(Insert.class, 0);
88+
Assertions.assertEquals(
89+
"\"table\"\"with\"\"quotes\"", insert.getTable().getFullyQualifiedName());
90+
91+
PlainSelect select = statements.get(PlainSelect.class, 2);
92+
List<SelectItem<?>> selectItems = select.getSelectItems();
93+
94+
Assertions.assertEquals(
95+
"\"column\"\"with\"\"quotes\"",
96+
selectItems.get(0).getExpression(Column.class).getColumnName());
97+
}
6598
}

0 commit comments

Comments
 (0)