diff --git a/.travis.yml b/.travis.yml
index 5652c04cf..581903065 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,4 +4,10 @@ jdk:
- openjdk11
after_success:
- - mvn clean cobertura:cobertura coveralls:report
\ No newline at end of file
+ - mvn clean cobertura:cobertura coveralls:report
+
+cache:
+ directories:
+ - $HOME/.m2
+ - $HOME/.gradle/caches/
+ - $HOME/.gradle/wrapper/
\ No newline at end of file
diff --git a/README.md b/README.md
index 5cac7869e..024d6addd 100644
--- a/README.md
+++ b/README.md
@@ -54,9 +54,25 @@ To help JSqlParser's development you are encouraged to provide
Also I would like to know about needed examples or documentation stuff.
## Extensions in the latest SNAPSHOT version 4.2
-
+* API change: Support `SELECT ...` without a `FROM` clause, making `SELECT 1, 2` and `SELECT *` parsable statements (before those failed)
+* API change: Support complex `UPDATE` sets (using multiple `SubQuery` or `ValueList` or Single Values, in combination)
+* Support nested `CASE` expressions with complex expression arguments
+* API change: Support `JOIN` with multiple trailing `ON` Expressions (`JOIN ... JOIN ... ON ... ON ...`)
+* Support Oracle Hierarchical `CONNECT_BY_ROOT` Operator
+* Support Transact-SQL `IF ... ELSE ...` Statement Control Flows.
+* Allow optional parameters for the `ALTER TABLE ...` statement (e.g. `ALTER TABLE ... MOVE TABLESPACE ...`)
+* Support Oracle `ALTER SYSTEM ...` statement
+* Support Oracle Named Function Parameters`Func( param1 => arg1, ...`
+* Add Gradle build
+* Allow `JdbcParameter` or `JdbcNamedParameter` for MySQL FullTextSearch
+* Allow `Cast` into `Row` Constructor
+* Support Oracle `RENAME ... TO ...` statement
+* Support Oracle `PURGE` statement
+* Support JSON functions `JSON_OBJECT()`, `JSON_ARRAY()`, `JSON_OBJECTAGG()`, `JSON_ARRAYAGG()`
* API change: merge ALL and ANY expressions class
-* allow `CURRENT DATE`in addition to `CURRENT_DATE` (without underbar)
+* Allow DB2 compliant `CURRENT DATE`in addition to `CURRENT_DATE` (without underscore)
+
+Additionally, we have fixed many errors and improved the code quality and the test coverage.
## Extensions of JSqlParser releases
@@ -67,16 +83,22 @@ Also I would like to know about needed examples or documentation stuff.
## Building from the sources
As the project is a Maven project, building is rather simple by running:
+```shell
+mvn package
+```
- mvn package
+Since 4.2, alternatively Gradle can be used
+```shell
+gradle build
+```
The project requires the following to build:
-- Maven
+- 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+
-This will produce the jsqlparser-VERSION.jar file in the target/ directory.
+This will produce the jsqlparser-VERSION.jar file in the `target/` directory (`build/libs/jsqlparser-VERSION.jar` in case of Gradle).
-**To build this project without using Maven, one has to build the parser by JavaCC using the CLI options it provides.**
+**To build this project without using Maven or Gradle, one has to build the parser by JavaCC using the CLI options it provides.**
## Debugging through problems
@@ -124,7 +146,7 @@ And this is the dependency declaration in your pom:
com.github.jsqlparser
jsqlparser
- 4.0
+ 4.1
```
diff --git a/build.gradle b/build.gradle
index 8bd8e2600..f137150c8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -73,7 +73,7 @@ jacocoTestCoverageVerification {
violationRules {
rule {
limit {
- minimum = 0.837
+ minimum = 0.838
}
}
}
diff --git a/src/main/java/net/sf/jsqlparser/statement/update/Update.java b/src/main/java/net/sf/jsqlparser/statement/update/Update.java
index 3dcd27059..fbfafd68d 100644
--- a/src/main/java/net/sf/jsqlparser/statement/update/Update.java
+++ b/src/main/java/net/sf/jsqlparser/statement/update/Update.java
@@ -183,12 +183,12 @@ public void setSelect(Select select) {
@Deprecated
public boolean isUseColumnsBrackets() {
- return updateSets.get(0).usingBrackets;
+ return updateSets.get(0).usingBracketsForColumns;
}
@Deprecated
public void setUseColumnsBrackets(boolean useColumnsBrackets) {
- updateSets.get(0).usingBrackets = useColumnsBrackets;
+ updateSets.get(0).usingBracketsForColumns = useColumnsBrackets;
}
@Deprecated
@@ -268,7 +268,7 @@ public String toString() {
b.append(", ");
}
- if (updateSet.usingBrackets) {
+ if (updateSet.usingBracketsForColumns) {
b.append("(");
}
@@ -279,46 +279,28 @@ public String toString() {
b.append(updateSet.columns.get(i));
}
- if (updateSet.usingBrackets) {
+ if (updateSet.usingBracketsForColumns) {
b.append(")");
}
b.append(" = ");
+ if (updateSet.usingBracketsForValues) {
+ b.append("(");
+ }
+
for (int i = 0; i < updateSet.expressions.size(); i++) {
if (i > 0) {
b.append(", ");
}
b.append(updateSet.expressions.get(i));
}
+ if (updateSet.usingBracketsForValues) {
+ b.append(")");
+ }
j++;
}
-
-// if (!useSelect) {
-// for (int i = 0; i < getColumns().size(); i++) {
-// if (i != 0) {
-// b.append(", ");
-// }
-// b.append(columns.get(i)).append(" = ");
-// b.append(expressions.get(i));
-// }
-// } else {
-// if (useColumnsBrackets) {
-// b.append("(");
-// }
-// for (int i = 0; i < getColumns().size(); i++) {
-// if (i != 0) {
-// b.append(", ");
-// }
-// b.append(columns.get(i));
-// }
-// if (useColumnsBrackets) {
-// b.append(")");
-// }
-// b.append(" = ");
-// b.append("(").append(select).append(")");
-// }
if (fromItem != null) {
b.append(" FROM ").append(fromItem);
if (joins != null) {
diff --git a/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java b/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java
index 4426b87f8..3e6da1ba1 100644
--- a/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java
+++ b/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java
@@ -17,7 +17,8 @@
import java.util.Objects;
public class UpdateSet {
- protected boolean usingBrackets = false;
+ protected boolean usingBracketsForColumns = false;
+ protected boolean usingBracketsForValues = false;
protected ArrayList columns = new ArrayList<>();
protected ArrayList expressions = new ArrayList<>();
@@ -34,12 +35,20 @@ public UpdateSet(Column column, Expression expression) {
this.expressions.add(expression);
}
- public boolean isUsingBrackets() {
- return usingBrackets;
+ public boolean isUsingBracketsForValues() {
+ return usingBracketsForValues;
}
- public void setUsingBrackets(boolean usingBrackets) {
- this.usingBrackets = usingBrackets;
+ public void setUsingBracketsForValues(boolean usingBracketsForValues) {
+ this.usingBracketsForValues = usingBracketsForValues;
+ }
+
+ public boolean isUsingBracketsForColumns() {
+ return usingBracketsForColumns;
+ }
+
+ public void setUsingBracketsForColumns(boolean usingBracketsForColumns) {
+ this.usingBracketsForColumns = usingBracketsForColumns;
}
public ArrayList getColumns() {
@@ -61,13 +70,18 @@ public void setExpressions(ArrayList expressions) {
public void add(Column column, Expression expression) {
columns.add(column);
expressions.add(expression);
- };
+ }
public void add(Column column) {
columns.add(column);
- };
+ }
+
+ public void add(Expression expression) {
+ expressions.add(expression);
+ }
public void add(ExpressionList expressionList) {
expressions.addAll(expressionList.getExpressions());
- };
+ }
+
}
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java
index 01851ef5f..fdd168391 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java
@@ -66,7 +66,7 @@ public void deParse(Update update) {
buffer.append(", ");
}
- if (updateSet.isUsingBrackets()) {
+ if (updateSet.isUsingBracketsForColumns()) {
buffer.append("(");
}
for (int i = 0; i < updateSet.getColumns().size(); i++) {
@@ -75,56 +75,27 @@ public void deParse(Update update) {
}
updateSet.getColumns().get(i).accept(expressionVisitor);
}
- if (updateSet.isUsingBrackets()) {
+ if (updateSet.isUsingBracketsForColumns()) {
buffer.append(")");
}
buffer.append(" = ");
+ if (updateSet.isUsingBracketsForValues()) {
+ buffer.append("(");
+ }
for (int i = 0; i < updateSet.getExpressions().size(); i++) {
if (i > 0) {
buffer.append(", ");
}
updateSet.getExpressions().get(i).accept(expressionVisitor);
}
+ if (updateSet.isUsingBracketsForValues()) {
+ buffer.append(")");
+ }
j++;
}
-
-// if (!update.isUseSelect()) {
-// for (int i = 0; i < update.getColumns().size(); i++) {
-// Column column = update.getColumns().get(i);
-// column.accept(expressionVisitor);
-//
-// buffer.append(" = ");
-//
-// Expression expression = update.getExpressions().get(i);
-// expression.accept(expressionVisitor);
-// if (i < update.getColumns().size() - 1) {
-// buffer.append(", ");
-// }
-// }
-// } else {
-// if (update.isUseColumnsBrackets()) {
-// buffer.append("(");
-// }
-// for (int i = 0; i < update.getColumns().size(); i++) {
-// if (i != 0) {
-// buffer.append(", ");
-// }
-// Column column = update.getColumns().get(i);
-// column.accept(expressionVisitor);
-// }
-// if (update.isUseColumnsBrackets()) {
-// buffer.append(")");
-// }
-// buffer.append(" = ");
-// buffer.append("(");
-// Select select = update.getSelect();
-// select.getSelectBody().accept(selectVisitor);
-// buffer.append(")");
-// }
-
if (update.getFromItem() != null) {
buffer.append(" FROM ").append(update.getFromItem());
if (update.getJoins() != null) {
diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
index caa931d61..ec23fa8ee 100644
--- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
+++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
@@ -1114,6 +1114,7 @@ Update Update( List with ):
UpdateSet updateSet = null;
Column tableColumn = null;
+ SubSelect subSelect;
Expression valueExpression = null;
ExpressionList expressionList;
Expression where = null;
@@ -1130,31 +1131,44 @@ Update Update( List with ):
(
- LOOKAHEAD(3) (
- tableColumn=Column() "=" valueExpression=SimpleExpression() { update.addUpdateSet(tableColumn, valueExpression); }
- ("," tableColumn=Column() "=" valueExpression=SimpleExpression() { update.addUpdateSet(tableColumn, valueExpression); } )*
- )
+ LOOKAHEAD(3) tableColumn=Column() "=" valueExpression=SimpleExpression() { update.addUpdateSet(tableColumn, valueExpression); }
+ ("," tableColumn=Column() "=" valueExpression=SimpleExpression() { update.addUpdateSet(tableColumn, valueExpression); } )*
|
(
{ updateSet = new UpdateSet(); update.addUpdateSet(updateSet); }
- [ "(" { updateSet.setUsingBrackets(true); } ]
+ [ LOOKAHEAD(2) "(" { updateSet.setUsingBracketsForColumns(true); } ]
tableColumn=Column() { updateSet.add(tableColumn); }
- ("," tableColumn=Column() { updateSet.add(tableColumn); } )*
- [ ")" ]
+ ( LOOKAHEAD(2) "," tableColumn=Column() { updateSet.add(tableColumn); } )*
+ [ LOOKAHEAD(2) ")" ]
"="
- expressionList = ComplexExpressionList() { updateSet.add(expressionList); }
(
- ","
- tableColumn=Column() { updateSet = new UpdateSet(tableColumn); update.addUpdateSet(updateSet); }
- ("," tableColumn=Column() { updateSet.add(tableColumn); } )*
+ LOOKAHEAD(3) subSelect=SubSelect() { updateSet.add(subSelect.withUseBrackets(false)); }
+ |
+ LOOKAHEAD(3) "(" expressionList = ComplexExpressionList() { updateSet.setUsingBracketsForValues(true); updateSet.add(expressionList); } ")"
+ |
+ valueExpression = Expression() { updateSet.add(valueExpression); }
+ )
+
+ (
+ "," { updateSet = new UpdateSet(); update.addUpdateSet(updateSet); }
+
+ [ LOOKAHEAD(2) "(" { updateSet.setUsingBracketsForColumns(true); } ]
+ tableColumn=Column() { updateSet.add(tableColumn); }
+ ( LOOKAHEAD(2) "," tableColumn=Column() { updateSet.add(tableColumn); } )*
+ [ LOOKAHEAD(2) ")" ]
"="
- "("
- expressionList = ComplexExpressionList() { updateSet.add(expressionList); }
- ")"
+
+ (
+ LOOKAHEAD(3) subSelect=SubSelect() { updateSet.add(subSelect.withUseBrackets(false)); }
+ |
+ LOOKAHEAD(3) "(" expressionList = ComplexExpressionList() { updateSet.setUsingBracketsForValues(true); updateSet.add(expressionList); } ")"
+ |
+ valueExpression = Expression() { updateSet.add(valueExpression); }
+ )
) *
)
)
@@ -1815,12 +1829,12 @@ PlainSelect PlainSelect() #PlainSelect:
selectItems=SelectItemsList()
[intoTables = IntoClause() { plainSelect.setIntoTables(intoTables); } ]
- [
+ [ LOOKAHEAD(2)
fromItem=FromItem()
joins=JoinsList() ]
[ ksqlWindow=KSQLWindowClause() { plainSelect.setKsqlWindow(ksqlWindow); } ]
- [ where=WhereClause() { plainSelect.setWhere(where); }]
+ [ LOOKAHEAD(2) where=WhereClause() { plainSelect.setWhere(where); }]
[ oracleHierarchicalQueryClause=OracleHierarchicalQueryClause() { plainSelect.setOracleHierarchical(oracleHierarchicalQueryClause); } ]
[ groupBy=GroupByColumnReferences() { plainSelect.setGroupByElement(groupBy); }]
[ having=Having() { plainSelect.setHaving(having); }]
@@ -1877,7 +1891,7 @@ SelectBody SetOperationList() #SetOperationList: {
)*
- [orderByElements=OrderByElements() {list.setOrderByElements(orderByElements);} ]
+ [ LOOKAHEAD(2) orderByElements=OrderByElements() {list.setOrderByElements(orderByElements);} ]
[LOOKAHEAD() limit=LimitWithOffset() {list.setLimit(limit);} ]
[LOOKAHEAD() offset = Offset() { list.setOffset(offset);} ]
[LOOKAHEAD() fetch = Fetch() { list.setFetch(fetch);} ]
@@ -1992,7 +2006,7 @@ List SelectItemsList():
SelectItem selectItem = null;
}
{
- selectItem=SelectItem() { selectItemsList.add(selectItem); } ("," selectItem=SelectItem() { selectItemsList.add(selectItem); } )*
+ selectItem=SelectItem() { selectItemsList.add(selectItem); } ( LOOKAHEAD(2) "," selectItem=SelectItem() { selectItemsList.add(selectItem); } )*
{ return selectItemsList; }
}
@@ -2280,7 +2294,7 @@ List IntoClause():
Table table;
}
{
- table=Table() { tables.add(table); } ("," table=Table() { tables.add(table); } )*
+ table=Table() { tables.add(table); } ( LOOKAHEAD(2) "," table=Table() { tables.add(table); } )*
{
return tables;
}
@@ -2432,7 +2446,7 @@ List JoinsList():
Join join = null;
}
{
- (join=JoinerExpression() { joinsList.add(join); })*
+ ( LOOKAHEAD(2) join=JoinerExpression() { joinsList.add(join); })*
{ return joinsList; }
}
@@ -2655,7 +2669,7 @@ List OrderByElements():
}
{
[ ] orderByElement=OrderByElement() { orderByList.add(orderByElement); }
- ("," orderByElement=OrderByElement() { orderByList.add(orderByElement); } )*
+ ( LOOKAHEAD(2) "," orderByElement=OrderByElement() { orderByList.add(orderByElement); } )*
{
return orderByList;
}
@@ -4959,7 +4973,7 @@ CreateTable CreateTable():
// see https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_7002.htm#i2126725
// table properties , all these are optional
[ rowMovement = RowMovement() { createTable.setRowMovement(rowMovement); }]
- [ select = SelectWithWithItems( ) { createTable.setSelect(select, false); }]
+ [ select = SelectWithWithItems( ) { createTable.setSelect(select, fa
[
( LOOKAHEAD("(" Table() ")") "(" likeTable=Table() { createTable.setLikeTable(likeTable, true); } ")"
| likeTable=Table() { createTable.setLikeTable(likeTable, false); } )
diff --git a/src/test/java/net/sf/jsqlparser/statement/ExplainTest.java b/src/test/java/net/sf/jsqlparser/statement/ExplainTest.java
index f146f239b..3239a6780 100644
--- a/src/test/java/net/sf/jsqlparser/statement/ExplainTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/ExplainTest.java
@@ -65,5 +65,8 @@ public void getOption_returnsValues() throws JSQLParserException {
ExplainStatement.Option buffers = explain.getOption(ExplainStatement.OptionType.BUFFERS);
assertThat(buffers).isNotNull().extracting(ExplainStatement.Option::getValue).isEqualTo("FALSE");
+
+ explain = (ExplainStatement) CCJSqlParserUtil.parse("EXPLAIN SELECT * FROM mytable");
+ assertThat(explain.getOption(ExplainStatement.OptionType.ANALYZE)).isNull();
}
}
diff --git a/src/test/java/net/sf/jsqlparser/statement/IfElseStatementTest.java b/src/test/java/net/sf/jsqlparser/statement/IfElseStatementTest.java
index ff71a2f4e..a2aa90e6f 100644
--- a/src/test/java/net/sf/jsqlparser/statement/IfElseStatementTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/IfElseStatementTest.java
@@ -82,7 +82,7 @@ public void testObjectBuilder() throws JSQLParserException {
}
@Test
- public void testValidation() throws JSQLParserException {
+ public void testValidation() {
String sqlStr = "IF OBJECT_ID('tOrigin', 'U') IS NOT NULL DROP TABLE tOrigin1;";
List errors =
Validation.validate(Arrays.asList(DatabaseType.SQLSERVER, FeaturesAllowed.DROP), sqlStr);
diff --git a/src/test/java/net/sf/jsqlparser/statement/ResetStatementTest.java b/src/test/java/net/sf/jsqlparser/statement/ResetStatementTest.java
index e64c709bd..745348d41 100644
--- a/src/test/java/net/sf/jsqlparser/statement/ResetStatementTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/ResetStatementTest.java
@@ -10,6 +10,7 @@
package net.sf.jsqlparser.statement;
import net.sf.jsqlparser.JSQLParserException;
+import org.junit.Assert;
import org.junit.Test;
import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
@@ -25,4 +26,14 @@ public void tesResetAll() throws JSQLParserException {
assertSqlCanBeParsedAndDeparsed("RESET ALL");
}
+ @Test
+ public void testObject() {
+ ResetStatement resetStatement=new ResetStatement();
+ Assert.assertNotNull(resetStatement.getName());
+
+ resetStatement.add("something");
+ resetStatement.setName("somethingElse");
+ Assert.assertEquals("somethingElse", resetStatement.getName());
+ }
+
}
diff --git a/src/test/java/net/sf/jsqlparser/statement/RollbackStatementTest.java b/src/test/java/net/sf/jsqlparser/statement/RollbackStatementTest.java
new file mode 100644
index 000000000..5d72bd0d1
--- /dev/null
+++ b/src/test/java/net/sf/jsqlparser/statement/RollbackStatementTest.java
@@ -0,0 +1,30 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2021 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.statement;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class RollbackStatementTest {
+
+ @Test
+ public void testObject() {
+ RollbackStatement rollbackStatement = new RollbackStatement()
+ .withUsingWorkKeyword(true)
+ .withUsingSavepointKeyword(true)
+ .withSavepointName("mySavePoint")
+ .withForceDistributedTransactionIdentifier("$ForceDistributedTransactionIdentifier");
+
+ Assert.assertTrue(rollbackStatement.isUsingSavepointKeyword());
+ Assert.assertEquals("mySavePoint", rollbackStatement.getSavepointName());
+ Assert.assertEquals("$ForceDistributedTransactionIdentifier", rollbackStatement.getForceDistributedTransactionIdentifier());
+ }
+
+}
diff --git a/src/test/java/net/sf/jsqlparser/statement/SetStatementTest.java b/src/test/java/net/sf/jsqlparser/statement/SetStatementTest.java
index c99220e37..bf55cd34f 100644
--- a/src/test/java/net/sf/jsqlparser/statement/SetStatementTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/SetStatementTest.java
@@ -11,8 +11,13 @@
import net.sf.jsqlparser.JSQLParserException;
import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
+
+import net.sf.jsqlparser.expression.StringValue;
+import org.junit.Assert;
import org.junit.Test;
+import java.util.Collections;
+
/**
*
* @author toben
@@ -57,4 +62,13 @@ public void tesLocalWithEq() throws JSQLParserException {
public void testValueOnIssue927() throws JSQLParserException {
assertSqlCanBeParsedAndDeparsed("SET standard_conforming_strings = on");
}
+
+ @Test
+ public void testObject() {
+ SetStatement setStatement = new SetStatement();
+ setStatement.add("standard_conforming_strings", Collections.singletonList(new StringValue("ON")), false);
+ setStatement.withUseEqual(0, true).remove(0);
+
+ Assert.assertEquals(0, setStatement.getCount());
+ }
}
diff --git a/src/test/java/net/sf/jsqlparser/statement/StatementsTest.java b/src/test/java/net/sf/jsqlparser/statement/StatementsTest.java
index 5ae82d230..4f8529e6b 100644
--- a/src/test/java/net/sf/jsqlparser/statement/StatementsTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/StatementsTest.java
@@ -67,7 +67,10 @@ public void testStatementsProblem() throws JSQLParserException {
@Test
public void testStatementsErrorRecovery() throws JSQLParserException, ParseException {
- String sqls = "select * from mytable; select * from;";
+ // "SELECT *" and "SELECT 1,2" are valid statements and so would return a correct SELECT object
+ // String sqls = "select * from mytable; select * from;";
+ String sqls = "select * from mytable; select from;";
+
CCJSqlParser parser = new CCJSqlParser(new StringProvider(sqls));
parser.setErrorRecovery(true);
Statements parseStatements = parser.Statements();
@@ -75,6 +78,7 @@ public void testStatementsErrorRecovery() throws JSQLParserException, ParseExcep
assertEquals(2, parseStatements.getStatements().size());
assertTrue(parseStatements.getStatements().get(0) instanceof Select);
+
assertNull(parseStatements.getStatements().get(1));
}
@@ -93,7 +97,10 @@ public void testStatementsErrorRecovery2() throws JSQLParserException, ParseExce
@Test
public void testStatementsErrorRecovery3() throws JSQLParserException, ParseException {
- String sqls = "select * from mytable; select * from;select * from mytable2";
+ // "SELECT *" and "SELECT 1, 2" are valid SELECT statements
+ // String sqls = "select * from mytable; select * from;select * from mytable2";
+ String sqls = "select * from mytable; select from;select * from mytable2";
+
CCJSqlParser parser = new CCJSqlParser(new StringProvider(sqls));
parser.setErrorRecovery(true);
Statements parseStatements = parser.Statements();
diff --git a/src/test/java/net/sf/jsqlparser/statement/alter/AlterSessionTest.java b/src/test/java/net/sf/jsqlparser/statement/alter/AlterSessionTest.java
index 7b61b4a07..6ca0fd408 100644
--- a/src/test/java/net/sf/jsqlparser/statement/alter/AlterSessionTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/alter/AlterSessionTest.java
@@ -11,8 +11,12 @@
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.test.TestUtils;
+import org.junit.Assert;
import org.junit.Test;
+import java.util.Arrays;
+import java.util.Collections;
+
public class AlterSessionTest {
@Test
public void testAlterSessionAdvise() throws JSQLParserException {
@@ -64,4 +68,25 @@ public void testAlterSessionSet() throws JSQLParserException {
TestUtils.assertSqlCanBeParsedAndDeparsed("ALTER SESSION SET ddl_lock_timeout=7200", true);
TestUtils.assertSqlCanBeParsedAndDeparsed("ALTER SESSION SET ddl_lock_timeout = 7200", true);
}
+
+
+ @Test
+ public void testAlterSessionResumable() throws JSQLParserException {
+ TestUtils.assertSqlCanBeParsedAndDeparsed("ALTER SESSION ENABLE RESUMABLE", true);
+ TestUtils.assertSqlCanBeParsedAndDeparsed("ALTER SESSION DISABLE RESUMABLE", true);
+ }
+
+ @Test
+ public void testObject() {
+ AlterSession alterSession = new AlterSession(AlterSessionOperation.FORCE_PARALLEL_QUERY, Collections.emptyList());
+ Assert.assertEquals(AlterSessionOperation.FORCE_PARALLEL_QUERY, alterSession.getOperation());
+
+ alterSession.setOperation(AlterSessionOperation.DISABLE_PARALLEL_DML);
+ Assert.assertEquals(AlterSessionOperation.DISABLE_PARALLEL_DML, alterSession.getOperation());
+
+ Assert.assertEquals(0, alterSession.getParameters().size());
+
+ alterSession.setParameters(Arrays.asList("PARALLEL", "6"));
+ Assert.assertEquals(2, alterSession.getParameters().size());
+ }
}
diff --git a/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java b/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java
index 5a8bb365b..07a176db2 100644
--- a/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/create/CreateTableTest.java
@@ -845,4 +845,10 @@ public void testCreateTableIssue1230() throws JSQLParserException {
assertSqlCanBeParsedAndDeparsed(
"CREATE TABLE TABLE_HISTORY (ID bigint generated by default as identity, CREATED_AT timestamp not null, TEXT varchar (255), primary key (ID))");
}
+
+ @Test
+ public void testCreateUnionIssue1309() throws JSQLParserException {
+ assertSqlCanBeParsedAndDeparsed(
+ "CREATE TABLE temp.abc AS (SELECT c FROM t1) UNION (SELECT c FROM t2)");
+ }
}
diff --git a/src/test/java/net/sf/jsqlparser/statement/create/synonym/CreateSynonymTest.java b/src/test/java/net/sf/jsqlparser/statement/create/synonym/CreateSynonymTest.java
index 74ad5248f..0f3641bd2 100644
--- a/src/test/java/net/sf/jsqlparser/statement/create/synonym/CreateSynonymTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/create/synonym/CreateSynonymTest.java
@@ -11,7 +11,9 @@
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
+import net.sf.jsqlparser.schema.Synonym;
import org.assertj.core.api.Assertions;
+import org.junit.Assert;
import org.junit.Test;
import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
@@ -51,5 +53,8 @@ public void synonymAttributes() throws Exception {
Assertions.assertThat(createSynonym.isPublicSynonym()).isTrue();
Assertions.assertThat(createSynonym.getSynonym().getFullyQualifiedName()).isEqualTo("TBL_TABLE_NAME");
Assertions.assertThat(createSynonym.getFor()).isEqualTo("SCHEMA.T_TBL_NAME");
+
+ Assert.assertEquals(2, createSynonym.getForList().size());
+ Assert.assertEquals("NEW_TBL_TABLE_NAME", createSynonym.withSynonym(new Synonym().withName("NEW_TBL_TABLE_NAME")).getSynonym().getName());
}
}
diff --git a/src/test/java/net/sf/jsqlparser/statement/show/ShowTablesStatementTest.java b/src/test/java/net/sf/jsqlparser/statement/show/ShowTablesStatementTest.java
index 535759351..e280cb000 100644
--- a/src/test/java/net/sf/jsqlparser/statement/show/ShowTablesStatementTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/show/ShowTablesStatementTest.java
@@ -9,6 +9,10 @@
*/
package net.sf.jsqlparser.statement.show;
+import net.sf.jsqlparser.JSQLParserException;
+import net.sf.jsqlparser.parser.CCJSqlParserUtil;
+import net.sf.jsqlparser.test.TestUtils;
+import org.junit.Assert;
import org.junit.Test;
import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
@@ -44,4 +48,18 @@ public void showTablesLikeExpression() throws Exception {
public void showTablesWhereExpression() throws Exception {
assertSqlCanBeParsedAndDeparsed("SHOW TABLES WHERE table_name = 'FOO'");
}
+
+ @Test
+ public void testObject() throws JSQLParserException, JSQLParserException {
+ ShowTablesStatement showTablesStatement = (ShowTablesStatement) CCJSqlParserUtil.parse("SHOW TABLES WHERE table_name = 'FOO'");
+ Assert.assertEquals(0, showTablesStatement.getModifiers().size());
+ TestUtils.assertExpressionCanBeDeparsedAs(showTablesStatement.getWhereCondition(), "table_name = 'FOO'");
+
+ showTablesStatement = (ShowTablesStatement) CCJSqlParserUtil.parse("SHOW FULL TABLES IN db_name");
+ Assert.assertEquals(1, showTablesStatement.getModifiers().size());
+ Assert.assertEquals(ShowTablesStatement.SelectionMode.IN, showTablesStatement.getSelectionMode());
+
+ showTablesStatement = (ShowTablesStatement) CCJSqlParserUtil.parse("SHOW TABLES LIKE '%FOO%'");
+ TestUtils.assertExpressionCanBeDeparsedAs(showTablesStatement.getLikeExpression(), "'%FOO%'");
+ }
}
diff --git a/src/test/java/net/sf/jsqlparser/statement/update/UpdateTest.java b/src/test/java/net/sf/jsqlparser/statement/update/UpdateTest.java
index 565cd493a..8476b9bb1 100644
--- a/src/test/java/net/sf/jsqlparser/statement/update/UpdateTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/update/UpdateTest.java
@@ -20,6 +20,9 @@
import static net.sf.jsqlparser.test.TestUtils.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+
+import net.sf.jsqlparser.parser.CCJSqlParserUtil;
+import org.junit.Assert;
import org.junit.Test;
public class UpdateTest {
@@ -191,44 +194,58 @@ public void testWith() throws JSQLParserException {
@Test
public void testUpdateSetsIssue1316() throws JSQLParserException {
- String statement =
+ String sqlStr =
"update test\n" +
"set (a, b) = (select '1', '2')";
- assertSqlCanBeParsedAndDeparsed(statement, true);
+ assertSqlCanBeParsedAndDeparsed(sqlStr, true);
+
+ sqlStr =
+ "update test\n" +
+ "set a = '1'" +
+ " , b = '2'";
+ assertSqlCanBeParsedAndDeparsed(sqlStr, true);
- statement =
+ sqlStr =
"update test\n" +
"set (a, b) = ('1', '2')";
- assertSqlCanBeParsedAndDeparsed(statement, true);
+ assertSqlCanBeParsedAndDeparsed(sqlStr, true);
- statement =
+ sqlStr =
"update test\n" +
- "set (a, b) = values ('1', '2')";
- assertSqlCanBeParsedAndDeparsed(statement, true);
+ "set (a, b) = (values ('1', '2'))";
+ assertSqlCanBeParsedAndDeparsed(sqlStr, true);
- statement =
+ sqlStr =
"update test\n" +
"set (a, b) = (1, (select 2))";
- assertSqlCanBeParsedAndDeparsed(statement, true);
-
- statement =
- "UPDATE\n" +
- "prpjpaymentbill b\n" +
- "SET\n" +
- "(\n" +
- "b.packagecode,\n" +
- "b.packageremark,\n" +
- "b.agentcode\n" +
- ") =\n" +
- "(SELECT\n" +
- "p.payrefreason,\n" +
- "p.classcode,\n" +
- "p.riskcode\n" +
- "FROM\n" +
- "prpjcommbill p where p.policertiid='SDDH200937010330006366' ),\n" +
- "b.payrefnotype = '05',\n" +
- "b.packageunit = '4101170402'\n" +
- "where b.payrefno='B370202091026000005' ";
- assertSqlCanBeParsedAndDeparsed(statement, true);
+ assertSqlCanBeParsedAndDeparsed(sqlStr, true);
+
+ sqlStr =
+ "UPDATE prpjpaymentbill b\n" +
+ "SET ( b.packagecode\n" +
+ " , b.packageremark\n" +
+ " , b.agentcode ) = ( SELECT p.payrefreason\n" +
+ " , p.classcode\n" +
+ " , p.riskcode\n" +
+ " FROM prpjcommbill p\n" +
+ " WHERE p.policertiid = 'SDDH200937010330006366' ) -- this is supposed to be UpdateSet 1\n" +
+ " , b.payrefnotype = '05' -- this is supposed to be UpdateSet 2\n" +
+ " , b.packageunit = '4101170402' -- this is supposed to be UpdateSet 3\n" +
+ "WHERE b.payrefno = 'B370202091026000005'";
+
+
+ assertSqlCanBeParsedAndDeparsed(sqlStr, true);
+
+ Update update = (Update) CCJSqlParserUtil.parse(sqlStr);
+ Assert.assertEquals(3, update.getUpdateSets().size());
+
+ Assert.assertEquals(3, update.getUpdateSets().get(0).getColumns().size());
+ Assert.assertEquals(1, update.getUpdateSets().get(0).getExpressions().size());
+
+ Assert.assertEquals(1, update.getUpdateSets().get(1).getColumns().size());
+ Assert.assertEquals(1, update.getUpdateSets().get(1).getExpressions().size());
+
+ Assert.assertEquals(1, update.getUpdateSets().get(2).getColumns().size());
+ Assert.assertEquals(1, update.getUpdateSets().get(2).getExpressions().size());
}
}
diff --git a/src/test/java/net/sf/jsqlparser/statement/values/ValuesTest.java b/src/test/java/net/sf/jsqlparser/statement/values/ValuesTest.java
index aa32bc543..46d71a1bc 100644
--- a/src/test/java/net/sf/jsqlparser/statement/values/ValuesTest.java
+++ b/src/test/java/net/sf/jsqlparser/statement/values/ValuesTest.java
@@ -15,6 +15,7 @@
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.statement.Statement;
+import net.sf.jsqlparser.statement.StatementVisitorAdapter;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SetOperationList;
@@ -22,6 +23,8 @@
import org.junit.Test;
+import java.util.Arrays;
+
public class ValuesTest {
@Test
@@ -48,4 +51,12 @@ public void testDuplicateKey() throws JSQLParserException {
public void testComplexWithQueryIssue561() throws JSQLParserException {
assertSqlCanBeParsedAndDeparsed("WITH split (word, str, hascomma) AS (VALUES ('', 'Auto,A,1234444', 1) UNION ALL SELECT substr(str, 0, CASE WHEN instr(str, ',') THEN instr(str, ',') ELSE length(str) + 1 END), ltrim(substr(str, instr(str, ',')), ','), instr(str, ',') FROM split WHERE hascomma) SELECT trim(word) FROM split WHERE word != ''");
}
+
+ @Test
+ public void testObject() {
+ ValuesStatement valuesStatement=new ValuesStatement().addExpressions(new StringValue("1"), new StringValue("2"));
+ valuesStatement.addExpressions(Arrays.asList(new StringValue("3"), new StringValue("4")));
+
+ valuesStatement.accept(new StatementVisitorAdapter());
+ }
}
diff --git a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java
index bc8e2954d..ee5e5e408 100644
--- a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java
+++ b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java
@@ -16,6 +16,7 @@
import java.util.ArrayList;
import java.util.List;
+import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.update.UpdateSet;
import org.junit.Before;
import org.junit.Test;
@@ -31,7 +32,6 @@
import net.sf.jsqlparser.statement.IfElseStatement;
import net.sf.jsqlparser.statement.SetStatement;
import net.sf.jsqlparser.statement.delete.Delete;
-import net.sf.jsqlparser.statement.drop.Drop;
import net.sf.jsqlparser.statement.execute.Execute;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.replace.Replace;
@@ -368,12 +368,9 @@ public void shouldUseProvidedDeparsersWhenDeParsingUpsertWithExpressionList() th
@Test
@SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert")
- public void shouldUseProvidedDeparsersWhenDeParsingIfThenStatement() {
- Expression condition = mock(Expression.class);
- Drop ifStatement = mock(Drop.class);
-
- IfElseStatement ifElseStatement = new IfElseStatement(condition, ifStatement);
-
+ public void shouldUseProvidedDeparsersWhenDeParsingIfThenStatement() throws JSQLParserException {
+ String sqlStr = "IF OBJECT_ID('tOrigin', 'U') IS NOT NULL DROP TABLE tOrigin1";
+ IfElseStatement ifElseStatement = (IfElseStatement) CCJSqlParserUtil.parse(sqlStr);
statementDeParser.deParse(ifElseStatement);
}