collection = Optional.ofNullable(getReturningExpressionList()).orElseGet(ArrayList::new);
collection.addAll(returningExpressionList);
return this.withReturningExpressionList(collection);
}
diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/InsertConflictAction.java b/src/main/java/net/sf/jsqlparser/statement/insert/InsertConflictAction.java
new file mode 100644
index 000000000..32d9313eb
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/statement/insert/InsertConflictAction.java
@@ -0,0 +1,108 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2022 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.statement.insert;
+
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.schema.Column;
+import net.sf.jsqlparser.statement.update.UpdateSet;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Objects;
+
+/**
+ * https://www.postgresql.org/docs/current/sql-insert.html
+ *
+ * conflict_action is one of:
+ *
+ * DO NOTHING
+ * DO UPDATE SET { column_name = { expression | DEFAULT } |
+ * ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |
+ * ( column_name [, ...] ) = ( sub-SELECT )
+ * } [, ...]
+ * [ WHERE condition ]
+ *
+ */
+
+public class InsertConflictAction {
+ ConflictActionType conflictActionType;
+
+ private final ArrayList updateSets = new ArrayList<>();
+ Expression whereExpression;
+
+ public InsertConflictAction(ConflictActionType conflictActionType) {
+ this.conflictActionType = Objects.requireNonNull(conflictActionType, "The Conflict Action Type is mandatory and must not be Null.");
+ }
+
+ public ConflictActionType getConflictActionType() {
+ return conflictActionType;
+ }
+
+ public void setConflictActionType(ConflictActionType conflictActionType) {
+ this.conflictActionType = Objects.requireNonNull(conflictActionType, "The Conflict Action Type is mandatory and must not be Null.");
+ }
+
+ public InsertConflictAction withConflictActionType(ConflictActionType conflictActionType) {
+ setConflictActionType(conflictActionType);
+ return this;
+ }
+
+ public InsertConflictAction addUpdateSet(Column column, Expression expression) {
+ this.updateSets.add(new UpdateSet(column, expression));
+ return this;
+ }
+
+ public InsertConflictAction addUpdateSet(UpdateSet updateSet) {
+ this.updateSets.add(updateSet);
+ return this;
+ }
+
+ public InsertConflictAction withUpdateSets(Collection updateSets) {
+ this.updateSets.clear();
+ this.updateSets.addAll(updateSets);
+ return this;
+ }
+
+ public Expression getWhereExpression() {
+ return whereExpression;
+ }
+
+ public void setWhereExpression(Expression whereExpression) {
+ this.whereExpression = whereExpression;
+ }
+
+ public InsertConflictAction withWhereExpression(Expression whereExpression) {
+ setWhereExpression(whereExpression);
+ return this;
+ }
+
+ @SuppressWarnings("PMD.SwitchStmtsShouldHaveDefault")
+ public StringBuilder appendTo(StringBuilder builder) {
+ switch (conflictActionType) {
+ case DO_NOTHING:
+ builder.append(" DO NOTHING");
+ break;
+ case DO_UPDATE:
+ builder.append(" DO UPDATE ");
+ UpdateSet.appendUpdateSetsTo(builder, updateSets);
+
+ if (whereExpression!=null) {
+ builder.append(" WHERE ").append(whereExpression);
+ }
+ break;
+ }
+ return builder;
+ }
+
+ @Override
+ public String toString() {
+ return appendTo(new StringBuilder()).toString();
+ }
+}
diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/InsertConflictTarget.java b/src/main/java/net/sf/jsqlparser/statement/insert/InsertConflictTarget.java
new file mode 100644
index 000000000..0f8e9808f
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/statement/insert/InsertConflictTarget.java
@@ -0,0 +1,121 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2022 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.statement.insert;
+
+import net.sf.jsqlparser.expression.Expression;
+
+/**
+ * https://www.postgresql.org/docs/current/sql-insert.html
+ *
+ * conflict_target can be one of:
+ *
+ * ( { index_column_name | ( index_expression ) } [ COLLATE collation ] [ opclass ] [, ...] ) [ WHERE index_predicate ]
+ * ON CONSTRAINT constraint_name
+ *
+ * Currently, COLLATE is not supported yet.
+ */
+public class InsertConflictTarget {
+
+ String indexColumnName;
+ Expression indexExpression;
+ Expression whereExpression;
+ String constraintName;
+
+ public InsertConflictTarget(String indexColumnName, Expression indexExpression, Expression whereExpression, String constraintName) {
+ this.indexColumnName = indexColumnName;
+ this.indexExpression = indexExpression;
+
+ this.whereExpression = whereExpression;
+ this.constraintName = constraintName;
+ }
+
+ public String getIndexColumnName() {
+ return indexColumnName;
+ }
+
+ public void setIndexColumnName(String indexColumnName) {
+ this.indexColumnName = indexColumnName;
+ this.indexExpression = null;
+ }
+
+ public InsertConflictTarget withIndexColumnName(String indexColumnName) {
+ setIndexColumnName(indexColumnName);
+ return this;
+ }
+
+ public Expression getIndexExpression() {
+ return indexExpression;
+ }
+
+ public void setIndexExpression(Expression indexExpression) {
+ this.indexExpression = indexExpression;
+ this.indexColumnName = null;
+ }
+
+ public InsertConflictTarget withIndexExpression(Expression indexExpression) {
+ setIndexExpression(indexExpression);
+ return this;
+ }
+
+ public Expression getWhereExpression() {
+ return whereExpression;
+ }
+
+ public void setWhereExpression(Expression whereExpression) {
+ this.whereExpression = whereExpression;
+ }
+
+ public InsertConflictTarget withWhereExpression(Expression whereExpression) {
+ setWhereExpression(whereExpression);
+ return this;
+ }
+
+ public String getConstraintName() {
+ return constraintName;
+ }
+
+ public void setConstraintName(String constraintName) {
+ this.constraintName = constraintName;
+ }
+
+ public InsertConflictTarget withConstraintName(String constraintName) {
+ setConstraintName(constraintName);
+ return this;
+ }
+
+ public StringBuilder appendTo(StringBuilder builder) {
+ if (constraintName==null) {
+ builder.append(" ( ");
+
+ //@todo: Index Expression is not supported yet
+ //if (indexColumnName != null) {
+ builder.append(indexColumnName);
+ //} else {
+ // builder.append(" ( ").append(indexExpression).append(" )");
+ //}
+ builder.append(" ");
+
+ //@todo: Collate is not supported yet
+
+ builder.append(") ");
+
+ if (whereExpression != null) {
+ builder.append(" WHERE ").append(whereExpression);
+ }
+ } else {
+ builder.append(" ON CONSTRAINT ").append(constraintName);
+ }
+ return builder;
+ }
+
+ public String toString() {
+ return appendTo(new StringBuilder()).toString();
+ }
+}
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java b/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java
index 4cc9c25c9..15c4f17c5 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java
@@ -95,7 +95,14 @@ public String toString() {
if (groupByExpressions.isUsingBrackets()) {
b.append(" )");
}
- } else if (groupingSets.size() > 0) {
+ } else if (groupByExpressions.isUsingBrackets()) {
+ b.append("()");
+ }
+
+ if (groupingSets.size() > 0) {
+ if (b.charAt(b.length() - 1) != ' ') {
+ b.append(' ');
+ }
b.append("GROUPING SETS (");
boolean first = true;
for (Object o : groupingSets) {
@@ -112,10 +119,6 @@ public String toString() {
}
}
b.append(")");
- } else {
- if (groupByExpressions.isUsingBrackets()) {
- b.append("()");
- }
}
return b.toString();
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Join.java b/src/main/java/net/sf/jsqlparser/statement/select/Join.java
index 4c6d74ffc..7c4200bef 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/Join.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/Join.java
@@ -304,10 +304,12 @@ public String toString() {
} else if (isSimple()) {
builder.append(rightItem);
} else {
+ if (isNatural()) {
+ builder.append("NATURAL ");
+ }
+
if (isRight()) {
builder.append("RIGHT ");
- } else if (isNatural()) {
- builder.append("NATURAL ");
} else if (isFull()) {
builder.append("FULL ");
} else if (isLeft()) {
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java b/src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java
index ff1a174a9..6fc59b926 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java
@@ -532,28 +532,38 @@ public static String getStringList(List> list) {
* @return comma separated list of the elements in the list
*/
public static String getStringList(List> list, boolean useComma, boolean useBrackets) {
- StringBuilder ans = new StringBuilder();
- String comma = ",";
- if (!useComma) {
- comma = "";
- }
+ return appendStringListTo(new StringBuilder(), list, useComma, useBrackets).toString();
+ }
+
+ /**
+ * Append the toString out put of the objects in the List (that can be comma
+ * separated). If the List is null or empty an empty string is returned.
+ *
+ * @param list list of objects with toString methods
+ * @param useComma true if the list has to be comma separated
+ * @param useBrackets true if the list has to be enclosed in brackets
+ * @return comma separated list of the elements in the list
+ */
+ public static StringBuilder appendStringListTo(StringBuilder builder, List> list, boolean useComma, boolean useBrackets) {
if (list != null) {
+ String comma = useComma ? "," : "";
+
if (useBrackets) {
- ans.append("(");
+ builder.append("(");
}
- for (int i = 0; i < list.size(); i++) {
- ans.append(list.get(i)).append( i < list.size() - 1
- ? comma + " "
- : "" );
+ int size = list.size();
+ for (int i = 0; i < size; i++) {
+ builder.append(list.get(i)).append( i < size - 1
+ ? comma + " "
+ : "" );
}
if (useBrackets) {
- ans.append(")");
+ builder.append(")");
}
}
-
- return ans.toString();
+ return builder;
}
public PlainSelect withMySqlSqlCalcFoundRows(boolean mySqlCalcFoundRows) {
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Select.java b/src/main/java/net/sf/jsqlparser/statement/select/Select.java
index 7886f44f7..67a002777 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/Select.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/Select.java
@@ -23,6 +23,8 @@ public class Select implements Statement {
private SelectBody selectBody;
private List withItemsList;
+ private boolean useWithBrackets = false;
+
@Override
public void accept(StatementVisitor statementVisitor) {
statementVisitor.visit(this);
@@ -41,11 +43,27 @@ public void setSelectBody(SelectBody body) {
selectBody = body;
}
+ public void setUsingWithBrackets(boolean useWithBrackets) {
+ this.useWithBrackets = useWithBrackets;
+ }
+
+ public Select withUsingWithBrackets(boolean useWithBrackets) {
+ this.useWithBrackets = useWithBrackets;
+ return this;
+ }
+
+ public boolean isUsingWithBrackets() {
+ return this.useWithBrackets;
+ }
+
@Override
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
public String toString() {
StringBuilder retval = new StringBuilder();
if (withItemsList != null && !withItemsList.isEmpty()) {
+ if (useWithBrackets) {
+ retval.append("( ");
+ }
retval.append("WITH ");
for (Iterator iter = withItemsList.iterator(); iter.hasNext();) {
WithItem withItem = iter.next();
@@ -57,6 +75,9 @@ public String toString() {
}
}
retval.append(selectBody);
+ if (withItemsList != null && !withItemsList.isEmpty() && useWithBrackets) {
+ retval.append(" )");
+ }
return retval.toString();
}
diff --git a/src/main/java/net/sf/jsqlparser/statement/truncate/Truncate.java b/src/main/java/net/sf/jsqlparser/statement/truncate/Truncate.java
index 67d064249..9848c7799 100644
--- a/src/main/java/net/sf/jsqlparser/statement/truncate/Truncate.java
+++ b/src/main/java/net/sf/jsqlparser/statement/truncate/Truncate.java
@@ -18,6 +18,9 @@ public class Truncate implements Statement {
private Table table;
boolean cascade; // to support TRUNCATE TABLE ... CASCADE
+ boolean tableToken; // to support TRUNCATE without TABLE
+ boolean only; // to support TRUNCATE with ONLY
+
@Override
public void accept(StatementVisitor statementVisitor) {
statementVisitor.visit(this);
@@ -41,10 +44,42 @@ public void setCascade(boolean c) {
@Override
public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("TRUNCATE");
+ if (tableToken) {
+ sb.append(" TABLE");
+ }
+ if (only) {
+ sb.append(" ONLY");
+ }
+ sb.append(" ");
+ sb.append(table);
+
if (cascade) {
- return "TRUNCATE TABLE " + table + " CASCADE";
+ sb.append( " CASCADE");
}
- return "TRUNCATE TABLE " + table;
+ return sb.toString();
+ }
+
+ public boolean isTableToken() {
+ return tableToken;
+ }
+
+ public void setTableToken(boolean hasTable) {
+ this.tableToken = hasTable;
+ }
+
+ public boolean isOnly() {
+ return only;
+ }
+
+ public void setOnly(boolean only) {
+ this.only = only;
+ }
+
+ public Truncate withTableToken(boolean hasTableToken){
+ this.setTableToken(hasTableToken);
+ return this;
}
public Truncate withTable(Table table) {
@@ -56,4 +91,9 @@ public Truncate withCascade(boolean cascade) {
this.setCascade(cascade);
return this;
}
+ public Truncate withOnly(boolean only) {
+ this.setOnly(only);
+ return this;
+ }
}
+
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 33f703bb4..0da3fd3a4 100644
--- a/src/main/java/net/sf/jsqlparser/statement/update/Update.java
+++ b/src/main/java/net/sf/jsqlparser/statement/update/Update.java
@@ -19,6 +19,7 @@
import net.sf.jsqlparser.expression.OracleHint;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
+import net.sf.jsqlparser.statement.OutputClause;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.StatementVisitor;
import net.sf.jsqlparser.statement.select.*;
@@ -36,11 +37,20 @@ public class Update implements Statement {
private OracleHint oracleHint = null;
private List orderByElements;
private Limit limit;
- private boolean returningAllColumns = false;
- private List returningExpressionList = null;
+ private List returningExpressionList = null;
private UpdateModifierPriority modifierPriority;
private boolean modifierIgnore;
+ private OutputClause outputClause;
+
+ public OutputClause getOutputClause() {
+ return outputClause;
+ }
+
+ public void setOutputClause(OutputClause outputClause) {
+ this.outputClause = outputClause;
+ }
+
public ArrayList getUpdateSets() {
return updateSets;
}
@@ -219,19 +229,11 @@ public Limit getLimit() {
return limit;
}
- public boolean isReturningAllColumns() {
- return returningAllColumns;
- }
-
- public void setReturningAllColumns(boolean returningAllColumns) {
- this.returningAllColumns = returningAllColumns;
- }
-
- public List getReturningExpressionList() {
+ public List getReturningExpressionList() {
return returningExpressionList;
}
- public void setReturningExpressionList(List returningExpressionList) {
+ public void setReturningExpressionList(List returningExpressionList) {
this.returningExpressionList = returningExpressionList;
}
@@ -251,7 +253,6 @@ public void setModifierIgnore(boolean modifierIgnore) {
this.modifierIgnore = modifierIgnore;
}
-
@Override
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity", "PMD.ExcessiveMethodLength"})
public String toString() {
@@ -285,47 +286,13 @@ public String toString() {
}
}
}
- b.append(" SET ");
- int j = 0;
- for (UpdateSet updateSet : updateSets) {
- if (j > 0) {
- b.append(", ");
- }
+ UpdateSet.appendUpdateSetsTo(b, updateSets);
- if (updateSet.usingBracketsForColumns) {
- b.append("(");
- }
-
- for (int i = 0; i < updateSet.columns.size(); i++) {
- if (i > 0) {
- b.append(", ");
- }
- b.append(updateSet.columns.get(i));
- }
-
- 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 (outputClause != null) {
+ outputClause.appendTo(b);
}
+
if (fromItem != null) {
b.append(" FROM ").append(fromItem);
if (joins != null) {
@@ -350,9 +317,7 @@ public String toString() {
b.append(limit);
}
- if (isReturningAllColumns()) {
- b.append(" RETURNING *");
- } else if (getReturningExpressionList() != null) {
+ if (getReturningExpressionList() != null) {
b.append(" RETURNING ").append(PlainSelect.
getStringList(getReturningExpressionList(), true, false));
}
@@ -405,12 +370,7 @@ public Update withLimit(Limit limit) {
return this;
}
- public Update withReturningAllColumns(boolean returningAllColumns) {
- this.setReturningAllColumns(returningAllColumns);
- return this;
- }
-
- public Update withReturningExpressionList(List returningExpressionList) {
+ public Update withReturningExpressionList(List returningExpressionList) {
this.setReturningExpressionList(returningExpressionList);
return this;
}
@@ -430,36 +390,36 @@ public Update withExpressions(List expressions) {
return this;
}
- public Update withModifierPriority(UpdateModifierPriority modifierPriority){
+ public Update withModifierPriority(UpdateModifierPriority modifierPriority) {
this.setModifierPriority(modifierPriority);
return this;
}
- public Update withModifierIgnore(boolean modifierIgnore){
+ public Update withModifierIgnore(boolean modifierIgnore) {
this.setModifierIgnore(modifierIgnore);
return this;
}
public Update addColumns(Column... columns) {
- List collection = Optional.ofNullable(getColumns()).orElseGet(ArrayList::new);
+ List collection = new ArrayList<>(Optional.ofNullable(getColumns()).orElseGet(ArrayList::new));
Collections.addAll(collection, columns);
return this.withColumns(collection);
}
public Update addColumns(Collection extends Column> columns) {
- List collection = Optional.ofNullable(getColumns()).orElseGet(ArrayList::new);
+ List collection = new ArrayList<>(Optional.ofNullable(getColumns()).orElseGet(ArrayList::new));
collection.addAll(columns);
return this.withColumns(collection);
}
public Update addExpressions(Expression... expressions) {
- List collection = Optional.ofNullable(getExpressions()).orElseGet(ArrayList::new);
+ List collection = new ArrayList<>(Optional.ofNullable(getExpressions()).orElseGet(ArrayList::new));
Collections.addAll(collection, expressions);
return this.withExpressions(collection);
}
public Update addExpressions(Collection extends Expression> expressions) {
- List collection = Optional.ofNullable(getExpressions()).orElseGet(ArrayList::new);
+ List collection = new ArrayList<>(Optional.ofNullable(getExpressions()).orElseGet(ArrayList::new));
collection.addAll(expressions);
return this.withExpressions(collection);
}
@@ -500,14 +460,14 @@ public Update addOrderByElements(Collection extends OrderByElement> orderByEle
return this.withOrderByElements(collection);
}
- public Update addReturningExpressionList(SelectExpressionItem... returningExpressionList) {
- List collection = Optional.ofNullable(getReturningExpressionList()).orElseGet(ArrayList::new);
+ public Update addReturningExpressionList(SelectItem... returningExpressionList) {
+ List collection = Optional.ofNullable(getReturningExpressionList()).orElseGet(ArrayList::new);
Collections.addAll(collection, returningExpressionList);
return this.withReturningExpressionList(collection);
}
- public Update addReturningExpressionList(Collection extends SelectExpressionItem> returningExpressionList) {
- List collection = Optional.ofNullable(getReturningExpressionList()).orElseGet(ArrayList::new);
+ public Update addReturningExpressionList(Collection extends SelectItem> returningExpressionList) {
+ List collection = Optional.ofNullable(getReturningExpressionList()).orElseGet(ArrayList::new);
collection.addAll(returningExpressionList);
return this.withReturningExpressionList(collection);
}
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 3e6da1ba1..a25df6e5e 100644
--- a/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java
+++ b/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java
@@ -14,6 +14,7 @@
import net.sf.jsqlparser.schema.Column;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Objects;
public class UpdateSet {
@@ -84,4 +85,55 @@ public void add(ExpressionList expressionList) {
expressions.addAll(expressionList.getExpressions());
}
+ public final static StringBuilder appendUpdateSetsTo(StringBuilder builder, Collection updateSets) {
+ builder.append(" SET ");
+
+ int j = 0;
+ for (UpdateSet updateSet : updateSets) {
+ updateSet.appendTo(builder, j);
+ j++;
+ }
+ return builder;
+ }
+
+ @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPath"})
+ StringBuilder appendTo(StringBuilder builder, int j) {
+ if (j > 0) {
+ builder.append(", ");
+ }
+
+ if (usingBracketsForColumns) {
+ builder.append("(");
+ }
+
+ for (int i = 0; i < columns.size(); i++) {
+ if (i > 0) {
+ builder.append(", ");
+ }
+ builder.append(columns.get(i));
+ }
+
+ if (usingBracketsForColumns) {
+ builder.append(")");
+ }
+
+ builder.append(" = ");
+
+ if (usingBracketsForValues) {
+ builder.append("(");
+ }
+
+ for (int i = 0; i < expressions.size(); i++) {
+ if (i > 0) {
+ builder.append(", ");
+ }
+ builder.append(expressions.get(i));
+ }
+ if (usingBracketsForValues) {
+ builder.append(")");
+ }
+
+ return builder;
+ }
+
}
diff --git a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
index 32b316b58..945b163a1 100644
--- a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
+++ b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
@@ -27,6 +27,7 @@
import net.sf.jsqlparser.statement.alter.AlterSystemStatement;
import net.sf.jsqlparser.statement.alter.RenameTableStatement;
import net.sf.jsqlparser.statement.alter.sequence.AlterSequence;
+import net.sf.jsqlparser.statement.analyze.Analyze;
import net.sf.jsqlparser.statement.comment.Comment;
import net.sf.jsqlparser.statement.create.index.CreateIndex;
import net.sf.jsqlparser.statement.create.schema.CreateSchema;
@@ -686,6 +687,9 @@ public void visit(Replace replace) {
}
}
+ public void visit(Analyze analyze) {
+ visit(analyze.getTable());
+ }
@Override
public void visit(Drop drop) {
visit(drop.getName());
@@ -1032,6 +1036,11 @@ public void visit(AlterSystemStatement alterSystemStatement) {
// no tables involved in this statement
}
+ @Override
+ public void visit(UnsupportedStatement unsupportedStatement) {
+ // no tables involved in this statement
+ }
+
@Override
public void visit(GeometryDistance geometryDistance) {
visitBinaryExpression(geometryDistance);
diff --git a/src/main/java/net/sf/jsqlparser/util/cnfexpression/CNFConverter.java b/src/main/java/net/sf/jsqlparser/util/cnfexpression/CNFConverter.java
index 1238b7229..fbb4e8499 100644
--- a/src/main/java/net/sf/jsqlparser/util/cnfexpression/CNFConverter.java
+++ b/src/main/java/net/sf/jsqlparser/util/cnfexpression/CNFConverter.java
@@ -213,7 +213,6 @@ public class CNFConverter {
// notice temp1 will be settled as the root and temp2 will be
// settled as the dummy root.
private boolean isUsed = false;
- private CloneHelper clone = new CloneHelper();
private class Mule {
@@ -234,9 +233,8 @@ public static Expression convertToCNF(Expression expr) {
}
/**
- * this method takes an expression tree and converts that into a CNF form. Notice the 5 steps
- * shown above will turn into 5 different methods. For the sake of testing, I set them public.
- * return the converted expression.
+ * this method takes an expression tree and converts that into a CNF form. Notice the 5 steps shown above will turn
+ * into 5 different methods. For the sake of testing, I set them public. return the converted expression.
*
* @param express the original expression tree.
*/
@@ -260,21 +258,21 @@ private Expression convert(Expression express)
}
/**
- * this is the first step that rebuild the expression tree. Use the standard specified in the
- * above class. Traverse the original tree recursively and rebuild the tree from that.
+ * this is the first step that rebuild the expression tree. Use the standard specified in the above class. Traverse
+ * the original tree recursively and rebuild the tree from that.
*
* @param express the original expression tree.
*/
private void reorder(Expression express) {
- root = clone.modify(express);
+ root = CloneHelper.modify(express);
List list = new ArrayList();
list.add(root);
dummy = new MultiAndExpression(list);
}
/**
- * This method is used to deal with pushing not operators down. Since it needs an extra
- * parameter, I will create a new method to handle this.
+ * This method is used to deal with pushing not operators down. Since it needs an extra parameter, I will create a
+ * new method to handle this.
*/
private void pushNotDown() {
/* set the two temp parameters to their staring point. */
@@ -290,11 +288,10 @@ private void pushNotDown() {
}
/**
- * This method is the helper function to push not operators down. traverse the tree thoroughly,
- * when we meet the not operator. We only need to consider these three operators:
- * MultiAndOperator, MultiOrOperator, NotOperator. Handle them in a seperate way. when we finish
- * the traverse, the expression tree will have all the not operators pushed as downwards as they
- * could. In the method, I use two global variables: temp1 and temp2 to traverse the expression
+ * This method is the helper function to push not operators down. traverse the tree thoroughly, when we meet the not
+ * operator. We only need to consider these three operators: MultiAndOperator, MultiOrOperator, NotOperator. Handle
+ * them in a seperate way. when we finish the traverse, the expression tree will have all the not operators pushed
+ * as downwards as they could. In the method, I use two global variables: temp1 and temp2 to traverse the expression
* tree. Notice that temp2 will always be the parent of temp1.
*
* @param index the index of the children appeared in parents array.
@@ -322,8 +319,8 @@ private void pushNot(int index) {
}
/**
- * This function mainly deals with pushing not operators down. check the child. If it is not a
- * logic operator(and or or). stop at that point. Else use De Morgan law to push not downwards.
+ * This function mainly deals with pushing not operators down. check the child. If it is not a logic operator(and or
+ * or). stop at that point. Else use De Morgan law to push not downwards.
*
* @param index the index of the children appeared in parents array.
*/
@@ -386,10 +383,9 @@ private void handleNot(int index) {
}
/**
- * This method serves as dealing with the third step. It is used to put all the adjacent same
- * multi operators together. BFS the tree and do it node by node. In the end we will get the
- * tree where all the same multi operators store in the same odd level of the tree or in the
- * same even level of the tree.
+ * This method serves as dealing with the third step. It is used to put all the adjacent same multi operators
+ * together. BFS the tree and do it node by node. In the end we will get the tree where all the same multi operators
+ * store in the same odd level of the tree or in the same even level of the tree.
*/
@SuppressWarnings({"PMD.CyclomaticComplexity"})
private void gather() {
@@ -468,10 +464,10 @@ private void gather() {
}
/**
- * First, BFS the tree and gather all the or operators and their parents into a stack. Next, pop
- * them out and push the and operators under the or operators upwards(if there are). Do this
- * level by level, which means during each level we will call the gather() method to make the
- * tree uniform. When we move out of the stack. The expression tree shall be in CNF form.
+ * First, BFS the tree and gather all the or operators and their parents into a stack. Next, pop them out and push
+ * the and operators under the or operators upwards(if there are). Do this level by level, which means during each
+ * level we will call the gather() method to make the tree uniform. When we move out of the stack. The expression
+ * tree shall be in CNF form.
*/
private void pushAndUp() {
Queue queue = new LinkedList();
@@ -517,12 +513,11 @@ private void pushAndUp() {
}
/**
- * This helper function is used to deal with pushing and up: generally, pop the top element out
- * of the stack, use BFS to traverse the tree and push and up. It will case the expression tree
- * to have the and as the new root and multiple or as the children. Push them on the queue and
- * repeat the same process until the newly generated or operator does not have any and operators
- * in it(which means no elements will be added into the queue). when one level is finished,
- * regroup the tree. Do this until the stack is empty, the result will be the expression in CNF
+ * This helper function is used to deal with pushing and up: generally, pop the top element out of the stack, use
+ * BFS to traverse the tree and push and up. It will case the expression tree to have the and as the new root and
+ * multiple or as the children. Push them on the queue and repeat the same process until the newly generated or
+ * operator does not have any and operators in it(which means no elements will be added into the queue). when one
+ * level is finished, regroup the tree. Do this until the stack is empty, the result will be the expression in CNF
* form.
*
* @param stack the stack stores a list of combined data.
@@ -570,7 +565,7 @@ private void pushAnd(Stack stack) {
MultiAndExpression newand = new MultiAndExpression(list);
parents.setChild(parents.getIndex(children), newand);
for (int i = 0; i < and.size(); i++) {
- Expression temp = clone.shallowCopy(children);
+ Expression temp = CloneHelper.shallowCopy(children);
MultipleExpression mtemp = (MultipleExpression) temp;
mtemp.addChild(mtemp.size(), and.getChild(i));
newand.addChild(i, mtemp);
@@ -581,11 +576,10 @@ private void pushAnd(Stack stack) {
}
/**
- * This is the final step of the CNF conversion: now we have the Expression tree that has one
- * multiple and expression with a list of multiple or expression as the child. So we need to
- * convert the multiple expression back to the binary counterparts. Note the converted tree is
- * left inclined. Also I attach a parenthesis node before the or expression that is attached to
- * the and expression to make the generated result resembles the CNF form.
+ * This is the final step of the CNF conversion: now we have the Expression tree that has one multiple and
+ * expression with a list of multiple or expression as the child. So we need to convert the multiple expression back
+ * to the binary counterparts. Note the converted tree is left inclined. Also I attach a parenthesis node before the
+ * or expression that is attached to the and expression to make the generated result resembles the CNF form.
*/
private void changeBack() {
if (!(root instanceof MultiAndExpression)) {
@@ -593,9 +587,9 @@ private void changeBack() {
}
MultipleExpression temp = (MultipleExpression) root;
for (int i = 0; i < temp.size(); i++) {
- temp.setChild(i, clone.changeBack(true, temp.getChild(i)));
+ temp.setChild(i, CloneHelper.changeBack(true, temp.getChild(i)));
}
- root = clone.changeBack(false, temp);
+ root = CloneHelper.changeBack(false, temp);
}
}
diff --git a/src/main/java/net/sf/jsqlparser/util/cnfexpression/CloneHelper.java b/src/main/java/net/sf/jsqlparser/util/cnfexpression/CloneHelper.java
index 8b3e3347d..0936fab66 100644
--- a/src/main/java/net/sf/jsqlparser/util/cnfexpression/CloneHelper.java
+++ b/src/main/java/net/sf/jsqlparser/util/cnfexpression/CloneHelper.java
@@ -18,18 +18,16 @@
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
/**
- * This class is mainly used for handling the cloning of an expression tree.
- * Note this is the shallow copy of the tree. That means I do not modify
- * or copy the expression other than these expressions:
- * AND, OR, NOT, (), MULTI-AND, MULTI-OR.
- * Since the CNF conversion only change the condition part of the tree.
+ * This class is mainly used for handling the cloning of an expression tree. Note this is the shallow copy of the tree.
+ * That means I do not modify or copy the expression other than these expressions: AND, OR, NOT, (), MULTI-AND,
+ * MULTI-OR. Since the CNF conversion only change the condition part of the tree.
*
* @author messfish
*
*/
class CloneHelper {
- public Expression modify(Expression express) {
+ public static Expression modify(Expression express) {
if (express instanceof NotExpression) {
return new NotExpression(modify(((NotExpression) express).getExpression()));
}
@@ -40,7 +38,7 @@ public Expression modify(Expression express) {
}
if (express instanceof AndExpression) {
AndExpression and = (AndExpression) express;
- List list = new ArrayList();
+ List list = new ArrayList<>();
list.add(modify(and.getLeftExpression()));
list.add(modify(and.getRightExpression()));
MultiAndExpression result = new MultiAndExpression(list);
@@ -51,7 +49,7 @@ public Expression modify(Expression express) {
}
if (express instanceof OrExpression) {
OrExpression or = (OrExpression) express;
- List list = new ArrayList();
+ List list = new ArrayList<>();
list.add(modify(or.getLeftExpression()));
list.add(modify(or.getRightExpression()));
MultiOrExpression result = new MultiOrExpression(list);
@@ -71,16 +69,16 @@ public Expression modify(Expression express) {
}
/**
- * This method is used to copy the expression which happens at step four. I only copy the
- * conditional expressions since the CNF only changes the conditional part.
+ * This method is used to copy the expression which happens at step four. I only copy the conditional expressions
+ * since the CNF only changes the conditional part.
*
* @param express the expression that will be copied.
* @return the copied expression.
*/
- public Expression shallowCopy(Expression express) {
+ public static Expression shallowCopy(Expression express) {
if (express instanceof MultipleExpression) {
MultipleExpression multi = (MultipleExpression) express;
- List list = new ArrayList();
+ List list = new ArrayList<>();
for (int i = 0; i < multi.size(); i++) {
list.add(shallowCopy(multi.getChild(i)));
}
@@ -95,32 +93,54 @@ public Expression shallowCopy(Expression express) {
}
/**
- * This helper method is used to change the multiple expression into the binary form,
- * respectively and return the root of the expression tree.
+ * This helper method is used to change the multiple expression into the binary form, respectively and return the
+ * root of the expression tree.
*
* @param isMultiOr variable tells whether the expression is or.
* @param exp the expression that needs to be converted.
* @return the root of the expression tree.
*/
- public Expression changeBack(Boolean isMultiOr, Expression exp) {
+ public static Expression changeBack(Boolean isMultiOr, Expression exp) {
if (!(exp instanceof MultipleExpression)) {
return exp;
}
- MultipleExpression changed = (MultipleExpression) exp;
- Expression result = changed.getChild(0);
- for (int i = 1; i < changed.size(); i++) {
- Expression left = result;
- Expression right = changed.getChild(i);
- if (isMultiOr) {
- result = new OrExpression(left, right);
- } else {
- result = new AndExpression(left, right);
+
+ List result = ((MultipleExpression) exp).getList();
+ while (result.size() > 1) {
+ List compressed = new ArrayList<>();
+ for (int i = 0; i < result.size(); i = i + 2) {
+ Expression left = result.get(i);
+ Expression right = i + 1 < result.size() ? result.get(i + 1) : null;
+
+ if (isMultiOr) {
+ compressed.add(right != null ? new OrExpression(left, right) : left);
+ } else {
+ compressed.add(right != null ? new AndExpression(left, right) : left);
+ }
}
+ result = compressed;
}
if (isMultiOr) {
- return new Parenthesis(result);
+ return new Parenthesis(result.get(0));
+ } else {
+ return result.get(0);
}
- return result;
+
+// MultipleExpression changed = (MultipleExpression) exp;
+// Expression result = changed.getChild(0);
+// for (int i = 1; i < changed.size(); i++) {
+// Expression left = result;
+// Expression right = changed.getChild(i);
+// if (isMultiOr) {
+// result = new OrExpression(left, right);
+// } else {
+// result = new AndExpression(left, right);
+// }
+// }
+// if (isMultiOr) {
+// return new Parenthesis(result);
+// }
+// return result;
}
}
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/DeleteDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/DeleteDeParser.java
index c2830f4ee..e6f425bd4 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/DeleteDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/DeleteDeParser.java
@@ -17,6 +17,7 @@
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.select.Join;
+import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.WithItem;
public class DeleteDeParser extends AbstractDeParser {
@@ -60,6 +61,11 @@ public void deParse(Delete delete) {
buffer.append(
delete.getTables().stream().map(Table::getFullyQualifiedName).collect(joining(", ", " ", "")));
}
+
+ if (delete.getOutputClause()!=null) {
+ delete.getOutputClause().appendTo(buffer);
+ }
+
if (delete.isHasFrom()) {
buffer.append(" FROM");
}
@@ -91,6 +97,11 @@ public void deParse(Delete delete) {
new LimitDeparser(buffer).deParse(delete.getLimit());
}
+ if (delete.getReturningExpressionList() != null) {
+ buffer.append(" RETURNING ").append(PlainSelect.
+ getStringList(delete.getReturningExpressionList(), true, false));
+ }
+
}
public ExpressionVisitor getExpressionVisitor() {
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/DropDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/DropDeParser.java
index efdd29d47..0ec7c9a19 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/DropDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/DropDeParser.java
@@ -28,6 +28,10 @@ public void deParse(Drop drop) {
buffer.append(" ").append(drop.getName());
+ if (drop.getType().equals("FUNCTION")) {
+ buffer.append(Drop.formatFuncParams(drop.getParamsByType("FUNCTION")));
+ }
+
if (drop.getParameters() != null && !drop.getParameters().isEmpty()) {
buffer.append(" ").append(PlainSelect.getStringList(drop.getParameters()));
}
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/GroupByDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/GroupByDeParser.java
index d39a1d934..839ae1adb 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/GroupByDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/GroupByDeParser.java
@@ -51,6 +51,9 @@ public void deParse(GroupByElement groupBy) {
buffer.append(" )");
}
if (!groupBy.getGroupingSets().isEmpty()) {
+ if (buffer.charAt(buffer.length() - 1) != ' ') {
+ buffer.append(' ');
+ }
buffer.append("GROUPING SETS (");
boolean first = true;
for (Object o : groupBy.getGroupingSets()) {
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java
index 5cb975ee6..3b2bcf3b3 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java
@@ -19,7 +19,7 @@
import net.sf.jsqlparser.expression.operators.relational.NamedExpressionList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.insert.Insert;
-import net.sf.jsqlparser.statement.select.SelectExpressionItem;
+import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.WithItem;
@@ -76,14 +76,14 @@ public void deParse(Insert insert) {
}
buffer.append(")");
}
-
- if (insert.getItemsList() != null) {
- insert.getItemsList().accept(this);
+
+ if (insert.getOutputClause() != null) {
+ buffer.append(insert.getOutputClause().toString());
}
if (insert.getSelect() != null) {
buffer.append(" ");
- if (insert.isUseSelectBrackets()) {
+ if (insert.getSelect().isUsingWithBrackets()) {
buffer.append("(");
}
if (insert.getSelect().getWithItemsList() != null) {
@@ -94,7 +94,7 @@ public void deParse(Insert insert) {
buffer.append(" ");
}
insert.getSelect().getSelectBody().accept(selectVisitor);
- if (insert.isUseSelectBrackets()) {
+ if (insert.getSelect().isUsingWithBrackets()) {
buffer.append(")");
}
}
@@ -129,17 +129,19 @@ public void deParse(Insert insert) {
}
}
- if (insert.isReturningAllColumns()) {
- buffer.append(" RETURNING *");
- } else if (insert.getReturningExpressionList() != null) {
- buffer.append(" RETURNING ");
- for (Iterator iter = insert.getReturningExpressionList().iterator(); iter
- .hasNext();) {
- buffer.append(iter.next().toString());
- if (iter.hasNext()) {
- buffer.append(", ");
- }
+ //@todo: Accept some Visitors for the involved Expressions
+ if (insert.getConflictAction()!=null) {
+ buffer.append(" ON CONFLICT");
+
+ if (insert.getConflictTarget()!=null) {
+ insert.getConflictTarget().appendTo(buffer);
}
+ insert.getConflictAction().appendTo(buffer);
+ }
+
+ if (insert.getReturningExpressionList() != null) {
+ buffer.append(" RETURNING ").append(PlainSelect.
+ getStringList(insert.getReturningExpressionList(), true, false));
}
}
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java
index 055f610a4..7889a3369 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java
@@ -401,10 +401,12 @@ public void deparseJoin(Join join) {
buffer.append(", ");
} else {
+ if (join.isNatural()) {
+ buffer.append(" NATURAL");
+ }
+
if (join.isRight()) {
buffer.append(" RIGHT");
- } else if (join.isNatural()) {
- buffer.append(" NATURAL");
} else if (join.isFull()) {
buffer.append(" FULL");
} else if (join.isLeft()) {
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java
index 81412eb4a..f10651f22 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java
@@ -29,12 +29,14 @@
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.StatementVisitor;
import net.sf.jsqlparser.statement.Statements;
+import net.sf.jsqlparser.statement.UnsupportedStatement;
import net.sf.jsqlparser.statement.UseStatement;
import net.sf.jsqlparser.statement.alter.Alter;
import net.sf.jsqlparser.statement.alter.AlterSession;
import net.sf.jsqlparser.statement.alter.AlterSystemStatement;
import net.sf.jsqlparser.statement.alter.RenameTableStatement;
import net.sf.jsqlparser.statement.alter.sequence.AlterSequence;
+import net.sf.jsqlparser.statement.analyze.Analyze;
import net.sf.jsqlparser.statement.comment.Comment;
import net.sf.jsqlparser.statement.create.index.CreateIndex;
import net.sf.jsqlparser.statement.create.schema.CreateSchema;
@@ -142,6 +144,9 @@ public void visit(Select select) {
expressionDeParser.setBuffer(buffer);
selectDeParser.setExpressionVisitor(expressionDeParser);
if (select.getWithItemsList() != null && !select.getWithItemsList().isEmpty()) {
+ if (select.isUsingWithBrackets()) {
+ buffer.append("( ");
+ }
buffer.append("WITH ");
for (Iterator iter = select.getWithItemsList().iterator(); iter.hasNext();) {
WithItem withItem = iter.next();
@@ -153,15 +158,27 @@ public void visit(Select select) {
}
}
select.getSelectBody().accept(selectDeParser);
+ if (select.isUsingWithBrackets()) {
+ buffer.append(" )");
+ }
}
@Override
public void visit(Truncate truncate) {
- buffer.append("TRUNCATE TABLE ");
+ buffer.append("TRUNCATE");
+ if (truncate.isTableToken()) {
+ buffer.append(" TABLE");
+ }
+ if (truncate.isOnly()) {
+ buffer.append(" ONLY");
+ }
+ buffer.append(" ");
buffer.append(truncate.getTable());
+
if (truncate.getCascade()) {
- buffer.append(" CASCADE");
+ buffer.append( " CASCADE");
}
+
}
@Override
@@ -175,6 +192,11 @@ public void visit(Update update) {
}
+ public void visit(Analyze analyzer) {
+ buffer.append("ANALYZE ");
+ buffer.append(analyzer.getTable());
+ }
+
@Override
public void visit(Alter alter) {
AlterDeParser alterDeParser = new AlterDeParser(buffer);
@@ -373,4 +395,9 @@ public void visit(PurgeStatement purgeStatement) {
public void visit(AlterSystemStatement alterSystemStatement) {
alterSystemStatement.appendTo(buffer);
}
+
+ @Override
+ public void visit(UnsupportedStatement unsupportedStatement) {
+ unsupportedStatement.appendTo(buffer);
+ }
}
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 77d952568..da32c8f66 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/UpdateDeParser.java
@@ -16,7 +16,7 @@
import net.sf.jsqlparser.statement.select.Join;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.OrderByVisitor;
-import net.sf.jsqlparser.statement.select.SelectExpressionItem;
+import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.WithItem;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.update.UpdateSet;
@@ -103,6 +103,11 @@ public void deParse(Update update) {
j++;
}
+
+ if (update.getOutputClause()!=null) {
+ update.getOutputClause().appendTo(buffer);
+ }
+
if (update.getFromItem() != null) {
buffer.append(" FROM ").append(update.getFromItem());
if (update.getJoins() != null) {
@@ -127,17 +132,9 @@ public void deParse(Update update) {
new LimitDeparser(buffer).deParse(update.getLimit());
}
- if (update.isReturningAllColumns()) {
- buffer.append(" RETURNING *");
- } else if (update.getReturningExpressionList() != null) {
- buffer.append(" RETURNING ");
- for (Iterator iter = update.getReturningExpressionList().iterator(); iter
- .hasNext();) {
- buffer.append(iter.next().toString());
- if (iter.hasNext()) {
- buffer.append(", ");
- }
- }
+ if (update.getReturningExpressionList() != null) {
+ buffer.append(" RETURNING ").append(PlainSelect.
+ getStringList(update.getReturningExpressionList(), true, false));
}
}
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/H2Version.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/H2Version.java
index a5ff52606..9cd733acf 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/feature/H2Version.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/H2Version.java
@@ -100,6 +100,7 @@ public enum H2Version implements Version {
// http://h2database.com/html/commands.html#insert
Feature.insert,
Feature.insertValues,
+ Feature.values,
Feature.insertFromSelect,
// http://h2database.com/html/commands.html#update
Feature.update,
@@ -136,7 +137,8 @@ public enum H2Version implements Version {
// http://www.h2database.com/html/commands.html#grant_role
Feature.grant,
// http://h2database.com/html/commands.html#commit
- Feature.commit));
+ Feature.commit
+ ));
private Set features;
private String versionString;
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/MariaDbVersion.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/MariaDbVersion.java
index b241ffde5..6a1cba1a4 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/feature/MariaDbVersion.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/MariaDbVersion.java
@@ -60,7 +60,7 @@ public enum MariaDbVersion implements Version {
Feature.withItem, Feature.withItemRecursive,
// https://mariadb.com/kb/en/insert/
- Feature.insert, Feature.insertValues,
+ Feature.insert, Feature.insertValues, Feature.values,
Feature.insertFromSelect, Feature.insertModifierPriority, Feature.insertModifierIgnore,
Feature.insertUseSet, Feature.insertUseDuplicateKeyUpdate, Feature.insertReturningExpressionList,
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java
index cf30655d4..c13abaa3e 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/MySqlVersion.java
@@ -54,6 +54,7 @@ public enum MySqlVersion implements Version {
// https://dev.mysql.com/doc/refman/8.0/en/insert.html
Feature.insert,
Feature.insertValues,
+ Feature.values,
Feature.insertFromSelect, Feature.insertUseSet, Feature.insertModifierPriority,
Feature.insertModifierIgnore, Feature.insertUseDuplicateKeyUpdate,
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/OracleVersion.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/OracleVersion.java
index 62fe19bb6..3c970bf65 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/feature/OracleVersion.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/OracleVersion.java
@@ -88,6 +88,7 @@ public enum OracleVersion implements Version {
// https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/INSERT.html
Feature.insert,
Feature.insertValues,
+ Feature.values,
// https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/INSERT.html
// see "single_table_insert"
Feature.insertFromSelect,
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/PostgresqlVersion.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/PostgresqlVersion.java
index 3f439bd41..32e62cca7 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/feature/PostgresqlVersion.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/PostgresqlVersion.java
@@ -109,6 +109,7 @@ public enum PostgresqlVersion implements Version {
// https://www.postgresql.org/docs/current/sql-insert.html
Feature.insert,
Feature.insertValues,
+ Feature.values,
Feature.insertFromSelect,
Feature.insertReturningAll, Feature.insertReturningExpressionList,
// https://www.postgresql.org/docs/current/sql-update.html
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/SQLVersion.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/SQLVersion.java
index b6eda6455..3b8266c83 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/feature/SQLVersion.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/SQLVersion.java
@@ -29,10 +29,13 @@ public enum SQLVersion implements Version {
Feature.jdbcParameter,
Feature.jdbcNamedParameter,
// common features
+ Feature.setOperation,
Feature.select,
Feature.selectGroupBy, Feature.function,
Feature.insert,
+ Feature.insertFromSelect,
Feature.insertValues,
+ Feature.values,
Feature.update,
Feature.delete,
Feature.truncate,
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/AnalyzeValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/AnalyzeValidator.java
new file mode 100644
index 000000000..82864b7ff
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/AnalyzeValidator.java
@@ -0,0 +1,25 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2022 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.util.validation.validator;
+
+import net.sf.jsqlparser.parser.feature.Feature;
+import net.sf.jsqlparser.statement.analyze.Analyze;
+import net.sf.jsqlparser.util.validation.ValidationCapability;
+import net.sf.jsqlparser.util.validation.metadata.NamedObject;
+
+public class AnalyzeValidator extends AbstractValidator{
+ @Override
+ public void validate(Analyze analyze) {
+ for (ValidationCapability c : getCapabilities()) {
+ validateFeature(c, Feature.analyze);
+ validateName(c, NamedObject.table, analyze.getTable().getFullyQualifiedName(), true);
+ }
+ }
+}
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/DeleteValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/DeleteValidator.java
index 5188cefd9..7e07eb546 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/validator/DeleteValidator.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/DeleteValidator.java
@@ -28,6 +28,7 @@ public void validate(Delete delete) {
validateOptionalFeature(c, delete.getJoins(), Feature.deleteJoin);
validateOptionalFeature(c, delete.getLimit(), Feature.deleteLimit);
validateOptionalFeature(c, delete.getOrderByElements(), Feature.deleteOrderBy);
+ validateOptionalFeature(c, delete.getReturningExpressionList(), Feature.insertReturningExpressionList);
}
SelectValidator v = getValidator(SelectValidator.class);
@@ -46,6 +47,10 @@ public void validate(Delete delete) {
getValidator(LimitValidator.class).validate(delete.getLimit());
}
+ if (isNotEmpty(delete.getReturningExpressionList())) {
+ delete.getReturningExpressionList().forEach(c -> c .accept(v));
+ }
+
}
}
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/InsertValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/InsertValidator.java
index fd994af55..59fb966fe 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/validator/InsertValidator.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/InsertValidator.java
@@ -29,7 +29,6 @@ public void validate(Insert insert) {
validateOptionalFeature(c, insert.getSelect(), Feature.insertFromSelect);
validateFeature(c, insert.isUseSet(), Feature.insertUseSet);
validateFeature(c, insert.isUseDuplicate(), Feature.insertUseDuplicateKeyUpdate);
- validateFeature(c, insert.isReturningAllColumns(), Feature.insertReturningAll);
validateOptionalFeature(c, insert.getReturningExpressionList(), Feature.insertReturningExpressionList);
}
@@ -60,8 +59,8 @@ public void validate(Insert insert) {
}
if (isNotEmpty(insert.getReturningExpressionList())) {
- ExpressionValidator v = getValidator(ExpressionValidator.class);
- insert.getReturningExpressionList().forEach(c -> c.getExpression().accept(v));
+ SelectValidator v = getValidator(SelectValidator.class);
+ insert.getReturningExpressionList().forEach(c -> c .accept(v));
}
}
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/StatementValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/StatementValidator.java
index 921aad626..f6cfc121d 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/validator/StatementValidator.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/StatementValidator.java
@@ -27,12 +27,14 @@
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.StatementVisitor;
import net.sf.jsqlparser.statement.Statements;
+import net.sf.jsqlparser.statement.UnsupportedStatement;
import net.sf.jsqlparser.statement.UseStatement;
import net.sf.jsqlparser.statement.alter.Alter;
import net.sf.jsqlparser.statement.alter.AlterSession;
import net.sf.jsqlparser.statement.alter.AlterSystemStatement;
import net.sf.jsqlparser.statement.alter.RenameTableStatement;
import net.sf.jsqlparser.statement.alter.sequence.AlterSequence;
+import net.sf.jsqlparser.statement.analyze.Analyze;
import net.sf.jsqlparser.statement.comment.Comment;
import net.sf.jsqlparser.statement.create.function.CreateFunction;
import net.sf.jsqlparser.statement.create.index.CreateIndex;
@@ -267,6 +269,11 @@ public void visit(CreateSynonym createSynonym) {
getValidator(CreateSynonymValidator.class).validate(createSynonym);
}
+ @Override
+ public void visit(Analyze analyze) {
+ getValidator(AnalyzeValidator.class).validate(analyze);
+ }
+
@Override
public void visit(SavepointStatement savepointStatement) {
//TODO: not yet implemented
@@ -303,4 +310,9 @@ public void visit(PurgeStatement purgeStatement) {
public void visit(AlterSystemStatement alterSystemStatement) {
//TODO: not yet implemented
}
+
+ @Override
+ public void visit(UnsupportedStatement unsupportedStatement) {
+
+ }
}
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/UpdateValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/UpdateValidator.java
index 6bfb3264a..491168243 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/validator/UpdateValidator.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/UpdateValidator.java
@@ -9,10 +9,7 @@
*/
package net.sf.jsqlparser.util.validation.validator;
-import java.util.stream.Collectors;
-
import net.sf.jsqlparser.parser.feature.Feature;
-import net.sf.jsqlparser.statement.select.SelectExpressionItem;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.util.validation.ValidationCapability;
@@ -31,9 +28,7 @@ public void validate(Update update) {
validateFeature(c, update.isUseSelect(), Feature.updateUseSelect);
validateOptionalFeature(c, update.getOrderByElements(), Feature.updateOrderBy);
validateOptionalFeature(c, update.getLimit(), Feature.updateLimit);
- if (isNotEmpty(update.getReturningExpressionList()) || update.isReturningAllColumns()) {
- validateFeature(c, Feature.updateReturning);
- }
+ validateOptionalFeature(c, update.getReturningExpressionList(), Feature.updateReturning);
}
validateOptionalFromItem(update.getTable());
@@ -62,9 +57,9 @@ public void validate(Update update) {
getValidator(LimitValidator.class).validate(update.getLimit());
}
- if (update.getReturningExpressionList() != null) {
- validateOptionalExpressions(update.getReturningExpressionList().stream()
- .map(SelectExpressionItem::getExpression).collect(Collectors.toList()));
+ if (isNotEmpty(update.getReturningExpressionList())) {
+ SelectValidator v = getValidator(SelectValidator.class);
+ update.getReturningExpressionList().forEach(c -> c.accept(v));
}
}
diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
index 1f26d4068..16cdb9469 100644
--- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
+++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
@@ -18,12 +18,13 @@ options {
// FORCE_LA_CHECK = true;
UNICODE_INPUT = true;
JAVA_TEMPLATE_TYPE = "modern";
- JDK_VERSION = "1.7";
+ JDK_VERSION = "1.8";
TOKEN_EXTENDS = "BaseToken";
COMMON_TOKEN_ACTION = true;
NODE_DEFAULT_VOID = true;
TRACK_TOKENS = true;
VISITOR = true;
+ GRAMMAR_ENCODING = "UTF-8";
}
PARSER_BEGIN(CCJSqlParser)
@@ -37,6 +38,7 @@ import net.sf.jsqlparser.expression.operators.conditional.*;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.schema.*;
import net.sf.jsqlparser.statement.*;
+import net.sf.jsqlparser.statement.analyze.*;
import net.sf.jsqlparser.statement.alter.*;
import net.sf.jsqlparser.statement.alter.sequence.*;
import net.sf.jsqlparser.statement.comment.*;
@@ -69,7 +71,8 @@ import java.util.*;
public class CCJSqlParser extends AbstractJSqlParser {
public int bracketsCounter = 0;
public int caseCounter = 0;
-
+ public boolean interrupted = false;
+
public CCJSqlParser withConfiguration(FeatureConfiguration configuration) {
token_source.configuration = configuration;
return this;
@@ -168,6 +171,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
+|
|
|
|
@@ -314,6 +318,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
| ">
|
|
+|
|
|
|
@@ -479,7 +484,7 @@ TOKEN:
| <#LETTER: ["$","A"-"Z","_","#","a"-"z","\u00a2"-"\u00a5","\u00aa","\u00b5","\u00ba","\u00c0"-"\u00d6","\u00d8"-"\u00f6","\u00f8"-"\u021f","\u0222"-"\u0233","\u0250"-"\u02ad","\u02b0"-"\u02b8","\u02bb"-"\u02c1","\u02d0"-"\u02d1","\u02e0"-"\u02e4","\u02ee","\u037a","\u0386","\u0388"-"\u038a","\u038c","\u038e"-"\u03a1","\u03a3"-"\u03ce","\u03d0"-"\u03d7","\u03da"-"\u03f3","\u0400"-"\u0481","\u048c"-"\u04c4","\u04c7"-"\u04c8","\u04cb"-"\u04cc","\u04d0"-"\u04f5","\u04f8"-"\u04f9","\u0531"-"\u0556","\u0559","\u0561"-"\u0587","\u05d0"-"\u05ea","\u05f0"-"\u05f2","\u0621"-"\u063a","\u0640"-"\u064a","\u0671"-"\u06d3","\u06d5","\u06e5"-"\u06e6","\u06fa"-"\u06fc","\u0710","\u0712"-"\u072c","\u0780"-"\u07a5","\u0905"-"\u0939","\u093d","\u0950","\u0958"-"\u0961","\u0985"-"\u098c","\u098f"-"\u0990","\u0993"-"\u09a8","\u09aa"-"\u09b0","\u09b2","\u09b6"-"\u09b9","\u09dc"-"\u09dd","\u09df"-"\u09e1","\u09f0"-"\u09f3","\u0a05"-"\u0a0a","\u0a0f"-"\u0a10","\u0a13"-"\u0a28","\u0a2a"-"\u0a30","\u0a32"-"\u0a33","\u0a35"-"\u0a36","\u0a38"-"\u0a39","\u0a59"-"\u0a5c","\u0a5e","\u0a72"-"\u0a74","\u0a85"-"\u0a8b","\u0a8d","\u0a8f"-"\u0a91","\u0a93"-"\u0aa8","\u0aaa"-"\u0ab0","\u0ab2"-"\u0ab3","\u0ab5"-"\u0ab9","\u0abd","\u0ad0","\u0ae0","\u0b05"-"\u0b0c","\u0b0f"-"\u0b10","\u0b13"-"\u0b28","\u0b2a"-"\u0b30","\u0b32"-"\u0b33","\u0b36"-"\u0b39","\u0b3d","\u0b5c"-"\u0b5d","\u0b5f"-"\u0b61","\u0b85"-"\u0b8a","\u0b8e"-"\u0b90","\u0b92"-"\u0b95","\u0b99"-"\u0b9a","\u0b9c","\u0b9e"-"\u0b9f","\u0ba3"-"\u0ba4","\u0ba8"-"\u0baa","\u0bae"-"\u0bb5","\u0bb7"-"\u0bb9","\u0c05"-"\u0c0c","\u0c0e"-"\u0c10","\u0c12"-"\u0c28","\u0c2a"-"\u0c33","\u0c35"-"\u0c39","\u0c60"-"\u0c61","\u0c85"-"\u0c8c","\u0c8e"-"\u0c90","\u0c92"-"\u0ca8","\u0caa"-"\u0cb3","\u0cb5"-"\u0cb9","\u0cde","\u0ce0"-"\u0ce1","\u0d05"-"\u0d0c","\u0d0e"-"\u0d10","\u0d12"-"\u0d28","\u0d2a"-"\u0d39","\u0d60"-"\u0d61","\u0d85"-"\u0d96","\u0d9a"-"\u0db1","\u0db3"-"\u0dbb","\u0dbd","\u0dc0"-"\u0dc6","\u0e01"-"\u0e30","\u0e32"-"\u0e33","\u0e3f"-"\u0e46","\u0e81"-"\u0e82","\u0e84","\u0e87"-"\u0e88","\u0e8a","\u0e8d","\u0e94"-"\u0e97","\u0e99"-"\u0e9f","\u0ea1"-"\u0ea3","\u0ea5","\u0ea7","\u0eaa"-"\u0eab","\u0ead"-"\u0eb0","\u0eb2"-"\u0eb3","\u0ebd","\u0ec0"-"\u0ec4","\u0ec6","\u0edc"-"\u0edd","\u0f00","\u0f40"-"\u0f47","\u0f49"-"\u0f6a","\u0f88"-"\u0f8b","\u1000"-"\u1021","\u1023"-"\u1027","\u1029"-"\u102a","\u1050"-"\u1055","\u10a0"-"\u10c5","\u10d0"-"\u10f6","\u1100"-"\u1159","\u115f"-"\u11a2","\u11a8"-"\u11f9","\u1200"-"\u1206","\u1208"-"\u1246","\u1248","\u124a"-"\u124d","\u1250"-"\u1256","\u1258","\u125a"-"\u125d","\u1260"-"\u1286","\u1288","\u128a"-"\u128d","\u1290"-"\u12ae","\u12b0","\u12b2"-"\u12b5","\u12b8"-"\u12be","\u12c0","\u12c2"-"\u12c5","\u12c8"-"\u12ce","\u12d0"-"\u12d6","\u12d8"-"\u12ee","\u12f0"-"\u130e","\u1310","\u1312"-"\u1315","\u1318"-"\u131e","\u1320"-"\u1346","\u1348"-"\u135a","\u13a0"-"\u13f4","\u1401"-"\u166c","\u166f"-"\u1676","\u1681"-"\u169a","\u16a0"-"\u16ea","\u1780"-"\u17b3","\u17db","\u1820"-"\u1877","\u1880"-"\u18a8","\u1e00"-"\u1e9b","\u1ea0"-"\u1ef9","\u1f00"-"\u1f15","\u1f18"-"\u1f1d","\u1f20"-"\u1f45","\u1f48"-"\u1f4d","\u1f50"-"\u1f57","\u1f59","\u1f5b","\u1f5d","\u1f5f"-"\u1f7d","\u1f80"-"\u1fb4","\u1fb6"-"\u1fbc","\u1fbe","\u1fc2"-"\u1fc4","\u1fc6"-"\u1fcc","\u1fd0"-"\u1fd3","\u1fd6"-"\u1fdb","\u1fe0"-"\u1fec","\u1ff2"-"\u1ff4","\u1ff6"-"\u1ffc","\u203f"-"\u2040","\u207f","\u20a0"-"\u20af","\u2102","\u2107","\u210a"-"\u2113","\u2115","\u2119"-"\u211d","\u2124","\u2126","\u2128","\u212a"-"\u212d","\u212f"-"\u2131","\u2133"-"\u2139","\u2160"-"\u2183","\u3005"-"\u3007","\u3021"-"\u3029","\u3031"-"\u3035","\u3038"-"\u303a","\u3041"-"\u3094","\u309d"-"\u309e","\u30a1"-"\u30fe","\u3105"-"\u312c","\u3131"-"\u318e","\u31a0"-"\u31b7","\u3400"-"\u4db5","\u4e00"-"\u9fa5","\ua000"-"\ua48c","\uac00"-"\ud7a3","\uf900"-"\ufa2d","\ufb00"-"\ufb06","\ufb13"-"\ufb17","\ufb1d","\ufb1f"-"\ufb28","\ufb2a"-"\ufb36","\ufb38"-"\ufb3c","\ufb3e","\ufb40"-"\ufb41","\ufb43"-"\ufb44","\ufb46"-"\ufbb1","\ufbd3"-"\ufd3d","\ufd50"-"\ufd8f","\ufd92"-"\ufdc7","\ufdf0"-"\ufdfb","\ufe33"-"\ufe34","\ufe4d"-"\ufe4f","\ufe69","\ufe70"-"\ufe72","\ufe74","\ufe76"-"\ufefc","\uff04","\uff21"-"\uff3a","\uff3f","\uff41"-"\uff5a","\uff65"-"\uffbe","\uffc2"-"\uffc7","\uffca"-"\uffcf","\uffd2"-"\uffd7","\uffda"-"\uffdc","\uffe0"-"\uffe1","\uffe5"-"\uffe6"]>
| <#PART_LETTER: ["\u0000"-"\b","\u000e"-"\u001b","$","#","@","0"-"9","A"-"Z","_","a"-"z","\u007f"-"\u009f","\u00a2"-"\u00a5","\u00aa","\u00b5","\u00ba","\u00c0"-"\u00d6","\u00d8"-"\u00f6","\u00f8"-"\u021f","\u0222"-"\u0233","\u0250"-"\u02ad","\u02b0"-"\u02b8","\u02bb"-"\u02c1","\u02d0"-"\u02d1","\u02e0"-"\u02e4","\u02ee","\u0300"-"\u034e","\u0360"-"\u0362","\u037a","\u0386","\u0388"-"\u038a","\u038c","\u038e"-"\u03a1","\u03a3"-"\u03ce","\u03d0"-"\u03d7","\u03da"-"\u03f3","\u0400"-"\u0481","\u0483"-"\u0486","\u048c"-"\u04c4","\u04c7"-"\u04c8","\u04cb"-"\u04cc","\u04d0"-"\u04f5","\u04f8"-"\u04f9","\u0531"-"\u0556","\u0559","\u0561"-"\u0587","\u0591"-"\u05a1","\u05a3"-"\u05b9","\u05bb"-"\u05bd","\u05bf","\u05c1"-"\u05c2","\u05c4","\u05d0"-"\u05ea","\u05f0"-"\u05f2","\u0621"-"\u063a","\u0640"-"\u0655","\u0660"-"\u0669","\u0670"-"\u06d3","\u06d5"-"\u06dc","\u06df"-"\u06e8","\u06ea"-"\u06ed","\u06f0"-"\u06fc","\u070f"-"\u072c","\u0730"-"\u074a","\u0780"-"\u07b0","\u0901"-"\u0903","\u0905"-"\u0939","\u093c"-"\u094d","\u0950"-"\u0954","\u0958"-"\u0963","\u0966"-"\u096f","\u0981"-"\u0983","\u0985"-"\u098c","\u098f"-"\u0990","\u0993"-"\u09a8","\u09aa"-"\u09b0","\u09b2","\u09b6"-"\u09b9","\u09bc","\u09be"-"\u09c4","\u09c7"-"\u09c8","\u09cb"-"\u09cd","\u09d7","\u09dc"-"\u09dd","\u09df"-"\u09e3","\u09e6"-"\u09f3","\u0a02","\u0a05"-"\u0a0a","\u0a0f"-"\u0a10","\u0a13"-"\u0a28","\u0a2a"-"\u0a30","\u0a32"-"\u0a33","\u0a35"-"\u0a36","\u0a38"-"\u0a39","\u0a3c","\u0a3e"-"\u0a42","\u0a47"-"\u0a48","\u0a4b"-"\u0a4d","\u0a59"-"\u0a5c","\u0a5e","\u0a66"-"\u0a74","\u0a81"-"\u0a83","\u0a85"-"\u0a8b","\u0a8d","\u0a8f"-"\u0a91","\u0a93"-"\u0aa8","\u0aaa"-"\u0ab0","\u0ab2"-"\u0ab3","\u0ab5"-"\u0ab9","\u0abc"-"\u0ac5","\u0ac7"-"\u0ac9","\u0acb"-"\u0acd","\u0ad0","\u0ae0","\u0ae6"-"\u0aef","\u0b01"-"\u0b03","\u0b05"-"\u0b0c","\u0b0f"-"\u0b10","\u0b13"-"\u0b28","\u0b2a"-"\u0b30","\u0b32"-"\u0b33","\u0b36"-"\u0b39","\u0b3c"-"\u0b43","\u0b47"-"\u0b48","\u0b4b"-"\u0b4d","\u0b56"-"\u0b57","\u0b5c"-"\u0b5d","\u0b5f"-"\u0b61","\u0b66"-"\u0b6f","\u0b82"-"\u0b83","\u0b85"-"\u0b8a","\u0b8e"-"\u0b90","\u0b92"-"\u0b95","\u0b99"-"\u0b9a","\u0b9c","\u0b9e"-"\u0b9f","\u0ba3"-"\u0ba4","\u0ba8"-"\u0baa","\u0bae"-"\u0bb5","\u0bb7"-"\u0bb9","\u0bbe"-"\u0bc2","\u0bc6"-"\u0bc8","\u0bca"-"\u0bcd","\u0bd7","\u0be7"-"\u0bef","\u0c01"-"\u0c03","\u0c05"-"\u0c0c","\u0c0e"-"\u0c10","\u0c12"-"\u0c28","\u0c2a"-"\u0c33","\u0c35"-"\u0c39","\u0c3e"-"\u0c44","\u0c46"-"\u0c48","\u0c4a"-"\u0c4d","\u0c55"-"\u0c56","\u0c60"-"\u0c61","\u0c66"-"\u0c6f","\u0c82"-"\u0c83","\u0c85"-"\u0c8c","\u0c8e"-"\u0c90","\u0c92"-"\u0ca8","\u0caa"-"\u0cb3","\u0cb5"-"\u0cb9","\u0cbe"-"\u0cc4","\u0cc6"-"\u0cc8","\u0cca"-"\u0ccd","\u0cd5"-"\u0cd6","\u0cde","\u0ce0"-"\u0ce1","\u0ce6"-"\u0cef","\u0d02"-"\u0d03","\u0d05"-"\u0d0c","\u0d0e"-"\u0d10","\u0d12"-"\u0d28","\u0d2a"-"\u0d39","\u0d3e"-"\u0d43","\u0d46"-"\u0d48","\u0d4a"-"\u0d4d","\u0d57","\u0d60"-"\u0d61","\u0d66"-"\u0d6f","\u0d82"-"\u0d83","\u0d85"-"\u0d96","\u0d9a"-"\u0db1","\u0db3"-"\u0dbb","\u0dbd","\u0dc0"-"\u0dc6","\u0dca","\u0dcf"-"\u0dd4","\u0dd6","\u0dd8"-"\u0ddf","\u0df2"-"\u0df3","\u0e01"-"\u0e3a","\u0e3f"-"\u0e4e","\u0e50"-"\u0e59","\u0e81"-"\u0e82","\u0e84","\u0e87"-"\u0e88","\u0e8a","\u0e8d","\u0e94"-"\u0e97","\u0e99"-"\u0e9f","\u0ea1"-"\u0ea3","\u0ea5","\u0ea7","\u0eaa"-"\u0eab","\u0ead"-"\u0eb9","\u0ebb"-"\u0ebd","\u0ec0"-"\u0ec4","\u0ec6","\u0ec8"-"\u0ecd","\u0ed0"-"\u0ed9","\u0edc"-"\u0edd","\u0f00","\u0f18"-"\u0f19","\u0f20"-"\u0f29","\u0f35","\u0f37","\u0f39","\u0f3e"-"\u0f47","\u0f49"-"\u0f6a","\u0f71"-"\u0f84","\u0f86"-"\u0f8b","\u0f90"-"\u0f97","\u0f99"-"\u0fbc","\u0fc6","\u1000"-"\u1021","\u1023"-"\u1027","\u1029"-"\u102a","\u102c"-"\u1032","\u1036"-"\u1039","\u1040"-"\u1049","\u1050"-"\u1059","\u10a0"-"\u10c5","\u10d0"-"\u10f6","\u1100"-"\u1159","\u115f"-"\u11a2","\u11a8"-"\u11f9","\u1200"-"\u1206","\u1208"-"\u1246","\u1248","\u124a"-"\u124d","\u1250"-"\u1256","\u1258","\u125a"-"\u125d","\u1260"-"\u1286","\u1288","\u128a"-"\u128d","\u1290"-"\u12ae","\u12b0","\u12b2"-"\u12b5","\u12b8"-"\u12be","\u12c0","\u12c2"-"\u12c5","\u12c8"-"\u12ce","\u12d0"-"\u12d6","\u12d8"-"\u12ee","\u12f0"-"\u130e","\u1310","\u1312"-"\u1315","\u1318"-"\u131e","\u1320"-"\u1346","\u1348"-"\u135a","\u1369"-"\u1371","\u13a0"-"\u13f4","\u1401"-"\u166c","\u166f"-"\u1676","\u1681"-"\u169a","\u16a0"-"\u16ea","\u1780"-"\u17d3","\u17db","\u17e0"-"\u17e9","\u180b"-"\u180e","\u1810"-"\u1819","\u1820"-"\u1877","\u1880"-"\u18a9","\u1e00"-"\u1e9b","\u1ea0"-"\u1ef9","\u1f00"-"\u1f15","\u1f18"-"\u1f1d","\u1f20"-"\u1f45","\u1f48"-"\u1f4d","\u1f50"-"\u1f57","\u1f59","\u1f5b","\u1f5d","\u1f5f"-"\u1f7d","\u1f80"-"\u1fb4","\u1fb6"-"\u1fbc","\u1fbe","\u1fc2"-"\u1fc4","\u1fc6"-"\u1fcc","\u1fd0"-"\u1fd3","\u1fd6"-"\u1fdb","\u1fe0"-"\u1fec","\u1ff2"-"\u1ff4","\u1ff6"-"\u1ffc","\u200c"-"\u200f","\u202a"-"\u202e","\u203f"-"\u2040","\u206a"-"\u206f","\u207f","\u20a0"-"\u20af","\u20d0"-"\u20dc","\u20e1","\u2102","\u2107","\u210a"-"\u2113","\u2115","\u2119"-"\u211d","\u2124","\u2126","\u2128","\u212a"-"\u212d","\u212f"-"\u2131","\u2133"-"\u2139","\u2160"-"\u2183","\u3005"-"\u3007","\u3021"-"\u302f","\u3031"-"\u3035","\u3038"-"\u303a","\u3041"-"\u3094","\u3099"-"\u309a","\u309d"-"\u309e","\u30a1"-"\u30fe","\u3105"-"\u312c","\u3131"-"\u318e","\u31a0"-"\u31b7","\u3400"-"\u4db5","\u4e00"-"\u9fa5","\ua000"-"\ua48c","\uac00"-"\ud7a3","\uf900"-"\ufa2d","\ufb00"-"\ufb06","\ufb13"-"\ufb17","\ufb1d"-"\ufb28","\ufb2a"-"\ufb36","\ufb38"-"\ufb3c","\ufb3e","\ufb40"-"\ufb41","\ufb43"-"\ufb44","\ufb46"-"\ufbb1","\ufbd3"-"\ufd3d","\ufd50"-"\ufd8f","\ufd92"-"\ufdc7","\ufdf0"-"\ufdfb","\ufe20"-"\ufe23","\ufe33"-"\ufe34","\ufe4d"-"\ufe4f","\ufe69","\ufe70"-"\ufe72","\ufe74","\ufe76"-"\ufefc","\ufeff","\uff04","\uff10"-"\uff19","\uff21"-"\uff3a","\uff3f","\uff41"-"\uff5a","\uff65"-"\uffbe","\uffc2"-"\uffc7","\uffca"-"\uffcf","\uffd2"-"\uffd7","\uffda"-"\uffdc","\uffe0"-"\uffe1","\uffe5"-"\uffe6","\ufff9"-"\ufffb"]>
| < S_CHAR_LITERAL: (["U","E","N","R","B"]|"RB"|"_utf8")? (("'" ( | ~["'", "\\", "\n", "\r"] )* "'") | ("'" ("''" | ~["'"])* "'")) >
-| < S_QUOTED_IDENTIFIER: "\"" (~["\n","\r","\""])* "\"" | "$$" (~["\n","\r","\""])* "$$" | ("`" (~["\n","\r","`"])+ "`") | ( "[" ~["0"-"9","]"] (~["\n","\r","]"])* "]" ) >
+| < S_QUOTED_IDENTIFIER: "\"" (~["\n","\r","\""])* "\"" | "$$" (~["\n","\r","\""])* "$$" | ("`" (~["\n","\r","`"])+ "`") | ( "[" (~["\n","\r","]"])* "]" ) >
{ if ( !configuration.getAsBoolean(Feature.allowSquareBracketQuotation) && matchedToken.image.charAt(0) == '[' ) {
matchedToken.image = "[";
for (int i=0;i { ifElseStatement.setUsingSemicolonForIfStatement(true); } ]
[ LOOKAHEAD(2)
- stm2 = SingleStatement() { ifElseStatement.setElseStatement(stm2); }
+ stm2 = SingleStatement() { ifElseStatement.setElseStatement(stm2); }
[ { ifElseStatement.setUsingSemicolonForElseStatement(true); }]
]
@@ -518,6 +523,8 @@ Statement Statement() #Statement:
[ ]
)
+ |
+ LOOKAHEAD( { getAsBoolean(Feature.allowUnsupportedStatements) } ) stm = UnsupportedStatement()
} catch (ParseException e) {
if (errorRecovery) {
parseErrors.add(e);
@@ -540,8 +547,29 @@ Statement SingleStatement() :
{
try {
(
+ LOOKAHEAD(2) (
+ "(" with=WithList()
+ (
+ stm = Select( with ) { ( (Select) stm).setUsingWithBrackets(true); }
+
+ /* @todo: unsure, if we need to implement those
+ since DMLs in brackets do not really make any sense
+ |
+ stm = Insert( with ) { ( (Insert) stm).setUsingWithBrackets(true); }
+ |
+ stm = Update( with ) { ( (Update) stm).setUsingWithBrackets(true); }
+ |
+ stm = Delete( with ) { ( (Delete) stm).setUsingWithBrackets(true); }
+ |
+ stm = Merge( with ) { ( (Merge) stm).setUsingWithBrackets(true); }
+
+ */
+ )
+ ")"
+ )
+ |
(
- [ with=WithList() { } ]
+ [ with=WithList() ]
(
stm = Select( with )
|
@@ -554,86 +582,88 @@ Statement SingleStatement() :
stm = Merge( with)
)
)
- |
- stm = Upsert()
- |
- LOOKAHEAD(3)
- stm = Replace()
- |
- LOOKAHEAD(2)
- stm = AlterTable()
- |
- LOOKAHEAD(2)
- stm = AlterSession()
- |
- LOOKAHEAD(CreateFunctionStatement())
- stm = CreateFunctionStatement()
- |
- LOOKAHEAD(CreateIndex())
- stm = CreateIndex()
- |
- LOOKAHEAD(CreateSchema())
- stm = CreateSchema()
- |
- LOOKAHEAD(CreateSequence())
- stm = CreateSequence()
- |
- LOOKAHEAD(CreateSynonym())
- stm = CreateSynonym()
- |
- LOOKAHEAD(CreateTable())
- stm = CreateTable()
- |
- LOOKAHEAD(CreateView())
- stm = CreateView()
- |
- LOOKAHEAD(AlterView())
- stm = AlterView()
- |
- LOOKAHEAD(AlterSequence())
- stm = AlterSequence()
- |
- stm = Drop()
- |
- stm = Truncate()
- |
- stm = Execute()
- |
- stm = Set()
- |
- stm = RenameTableStatement()
- |
- stm = Reset()
- |
- LOOKAHEAD(ShowColumns())
- stm = ShowColumns()
- |
- LOOKAHEAD(ShowTables())
- stm = ShowTables()
- |
- stm = Show()
- |
- stm = Use()
- |
- stm = SavepointStatement()
- |
- stm = RollbackStatement()
- |
- stm = Commit()
- |
- stm = Comment()
- |
- stm = Describe()
- |
- stm = Explain()
- |
- stm = Declare()
- |
- stm = Grant()
- |
- stm = PurgeStatement()
- |
- stm = AlterSystemStatement()
+ |
+ stm = Upsert()
+ |
+ LOOKAHEAD(3)
+ stm = Replace()
+ |
+ LOOKAHEAD(2)
+ stm = AlterTable()
+ |
+ LOOKAHEAD(2)
+ stm = AlterSession()
+ |
+ LOOKAHEAD(CreateFunctionStatement())
+ stm = CreateFunctionStatement()
+ |
+ LOOKAHEAD(CreateIndex())
+ stm = CreateIndex()
+ |
+ LOOKAHEAD(CreateSchema())
+ stm = CreateSchema()
+ |
+ LOOKAHEAD(CreateSequence())
+ stm = CreateSequence()
+ |
+ LOOKAHEAD(CreateSynonym())
+ stm = CreateSynonym()
+ |
+ LOOKAHEAD(CreateTable())
+ stm = CreateTable()
+ |
+ LOOKAHEAD(CreateView())
+ stm = CreateView()
+ |
+ LOOKAHEAD(AlterView())
+ stm = AlterView()
+ |
+ LOOKAHEAD(AlterSequence())
+ stm = AlterSequence()
+ |
+ stm = Drop()
+ |
+ stm = Analyze()
+ |
+ stm = Truncate()
+ |
+ stm = Execute()
+ |
+ stm = Set()
+ |
+ stm = RenameTableStatement()
+ |
+ stm = Reset()
+ |
+ LOOKAHEAD(ShowColumns())
+ stm = ShowColumns()
+ |
+ LOOKAHEAD(ShowTables())
+ stm = ShowTables()
+ |
+ stm = Show()
+ |
+ stm = Use()
+ |
+ stm = SavepointStatement()
+ |
+ stm = RollbackStatement()
+ |
+ stm = Commit()
+ |
+ stm = Comment()
+ |
+ stm = Describe()
+ |
+ stm = Explain()
+ |
+ stm = Declare()
+ |
+ stm = Grant()
+ |
+ stm = PurgeStatement()
+ |
+ stm = AlterSystemStatement()
)
{ return stm; }
} catch (ParseException e) {
@@ -654,10 +684,27 @@ Block Block() #Block : {
}
{
-()*
+ ()*
try {
- (stm = SingleStatement() | stm = Block()) { list.add(stm); }
- ( (stm = SingleStatement() | stm = Block()) { list.add(stm); } )*
+ (
+ (
+ stm = SingleStatement()
+ | stm = Block()
+ )
+
+ { list.add(stm); }
+ )
+
+ (
+ (
+ (
+ stm = SingleStatement()
+ | stm = Block()
+ )
+
+ { list.add(stm); }
+ )
+ )*
} catch (ParseException e) {
if (errorRecovery) {
parseErrors.add(e);
@@ -666,11 +713,13 @@ Block Block() #Block : {
throw e;
}
}
+
{
stmts.setStatements(list);
block.setStatements(stmts);
}
-
+
+ [LOOKAHEAD(2) ]
{
return block;
}
@@ -706,33 +755,40 @@ Statements Statements() #Statements : {
[ LOOKAHEAD(2) ]
) { list.add(stm); }
+ |
+ LOOKAHEAD( { getAsBoolean(Feature.allowUnsupportedStatements) } ) stm = UnsupportedStatement()
+ { if ( !((UnsupportedStatement) stm).isEmpty() ) list.add(stm); }
)
-
- (
- { if (stm2!=null)
- ifElseStatement.setUsingSemicolonForElseStatement(true);
- else if (ifElseStatement!=null)
- ifElseStatement.setUsingSemicolonForIfStatement(true); }
+ (
+ { if (stm2!=null)
+ ifElseStatement.setUsingSemicolonForElseStatement(true);
+ else if (ifElseStatement!=null)
+ ifElseStatement.setUsingSemicolonForIfStatement(true); }
[
(
- condition=Condition()
+ condition=Condition()
stm = SingleStatement() { ifElseStatement = new IfElseStatement(condition, stm); }
- [ LOOKAHEAD(2)
+ [ LOOKAHEAD(2)
[ { ifElseStatement.setUsingSemicolonForIfStatement(true); } ]
- stm2 = SingleStatement() { ifElseStatement.setElseStatement(stm2); }
+ stm2 = SingleStatement() { ifElseStatement.setElseStatement(stm2); }
]
{ list.add( ifElseStatement ); }
)
|
(
- stm = SingleStatement()
+ stm = SingleStatement()
| stm = Block()
[ LOOKAHEAD(2) ]
) { list.add(stm); }
- ]
+ |
+ // For any reason, we can't LOOKAHEAD( { getAsBoolean(Feature.allowUnsupportedStatements) } ) here
+ // As it will result in a Stack Overflow
+ stm = UnsupportedStatement()
+ { if ( !((UnsupportedStatement) stm).isEmpty() ) list.add(stm); }
+ ]
)*
} catch (ParseException e) {
@@ -1106,7 +1162,7 @@ ShowStatement Show(): {
ValuesStatement Values(): {
ItemsList itemsList;
} {
-
+ ( | )
itemsList = SimpleExpressionList(false)
@@ -1132,10 +1188,12 @@ Update Update( List with ):
Limit limit = null;
List orderByElements;
boolean useColumnsBrackets = false;
- List returning = null;
+ List returning = null;
Token tk = null;
UpdateModifierPriority modifierPriority = null;
boolean modifierIgnore = false;
+
+ OutputClause outputClause = null;
}
{
{ update.setOracleHint(getOracleHint()); }
@@ -1186,21 +1244,19 @@ Update Update( List with ):
)
)
- [
+ [ outputClause = OutputClause() {update.setOutputClause(outputClause); } ]
+
+ [
fromItem=FromItem()
joins=JoinsList() ]
- [ where=WhereClause() { update.setWhere(where); } ]
+ [ where=WhereClause() { update.setWhere(where); } ]
- [ orderByElements = OrderByElements() { update.setOrderByElements(orderByElements); } ]
- [ limit = PlainLimit() { update.setLimit(limit); } ]
- [ (
- "*" { update.setReturningAllColumns(true); }
- | returning=ListExpressionItem()
- )
- ]
+ [ orderByElements = OrderByElements() { update.setOrderByElements(orderByElements); } ]
+ [ limit = PlainLimit() { update.setLimit(limit); } ]
+ [ returning=SelectItemsList() ]
- {
+ {
return update.withWithItemsList(with)
.withTable(table)
.withStartJoins(startJoins)
@@ -1209,7 +1265,7 @@ Update Update( List with ):
.withModifierPriority(modifierPriority)
.withModifierIgnore(modifierIgnore)
.withReturningExpressionList(returning);
- }
+ }
}
Replace Replace():
@@ -1287,14 +1343,9 @@ Insert Insert( List with ):
Table table = null;
Column tableColumn = null;
List columns = new ArrayList();
- List primaryExpList = new ArrayList();
- ItemsList itemsList = null;
Expression exp = null;
- MultiExpressionList multiExpr = null;
- List returning = null;
+ List returning = null;
Select select = null;
- boolean useValues = true;
- boolean useSelectBrackets = false;
boolean useDuplicate = false;
List duplicateUpdateColumns = null;
List duplicateUpdateExpressionList = null;
@@ -1306,6 +1357,11 @@ Insert Insert( List with ):
List setExpressionList = new ArrayList();
String name = null;
boolean useAs = false;
+ OutputClause outputClause = null;
+
+ UpdateSet updateSet = null;
+ InsertConflictTarget conflictTarget = null;
+ InsertConflictAction conflictAction = null;
}
{
{ insert.setOracleHint(getOracleHint()); }
@@ -1318,40 +1374,13 @@ Insert Insert( List with ):
[ [ { useAs = true; } ] name=RelObjectNameWithoutValue() { table.setAlias(new Alias(name,useAs)); }]
- [LOOKAHEAD(2) "(" tableColumn=Column() { columns.add(tableColumn); } ("," tableColumn=Column() { columns.add(tableColumn); } )* ")" ]
- (
- LOOKAHEAD(2) [ | ] "(" exp=SimpleExpression() { primaryExpList.add(exp); }
- ("," exp=SimpleExpression() { primaryExpList.add(exp); } )* ")" { itemsList = new ExpressionList(primaryExpList); }
- ("," "(" exp=SimpleExpression() {
- if (multiExpr==null) {
- multiExpr=new MultiExpressionList();
- multiExpr.addExpressionList((ExpressionList)itemsList);
- itemsList = multiExpr;
- }
- primaryExpList = new ArrayList();
- primaryExpList.add(exp); }
- ("," exp=SimpleExpression() { primaryExpList.add(exp); } )* ")" { multiExpr.addExpressionList(primaryExpList); } )*
-
- |
+ [LOOKAHEAD(2) "(" tableColumn=Column() { columns.add(tableColumn); } ("," tableColumn=Column() { columns.add(tableColumn); } )* ")" ]
- (
- LOOKAHEAD(2) "(" { useSelectBrackets = true; }
- { insert.setUseValues(false); }
- select = SelectWithWithItems( )
- ")"
- |
- { insert.setUseValues(false); }
- select = SelectWithWithItems( )
- )
-
- |
+ [ outputClause = OutputClause() { insert.setOutputClause(outputClause); } ]
-
+ (
(
- {
- useSet = true;
- insert.setUseValues(false);
- }
+ { useSet = true; }
tableColumn=Column() "=" exp=SimpleExpression()
{
setColumns = new ArrayList();
@@ -1363,9 +1392,11 @@ Insert Insert( List with ):
{ setColumns.add(tableColumn);
setExpressionList.add(exp); } )*
)
+ |
+ select = SelectWithWithItems( )
)
- [
+ [ LOOKAHEAD(2)
{ useDuplicate = true; }
tableColumn=Column() "=" exp=SimpleExpression()
{
@@ -1378,20 +1409,19 @@ Insert Insert( List with ):
{ duplicateUpdateColumns.add(tableColumn);
duplicateUpdateExpressionList.add(exp); } )*]
-
- [ (
- "*" { insert.setReturningAllColumns(true); }
- | returning=ListExpressionItem()
- )
+ [
+
+ [ conflictTarget = InsertConflictTarget() ]
+ conflictAction = InsertConflictAction() { insert.withConflictTarget(conflictTarget).setConflictAction(conflictAction); }
]
+ [ returning=SelectItemsList() ]
+
{
if (!columns.isEmpty()) {
insert.setColumns(columns);
}
return insert.withWithItemsList(with)
- .withItemsList(itemsList)
- .withUseSelectBrackets(useSelectBrackets)
.withSelect(select)
.withTable(table)
.withUseDuplicate(useDuplicate)
@@ -1406,6 +1436,148 @@ Insert Insert( List with ):
}
}
+InsertConflictTarget InsertConflictTarget():
+{
+ String indexColumnName = null;
+ Expression indexExpression = null;
+ Expression whereExpression = null;
+ String constraintName = null ;
+}
+{
+ (
+ (
+ "("
+ indexColumnName = RelObjectNameExt2()
+// |
+// (
+// "(" indexExpression = Expression() ")"
+// )
+
+ ")"
+ [ whereExpression = WhereClause() ]
+ )
+ |
+ (
+ constraintName = RelObjectNameExt2()
+ )
+ )
+
+ { return new InsertConflictTarget(indexColumnName, indexExpression, whereExpression, constraintName); }
+}
+
+InsertConflictAction InsertConflictAction():
+{
+ InsertConflictAction conflictAction;
+ ArrayList updateSets = new ArrayList();
+ UpdateSet updateSet = null;
+ Expression whereExpression = null;
+
+ Column tableColumn = null;
+ SubSelect subSelect;
+ Expression valueExpression = null;
+ ExpressionList expressionList;
+}
+{
+ (
+ LOOKAHEAD(2) (
+ { conflictAction = new InsertConflictAction( ConflictActionType.DO_NOTHING ); }
+ )
+ |
+ (
+ { conflictAction = new InsertConflictAction( ConflictActionType.DO_UPDATE ); }
+ (
+ LOOKAHEAD(3) tableColumn=Column()
+ "=" valueExpression=SimpleExpression() {
+ updateSet = new UpdateSet();
+ updateSet.add(tableColumn);
+ updateSet.add(valueExpression);
+ updateSets.add(updateSet);
+ }
+ (
+ ","
+ tableColumn=Column()
+ "=" valueExpression=SimpleExpression() {
+ updateSet = new UpdateSet();
+ updateSet.add(tableColumn);
+ updateSet.add(valueExpression);
+ updateSets.add(updateSet);
+ }
+ )*
+ |
+ (
+ { updateSet = new UpdateSet(); updateSets.add(updateSet); }
+
+ [ LOOKAHEAD(2) "(" { updateSet.setUsingBracketsForColumns(true); } ]
+ tableColumn=Column() { updateSet.add(tableColumn); }
+ ( LOOKAHEAD(2) "," tableColumn=Column() { updateSet.add(tableColumn); } )*
+ [ LOOKAHEAD(2) ")" ]
+
+ "="
+
+ (
+ 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(); updateSets.add(updateSet); }
+
+ [ LOOKAHEAD(2) "(" { updateSet.setUsingBracketsForColumns(true); } ]
+ tableColumn=Column() { updateSet.add(tableColumn); }
+ ( LOOKAHEAD(2) "," tableColumn=Column() { updateSet.add(tableColumn); } )*
+ [ LOOKAHEAD(2) ")" ]
+
+ "="
+
+ (
+ LOOKAHEAD(3) subSelect=SubSelect() { updateSet.add(subSelect.withUseBrackets(false)); }
+ |
+ LOOKAHEAD(3) "(" expressionList = ComplexExpressionList() { updateSet.setUsingBracketsForValues(true); updateSet.add(expressionList); } ")"
+ |
+ valueExpression = Expression() { updateSet.add(valueExpression); }
+ )
+ ) *
+ )
+ )
+
+ [ whereExpression = WhereClause() ]
+ )
+ )
+
+ { return conflictAction
+ .withUpdateSets(updateSets)
+ .withWhereExpression(whereExpression); }
+}
+
+OutputClause OutputClause():
+{
+ List selectItemList = null;
+ UserVariable tableVariable = null;
+ Table outputTable = null;
+ List columnList = null;
+}
+{
+
+ selectItemList = SelectItemsList()
+ [
+ (
+ tableVariable = UserVariable()
+ |
+ outputTable = Table()
+ )
+ [
+ LOOKAHEAD(2) columnList = ColumnsNamesList()
+ ]
+ ]
+
+ {
+ return new OutputClause(selectItemList, tableVariable, outputTable, columnList);
+ }
+}
+
Upsert Upsert():
{
Upsert upsert = new Upsert();
@@ -1499,6 +1671,9 @@ Delete Delete( List with ):
DeleteModifierPriority modifierPriority = null;
boolean modifierIgnore = false;
boolean modifierQuick = false;
+
+ List returning = null;
+ OutputClause outputClause = null;
}
{
{ delete.setOracleHint(getOracleHint()); }
@@ -1507,6 +1682,7 @@ Delete Delete( List with ):
[ { modifierIgnore = true; }]
[LOOKAHEAD(4) (table=TableWithAlias() { tables.add(table); }
("," table=TableWithAlias() { tables.add(table); } )*
+ [ outputClause = OutputClause() {delete.setOutputClause(outputClause); } ]
| ) { hasFrom = true; }]
[ LOOKAHEAD(3) table=TableWithAlias() joins=JoinsList() ]
@@ -1515,6 +1691,8 @@ Delete Delete( List with ):
[where=WhereClause() { delete.setWhere(where); } ]
[orderByElements = OrderByElements() { delete.setOrderByElements(orderByElements); } ]
[limit=PlainLimit() {delete.setLimit(limit); } ]
+
+ [ returning=SelectItemsList() ]
{
if (joins != null && joins.size() > 0) {
delete.setJoins(joins);
@@ -1526,7 +1704,8 @@ Delete Delete( List with ):
.withUsingList(usingList)
.withModifierPriority(modifierPriority)
.withModifierIgnore(modifierIgnore)
- .withModifierQuick(modifierQuick);
+ .withModifierQuick(modifierQuick)
+ .withReturningExpressionList(returning);
}
}
@@ -1661,7 +1840,7 @@ String RelObjectNameWithoutValue() :
| tk=
| tk=
| tk=
- | tk= | tk=
+ | tk= | tk= | tk=
/* Keywords for ALTER SESSION */
/* | tk= */ | tk= | tk=
@@ -1675,6 +1854,8 @@ String RelObjectNameWithoutValue() :
| tk=
| tk=
| tk=
+
+ | tk=
)
{ return tk.image; }
@@ -1687,7 +1868,7 @@ String RelObjectName() :
{ Token tk = null; String result = null; }
{
(result = RelObjectNameWithoutValue()
- | tk= | tk= | tk= | tk= | tk= | tk= | tk=