Skip to content

Commit

Permalink
Add Upsert Grammer (#460)
Browse files Browse the repository at this point in the history
* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add test for de parser

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload

* Add files via upload
  • Loading branch information
messfish authored and wumpz committed Jun 11, 2017
1 parent 3e75c68 commit aaeb8df
Show file tree
Hide file tree
Showing 10 changed files with 724 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.upsert.Upsert;

public interface StatementVisitor {

Expand Down Expand Up @@ -71,4 +72,7 @@ public interface StatementVisitor {
void visit(Merge merge);

void visit(Select select);

void visit(Upsert upsert);

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.upsert.Upsert;

public class StatementVisitorAdapter implements StatementVisitor {
@Override
Expand Down Expand Up @@ -122,4 +123,9 @@ public void visit(Merge merge) {
@Override
public void visit(AlterView alterView) {
}

@Override
public void visit(Upsert upsert) {

}
}
180 changes: 180 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
* #%L
* JSQLParser library
* %%
* Copyright (C) 2004 - 2017 JSQLParser
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/
package net.sf.jsqlparser.statement.upsert;

import java.util.List;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
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;

/**
* The UPSERT INTO statement. This statement is basically the combination of
* "insert" and "update". That means it will operate inserts if not present
* and updates otherwise the value in the table. Note the values modified
* will be either a list of values or a select statement.
*
*
* Here is the documentation of the grammar of this operation:
* http://phoenix.apache.org/language/#upsert_values
* http://phoenix.apache.org/language/#upsert_select
*
* @author messfish
*
*/
public class Upsert implements Statement {

private Table table;
private List<Column> columns;
private ItemsList itemsList;
private boolean useValues = true;
private Select select;
private boolean useSelectBrackets = true;
private boolean useDuplicate = false;
private List<Column> duplicateUpdateColumns;
private List<Expression> duplicateUpdateExpressionList;

@Override
public void accept(StatementVisitor statementVisitor) {
statementVisitor.visit(this);
}

public void setTable(Table name) {
table = name;
}

public Table getTable() {
return table;
}

public void setColumns(List<Column> list) {
columns = list;
}

public List<Column> getColumns() {
return columns;
}

public void setItemsList(ItemsList list) {
itemsList = list;
}

public ItemsList getItemsList() {
return itemsList;
}

public void setUseValues(boolean useValues) {
this.useValues = useValues;
}

public boolean isUseValues() {
return useValues;
}

public void setSelect(Select select) {
this.select = select;
}

public Select getSelect() {
return select;
}

public void setUseSelectBrackets(boolean useSelectBrackets) {
this.useSelectBrackets = useSelectBrackets;
}

public boolean isUseSelectBrackets() {
return useSelectBrackets;
}

public void setUseDuplicate(boolean useDuplicate) {
this.useDuplicate = useDuplicate;
}

public boolean isUseDuplicate() {
return useDuplicate;
}

public void setDuplicateUpdateColumns(List<Column> duplicateUpdateColumns) {
this.duplicateUpdateColumns = duplicateUpdateColumns;
}

public List<Column> getDuplicateUpdateColumns() {
return duplicateUpdateColumns;
}

public void setDuplicateUpdateExpressionList(List<Expression> duplicateUpdateExpressionList) {
this.duplicateUpdateExpressionList = duplicateUpdateExpressionList;
}

public List<Expression> getDuplicateUpdateExpressionList() {
return duplicateUpdateExpressionList;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();

sb.append("UPSERT INTO ");
sb.append(table).append(" ");
if (columns != null) {
sb.append(PlainSelect.getStringList(columns, true, true)).append(" ");
}
if (useValues) {
sb.append("VALUES ");
}

if (itemsList != null) {
sb.append(itemsList);
} else {
if (useSelectBrackets) {
sb.append("(");
}
if (select != null) {
sb.append(select);
}
if (useSelectBrackets) {
sb.append(")");
}
}

if (useDuplicate) {
sb.append(" ON DUPLICATE KEY UPDATE ");
for (int i = 0; i < getDuplicateUpdateColumns().size(); i++) {
if (i != 0) {
sb.append(", ");
}
sb.append(duplicateUpdateColumns.get(i)).append(" = ");
sb.append(duplicateUpdateExpressionList.get(i));
}
}

return sb.toString();
}

}

12 changes: 12 additions & 0 deletions src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
import net.sf.jsqlparser.statement.select.WithItem;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.upsert.Upsert;

/**
* Find all used tables within an select statement.
Expand Down Expand Up @@ -720,4 +721,15 @@ public void visit(DateTimeLiteralExpression literal) {
public void visit(Commit commit) {

}

@Override
public void visit(Upsert upsert) {
tables.add(upsert.getTable().getName());
if (upsert.getItemsList() != null) {
upsert.getItemsList().accept(this);
}
if (upsert.getSelect() != null) {
visit(upsert.getSelect());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import net.sf.jsqlparser.statement.select.WithItem;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.upsert.Upsert;

public class StatementDeParser implements StatementVisitor {
private ExpressionDeParser expressionDeParser;
Expand Down Expand Up @@ -204,4 +205,14 @@ public void visit(Merge merge) {
public void visit(Commit commit) {
buffer.append(commit.toString());
}

@Override
public void visit(Upsert upsert) {
selectDeParser.setBuffer(buffer);
expressionDeParser.setSelectVisitor(selectDeParser);
expressionDeParser.setBuffer(buffer);
selectDeParser.setExpressionVisitor(expressionDeParser);
UpsertDeParser upsertDeParser = new UpsertDeParser(expressionDeParser, selectDeParser, buffer);
upsertDeParser.deParse(upsert);
}
}
Loading

0 comments on commit aaeb8df

Please sign in to comment.