Skip to content

Commit

Permalink
Assorted Fixes #8 (#1807)
Browse files Browse the repository at this point in the history
* 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>

---------

Signed-off-by: Andreas Reichel <andreas@manticore-projects.com>
Co-authored-by: zaza <tzarna@gmail.com>
  • Loading branch information
manticore-projects and zaza authored Jun 15, 2023
1 parent 51cc444 commit a815f5f
Show file tree
Hide file tree
Showing 46 changed files with 1,503 additions and 248 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle

name: Java CI with Gradle

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

permissions:
contents: read

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
- name: Build with Gradle
uses: gradle/gradle-build-action@v2.4.2
with:
arguments: check
2 changes: 1 addition & 1 deletion .github/workflows/sphinx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
- name: Install XSLT Processor
run: sudo apt-get install xsltproc sphinx-common
- name: Install dependencies
run: pip install furo sphinx_rtd_theme sphinx-book-theme myst_parser sphinx-prompt sphinx_substitution_extensions sphinx_issues sphinx_inline_tabs pygments
run: pip install furo myst_parser sphinx-prompt sphinx_substitution_extensions sphinx_issues sphinx_inline_tabs pygments
- name: Checkout project sources
uses: actions/checkout@v2
with:
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ SELECT 1 FROM dual WHERE a = b
```

```text
SQL Text
└─Statements: net.sf.jsqlparser.statement.select.Select
├─selectItems -> Collection<SelectItem>
│ └─LongValue: 1
├─Table: dual
└─where: net.sf.jsqlparser.expression.operators.relational.EqualsTo
├─Column: a
└─Column: b
SQL Text
└─Statements: statement.select.PlainSelect
├─selectItems: statement.select.SelectItem
│ └─LongValue: 1
├─Table: dual
└─where: expression.operators.relational.EqualsTo
├─Column: a
└─Column: b
```

```java
Expand Down
28 changes: 7 additions & 21 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ plugins {

id "ca.coglinc2.javacc" version "latest.release"
id 'jacoco'
id 'com.github.kt3k.coveralls' version "latest.release"
id "com.github.spotbugs" version "latest.release"
id "com.diffplug.spotless" version "latest.release"
id 'pmd'
Expand Down Expand Up @@ -179,6 +180,10 @@ test {
maxHeapSize = "1G"
}

coveralls {
jacocoReportPath 'build/reports/jacoco/test/jacocoTestReport.xml'
}

jacocoTestReport {
dependsOn test // tests are required to run before generating the report
reports {
Expand Down Expand Up @@ -272,9 +277,7 @@ spotbugs {
}

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

consoleOutput = true
sourceSets = [sourceSets.main]

// clear the ruleset in order to use configured rules only
Expand Down Expand Up @@ -436,23 +439,6 @@ xslt {
tasks.register('sphinx', Exec) {
dependsOn(gitChangelogTask, renderRR, xslt, updateKeywords, xmldoc)

// doFirst() {
// exec {
// args = [
// "install"
// , "sphinx_rtd_theme"
// , "sphinx-book-theme"
// , "myst_parser"
// , "sphinx-prompt"
// , "sphinx_substitution_extensions"
// , "sphinx_issues"
// , "sphinx_inline_tabs"
// , "pygments"
// ]
// executable "pip"
// }
// }

String PROLOG = """
.. |_| unicode:: U+00A0
:trim:
Expand Down Expand Up @@ -555,7 +541,7 @@ publishing {
maven {
name = "GitHubPackages"

url = uri("https://maven.pkg.github.com/manticore-projects/jsqlparser")
url = uri("https://maven.pkg.github.com/JSQLParser/jsqlparser")
credentials(PasswordCredentials)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator;
import net.sf.jsqlparser.expression.operators.relational.RegExpMySQLOperator;
import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.AllColumns;
Expand Down Expand Up @@ -168,8 +167,6 @@ public interface ExpressionVisitor {

void visit(JsonOperator jsonExpr);

void visit(RegExpMySQLOperator regExpMySQLOperator);

void visit(UserVariable var);

void visit(NumericBind bind);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator;
import net.sf.jsqlparser.expression.operators.relational.RegExpMySQLOperator;
import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.AllColumns;
Expand Down Expand Up @@ -433,11 +432,6 @@ public void visit(JsonOperator expr) {
visitBinaryExpression(expr);
}

@Override
public void visit(RegExpMySQLOperator expr) {
visitBinaryExpression(expr);
}

@Override
public void visit(UserVariable var) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
*/
package net.sf.jsqlparser.expression;

import java.util.Objects;
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;

import java.util.Objects;

public class IntervalExpression extends ASTNodeAccessImpl implements Expression {

private String parameter = null;
Expand All @@ -27,6 +28,10 @@ public IntervalExpression(boolean intervalKeyword) {
this.intervalKeyword = intervalKeyword;
}

public boolean isUsingIntervalKeyword() {
return intervalKeyword;
}

public String getParameter() {
return parameter;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public void accept(ExpressionVisitor expressionVisitor) {
expressionVisitor.visit(this);
}

StringBuilder appendTo(StringBuilder builder) {
public StringBuilder appendTo(StringBuilder builder) {
builder.append("Trim(");

if (trimSpecification != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public ExpressionList withExpressions(T... expressions) {
return addExpressions(expressions);
}

public ExpressionList withExpressions(Collection<T> expressions) {
public ExpressionList<?> withExpressions(Collection<T> expressions) {
this.clear();
return addExpressions(expressions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class IsNullExpression extends ASTNodeAccessImpl implements Expression {
private Expression leftExpression;
private boolean not = false;
private boolean useIsNull = false;
private boolean useNotNull = false;

public Expression getLeftExpression() {
return leftExpression;
Expand All @@ -43,14 +44,25 @@ public void setUseIsNull(boolean useIsNull) {
this.useIsNull = useIsNull;
}

public boolean isUseNotNull() {
return useNotNull;
}

public IsNullExpression setUseNotNull(boolean useNotNull) {
this.useNotNull = useNotNull;
return this;
}

@Override
public void accept(ExpressionVisitor expressionVisitor) {
expressionVisitor.visit(this);
}

@Override
public String toString() {
if (isUseIsNull()) {
if (useNotNull) {
return leftExpression + " NOTNULL";
} else if (useIsNull) {
return leftExpression + (not ? " NOT" : "") + " ISNULL";
} else {
return leftExpression + " IS " + (not ? "NOT " : "") + "NULL";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,18 @@
import net.sf.jsqlparser.expression.ExpressionVisitor;

public class LikeExpression extends BinaryExpression {
public enum KeyWord {
LIKE, ILIKE, RLIKE, REGEXP;

public static KeyWord from(String keyword) {
return Enum.valueOf(KeyWord.class, keyword.toUpperCase());
}
}

private boolean not = false;
private boolean useBinary = false;
private Expression escapeExpression = null;
private boolean caseInsensitive = false;
private KeyWord likeKeyWord = KeyWord.LIKE;

public boolean isNot() {
return not;
Expand All @@ -27,23 +35,33 @@ public void setNot(boolean b) {
not = b;
}

public boolean isUseBinary() {
return useBinary;
}

public LikeExpression setUseBinary(boolean useBinary) {
this.useBinary = useBinary;
return this;
}

@Override
public void accept(ExpressionVisitor expressionVisitor) {
expressionVisitor.visit(this);
}

@Deprecated
@Override
public String getStringExpression() {
return caseInsensitive ? "ILIKE" : "LIKE";
return likeKeyWord.toString();
}

@Override
public String toString() {
String retval = getLeftExpression() + " " + (not ? "NOT " : "") + getStringExpression() + " " + getRightExpression();
String retval = getLeftExpression() + " " + (not ? "NOT " : "")
+ likeKeyWord + " " + (useBinary ? "BINARY " : "") + getRightExpression();
if (escapeExpression != null) {
retval += " ESCAPE " + escapeExpression ;
retval += " ESCAPE " + escapeExpression;
}

return retval;
}

Expand All @@ -55,19 +73,36 @@ public void setEscape(Expression escapeExpression) {
this.escapeExpression = escapeExpression;
}

@Deprecated
public boolean isCaseInsensitive() {
return caseInsensitive;
return likeKeyWord == KeyWord.ILIKE;
}

@Deprecated
public void setCaseInsensitive(boolean caseInsensitive) {
this.caseInsensitive = caseInsensitive;
this.likeKeyWord = KeyWord.ILIKE;
}

public KeyWord getLikeKeyWord() {
return likeKeyWord;
}

public LikeExpression setLikeKeyWord(KeyWord likeKeyWord) {
this.likeKeyWord = likeKeyWord;
return this;
}

public LikeExpression setLikeKeyWord(String likeKeyWord) {
this.likeKeyWord = KeyWord.from(likeKeyWord);
return this;
}

public LikeExpression withEscape(Expression escape) {
this.setEscape(escape);
return this;
}

@Deprecated
public LikeExpression withCaseInsensitive(boolean caseInsensitive) {
this.setCaseInsensitive(caseInsensitive);
return this;
Expand Down
Loading

0 comments on commit a815f5f

Please sign in to comment.