Skip to content

Commit

Permalink
feat: Oracle Alternative Quoting
Browse files Browse the repository at this point in the history
- 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)
  • Loading branch information
manticore-projects committed Jan 29, 2023
1 parent fcb5ab1 commit c57c427
Show file tree
Hide file tree
Showing 17 changed files with 5,856 additions and 2,721 deletions.
152 changes: 44 additions & 108 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# JSqlParser
# [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"/>

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

Expand All @@ -9,127 +9,63 @@

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

Look here for more information and examples: https://github.com/JSQLParser/JSqlParser/wiki.

## License

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

## Discussion

Please provide feedback on:

* API changes: extend visitor with return values (https://github.com/JSQLParser/JSqlParser/issues/901)

## News
* Released version **4.5** of JSqlParser
* The array parsing is the default behaviour. Square bracket quotation has to be enabled using
a parser flag (**CCJSqlParser.withSquareBracketQuotation**).
* due to an API change the version will be 3.0
* JSqlParser uses now Java 8 at the minimum

More news can be found here: https://github.com/JSQLParser/JSqlParser/wiki/News.

## Alternatives to JSqlParser?
[**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.

## JSqlParser

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.

## Support
If you need help using JSqlParser feel free to file an issue or contact me.

## Contributions
To help JSqlParser's development you are encouraged to provide
* feedback
* bugreports
* pull requests for new features
* improvement requests
* fund new features or sponsor JSqlParser ([**Sponsor**](https://www.paypal.me/wumpz))

**Please write in English, since it's the language most of the dev team knows.**
## Summary

Any requests for examples or any particular documentation will be most welcome.
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)):

## Extensions in the latest SNAPSHOT version 4.6

* support for named windows in window expressions: `SELECT sum(c) OVER winName FROM mytable WINDOW winName AS (PARTITION BY pcol)`
```sql
SELECT 1 FROM dual WHERE a = b
```

Additionally, we have fixed many errors and improved the code quality and the test coverage.
```text
SQL Text
└─Statements: net.sf.jsqlparser.statement.select.Select
└─selectBody: net.sf.jsqlparser.statement.select.PlainSelect
├─selectItems -> Collection<SelectExpressionItem>
│ └─selectItems: net.sf.jsqlparser.statement.select.SelectExpressionItem
│ └─LongValue: 1
├─Table: dual
└─where: net.sf.jsqlparser.expression.operators.relational.EqualsTo
├─Column: a
└─Column: b
```

## Extensions of JSqlParser releases
```java
Statement statement = CCJSqlParserUtil.parse(sqlStr);
if (statement instanceof Select) {
Select select = (Select) statement;
PlainSelect plainSelect = (PlainSelect) select.getSelectBody();

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

## Building from the sources
Table table = (Table) plainSelect.getFromItem();

As the project is a Maven project, building is rather simple by running:
```shell
mvn package
EqualsTo equalsTo = (EqualsTo) plainSelect.getWhere();
Column a = (Column) equalsTo.getLeftExpression();
Column b = (Column) equalsTo.getRightExpression();
}
```

Since 4.2, alternatively Gradle can be used
```shell
gradle build
```

The project requires the following to build:
- Maven (or Gradle)
- JDK 8 or later. The JAR will target JDK 8, but the version of the maven-compiler-plugin that JSqlParser uses requires JDK 8+
## [Supported Grammar and Syntax](https://jsqlparser.github.io/JSqlParser/syntax.html)

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

**To build this project without using Maven or Gradle, one has to build the parser by JavaCC using the CLI options it provides.**
| RDBMS | Statements |
|------------------------------------|-----------------------------------------|
| 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 ...` |

## Debugging through problems

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.
**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)).

## Source Code conventions
## [Documentation](https://jsqlparser.github.io/JSqlParser)

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

```java
public void setUsingSelect(SubSelect usingSelect) {
this.usingSelect = usingSelect;
if (this.usingSelect != null) {
this.usingSelect.setUseBrackets(false);
}
}
```

This is a valid piece of source code:
* blocks without braces are not allowed
* after control statements (if, while, for) a whitespace is expected
* the opening brace should be in the same line as the control statement

## Maven Repository

JSQLParser is deployed at Sonatype open source maven repository.
Starting from now I will deploy there. The first snapshot version there will be 0.8.5-SNAPSHOT.
To use it this is the repository configuration:

```xml
<repositories>
<repository>
<id>jsqlparser-snapshots</id>
<snapshots>
<enabled>true</enabled>
</snapshots>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
</repositories>
```
These repository releases will be synchronised to Maven Central. Snapshots remain at Sonatype.

And this is the dependency declaration in your pom:
```xml
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>4.5</version>
</dependency>
```
## License

