From 12e684df4b81c7700a15f8ffe8f21f7dd284dfb6 Mon Sep 17 00:00:00 2001 From: messfish Date: Tue, 6 Jun 2017 18:51:47 -0400 Subject: [PATCH 01/20] Add files via upload --- .../sf/jsqlparser/util/TablesNamesFinder.java | 12 ++ .../util/deparser/StatementDeParser.java | 11 ++ .../util/deparser/UpsertDeParser.java | 180 ++++++++++++++++++ 3 files changed, 203 insertions(+) create mode 100644 src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java diff --git a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java index 215f56aed..a8b972474 100644 --- a/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java +++ b/src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java @@ -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. @@ -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()); + } + } } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java index 49dbb2f30..a8896103b 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java @@ -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; @@ -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 selectDeParser = new SelectDeParser(); + selectDeParser.setBuffer(buffer); + ExpressionDeParser expressionDeParser = new ExpressionDeParser(selectDeParser, buffer); + selectDeParser.setExpressionVisitor(expressionDeParser); + UpsertDeParser upsertDeParser = new UpsertDeParser(expressionDeParser, selectDeParser, buffer); + upsertDeParser.deParse(upsert); + } } diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java new file mode 100644 index 000000000..46fb0cdba --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java @@ -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 + * . + * #L% + */ +package net.sf.jsqlparser.util.deparser; + +import java.util.Iterator; + +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.ExpressionVisitor; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor; +import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList; +import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.statement.select.SelectVisitor; +import net.sf.jsqlparser.statement.select.SubSelect; +import net.sf.jsqlparser.statement.select.WithItem; +import net.sf.jsqlparser.statement.upsert.Upsert; + +/** + * A class to de-parse (that is, tranform from JSqlParser hierarchy into a string) + * @author messfish + * + */ +public class UpsertDeParser implements ItemsListVisitor { + + private StringBuilder buffer; + private ExpressionVisitor expressionVisitor; + private SelectVisitor selectVisitor; + + /** + * Constructor: this constructor is used to assign the values coming from the + * arguments to their global values. + * @param expressionVisitor a {@link ExpressionVisitor} to de-parse + * {@link net.sf.jsqlparser.expression.Expression}s. It has to share the same
+ * StringBuilder (buffer parameter) as this object in order to work + * @param selectVisitor a {@link SelectVisitor} to de-parse + * {@link net.sf.jsqlparser.statement.select.Select}s. It has to share the same
+ * StringBuilder (buffer parameter) as this object in order to work + * @param buffer the buffer that will be filled with the insert + */ + public UpsertDeParser(ExpressionVisitor expressionVisitor, SelectVisitor selectVisitor, StringBuilder buffer) { + this.buffer = buffer; + this.expressionVisitor = expressionVisitor; + this.selectVisitor = selectVisitor; + } + + public StringBuilder getBuffer() { + return buffer; + } + + public void setBuffer(StringBuilder buffer) { + this.buffer = buffer; + } + + public void deParse(Upsert upsert) { + buffer.append("UPSERT INTO "); + + buffer.append(upsert.getTable().getFullyQualifiedName()); + if (upsert.getColumns() != null) { + buffer.append(" ("); + for (Iterator iter = upsert.getColumns().iterator(); iter.hasNext();) { + Column column = iter.next(); + buffer.append(column.getColumnName()); + if (iter.hasNext()) { + buffer.append(", "); + } + } + buffer.append(")"); + } + + if (upsert.getItemsList() != null) { + upsert.getItemsList().accept(this); + } + + if (upsert.getSelect() != null) { + buffer.append(" "); + if (upsert.isUseSelectBrackets()) { + buffer.append("("); + } + if (upsert.getSelect().getWithItemsList() != null) { + buffer.append("WITH "); + for (WithItem with : upsert.getSelect().getWithItemsList()) { + with.accept(selectVisitor); + } + buffer.append(" "); + } + upsert.getSelect().getSelectBody().accept(selectVisitor); + if (upsert.isUseSelectBrackets()) { + buffer.append(")"); + } + } + + if (upsert.isUseDuplicate()) { + buffer.append(" ON DUPLICATE KEY UPDATE "); + for (int i = 0; i < upsert.getDuplicateUpdateColumns().size(); i++) { + Column column = upsert.getDuplicateUpdateColumns().get(i); + buffer.append(column.getFullyQualifiedName()).append(" = "); + + Expression expression = upsert.getDuplicateUpdateExpressionList().get(i); + expression.accept(expressionVisitor); + if (i < upsert.getDuplicateUpdateColumns().size() - 1) { + buffer.append(", "); + } + } + } + + } + + @Override + public void visit(ExpressionList expressionList) { + buffer.append(" VALUES ("); + for (Iterator iter = expressionList.getExpressions().iterator(); iter.hasNext();) { + Expression expression = iter.next(); + expression.accept(expressionVisitor); + if (iter.hasNext()) { + buffer.append(", "); + } + } + buffer.append(")"); + } + + @Override + public void visit(MultiExpressionList multiExprList) { + buffer.append(" VALUES "); + for (Iterator it = multiExprList.getExprList().iterator(); it.hasNext();) { + buffer.append("("); + for (Iterator iter = it.next().getExpressions().iterator(); iter.hasNext();) { + Expression expression = iter.next(); + expression.accept(expressionVisitor); + if (iter.hasNext()) { + buffer.append(", "); + } + } + buffer.append(")"); + if (it.hasNext()) { + buffer.append(", "); + } + } + } + + @Override + public void visit(SubSelect subSelect) { + subSelect.getSelectBody().accept(selectVisitor); + } + + public ExpressionVisitor getExpressionVisitor() { + return expressionVisitor; + } + + public SelectVisitor getSelectVisitor() { + return selectVisitor; + } + + public void setExpressionVisitor(ExpressionVisitor visitor) { + expressionVisitor = visitor; + } + + public void setSelectVisitor(SelectVisitor visitor) { + selectVisitor = visitor; + } + +} From e4e61f7d506d4a6670a4e3e7f25080a465b01d81 Mon Sep 17 00:00:00 2001 From: messfish Date: Tue, 6 Jun 2017 18:52:18 -0400 Subject: [PATCH 02/20] Add files via upload --- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 54874890f..facd3ad7b 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -78,6 +78,7 @@ import net.sf.jsqlparser.statement.execute.*; import net.sf.jsqlparser.statement.select.*; import net.sf.jsqlparser.statement.truncate.*; import net.sf.jsqlparser.statement.update.*; +import net.sf.jsqlparser.statement.upsert.*; import net.sf.jsqlparser.statement.merge.*; import java.util.*; @@ -192,6 +193,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */ | | | +| | | | @@ -364,6 +366,8 @@ Statement SingleStatement() : | stm = Insert() | + stm = Upsert() + | stm = Delete() | stm = Replace() @@ -668,6 +672,84 @@ Insert Insert(): } } +Upsert Upsert(): +{ + Upsert upsert = new Upsert(); + Table table = null; + Column tableColumn = null; + List columns = new ArrayList(); + List primaryExpList = new ArrayList(); + ItemsList itemsList = null; + Expression exp = null; + MultiExpressionList multiExpr = null; + List returning = null; + Select select = null; + boolean useSelectBrackets = false; + boolean useDuplicate = false; + List duplicateUpdateColumns = null; + List duplicateUpdateExpressionList = null; + Token tk = null; +} +{ + + [] table=Table() + + + [LOOKAHEAD(2) "(" tableColumn=Column() { columns.add(tableColumn); } ("," tableColumn=Column() { columns.add(tableColumn); } )* ")" ] + ( + LOOKAHEAD(2) [ | ] "(" exp=SimpleExpression() { primaryExpList.add(exp); } + ("," exp=SimpleExpression() { primaryExpList.add(exp); } )* ")" { itemsList = new ExpressionList(primaryExpList); } + ("," "(" exp=SimpleExpression() { + if (multiExpr==null) { + multiExpr=new MultiExpressionList(); + multiExpr.addExpressionList((ExpressionList)itemsList); + itemsList = multiExpr; + } + primaryExpList = new ArrayList(); + primaryExpList.add(exp); } + ("," exp=SimpleExpression() { primaryExpList.add(exp); } )* ")" { multiExpr.addExpressionList(primaryExpList); } )* + + | + + ( + LOOKAHEAD(2) "(" { useSelectBrackets = true; } + { upsert.setUseValues(false); } + select = Select() + ")" + | + { upsert.setUseValues(false); } + select = Select() + ) + ) + + [ + { useDuplicate = true; } + tableColumn=Column() "=" exp=SimpleExpression() + { + duplicateUpdateColumns = new ArrayList(); + duplicateUpdateExpressionList = new ArrayList(); + duplicateUpdateColumns.add(tableColumn); + duplicateUpdateExpressionList.add(exp); + } + ("," tableColumn=Column() "=" exp=SimpleExpression() + { duplicateUpdateColumns.add(tableColumn); + duplicateUpdateExpressionList.add(exp); } )*] + + { + upsert.setItemsList(itemsList); + upsert.setUseSelectBrackets(useSelectBrackets); + upsert.setSelect(select); + upsert.setTable(table); + if (columns.size() > 0) { + upsert.setColumns(columns); + } + upsert.setUseDuplicate(useDuplicate); + upsert.setDuplicateUpdateColumns(duplicateUpdateColumns); + upsert.setDuplicateUpdateExpressionList(duplicateUpdateExpressionList); + return upsert; + } +} + Delete Delete(): { Delete delete = new Delete(); From 6d80406c58c51bc628bdd28a25a22063fc164955 Mon Sep 17 00:00:00 2001 From: messfish Date: Tue, 6 Jun 2017 18:53:58 -0400 Subject: [PATCH 03/20] Add files via upload --- .../statement/StatementVisitor.java | 4 + .../statement/StatementVisitorAdapter.java | 6 + .../jsqlparser/statement/upsert/Upsert.java | 180 ++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java diff --git a/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java b/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java index 8688084de..9a9a05ee9 100644 --- a/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java +++ b/src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java @@ -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 { @@ -71,4 +72,7 @@ public interface StatementVisitor { void visit(Merge merge); void visit(Select select); + + void visit(Upsert upsert); + } diff --git a/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java b/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java index 8e0c07415..b2a364c81 100644 --- a/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java +++ b/src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java @@ -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 @@ -122,4 +123,9 @@ public void visit(Merge merge) { @Override public void visit(AlterView alterView) { } + + @Override + public void visit(Upsert upsert) { + + } } diff --git a/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java b/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java new file mode 100644 index 000000000..a5d9a86db --- /dev/null +++ b/src/main/java/net/sf/jsqlparser/statement/upsert/Upsert.java @@ -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 + * . + * #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 columns; + private ItemsList itemsList; + private boolean useValues = true; + private Select select; + private boolean useSelectBrackets = true; + private boolean useDuplicate = false; + private List duplicateUpdateColumns; + private List 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 list) { + columns = list; + } + + public List 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 duplicateUpdateColumns) { + this.duplicateUpdateColumns = duplicateUpdateColumns; + } + + public List getDuplicateUpdateColumns() { + return duplicateUpdateColumns; + } + + public void setDuplicateUpdateExpressionList(List duplicateUpdateExpressionList) { + this.duplicateUpdateExpressionList = duplicateUpdateExpressionList; + } + + public List 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(); + } + +} + From b181025941aefadf4ab83af6c91f09d317352748 Mon Sep 17 00:00:00 2001 From: messfish Date: Tue, 6 Jun 2017 18:54:43 -0400 Subject: [PATCH 04/20] Add files via upload --- .../sf/jsqlparser/test/upsert/UpsertTest.java | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java diff --git a/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java b/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java new file mode 100644 index 000000000..e01fcfe18 --- /dev/null +++ b/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java @@ -0,0 +1,92 @@ +package net.sf.jsqlparser.test.upsert; + +import static org.junit.Assert.*; + +import java.io.StringReader; + +import org.junit.Test; + +import net.sf.jsqlparser.JSQLParserException; +import net.sf.jsqlparser.expression.LongValue; +import net.sf.jsqlparser.expression.StringValue; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.parser.CCJSqlParserManager; +import net.sf.jsqlparser.schema.Column; +import net.sf.jsqlparser.schema.Table; +import net.sf.jsqlparser.statement.select.PlainSelect; +import net.sf.jsqlparser.statement.upsert.Upsert; + +public class UpsertTest { + + CCJSqlParserManager parserManager = new CCJSqlParserManager(); + + @Test + public void testUpsert() throws JSQLParserException { + String statement ="UPSERT INTO TEST (NAME, ID) VALUES ('foo', 123)"; + Upsert upsert = (Upsert) parserManager.parse(new StringReader(statement)); + assertEquals("TEST", upsert.getTable().getName()); + assertEquals(2, upsert.getColumns().size()); + assertEquals("NAME", ((Column) upsert.getColumns().get(0)).getColumnName()); + assertEquals("ID", ((Column) upsert.getColumns().get(1)).getColumnName()); + assertEquals(2, ((ExpressionList) upsert.getItemsList()).getExpressions().size()); + assertEquals("foo", + ((StringValue) ((ExpressionList) upsert.getItemsList()).getExpressions().get(0)). + getValue()); + assertEquals(123, ((LongValue) ((ExpressionList) upsert.getItemsList()).getExpressions(). + get(1)).getValue()); + assertEquals(statement, "" + upsert); + } + + @Test + public void testUpsertDuplicate() throws JSQLParserException { + String statement="UPSERT INTO TEST (ID, COUNTER) VALUES (123, 0) ON DUPLICATE KEY UPDATE COUNTER = COUNTER + 1"; + Upsert upsert= (Upsert) parserManager.parse(new StringReader(statement)); + assertEquals("TEST", upsert.getTable().getName()); + assertEquals(2, upsert.getColumns().size()); + assertEquals("ID", ((Column) upsert.getColumns().get(0)).getColumnName()); + assertEquals("COUNTER", ((Column) upsert.getColumns().get(1)).getColumnName()); + assertEquals(2, ((ExpressionList) upsert.getItemsList()).getExpressions().size()); + assertEquals(123, ((LongValue) ((ExpressionList) upsert.getItemsList()).getExpressions(). + get(0)).getValue()); + assertEquals(0, ((LongValue) ((ExpressionList) upsert.getItemsList()).getExpressions(). + get(1)).getValue()); + assertEquals(1, upsert.getDuplicateUpdateColumns().size()); + assertEquals("COUNTER", ((Column) upsert.getDuplicateUpdateColumns().get(0)).getColumnName()); + assertEquals(1, upsert.getDuplicateUpdateExpressionList().size()); + assertEquals("COUNTER + 1", upsert.getDuplicateUpdateExpressionList().get(0).toString()); + assertEquals(statement, "" + upsert); + } + + @Test + public void testUpsertSelect() throws JSQLParserException { + String statement="UPSERT INTO test.targetTable (col1, col2) SELECT * FROM test.sourceTable"; + Upsert upsert= (Upsert) parserManager.parse(new StringReader(statement)); + assertEquals("test.targetTable", upsert.getTable().getFullyQualifiedName()); + assertEquals(2, upsert.getColumns().size()); + assertEquals("col1", ((Column) upsert.getColumns().get(0)).getColumnName()); + assertEquals("col2", ((Column) upsert.getColumns().get(1)).getColumnName()); + assertNull(upsert.getItemsList()); + assertNotNull(upsert.getSelect()); + assertEquals("test.sourceTable", + ((Table) ((PlainSelect) upsert.getSelect().getSelectBody()).getFromItem()).getFullyQualifiedName()); + assertEquals(statement, "" + upsert); + } + + @Test + public void testUpsertN() throws JSQLParserException { + String statement="UPSERT INTO TEST VALUES ('foo', 'bar', 3)"; + Upsert upsert= (Upsert) parserManager.parse(new StringReader(statement)); + assertEquals("TEST", upsert.getTable().getName()); + assertEquals(3, ((ExpressionList) upsert.getItemsList()).getExpressions().size()); + assertEquals("foo", + ((StringValue) ((ExpressionList) upsert.getItemsList()).getExpressions().get(0)). + getValue()); + assertEquals("bar", + ((StringValue) ((ExpressionList) upsert.getItemsList()).getExpressions().get(1)). + getValue()); + assertEquals(3, ((LongValue) ((ExpressionList) upsert.getItemsList()).getExpressions(). + get(2)).getValue()); + assertEquals(statement, "" + upsert); + } + +} From 82b7711503e9108a6e383a1531d5c6994bd87e11 Mon Sep 17 00:00:00 2001 From: messfish Date: Thu, 8 Jun 2017 21:44:12 -0400 Subject: [PATCH 05/20] Add files via upload --- .../net/sf/jsqlparser/util/deparser/StatementDeParser.java | 4 ++-- .../java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java index a8896103b..9b4379eff 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java @@ -208,9 +208,9 @@ public void visit(Commit commit) { @Override public void visit(Upsert upsert) { - SelectDeParser selectDeParser = new SelectDeParser(); selectDeParser.setBuffer(buffer); - ExpressionDeParser expressionDeParser = new ExpressionDeParser(selectDeParser, buffer); + expressionDeParser.setSelectVisitor(selectDeParser); + expressionDeParser.setBuffer(buffer); selectDeParser.setExpressionVisitor(expressionDeParser); UpsertDeParser upsertDeParser = new UpsertDeParser(expressionDeParser, selectDeParser, buffer); upsertDeParser.deParse(upsert); 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 46fb0cdba..809064849 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java @@ -44,7 +44,7 @@ public class UpsertDeParser implements ItemsListVisitor { private StringBuilder buffer; private ExpressionVisitor expressionVisitor; private SelectVisitor selectVisitor; - + /** * Constructor: this constructor is used to assign the values coming from the * arguments to their global values. From 6daa831ad03a6c615afd59e90030534f95f9f8de Mon Sep 17 00:00:00 2001 From: messfish Date: Thu, 8 Jun 2017 21:45:02 -0400 Subject: [PATCH 06/20] Add test for de parser --- .../util/deparser/StatementDeParserTest.java | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) 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 0d176e009..b5c90bfeb 100644 --- a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java +++ b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java @@ -36,6 +36,7 @@ import net.sf.jsqlparser.statement.select.SelectBody; import net.sf.jsqlparser.statement.select.WithItem; import net.sf.jsqlparser.statement.update.Update; +import net.sf.jsqlparser.statement.upsert.Upsert; @RunWith(MockitoJUnitRunner.class) public class StatementDeParserTest { @@ -116,14 +117,14 @@ public void shouldUseProvidedDeparsersWhenDeParsingInsert() throws JSQLParserExc withItem2.setSelectBody(withItem2SelectBody); statementDeParser.visit(insert); - + then(withItem1).should().accept(selectDeParser); then(withItem2).should().accept(selectDeParser); then(selectBody).should().accept(selectDeParser); then(duplicateUpdateExpression1).should().accept(expressionDeParser); then(duplicateUpdateExpression1).should().accept(expressionDeParser); } - + @Test @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") public void shouldUseProvidedDeParsersWhenDeParsingReplaceWithoutItemsList() { @@ -311,4 +312,50 @@ public boolean matchesSafely(ReplaceDeParser item) { } }; } + + @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") + public void shouldUseProvidedDeparsersWhenDeParsingUpsert() throws JSQLParserException { + Upsert upsert = new Upsert(); + Table table = new Table(); + List duplicateUpdateColumns = new ArrayList(); + List duplicateUpdateExpressionList = new ArrayList(); + Column duplicateUpdateColumn1 = new Column(); + Column duplicateUpdateColumn2 = new Column(); + Expression duplicateUpdateExpression1 = mock(Expression.class); + Expression duplicateUpdateExpression2 = mock(Expression.class); + Select select = new Select(); + List withItemsList = new ArrayList(); + WithItem withItem1 = spy(new WithItem()); + WithItem withItem2 = spy(new WithItem()); + SelectBody withItem1SelectBody = mock(SelectBody.class); + SelectBody withItem2SelectBody = mock(SelectBody.class); + SelectBody selectBody = mock(SelectBody.class); + + upsert.setSelect(select); + upsert.setTable(table); + upsert.setUseDuplicate(true); + upsert.setDuplicateUpdateColumns(duplicateUpdateColumns); + upsert.setDuplicateUpdateExpressionList(duplicateUpdateExpressionList); + duplicateUpdateColumns.add(duplicateUpdateColumn1); + duplicateUpdateColumns.add(duplicateUpdateColumn2); + duplicateUpdateExpressionList.add(duplicateUpdateExpression1); + duplicateUpdateExpressionList.add(duplicateUpdateExpression2); + upsert.setDuplicateUpdateExpressionList(duplicateUpdateExpressionList); + select.setWithItemsList(withItemsList); + select.setSelectBody(selectBody); + withItemsList.add(withItem1); + withItemsList.add(withItem2); + withItem1.setSelectBody(withItem1SelectBody); + withItem2.setSelectBody(withItem2SelectBody); + + statementDeParser.visit(upsert); + + then(withItem1).should().accept(selectDeParser); + then(withItem2).should().accept(selectDeParser); + then(selectBody).should().accept(selectDeParser); + then(duplicateUpdateExpression1).should().accept(expressionDeParser); + then(duplicateUpdateExpression1).should().accept(expressionDeParser); + } + } From 8b4f7b6bab67780f68426d106daca558356f2913 Mon Sep 17 00:00:00 2001 From: messfish Date: Sat, 10 Jun 2017 09:55:14 -0400 Subject: [PATCH 07/20] Add files via upload --- .../util/TablesNamesFinderTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java b/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java index 52bc301af..8219860ef 100644 --- a/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java +++ b/src/test/java/net/sf/jsqlparser/util/TablesNamesFinderTest.java @@ -21,6 +21,7 @@ import net.sf.jsqlparser.statement.replace.Replace; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.update.Update; +import net.sf.jsqlparser.statement.upsert.Upsert; import net.sf.jsqlparser.test.TestException; import net.sf.jsqlparser.test.simpleparsing.CCJSqlParserManagerTest; import static org.junit.Assert.*; @@ -414,4 +415,30 @@ public void testGetTableListForMergeUsingQuery() throws Exception { assertEquals("employees", (String) tableList.get(0)); assertEquals("hr_records", (String) tableList.get(1)); } + + @Test + public void testUpsertValues() throws Exception { + String sql = "UPSERT INTO MY_TABLE1 (a) VALUES (5)"; + net.sf.jsqlparser.statement.Statement statement = pm.parse(new StringReader(sql)); + + Upsert insertStatement = (Upsert) statement; + TablesNamesFinder tablesNamesFinder = new TablesNamesFinder(); + List tableList = tablesNamesFinder.getTableList(insertStatement); + assertEquals(1, tableList.size()); + assertTrue(tableList.contains("MY_TABLE1")); + } + + @Test + public void testUpsertSelect() throws Exception { + String sql = "UPSERT INTO mytable (mycolumn) SELECT mycolumn FROM mytable2"; + net.sf.jsqlparser.statement.Statement statement = pm.parse(new StringReader(sql)); + + Upsert insertStatement = (Upsert) statement; + TablesNamesFinder tablesNamesFinder = new TablesNamesFinder(); + List tableList = tablesNamesFinder.getTableList(insertStatement); + assertEquals(2, tableList.size()); + assertTrue(tableList.contains("mytable")); + assertTrue(tableList.contains("mytable2")); + } + } From abc610ea0e76d5e65532cfafdd932eb3efb45b08 Mon Sep 17 00:00:00 2001 From: messfish Date: Sat, 10 Jun 2017 22:17:32 -0400 Subject: [PATCH 08/20] Add files via upload --- .../net/sf/jsqlparser/test/upsert/UpsertTest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java b/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java index e01fcfe18..c5e15a217 100644 --- a/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java +++ b/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java @@ -25,6 +25,7 @@ public void testUpsert() throws JSQLParserException { String statement ="UPSERT INTO TEST (NAME, ID) VALUES ('foo', 123)"; Upsert upsert = (Upsert) parserManager.parse(new StringReader(statement)); assertEquals("TEST", upsert.getTable().getName()); + assertTrue(upsert.isUseValues()); assertEquals(2, upsert.getColumns().size()); assertEquals("NAME", ((Column) upsert.getColumns().get(0)).getColumnName()); assertEquals("ID", ((Column) upsert.getColumns().get(1)).getColumnName()); @@ -34,6 +35,8 @@ public void testUpsert() throws JSQLParserException { getValue()); assertEquals(123, ((LongValue) ((ExpressionList) upsert.getItemsList()).getExpressions(). get(1)).getValue()); + assertFalse(upsert.isUseSelectBrackets()); + assertFalse(upsert.isUseDuplicate()); assertEquals(statement, "" + upsert); } @@ -43,6 +46,7 @@ public void testUpsertDuplicate() throws JSQLParserException { Upsert upsert= (Upsert) parserManager.parse(new StringReader(statement)); assertEquals("TEST", upsert.getTable().getName()); assertEquals(2, upsert.getColumns().size()); + assertTrue(upsert.isUseValues()); assertEquals("ID", ((Column) upsert.getColumns().get(0)).getColumnName()); assertEquals("COUNTER", ((Column) upsert.getColumns().get(1)).getColumnName()); assertEquals(2, ((ExpressionList) upsert.getItemsList()).getExpressions().size()); @@ -54,6 +58,8 @@ public void testUpsertDuplicate() throws JSQLParserException { assertEquals("COUNTER", ((Column) upsert.getDuplicateUpdateColumns().get(0)).getColumnName()); assertEquals(1, upsert.getDuplicateUpdateExpressionList().size()); assertEquals("COUNTER + 1", upsert.getDuplicateUpdateExpressionList().get(0).toString()); + assertFalse(upsert.isUseSelectBrackets()); + assertTrue(upsert.isUseDuplicate()); assertEquals(statement, "" + upsert); } @@ -63,12 +69,14 @@ public void testUpsertSelect() throws JSQLParserException { Upsert upsert= (Upsert) parserManager.parse(new StringReader(statement)); assertEquals("test.targetTable", upsert.getTable().getFullyQualifiedName()); assertEquals(2, upsert.getColumns().size()); + assertFalse(upsert.isUseValues()); assertEquals("col1", ((Column) upsert.getColumns().get(0)).getColumnName()); assertEquals("col2", ((Column) upsert.getColumns().get(1)).getColumnName()); assertNull(upsert.getItemsList()); assertNotNull(upsert.getSelect()); assertEquals("test.sourceTable", ((Table) ((PlainSelect) upsert.getSelect().getSelectBody()).getFromItem()).getFullyQualifiedName()); + assertFalse(upsert.isUseDuplicate()); assertEquals(statement, "" + upsert); } @@ -78,6 +86,7 @@ public void testUpsertN() throws JSQLParserException { Upsert upsert= (Upsert) parserManager.parse(new StringReader(statement)); assertEquals("TEST", upsert.getTable().getName()); assertEquals(3, ((ExpressionList) upsert.getItemsList()).getExpressions().size()); + assertTrue(upsert.isUseValues()); assertEquals("foo", ((StringValue) ((ExpressionList) upsert.getItemsList()).getExpressions().get(0)). getValue()); @@ -86,6 +95,8 @@ public void testUpsertN() throws JSQLParserException { getValue()); assertEquals(3, ((LongValue) ((ExpressionList) upsert.getItemsList()).getExpressions(). get(2)).getValue()); + assertFalse(upsert.isUseSelectBrackets()); + assertFalse(upsert.isUseDuplicate()); assertEquals(statement, "" + upsert); } From cf31a3159f4375e0da6ab12afc382264248f69e8 Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 11 Jun 2017 10:20:55 -0400 Subject: [PATCH 09/20] Add files via upload --- .../net/sf/jsqlparser/util/deparser/StatementDeParserTest.java | 2 ++ 1 file changed, 2 insertions(+) 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 b5c90bfeb..118a4232b 100644 --- a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java +++ b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java @@ -322,6 +322,7 @@ public void shouldUseProvidedDeparsersWhenDeParsingUpsert() throws JSQLParserExc List duplicateUpdateExpressionList = new ArrayList(); Column duplicateUpdateColumn1 = new Column(); Column duplicateUpdateColumn2 = new Column(); + ItemsList item = mock(ItemsList.class); Expression duplicateUpdateExpression1 = mock(Expression.class); Expression duplicateUpdateExpression2 = mock(Expression.class); Select select = new Select(); @@ -335,6 +336,7 @@ public void shouldUseProvidedDeparsersWhenDeParsingUpsert() throws JSQLParserExc upsert.setSelect(select); upsert.setTable(table); upsert.setUseDuplicate(true); + upsert.setItemsList(item); upsert.setDuplicateUpdateColumns(duplicateUpdateColumns); upsert.setDuplicateUpdateExpressionList(duplicateUpdateExpressionList); duplicateUpdateColumns.add(duplicateUpdateColumn1); From 8f6f47f49f1104ae30fb1c73d1da9e618d821bfc Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 11 Jun 2017 10:57:51 -0400 Subject: [PATCH 10/20] Add files via upload --- .../util/deparser/StatementDeParserTest.java | 54 +++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) 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 118a4232b..ee86fc28e 100644 --- a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java +++ b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java @@ -24,6 +24,7 @@ import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.ItemsList; +import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.SetStatement; @@ -315,14 +316,14 @@ public boolean matchesSafely(ReplaceDeParser item) { @Test @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") - public void shouldUseProvidedDeparsersWhenDeParsingUpsert() throws JSQLParserException { + public void shouldUseProvidedDeparsersWhenDeParsingUpsertWithExpressionList() throws JSQLParserException { Upsert upsert = new Upsert(); Table table = new Table(); List duplicateUpdateColumns = new ArrayList(); List duplicateUpdateExpressionList = new ArrayList(); Column duplicateUpdateColumn1 = new Column(); Column duplicateUpdateColumn2 = new Column(); - ItemsList item = mock(ItemsList.class); + ExpressionList item1 = mock(ExpressionList.class); Expression duplicateUpdateExpression1 = mock(Expression.class); Expression duplicateUpdateExpression2 = mock(Expression.class); Select select = new Select(); @@ -336,7 +337,54 @@ public void shouldUseProvidedDeparsersWhenDeParsingUpsert() throws JSQLParserExc upsert.setSelect(select); upsert.setTable(table); upsert.setUseDuplicate(true); - upsert.setItemsList(item); + upsert.setItemsList(item1); + upsert.setDuplicateUpdateColumns(duplicateUpdateColumns); + upsert.setDuplicateUpdateExpressionList(duplicateUpdateExpressionList); + duplicateUpdateColumns.add(duplicateUpdateColumn1); + duplicateUpdateColumns.add(duplicateUpdateColumn2); + duplicateUpdateExpressionList.add(duplicateUpdateExpression1); + duplicateUpdateExpressionList.add(duplicateUpdateExpression2); + upsert.setDuplicateUpdateExpressionList(duplicateUpdateExpressionList); + select.setWithItemsList(withItemsList); + select.setSelectBody(selectBody); + withItemsList.add(withItem1); + withItemsList.add(withItem2); + withItem1.setSelectBody(withItem1SelectBody); + withItem2.setSelectBody(withItem2SelectBody); + + statementDeParser.visit(upsert); + + then(withItem1).should().accept(selectDeParser); + then(withItem2).should().accept(selectDeParser); + then(selectBody).should().accept(selectDeParser); + then(duplicateUpdateExpression1).should().accept(expressionDeParser); + then(duplicateUpdateExpression1).should().accept(expressionDeParser); + } + + @Test + @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") + public void shouldUseProvidedDeparsersWhenDeParsingUpsertWithMultiExpressionList() throws JSQLParserException { + Upsert upsert = new Upsert(); + Table table = new Table(); + List duplicateUpdateColumns = new ArrayList(); + List duplicateUpdateExpressionList = new ArrayList(); + Column duplicateUpdateColumn1 = new Column(); + Column duplicateUpdateColumn2 = new Column(); + MultiExpressionList item1 = mock(MultiExpressionList.class); + Expression duplicateUpdateExpression1 = mock(Expression.class); + Expression duplicateUpdateExpression2 = mock(Expression.class); + Select select = new Select(); + List withItemsList = new ArrayList(); + WithItem withItem1 = spy(new WithItem()); + WithItem withItem2 = spy(new WithItem()); + SelectBody withItem1SelectBody = mock(SelectBody.class); + SelectBody withItem2SelectBody = mock(SelectBody.class); + SelectBody selectBody = mock(SelectBody.class); + + upsert.setSelect(select); + upsert.setTable(table); + upsert.setUseDuplicate(true); + upsert.setItemsList(item1); upsert.setDuplicateUpdateColumns(duplicateUpdateColumns); upsert.setDuplicateUpdateExpressionList(duplicateUpdateExpressionList); duplicateUpdateColumns.add(duplicateUpdateColumn1); From 1298bb6450b198b7bfa729e957e1329886dbd430 Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 11 Jun 2017 10:58:49 -0400 Subject: [PATCH 11/20] Add files via upload --- .../jsqlparser/util/deparser/StatementDeParser.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java index 9b4379eff..1f3a4484d 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java @@ -23,6 +23,9 @@ import java.util.Iterator; +import net.sf.jsqlparser.expression.operators.relational.ExpressionList; +import net.sf.jsqlparser.expression.operators.relational.ItemsList; +import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList; import net.sf.jsqlparser.statement.Commit; import net.sf.jsqlparser.statement.SetStatement; import net.sf.jsqlparser.statement.StatementVisitor; @@ -39,6 +42,7 @@ import net.sf.jsqlparser.statement.merge.Merge; import net.sf.jsqlparser.statement.replace.Replace; import net.sf.jsqlparser.statement.select.Select; +import net.sf.jsqlparser.statement.select.SubSelect; import net.sf.jsqlparser.statement.select.WithItem; import net.sf.jsqlparser.statement.truncate.Truncate; import net.sf.jsqlparser.statement.update.Update; @@ -214,5 +218,13 @@ public void visit(Upsert upsert) { selectDeParser.setExpressionVisitor(expressionDeParser); UpsertDeParser upsertDeParser = new UpsertDeParser(expressionDeParser, selectDeParser, buffer); upsertDeParser.deParse(upsert); + ItemsList item = upsert.getItemsList(); + if (item instanceof ExpressionList) { + upsertDeParser.visit((ExpressionList) item); + } else if (item instanceof MultiExpressionList) { + upsertDeParser.visit((MultiExpressionList) item); + } else if (item instanceof SubSelect) { + upsertDeParser.visit((SubSelect) item); + } } } From 911efa6681c26849e0ea707282d3b84b61c0ffbb Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 11 Jun 2017 13:07:29 -0400 Subject: [PATCH 12/20] Add files via upload --- .../jsqlparser/util/deparser/StatementDeParser.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java index 1f3a4484d..9b4379eff 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java @@ -23,9 +23,6 @@ import java.util.Iterator; -import net.sf.jsqlparser.expression.operators.relational.ExpressionList; -import net.sf.jsqlparser.expression.operators.relational.ItemsList; -import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList; import net.sf.jsqlparser.statement.Commit; import net.sf.jsqlparser.statement.SetStatement; import net.sf.jsqlparser.statement.StatementVisitor; @@ -42,7 +39,6 @@ import net.sf.jsqlparser.statement.merge.Merge; import net.sf.jsqlparser.statement.replace.Replace; import net.sf.jsqlparser.statement.select.Select; -import net.sf.jsqlparser.statement.select.SubSelect; import net.sf.jsqlparser.statement.select.WithItem; import net.sf.jsqlparser.statement.truncate.Truncate; import net.sf.jsqlparser.statement.update.Update; @@ -218,13 +214,5 @@ public void visit(Upsert upsert) { selectDeParser.setExpressionVisitor(expressionDeParser); UpsertDeParser upsertDeParser = new UpsertDeParser(expressionDeParser, selectDeParser, buffer); upsertDeParser.deParse(upsert); - ItemsList item = upsert.getItemsList(); - if (item instanceof ExpressionList) { - upsertDeParser.visit((ExpressionList) item); - } else if (item instanceof MultiExpressionList) { - upsertDeParser.visit((MultiExpressionList) item); - } else if (item instanceof SubSelect) { - upsertDeParser.visit((SubSelect) item); - } } } From 0bc22741c80e6a853fff754d3bfa0b608a09d8e1 Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 11 Jun 2017 13:08:22 -0400 Subject: [PATCH 13/20] Add files via upload --- .../util/deparser/StatementDeParserTest.java | 50 ------------------- 1 file changed, 50 deletions(-) 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 ee86fc28e..7dcd59aa3 100644 --- a/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java +++ b/src/test/java/net/sf/jsqlparser/util/deparser/StatementDeParserTest.java @@ -24,7 +24,6 @@ import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.operators.relational.ExpressionList; import net.sf.jsqlparser.expression.operators.relational.ItemsList; -import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList; import net.sf.jsqlparser.schema.Column; import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.SetStatement; @@ -323,7 +322,6 @@ public void shouldUseProvidedDeparsersWhenDeParsingUpsertWithExpressionList() th List duplicateUpdateExpressionList = new ArrayList(); Column duplicateUpdateColumn1 = new Column(); Column duplicateUpdateColumn2 = new Column(); - ExpressionList item1 = mock(ExpressionList.class); Expression duplicateUpdateExpression1 = mock(Expression.class); Expression duplicateUpdateExpression2 = mock(Expression.class); Select select = new Select(); @@ -337,54 +335,6 @@ public void shouldUseProvidedDeparsersWhenDeParsingUpsertWithExpressionList() th upsert.setSelect(select); upsert.setTable(table); upsert.setUseDuplicate(true); - upsert.setItemsList(item1); - upsert.setDuplicateUpdateColumns(duplicateUpdateColumns); - upsert.setDuplicateUpdateExpressionList(duplicateUpdateExpressionList); - duplicateUpdateColumns.add(duplicateUpdateColumn1); - duplicateUpdateColumns.add(duplicateUpdateColumn2); - duplicateUpdateExpressionList.add(duplicateUpdateExpression1); - duplicateUpdateExpressionList.add(duplicateUpdateExpression2); - upsert.setDuplicateUpdateExpressionList(duplicateUpdateExpressionList); - select.setWithItemsList(withItemsList); - select.setSelectBody(selectBody); - withItemsList.add(withItem1); - withItemsList.add(withItem2); - withItem1.setSelectBody(withItem1SelectBody); - withItem2.setSelectBody(withItem2SelectBody); - - statementDeParser.visit(upsert); - - then(withItem1).should().accept(selectDeParser); - then(withItem2).should().accept(selectDeParser); - then(selectBody).should().accept(selectDeParser); - then(duplicateUpdateExpression1).should().accept(expressionDeParser); - then(duplicateUpdateExpression1).should().accept(expressionDeParser); - } - - @Test - @SuppressWarnings("PMD.JUnitTestsShouldIncludeAssert") - public void shouldUseProvidedDeparsersWhenDeParsingUpsertWithMultiExpressionList() throws JSQLParserException { - Upsert upsert = new Upsert(); - Table table = new Table(); - List duplicateUpdateColumns = new ArrayList(); - List duplicateUpdateExpressionList = new ArrayList(); - Column duplicateUpdateColumn1 = new Column(); - Column duplicateUpdateColumn2 = new Column(); - MultiExpressionList item1 = mock(MultiExpressionList.class); - Expression duplicateUpdateExpression1 = mock(Expression.class); - Expression duplicateUpdateExpression2 = mock(Expression.class); - Select select = new Select(); - List withItemsList = new ArrayList(); - WithItem withItem1 = spy(new WithItem()); - WithItem withItem2 = spy(new WithItem()); - SelectBody withItem1SelectBody = mock(SelectBody.class); - SelectBody withItem2SelectBody = mock(SelectBody.class); - SelectBody selectBody = mock(SelectBody.class); - - upsert.setSelect(select); - upsert.setTable(table); - upsert.setUseDuplicate(true); - upsert.setItemsList(item1); upsert.setDuplicateUpdateColumns(duplicateUpdateColumns); upsert.setDuplicateUpdateExpressionList(duplicateUpdateExpressionList); duplicateUpdateColumns.add(duplicateUpdateColumn1); From 244afa680d4c567de031344a24e88cfd7a8cc6ef Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 11 Jun 2017 13:09:03 -0400 Subject: [PATCH 14/20] Add files via upload --- .../sf/jsqlparser/test/upsert/UpsertTest.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java b/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java index c5e15a217..8788f25d1 100644 --- a/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java +++ b/src/test/java/net/sf/jsqlparser/test/upsert/UpsertTest.java @@ -1,5 +1,6 @@ package net.sf.jsqlparser.test.upsert; +import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; import static org.junit.Assert.*; import java.io.StringReader; @@ -100,4 +101,61 @@ public void testUpsertN() throws JSQLParserException { assertEquals(statement, "" + upsert); } + @Test + public void testUpsertMultiRowValue() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO mytable (col1, col2) VALUES (a, b), (d, e)"); + } + + @Test + public void testUpsertMultiRowValueDifferent() throws JSQLParserException { + try { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO mytable (col1, col2) VALUES (a, b), (d, e, c)"); + } catch (Exception e) { + return; + } + fail("should not work"); + } + + @Test + public void testSimpleUpsert() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO example (num, name, address, tel) VALUES (1, 'name', 'test ', '1234-1234')"); + } + + @Test + public void testUpsertHasSelect() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO mytable (mycolumn) SELECT mycolumn FROM mytable"); + assertSqlCanBeParsedAndDeparsed("UPSERT INTO mytable (mycolumn) (SELECT mycolumn FROM mytable)"); + } + + @Test + public void testUpsertWithSelect() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO mytable (mycolumn) WITH a AS (SELECT mycolumn FROM mytable) SELECT mycolumn FROM a"); + assertSqlCanBeParsedAndDeparsed("UPSERT INTO mytable (mycolumn) (WITH a AS (SELECT mycolumn FROM mytable) SELECT mycolumn FROM a)"); + } + + @Test + public void testUpsertWithKeywords() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO kvPair (value, key) VALUES (?, ?)"); + } + + @Test + public void testHexValues() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO TABLE2 VALUES ('1', \"DSDD\", x'EFBFBDC7AB')"); + } + + @Test + public void testHexValues2() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO TABLE2 VALUES ('1', \"DSDD\", 0xEFBFBDC7AB)"); + } + + @Test + public void testHexValues3() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO TABLE2 VALUES ('1', \"DSDD\", 0xabcde)"); + } + + @Test + public void testDuplicateKey() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("UPSERT INTO Users0 (UserId, Key, Value) VALUES (51311, 'T_211', 18) ON DUPLICATE KEY UPDATE Value = 18"); + } + } From e4bc8ee86a237736f27dbd0a484f6a5f69a5c41f Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 11 Jun 2017 13:25:22 -0400 Subject: [PATCH 15/20] Add files via upload --- .../util/deparser/UpsertDeParser.java | 78 +++++++++++-------- 1 file changed, 45 insertions(+), 33 deletions(-) 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 809064849..6d40d2d4e 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/UpsertDeParser.java @@ -75,15 +75,7 @@ public void deParse(Upsert upsert) { buffer.append(upsert.getTable().getFullyQualifiedName()); if (upsert.getColumns() != null) { - buffer.append(" ("); - for (Iterator iter = upsert.getColumns().iterator(); iter.hasNext();) { - Column column = iter.next(); - buffer.append(column.getColumnName()); - if (iter.hasNext()) { - buffer.append(", "); - } - } - buffer.append(")"); + appendColumns(upsert); } if (upsert.getItemsList() != null) { @@ -91,37 +83,57 @@ public void deParse(Upsert upsert) { } if (upsert.getSelect() != null) { - buffer.append(" "); - if (upsert.isUseSelectBrackets()) { - buffer.append("("); - } - if (upsert.getSelect().getWithItemsList() != null) { - buffer.append("WITH "); - for (WithItem with : upsert.getSelect().getWithItemsList()) { - with.accept(selectVisitor); - } - buffer.append(" "); - } - upsert.getSelect().getSelectBody().accept(selectVisitor); - if (upsert.isUseSelectBrackets()) { - buffer.append(")"); - } + appendSelect(upsert); } if (upsert.isUseDuplicate()) { - buffer.append(" ON DUPLICATE KEY UPDATE "); - for (int i = 0; i < upsert.getDuplicateUpdateColumns().size(); i++) { - Column column = upsert.getDuplicateUpdateColumns().get(i); - buffer.append(column.getFullyQualifiedName()).append(" = "); + appendDuplicate(upsert); + } - Expression expression = upsert.getDuplicateUpdateExpressionList().get(i); - expression.accept(expressionVisitor); - if (i < upsert.getDuplicateUpdateColumns().size() - 1) { - buffer.append(", "); - } + } + + private void appendColumns(Upsert upsert) { + buffer.append(" ("); + for (Iterator iter = upsert.getColumns().iterator(); iter.hasNext();) { + Column column = iter.next(); + buffer.append(column.getColumnName()); + if (iter.hasNext()) { + buffer.append(", "); } } + buffer.append(")"); + } + + private void appendSelect(Upsert upsert) { + buffer.append(" "); + if (upsert.isUseSelectBrackets()) { + buffer.append("("); + } + if (upsert.getSelect().getWithItemsList() != null) { + buffer.append("WITH "); + for (WithItem with : upsert.getSelect().getWithItemsList()) { + with.accept(selectVisitor); + } + buffer.append(" "); + } + upsert.getSelect().getSelectBody().accept(selectVisitor); + if (upsert.isUseSelectBrackets()) { + buffer.append(")"); + } + } + + private void appendDuplicate(Upsert upsert) { + buffer.append(" ON DUPLICATE KEY UPDATE "); + for (int i = 0; i < upsert.getDuplicateUpdateColumns().size(); i++) { + Column column = upsert.getDuplicateUpdateColumns().get(i); + buffer.append(column.getFullyQualifiedName()).append(" = "); + Expression expression = upsert.getDuplicateUpdateExpressionList().get(i); + expression.accept(expressionVisitor); + if (i < upsert.getDuplicateUpdateColumns().size() - 1) { + buffer.append(", "); + } + } } @Override From 1cfd2b260505a771e9a37e00037b142946d666b7 Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 2 Jul 2017 15:34:55 -0400 Subject: [PATCH 16/20] add "set" functions --- .../jsqlparser/statement/insert/Insert.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) 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 31541aaa5..ad312b433 100644 --- a/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java +++ b/src/main/java/net/sf/jsqlparser/statement/insert/Insert.java @@ -54,6 +54,12 @@ public class Insert implements Statement { private boolean returningAllColumns = false; private List returningExpressionList = null; + + /* these lines of codes are used to handle SET syntax in the insert part. + * the SET syntax is based on this: https://dev.mysql.com/doc/refman/5.6/en/insert.html. */ + private boolean useSet = false; + private List setColumns; + private List setExpressionList; @Override public void accept(StatementVisitor statementVisitor) { @@ -173,6 +179,30 @@ public boolean isModifierIgnore() { public void setModifierIgnore(boolean modifierIgnore) { this.modifierIgnore = modifierIgnore; } + + public void setUseSet(boolean useSet) { + this.useSet = useSet; + } + + public boolean isUseSet() { + return useSet; + } + + public void setSetColumns(List setColumns) { + this.setColumns = setColumns; + } + + public List getSetColumns() { + return setColumns; + } + + public void setSetExpressionList(List setExpressionList) { + this.setExpressionList = setExpressionList; + } + + public List getSetExpressionList() { + return setExpressionList; + } @Override public String toString() { @@ -208,6 +238,17 @@ public String toString() { sql.append(")"); } } + + if (useSet) { + sql.append("SET "); + for (int i = 0; i < getSetColumns().size(); i++) { + if (i != 0) { + sql.append(", "); + } + sql.append(setColumns.get(i)).append(" = "); + sql.append(setExpressionList.get(i)); + } + } if (useDuplicate) { sql.append(" ON DUPLICATE KEY UPDATE "); @@ -229,4 +270,5 @@ public String toString() { return sql.toString(); } + } From 57993b09517afefaa3cf7e028a04b4b511148e95 Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 2 Jul 2017 15:35:38 -0400 Subject: [PATCH 17/20] Update "SET" function --- .../jsqlparser/util/deparser/InsertDeParser.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 154209158..f116187d4 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/InsertDeParser.java @@ -115,6 +115,22 @@ public void deParse(Insert insert) { buffer.append(")"); } } + + if (insert.isUseSet()) { + buffer.append(" SET "); + for (int i = 0; i < insert.getSetColumns().size(); i++) { + Column column = insert.getSetColumns().get(i); + column.accept(expressionVisitor); + + buffer.append(" = "); + + Expression expression = insert.getSetExpressionList().get(i); + expression.accept(expressionVisitor); + if (i < insert.getSetColumns().size() - 1) { + buffer.append(", "); + } + } + } if (insert.isUseDuplicate()) { buffer.append(" ON DUPLICATE KEY UPDATE "); From 8d4e416f86f9dce7466c5895ba3966779f3e246e Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 2 Jul 2017 15:37:11 -0400 Subject: [PATCH 18/20] Update "SET" function --- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 5a60c39bd..ea7bc0c58 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -302,7 +302,7 @@ TOKEN : /* Operators */ TOKEN : /* Date/Time with time zones */ { - ()* ("(" ")")? ()* ( | ) ()+ "TIME" ()+ > + ( | ) "TIME" > } TOKEN : /* Numeric Constants */ @@ -507,9 +507,9 @@ Update Update(): ] { - update.setColumns(columns); - update.setExpressions(expList); - update.setTables(tables); + update.setColumns(columns); + update.setExpressions(expList); + update.setTables(tables); update.setFromItem(fromItem); update.setJoins(joins); update.setSelect(select); @@ -583,13 +583,14 @@ Insert Insert(): Insert insert = new Insert(); Table table = null; Column tableColumn = null; - List columns = new ArrayList(); + List columns = new ArrayList(); List primaryExpList = new ArrayList(); ItemsList itemsList = null; Expression exp = null; MultiExpressionList multiExpr = null; List returning = null; Select select = null; + boolean useValues = true; boolean useSelectBrackets = false; boolean useDuplicate = false; List duplicateUpdateColumns = null; @@ -597,6 +598,9 @@ Insert Insert(): Token tk = null; InsertModifierPriority modifierPriority = null; boolean modifierIgnore = false; + boolean useSet = false; + List setColumns = new ArrayList(); + List setExpressionList = new ArrayList(); } { @@ -633,6 +637,26 @@ Insert Insert(): { insert.setUseValues(false); } select = Select() ) + + | + + + ( + { + useSet = true; + insert.setUseValues(false); + } + tableColumn=Column() "=" exp=SimpleExpression() + { + setColumns = new ArrayList(); + setExpressionList = new ArrayList(); + setColumns.add(tableColumn); + setExpressionList.add(exp); + } + ("," tableColumn=Column() "=" exp=SimpleExpression() + { setColumns.add(tableColumn); + setExpressionList.add(exp); } )* + ) ) [ @@ -668,6 +692,9 @@ Insert Insert(): insert.setReturningExpressionList(returning); insert.setModifierPriority(modifierPriority); insert.setModifierIgnore(modifierIgnore); + insert.setUseSet(useSet); + insert.setSetColumns(setColumns); + insert.setSetExpressionList(setExpressionList); return insert; } } @@ -2701,7 +2728,6 @@ Function Function() #Function: retval.setParameters(expressionList); retval.setName(funcName); retval.setKeep(keep); - linkAST(retval,jjtThis); return retval; } } @@ -3428,4 +3454,4 @@ Commit Commit(): { return commit; } -} +} \ No newline at end of file From 82bfea37c8cb6209d6b6008e7f4edd7b5df3e651 Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 2 Jul 2017 15:37:49 -0400 Subject: [PATCH 19/20] Update "SET" function --- .../sf/jsqlparser/test/insert/InsertTest.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/test/java/net/sf/jsqlparser/test/insert/InsertTest.java b/src/test/java/net/sf/jsqlparser/test/insert/InsertTest.java index 4413e380c..60e6252ec 100644 --- a/src/test/java/net/sf/jsqlparser/test/insert/InsertTest.java +++ b/src/test/java/net/sf/jsqlparser/test/insert/InsertTest.java @@ -13,6 +13,7 @@ import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.statement.insert.Insert; import net.sf.jsqlparser.statement.select.PlainSelect; + import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; import static org.junit.Assert.*; @@ -83,6 +84,63 @@ public void testInsertFromSelect() throws JSQLParserException { String statementToString = "INSERT INTO mytable (col1, col2, col3) SELECT * FROM mytable2"; assertEquals(statementToString, "" + insert); } + + @Test + public void testInsertFromSet() throws JSQLParserException { + String statement = "INSERT INTO mytable SET col1 = 12, col2 = name1 * name2"; + Insert insert = (Insert) parserManager.parse(new StringReader(statement)); + assertEquals("mytable", insert.getTable().getName()); + assertEquals(2, insert.getSetColumns().size()); + assertEquals("col1", ((Column) insert.getSetColumns().get(0)).getColumnName()); + assertEquals("col2", ((Column) insert.getSetColumns().get(1)).getColumnName()); + assertEquals(2, insert.getSetExpressionList().size()); + assertEquals("12", insert.getSetExpressionList().get(0).toString()); + assertEquals("name1 * name2", insert.getSetExpressionList().get(1).toString()); + assertEquals(statement, "" + insert); + } + + @Test + public void testInsertValuesWithDuplicateElimination() throws JSQLParserException { + String statement = "INSERT INTO TEST (ID, COUNTER) VALUES (123, 0) " + + "ON DUPLICATE KEY UPDATE COUNTER = COUNTER + 1"; + Insert insert = (Insert) parserManager.parse(new StringReader(statement)); + assertEquals("TEST", insert.getTable().getName()); + assertEquals(2, insert.getColumns().size()); + assertTrue(insert.isUseValues()); + assertEquals("ID", ((Column) insert.getColumns().get(0)).getColumnName()); + assertEquals("COUNTER", ((Column) insert.getColumns().get(1)).getColumnName()); + assertEquals(2, ((ExpressionList) insert.getItemsList()).getExpressions().size()); + assertEquals(123, ((LongValue) ((ExpressionList) insert.getItemsList()).getExpressions(). + get(0)).getValue()); + assertEquals(0, ((LongValue) ((ExpressionList) insert.getItemsList()).getExpressions(). + get(1)).getValue()); + assertEquals(1, insert.getDuplicateUpdateColumns().size()); + assertEquals("COUNTER", ((Column) insert.getDuplicateUpdateColumns().get(0)).getColumnName()); + assertEquals(1, insert.getDuplicateUpdateExpressionList().size()); + assertEquals("COUNTER + 1", insert.getDuplicateUpdateExpressionList().get(0).toString()); + assertFalse(insert.isUseSelectBrackets()); + assertTrue(insert.isUseDuplicate()); + assertEquals(statement, "" + insert); + } + + @Test + public void testInsertFromSetWithDuplicateElimination() throws JSQLParserException { + String statement = "INSERT INTO mytable SET col1 = 122 " + + "ON DUPLICATE KEY UPDATE col2 = col2 + 1, col3 = 'saint'"; + Insert insert = (Insert) parserManager.parse(new StringReader(statement)); + assertEquals("mytable", insert.getTable().getName()); + assertEquals(1, insert.getSetColumns().size()); + assertEquals("col1", ((Column) insert.getSetColumns().get(0)).getColumnName()); + assertEquals(1, insert.getSetExpressionList().size()); + assertEquals("122", insert.getSetExpressionList().get(0).toString()); + assertEquals(2, insert.getDuplicateUpdateColumns().size()); + assertEquals("col2", ((Column) insert.getDuplicateUpdateColumns().get(0)).getColumnName()); + assertEquals("col3", ((Column) insert.getDuplicateUpdateColumns().get(1)).getColumnName()); + assertEquals(2, insert.getDuplicateUpdateExpressionList().size()); + assertEquals("col2 + 1", insert.getDuplicateUpdateExpressionList().get(0).toString()); + assertEquals("'saint'", insert.getDuplicateUpdateExpressionList().get(1).toString()); + assertEquals(statement, "" + insert); + } @Test public void testInsertMultiRowValue() throws JSQLParserException { @@ -191,4 +249,22 @@ public void testKeywordPrecisionIssue363() throws JSQLParserException { public void testWithDeparsingIssue406() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("insert into mytab3 (a,b,c) select a,b,c from mytab where exists(with t as (select * from mytab2) select * from t)", true); } + + @Test + public void testInsertSetInDeparsing() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("INSERT INTO mytable SET col1 = 12, col2 = name1 * name2"); + } + + @Test + public void testInsertValuesWithDuplicateEliminationInDeparsing() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("INSERT INTO TEST (ID, COUNTER) VALUES (123, 0) " + + "ON DUPLICATE KEY UPDATE COUNTER = COUNTER + 1"); + } + + @Test + public void testInsertSetWithDuplicateEliminationInDeparsing() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("INSERT INTO mytable SET col1 = 122 " + + "ON DUPLICATE KEY UPDATE col2 = col2 + 1, col3 = 'saint'"); + } + } From 8de63b6a0e11f78be609f79888c7eb885a5473c8 Mon Sep 17 00:00:00 2001 From: messfish Date: Sun, 2 Jul 2017 15:55:42 -0400 Subject: [PATCH 20/20] Add files via upload --- src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index ea7bc0c58..9180b4fd6 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -302,7 +302,7 @@ TOKEN : /* Operators */ TOKEN : /* Date/Time with time zones */ { - ( | ) "TIME" > + ()* ("(" ")")? ()* ( | ) ()+ "TIME" ()+ > } TOKEN : /* Numeric Constants */ @@ -2728,6 +2728,7 @@ Function Function() #Function: retval.setParameters(expressionList); retval.setName(funcName); retval.setKeep(keep); + linkAST(retval,jjtThis); return retval; } } @@ -3454,4 +3455,5 @@ Commit Commit(): { return commit; } + } \ No newline at end of file