Skip to content

Commit

Permalink
Refactor Parenthesed SelectBody and FromItem (#1754)
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

* fix: JSon Operator can use Simple Function

Supports `Function() ->> Literal` (although `Function()` would not allow Nested Expression Parameters)

fixes #1571

* style: Reformat changed files and headers

* style: Remove unused variable

* feat: Add support for Hangul "\uAC00"-"\uD7A3"

fixes #1747

* style: expose `SetStatement` key-value list

fixes #1746

* style: Appease PMD/Codacy

* feat: `ConflictTarget` allows multiple `IndexColumnNames`

fixes #1749
fixes #1633
fixes #955

* doc: fix reference in the Java Doc

* build: better Upload Groovy Task

* feat: ParenthesedSelectBody and ParenthesedFromItem

- First properly working version
- Work in progress, 13 tests failing

* feat: ParenthesedSelectBody and ParenthesedFromItem

- delete unneeded ParenthesedJoin
- rename ParenthesisFromItem into ParenthesedFromItem

* feat: ParenthesedSelectBody and ParenthesedFromItem

- fix `NULLS FIRST` and `NULLS LAST`

* feat: ParenthesedSelectBody and ParenthesedFromItem

- fix Oracle Hints

* feat: ParenthesedSelectBody and ParenthesedFromItem

- parse `SetOperation` only after a (first plain) SelectBody has found, this fixes the performance issue
- one more special Oracle Test succeeds
- 5 remaining test failures

* feat: ParenthesedSelectBody and ParenthesedFromItem

- extract `OrderByElements` into `SelectBody`
- one more special Oracle Test succeeds
- all tests succeed

* style: Appease PMD/Codacy

* style: Appease PMD/Codacy

* feat: Refactor SelectBody implementations

- `SelectBody` implements `FromItem`
- get rid of `SubSelect` and `SpecialSubSelect`
- `Merge` can use `FromItem` instead of `SubSelect` or `Table`
- `LateralSubSelect` extends `ParenthesedSelectBody` directly
- Simplify the `Select` statement, although it is still redundant since     `SelectBody` also could implement `Statement` directly
- `WithItem` can use `SelectBody` directly, which allows for nested `WithItems`

BREAKING-CHANGE: Lots of redundant methods and intermediate removed

* feat: Refactor SelectBody implementations

- `SelectBody` implements `Statement` and so makes `Select` redundant
- get rid of `ValuesList`
- refactor `ValuesStatement` into `Values` which just implements `SelectBody` (and becomes a `Statement` and a `FromItem`), move to `select` package

BREAKING-CHANGE: Lots of redundant methods and intermediate removed

* style: Code cleanup

- remove 3 unused/obsolete productions
- appease PMD/Codacy

* feat: Merge `SelectBody` into `Select` Statement

- former `SelectBody` implements `Statement` and so becomes `Select`
- this reduces the AST by 1 hierarchy level

* style: Remove unused import

* test: @disabled invalid Test

* style: Appease PMD/Codacy

* test: Add a SubSelect Parsing Test

---------

Co-authored-by: zaza <tzarna@gmail.com>
  • Loading branch information
manticore-projects and zaza authored Apr 27, 2023
1 parent 0e98333 commit a312dcd
Show file tree
Hide file tree
Showing 108 changed files with 4,105 additions and 5,009 deletions.
22 changes: 10 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,20 @@ SELECT 1 FROM dual WHERE a = b

```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
└─Statements: 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
```

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

SelectExpressionItem selectExpressionItem =
(SelectExpressionItem) plainSelect.getSelectItems().get(0);
Expand Down
2 changes: 1 addition & 1 deletion config/formatter/eclipse-java-google-style.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_local_variable_annotation" value="true"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;

/**
* Combines ANY and SOME expressions.
Expand All @@ -22,10 +22,10 @@ public class AnyComparisonExpression extends ASTNodeAccessImpl implements Expres

private final ItemsList itemsList;
private boolean useBracketsForValues = false;
private final SubSelect subSelect;
private final ParenthesedSelect subSelect;
private final AnyType anyType;

public AnyComparisonExpression(AnyType anyType, SubSelect subSelect) {
public AnyComparisonExpression(AnyType anyType, ParenthesedSelect subSelect) {
this.anyType = anyType;
this.subSelect = subSelect;
this.itemsList = null;
Expand All @@ -37,7 +37,7 @@ public AnyComparisonExpression(AnyType anyType, ItemsList itemsList) {
this.subSelect = null;
}

public SubSelect getSubSelect() {
public ParenthesedSelect getSubSelect() {
return subSelect;
}

Expand All @@ -46,13 +46,13 @@ public ItemsList getItemsList() {
}

public boolean isUsingItemsList() {
return itemsList!=null;
return itemsList != null;
}

public boolean isUsingSubSelect() {
return subSelect!=null;
return subSelect != null;
}

public boolean isUsingBracketsForValues() {
return useBracketsForValues;
}
Expand All @@ -77,11 +77,8 @@ public AnyType getAnyType() {

@Override
public String toString() {
String s = anyType.name()
+ " ("
+ ( subSelect!=null
? subSelect.toString()
: "VALUES " + itemsList.toString())
String s = anyType.name() + " ("
+ (subSelect != null ? subSelect.toString() : "VALUES " + itemsList.toString())
+ " )";
return s;
}
Expand Down
45 changes: 39 additions & 6 deletions src/main/java/net/sf/jsqlparser/expression/ExpressionVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,46 @@
*/
package net.sf.jsqlparser.expression;

import net.sf.jsqlparser.expression.operators.arithmetic.*;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseRightShift;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
import net.sf.jsqlparser.expression.operators.arithmetic.IntegerDivision;
import net.sf.jsqlparser.expression.operators.arithmetic.Modulo;
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.conditional.XorExpression;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.expression.operators.relational.Between;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
import net.sf.jsqlparser.expression.operators.relational.FullTextSearch;
import net.sf.jsqlparser.expression.operators.relational.GeometryDistance;
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.IsBooleanExpression;
import net.sf.jsqlparser.expression.operators.relational.IsDistinctExpression;
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
import net.sf.jsqlparser.expression.operators.relational.JsonOperator;
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
import net.sf.jsqlparser.expression.operators.relational.Matches;
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
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;
import net.sf.jsqlparser.statement.select.AllTableColumns;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.Select;

public interface ExpressionVisitor {

Expand Down Expand Up @@ -69,7 +100,7 @@ public interface ExpressionVisitor {

void visit(Between between);

void visit (OverlapsCondition overlapsCondition);
void visit(OverlapsCondition overlapsCondition);

void visit(EqualsTo equalsTo);

Expand All @@ -93,9 +124,9 @@ public interface ExpressionVisitor {

void visit(NotEqualsTo notEqualsTo);

void visit(Column tableColumn);
void visit(ParenthesedSelect selectBody);

void visit(SubSelect subSelect);
void visit(Column tableColumn);

void visit(CaseExpression caseExpression);

Expand Down Expand Up @@ -194,4 +225,6 @@ public interface ExpressionVisitor {
void visit(IsDistinctExpression isDistinctExpression);

void visit(GeometryDistance geometryDistance);

void visit(Select selectBody);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,66 @@
*/
package net.sf.jsqlparser.expression;

import net.sf.jsqlparser.expression.operators.arithmetic.*;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseRightShift;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
import net.sf.jsqlparser.expression.operators.arithmetic.IntegerDivision;
import net.sf.jsqlparser.expression.operators.arithmetic.Modulo;
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.conditional.XorExpression;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.expression.operators.relational.Between;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.FullTextSearch;
import net.sf.jsqlparser.expression.operators.relational.GeometryDistance;
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.IsBooleanExpression;
import net.sf.jsqlparser.expression.operators.relational.IsDistinctExpression;
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor;
import net.sf.jsqlparser.expression.operators.relational.JsonOperator;
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
import net.sf.jsqlparser.expression.operators.relational.Matches;
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
import net.sf.jsqlparser.expression.operators.relational.NamedExpressionList;
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.create.table.ColumnDefinition;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.AllTableColumns;
import net.sf.jsqlparser.statement.select.ExpressionListItem;
import net.sf.jsqlparser.statement.select.FunctionItem;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.Pivot;
import net.sf.jsqlparser.statement.select.PivotVisitor;
import net.sf.jsqlparser.statement.select.PivotXml;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
import net.sf.jsqlparser.statement.select.SelectItemVisitor;
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.UnPivot;
import net.sf.jsqlparser.statement.select.WithItem;

@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.UncommentedEmptyMethodBody"})
public class ExpressionVisitorAdapter implements ExpressionVisitor, ItemsListVisitor, PivotVisitor, SelectItemVisitor {
public class ExpressionVisitorAdapter
implements ExpressionVisitor, ItemsListVisitor, PivotVisitor, SelectItemVisitor {

private SelectVisitor selectVisitor;

Expand Down Expand Up @@ -237,17 +273,17 @@ public void visit(Column column) {
}

@Override
public void visit(SubSelect subSelect) {
public void visit(ParenthesedSelect selectBody) {
if (selectVisitor != null) {
if (subSelect.getWithItemsList() != null) {
for (WithItem item : subSelect.getWithItemsList()) {
if (selectBody.getWithItemsList() != null) {
for (WithItem item : selectBody.getWithItemsList()) {
item.accept(selectVisitor);
}
}
subSelect.getSelectBody().accept(selectVisitor);
selectBody.accept(selectVisitor);
}
if (subSelect.getPivot() != null) {
subSelect.getPivot().accept(this);
if (selectBody.getPivot() != null) {
selectBody.getPivot().accept(this);
}
}

Expand All @@ -274,7 +310,7 @@ public void visit(WhenClause expr) {
public void visit(ExistsExpression expr) {
expr.getRightExpression().accept(this);
}

@Override
public void visit(AnyComparisonExpression expr) {

Expand Down Expand Up @@ -356,8 +392,7 @@ public void visit(ExtractExpression expr) {
}

@Override
public void visit(IntervalExpression expr) {
}
public void visit(IntervalExpression expr) {}

@Override
public void visit(OracleHierarchicalExpression expr) {
Expand Down Expand Up @@ -502,16 +537,13 @@ public void visit(UnPivot unpivot) {
}

@Override
public void visit(AllColumns allColumns) {
}
public void visit(AllColumns allColumns) {}

@Override
public void visit(AllTableColumns allTableColumns) {
}
public void visit(AllTableColumns allTableColumns) {}

@Override
public void visit(AllValue allValue) {
}
public void visit(AllValue allValue) {}

@Override
public void visit(IsDistinctExpression isDistinctExpression) {
Expand All @@ -526,9 +558,9 @@ public void visit(SelectExpressionItem selectExpressionItem) {
@Override
public void visit(RowConstructor rowConstructor) {
if (rowConstructor.getColumnDefinitions().isEmpty()) {
for (Expression expression: rowConstructor.getExprList().getExpressions()) {
for (Expression expression : rowConstructor.getExprList().getExpressions()) {
expression.accept(this);
}
}
} else {
for (ColumnDefinition columnDefinition : rowConstructor.getColumnDefinitions()) {
columnDefinition.accept(this);
Expand Down Expand Up @@ -557,12 +589,10 @@ public void visit(TimeKeyExpression timeKeyExpression) {
}

@Override
public void visit(DateTimeLiteralExpression literal) {
}
public void visit(DateTimeLiteralExpression literal) {}

@Override
public void visit(NextValExpression nextVal) {
}
public void visit(NextValExpression nextVal) {}

@Override
public void visit(CollateExpression col) {
Expand Down Expand Up @@ -617,19 +647,19 @@ public void visit(TimezoneExpression expr) {
@Override
public void visit(JsonAggregateFunction expression) {
Expression expr = expression.getExpression();
if (expr!=null) {
if (expr != null) {
expr.accept(this);
}

expr = expression.getFilterExpression();
if (expr!=null) {
if (expr != null) {
expr.accept(this);
}
}

@Override
public void visit(JsonFunction expression) {
for (JsonFunctionExpression expr: expression.getExpressions()) {
for (JsonFunctionExpression expr : expression.getExpressions()) {
expr.getExpression().accept(this);
}
}
Expand All @@ -638,7 +668,7 @@ public void visit(JsonFunction expression) {
public void visit(ConnectByRootOperator connectByRootOperator) {
connectByRootOperator.getColumn().accept(this);
}

@Override
public void visit(OracleNamedFunctionParameter oracleNamedFunctionParameter) {
oracleNamedFunctionParameter.getExpression().accept(this);
Expand All @@ -649,7 +679,12 @@ public void visit(GeometryDistance geometryDistance) {
visitBinaryExpression(geometryDistance);
}

@Override
public void visit(Select selectBody) {

}

public void visit(ColumnDefinition columnDefinition) {
columnDefinition.accept(this);
}
columnDefinition.accept(this);
}
}
Loading

0 comments on commit a312dcd

Please sign in to comment.