Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.MultiPartName;
Expand Down Expand Up @@ -86,6 +87,10 @@ public List<ReturningOutputAlias> getOutputAliases() {
}

public StringBuilder appendTo(StringBuilder builder) {
return appendTo(builder, item -> builder.append(item));
}

public StringBuilder appendTo(StringBuilder builder, Consumer<SelectItem<?>> itemPrinter) {
builder.append(" ").append(keyword).append(" ");
if (outputAliases != null && !outputAliases.isEmpty()) {
builder.append("WITH (");
Expand All @@ -101,7 +106,7 @@ public StringBuilder appendTo(StringBuilder builder) {
if (i > 0) {
builder.append(", ");
}
builder.append(get(i));
itemPrinter.accept(get(i));
}

if (dataItems != null && !dataItems.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@ public <S> T visit(Insert insert, S context) {
expressionVisitor.visitUpdateSets(conflictAction.getUpdateSets(), context);
}

if (insert.getConflictTarget() != null) {
insert.getConflictTarget().accept(expressionVisitor, context);
}
visitReturningClause(insert.getReturningClause(), context);
return null;
}
Expand Down Expand Up @@ -457,6 +460,7 @@ public <S> T visit(Merge merge, S context) {
expressionVisitor.visitExpression(merge.getOnCondition(), context);
mergeOperationVisitor.visit(merge.getOperations(), context);
selectVisitor.visitOutputClause(merge.getOutputClause(), context);
visitReturningClause(merge.getReturningClause(), context);
return null;
}

Expand Down
22 changes: 20 additions & 2 deletions src/main/java/net/sf/jsqlparser/statement/create/table/Index.java
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ public enum NullOrdering {
public final String columnName;
public final List<String> params;
private final Expression expression;
private boolean expressionParenthesized = true;
private String collation;
private String operatorClass;
private List<Option> operatorClassParameters;
Expand Down Expand Up @@ -386,6 +387,19 @@ public boolean isExpression() {
return expression != null;
}

public boolean isExpressionParenthesized() {
return expressionParenthesized;
}

public void setExpressionParenthesized(boolean expressionParenthesized) {
this.expressionParenthesized = expressionParenthesized;
}

public ColumnParams withExpressionParenthesized(boolean expressionParenthesized) {
setExpressionParenthesized(expressionParenthesized);
return this;
}

public String getCollation() {
return collation;
}
Expand Down Expand Up @@ -461,9 +475,13 @@ public String toString() {
/** Renders expression keys through the caller's expression printer. */
public void appendTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
if (expression != null) {
builder.append('(');
if (expressionParenthesized) {
builder.append('(');
}
expressionPrinter.accept(expression);
builder.append(')');
if (expressionParenthesized) {
builder.append(')');
}
} else {
builder.append(columnName);
}
Expand Down
28 changes: 23 additions & 5 deletions src/main/java/net/sf/jsqlparser/statement/insert/Insert.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ public class Insert implements Statement {
private List<Partition> partitions;
private Select select;
private boolean onlyDefaultValues = false;
private boolean overriding = false;

public enum OverridingMode {
NONE, SYSTEM, USER
}

private OverridingMode overridingMode = OverridingMode.NONE;
private List<UpdateSet> duplicateUpdateSets = null;
private InsertModifierPriority modifierPriority = null;
private boolean modifierIgnore = false;
Expand Down Expand Up @@ -226,12 +231,25 @@ public void setWithItemsList(List<WithItem<?>> withItemsList) {
this.withItemsList = withItemsList;
}

public OverridingMode getOverridingMode() {
return overridingMode;
}

public void setOverridingMode(OverridingMode overridingMode) {
this.overridingMode = java.util.Objects.requireNonNull(overridingMode);
}

public Insert withOverridingMode(OverridingMode overridingMode) {
setOverridingMode(overridingMode);
return this;
}

public boolean isOverriding() {
return overriding;
return overridingMode != OverridingMode.NONE;
}

public void setOverriding(boolean overriding) {
this.overriding = overriding;
this.overridingMode = overriding ? OverridingMode.SYSTEM : OverridingMode.NONE;
}

public Insert withOverriding(boolean overriding) {
Expand Down Expand Up @@ -388,8 +406,8 @@ private void appendInsertTargetAndValues(StringBuilder sql) {
sql.append(") ");
}

if (overriding) {
sql.append("OVERRIDING SYSTEM VALUE ");
if (isOverriding()) {
sql.append("OVERRIDING ").append(overridingMode).append(" VALUE ");
}

if (partitions != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
package net.sf.jsqlparser.statement.insert;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;
import net.sf.jsqlparser.statement.create.table.Index;
import java.util.function.Consumer;

import java.io.Serializable;
import java.util.*;
Expand All @@ -23,75 +26,145 @@
* ( { index_column_name | ( index_expression ) } [ COLLATE collation ] [ opclass ] [, ...] ) [ WHERE index_predicate ]
* ON CONSTRAINT constraint_name
* </pre>
* <p>
* Currently, COLLATE is not supported yet.
*/
public class InsertConflictTarget implements Serializable {
private final List<Index.ColumnParams> indexElements = new ArrayList<>();
private Expression whereExpression;
private String constraintName;

ArrayList<String> indexColumnNames = new ArrayList<>();
Expression indexExpression;
Expression whereExpression;
String constraintName;
public InsertConflictTarget() {}

public InsertConflictTarget(String indexColumnName, Expression indexExpression,
Expression whereExpression, String constraintName) {
this.indexColumnNames.add(indexColumnName);
this.indexExpression = indexExpression;
this(indexColumnName == null ? Collections.emptyList()
: Collections.singletonList(indexColumnName),
indexExpression, whereExpression, constraintName);
}

public InsertConflictTarget(Collection<String> indexColumnNames, Expression indexExpression,
Expression whereExpression, String constraintName) {
if (indexColumnNames != null && !indexColumnNames.isEmpty()) {
addAllIndexColumnNames(indexColumnNames);
} else if (indexExpression != null) {
setIndexExpression(indexExpression);
}
this.whereExpression = whereExpression;
this.constraintName = constraintName;
}

public InsertConflictTarget(Collection<String> indexColumnName, Expression indexExpression,
Expression whereExpression, String constraintName) {
this.indexColumnNames.addAll(indexColumnName);
this.indexExpression = indexExpression;
/** Ordered column and expression keys, including their collation and operator class. */
public List<Index.ColumnParams> getIndexElements() {
return indexElements;
}

this.whereExpression = whereExpression;
this.constraintName = constraintName;
public void setIndexElements(List<Index.ColumnParams> elements) {
List<Index.ColumnParams> copy = new ArrayList<>(elements);
indexElements.clear();
indexElements.addAll(copy);
}

public InsertConflictTarget withIndexElements(List<Index.ColumnParams> elements) {
setIndexElements(elements);
return this;
}

/** A mutable view of the column keys; expression keys are available via getIndexElements(). */
public List<String> getIndexColumnNames() {
return indexColumnNames;
return new AbstractList<String>() {
private int elementIndex(int index) {
int columnIndex = 0;
for (int i = 0; i < indexElements.size(); i++) {
if (!indexElements.get(i).isExpression() && columnIndex++ == index) {
return i;
}
}
throw new IndexOutOfBoundsException("Column index: " + index);
}

@Override
public String get(int index) {
return indexElements.get(elementIndex(index)).getColumnName();
}

@Override
public int size() {
return (int) indexElements.stream().filter(key -> !key.isExpression()).count();
}

@Override
public String set(int index, String name) {
return indexElements.set(elementIndex(index), new Index.ColumnParams(name))
.getColumnName();
}

@Override
public void add(int index, String name) {
indexElements.add(index == size() ? indexElements.size() : elementIndex(index),
new Index.ColumnParams(name));
}

@Override
public boolean addAll(Collection<? extends String> names) {
return addAll(size(), names);
}

@Override
public boolean addAll(int index, Collection<? extends String> names) {
int insertionIndex = index == size() ? indexElements.size() : elementIndex(index);
List<Index.ColumnParams> additions = new ArrayList<>();
for (String name : names) {
additions.add(new Index.ColumnParams(name));
}
return indexElements.addAll(insertionIndex, additions);
}

@Override
public String remove(int index) {
return indexElements.remove(elementIndex(index)).getColumnName();
}
};
}

@Deprecated
public String getIndexColumnName() {
return indexColumnNames.isEmpty() ? null : indexColumnNames.get(0);
return getIndexColumnName(0);
}

public String getIndexColumnName(int index) {
return indexColumnNames.size() > index ? indexColumnNames.get(index) : null;
List<String> names = getIndexColumnNames();
return names.size() > index ? names.get(index) : null;
}

public boolean addIndexColumnName(String indexColumnName) {
this.indexExpression = null;
return this.indexColumnNames.add(indexColumnName);
public boolean addIndexColumnName(String name) {
indexElements.removeIf(Index.ColumnParams::isExpression);
return indexElements.add(new Index.ColumnParams(name));
}

public InsertConflictTarget withIndexColumnName(String indexColumnName) {
this.indexExpression = null;
this.indexColumnNames.add(indexColumnName);
public InsertConflictTarget withIndexColumnName(String name) {
addIndexColumnName(name);
return this;
}

public boolean addAllIndexColumnNames(Collection<String> indexColumnName) {
this.indexExpression = null;
return this.indexColumnNames.addAll(indexColumnName);
public boolean addAllIndexColumnNames(Collection<String> names) {
indexElements.removeIf(Index.ColumnParams::isExpression);
return getIndexColumnNames().addAll(names);
}


/** Returns the first expression key, or null for a column-only target. */
public Expression getIndexExpression() {
return indexExpression;
return indexElements.stream().filter(Index.ColumnParams::isExpression)
.map(Index.ColumnParams::getExpression).findFirst().orElse(null);
}

public void setIndexExpression(Expression indexExpression) {
this.indexExpression = indexExpression;
this.indexColumnNames.clear();
public void setIndexExpression(Expression expression) {
indexElements.clear();
if (expression != null) {
indexElements.add(new Index.ColumnParams(expression));
}
}

public InsertConflictTarget withIndexExpression(Expression indexExpression) {
setIndexExpression(indexExpression);
public InsertConflictTarget withIndexExpression(Expression expression) {
setIndexExpression(expression);
return this;
}

Expand Down Expand Up @@ -121,35 +194,42 @@ public InsertConflictTarget withConstraintName(String constraintName) {
return this;
}

public StringBuilder appendTo(StringBuilder builder) {
if (constraintName == null) {
builder.append(" ( ");

// @todo: Index Expression is not supported yet
if (!indexColumnNames.isEmpty()) {
boolean insertComma = false;
for (String s : indexColumnNames) {
builder.append(insertComma ? ", " : " ").append(s);
insertComma |= true;
}
} else {
builder.append(" ( ").append(indexExpression).append(" )");
/** Visits expression keys and the optional index predicate. */
public <S> void accept(ExpressionVisitor<?> visitor, S context) {
for (Index.ColumnParams element : indexElements) {
if (element.getExpression() != null) {
element.getExpression().accept(visitor, context);
}
builder.append(" ");

// @todo: Collate is not supported yet
}
if (whereExpression != null) {
whereExpression.accept(visitor, context);
}
}

builder.append(") ");
public StringBuilder appendTo(StringBuilder builder) {
return appendTo(builder, expression -> builder.append(expression));
}

if (whereExpression != null) {
builder.append(" WHERE ").append(whereExpression);
public StringBuilder appendTo(StringBuilder builder, Consumer<Expression> expressionPrinter) {
if (constraintName != null) {
return builder.append(" ON CONSTRAINT ").append(constraintName);
}
builder.append(" (");
for (int i = 0; i < indexElements.size(); i++) {
if (i > 0) {
builder.append(", ");
}
} else {
builder.append(" ON CONSTRAINT ").append(constraintName);
indexElements.get(i).appendTo(builder, expressionPrinter);
}
builder.append(")");
if (whereExpression != null) {
builder.append(" WHERE ");
expressionPrinter.accept(whereExpression);
}
return builder;
}

@Override
public String toString() {
return appendTo(new StringBuilder()).toString();
}
Expand Down
Loading
Loading