Skip to content

Commit c79dfff

Browse files
Backslash Quotation of Single-Quote '\\'' (#1813)
* Fixes #1684: Support CREATE MATERIALIZED VIEW with AUTO REFRESH Support parsing create view statements in Redshift with AUTO REFRESH option. * Reduce cyclomatic complexity in CreateView.toString Extract adding the force option into a dedicated method resulting in the cyclomatic complexity reduction of the CreateView.toString method. * Enhanced Keywords Add Keywords and document, which keywords are allowed for what purpose * Fix incorrect tests * Define Reserved Keywords explicitly Derive All Keywords from Grammar directly Generate production for Object Names (semi-) automatically Add parametrized Keyword Tests * Fix test resources * Adjust Gradle to JUnit 5 Parallel Test execution Gradle Caching Explicitly request for latest JavaCC 7.0.10 * Do not mark SpeedTest for concurrent execution * Remove unused imports * Adjust Gradle to JUnit 5 Parallel Test execution Gradle Caching Explicitly request for latest JavaCC 7.0.10 * Do not mark SpeedTest for concurrent execution * Remove unused imports * Sphinx Documentation Update the MANTICORE Sphinx Theme, but ignore it in GIT Add the content to the Sphinx sites Add a Gradle function to derive Stable and Snapshot version from GIT Tags Add a Gradle GIT change task Add a Gradle sphinx task Add a special Test case for illustrating the use of JSQLParser * doc: request for `Conventional Commit` messages * feat: make important Classes Serializable Implement Serializable for persisting via ObjectOutputStream * chore: Make Serializable * doc: Better integration of the RR diagrams - apply neutral Sphinx theme - insert the RR diagrams into the sphinx sources - better documentation on Gradle dependencies - link GitHub repository * Merge * feat: Oracle Alternative Quoting - add support for Oracle Alternative Quoting e.g. `q'(...)'` - fixes #1718 - add a Logo and FavIcon to the Website - document recent changes on Quoting/Escaping - add an example on building SQL from Java - rework the README.md, promote the Website - add Spotless Formatter, using Google Java Style (with Tab=4 Spaces) * style: Appease PMD/Codacy * doc: fix the issue template - fix the issue template - fix the -SNAPSHOT version number * Update issue templates * Update issue templates * feat: Support more Statement Separators - `GO` - Slash `/` - Two empty lines * feat: FETCH uses EXPRESSION - `FETCH` uses `EXPRESSION` instead of SimpleJDBCParameter only - Visit/Accept `FETCH` `EXPRESSION` instead of `append` to String - Visit/Accept `OFFSET` `EXPRESSION` instead of `append` to String - Gradle: remove obsolete/incompatible `jvmArgs` from Test() * style: apply Spotless * test: commit missing test * feat: Lateral View Implement Lateral View according to https://spark.apache.org/docs/latest/sql-ref-syntax-qry-select-lateral-view.html#syntax Add proper tests Fixes #1777 Fixes #239 Fixes #1723 * feat: Oracle `HAVING` before `GROUP BY` Basic support for Oracle's `HAVING` before `GROUP BY` option. It will be parsed without any special consideration for the order. Special Oracle Test groupby07.sql gets parsed, but fails when the deparser reorders the clauses. Fixes #1774 * feat: Multi-Part Names for Variables and Parameters Fixes #1771 Fixes #1768 * feat: ClickHouse `Select...` ``FINAL` modifier Fixes #1774 BREAKING-CHANGE: introduces reserved keyword `FINAL` * feat: Test if a JOIN is an INNER JOIN according to the SQL:2016 An `INNER JOIN` is a qualified `JOIN` with the `INNER` qualifier or without any `LEFT` or `RIGHT` qualifier. Fixes #1775 * feat: Switch off contradicting `JOIN` qualifiers, when setting a qualifier * feat: implement SQL:2016 Convert() and Trim() - Fixes #868 - Fixes #1767 - Fixes Special Oracle Test `function03.sql` * feat: ClickHouse `LIMIT ... BY ...` clause - LimitDeparser accepts ExpressionVisitor - `SELECT` can have optional `LIMIT ... BY ...` clause - Fixes #1436 * test: add specific tests for closed issues * test: add specific tests for closed issues * refactor: remove `SelectExpressionItem` in favor of `SelectItem` BREAKING-CHANGE: `SelectExpressionItem` removed * doc: Update examples * build: Add missing import * doc: Update the README.md * fix: assign Enum case insensitive Fixes #1779 * fix: assign Enum case insensitive Remove redundant `DateTime` enum Fixes #1779 * Revert "fix: assign Enum case insensitive" This reverts commit 86d0ace. * feat: Consolidate the `ExpressionList`, removing many redundant List alike Classes and Productions - `ExpressionList` extends a `List<Expression>` directly and implements `Expression` - `ExpressionList` has no Brackets - introduce `ParenthesedExpressionList` which extends `ExpressionList` and has Brackets - refactor `MultiExpressionList` to extend `List<ExpressionList>` - replace any occurrence of `List<Expression>` with `ExpressionList` and remove lots of redundant Productions - `RowConstructor` extends `ExpressionList` - remove redundant `ValueExpressionList` (it was just an `ExpressionList` - get rid of any `useBrackets` flags - consolidate the `Cast` Functions - use `ExpressionListDeparser` as much as possible BREAKING-CHANGE: All `List<Expression>` and `List<Column>` related methods have changed. No `useBrackets` flags, instead use `ParenthesedExpressionList` when brackets are needed. * fix: Remove tests for `()`, since `ParenthesedExpressionList` will catch those too * refactor: UpdateSets for `Update` and `InsertConflictTarget` - remove redundant code - add license headers - register `function06.sql` success * build: Increase TimeOut for the GitHub CI * style: Appease Codacy * style: Checkstyle * refactor: Remove `ItemsList`, `MultiExpressionList`, `Replace` Since we have proper `ExpressionList` implementing `Expression` we can narrow down the API: - remove `ItemsList`, `ItemsListVisitor`, `ItemsListValidator` in favor of `ExpressionList` - remove `MultiExpressionList` in favor of `ExpressionList` - refactor `NamedExpressionList` so it extends `ExpressionList` and uses `ExpressionListDeparser` - simplify `InExpression` and `AnyComparisionExpression` BREAKING-CHANGE: many Classes and Methods removed * style: Appease Codacy * style: Rework all the ENUMs - assign Value only when really needed - implement `from()` method for getting the case-insensitive Enum * doc: Better Sphinx Tabs Addresses issue #1784 item 2 * doc: RR chart colors cater for Dark Mode Addresses issue #1784 item 3 * refactor: remove SimpleFunction Remove the production `SimpleFunction` Clean-up `InternalFunction` * build: improve Gradle Build - fix Version/Snapshot - add XML Doclet (for generating API Website via XSLT later) - fix the publishing task and add GitHub package * refactor: `Insert` uses `ExpressionList` and `UpdateSet` * test: Disable API Sanitation for the moment * style: Appease Checkstyle * style: Appease PMD * fix: find the correct position when field belongs to an internal class * style: replace all List<Expression> with ExpressionList<> and enforce policy via Acceptance Test - refactor `Merge`, use `ExpressionList`, `UpdateSet` and Visitor Pattern - refactor `Upsert`, use `ExpressionList`, `UpdateSet` and Visitor Pattern - refactor `Set` Statement - refactor `Limit`, `Pivot`, `Unpivot` ** Breaking Changes ** Getters/Setters of `Merge`, `Upsert`, `Set` have changed * refactor: generify `SelectItem` and remove `FunctionItem` and `ExpressionListItem` - generify `SelectItem<T extends Expression>` - replace `FunctionItem` with `SelectItem<Function>` - replace `ExpressionListItem` with `SelectItem<ExpressionList>` - appease PMD/Codacy ** Breaking Changes ** Getters/Setters of `Pivot`, `UnPivot`, `PivotXML` have changed * fix: Java Version 8 * feat: JdbcNamedParameter allows "&" (instead of ":") - fixes #1785 * feat: access Elements of Array Columns - Example `update utilisateur set listes[0] = 1` - fixes #1083 * feat: `MEMBER OF` condition as shown at https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of - fixes #1631 * style: appease PMD/Codacy * style: appease PMD/Codacy * test: add unit test for issue #1778 * feat: Write API documentation to the WebSite via XMLDoclet * Update sphinx.yml * build: Sphinx build fixes * build: Sphinx build fixes * build: Sphinx build fixes * build: improve the GIT Snapshot detection * fix: issue #1791 - Allow `START` keyword as table `CreateParameter` * fix: issue #1789 - allow `CREATE TABLE ...` column parameter with Postgres`nextval('public.actor_actor_id_seq'::regclass)` * fix: issue #1789 - allow `CREATE TABLE ...` column parameter with Postgres`nextval('public.actor_actor_id_seq'::regclass)` * refactor: simplify production `CreateParameter()` * refactor: SHOW statement, supporting any RDBMS specific implementation - returns any RDBMS specific implementation as `UnsupportedStatement` - fixes #1702 * refactor: RETURNING clause - supports Oracle's `RETURN ... INTO ...` - fixes #1780 - fixes #686 - Special Oracle tests `insert11.sql` and `insert12.sql` * refactor: CREATE and ALTER productions - avoid LOOKAHEADs - simplify the SimpleStatement() production - use UnsupportedStatements() for any RDBMS specific syntax - fixes #1515 - fixes #1453 * fix: Complex Parsing Approach - optionally provide a global Executor, instead spawning one for each parse - run into Complex Parsing only, when Complex Parsing was allowed - provide a Logger - fixes #1792 * style: Quieten the logger * style: Cosmetic improvements * feat: chaining JSON Expressions - supports chains like '{"obj":{"field": "value"}}'::JSON -> 'obj'::TEXT ->> 'field'::TEXT - fixes #1792 * style: remove unused imports * refact: Statements extends List<Statement> * build: try to work around the Maven/JDK8 issue on GitHub * feat: parse CREATE TRIGGER as UnsupportedStatement - fixes #1090 * feat: functions blocks, parenthesed JSON Expressions - fixes #1792, the very complex example - fixes #1477 * feat: functions blocks, parenthesed JSON Expressions - fixes #1792, the very complex example - fixes #1477 - cosmetics * Create gradle.yml * feat: Quoted Identifiers can contain double-quotes (PostgreSQL) - `SELECT "test""column""name"` - fixes #1335 * build: improve Upload task * doc: Website improvements - Show Release vs. SNAPSHOT - FURO theme - fix inline tab appearance * doc: Website, fix tabs * fix: throw the specific exception * doc: write migration guide * fix: expose IntervalExpression attributes and use DeParser * doc: migration guide * feat: T-SQL `FOR ...` clause - fixes #1800 * fix: SPHINX modules and themes * docs: write migration guide - migration guide - Getters for List Elements - Rename Join `rightItem` to `fromItem` * feat: `QUALIFY` clause - fixes #1805 * feat: Postgres `NOTNULL` support - incorporates PR #1725, all credits to @tomershay Signed-off-by: Andreas Reichel <andreas@manticore-projects.com> * feat: MySQL `NOT RLIKE`, `NOT REGEXP` expressions - fixes #1553 - remove RegExpMySQLOperator, replaced by flavoured `LIKE` expression Signed-off-by: Andreas Reichel <andreas@manticore-projects.com> * fix: `INSERT` must use simple Column Names only - salvages PR #589, credits to @wheredevel Signed-off-by: Andreas Reichel <andreas@manticore-projects.com> * fix: Backslash escaped single quote `'\''` fixes #1812 Signed-off-by: Andreas Reichel <andreas@manticore-projects.com> * style: Licenses from Maven plugin Signed-off-by: Andreas Reichel <andreas@manticore-projects.com> --------- Signed-off-by: Andreas Reichel <andreas@manticore-projects.com> Co-authored-by: zaza <tzarna@gmail.com>
1 parent a815f5f commit c79dfff

