expressions;
- private boolean useValues = true;
- private boolean useIntoTables = false;
-
- @Override
- public void accept(StatementVisitor statementVisitor) {
- statementVisitor.visit(this);
- }
- public Table getTable() {
- return table;
- }
+/**
+ * Not Standard compliant REPLACE Statement
+ * @deprecated
+ * This class has been merged into the UPSERT statement and should not longer been used.
+ * Use {@link Upsert} instead.
+ *
+ */
- public void setTable(Table name) {
- table = name;
- }
+@Deprecated
+public class Replace extends Upsert {
+ @Deprecated
public boolean isUseIntoTables() {
- return useIntoTables;
+ return super.isUsingInto();
}
+ @Deprecated
public void setUseIntoTables(boolean useIntoTables) {
- this.useIntoTables = useIntoTables;
- }
-
- public List getColumns() {
- return columns;
- }
-
- public ItemsList getItemsList() {
- return itemsList;
- }
-
- public void setColumns(List list) {
- columns = list;
- }
-
- public void setItemsList(ItemsList list) {
- itemsList = list;
+ super.setUsingInto( useIntoTables );
}
+ @Deprecated
/**
* A list of {@link net.sf.jsqlparser.expression.Expression}s (from a "REPLACE mytab SET
* col1=exp1, col2=exp2").
* it is null in case of a "REPLACE mytab (col1, col2) [...]"
*/
public List getExpressions() {
- return expressions;
+ return super.getSetExpressions();
}
+ @Deprecated
public void setExpressions(List list) {
- expressions = list;
- }
-
- public boolean isUseValues() {
- return useValues;
- }
-
- public void setUseValues(boolean useValues) {
- this.useValues = useValues;
- }
-
- @Override
- public String toString() {
- StringBuilder sql = new StringBuilder();
- sql.append("REPLACE ");
- if (isUseIntoTables()) {
- sql.append("INTO ");
- }
- sql.append(table);
-
- if (expressions != null && columns != null) {
- // the SET col1=exp1, col2=exp2 case
- sql.append(" SET ");
- // each element from expressions match up with a column from columns.
- for (int i = 0, s = columns.size(); i < s; i++) {
- sql.append(columns.get(i)).append("=").append(expressions.get(i));
- sql.append( i < s - 1
- ? ", "
- : "" );
- }
- } else if (columns != null) {
- // the REPLACE mytab (col1, col2) [...] case
- sql.append(" ").append(PlainSelect.getStringList(columns, true, true));
- }
-
- if (itemsList != null) {
- // REPLACE mytab SELECT * FROM mytab2
- // or VALUES ('as', ?, 565)
-
- if (useValues) {
- sql.append(" VALUES");
- }
-
- sql.append(" ").append(itemsList);
- }
-
- return sql.toString();
- }
-
- public Replace withUseValues(boolean useValues) {
- this.setUseValues(useValues);
- return this;
+ super.setItemsList( new ExpressionList(list) );
}
+ @Deprecated
public Replace withUseIntoTables(boolean useIntoTables) {
- this.setUseIntoTables(useIntoTables);
- return this;
- }
-
- public Replace withTable(Table table) {
- this.setTable(table);
- return this;
- }
-
- public Replace withColumns(List columns) {
- this.setColumns(columns);
- return this;
- }
-
- public Replace withItemsList(ItemsList itemsList) {
- this.setItemsList(itemsList);
+ super.setUsingInto(useIntoTables);
return this;
}
+ @Deprecated
public Replace withExpressions(List expressions) {
- this.setExpressions(expressions);
+ super.setItemsList( new ExpressionList(expressions) );
return this;
}
- public Replace addColumns(Column... columns) {
- List collection = Optional.ofNullable(getColumns()).orElseGet(ArrayList::new);
- Collections.addAll(collection, columns);
- return this.withColumns(collection);
- }
-
- public Replace addColumns(Collection extends Column> columns) {
- List collection = Optional.ofNullable(getColumns()).orElseGet(ArrayList::new);
- collection.addAll(columns);
- return this.withColumns(collection);
- }
-
+ @Deprecated
public Replace addExpressions(Expression... expressions) {
- List collection = Optional.ofNullable(getExpressions()).orElseGet(ArrayList::new);
+ List collection = Optional.ofNullable( super.getSetExpressions() ).orElseGet(ArrayList::new);
Collections.addAll(collection, expressions);
return this.withExpressions(collection);
}
+ @Deprecated
public Replace addExpressions(Collection extends Expression> expressions) {
- List collection = Optional.ofNullable(getExpressions()).orElseGet(ArrayList::new);
+ List collection = Optional.ofNullable( super.getSetExpressions() ).orElseGet(ArrayList::new);
collection.addAll(expressions);
return this.withExpressions(collection);
}
-
- public E getItemsList(Class type) {
- return type.cast(getItemsList());
- }
}
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Distinct.java b/src/main/java/net/sf/jsqlparser/statement/select/Distinct.java
index 8cc89d5fd..6a1113bcd 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/Distinct.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/Distinct.java
@@ -9,13 +9,14 @@
*/
package net.sf.jsqlparser.statement.select;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
-public class Distinct {
+public class Distinct implements Serializable {
private List onSelectItems;
private boolean useUnique = false;
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/ExpressionListItem.java b/src/main/java/net/sf/jsqlparser/statement/select/ExpressionListItem.java
index 2bbe4dea9..0a8fee08c 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/ExpressionListItem.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/ExpressionListItem.java
@@ -12,7 +12,9 @@
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
-public class ExpressionListItem {
+import java.io.Serializable;
+
+public class ExpressionListItem implements Serializable {
private ExpressionList expressionList;
private Alias alias;
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Fetch.java b/src/main/java/net/sf/jsqlparser/statement/select/Fetch.java
index 9f625a162..80468b81b 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/Fetch.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/Fetch.java
@@ -11,7 +11,9 @@
import net.sf.jsqlparser.expression.JdbcParameter;
-public class Fetch {
+import java.io.Serializable;
+
+public class Fetch implements Serializable {
private long rowCount;
private JdbcParameter fetchJdbcParameter = null;
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/First.java b/src/main/java/net/sf/jsqlparser/statement/select/First.java
index 4ef0a3e8b..8a54cdf47 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/First.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/First.java
@@ -11,7 +11,9 @@
import net.sf.jsqlparser.expression.JdbcParameter;
-public class First {
+import java.io.Serializable;
+
+public class First implements Serializable {
public enum Keyword {
FIRST,
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 15c4f17c5..19400ce12 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/GroupByElement.java
@@ -9,6 +9,7 @@
*/
package net.sf.jsqlparser.statement.select;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -17,7 +18,7 @@
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
-public class GroupByElement {
+public class GroupByElement implements Serializable {
// ExpressionList has 'usingBrackets = true' and so we need to switch it off explicitly
private ExpressionList groupByExpressions = new ExpressionList().withUsingBrackets(false);
private List groupingSets = new ArrayList();
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 7c4200bef..e56b37cee 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/Join.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/Join.java
@@ -21,6 +21,7 @@ public class Join extends ASTNodeAccessImpl {
private boolean right = false;
private boolean left = false;
private boolean natural = false;
+ private boolean global = false;
private boolean full = false;
private boolean inner = false;
private boolean simple = false;
@@ -166,6 +167,10 @@ public boolean isNatural() {
return natural;
}
+ public boolean isGlobal() {
+ return global;
+ }
+
public Join withNatural(boolean b) {
this.setNatural(b);
return this;
@@ -175,6 +180,10 @@ public void setNatural(boolean b) {
natural = b;
}
+ public void setGlobal(boolean b) {
+ global = b;
+ }
+
/**
* Whether is a "FULL" join
*
@@ -299,6 +308,10 @@ public void setJoinWindow(KSQLJoinWindow joinWindow) {
public String toString() {
StringBuilder builder = new StringBuilder();
+ if ( isGlobal() ) {
+ builder.append("GLOBAL ");
+ }
+
if (isSimple() && isOuter()) {
builder.append("OUTER ").append(rightItem);
} else if (isSimple()) {
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Offset.java b/src/main/java/net/sf/jsqlparser/statement/select/Offset.java
index 22556d4d8..c9b1337e7 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/Offset.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/Offset.java
@@ -11,7 +11,9 @@
import net.sf.jsqlparser.expression.Expression;
-public class Offset {
+import java.io.Serializable;
+
+public class Offset implements Serializable {
private Expression offsetExpression = null;
private String offsetParam = null;
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/OptimizeFor.java b/src/main/java/net/sf/jsqlparser/statement/select/OptimizeFor.java
index 9c8bbb6d2..3e34219ba 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/OptimizeFor.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/OptimizeFor.java
@@ -9,10 +9,12 @@
*/
package net.sf.jsqlparser.statement.select;
+import java.io.Serializable;
+
/**
* A optimize for clause.
*/
-public class OptimizeFor {
+public class OptimizeFor implements Serializable {
private long rowCount;
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/OrderByElement.java b/src/main/java/net/sf/jsqlparser/statement/select/OrderByElement.java
index df07cf4bb..d9d1c6f85 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/OrderByElement.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/OrderByElement.java
@@ -11,7 +11,9 @@
import net.sf.jsqlparser.expression.Expression;
-public class OrderByElement {
+import java.io.Serializable;
+
+public class OrderByElement implements Serializable {
public enum NullOrdering {
NULLS_FIRST,
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Pivot.java b/src/main/java/net/sf/jsqlparser/statement/select/Pivot.java
index f3318ee5f..f95474854 100755
--- a/src/main/java/net/sf/jsqlparser/statement/select/Pivot.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/Pivot.java
@@ -9,6 +9,7 @@
*/
package net.sf.jsqlparser.statement.select;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -17,7 +18,7 @@
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.schema.Column;
-public class Pivot {
+public class Pivot implements Serializable {
private List functionItems;
private List forColumns;
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 6fc59b926..af61ef60b 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java
@@ -15,9 +15,11 @@
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
+import static java.util.stream.Collectors.joining;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.OracleHierarchicalExpression;
import net.sf.jsqlparser.expression.OracleHint;
+import net.sf.jsqlparser.expression.WindowDefinition;
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
import net.sf.jsqlparser.schema.Table;
@@ -46,6 +48,7 @@ public class PlainSelect extends ASTNodeAccessImpl implements SelectBody {
private boolean oracleSiblings = false;
private boolean forUpdate = false;
private Table forUpdateTable = null;
+ private boolean skipLocked;
private boolean useBrackets = false;
private Wait wait;
private boolean mySqlSqlCalcFoundRows = false;
@@ -55,6 +58,7 @@ public class PlainSelect extends ASTNodeAccessImpl implements SelectBody {
private boolean noWait = false;
private boolean emitChanges = false;
private WithIsolation withIsolation;
+ private List windowDefinitions;
public boolean isUseBrackets() {
return useBrackets;
@@ -230,8 +234,7 @@ public void setHaving(Expression expression) {
}
/**
- * A list of {@link Expression}s of the GROUP BY clause. It is null in case
- * there is no GROUP BY clause
+ * A list of {@link Expression}s of the GROUP BY clause. It is null in case there is no GROUP BY clause
*
* @return a list of {@link Expression}s
*/
@@ -331,7 +334,6 @@ public boolean isEmitChanges() {
return emitChanges;
}
-
public WithIsolation getWithIsolation() {
return withIsolation;
}
@@ -340,8 +342,24 @@ public void setWithIsolation(WithIsolation withIsolation) {
this.withIsolation = withIsolation;
}
+ public List getWindowDefinitions() {
+ return windowDefinitions;
+ }
+
+ public void setWindowDefinitions(List windowDefinitions) {
+ this.windowDefinitions = windowDefinitions;
+ }
+
+ public boolean isSkipLocked() {
+ return skipLocked;
+ }
+
+ public void setSkipLocked(boolean skipLocked) {
+ this.skipLocked = skipLocked;
+ }
+
@Override
- @SuppressWarnings({"PMD.CyclomaticComplexity" , "PMD.ExcessiveMethodLength", "PMD.NPathComplexity"})
+ @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.ExcessiveMethodLength", "PMD.NPathComplexity"})
public String toString() {
StringBuilder sql = new StringBuilder();
if (useBrackets) {
@@ -418,8 +436,14 @@ public String toString() {
if (having != null) {
sql.append(" HAVING ").append(having);
}
+
+ if (windowDefinitions != null) {
+ sql.append(" WINDOW ");
+ sql.append(windowDefinitions.stream().map(WindowDefinition::toString).collect(joining(", ")));
+ }
+
sql.append(orderByToString(oracleSiblings, orderByElements));
- if (emitChanges){
+ if (emitChanges) {
sql.append(" EMIT CHANGES");
}
if (limit != null) {
@@ -449,6 +473,8 @@ public String toString() {
if (isNoWait()) {
sql.append(" NOWAIT");
+ } else if (isSkipLocked()) {
+ sql.append(" SKIP LOCKED");
}
}
if (optimizeFor != null) {
@@ -471,7 +497,7 @@ public String toString() {
}
if (withIsolation != null) {
sql.append(withIsolation);
- }
+ }
}
if (forXmlPath != null) {
sql.append(" FOR XML PATH(").append(forXmlPath).append(")");
@@ -509,8 +535,8 @@ public static String getFormatedList(List> list, String expression, boolean us
}
/**
- * List the toString out put of the objects in the List comma separated. If the
- * List is null or empty an empty string is returned.
+ * List the toString out put of the objects in the List comma separated. If the List is null or empty an empty
+ * string is returned.
*
* The same as getStringList(list, true, false)
*
@@ -523,11 +549,11 @@ public static String getStringList(List> list) {
}
/**
- * List 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.
+ * List 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 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
*/
@@ -536,17 +562,17 @@ public static String getStringList(List> list, boolean useComma, boolean useBr
}
/**
- * 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.
+ * 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 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 ? "," : "";
+ String comma = useComma ? ", " : " ";
if (useBrackets) {
builder.append("(");
@@ -554,9 +580,9 @@ public static StringBuilder appendStringListTo(StringBuilder builder, List> li
int size = list.size();
for (int i = 0; i < size; i++) {
- builder.append(list.get(i)).append( i < size - 1
- ? comma + " "
- : "" );
+ builder.append(list.get(i)).append(i < size - 1
+ ? comma
+ : "");
}
if (useBrackets) {
@@ -705,6 +731,11 @@ public PlainSelect withNoWait(boolean noWait) {
return this;
}
+ public PlainSelect withSkipLocked(boolean skipLocked) {
+ this.setSkipLocked(skipLocked);
+ return this;
+ }
+
public PlainSelect withHaving(Expression having) {
this.setHaving(having);
return this;
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Skip.java b/src/main/java/net/sf/jsqlparser/statement/select/Skip.java
index f7af8f1f4..0031898d4 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/Skip.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/Skip.java
@@ -11,7 +11,9 @@
import net.sf.jsqlparser.expression.JdbcParameter;
-public class Skip {
+import java.io.Serializable;
+
+public class Skip implements Serializable {
private Long rowCount;
private JdbcParameter jdbcParameter;
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Top.java b/src/main/java/net/sf/jsqlparser/statement/select/Top.java
index 1c51cebe3..ad57c2a56 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/Top.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/Top.java
@@ -11,7 +11,9 @@
import net.sf.jsqlparser.expression.Expression;
-public class Top {
+import java.io.Serializable;
+
+public class Top implements Serializable {
private boolean hasParenthesis = false;
private boolean isPercentage = false;
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/UnPivot.java b/src/main/java/net/sf/jsqlparser/statement/select/UnPivot.java
index 699bfc5ac..3ae7acf50 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/UnPivot.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/UnPivot.java
@@ -12,9 +12,10 @@
import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.schema.Column;
+import java.io.Serializable;
import java.util.List;
-public class UnPivot {
+public class UnPivot implements Serializable {
private boolean includeNulls = false;
private boolean includeNullsSpecified = false;
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/ValuesList.java b/src/main/java/net/sf/jsqlparser/statement/select/ValuesList.java
index 70b9c9c6e..27c64c036 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/ValuesList.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/ValuesList.java
@@ -88,7 +88,7 @@ public String toString() {
StringBuilder b = new StringBuilder();
b.append("(VALUES ");
- for (Iterator it = getMultiExpressionList().getExprList().iterator(); it.
+ for (Iterator it = getMultiExpressionList().getExpressionLists().iterator(); it.
hasNext();) {
b.append(PlainSelect.getStringList(it.next().getExpressions(), true, !isNoBrackets()));
if (it.hasNext()) {
@@ -97,7 +97,7 @@ public String toString() {
}
b.append(")");
if (alias != null) {
- b.append(alias.toString());
+ b.append(alias);
if (columnNames != null) {
b.append("(");
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Wait.java b/src/main/java/net/sf/jsqlparser/statement/select/Wait.java
index 5045449a3..0d94e22a0 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/Wait.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/Wait.java
@@ -9,7 +9,9 @@
*/
package net.sf.jsqlparser.statement.select;
-public class Wait {
+import java.io.Serializable;
+
+public class Wait implements Serializable {
private long timeout;
diff --git a/src/main/java/net/sf/jsqlparser/statement/select/WithIsolation.java b/src/main/java/net/sf/jsqlparser/statement/select/WithIsolation.java
index 2fde93e2f..7aef6ef4e 100644
--- a/src/main/java/net/sf/jsqlparser/statement/select/WithIsolation.java
+++ b/src/main/java/net/sf/jsqlparser/statement/select/WithIsolation.java
@@ -10,7 +10,9 @@
package net.sf.jsqlparser.statement.select;
-public class WithIsolation {
+import java.io.Serializable;
+
+public class WithIsolation implements Serializable {
private String isolation = "UR";
diff --git a/src/main/java/net/sf/jsqlparser/statement/show/ShowIndexStatement.java b/src/main/java/net/sf/jsqlparser/statement/show/ShowIndexStatement.java
new file mode 100644
index 000000000..39a35d07c
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/statement/show/ShowIndexStatement.java
@@ -0,0 +1,54 @@
+ /*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2019 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.statement.show;
+
+import net.sf.jsqlparser.statement.Statement;
+import net.sf.jsqlparser.statement.StatementVisitor;
+
+/**
+*
+* @author Jayant Kumar Yadav
+*/
+
+public class ShowIndexStatement implements Statement {
+
+ private String tableName;
+
+ public ShowIndexStatement() {
+ // empty constructor
+ }
+
+ public ShowIndexStatement(String tableName) {
+ this.tableName = tableName;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ @Override
+ public String toString() {
+ return "SHOW INDEX FROM " + tableName;
+ }
+
+ @Override
+ public void accept(StatementVisitor statementVisitor) {
+ statementVisitor.visit(this);
+ }
+
+ public ShowIndexStatement withTableName(String tableName) {
+ this.setTableName(tableName);
+ return this;
+ }
+}
\ No newline at end of file
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 a25df6e5e..3cb26eaea 100644
--- a/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java
+++ b/src/main/java/net/sf/jsqlparser/statement/update/UpdateSet.java
@@ -13,11 +13,12 @@
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.schema.Column;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
-public class UpdateSet {
+public class UpdateSet implements Serializable {
protected boolean usingBracketsForColumns = false;
protected boolean usingBracketsForValues = false;
protected ArrayList columns = new ArrayList<>();
diff --git a/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java b/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java
index e68969691..ed602836e 100644
--- a/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java
+++ b/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java
@@ -9,12 +9,8 @@
*/
package net.sf.jsqlparser.statement.upsert;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
@@ -23,6 +19,12 @@
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
public class Upsert implements Statement {
private Table table;
@@ -35,10 +37,40 @@ public class Upsert implements Statement {
private List duplicateUpdateColumns;
private List duplicateUpdateExpressionList;
+ private UpsertType upsertType = UpsertType.UPSERT;
+
+ private boolean isUsingInto;
+
@Override
public void accept(StatementVisitor statementVisitor) {
statementVisitor.visit(this);
}
+
+ public UpsertType getUpsertType() {
+ return upsertType;
+ }
+
+ public void setUpsertType(UpsertType upsertType) {
+ this.upsertType=upsertType;
+ }
+
+ public Upsert withUpsertType(UpsertType upsertType) {
+ setUpsertType(upsertType);
+ return this;
+ }
+
+ public boolean isUsingInto() {
+ return isUsingInto;
+ }
+
+ public void setUsingInto(boolean useInto) {
+ this.isUsingInto = useInto;
+ }
+
+ public Upsert withUsingInto(boolean useInto) {
+ setUsingInto(useInto);
+ return this;
+ }
public void setTable(Table name) {
table = name;
@@ -63,6 +95,15 @@ public void setItemsList(ItemsList list) {
public ItemsList getItemsList() {
return itemsList;
}
+
+ public List getSetExpressions() {
+ List expressions = null;
+ if (itemsList instanceof ExpressionList) {
+ ExpressionList expressionList = (ExpressionList) itemsList;
+ expressions= expressionList.getExpressions();
+ }
+ return expressions;
+ }
public void setUseValues(boolean useValues) {
this.useValues = useValues;
@@ -113,30 +154,70 @@ public List getDuplicateUpdateExpressionList() {
}
@Override
- @SuppressWarnings({"PMD.CyclomaticComplexity"})
+ @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
public String toString() {
StringBuilder sb = new StringBuilder();
-
- sb.append("UPSERT INTO ");
- sb.append(table).append(" ");
- if (columns != null) {
- sb.append(PlainSelect.getStringList(columns, true, true)).append(" ");
- }
- if (useValues) {
- sb.append("VALUES ");
+
+ switch (upsertType) {
+ case REPLACE:
+ case REPLACE_SET:
+ sb.append("REPLACE ");
+ break;
+ case INSERT_OR_ABORT:
+ sb.append("INSERT OR ABORT ");
+ break;
+ case INSERT_OR_FAIL:
+ sb.append("INSERT OR FAIL ");
+ break;
+ case INSERT_OR_IGNORE:
+ sb.append("INSERT OR IGNORE ");
+ break;
+ case INSERT_OR_REPLACE:
+ sb.append("INSERT OR REPLACE ");
+ break;
+ case INSERT_OR_ROLLBACK:
+ sb.append("INSERT OR ROLLBACK ");
+ break;
+ case UPSERT:
+ default:
+ sb.append("UPSERT ");
}
- if (itemsList != null) {
- sb.append(itemsList);
+ if (isUsingInto) {
+ sb.append("INTO ");
+ }
+ sb.append(table).append(" ");
+
+ if (upsertType==UpsertType.REPLACE_SET) {
+ sb.append("SET ");
+ // each element from expressions match up with a column from columns.
+ List expressions = getSetExpressions();
+ for (int i = 0, s = columns.size(); i < s; i++) {
+ sb.append(columns.get(i)).append("=").append(expressions.get(i));
+ sb.append( i < s - 1
+ ? ", "
+ : "" );
+ }
} else {
- if (useSelectBrackets) {
- sb.append("(");
+ if (columns != null) {
+ sb.append(PlainSelect.getStringList(columns, true, true)).append(" ");
}
- if (select != null) {
- sb.append(select);
+ if (useValues) {
+ sb.append("VALUES ");
}
- if (useSelectBrackets) {
- sb.append(")");
+
+ if (itemsList != null) {
+ sb.append(itemsList);
+ } else {
+ if (useSelectBrackets) {
+ sb.append("(");
+ }
+ if (select != null) {
+ sb.append(select);
+ }
+ if (useSelectBrackets) {
+ sb.append(")");
+ }
}
}
diff --git a/src/main/java/net/sf/jsqlparser/statement/upsert/UpsertType.java b/src/main/java/net/sf/jsqlparser/statement/upsert/UpsertType.java
new file mode 100644
index 000000000..63f34785a
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/statement/upsert/UpsertType.java
@@ -0,0 +1,21 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2023 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.statement.upsert;
+
+public enum UpsertType {
+ UPSERT
+ , REPLACE
+ , REPLACE_SET
+ , INSERT_OR_ABORT
+ , INSERT_OR_FAIL
+ , INSERT_OR_IGNORE
+ , INSERT_OR_REPLACE
+ , INSERT_OR_ROLLBACK
+}
diff --git a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
index 945b163a1..566f06f74 100644
--- a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
+++ b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
@@ -13,15 +13,119 @@
import java.util.List;
import java.util.Map;
-import net.sf.jsqlparser.expression.*;
-import net.sf.jsqlparser.expression.operators.arithmetic.*;
+import net.sf.jsqlparser.expression.AllValue;
+import net.sf.jsqlparser.expression.AnalyticExpression;
+import net.sf.jsqlparser.expression.AnyComparisonExpression;
+import net.sf.jsqlparser.expression.ArrayConstructor;
+import net.sf.jsqlparser.expression.ArrayExpression;
+import net.sf.jsqlparser.expression.BinaryExpression;
+import net.sf.jsqlparser.expression.CaseExpression;
+import net.sf.jsqlparser.expression.CastExpression;
+import net.sf.jsqlparser.expression.CollateExpression;
+import net.sf.jsqlparser.expression.ConnectByRootOperator;
+import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
+import net.sf.jsqlparser.expression.DateValue;
+import net.sf.jsqlparser.expression.DoubleValue;
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.ExpressionVisitor;
+import net.sf.jsqlparser.expression.ExtractExpression;
+import net.sf.jsqlparser.expression.Function;
+import net.sf.jsqlparser.expression.HexValue;
+import net.sf.jsqlparser.expression.IntervalExpression;
+import net.sf.jsqlparser.expression.JdbcNamedParameter;
+import net.sf.jsqlparser.expression.JdbcParameter;
+import net.sf.jsqlparser.expression.JsonAggregateFunction;
+import net.sf.jsqlparser.expression.JsonExpression;
+import net.sf.jsqlparser.expression.JsonFunction;
+import net.sf.jsqlparser.expression.JsonFunctionExpression;
+import net.sf.jsqlparser.expression.KeepExpression;
+import net.sf.jsqlparser.expression.LongValue;
+import net.sf.jsqlparser.expression.MySQLGroupConcat;
+import net.sf.jsqlparser.expression.NextValExpression;
+import net.sf.jsqlparser.expression.NotExpression;
+import net.sf.jsqlparser.expression.NullValue;
+import net.sf.jsqlparser.expression.NumericBind;
+import net.sf.jsqlparser.expression.OracleHierarchicalExpression;
+import net.sf.jsqlparser.expression.OracleHint;
+import net.sf.jsqlparser.expression.OracleNamedFunctionParameter;
+import net.sf.jsqlparser.expression.OverlapsCondition;
+import net.sf.jsqlparser.expression.Parenthesis;
+import net.sf.jsqlparser.expression.RowConstructor;
+import net.sf.jsqlparser.expression.RowGetExpression;
+import net.sf.jsqlparser.expression.SafeCastExpression;
+import net.sf.jsqlparser.expression.SignedExpression;
+import net.sf.jsqlparser.expression.StringValue;
+import net.sf.jsqlparser.expression.TimeKeyExpression;
+import net.sf.jsqlparser.expression.TimeValue;
+import net.sf.jsqlparser.expression.TimestampValue;
+import net.sf.jsqlparser.expression.TimezoneExpression;
+import net.sf.jsqlparser.expression.TryCastExpression;
+import net.sf.jsqlparser.expression.UserVariable;
+import net.sf.jsqlparser.expression.ValueListExpression;
+import net.sf.jsqlparser.expression.VariableAssignment;
+import net.sf.jsqlparser.expression.WhenClause;
+import net.sf.jsqlparser.expression.XMLSerializeExpr;
+import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseLeftShift;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseRightShift;
+import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
+import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
+import net.sf.jsqlparser.expression.operators.arithmetic.Division;
+import net.sf.jsqlparser.expression.operators.arithmetic.IntegerDivision;
+import net.sf.jsqlparser.expression.operators.arithmetic.Modulo;
+import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
+import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.conditional.XorExpression;
-import net.sf.jsqlparser.expression.operators.relational.*;
+import net.sf.jsqlparser.expression.operators.relational.Between;
+import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
+import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
+import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
+import net.sf.jsqlparser.expression.operators.relational.FullTextSearch;
+import net.sf.jsqlparser.expression.operators.relational.GeometryDistance;
+import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
+import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
+import net.sf.jsqlparser.expression.operators.relational.InExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsBooleanExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsDistinctExpression;
+import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
+import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor;
+import net.sf.jsqlparser.expression.operators.relational.JsonOperator;
+import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
+import net.sf.jsqlparser.expression.operators.relational.Matches;
+import net.sf.jsqlparser.expression.operators.relational.MinorThan;
+import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
+import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
+import net.sf.jsqlparser.expression.operators.relational.NamedExpressionList;
+import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
+import net.sf.jsqlparser.expression.operators.relational.RegExpMatchOperator;
+import net.sf.jsqlparser.expression.operators.relational.RegExpMySQLOperator;
+import net.sf.jsqlparser.expression.operators.relational.SimilarToExpression;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
-import net.sf.jsqlparser.statement.*;
+import net.sf.jsqlparser.statement.Block;
+import net.sf.jsqlparser.statement.Commit;
+import net.sf.jsqlparser.statement.CreateFunctionalStatement;
+import net.sf.jsqlparser.statement.DeclareStatement;
+import net.sf.jsqlparser.statement.DescribeStatement;
+import net.sf.jsqlparser.statement.ExplainStatement;
+import net.sf.jsqlparser.statement.IfElseStatement;
+import net.sf.jsqlparser.statement.PurgeObjectType;
+import net.sf.jsqlparser.statement.PurgeStatement;
+import net.sf.jsqlparser.statement.ResetStatement;
+import net.sf.jsqlparser.statement.RollbackStatement;
+import net.sf.jsqlparser.statement.SavepointStatement;
+import net.sf.jsqlparser.statement.SetStatement;
+import net.sf.jsqlparser.statement.ShowColumnsStatement;
+import net.sf.jsqlparser.statement.ShowStatement;
+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;
@@ -62,6 +166,7 @@
import net.sf.jsqlparser.statement.select.TableFunction;
import net.sf.jsqlparser.statement.select.ValuesList;
import net.sf.jsqlparser.statement.select.WithItem;
+import net.sf.jsqlparser.statement.show.ShowIndexStatement;
import net.sf.jsqlparser.statement.show.ShowTablesStatement;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;
@@ -189,6 +294,12 @@ public void visit(Between between) {
between.getBetweenExpressionEnd().accept(this);
}
+ @Override
+ public void visit(OverlapsCondition overlapsCondition) {
+ overlapsCondition.getLeft().accept(this);
+ overlapsCondition.getRight().accept(this);
+ }
+
@Override
public void visit(Column tableColumn) {
if (allowColumnProcessing && tableColumn.getTable() != null && tableColumn.getTable().getName() != null) {
@@ -468,6 +579,11 @@ public void visit(TryCastExpression cast) {
cast.getLeftExpression().accept(this);
}
+ @Override
+ public void visit(SafeCastExpression cast) {
+ cast.getLeftExpression().accept(this);
+ }
+
@Override
public void visit(Modulo modulo) {
visitBinaryExpression(modulo);
@@ -753,6 +869,11 @@ public void visit(ShowColumnsStatement set) {
throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
}
+ @Override
+ public void visit(ShowIndexStatement showIndex) {
+ throw new UnsupportedOperationException(NOT_SUPPORTED_YET);
+ }
+
@Override
public void visit(RowConstructor rowConstructor) {
for (Expression expr : rowConstructor.getExprList().getExpressions()) {
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/CreateTableDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/CreateTableDeParser.java
index 4036d9ad0..d930e944c 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/CreateTableDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/CreateTableDeParser.java
@@ -120,6 +120,9 @@ public void deParse(CreateTable createTable) {
buffer.append(")");
}
}
+ if (createTable.getSpannerInterleaveIn() != null) {
+ buffer.append(", ").append(createTable.getSpannerInterleaveIn());
+ }
}
}
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/CreateViewDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/CreateViewDeParser.java
index fd9dd958c..8eb03ae53 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/CreateViewDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/CreateViewDeParser.java
@@ -11,6 +11,7 @@
import net.sf.jsqlparser.statement.create.view.CreateView;
import net.sf.jsqlparser.statement.create.view.TemporaryOption;
+import net.sf.jsqlparser.statement.create.view.AutoRefreshOption;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectVisitor;
@@ -42,16 +43,16 @@ public void deParse(CreateView createView) {
buffer.append("OR REPLACE ");
}
switch (createView.getForce()) {
- case FORCE:
- buffer.append("FORCE ");
- break;
- case NO_FORCE:
- buffer.append("NO FORCE ");
- break;
- case NONE:
- break;
- default:
- // nothing
+ case FORCE:
+ buffer.append("FORCE ");
+ break;
+ case NO_FORCE:
+ buffer.append("NO FORCE ");
+ break;
+ case NONE:
+ break;
+ default:
+ // nothing
}
if (createView.getTemporary() != TemporaryOption.NONE) {
buffer.append(createView.getTemporary().name()).append(" ");
@@ -60,6 +61,12 @@ public void deParse(CreateView createView) {
buffer.append("MATERIALIZED ");
}
buffer.append("VIEW ").append(createView.getView().getFullyQualifiedName());
+ if (createView.isIfNotExists()) {
+ buffer.append(" IF NOT EXISTS");
+ }
+ if (createView.getAutoRefresh() != AutoRefreshOption.NONE) {
+ buffer.append(" AUTO REFRESH ").append(createView.getAutoRefresh().name());
+ }
if (createView.getColumnNames() != null) {
buffer.append(PlainSelect.getStringList(createView.getColumnNames(), true, true));
}
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 0ec7c9a19..090a2cad1 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/DropDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/DropDeParser.java
@@ -21,6 +21,12 @@ public DropDeParser(StringBuilder buffer) {
@Override
public void deParse(Drop drop) {
buffer.append("DROP ");
+ if (drop.isUsingTemporary()) {
+ buffer.append("TEMPORARY ");
+ }
+ if (drop.isMaterialized()) {
+ buffer.append("MATERIALIZED ");
+ }
buffer.append(drop.getType());
if (drop.isIfExists()) {
buffer.append(" IF EXISTS");
@@ -33,7 +39,7 @@ public void deParse(Drop drop) {
}
if (drop.getParameters() != null && !drop.getParameters().isEmpty()) {
- buffer.append(" ").append(PlainSelect.getStringList(drop.getParameters()));
+ buffer.append(" ").append(PlainSelect.getStringList(drop.getParameters(), false, false));
}
}
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java
index 0cef345fe..33cd00aab 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java
@@ -107,6 +107,11 @@ public void visit(Between between) {
}
+ @Override
+ public void visit(OverlapsCondition overlapsCondition) {
+ buffer.append(overlapsCondition.toString());
+ }
+
@Override
public void visit(EqualsTo equalsTo) {
visitOldOracleJoinBinaryExpression(equalsTo, " = ");
@@ -324,6 +329,7 @@ public void visit(OrExpression orExpression) {
visitBinaryExpression(orExpression, " OR ");
}
+
@Override
public void visit(XorExpression xorExpression) {
visitBinaryExpression(xorExpression, " XOR ");
@@ -459,19 +465,7 @@ public void visit(Function function) {
@Override
public void visit(ExpressionList expressionList) {
- if (expressionList.isUsingBrackets()) {
- buffer.append("(");
- }
- for (Iterator iter = expressionList.getExpressions().iterator(); iter.hasNext();) {
- Expression expression = iter.next();
- expression.accept(this);
- if (iter.hasNext()) {
- buffer.append(", ");
- }
- }
- if (expressionList.isUsingBrackets()) {
- buffer.append(")");
- }
+ new ExpressionListDeParser(this, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
}
@Override
@@ -550,7 +544,7 @@ public void visit(WhenClause whenClause) {
public void visit(AnyComparisonExpression anyComparisonExpression) {
buffer.append(anyComparisonExpression.getAnyType().name()).append(" ( ");
SubSelect subSelect = anyComparisonExpression.getSubSelect();
- if (subSelect!=null) {
+ if (subSelect != null) {
subSelect.accept((ExpressionVisitor) this);
} else {
ExpressionList expressionList = (ExpressionList) anyComparisonExpression.getItemsList();
@@ -558,7 +552,7 @@ public void visit(AnyComparisonExpression anyComparisonExpression) {
buffer.append(
PlainSelect.getStringList(expressionList.getExpressions(), true, anyComparisonExpression.isUsingBracketsForValues()));
}
- buffer.append(" ) ");
+ buffer.append(" ) ");
}
@Override
@@ -592,7 +586,7 @@ public void visit(CastExpression cast) {
buffer.append("CAST(");
cast.getLeftExpression().accept(this);
buffer.append(" AS ");
- buffer.append( cast.getRowConstructor()!=null ? cast.getRowConstructor() : cast.getType() );
+ buffer.append(cast.getRowConstructor() != null ? cast.getRowConstructor() : cast.getType());
buffer.append(")");
} else {
cast.getLeftExpression().accept(this);
@@ -607,7 +601,7 @@ public void visit(TryCastExpression cast) {
buffer.append("TRY_CAST(");
cast.getLeftExpression().accept(this);
buffer.append(" AS ");
- buffer.append( cast.getRowConstructor()!=null ? cast.getRowConstructor() : cast.getType() );
+ buffer.append(cast.getRowConstructor() != null ? cast.getRowConstructor() : cast.getType());
buffer.append(")");
} else {
cast.getLeftExpression().accept(this);
@@ -616,6 +610,22 @@ public void visit(TryCastExpression cast) {
}
}
+ @Override
+ public void visit(SafeCastExpression cast) {
+ if (cast.isUseCastKeyword()) {
+ buffer.append("SAFE_CAST(");
+ cast.getLeftExpression().accept(this);
+ buffer.append(" AS ");
+ buffer.append(cast.getRowConstructor() != null ? cast.getRowConstructor() : cast.getType());
+ buffer.append(")");
+ } else {
+ cast.getLeftExpression().accept(this);
+ buffer.append("::");
+ buffer.append(cast.getType());
+ }
+
+ }
+
@Override
public void visit(Modulo modulo) {
visitBinaryExpression(modulo, " % ");
@@ -659,9 +669,9 @@ public void visit(AnalyticExpression aexpr) {
}
if (aexpr.getFuncOrderBy() != null) {
buffer.append(" ORDER BY ");
- buffer.append( aexpr.getFuncOrderBy().stream().map(OrderByElement::toString).collect(joining(", ")));
+ buffer.append(aexpr.getFuncOrderBy().stream().map(OrderByElement::toString).collect(joining(", ")));
}
-
+
buffer.append(") ");
if (keep != null) {
keep.accept(this);
@@ -676,7 +686,7 @@ public void visit(AnalyticExpression aexpr) {
buffer.append(" ");
}
}
-
+
if (aexpr.isIgnoreNullsOutside()) {
buffer.append("IGNORE NULLS ");
}
@@ -687,48 +697,60 @@ public void visit(AnalyticExpression aexpr) {
case WITHIN_GROUP:
buffer.append("WITHIN GROUP");
break;
+ case WITHIN_GROUP_OVER:
+ buffer.append("WITHIN GROUP (");
+ aexpr.getWindowDefinition().getOrderBy().toStringOrderByElements(buffer);
+ buffer.append(") OVER (");
+ aexpr.getWindowDefinition().getPartitionBy().toStringPartitionBy(buffer);
+ buffer.append(")");
+ break;
default:
buffer.append("OVER");
}
- buffer.append(" (");
- if (partitionExpressionList != null && !partitionExpressionList.getExpressions().isEmpty()) {
- buffer.append("PARTITION BY ");
- if (aexpr.isPartitionByBrackets()) {
- buffer.append("(");
- }
- List expressions = partitionExpressionList.getExpressions();
- for (int i = 0; i < expressions.size(); i++) {
- if (i > 0) {
- buffer.append(", ");
+ if (aexpr.getWindowName() != null) {
+ buffer.append(" ").append(aexpr.getWindowName());
+ } else if (aexpr.getType()!=AnalyticType.WITHIN_GROUP_OVER) {
+ buffer.append(" (");
+
+ if (partitionExpressionList != null && !partitionExpressionList.getExpressions().isEmpty()) {
+ buffer.append("PARTITION BY ");
+ if (aexpr.isPartitionByBrackets()) {
+ buffer.append("(");
}
- expressions.get(i).accept(this);
- }
- if (aexpr.isPartitionByBrackets()) {
- buffer.append(")");
+ List expressions = partitionExpressionList.getExpressions();
+ for (int i = 0; i < expressions.size(); i++) {
+ if (i > 0) {
+ buffer.append(", ");
+ }
+ expressions.get(i).accept(this);
+ }
+ if (aexpr.isPartitionByBrackets()) {
+ buffer.append(")");
+ }
+ buffer.append(" ");
}
- buffer.append(" ");
- }
- if (orderByElements != null && !orderByElements.isEmpty()) {
- buffer.append("ORDER BY ");
- orderByDeParser.setExpressionVisitor(this);
- orderByDeParser.setBuffer(buffer);
- for (int i = 0; i < orderByElements.size(); i++) {
- if (i > 0) {
- buffer.append(", ");
+ if (orderByElements != null && !orderByElements.isEmpty()) {
+ buffer.append("ORDER BY ");
+ orderByDeParser.setExpressionVisitor(this);
+ orderByDeParser.setBuffer(buffer);
+ for (int i = 0; i < orderByElements.size(); i++) {
+ if (i > 0) {
+ buffer.append(", ");
+ }
+ orderByDeParser.deParseElement(orderByElements.get(i));
}
- orderByDeParser.deParseElement(orderByElements.get(i));
}
- }
- if (windowElement != null) {
- if (orderByElements != null && !orderByElements.isEmpty()) {
- buffer.append(' ');
+ if (windowElement != null) {
+ if (orderByElements != null && !orderByElements.isEmpty()) {
+ buffer.append(' ');
+ }
+ buffer.append(windowElement);
}
- buffer.append(windowElement);
- }
- buffer.append(")");
+ buffer.append(")");
+ }
}
@Override
@@ -806,7 +828,8 @@ public void visit(MySQLGroupConcat groupConcat) {
@Override
public void visit(ValueListExpression valueList) {
- buffer.append(valueList.toString());
+ ExpressionList expressionList = valueList.getExpressionList();
+ expressionList.accept(this);
}
@Override
@@ -815,12 +838,12 @@ public void visit(RowConstructor rowConstructor) {
buffer.append(rowConstructor.getName());
}
buffer.append("(");
-
- if (rowConstructor.getColumnDefinitions().size()>0) {
+
+ if (rowConstructor.getColumnDefinitions().size() > 0) {
buffer.append("(");
int i = 0;
- for (ColumnDefinition columnDefinition:rowConstructor.getColumnDefinitions()) {
- buffer.append(i>0 ? ", " : "").append(columnDefinition.toString());
+ for (ColumnDefinition columnDefinition : rowConstructor.getColumnDefinitions()) {
+ buffer.append(i > 0 ? ", " : "").append(columnDefinition.toString());
i++;
}
buffer.append(")");
@@ -861,7 +884,7 @@ public void visit(DateTimeLiteralExpression literal) {
@Override
public void visit(NextValExpression nextVal) {
- buffer.append(nextVal.isUsingNextValueFor() ? "NEXT VALUE FOR " : "NEXTVAL FOR ").append(nextVal.getName());
+ buffer.append(nextVal.isUsingNextValueFor() ? "NEXT VALUE FOR " : "NEXTVAL FOR ").append(nextVal.getName());
}
@Override
@@ -929,7 +952,7 @@ public void visit(XMLSerializeExpr expr) {
buffer.append("xmlserialize(xmlagg(xmltext(");
expr.getExpression().accept(this);
buffer.append(")");
- if (expr.getOrderByElements() != null){
+ if (expr.getOrderByElements() != null) {
buffer.append(" ORDER BY ");
for (Iterator i = expr.getOrderByElements().iterator(); i.hasNext();) {
buffer.append(i.next().toString());
@@ -958,9 +981,9 @@ public void visit(JsonAggregateFunction expression) {
@Override
public void visit(JsonFunction expression) {
- expression.append(buffer);
+ expression.append(buffer);
}
-
+
@Override
public void visit(ConnectByRootOperator connectByRootOperator) {
buffer.append("CONNECT_BY_ROOT ");
@@ -970,9 +993,9 @@ public void visit(ConnectByRootOperator connectByRootOperator) {
@Override
public void visit(OracleNamedFunctionParameter oracleNamedFunctionParameter) {
buffer
- .append(oracleNamedFunctionParameter.getName())
- .append(" => ");
-
+ .append(oracleNamedFunctionParameter.getName())
+ .append(" => ");
+
oracleNamedFunctionParameter.getExpression().accept(this);
}
@@ -993,9 +1016,9 @@ public void visit(AllValue allValue) {
@Override
public void visit(IsDistinctExpression isDistinctExpression) {
- buffer.append(isDistinctExpression.getLeftExpression() +
- isDistinctExpression.getStringExpression() +
- isDistinctExpression.getRightExpression());
+ buffer.append(isDistinctExpression.getLeftExpression()
+ + isDistinctExpression.getStringExpression()
+ + isDistinctExpression.getRightExpression());
}
@Override
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionListDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionListDeParser.java
new file mode 100644
index 000000000..0a39e6cdd
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/ExpressionListDeParser.java
@@ -0,0 +1,52 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2019 JSQLParser
+ * %%
+ * Dual licensed under GNU LGPL 2.1 or Apache License 2.0
+ * #L%
+ */
+package net.sf.jsqlparser.util.deparser;
+
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.ExpressionVisitor;
+
+import java.util.Collection;
+
+public class ExpressionListDeParser extends AbstractDeParser> {
+
+ private final ExpressionVisitor expressionVisitor;
+ private final boolean useBrackets;
+ private final boolean useComma;
+
+ public ExpressionListDeParser(ExpressionVisitor expressionVisitor, StringBuilder builder, boolean useBrackets, boolean useComma) {
+ super(builder);
+ this.expressionVisitor = expressionVisitor;
+ this.useBrackets = useBrackets;
+ this.useComma = useComma;
+ }
+
+ @Override
+ public void deParse(Collection expressions) {
+ if (expressions != null) {
+ String comma = useComma ? ", " : " ";
+ if (useBrackets) {
+ buffer.append("(");
+ }
+ int i=0;
+ int size = expressions.size() - 1;
+ for (Expression expression: expressions) {
+ expression.accept(expressionVisitor);
+ if (i iter = expressionList.getExpressions().iterator(); iter.hasNext();) {
- Expression expression = iter.next();
- expression.accept(expressionVisitor);
- if (iter.hasNext()) {
- buffer.append(", ");
- }
- }
- buffer.append(")");
+ new ExpressionListDeParser(expressionVisitor, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
}
@Override
@@ -165,20 +160,15 @@ public void visit(NamedExpressionList NamedExpressionList) {
@Override
public void visit(MultiExpressionList multiExprList) {
- buffer.append(" VALUES ");
- for (Iterator it = multiExprList.getExprList().iterator(); it.hasNext();) {
- buffer.append("(");
- for (Iterator iter = it.next().getExpressions().iterator(); iter.hasNext();) {
- Expression expression = iter.next();
- expression.accept(expressionVisitor);
- if (iter.hasNext()) {
- buffer.append(", ");
- }
- }
- buffer.append(")");
- if (it.hasNext()) {
+ List expressionLists = multiExprList.getExpressionLists();
+ int n = expressionLists.size() - 1;
+ int i = 0;
+ for (ExpressionList expressionList : expressionLists) {
+ new ExpressionListDeParser(expressionVisitor, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
+ if (i 1))
+ unPivotClause != null && unPivotClause.size() > 1))
.append(" FOR ").append(PlainSelect.getStringList(unpivotForClause, true,
- unpivotForClause != null && unpivotForClause.size() > 1))
+ unpivotForClause != null && unpivotForClause.size() > 1))
.append(" IN ").append(PlainSelect.getStringList(unpivot.getUnPivotInClause(), true, true)).append(")");
if (unpivot.getAlias() != null) {
buffer.append(unpivot.getAlias().toString());
@@ -395,6 +401,10 @@ public void visit(SubJoin subjoin) {
@SuppressWarnings({"PMD.CyclomaticComplexity"})
public void deparseJoin(Join join) {
+ if ( join.isGlobal() ) {
+ buffer.append(" GLOBAL ");
+ }
+
if (join.isSimple() && join.isOuter()) {
buffer.append(", OUTER ");
} else if (join.isSimple()) {
@@ -443,7 +453,7 @@ public void deparseJoin(Join join) {
buffer.append(" ON ");
onExpression.accept(expressionVisitor);
}
- if (join.getUsingColumns().size()>0) {
+ if (join.getUsingColumns().size() > 0) {
buffer.append(" USING (");
for (Iterator iterator = join.getUsingColumns().iterator(); iterator.hasNext();) {
Column column = iterator.next();
@@ -529,7 +539,32 @@ public void visit(LateralSubSelect lateralSubSelect) {
@Override
public void visit(ValuesList valuesList) {
- buffer.append(valuesList.toString());
+ buffer.append("(VALUES ");
+ List expressionLists = valuesList.getMultiExpressionList().getExpressionLists();
+ int n = expressionLists.size() - 1;
+ int i = 0;
+ for (ExpressionList expressionList : expressionLists) {
+ new ExpressionListDeParser(expressionVisitor, buffer, !valuesList.isNoBrackets(), true).deParse(expressionList.getExpressions());
+ if (i it = valuesList.getColumnNames().iterator(); it.hasNext();) {
+ buffer.append(it.next());
+ if (it.hasNext()) {
+ buffer.append(", ");
+ }
+ }
+ buffer.append(")");
+ }
+ }
}
@Override
@@ -546,7 +581,7 @@ public void visit(TableFunction tableFunction) {
public void visit(ParenthesisFromItem parenthesis) {
buffer.append("(");
parenthesis.getFromItem().accept(this);
-
+
buffer.append(")");
if (parenthesis.getAlias() != null) {
buffer.append(parenthesis.getAlias().toString());
@@ -571,16 +606,41 @@ void deParse(PlainSelect statement) {
@Override
public void visit(ExpressionList expressionList) {
- buffer.append(expressionList.toString());
+ new ExpressionListDeParser(expressionVisitor, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
}
@Override
public void visit(NamedExpressionList namedExpressionList) {
buffer.append(namedExpressionList.toString());
+
+ buffer.append("(");
+ List expressions = namedExpressionList.getExpressions();
+ List names = namedExpressionList.getNames();
+ for (int i = 0; i < expressions.size(); i++) {
+ Expression expression = expressions.get(i);
+ String name = names.get(i);
+ if (i > 0) {
+ buffer.append(" ");
+ }
+ if (!name.equals("")) {
+ buffer.append(name).append(" ");
+ }
+ expression.accept(expressionVisitor);
+ }
+ buffer.append(")");
}
@Override
public void visit(MultiExpressionList multiExprList) {
- buffer.append(multiExprList.toString());
+ List expressionLists = multiExprList.getExpressionLists();
+ int n = expressionLists.size() - 1;
+ int i = 0;
+ for (ExpressionList expressionList : expressionLists) {
+ new ExpressionListDeParser(expressionVisitor, buffer, expressionList.isUsingBrackets(), true).deParse(expressionList.getExpressions());
+ if (i {
+
+ public ShowIndexStatementDeParser(StringBuilder buffer) {
+ super(buffer);
+ }
+
+ @Override
+ public void deParse(ShowIndexStatement show) {
+ buffer.append("SHOW INDEX FROM ").append(show.getTableName());
+ }
+
+}
\ No newline at end of file
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 f10651f22..5c5a99cc7 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java
@@ -54,6 +54,7 @@
import net.sf.jsqlparser.statement.replace.Replace;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.WithItem;
+import net.sf.jsqlparser.statement.show.ShowIndexStatement;
import net.sf.jsqlparser.statement.show.ShowTablesStatement;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;
@@ -278,6 +279,11 @@ public void visit(UseStatement use) {
public void visit(ShowColumnsStatement show) {
new ShowColumnsStatementDeParser(buffer).deParse(show);
}
+
+ @Override
+ public void visit(ShowIndexStatement showIndexes) {
+ new ShowIndexStatementDeParser(buffer).deParse(showIndexes);
+ }
@Override
public void visit(ShowTablesStatement showTables) {
@@ -294,6 +300,9 @@ public void visit(Block block) {
}
}
buffer.append("END");
+ if (block.hasSemicolonAfterEnd()) {
+ buffer.append(";");
+ }
}
@Override
diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java
index 32311c47b..05e42053e 100644
--- a/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java
+++ b/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java
@@ -9,8 +9,6 @@
*/
package net.sf.jsqlparser.util.deparser;
-import java.util.Iterator;
-
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
@@ -22,6 +20,10 @@
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.WithItem;
import net.sf.jsqlparser.statement.upsert.Upsert;
+import net.sf.jsqlparser.statement.upsert.UpsertType;
+
+import java.util.Iterator;
+import java.util.List;
@SuppressWarnings({"PMD.UncommentedEmptyMethodBody"})
public class UpsertDeParser extends AbstractDeParser implements ItemsListVisitor {
@@ -36,26 +38,69 @@ public UpsertDeParser(ExpressionVisitor expressionVisitor, SelectVisitor selectV
}
@Override
+ @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
public void deParse(Upsert upsert) {
- buffer.append("UPSERT INTO ");
-
- buffer.append(upsert.getTable().getFullyQualifiedName());
- if (upsert.getColumns() != null) {
- appendColumns(upsert);
+ switch (upsert.getUpsertType()) {
+ case REPLACE:
+ case REPLACE_SET:
+ buffer.append("REPLACE ");
+ break;
+ case INSERT_OR_ABORT:
+ buffer.append("INSERT OR ABORT ");
+ break;
+ case INSERT_OR_FAIL:
+ buffer.append("INSERT OR FAIL ");
+ break;
+ case INSERT_OR_IGNORE:
+ buffer.append("INSERT OR IGNORE ");
+ break;
+ case INSERT_OR_REPLACE:
+ buffer.append("INSERT OR REPLACE ");
+ break;
+ case INSERT_OR_ROLLBACK:
+ buffer.append("INSERT OR ROLLBACK ");
+ break;
+ case UPSERT:
+ default:
+ buffer.append("UPSERT ");
}
- if (upsert.getItemsList() != null) {
- upsert.getItemsList().accept(this);
+ if (upsert.isUsingInto()) {
+ buffer.append("INTO ");
}
+ buffer.append(upsert.getTable().getFullyQualifiedName());
- if (upsert.getSelect() != null) {
- appendSelect(upsert);
- }
+ if (upsert.getUpsertType() == UpsertType.REPLACE_SET) {
+ appendReplaceSetClause(upsert);
+ } else {
+ if (upsert.getColumns() != null) {
+ appendColumns(upsert);
+ }
+
+ if (upsert.getItemsList() != null) {
+ upsert.getItemsList().accept(this);
+ }
+
+ if (upsert.getSelect() != null) {
+ appendSelect(upsert);
+ }
- if (upsert.isUseDuplicate()) {
- appendDuplicate(upsert);
+ if (upsert.isUseDuplicate()) {
+ appendDuplicate(upsert);
+ }
}
+ }
+ private void appendReplaceSetClause(Upsert upsert) {
+ buffer.append(" SET ");
+ // each element from expressions match up with a column from columns.
+ List expressions = upsert.getSetExpressions();
+ for (int i = 0, s = upsert.getColumns().size(); i < s; i++) {
+ buffer.append(upsert.getColumns().get(i)).append("=").append(expressions.get(i));
+ buffer.append( i < s - 1
+ ? ", "
+ : "" );
+ }
}
private void appendColumns(Upsert upsert) {
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java b/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java
index 6ec4c7ba1..04c9a1277 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/feature/FeaturesAllowed.java
@@ -110,7 +110,8 @@ public class FeaturesAllowed implements FeatureSetValidation, ModifyableFeatureS
* all {@link Feature}' for SQL UPDATE including {@link #SELECT}
*/
public static final FeaturesAllowed DELETE = new FeaturesAllowed("DELETE", Feature.delete, Feature.deleteJoin,
- Feature.deleteLimit, Feature.deleteOrderBy, Feature.deleteTables, Feature.truncate)
+ Feature.deleteLimit, Feature.deleteOrderBy, Feature.deleteTables, Feature.deleteReturningExpressionList,
+ Feature.truncate)
.add(SELECT).unmodifyable();
/**
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 6a1cba1a4..185da5664 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
@@ -9,12 +9,12 @@
*/
package net.sf.jsqlparser.util.validation.feature;
+import net.sf.jsqlparser.parser.feature.Feature;
+
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;
-import net.sf.jsqlparser.parser.feature.Feature;
-
/**
* Please add Features supported and place a link to public documentation
*
@@ -35,7 +35,10 @@ public enum MariaDbVersion implements Version {
Feature.selectHaving,
Feature.limit, Feature.limitOffset, Feature.offset, Feature.offsetParam,
Feature.orderBy,
- Feature.selectForUpdate, Feature.selectForUpdateWait, Feature.selectForUpdateNoWait,
+ Feature.selectForUpdate,
+ Feature.selectForUpdateWait,
+ Feature.selectForUpdateNoWait,
+ Feature.selectForUpdateSkipLocked,
// https://mariadb.com/kb/en/join-syntax/
Feature.join, Feature.joinSimple, Feature.joinRight, Feature.joinNatural, Feature.joinLeft,
@@ -96,7 +99,7 @@ public enum MariaDbVersion implements Version {
Feature.dropViewIfExists, Feature.dropSchemaIfExists, Feature.dropSequenceIfExists,
// https://mariadb.com/kb/en/replace/
- Feature.replace,
+ Feature.upsert,
// https://mariadb.com/kb/en/alter/
Feature.alterTable,
@@ -130,6 +133,8 @@ public enum MariaDbVersion implements Version {
Feature.showTables,
// https://mariadb.com/kb/en/show-columns/
Feature.showColumns,
+ // https://mariadb.com/kb/en/show-index/
+ Feature.showIndex,
// https://mariadb.com/kb/en/use/
Feature.use,
// https://mariadb.com/kb/en/grant/
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 c13abaa3e..01bbce4c1 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
@@ -9,10 +9,11 @@
*/
package net.sf.jsqlparser.util.validation.feature;
+import net.sf.jsqlparser.parser.feature.Feature;
+
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;
-import net.sf.jsqlparser.parser.feature.Feature;
/**
* Please add Features supported and place a link to public documentation
@@ -33,7 +34,10 @@ public enum MySqlVersion implements Version {
Feature.select,
Feature.selectGroupBy, Feature.selectHaving,
Feature.limit, Feature.limitOffset, Feature.offset, Feature.offsetParam, Feature.orderBy,
- Feature.selectForUpdate, Feature.selectForUpdateOfTable, Feature.selectForUpdateNoWait,
+ Feature.selectForUpdate,
+ Feature.selectForUpdateOfTable,
+ Feature.selectForUpdateNoWait,
+ Feature.selectForUpdateSkipLocked,
Feature.distinct,
Feature.setOperation,
@@ -62,7 +66,7 @@ public enum MySqlVersion implements Version {
Feature.update, Feature.updateJoins, Feature.updateOrderBy, Feature.updateLimit,
// https://dev.mysql.com/doc/refman/8.0/en/replace.html
- Feature.replace,
+ Feature.upsert,
// https://dev.mysql.com/doc/refman/8.0/en/delete.html
Feature.delete, Feature.deleteJoin, Feature.deleteTables, Feature.deleteLimit,
@@ -114,6 +118,8 @@ public enum MySqlVersion implements Version {
Feature.showTables,
// https://dev.mysql.com/doc/refman/8.0/en/show-columns.html
Feature.showColumns,
+ // https://dev.mysql.com/doc/refman/8.0/en/show-index.html
+ Feature.showIndex,
// https://dev.mysql.com/doc/refman/8.0/en/grant.html
Feature.grant,
// https://dev.mysql.com/doc/refman/8.0/en/use.html
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 3c970bf65..26d4e678e 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
@@ -83,7 +83,9 @@ public enum OracleVersion implements Version {
// https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
// see "for_update_clause"
Feature.selectForUpdate,
- Feature.selectForUpdateWait, Feature.selectForUpdateNoWait,
+ Feature.selectForUpdateWait,
+ Feature.selectForUpdateNoWait,
+ Feature.selectForUpdateSkipLocked,
// https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/INSERT.html
Feature.insert,
@@ -100,6 +102,7 @@ public enum OracleVersion implements Version {
// https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/DELETE.html
Feature.delete,
+ Feature.deleteReturningExpressionList,
// https://www.oracletutorial.com/oracle-basics/oracle-truncate-table/
Feature.truncate,
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 32e62cca7..c5d3d898a 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
@@ -76,6 +76,7 @@ public enum PostgresqlVersion implements Version {
Feature.selectForUpdate,
Feature.selectForUpdateOfTable,
Feature.selectForUpdateNoWait,
+ Feature.selectForUpdateSkipLocked,
// https://www.postgresql.org/docs/current/queries-union.html
Feature.setOperation,
@@ -98,7 +99,7 @@ public enum PostgresqlVersion implements Version {
// https://www.postgresql.org/docs/current/sql-createindex.html
Feature.createIndex,
// https://www.postgresql.org/docs/current/sql-createtable.html
- Feature.createTable, Feature.createTableUnlogged,
+ Feature.createTable, Feature.createTableUnlogged,
Feature.createTableCreateOptionStrings, Feature.createTableTableOptionStrings,
Feature.createTableFromSelect, Feature.createTableIfNotExists,
// https://www.postgresql.org/docs/current/sql-createview.html
@@ -111,12 +112,14 @@ public enum PostgresqlVersion implements Version {
Feature.insertValues,
Feature.values,
Feature.insertFromSelect,
- Feature.insertReturningAll, Feature.insertReturningExpressionList,
+ Feature.insertReturningAll,
+ Feature.insertReturningExpressionList,
// https://www.postgresql.org/docs/current/sql-update.html
Feature.update,
Feature.updateReturning,
// https://www.postgresql.org/docs/current/sql-delete.html
Feature.delete,
+ Feature.deleteReturningExpressionList,
// https://www.postgresql.org/docs/current/sql-truncate.html
Feature.truncate,
@@ -150,7 +153,10 @@ public enum PostgresqlVersion implements Version {
// https://www.postgresql.org/docs/current/sql-commit.html
Feature.commit
)),
- V11("11", V10.copy().getFeatures()), V12("12", V11.copy().getFeatures());
+ V11("11", V10.copy().getFeatures()),
+ V12("12", V11.copy().getFeatures()),
+ V13("13", V12.copy().getFeatures()),
+ V14("14", V13.copy().getFeatures());
private Set features;
private String versionString;
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 7e07eb546..564278dfe 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,7 +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);
+ validateOptionalFeature(c, delete.getReturningExpressionList(), Feature.deleteReturningExpressionList);
}
SelectValidator v = getValidator(SelectValidator.class);
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java
index d517c4b00..35c8c0687 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/ExpressionValidator.java
@@ -79,6 +79,13 @@ public void visit(Between between) {
between.getBetweenExpressionEnd().accept(this);
}
+ @Override
+ public void visit(OverlapsCondition overlapsCondition) {
+ validateOptionalExpressionList(overlapsCondition.getLeft());
+ validateOptionalExpressionList(overlapsCondition.getRight());
+ }
+
+
@Override
public void visit(EqualsTo equalsTo) {
visitOldOracleJoinBinaryExpression(equalsTo, " = ");
@@ -355,6 +362,12 @@ public void visit(TryCastExpression cast) {
cast.getLeftExpression().accept(this);
}
+ @Override
+ public void visit(SafeCastExpression cast) {
+ cast.getLeftExpression().accept(this);
+
+ }
+
@Override
public void visit(Modulo modulo) {
visitBinaryExpression(modulo, " % ");
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/ReplaceValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/ReplaceValidator.java
index 48904dc14..0c1323339 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/validator/ReplaceValidator.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/ReplaceValidator.java
@@ -9,25 +9,10 @@
*/
package net.sf.jsqlparser.util.validation.validator;
-import net.sf.jsqlparser.parser.feature.Feature;
-import net.sf.jsqlparser.statement.replace.Replace;
-import net.sf.jsqlparser.util.validation.ValidationCapability;
-
+@Deprecated
/**
* @author gitmotte
*/
-public class ReplaceValidator extends AbstractValidator {
-
-
- @Override
- public void validate(Replace replace) {
- for (ValidationCapability c : getCapabilities()) {
- validateFeature(c, Feature.replace);
- }
- validateOptionalFromItem(replace.getTable());
- validateOptionalItemsList(replace.getItemsList());
- validateOptionalExpressions(replace.getExpressions());
- validateOptionalExpressions(replace.getColumns());
- }
+public class ReplaceValidator extends UpsertValidator {
}
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java
index 52e15262d..8c5df9c1b 100644
--- a/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/SelectValidator.java
@@ -86,6 +86,7 @@ public void visit(PlainSelect plainSelect) {
validateOptionalFeature(c, plainSelect.getForUpdateTable(), Feature.selectForUpdateOfTable);
validateOptionalFeature(c, plainSelect.getWait(), Feature.selectForUpdateWait);
validateFeature(c, plainSelect.isNoWait(), Feature.selectForUpdateNoWait);
+ validateFeature(c, plainSelect.isSkipLocked(), Feature.selectForUpdateSkipLocked);
}
validateOptionalFeature(c, plainSelect.getForXmlPath(), Feature.selectForXmlPath);
diff --git a/src/main/java/net/sf/jsqlparser/util/validation/validator/ShowIndexStatementValidator.java b/src/main/java/net/sf/jsqlparser/util/validation/validator/ShowIndexStatementValidator.java
new file mode 100644
index 000000000..624ee3828
--- /dev/null
+++ b/src/main/java/net/sf/jsqlparser/util/validation/validator/ShowIndexStatementValidator.java
@@ -0,0 +1,27 @@
+/*-
+ * #%L
+ * JSQLParser library
+ * %%
+ * Copyright (C) 2004 - 2019 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.show.ShowIndexStatement;
+import net.sf.jsqlparser.util.validation.metadata.NamedObject;
+
+/**
+*
+* @author Jayant Kumar Yadav
+*/
+
+public class ShowIndexStatementValidator extends AbstractValidator {
+
+ @Override
+ public void validate(ShowIndexStatement show) {
+ validateFeatureAndName(Feature.showIndex, NamedObject.table, show.getTableName());
+ }
+}
\ No newline at end of file
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 f6cfc121d..895ac2037 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
@@ -53,6 +53,7 @@
import net.sf.jsqlparser.statement.merge.Merge;
import net.sf.jsqlparser.statement.replace.Replace;
import net.sf.jsqlparser.statement.select.Select;
+import net.sf.jsqlparser.statement.show.ShowIndexStatement;
import net.sf.jsqlparser.statement.show.ShowTablesStatement;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;
@@ -182,7 +183,12 @@ public void visit(ShowStatement show) {
public void visit(ShowColumnsStatement show) {
getValidator(ShowColumnsStatementValidator.class).validate(show);
}
-
+
+ @Override
+ public void visit(ShowIndexStatement show) {
+ getValidator(ShowIndexStatementValidator.class).validate(show);
+ }
+
@Override
public void visit(ShowTablesStatement showTables) {
getValidator(ShowTablesStatementValidator.class).validate(showTables);
diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
index 16cdb9469..fd7a8ada0 100644
--- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
+++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
@@ -25,12 +25,16 @@ options {
TRACK_TOKENS = true;
VISITOR = true;
GRAMMAR_ENCODING = "UTF-8";
+ KEEP_LINE_COLUMN = true;
}
PARSER_BEGIN(CCJSqlParser)
package net.sf.jsqlparser.parser;
+import java.lang.reflect.Field;
+import java.lang.Integer;
+
import net.sf.jsqlparser.parser.feature.*;
import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.expression.operators.arithmetic.*;
@@ -120,6 +124,8 @@ SKIP:
}
+// http://www.h2database.com/html/advanced.html#keywords
+
TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
{
@@ -143,12 +149,14 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
+|
|
|
|
|
|
|
+|
|
|
|
@@ -157,7 +165,6 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
| /* H2 casewhen function */
|
-|
|
|
|
@@ -182,7 +189,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
-|
+|
|
|
|
@@ -251,6 +258,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
+|
|
|
|
@@ -273,6 +281,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
+|
|
|
|
@@ -285,12 +294,6 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
-
-/* @todo:
- this collides with SELECT 'yelp'::name ...
-|
-*/
-
|
|
|
@@ -320,8 +323,10 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
+|
|
|
+|
|
|
|
@@ -342,11 +347,14 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
+|
|
|
|
|
|
+|
+|
|
|
|
@@ -356,6 +364,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
+|
|
|
|
@@ -364,8 +373,6 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
-|
-|
|
|
|
@@ -375,6 +382,8 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
+|
+|
|
|
|
@@ -396,6 +405,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
+|
|
|
|
@@ -436,12 +446,13 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
|
|
+|
|
}
-TOKEN : /* Stuff */
+TOKEN : /* Statement Separators */
{
-
+
}
TOKEN : /* Operators */
@@ -481,23 +492,76 @@ SPECIAL_TOKEN:
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","`"])+ "`") | ( "[" (~["\n","\r","]"])* "]" ) >
- { if ( !configuration.getAsBoolean(Feature.allowSquareBracketQuotation) && matchedToken.image.charAt(0) == '[' ) {
- matchedToken.image = "[";
- for (int i=0;i
+ | | [ "$" , "#", "_" ] // Not SQL:2016 compliant!
+ >
+| <#PART_LETTER: | | [ "$" , "#", "_" , "@" ] >
+
+// Unicode characters and categories are defined here: https://www.unicode.org/Public/UNIDATA/UnicodeData.txt
+// SQL:2016 states:
+// An is any character in the Unicode General Category classes “Lu”, “Ll”, “Lt”, “Lm”, “Lo”, or “Nl”.
+// An is U+00B7, “Middle Dot”, or any character in the Unicode General Category classes “Mn”, “Mc”, “Nd”, “Pc”, or “Cf”.
+
+// unicode_identifier_start
+| <#UnicodeIdentifierStart: ("\u00B7" | | | | |