diff --git a/src/main/java/net/sf/jsqlparser/statement/merge/MergeInsert.java b/src/main/java/net/sf/jsqlparser/statement/merge/MergeInsert.java index bc9ea695a..f6affa3ef 100644 --- a/src/main/java/net/sf/jsqlparser/statement/merge/MergeInsert.java +++ b/src/main/java/net/sf/jsqlparser/statement/merge/MergeInsert.java @@ -20,10 +20,19 @@ public class MergeInsert implements Serializable { + private Expression andPredicate; private ExpressionList columns; private ExpressionList values; private Expression whereCondition; + public Expression getAndPredicate() { + return andPredicate; + } + + public void setAndPredicate(Expression andPredicate) { + this.andPredicate = andPredicate; + } + public ExpressionList getColumns() { return columns; } @@ -50,12 +59,25 @@ public void setWhereCondition(Expression whereCondition) { @Override public String toString() { - return " WHEN NOT MATCHED THEN INSERT " - + (columns != null ? columns.toString() : "") - + " VALUES " + values.toString() - + (whereCondition != null - ? " WHERE " + whereCondition - : ""); + StringBuilder b = new StringBuilder(); + b.append(" WHEN NOT MATCHED"); + if (andPredicate != null) { + b.append(" AND ").append(andPredicate.toString()); + } + b.append(" THEN INSERT "); + if (columns != null) { + b.append(columns.toString()); + } + b.append(" VALUES ").append(values.toString()); + if (whereCondition != null) { + b.append(" WHERE ").append(whereCondition.toString()); + } + return b.toString(); + } + + public MergeInsert withAndPredicate(Expression andPredicate) { + this.setAndPredicate(andPredicate); + return this; } public MergeInsert withColumns(ExpressionList columns) { @@ -95,6 +117,10 @@ public MergeInsert withWhereCondition(Expression whereCondition) { return this; } + public E getAndPredicate(Class type) { + return type.cast(getAndPredicate()); + } + public E getWhereCondition(Class type) { return type.cast(getWhereCondition()); } 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 93a2af08c..732ef3e39 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java @@ -255,7 +255,12 @@ public void visit(Merge merge) { } private void deparseMergeInsert(MergeInsert mergeInsert) { - buffer.append(" WHEN NOT MATCHED THEN INSERT "); + buffer.append(" WHEN NOT MATCHED"); + if (mergeInsert.getAndPredicate() != null) { + buffer.append(" AND "); + mergeInsert.getAndPredicate().accept(expressionDeParser); + } + buffer.append(" THEN INSERT "); if (mergeInsert.getColumns() != null) { mergeInsert.getColumns().accept(expressionDeParser); } diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 91d49c82b..7905024a5 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -1695,12 +1695,15 @@ MergeUpdate MergeUpdateClause() : { MergeInsert MergeInsertClause() : { MergeInsert mi = new MergeInsert(); + Expression predicate; ExpressionList columns; ExpressionList expList; Expression condition; } { - + + [ predicate = Expression() { mi.setAndPredicate(predicate); } ] + [ "(" columns = ColumnList() ")" { diff --git a/src/test/java/net/sf/jsqlparser/statement/merge/MergeTest.java b/src/test/java/net/sf/jsqlparser/statement/merge/MergeTest.java index 94ff0557d..5034be8cd 100644 --- a/src/test/java/net/sf/jsqlparser/statement/merge/MergeTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/merge/MergeTest.java @@ -254,4 +254,13 @@ public void testSnowflakeMergeStatementWithMatchedAndPredicate() throws JSQLPars assertSqlCanBeParsedAndDeparsed(sql, true); } + + @Test + void testSnowflakeMergeStatementWithNotMatchedAndPredicate() throws JSQLParserException { + String sql = "MERGE INTO target USING (select k, max(v) as v from src group by k) AS b ON target.k = b.k\n" + + " WHEN MATCHED THEN UPDATE SET target.v = b.v\n" + + " WHEN NOT MATCHED AND b.v != 11 THEN INSERT (k, v) VALUES (b.k, b.v)"; + + assertSqlCanBeParsedAndDeparsed(sql, true); + } }