From 642974271120fa36adf644062c4d1fed4fba5e14 Mon Sep 17 00:00:00 2001 From: zhangkenan Date: Thu, 28 Aug 2025 15:08:27 +0800 Subject: [PATCH 1/4] support opengauss "on duplicate key nothing" grammar --- .../statement/insert/ConflictActionType.java | 4 +- .../jsqlparser/statement/insert/Insert.java | 43 ++++--- .../insert/InsertDuplicateAction.java | 117 ++++++++++++++++++ .../jsqlparser/statement/upsert/Upsert.java | 29 ++++- .../util/deparser/InsertDeParser.java | 21 ++-- .../util/deparser/UpsertDeParser.java | 12 +- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 31 ++++- .../statement/insert/InsertTest.java | 6 +- .../statement/upsert/UpsertTest.java | 6 +- .../util/deparser/StatementDeParserTest.java | 2 +- 10 files changed, 229 insertions(+), 42 deletions(-) create mode 100644 src/main/java/net/sf/jsqlparser/statement/insert/InsertDuplicateAction.java diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/ConflictActionType.java b/src/main/java/net/sf/jsqlparser/statement/insert/ConflictActionType.java index 69d6532f0..3de1a21e7 100644 --- a/src/main/java/net/sf/jsqlparser/statement/insert/ConflictActionType.java +++ b/src/main/java/net/sf/jsqlparser/statement/insert/ConflictActionType.java @@ -10,7 +10,9 @@ package net.sf.jsqlparser.statement.insert; public enum ConflictActionType { - DO_NOTHING, DO_UPDATE; + NOTHING, + DO_NOTHING, + DO_UPDATE; public static ConflictActionType from(String type) { return Enum.valueOf(ConflictActionType.class, type.toUpperCase()); diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java index c2f6faed0..ee9f13450 100644 --- a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java +++ b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java @@ -18,18 +18,10 @@ import net.sf.jsqlparser.statement.ReturningClause; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.StatementVisitor; -import net.sf.jsqlparser.statement.select.PlainSelect; -import net.sf.jsqlparser.statement.select.Select; -import net.sf.jsqlparser.statement.select.SetOperationList; -import net.sf.jsqlparser.statement.select.Values; -import net.sf.jsqlparser.statement.select.WithItem; +import net.sf.jsqlparser.statement.select.*; import net.sf.jsqlparser.statement.update.UpdateSet; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; +import java.util.*; @SuppressWarnings({"PMD.CyclomaticComplexity"}) public class Insert implements Statement { @@ -52,8 +44,12 @@ public class Insert implements Statement { private OutputClause outputClause; private InsertConflictTarget conflictTarget; private InsertConflictAction conflictAction; + private InsertDuplicateAction duplicateAction; public List getDuplicateUpdateSets() { + if (duplicateAction != null) { + return duplicateAction.getUpdateSets(); + } return duplicateUpdateSets; } @@ -62,7 +58,13 @@ public List getSetUpdateSets() { } public Insert withDuplicateUpdateSets(List duplicateUpdateSets) { - this.duplicateUpdateSets = duplicateUpdateSets; + if (duplicateAction != null) { + duplicateAction.setConflictActionType(ConflictActionType.DO_UPDATE); + duplicateAction.setUpdateSets(duplicateUpdateSets); + } else { + duplicateAction = new InsertDuplicateAction(ConflictActionType.DO_UPDATE); + duplicateAction.setUpdateSets(duplicateUpdateSets); + } return this; } @@ -157,7 +159,7 @@ public boolean isUseSelectBrackets() { @Deprecated public boolean isUseDuplicate() { - return duplicateUpdateSets != null && !duplicateUpdateSets.isEmpty(); + return duplicateAction != null && duplicateAction.getUpdateSets() != null && !duplicateAction.getUpdateSets().isEmpty(); } public InsertModifierPriority getModifierPriority() { @@ -263,7 +265,7 @@ public String toString() { StringBuilder sql = new StringBuilder(); if (withItemsList != null && !withItemsList.isEmpty()) { sql.append("WITH "); - for (Iterator> iter = withItemsList.iterator(); iter.hasNext();) { + for (Iterator> iter = withItemsList.iterator(); iter.hasNext(); ) { WithItem withItem = iter.next(); sql.append(withItem); if (iter.hasNext()) { @@ -331,9 +333,9 @@ public String toString() { sql = UpdateSet.appendUpdateSetsTo(sql, setUpdateSets); } - if (duplicateUpdateSets != null && !duplicateUpdateSets.isEmpty()) { + if (duplicateAction != null) { sql.append(" ON DUPLICATE KEY UPDATE "); - sql = UpdateSet.appendUpdateSetsTo(sql, duplicateUpdateSets); + duplicateAction.appendTo(sql); } if (conflictAction != null) { @@ -387,9 +389,16 @@ public Insert addColumns(Column... columns) { } public Insert addColumns(Collection columns) { - ExpressionList collection = - Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new); + ExpressionList collection = Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new); collection.addAll(columns); return this.withColumns(collection); } + + public InsertDuplicateAction getDuplicateAction() { + return duplicateAction; + } + + public void setDuplicateAction(InsertDuplicateAction duplicateAction) { + this.duplicateAction = duplicateAction; + } } diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/InsertDuplicateAction.java b/src/main/java/net/sf/jsqlparser/statement/insert/InsertDuplicateAction.java new file mode 100644 index 000000000..1e359f125 --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/statement/insert/InsertDuplicateAction.java @@ -0,0 +1,117 @@ +/*- + * #%L + * JSQLParser library + * %% + * Copyright (C) 2004 - 2025 JSQLParser + * %% + * Dual licensed under GNU LGPL 2.1 or Apache License 2.0 + * #L% + */ +package net.sf.jsqlparser.statement.insert; + +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.statement.update.UpdateSet; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +/** + * on duplicate key is one of: + * + * ON DUPLICATE KEY UPDATE NOTHING ON DUPLICATE KEY UPDATE { column_name = { expression | DEFAULT } | ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT + * } [, ...] ) | ( column_name [, ...] ) = ( sub-SELECT ) } [, ...] [ WHERE condition ] + * + * @author zhangconan + */ +public class InsertDuplicateAction implements Serializable { + + ConflictActionType conflictActionType; + Expression whereExpression; + private List updateSets; + + public InsertDuplicateAction(ConflictActionType conflictActionType) { + this.conflictActionType = Objects.requireNonNull(conflictActionType, "The Conflict Action Type is mandatory and must not be Null."); + } + + public List getUpdateSets() { + return updateSets; + } + + public void setUpdateSets(List updateSets) { + this.updateSets = updateSets; + } + + public InsertDuplicateAction withUpdateSets(List updateSets) { + this.setUpdateSets(updateSets); + return this; + } + + public ConflictActionType getConflictActionType() { + return conflictActionType; + } + + public void setConflictActionType(ConflictActionType conflictActionType) { + this.conflictActionType = Objects.requireNonNull(conflictActionType, "The Conflict Action Type is mandatory and must not be Null."); + } + + public InsertDuplicateAction withConflictActionType(ConflictActionType conflictActionType) { + setConflictActionType(conflictActionType); + return this; + } + + public InsertDuplicateAction addUpdateSet(Column column, Expression expression) { + return this.addUpdateSet(new UpdateSet()); + } + + public InsertDuplicateAction addUpdateSet(UpdateSet updateSet) { + if (updateSets == null) { + updateSets = new ArrayList<>(); + } + this.updateSets.add(updateSet); + return this; + } + + public InsertDuplicateAction withUpdateSets(Collection updateSets) { + this.setUpdateSets(new ArrayList<>(updateSets)); + return this; + } + + public Expression getWhereExpression() { + return whereExpression; + } + + public void setWhereExpression(Expression whereExpression) { + this.whereExpression = whereExpression; + } + + public InsertDuplicateAction withWhereExpression(Expression whereExpression) { + setWhereExpression(whereExpression); + return this; + } + + @SuppressWarnings("PMD.SwitchStmtsShouldHaveDefault") + public StringBuilder appendTo(StringBuilder builder) { + switch (conflictActionType) { + case NOTHING: + builder.append(" NOTHING "); + break; + default: + UpdateSet.appendUpdateSetsTo(builder, updateSets); + + if (whereExpression != null) { + builder.append(" WHERE ").append(whereExpression); + } + break; + } + return builder; + } + + @Override + public String toString() { + return appendTo(new StringBuilder()).toString(); + } +} diff --git a/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java b/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java index 6bb0376b9..c734aa87c 100644 --- a/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java +++ b/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java @@ -14,6 +14,8 @@ import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.StatementVisitor; +import net.sf.jsqlparser.statement.insert.ConflictActionType; +import net.sf.jsqlparser.statement.insert.InsertDuplicateAction; import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.SetOperationList; @@ -35,6 +37,7 @@ public class Upsert implements Statement { private List duplicateUpdateSets; private UpsertType upsertType = UpsertType.UPSERT; private boolean isUsingInto; + private InsertDuplicateAction duplicateAction; public List getUpdateSets() { return updateSets; @@ -46,11 +49,20 @@ public Upsert setUpdateSets(List updateSets) { } public List getDuplicateUpdateSets() { + if (duplicateAction != null) { + return duplicateAction.getUpdateSets(); + } return duplicateUpdateSets; } public Upsert setDuplicateUpdateSets(List duplicateUpdateSets) { - this.duplicateUpdateSets = duplicateUpdateSets; + if (duplicateAction != null) { + duplicateAction.setConflictActionType(ConflictActionType.DO_UPDATE); + duplicateAction.setUpdateSets(duplicateUpdateSets); + } else { + duplicateAction = new InsertDuplicateAction(ConflictActionType.DO_UPDATE); + duplicateAction.setUpdateSets(duplicateUpdateSets); + } return this; } @@ -181,9 +193,9 @@ public String toString() { } } - if (duplicateUpdateSets != null) { + if (duplicateAction != null) { sb.append(" ON DUPLICATE KEY UPDATE "); - UpdateSet.appendUpdateSetsTo(sb, duplicateUpdateSets); + duplicateAction.appendTo(sb); } return sb.toString(); @@ -214,9 +226,16 @@ public Upsert addColumns(Column... columns) { } public Upsert addColumns(Collection columns) { - ExpressionList collection = - Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new); + ExpressionList collection = Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new); collection.addAll(columns); return this.withColumns(collection); } + + public InsertDuplicateAction getDuplicateAction() { + return duplicateAction; + } + + public void setDuplicateAction(InsertDuplicateAction duplicateAction) { + this.duplicateAction = duplicateAction; + } } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java index a555f2ba7..2bab7182a 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java @@ -12,6 +12,7 @@ import net.sf.jsqlparser.expression.ExpressionVisitor; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Partition; +import net.sf.jsqlparser.statement.insert.ConflictActionType; import net.sf.jsqlparser.statement.insert.Insert; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.SelectVisitor; @@ -28,22 +29,18 @@ public InsertDeParser() { super(new StringBuilder()); } - public InsertDeParser(ExpressionVisitor expressionVisitor, - SelectVisitor selectVisitor, - StringBuilder buffer) { + public InsertDeParser(ExpressionVisitor expressionVisitor, SelectVisitor selectVisitor, StringBuilder buffer) { super(buffer); this.expressionVisitor = expressionVisitor; this.selectVisitor = selectVisitor; } @Override - @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.ExcessiveMethodLength", - "PMD.NPathComplexity"}) + @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.ExcessiveMethodLength", "PMD.NPathComplexity"}) public void deParse(Insert insert) { if (insert.getWithItemsList() != null && !insert.getWithItemsList().isEmpty()) { builder.append("WITH "); - for (Iterator> iter = insert.getWithItemsList().iterator(); iter - .hasNext();) { + for (Iterator> iter = insert.getWithItemsList().iterator(); iter.hasNext(); ) { WithItem withItem = iter.next(); withItem.accept(this.selectVisitor, null); if (iter.hasNext()) { @@ -80,7 +77,7 @@ public void deParse(Insert insert) { if (insert.getColumns() != null) { builder.append(" ("); - for (Iterator iter = insert.getColumns().iterator(); iter.hasNext();) { + for (Iterator iter = insert.getColumns().iterator(); iter.hasNext(); ) { Column column = iter.next(); builder.append(column.getColumnName()); if (iter.hasNext()) { @@ -115,9 +112,13 @@ public void deParse(Insert insert) { deparseUpdateSets(insert.getSetUpdateSets(), builder, expressionVisitor); } - if (insert.getDuplicateUpdateSets() != null) { + if (insert.getDuplicateAction() != null) { builder.append(" ON DUPLICATE KEY UPDATE "); - deparseUpdateSets(insert.getDuplicateUpdateSets(), builder, expressionVisitor); + if (ConflictActionType.DO_UPDATE.equals(insert.getDuplicateAction().getConflictActionType())) { + deparseUpdateSets(insert.getDuplicateUpdateSets(), builder, expressionVisitor); + } else { + insert.getDuplicateAction().appendTo(builder); + } } // @todo: Accept some Visitors for the involved Expressions 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 0835284a4..427f5a63e 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java @@ -10,6 +10,7 @@ package net.sf.jsqlparser.util.deparser; import net.sf.jsqlparser.expression.ExpressionVisitor; +import net.sf.jsqlparser.statement.insert.ConflictActionType; import net.sf.jsqlparser.statement.select.SelectVisitor; import net.sf.jsqlparser.statement.upsert.Upsert; @@ -19,8 +20,7 @@ public class UpsertDeParser extends AbstractDeParser { private ExpressionDeParser expressionVisitor; private SelectDeParser selectVisitor; - public UpsertDeParser(ExpressionDeParser expressionVisitor, SelectDeParser selectVisitor, - StringBuilder buffer) { + public UpsertDeParser(ExpressionDeParser expressionVisitor, SelectDeParser selectVisitor, StringBuilder buffer) { super(buffer); this.expressionVisitor = expressionVisitor; this.expressionVisitor.setSelectVisitor(selectVisitor); @@ -78,9 +78,13 @@ public void deParse(Upsert upsert) { upsert.getSelect().accept((SelectVisitor) selectVisitor, null); } - if (upsert.getDuplicateUpdateSets() != null) { + if (upsert.getDuplicateAction() != null) { builder.append(" ON DUPLICATE KEY UPDATE "); - deparseUpdateSets(upsert.getDuplicateUpdateSets(), builder, expressionVisitor); + if (ConflictActionType.DO_UPDATE.equals(upsert.getDuplicateAction().getConflictActionType())) { + deparseUpdateSets(upsert.getDuplicateUpdateSets(), builder, expressionVisitor); + } else { + upsert.getDuplicateAction().appendTo(builder); + } } } } diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 69b534654..03a86ac56 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -2742,6 +2742,8 @@ Insert Insert(): InsertConflictTarget conflictTarget = null; InsertConflictAction conflictAction = null; + + InsertDuplicateAction duplicateAction = null; } { { insert.setOracleHint(getOracleHint()); } @@ -2780,7 +2782,7 @@ Insert Insert(): ) [ LOOKAHEAD(2) - duplicateUpdateSets = UpdateSets() { insert.withDuplicateUpdateSets(duplicateUpdateSets); } + duplicateAction = InsertDuplicateAction() { insert.setDuplicateAction(duplicateAction); } ] [ @@ -2860,6 +2862,30 @@ InsertConflictAction InsertConflictAction(): .withWhereExpression(whereExpression); } } +InsertDuplicateAction InsertDuplicateAction(): +{ + InsertDuplicateAction duplicateAction; + Expression whereExpression = null; + List updateSets; +} +{ + ( + LOOKAHEAD(2) ( + { duplicateAction = new InsertDuplicateAction( ConflictActionType.NOTHING ); } + ) + | + ( + { duplicateAction = new InsertDuplicateAction( ConflictActionType.DO_UPDATE ); } + updateSets = UpdateSets() { duplicateAction.setUpdateSets(updateSets); } + [ whereExpression = WhereClause() ] + ) + ) + + { return duplicateAction + .withWhereExpression(whereExpression); } +} + + OutputClause OutputClause(): { List> selectItemList = null; @@ -2895,6 +2921,7 @@ Upsert Upsert(): Select select = null; List duplicateUpdateSets; + InsertDuplicateAction duplicateAction = null; Token tk = null; } { @@ -2925,7 +2952,7 @@ Upsert Upsert(): [ - duplicateUpdateSets = UpdateSets() { upsert.setDuplicateUpdateSets(duplicateUpdateSets); } + duplicateAction = InsertDuplicateAction() { upsert.setDuplicateAction(duplicateAction); } ] { diff --git a/src/test/java/net/sf/jsqlparser/statement/insert/InsertTest.java b/src/test/java/net/sf/jsqlparser/statement/insert/InsertTest.java index 850fedfd9..e20476b9f 100644 --- a/src/test/java/net/sf/jsqlparser/statement/insert/InsertTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/insert/InsertTest.java @@ -916,5 +916,9 @@ void insertDemo() { TestUtils.assertStatementCanBeDeparsedAs( insert, "INSERT INTO test VALUES ('A', 'B')"); } - + @Test + public void testSimpleDuplicateInsert() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed( + "INSERT INTO example (num, name, address, tel) VALUES (1, 'name', 'test ', '1234-1234') ON DUPLICATE KEY update NOTHING"); + } } diff --git a/src/test/java/net/sf/jsqlparser/statement/upsert/UpsertTest.java b/src/test/java/net/sf/jsqlparser/statement/upsert/UpsertTest.java index 508a2da03..d1aa00c40 100644 --- a/src/test/java/net/sf/jsqlparser/statement/upsert/UpsertTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/upsert/UpsertTest.java @@ -107,7 +107,11 @@ public void testUpsertMultiRowValue() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("UPSERT INTO mytable (col1, col2) VALUES (a, b), (d, e)", true); } - + @Test + public void testUpsertMultiRowValueDoNothing() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO mytable (col1, col2) VALUES (a, b) ON DUPLICATE KEY UPDATE nothing", + true); + } @Test @Disabled /* not the job of the parser to validate this, it even may be valid eventually */ diff --git a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java index 1b129e6a2..23b3927e6 100644 --- a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java +++ b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java @@ -129,7 +129,7 @@ public void shouldUseProvidedDeparsersWhenDeParsingInsert() { then(withItem2).should().accept((SelectVisitor) selectDeParser, null); then(select).should().accept((SelectVisitor) selectDeParser, null); then(duplicateUpdateExpression1).should().accept(expressionDeParser, null); - then(duplicateUpdateExpression1).should().accept(expressionDeParser, null); + then(duplicateUpdateExpression2).should().accept(expressionDeParser, null); } // @Test From b65b51c0661346578fe670e8aa165eb53e1e247b Mon Sep 17 00:00:00 2001 From: zhangkenan Date: Thu, 28 Aug 2025 17:34:47 +0800 Subject: [PATCH 2/4] use import single classes instead of wildcard imports in Insert class. --- .../java/net/sf/jsqlparser/statement/insert/Insert.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java index ee9f13450..78063885e 100644 --- a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java +++ b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java @@ -18,7 +18,11 @@ import net.sf.jsqlparser.statement.ReturningClause; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.StatementVisitor; -import net.sf.jsqlparser.statement.select.*; +import net.sf.jsqlparser.statement.select.PlainSelect; +import net.sf.jsqlparser.statement.select.Select; +import net.sf.jsqlparser.statement.select.SetOperationList; +import net.sf.jsqlparser.statement.select.Values; +import net.sf.jsqlparser.statement.select.WithItem; import net.sf.jsqlparser.statement.update.UpdateSet; import java.util.*; From 48f905e17f96e89416adea8788de5625e435044c Mon Sep 17 00:00:00 2001 From: zhangkenan Date: Thu, 28 Aug 2025 17:35:57 +0800 Subject: [PATCH 3/4] use import single classes instead of wildcard imports in Insert class. --- .../java/net/sf/jsqlparser/statement/insert/Insert.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java index 78063885e..19ec9f347 100644 --- a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java +++ b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java @@ -25,7 +25,11 @@ import net.sf.jsqlparser.statement.select.WithItem; import net.sf.jsqlparser.statement.update.UpdateSet; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; @SuppressWarnings({"PMD.CyclomaticComplexity"}) public class Insert implements Statement { From 7c66eb1bd93d52e34c733ee64a4ce91bb7ec15fc Mon Sep 17 00:00:00 2001 From: zhangkenan Date: Thu, 28 Aug 2025 18:17:04 +0800 Subject: [PATCH 4/4] use './gradlew :spotlessApply' adjust code format. --- .../statement/insert/ConflictActionType.java | 4 +--- .../net/sf/jsqlparser/statement/insert/Insert.java | 8 +++++--- .../statement/insert/InsertDuplicateAction.java | 11 +++++++---- .../net/sf/jsqlparser/statement/upsert/Upsert.java | 3 ++- .../jsqlparser/util/deparser/InsertDeParser.java | 14 +++++++++----- .../jsqlparser/util/deparser/UpsertDeParser.java | 6 ++++-- .../sf/jsqlparser/statement/insert/InsertTest.java | 1 + .../sf/jsqlparser/statement/upsert/UpsertTest.java | 5 ++++- 8 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/ConflictActionType.java b/src/main/java/net/sf/jsqlparser/statement/insert/ConflictActionType.java index 3de1a21e7..8e82829b4 100644 --- a/src/main/java/net/sf/jsqlparser/statement/insert/ConflictActionType.java +++ b/src/main/java/net/sf/jsqlparser/statement/insert/ConflictActionType.java @@ -10,9 +10,7 @@ package net.sf.jsqlparser.statement.insert; public enum ConflictActionType { - NOTHING, - DO_NOTHING, - DO_UPDATE; + NOTHING, DO_NOTHING, DO_UPDATE; public static ConflictActionType from(String type) { return Enum.valueOf(ConflictActionType.class, type.toUpperCase()); diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java index 19ec9f347..1a750494c 100644 --- a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java +++ b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java @@ -167,7 +167,8 @@ public boolean isUseSelectBrackets() { @Deprecated public boolean isUseDuplicate() { - return duplicateAction != null && duplicateAction.getUpdateSets() != null && !duplicateAction.getUpdateSets().isEmpty(); + return duplicateAction != null && duplicateAction.getUpdateSets() != null + && !duplicateAction.getUpdateSets().isEmpty(); } public InsertModifierPriority getModifierPriority() { @@ -273,7 +274,7 @@ public String toString() { StringBuilder sql = new StringBuilder(); if (withItemsList != null && !withItemsList.isEmpty()) { sql.append("WITH "); - for (Iterator> iter = withItemsList.iterator(); iter.hasNext(); ) { + for (Iterator> iter = withItemsList.iterator(); iter.hasNext();) { WithItem withItem = iter.next(); sql.append(withItem); if (iter.hasNext()) { @@ -397,7 +398,8 @@ public Insert addColumns(Column... columns) { } public Insert addColumns(Collection columns) { - ExpressionList collection = Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new); + ExpressionList collection = + Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new); collection.addAll(columns); return this.withColumns(collection); } diff --git a/src/main/java/net/sf/jsqlparser/statement/insert/InsertDuplicateAction.java b/src/main/java/net/sf/jsqlparser/statement/insert/InsertDuplicateAction.java index 1e359f125..4a106a6f7 100644 --- a/src/main/java/net/sf/jsqlparser/statement/insert/InsertDuplicateAction.java +++ b/src/main/java/net/sf/jsqlparser/statement/insert/InsertDuplicateAction.java @@ -22,8 +22,9 @@ /** * on duplicate key is one of: * - * ON DUPLICATE KEY UPDATE NOTHING ON DUPLICATE KEY UPDATE { column_name = { expression | DEFAULT } | ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT - * } [, ...] ) | ( column_name [, ...] ) = ( sub-SELECT ) } [, ...] [ WHERE condition ] + * ON DUPLICATE KEY UPDATE NOTHING ON DUPLICATE KEY UPDATE { column_name = { expression | DEFAULT } + * | ( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) | ( column_name [, ...] + * ) = ( sub-SELECT ) } [, ...] [ WHERE condition ] * * @author zhangconan */ @@ -34,7 +35,8 @@ public class InsertDuplicateAction implements Serializable { private List updateSets; public InsertDuplicateAction(ConflictActionType conflictActionType) { - this.conflictActionType = Objects.requireNonNull(conflictActionType, "The Conflict Action Type is mandatory and must not be Null."); + this.conflictActionType = Objects.requireNonNull(conflictActionType, + "The Conflict Action Type is mandatory and must not be Null."); } public List getUpdateSets() { @@ -55,7 +57,8 @@ public ConflictActionType getConflictActionType() { } public void setConflictActionType(ConflictActionType conflictActionType) { - this.conflictActionType = Objects.requireNonNull(conflictActionType, "The Conflict Action Type is mandatory and must not be Null."); + this.conflictActionType = Objects.requireNonNull(conflictActionType, + "The Conflict Action Type is mandatory and must not be Null."); } public InsertDuplicateAction withConflictActionType(ConflictActionType conflictActionType) { 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 c734aa87c..c13397569 100644 --- a/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java +++ b/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java @@ -226,7 +226,8 @@ public Upsert addColumns(Column... columns) { } public Upsert addColumns(Collection columns) { - ExpressionList collection = Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new); + ExpressionList collection = + Optional.ofNullable(getColumns()).orElseGet(ExpressionList::new); collection.addAll(columns); return this.withColumns(collection); } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java index 2bab7182a..58a3018c5 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java @@ -29,18 +29,21 @@ public InsertDeParser() { super(new StringBuilder()); } - public InsertDeParser(ExpressionVisitor expressionVisitor, SelectVisitor selectVisitor, StringBuilder buffer) { + public InsertDeParser(ExpressionVisitor expressionVisitor, + SelectVisitor selectVisitor, StringBuilder buffer) { super(buffer); this.expressionVisitor = expressionVisitor; this.selectVisitor = selectVisitor; } @Override - @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.ExcessiveMethodLength", "PMD.NPathComplexity"}) + @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.ExcessiveMethodLength", + "PMD.NPathComplexity"}) public void deParse(Insert insert) { if (insert.getWithItemsList() != null && !insert.getWithItemsList().isEmpty()) { builder.append("WITH "); - for (Iterator> iter = insert.getWithItemsList().iterator(); iter.hasNext(); ) { + for (Iterator> iter = insert.getWithItemsList().iterator(); iter + .hasNext();) { WithItem withItem = iter.next(); withItem.accept(this.selectVisitor, null); if (iter.hasNext()) { @@ -77,7 +80,7 @@ public void deParse(Insert insert) { if (insert.getColumns() != null) { builder.append(" ("); - for (Iterator iter = insert.getColumns().iterator(); iter.hasNext(); ) { + for (Iterator iter = insert.getColumns().iterator(); iter.hasNext();) { Column column = iter.next(); builder.append(column.getColumnName()); if (iter.hasNext()) { @@ -114,7 +117,8 @@ public void deParse(Insert insert) { if (insert.getDuplicateAction() != null) { builder.append(" ON DUPLICATE KEY UPDATE "); - if (ConflictActionType.DO_UPDATE.equals(insert.getDuplicateAction().getConflictActionType())) { + if (ConflictActionType.DO_UPDATE + .equals(insert.getDuplicateAction().getConflictActionType())) { deparseUpdateSets(insert.getDuplicateUpdateSets(), builder, expressionVisitor); } else { insert.getDuplicateAction().appendTo(builder); 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 427f5a63e..218ca1db3 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java @@ -20,7 +20,8 @@ public class UpsertDeParser extends AbstractDeParser { private ExpressionDeParser expressionVisitor; private SelectDeParser selectVisitor; - public UpsertDeParser(ExpressionDeParser expressionVisitor, SelectDeParser selectVisitor, StringBuilder buffer) { + public UpsertDeParser(ExpressionDeParser expressionVisitor, SelectDeParser selectVisitor, + StringBuilder buffer) { super(buffer); this.expressionVisitor = expressionVisitor; this.expressionVisitor.setSelectVisitor(selectVisitor); @@ -80,7 +81,8 @@ public void deParse(Upsert upsert) { if (upsert.getDuplicateAction() != null) { builder.append(" ON DUPLICATE KEY UPDATE "); - if (ConflictActionType.DO_UPDATE.equals(upsert.getDuplicateAction().getConflictActionType())) { + if (ConflictActionType.DO_UPDATE + .equals(upsert.getDuplicateAction().getConflictActionType())) { deparseUpdateSets(upsert.getDuplicateUpdateSets(), builder, expressionVisitor); } else { upsert.getDuplicateAction().appendTo(builder); diff --git a/src/test/java/net/sf/jsqlparser/statement/insert/InsertTest.java b/src/test/java/net/sf/jsqlparser/statement/insert/InsertTest.java index e20476b9f..95e1d069b 100644 --- a/src/test/java/net/sf/jsqlparser/statement/insert/InsertTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/insert/InsertTest.java @@ -916,6 +916,7 @@ void insertDemo() { TestUtils.assertStatementCanBeDeparsedAs( insert, "INSERT INTO test VALUES ('A', 'B')"); } + @Test public void testSimpleDuplicateInsert() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed( diff --git a/src/test/java/net/sf/jsqlparser/statement/upsert/UpsertTest.java b/src/test/java/net/sf/jsqlparser/statement/upsert/UpsertTest.java index d1aa00c40..3a01b890d 100644 --- a/src/test/java/net/sf/jsqlparser/statement/upsert/UpsertTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/upsert/UpsertTest.java @@ -107,11 +107,14 @@ public void testUpsertMultiRowValue() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("UPSERT INTO mytable (col1, col2) VALUES (a, b), (d, e)", true); } + @Test public void testUpsertMultiRowValueDoNothing() throws JSQLParserException { - assertSqlCanBeParsedAndDeparsed("UPSERT INTO mytable (col1, col2) VALUES (a, b) ON DUPLICATE KEY UPDATE nothing", + assertSqlCanBeParsedAndDeparsed( + "UPSERT INTO mytable (col1, col2) VALUES (a, b) ON DUPLICATE KEY UPDATE nothing", true); } + @Test @Disabled /* not the job of the parser to validate this, it even may be valid eventually */