File tree

6 files changed

+70
-6
lines changed

6 files changed

+70
-6
lines changed

src/main/java/net/sf/jsqlparser/schema/Sequence.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
/*
2-
* #%L JSQLParser library %% Copyright (C) 2004 - 2020 JSQLParser %% Dual licensed under GNU LGPL
3-
* 2.1 or Apache License 2.0 #L%
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2019 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
49
*/
510
package net.sf.jsqlparser.schema;
611

src/main/java/net/sf/jsqlparser/statement/select/ForClause.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2023 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
110
package net.sf.jsqlparser.statement.select;
211

312
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;

src/main/java/net/sf/jsqlparser/util/PerformanceTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2023 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
110
package net.sf.jsqlparser.util;
211

312
import net.sf.jsqlparser.parser.CCJSqlParser;

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,15 @@ TOKEN:
565565
}
566566
}
567567
input_stream.backup(image.length() - matchedToken.image.length() );
568-
}
568+
} else if ( configuration.getAsBoolean(Feature.allowBackslashEscapeCharacter) && matchedToken.image.contains("\\''") ) {
569+
matchedToken.image = image.substring( 0, image.lastIndexOf("\\'") + 3);
570+
for (int i=0;i<CCJSqlParserConstants.tokenImage.length;i++) {
571+
if ( CCJSqlParserConstants.tokenImage[i].equals("<S_CHAR_LITERAL>") ) {
572+
matchedToken.kind = i;
573+
}
574+
}
575+
input_stream.backup(image.length() - matchedToken.image.length() );
576+
}
569577
}
570578
| < S_QUOTED_IDENTIFIER: "\"" ( "\"\"" | ~["\n","\r","\""])* "\"" | "$$" (~["$"])* "$$" | ("`" (~["\n","\r","`"])+ "`") | ( "[" (~["\n","\r","]"])* "]" ) >
571579
{
@@ -3405,7 +3413,7 @@ Expression LikeExpression(Expression leftExpression) #LikeExpression:
34053413
| token = <K_RLIKE>
34063414
| token = <K_REGEXP>
34073415
) { result.setLikeKeyWord( LikeExpression.KeyWord.from(token.image)); }
3408-
[ <K_BINARY> {result.setUseBinary(true); } ]
3416+
[ LOOKAHEAD(2) <K_BINARY> {result.setUseBinary(true); } ]
34093417
rightExpression=SimpleExpression()
34103418
[ LOOKAHEAD(2) <K_ESCAPE>
34113419
(

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2023 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
110
package net.sf.jsqlparser.statement.select;
211

312
import net.sf.jsqlparser.JSQLParserException;

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3266,7 +3266,7 @@ public void testIssue167_singleQuoteEscape(String sqlStr) throws JSQLParserExcep
32663266
}
32673267

32683268
@ParameterizedTest
3269-
@ValueSource(strings = {"SELECT '\\'''", "SELECT '\\\\\\''"})
3269+
@ValueSource(strings = {"SELECT '\\'\\''", "SELECT '\\\\\\''"})
32703270
public void testIssue167_singleQuoteEscape2(String sqlStr) throws JSQLParserException {
32713271
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true,
32723272
parser -> parser.withBackslashEscapeCharacter(true));
@@ -5722,4 +5722,28 @@ public void testNotIsNullInFilter() throws JSQLParserException {
57225722
String stmt = "SELECT count(*) FILTER (WHERE i NOT ISNULL) AS filtered FROM tasks";
57235723
assertSqlCanBeParsedAndDeparsed(stmt);
57245724
}
5725+
5726+
@Test
5727+
void testBackSlashQuotationIssue1812() throws JSQLParserException {
5728+
String sqlStr = "SELECT ('\\'', 'a')";
5729+
Statement stmt2 = CCJSqlParserUtil.parse(
5730+
sqlStr
5731+
, parser -> parser
5732+
.withBackslashEscapeCharacter(true)
5733+
);
5734+
5735+
sqlStr = "INSERT INTO recycle_record (a,f) VALUES ('\\'anything', 'abc');";
5736+
stmt2 = CCJSqlParserUtil.parse(
5737+
sqlStr
5738+
, parser -> parser
5739+
.withBackslashEscapeCharacter(true)
5740+
);
5741+
5742+
sqlStr = "INSERT INTO recycle_record (a,f) VALUES ('\\'','83653692186728700711687663398101');";
5743+
stmt2 = CCJSqlParserUtil.parse(
5744+
sqlStr
5745+
, parser -> parser
5746+
.withBackslashEscapeCharacter(true)
5747+
);
5748+
}
57255749
}

0 commit comments

Comments
 (0)