Skip to content

Commit c57c427

Browse files
feat: Oracle Alternative Quoting
- add support for Oracle Alternative Quoting e.g. `q'(...)'` - fixes JSQLParser#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)
1 parent fcb5ab1 commit c57c427

File tree

17 files changed

+5856
-2721
lines changed

17 files changed

+5856
-2721
lines changed

README.md

Lines changed: 44 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# JSqlParser
1+
# [JSqlParser (4.5 Stable or 4.6 Snapshot)](https://jsqlparser.github.io/JSqlParser) <img src="src/site/sphinx/_images/logo-no-background.svg" alt="drawing" width="200" align="right"/>
22

33
![Build Status](https://github.com/JSQLParser/JSqlParser/actions/workflows/maven.yml/badge.svg)
44

@@ -9,127 +9,63 @@
99

1010
[![Gitter](https://badges.gitter.im/JSQLParser/JSqlParser.svg)](https://gitter.im/JSQLParser/JSqlParser?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
1111

12-
Look here for more information and examples: https://github.com/JSQLParser/JSqlParser/wiki.
13-
14-
## License
15-
16-
JSqlParser is dual licensed under **LGPL V2.1** or **Apache Software License, Version 2.0**.
17-
18-
## Discussion
19-
20-
Please provide feedback on:
21-
22-
* API changes: extend visitor with return values (https://github.com/JSQLParser/JSqlParser/issues/901)
23-
24-
## News
25-
* Released version **4.5** of JSqlParser
26-
* The array parsing is the default behaviour. Square bracket quotation has to be enabled using
27-
a parser flag (**CCJSqlParser.withSquareBracketQuotation**).
28-
* due to an API change the version will be 3.0
29-
* JSqlParser uses now Java 8 at the minimum
30-
31-
More news can be found here: https://github.com/JSQLParser/JSqlParser/wiki/News.
32-
33-
## Alternatives to JSqlParser?
34-
[**General SQL Parser**](http://www.sqlparser.com/features/introduce.php?utm_source=github-jsqlparser&utm_medium=text-general) looks pretty good, with extended SQL syntax (like PL/SQL and T-SQL) and java + .NET APIs. The tool is commercial (license available online), with a free download option.
35-
36-
## JSqlParser
37-
38-
JSqlParser is a SQL statement parser. It translates SQLs in a traversable hierarchy of Java classes. JSqlParser is not limited to one database but provides support for a lot of specials of Oracle, SqlServer, MySQL, PostgreSQL ... To name some, it has support for Oracles join syntax using (+), PostgreSQLs cast syntax using ::, relational operators like != and so on.
39-
40-
## Support
41-
If you need help using JSqlParser feel free to file an issue or contact me.
42-
43-
## Contributions
44-
To help JSqlParser's development you are encouraged to provide
45-
* feedback
46-
* bugreports
47-
* pull requests for new features
48-
* improvement requests
49-
* fund new features or sponsor JSqlParser ([**Sponsor**](https://www.paypal.me/wumpz))
50-
51-
**Please write in English, since it's the language most of the dev team knows.**
12+
## Summary
5213

53-
Any requests for examples or any particular documentation will be most welcome.
14+
Please visit the [WebSite](https://jsqlparser.github.io/JSqlParser). **JSqlParser** is a RDBMS agnostic SQL statement parser. It translates SQL statements into a traversable hierarchy of Java classes (see [Samples](https://jsqlparser.github.io/JSqlParser/usage.html#parse-a-sql-statements)):
5415

55-
## Extensions in the latest SNAPSHOT version 4.6
56-
57-
* support for named windows in window expressions: `SELECT sum(c) OVER winName FROM mytable WINDOW winName AS (PARTITION BY pcol)`
16+
```sql
17+
SELECT 1 FROM dual WHERE a = b
18+
```
5819

59-
Additionally, we have fixed many errors and improved the code quality and the test coverage.
20+
```text
21+
SQL Text
22+
└─Statements: net.sf.jsqlparser.statement.select.Select
23+
└─selectBody: net.sf.jsqlparser.statement.select.PlainSelect
24+
├─selectItems -> Collection<SelectExpressionItem>
25+
│ └─selectItems: net.sf.jsqlparser.statement.select.SelectExpressionItem
26+
│ └─LongValue: 1
27+
├─Table: dual
28+
└─where: net.sf.jsqlparser.expression.operators.relational.EqualsTo
29+
├─Column: a
30+
└─Column: b
31+
```
6032

61-
## Extensions of JSqlParser releases
33+
```java
34+
Statement statement = CCJSqlParserUtil.parse(sqlStr);
35+
if (statement instanceof Select) {
36+
Select select = (Select) statement;
37+
PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
6238

63-
* [Release Notes](https://github.com/JSQLParser/JSqlParser/releases)
64-
* Modifications before GitHub's release tagging are listed in the [Older Releases](https://github.com/JSQLParser/JSqlParser/wiki/Older-Releases) page.
39+
SelectExpressionItem selectExpressionItem =
40+
(SelectExpressionItem) plainSelect.getSelectItems().get(0);
6541

66-
## Building from the sources
42+
Table table = (Table) plainSelect.getFromItem();
6743

68-
As the project is a Maven project, building is rather simple by running:
69-
```shell
70-
mvn package
44+
EqualsTo equalsTo = (EqualsTo) plainSelect.getWhere();
45+
Column a = (Column) equalsTo.getLeftExpression();
46+
Column b = (Column) equalsTo.getRightExpression();
47+
}
7148
```
7249

73-
Since 4.2, alternatively Gradle can be used
74-
```shell
75-
gradle build
76-
```
77-
78-
The project requires the following to build:
79-
- Maven (or Gradle)
80-
- JDK 8 or later. The JAR will target JDK 8, but the version of the maven-compiler-plugin that JSqlParser uses requires JDK 8+
50+
## [Supported Grammar and Syntax](https://jsqlparser.github.io/JSqlParser/syntax.html)
8151

82-
This will produce the jsqlparser-VERSION.jar file in the `target/` directory (`build/libs/jsqlparser-VERSION.jar` in case of Gradle).
52+
**JSqlParser** aims to support the SQL standard as well as all major RDBMS. Any missing syntax or features can be added on demand.
8353

84-
**To build this project without using Maven or Gradle, one has to build the parser by JavaCC using the CLI options it provides.**
54+
| RDBMS | Statements |
55+
|------------------------------------|-----------------------------------------|
56+
| Oracle<br>MS SQL Server and Sybase<br>PostgreSQL<br>MySQL and MariaDB<br>DB2<br>H2 and HSQLDB and Derby<br>SQLite| `SELECT`<br>`INSERT`, `UPDATE`, `UPSERT`, `MERGE`<br>`DELETE`, `TRUNCATE TABLE`<br>`CREATE ...`, `ALTER ....`, `DROP ...`<br>`WITH ...` |
8557

86-
## Debugging through problems
8758

88-
Refer to the [Visualize Parsing](https://github.com/JSQLParser/JSqlParser/wiki/Examples-of-SQL-parsing#visualize-parsing) section to learn how to run the parser in debug mode.
59+
**JSqlParser** can also be used to create SQL Statements from Java Code with a fluent API (see [Samples](https://jsqlparser.github.io/JSqlParser/usage.html#build-a-sql-statements)).
8960

90-
## Source Code conventions
61+
## [Documentation](https://jsqlparser.github.io/JSqlParser)
9162

92-
Recently a checkstyle process was integrated into the build process. JSqlParser follows the sun java format convention. There are no TABs allowed. Use spaces.
63+
### [Samples](https://jsqlparser.github.io/JSqlParser/usage.html#parse-a-sql-statements)
64+
### [Build Instructions](https://jsqlparser.github.io/JSqlParser/usage.html)
65+
### [Contribution](https://jsqlparser.github.io/JSqlParser/contribution.html)
66+
### [Change Log](https://jsqlparser.github.io/JSqlParser/changelog.html#latest-changes-since-jsqlparser-version)
67+
### [Issues](https://github.com/JSQLParser/JSqlParser/issues)
9368

94-
```java
95-
public void setUsingSelect(SubSelect usingSelect) {
96-
this.usingSelect = usingSelect;
97-
if (this.usingSelect != null) {
98-
this.usingSelect.setUseBrackets(false);
99-
}
100-
}
101-
```
102-
103-
This is a valid piece of source code:
104-
* blocks without braces are not allowed
105-
* after control statements (if, while, for) a whitespace is expected
106-
* the opening brace should be in the same line as the control statement
107-
108-
## Maven Repository
109-
110-
JSQLParser is deployed at Sonatype open source maven repository.
111-
Starting from now I will deploy there. The first snapshot version there will be 0.8.5-SNAPSHOT.
112-
To use it this is the repository configuration:
113-
114-
```xml
115-
<repositories>
116-
<repository>
117-
<id>jsqlparser-snapshots</id>
118-
<snapshots>
119-
<enabled>true</enabled>
120-
</snapshots>
121-
<url>https://oss.sonatype.org/content/groups/public/</url>
122-
</repository>
123-
</repositories>
124-
```
125-
These repository releases will be synchronised to Maven Central. Snapshots remain at Sonatype.
126-
127-
And this is the dependency declaration in your pom:
128-
```xml
129-
<dependency>
130-
<groupId>com.github.jsqlparser</groupId>
131-
<artifactId>jsqlparser</artifactId>
132-
<version>4.5</version>
133-
</dependency>
134-
```
69+
## License
13570

71+
**JSqlParser** is dual licensed under **LGPL V2.1** or **Apache Software License, Version 2.0**.

build.gradle

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ plugins {
88
id "ca.coglinc2.javacc" version "latest.release"
99
id 'jacoco'
1010
id "com.github.spotbugs" version "latest.release"
11+
id "com.diffplug.spotless" version "latest.release"
1112
id 'pmd'
1213
id 'checkstyle'
13-
14+
1415
// download the RR tools which have no Maven Repository
1516
id "de.undercouch.download" version "latest.release"
1617

@@ -98,6 +99,7 @@ java {
9899
}
99100

100101
test {
102+
environment = [ 'EXPORT_TEST_TO_FILE': 'True' ]
101103
useJUnitPlatform()
102104

103105
// set heap size for the test JVM(s)
@@ -200,23 +202,23 @@ spotbugsMain {
200202
spotbugs {
201203
// fail only on P1 and without the net.sf.jsqlparser.parser.*
202204
excludeFilter = file("config/spotbugs/spotBugsExcludeFilter.xml")
203-
205+
204206
// do not run over the test, although we should do that eventually
205-
spotbugsTest.enabled = false
207+
spotbugsTest.enabled = false
206208
}
207209

208210
pmd {
209211
consoleOutput = false
210212
//toolVersion = "6.46.0"
211-
213+
212214
sourceSets = [sourceSets.main]
213-
215+
214216
// clear the ruleset in order to use configured rules only
215217
ruleSets = []
216-
218+
217219
//rulesMinimumPriority = 1
218220
ruleSetFiles = files("config/pmd/ruleset.xml")
219-
221+
220222
pmdMain {
221223
excludes = [
222224
"build/generated/*"
@@ -229,6 +231,25 @@ checkstyle {
229231
configFile =rootProject.file('config/checkstyle/checkstyle.xml')
230232
}
231233

234+
spotless {
235+
// optional: limit format enforcement to just the files changed by this feature branch
236+
ratchetFrom 'origin/master'
237+
238+
format 'misc', {
239+
// define the files to apply `misc` to
240+
target '*.gradle', '*.md', '.gitignore'
241+
242+
// define the steps to apply to those files
243+
trimTrailingWhitespace()
244+
indentWithSpaces(4) // or spaces. Takes an integer argument if you don't like 4
245+
endWithNewline()
246+
}
247+
java {
248+
indentWithSpaces(4)
249+
eclipse().configFile('config/formatter/eclipse-java-google-style.xml')
250+
}
251+
}
252+
232253
tasks.withType(Checkstyle) {
233254
reports {
234255
xml.required = false
@@ -239,7 +260,7 @@ tasks.withType(Checkstyle) {
239260
task renderRR() {
240261
dependsOn(compileJavacc)
241262
doLast {
242-
// these WAR files have been provided as a courtesy by Gunther Rademacher
263+
// these WAR files have been provided as a courtesy by Gunther Rademacher
243264
// and belong to the RR - Railroad Diagram Generator Project
244265
// https://github.com/GuntherRademacher/rr
245266
//
@@ -340,8 +361,8 @@ task sphinx(type: Exec) {
340361
dependsOn(gitChangelogTask, renderRR, updateKeywords)
341362

342363
String PROLOG = """
343-
.. |_| unicode:: U+00A0
344-
:trim:
364+
.. |_| unicode:: U+00A0
365+
:trim:
345366
346367
.. |JSQLPARSER_EMAIL| replace:: [email protected]
347368
.. |JSQLPARSER_VERSION| replace:: ${getVersion(false)}

config/formatter/eclipse-java-google-style.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@
167167
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
168168
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
169169
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
170-
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
170+
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
171171
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
172172
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
173173
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
@@ -241,7 +241,7 @@
241241
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant.count_dependent" value="16|-1|16"/>
242242
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/>
243243
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
244-
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
244+
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="0"/>
245245
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
246246
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
247247
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>

pom.xml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,50 @@
391391
</execution>
392392
</executions>
393393
</plugin>
394+
<plugin>
395+
<groupId>com.diffplug.spotless</groupId>
396+
<artifactId>spotless-maven-plugin</artifactId>
397+
<version>2.28.0</version>
398+
<configuration>
399+
<!-- optional: limit format enforcement to just the files changed by this feature branch -->
400+
<ratchetFrom>origin/master</ratchetFrom>
401+
<formats>
402+
<!-- you can define as many formats as you want, each is independent -->
403+
<format>
404+
<!-- define the files to apply to -->
405+
<includes>
406+
<include>*.md</include>
407+
<include>.gitignore</include>
408+
</includes>
409+
<!-- define the steps to apply to those files -->
410+
<trimTrailingWhitespace/>
411+
<endWithNewline/>
412+
<indent>
413+
<tabs>true</tabs>
414+
<spacesPerTab>4</spacesPerTab>
415+
</indent>
416+
</format>
417+
</formats>
418+
<!-- define a language-specific format -->
419+
<java>
420+
<!-- These are the defaults, you can override if you want -->
421+
<includes>
422+
<include>src/main/java/**/*.java</include>
423+
<include>src/test/java/**/*.java</include>
424+
</includes>
425+
426+
<importOrder /> <!-- standard import order -->
427+
<removeUnusedImports />
428+
429+
<!-- Apply Google style guide https://google.github.io/styleguide/javaguide.html -->
430+
<eclipse>
431+
<file>config/formatter/eclipse-java-google-style.xml</file>
432+
</eclipse>
433+
434+
<formatAnnotations /> <!-- fixes formatting of type annotations, see below -->
435+
</java>
436+
</configuration>
437+
</plugin>
394438
</plugins>
395439
</build>
396440

src/main/java/net/sf/jsqlparser/expression/StringValue.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public final class StringValue extends ASTNodeAccessImpl implements Expression {
2323
private String value = "";
2424
private String prefix = null;
2525

26-
public static final List<String> ALLOWED_PREFIXES = Arrays.asList("N", "U", "E", "R", "B", "RB", "_utf8");
26+
public static final List<String> ALLOWED_PREFIXES = Arrays.asList("N", "U", "E", "R", "B", "RB", "_utf8", "Q");
2727

2828
public StringValue() {
2929
// empty constructor

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,16 @@ TOKEN:
518518

519519
| < #SPECIAL_ESC: "\\'" > /* Allowing this will break LIKE ... ESCAPE ... */
520520
| < #ESC: "\\" ["n","t","b","r","f","\\","\""] >
521-
| < S_CHAR_LITERAL: (["U","E","N","R","B"]|"RB"|"_utf8")? (("'" ( <ESC> | <SPECIAL_ESC> | ~["'", "\\"] )* "'") | ("'" ("''" | ~["'"])* "'")) >
521+
| < S_CHAR_LITERAL: (["U","E","N","R","B"]|"RB"|"_utf8")?
522+
(
523+
("'" ( <ESC> | <SPECIAL_ESC> | ~["'", "\\"] )* "'") | ("'" ("''" | ~["'"])* "'")
524+
// Alternative Oracle Escape Modes
525+
| ("q'{" (~[])* "}'")
526+
| ("q'(" (~[])* ")'")
527+
| ("q'[" (~[])* "]'")
528+
| ("q''" (~[])* "''")
529+
// | ("q'\\" (~[])* "\\'") <--- Does not work
530+
) >
522531
{
523532
// <S_CHAR_LITERAL> contains the <SPECIAL_ESC> token and always the longest match is returned
524533
// So when Backslash is explicitly not allowed as an Escape Character and a <S_CHAR_LITERAL> is found

src/main/resources/rr/xhtml2rst.xsl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
#%L
4+
JSQLParser library
5+
%%
6+
Copyright (C) 2004 - 2023 JSQLParser
7+
%%
8+
Dual licensed under GNU LGPL 2.1 or Apache License 2.0
9+
#L%
10+
-->
11+
212
<xsl:stylesheet version="1.1"
313
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
414
xmlns:xhtml="http://www.w3.org/1999/xhtml"
@@ -92,4 +102,4 @@ The EBNF and Railroad Diagrams for JSQLParser-|JSQLPARSER_VERSION|.
92102
</a>
93103
</li>
94104
</xsl:template>
95-
</xsl:stylesheet>
105+
</xsl:stylesheet>

0 commit comments

Comments
 (0)