Skip to content

Commit 6429742

Browse files
author
zhangkenan
committed
support opengauss "on duplicate key nothing" grammar
1 parent 90cc63f commit 6429742

File tree

10 files changed

+229
-42
lines changed

10 files changed

+229
-42
lines changed

src/main/java/net/sf/jsqlparser/statement/insert/ConflictActionType.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
package net.sf.jsqlparser.statement.insert;
1111

1212
public enum ConflictActionType {
13-
DO_NOTHING, DO_UPDATE;
13+
NOTHING,
14+
DO_NOTHING,
15+
DO_UPDATE;
1416

1517
public static ConflictActionType from(String type) {
1618
return Enum.valueOf(ConflictActionType.class, type.toUpperCase());

src/main/java/net/sf/jsqlparser/statement/insert/Insert.java

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,10 @@
1818
import net.sf.jsqlparser.statement.ReturningClause;
1919
import net.sf.jsqlparser.statement.Statement;
2020
import net.sf.jsqlparser.statement.StatementVisitor;
21-
import net.sf.jsqlparser.statement.select.PlainSelect;
22-
import net.sf.jsqlparser.statement.select.Select;
23-
import net.sf.jsqlparser.statement.select.SetOperationList;
24-
import net.sf.jsqlparser.statement.select.Values;
25-
import net.sf.jsqlparser.statement.select.WithItem;
21+
import net.sf.jsqlparser.statement.select.*;
2622
import net.sf.jsqlparser.statement.update.UpdateSet;
2723

28-
import java.util.Arrays;
29-
import java.util.Collection;
30-
import java.util.Iterator;
31-
import java.util.List;
32-
import java.util.Optional;
24+
import java.util.*;
3325

3426
@SuppressWarnings({"PMD.CyclomaticComplexity"})
3527
public class Insert implements Statement {
@@ -52,8 +44,12 @@ public class Insert implements Statement {
5244
private OutputClause outputClause;
5345
private InsertConflictTarget conflictTarget;
5446
private InsertConflictAction conflictAction;
47+
private InsertDuplicateAction duplicateAction;
5548

5649
public List<UpdateSet> getDuplicateUpdateSets() {
50+
if (duplicateAction != null) {
51+
return duplicateAction.getUpdateSets();
52+
}
5753
return duplicateUpdateSets;
5854
}
5955

@@ -62,7 +58,13 @@ public List<UpdateSet> getSetUpdateSets() {
6258
}
6359

6460
public Insert withDuplicateUpdateSets(List<UpdateSet> duplicateUpdateSets) {
65-
this.duplicateUpdateSets = duplicateUpdateSets;
61+
if (duplicateAction != null) {
62+
duplicateAction.setConflictActionType(ConflictActionType.DO_UPDATE);
63+
duplicateAction.setUpdateSets(duplicateUpdateSets);
64+
} else {
65+
duplicateAction = new InsertDuplicateAction(ConflictActionType.DO_UPDATE);
66+
duplicateAction.setUpdateSets(duplicateUpdateSets);
67+
}
6668
return this;
6769
}
6870

@@ -157,7 +159,7 @@ public boolean isUseSelectBrackets() {
157159

158160
@Deprecated
159161
public boolean isUseDuplicate() {
160-
return duplicateUpdateSets != null && !duplicateUpdateSets.isEmpty();
162+
return duplicateAction != null && duplicateAction.getUpdateSets() != null && !duplicateAction.getUpdateSets().isEmpty();
161163
}
162164

163165
public InsertModifierPriority getModifierPriority() {
@@ -263,7 +265,7 @@ public String toString() {
263265
StringBuilder sql = new StringBuilder();
264266
if (withItemsList != null && !withItemsList.isEmpty()) {
265267
sql.append("WITH ");
266-
for (Iterator<WithItem<?>> iter = withItemsList.iterator(); iter.hasNext();) {
268+
for (Iterator<WithItem<?>> iter = withItemsList.iterator(); iter.hasNext(); ) {
267269
WithItem<?> withItem = iter.next();
268270
sql.append(withItem);
269271
if (iter.hasNext()) {
@@ -331,9 +333,9 @@ public String toString() {
331333
sql = UpdateSet.appendUpdateSetsTo(sql, setUpdateSets);
332334
}
333335

334-
if (duplicateUpdateSets != null && !duplicateUpdateSets.isEmpty()) {
336+
if (duplicateAction != null) {
335337
sql.append(" ON DUPLICATE KEY UPDATE ");
336-
sql = UpdateSet.appendUpdateSetsTo(sql, duplicateUpdateSets);
338+
duplicateAction.appendTo(sql);
337339
}
338340

339341
if (conflictAction != null) {
@@ -387,9 +389,16 @@ public Insert addColumns(Column... columns) {
387389
}
388390

389391
public Insert addColumns(Collection<Column> columns) {
390-
ExpressionList<Column> collection =
391-
Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new);
392+
ExpressionList<Column> collection = Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new);
392393
collection.addAll(columns);
393394
return this.withColumns(collection);
394395
}
396+
397+
public InsertDuplicateAction getDuplicateAction() {
398+
return duplicateAction;
399+
}
400+
401+
public void setDuplicateAction(InsertDuplicateAction duplicateAction) {
402+
this.duplicateAction = duplicateAction;
403+
}
395404
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2025 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement.insert;
11+
12+
import net.sf.jsqlparser.expression.Expression;
13+
import net.sf.jsqlparser.schema.Column;
14+
import net.sf.jsqlparser.statement.update.UpdateSet;
15+
16+
import java.io.Serializable;
17+
import java.util.ArrayList;
18+
import java.util.Collection;
19+
import java.util.List;
20+
import java.util.Objects;
21+
22+
/**
23+
* on duplicate key is one of:
24+
*
25+
* ON DUPLICATE KEY UPDATE NOTHING ON DUPLICATE KEY UPDATE { column_name = { expression | DEFAULT } | ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT
26+
* } [, ...] ) | ( column_name [, ...] ) = ( sub-SELECT ) } [, ...] [ WHERE condition ]
27+
*
28+
* @author zhangconan
29+
*/
30+
public class InsertDuplicateAction implements Serializable {
31+
32+
ConflictActionType conflictActionType;
33+
Expression whereExpression;
34+
private List<UpdateSet> updateSets;
35+
36+
public InsertDuplicateAction(ConflictActionType conflictActionType) {
37+
this.conflictActionType = Objects.requireNonNull(conflictActionType, "The Conflict Action Type is mandatory and must not be Null.");
38+
}
39+
40+
public List<UpdateSet> getUpdateSets() {
41+
return updateSets;
42+
}
43+
44+
public void setUpdateSets(List<UpdateSet> updateSets) {
45+
this.updateSets = updateSets;
46+
}
47+
48+
public InsertDuplicateAction withUpdateSets(List<UpdateSet> updateSets) {
49+
this.setUpdateSets(updateSets);
50+
return this;
51+
}
52+
53+
public ConflictActionType getConflictActionType() {
54+
return conflictActionType;
55+
}
56+
57+
public void setConflictActionType(ConflictActionType conflictActionType) {
58+
this.conflictActionType = Objects.requireNonNull(conflictActionType, "The Conflict Action Type is mandatory and must not be Null.");
59+
}
60+
61+
public InsertDuplicateAction withConflictActionType(ConflictActionType conflictActionType) {
62+
setConflictActionType(conflictActionType);
63+
return this;
64+
}
65+
66+
public InsertDuplicateAction addUpdateSet(Column column, Expression expression) {
67+
return this.addUpdateSet(new UpdateSet());
68+
}
69+
70+
public InsertDuplicateAction addUpdateSet(UpdateSet updateSet) {
71+
if (updateSets == null) {
72+
updateSets = new ArrayList<>();
73+
}
74+
this.updateSets.add(updateSet);
75+
return this;
76+
}
77+
78+
public InsertDuplicateAction withUpdateSets(Collection<UpdateSet> updateSets) {
79+
this.setUpdateSets(new ArrayList<>(updateSets));
80+
return this;
81+
}
82+
83+
public Expression getWhereExpression() {
84+
return whereExpression;
85+
}
86+
87+
public void setWhereExpression(Expression whereExpression) {
88+
this.whereExpression = whereExpression;
89+
}
90+
91+
public InsertDuplicateAction withWhereExpression(Expression whereExpression) {
92+
setWhereExpression(whereExpression);
93+
return this;
94+
}
95+
96+
@SuppressWarnings("PMD.SwitchStmtsShouldHaveDefault")
97+
public StringBuilder appendTo(StringBuilder builder) {
98+
switch (conflictActionType) {
99+
case NOTHING:
100+
builder.append(" NOTHING ");
101+
break;
102+
default:
103+
UpdateSet.appendUpdateSetsTo(builder, updateSets);
104+
105+
if (whereExpression != null) {
106+
builder.append(" WHERE ").append(whereExpression);
107+
}
108+
break;
109+
}
110+
return builder;
111+
}
112+
113+
@Override
114+
public String toString() {
115+
return appendTo(new StringBuilder()).toString();
116+
}
117+
}

src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import net.sf.jsqlparser.schema.Table;
1515
import net.sf.jsqlparser.statement.Statement;
1616
import net.sf.jsqlparser.statement.StatementVisitor;
17+
import net.sf.jsqlparser.statement.insert.ConflictActionType;
18+
import net.sf.jsqlparser.statement.insert.InsertDuplicateAction;
1719
import net.sf.jsqlparser.statement.select.PlainSelect;
1820
import net.sf.jsqlparser.statement.select.Select;
1921
import net.sf.jsqlparser.statement.select.SetOperationList;
@@ -35,6 +37,7 @@ public class Upsert implements Statement {
3537
private List<UpdateSet> duplicateUpdateSets;
3638
private UpsertType upsertType = UpsertType.UPSERT;
3739
private boolean isUsingInto;
40+
private InsertDuplicateAction duplicateAction;
3841

3942
public List<UpdateSet> getUpdateSets() {
4043
return updateSets;
@@ -46,11 +49,20 @@ public Upsert setUpdateSets(List<UpdateSet> updateSets) {
4649
}
4750

4851
public List<UpdateSet> getDuplicateUpdateSets() {
52+
if (duplicateAction != null) {
53+
return duplicateAction.getUpdateSets();
54+
}
4955
return duplicateUpdateSets;
5056
}
5157

5258
public Upsert setDuplicateUpdateSets(List<UpdateSet> duplicateUpdateSets) {
53-
this.duplicateUpdateSets = duplicateUpdateSets;
59+
if (duplicateAction != null) {
60+
duplicateAction.setConflictActionType(ConflictActionType.DO_UPDATE);
61+
duplicateAction.setUpdateSets(duplicateUpdateSets);
62+
} else {
63+
duplicateAction = new InsertDuplicateAction(ConflictActionType.DO_UPDATE);
64+
duplicateAction.setUpdateSets(duplicateUpdateSets);
65+
}
5466
return this;
5567
}
5668

@@ -181,9 +193,9 @@ public String toString() {
181193
}
182194
}
183195

184-
if (duplicateUpdateSets != null) {
196+
if (duplicateAction != null) {
185197
sb.append(" ON DUPLICATE KEY UPDATE ");
186-
UpdateSet.appendUpdateSetsTo(sb, duplicateUpdateSets);
198+
duplicateAction.appendTo(sb);
187199
}
188200

189201
return sb.toString();
@@ -214,9 +226,16 @@ public Upsert addColumns(Column... columns) {
214226
}
215227

216228
public Upsert addColumns(Collection<? extends Column> columns) {
217-
ExpressionList<Column> collection =
218-
Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new);
229+
ExpressionList<Column> collection = Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new);
219230
collection.addAll(columns);
220231
return this.withColumns(collection);
221232
}
233+
234+
public InsertDuplicateAction getDuplicateAction() {
235+
return duplicateAction;
236+
}
237+
238+
public void setDuplicateAction(InsertDuplicateAction duplicateAction) {
239+
this.duplicateAction = duplicateAction;
240+
}
222241
}

src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import net.sf.jsqlparser.expression.ExpressionVisitor;
1313
import net.sf.jsqlparser.schema.Column;
1414
import net.sf.jsqlparser.schema.Partition;
15+
import net.sf.jsqlparser.statement.insert.ConflictActionType;
1516
import net.sf.jsqlparser.statement.insert.Insert;
1617
import net.sf.jsqlparser.statement.select.Select;
1718
import net.sf.jsqlparser.statement.select.SelectVisitor;
@@ -28,22 +29,18 @@ public InsertDeParser() {
2829
super(new StringBuilder());
2930
}
3031

31-
public InsertDeParser(ExpressionVisitor<StringBuilder> expressionVisitor,
32-
SelectVisitor<StringBuilder> selectVisitor,
33-
StringBuilder buffer) {
32+
public InsertDeParser(ExpressionVisitor<StringBuilder> expressionVisitor, SelectVisitor<StringBuilder> selectVisitor, StringBuilder buffer) {
3433
super(buffer);
3534
this.expressionVisitor = expressionVisitor;
3635
this.selectVisitor = selectVisitor;
3736
}
3837

3938
@Override
40-
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.ExcessiveMethodLength",
41-
"PMD.NPathComplexity"})
39+
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.ExcessiveMethodLength", "PMD.NPathComplexity"})
4240
public void deParse(Insert insert) {
4341
if (insert.getWithItemsList() != null && !insert.getWithItemsList().isEmpty()) {
4442
builder.append("WITH ");
45-
for (Iterator<WithItem<?>> iter = insert.getWithItemsList().iterator(); iter
46-
.hasNext();) {
43+
for (Iterator<WithItem<?>> iter = insert.getWithItemsList().iterator(); iter.hasNext(); ) {
4744
WithItem<?> withItem = iter.next();
4845
withItem.accept(this.selectVisitor, null);
4946
if (iter.hasNext()) {
@@ -80,7 +77,7 @@ public void deParse(Insert insert) {
8077

8178
if (insert.getColumns() != null) {
8279
builder.append(" (");
83-
for (Iterator<Column> iter = insert.getColumns().iterator(); iter.hasNext();) {
80+
for (Iterator<Column> iter = insert.getColumns().iterator(); iter.hasNext(); ) {
8481
Column column = iter.next();
8582
builder.append(column.getColumnName());
8683
if (iter.hasNext()) {
@@ -115,9 +112,13 @@ public void deParse(Insert insert) {
115112
deparseUpdateSets(insert.getSetUpdateSets(), builder, expressionVisitor);
116113
}
117114

118-
if (insert.getDuplicateUpdateSets() != null) {
115+
if (insert.getDuplicateAction() != null) {
119116
builder.append(" ON DUPLICATE KEY UPDATE ");
120-
deparseUpdateSets(insert.getDuplicateUpdateSets(), builder, expressionVisitor);
117+
if (ConflictActionType.DO_UPDATE.equals(insert.getDuplicateAction().getConflictActionType())) {
118+
deparseUpdateSets(insert.getDuplicateUpdateSets(), builder, expressionVisitor);
119+
} else {
120+
insert.getDuplicateAction().appendTo(builder);
121+
}
121122
}
122123

123124
// @todo: Accept some Visitors for the involved Expressions

src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package net.sf.jsqlparser.util.deparser;
1111

1212
import net.sf.jsqlparser.expression.ExpressionVisitor;
13+
import net.sf.jsqlparser.statement.insert.ConflictActionType;
1314
import net.sf.jsqlparser.statement.select.SelectVisitor;
1415
import net.sf.jsqlparser.statement.upsert.Upsert;
1516

@@ -19,8 +20,7 @@ public class UpsertDeParser extends AbstractDeParser<Upsert> {
1920
private ExpressionDeParser expressionVisitor;
2021
private SelectDeParser selectVisitor;
2122

22-
public UpsertDeParser(ExpressionDeParser expressionVisitor, SelectDeParser selectVisitor,
23-
StringBuilder buffer) {
23+
public UpsertDeParser(ExpressionDeParser expressionVisitor, SelectDeParser selectVisitor, StringBuilder buffer) {
2424
super(buffer);
2525
this.expressionVisitor = expressionVisitor;
2626
this.expressionVisitor.setSelectVisitor(selectVisitor);
@@ -78,9 +78,13 @@ public void deParse(Upsert upsert) {
7878
upsert.getSelect().accept((SelectVisitor<StringBuilder>) selectVisitor, null);
7979
}
8080

81-
if (upsert.getDuplicateUpdateSets() != null) {
81+
if (upsert.getDuplicateAction() != null) {
8282
builder.append(" ON DUPLICATE KEY UPDATE ");
83-
deparseUpdateSets(upsert.getDuplicateUpdateSets(), builder, expressionVisitor);
83+
if (ConflictActionType.DO_UPDATE.equals(upsert.getDuplicateAction().getConflictActionType())) {
84+
deparseUpdateSets(upsert.getDuplicateUpdateSets(), builder, expressionVisitor);
85+
} else {
86+
upsert.getDuplicateAction().appendTo(builder);
87+
}
8488
}
8589
}
8690
}

0 commit comments

Comments
 (0)