**JSqlParser** is dual licensed under **LGPL V2.1** or **Apache Software License, Version 2.0**.
41 changes: 31 additions & 10 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ plugins {
id "ca.coglinc2.javacc" version "latest.release"
id 'jacoco'
id "com.github.spotbugs" version "latest.release"
id "com.diffplug.spotless" version "latest.release"
id 'pmd'
id 'checkstyle'

// download the RR tools which have no Maven Repository
id "de.undercouch.download" version "latest.release"

Expand Down Expand Up @@ -98,6 +99,7 @@ java {
}

test {
environment = [ 'EXPORT_TEST_TO_FILE': 'True' ]
useJUnitPlatform()

// set heap size for the test JVM(s)
Expand Down Expand Up @@ -200,23 +202,23 @@ spotbugsMain {
spotbugs {
// fail only on P1 and without the net.sf.jsqlparser.parser.*
excludeFilter = file("config/spotbugs/spotBugsExcludeFilter.xml")

// do not run over the test, although we should do that eventually
spotbugsTest.enabled = false
spotbugsTest.enabled = false
}

pmd {
consoleOutput = false
//toolVersion = "6.46.0"

sourceSets = [sourceSets.main]

// clear the ruleset in order to use configured rules only
ruleSets = []

//rulesMinimumPriority = 1
ruleSetFiles = files("config/pmd/ruleset.xml")

pmdMain {
excludes = [
"build/generated/*"
Expand All @@ -229,6 +231,25 @@ checkstyle {
configFile =rootProject.file('config/checkstyle/checkstyle.xml')
}

spotless {
// optional: limit format enforcement to just the files changed by this feature branch
ratchetFrom 'origin/master'

format 'misc', {
// define the files to apply `misc` to
target '*.gradle', '*.md', '.gitignore'

// define the steps to apply to those files
trimTrailingWhitespace()
indentWithSpaces(4) // or spaces. Takes an integer argument if you don't like 4
endWithNewline()
}
java {
indentWithSpaces(4)
eclipse().configFile('config/formatter/eclipse-java-google-style.xml')
}
}

tasks.withType(Checkstyle) {
reports {
xml.required = false
Expand All @@ -239,7 +260,7 @@ tasks.withType(Checkstyle) {
task renderRR() {
dependsOn(compileJavacc)
doLast {
// these WAR files have been provided as a courtesy by Gunther Rademacher
// these WAR files have been provided as a courtesy by Gunther Rademacher
// and belong to the RR - Railroad Diagram Generator Project
// https://github.com/GuntherRademacher/rr
//
Expand Down Expand Up @@ -340,8 +361,8 @@ task sphinx(type: Exec) {
dependsOn(gitChangelogTask, renderRR, updateKeywords)

String PROLOG = """
.. |_| unicode:: U+00A0
:trim:
.. |_| unicode:: U+00A0
:trim:
.. |JSQLPARSER_EMAIL| replace:: support@manticore-projects.com
.. |JSQLPARSER_VERSION| replace:: ${getVersion(false)}
Expand Down
4 changes: 2 additions & 2 deletions config/formatter/eclipse-java-google-style.xml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
Expand Down Expand Up @@ -241,7 +241,7 @@
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant.count_dependent" value="16|-1|16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
Expand Down
44 changes: 44 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,50 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
<version>2.28.0</version>
<configuration>
<!-- optional: limit format enforcement to just the files changed by this feature branch -->
<ratchetFrom>origin/master</ratchetFrom>
<formats>
<!-- you can define as many formats as you want, each is independent -->
<format>
<!-- define the files to apply to -->
<includes>
<include>*.md</include>
<include>.gitignore</include>
</includes>
<!-- define the steps to apply to those files -->
<trimTrailingWhitespace/>
<endWithNewline/>
<indent>
<tabs>true</tabs>
<spacesPerTab>4</spacesPerTab>
</indent>
</format>
</formats>
<!-- define a language-specific format -->
<java>
<!-- These are the defaults, you can override if you want -->
<includes>
<include>src/main/java/**/*.java</include>
<include>src/test/java/**/*.java</include>
</includes>

<importOrder /> <!-- standard import order -->
<removeUnusedImports />

<!-- Apply Google style guide https://google.github.io/styleguide/javaguide.html -->
<eclipse>
<file>config/formatter/eclipse-java-google-style.xml</file>
</eclipse>

<formatAnnotations /> <!-- fixes formatting of type annotations, see below -->
</java>
</configuration>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public final class StringValue extends ASTNodeAccessImpl implements Expression {
private String value = "";
private String prefix = null;

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

public StringValue() {
// empty constructor
Expand Down
11 changes: 10 additions & 1 deletion src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,16 @@ TOKEN:

| < #SPECIAL_ESC: "\\'" > /* Allowing this will break LIKE ... ESCAPE ... */
| < #ESC: "\\" ["n","t","b","r","f","\\","\""] >
| < S_CHAR_LITERAL: (["U","E","N","R","B"]|"RB"|"_utf8")? (("'" ( <ESC> | <SPECIAL_ESC> | ~["'", "\\"] )* "'") | ("'" ("''" | ~["'"])* "'")) >
| < S_CHAR_LITERAL: (["U","E","N","R","B"]|"RB"|"_utf8")?
(
("'" ( <ESC> | <SPECIAL_ESC> | ~["'", "\\"] )* "'") | ("'" ("''" | ~["'"])* "'")
// Alternative Oracle Escape Modes
| ("q'{" (~[])* "}'")
| ("q'(" (~[])* ")'")
| ("q'[" (~[])* "]'")
| ("q''" (~[])* "''")
// | ("q'\\" (~[])* "\\'") <--- Does not work
) >
{
// <S_CHAR_LITERAL> contains the <SPECIAL_ESC> token and always the longest match is returned
// So when Backslash is explicitly not allowed as an Escape Character and a <S_CHAR_LITERAL> is found
Expand Down
12 changes: 11 additions & 1 deletion src/main/resources/rr/xhtml2rst.xsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
#%L
JSQLParser library
%%
Copyright (C) 2004 - 2023 JSQLParser
%%
Dual licensed under GNU LGPL 2.1 or Apache License 2.0
#L%
-->

<xsl:stylesheet version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
Expand Down Expand Up @@ -92,4 +102,4 @@ The EBNF and Railroad Diagrams for JSQLParser-|JSQLPARSER_VERSION|.
</a>
</li>
</xsl:template>
</xsl:stylesheet>
</xsl:stylesheet>
Loading

0 comments on commit c57c427

Please sign in to comment.