Skip to content

Commit

Permalink
feat: add support for and predicate in merge insert
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjgoss committed Nov 8, 2023
1 parent 10457b6 commit 93b3930
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 8 deletions.
38 changes: 32 additions & 6 deletions src/main/java/net/sf/jsqlparser/statement/merge/MergeInsert.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,19 @@

public class MergeInsert implements Serializable {

private Expression andPredicate;
private ExpressionList<Column> columns;
private ExpressionList<Expression> values;
private Expression whereCondition;

public Expression getAndPredicate() {
return andPredicate;
}

public void setAndPredicate(Expression andPredicate) {
this.andPredicate = andPredicate;
}

public ExpressionList<Column> getColumns() {
return columns;
}
Expand All @@ -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<Column> columns) {
Expand Down Expand Up @@ -95,6 +117,10 @@ public MergeInsert withWhereCondition(Expression whereCondition) {
return this;
}

public <E extends Expression> E getAndPredicate(Class<E> type) {
return type.cast(getAndPredicate());
}

public <E extends Expression> E getWhereCondition(Class<E> type) {
return type.cast(getWhereCondition());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
5 changes: 4 additions & 1 deletion src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -1695,12 +1695,15 @@ MergeUpdate MergeUpdateClause() : {

MergeInsert MergeInsertClause() : {
MergeInsert mi = new MergeInsert();
Expression predicate;
ExpressionList<Column> columns;
ExpressionList expList;
Expression condition;
}
{
<K_WHEN> <K_NOT> <K_MATCHED> <K_THEN>
<K_WHEN> <K_NOT> <K_MATCHED>
[ <K_AND> predicate = Expression() { mi.setAndPredicate(predicate); } ]
<K_THEN>
<K_INSERT>
[ "(" columns = ColumnList() ")"
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

0 comments on commit 93b3930

Please sign in to comment.