Skip to content

Commit

Permalink
feat: Quoted Identifiers can contain double-quotes (PostgreSQL)
Browse files Browse the repository at this point in the history
- `SELECT "test""column""name"`
- fixes #1335
  • Loading branch information
manticore-projects committed May 18, 2023
1 parent 5263b91 commit 73c55fd
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/Statements.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public void accept(StatementVisitor statementVisitor) {
statementVisitor.visit(this);
}

public <E extends Statement> E get(Class<E> type, int index) {
return type.cast(get(index));
}

@Override
public String toString() {
StringBuilder b = new StringBuilder();
Expand Down
2 changes: 1 addition & 1 deletion src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ TOKEN:
input_stream.backup(image.length() - matchedToken.image.length() );
}
}
| < S_QUOTED_IDENTIFIER: "\"" (~["\n","\r","\""])* "\"" | "$$" (~["$"])* "$$" | ("`" (~["\n","\r","`"])+ "`") | ( "[" (~["\n","\r","]"])* "]" ) >
| < S_QUOTED_IDENTIFIER: "\"" ( "\"\"" | ~["\n","\r","\""])* "\"" | "$$" (~["$"])* "$$" | ("`" (~["\n","\r","`"])+ "`") | ( "[" (~["\n","\r","]"])* "]" ) >
{
if ( !configuration.getAsBoolean(Feature.allowSquareBracketQuotation) && matchedToken.image.charAt(0) == '[' ) {
matchedToken.image = "[";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
package net.sf.jsqlparser.expression;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.test.TestUtils;
import org.junit.jupiter.api.Test;

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

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

sqlStr =
"SELECT\n"
+ " CASE\n"
+ " WHEN true\n"
+ " THEN (SELECT ((('{\"obj\":{\"field\": \"value\"}}'::JSON -> 'obj'::TEXT ->> 'field'::TEXT))))\n"
+ " END";
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
assertSqlCanBeParsedAndDeparsed(sqlStr, true);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void testAlter() throws JSQLParserException {
String sqlStr =
"ALTER INDEX idx_t_fa RENAME TO idx_t_fb";
Statement statement = TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
Assertions.assertTrue(statement instanceof UnsupportedStatement);
assertTrue(statement instanceof UnsupportedStatement);
}

@Test
Expand Down
33 changes: 33 additions & 0 deletions src/test/java/net/sf/jsqlparser/statement/select/PostgresTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.JsonExpression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statements;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.test.TestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.List;

import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;

public class PostgresTest {
Expand Down Expand Up @@ -62,4 +68,31 @@ public void testJSonOperatorIssue1571() throws JSQLParserException {
"select visit_hour,json_array_elements(into_sex_json)->>'name',json_array_elements(into_sex_json)->>'value' from period_market";
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
}

@Test
void testPostgresQuotingIssue1335() throws JSQLParserException {
String sqlStr =
"INSERT INTO \"table\"\"with\"\"quotes\" (\"column\"\"with\"\"quotes\")\n"
+ "VALUES ('1'), ('2'), ('3');\n"
+ "\n"
+ "UPDATE \"table\"\"with\"\"quotes\" SET \"column\"\"with\"\"quotes\" = '1.0' \n"
+ "WHERE \"column\"\"with\"\"quotes\" = '1';\n"
+ "\n"
+ "SELECT \"column\"\"with\"\"quotes\" FROM \"table\"\"with\"\"quotes\"\n"
+ "WHERE \"column\"\"with\"\"quotes\" IS NOT NULL;";

Statements statements = CCJSqlParserUtil.parseStatements(sqlStr);
Assertions.assertEquals(3, statements.size());

Insert insert = statements.get(Insert.class, 0);
Assertions.assertEquals(
"\"table\"\"with\"\"quotes\"", insert.getTable().getFullyQualifiedName());

PlainSelect select = statements.get(PlainSelect.class, 2);
List<SelectItem<?>> selectItems = select.getSelectItems();

Assertions.assertEquals(
"\"column\"\"with\"\"quotes\"",
selectItems.get(0).getExpression(Column.class).getColumnName());
}
}

0 comments on commit 73c55fd

Please sign in to comment.