Skip to content

Commit b7fe0b1

Browse files
committed
Merge origin/master
2 parents 6cb459d + fb64e32 commit b7fe0b1

File tree

13 files changed

+729
-22
lines changed

13 files changed

+729
-22
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Also I would like to know about needed examples or documentation stuff.
4747

4848
## Extensions in the latest SNAPSHOT version 1.1
4949

50+
* support for **UPSERT** syntax
5051
* absolute token positions in addition to column/line
5152
* common normal form transformer for expressions (https://en.wikipedia.org/wiki/Conjunctive_normal_form)
5253
* checkstyle integration to force first souce code conventions

src/main/java/net/sf/jsqlparser/expression/Function.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222
package net.sf.jsqlparser.expression;
2323

2424
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
25+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
2526

2627
/**
2728
* A function as MAX,COUNT...
2829
*/
29-
public class Function implements Expression {
30+
public class Function extends ASTNodeAccessImpl implements Expression {
3031

3132
private String name;
3233
private ExpressionList parameters;

src/main/java/net/sf/jsqlparser/parser/ASTNodeAccessImpl.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,6 @@
1919
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
2020
* #L%
2121
*/
22-
/*
23-
* Copyright (C) 2015 JSQLParser.
24-
*
25-
* This library is free software; you can redistribute it and/or
26-
* modify it under the terms of the GNU Lesser General Public
27-
* License as published by the Free Software Foundation; either
28-
* version 2.1 of the License, or (at your option) any later version.
29-
*
30-
* This library is distributed in the hope that it will be useful,
31-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
32-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33-
* Lesser General Public License for more details.
34-
*
35-
* You should have received a copy of the GNU Lesser General Public
36-
* License along with this library; if not, write to the Free Software
37-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
38-
* MA 02110-1301 USA
39-
*/
4022
package net.sf.jsqlparser.parser;
4123

4224
/**

src/main/java/net/sf/jsqlparser/statement/StatementVisitor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import net.sf.jsqlparser.statement.select.Select;
3636
import net.sf.jsqlparser.statement.truncate.Truncate;
3737
import net.sf.jsqlparser.statement.update.Update;
38+
import net.sf.jsqlparser.statement.upsert.Upsert;
3839

3940
public interface StatementVisitor {
4041

@@ -71,4 +72,7 @@ public interface StatementVisitor {
7172
void visit(Merge merge);
7273

7374
void visit(Select select);
75+
76+
void visit(Upsert upsert);
77+
7478
}

src/main/java/net/sf/jsqlparser/statement/StatementVisitorAdapter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import net.sf.jsqlparser.statement.select.Select;
3636
import net.sf.jsqlparser.statement.truncate.Truncate;
3737
import net.sf.jsqlparser.statement.update.Update;
38+
import net.sf.jsqlparser.statement.upsert.Upsert;
3839

3940
public class StatementVisitorAdapter implements StatementVisitor {
4041
@Override
@@ -122,4 +123,9 @@ public void visit(Merge merge) {
122123
@Override
123124
public void visit(AlterView alterView) {
124125
}
126+
127+
@Override
128+
public void visit(Upsert upsert) {
129+
130+
}
125131
}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2017 JSQLParser
6+
* %%
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 2.1 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Lesser Public
18+
* License along with this program. If not, see
19+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
20+
* #L%
21+
*/
22+
package net.sf.jsqlparser.statement.upsert;
23+
24+
import java.util.List;
25+
26+
import net.sf.jsqlparser.expression.Expression;
27+
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
28+
import net.sf.jsqlparser.schema.Column;
29+
import net.sf.jsqlparser.schema.Table;
30+
import net.sf.jsqlparser.statement.Statement;
31+
import net.sf.jsqlparser.statement.StatementVisitor;
32+
import net.sf.jsqlparser.statement.select.PlainSelect;
33+
import net.sf.jsqlparser.statement.select.Select;
34+
35+
/**
36+
* The UPSERT INTO statement. This statement is basically the combination of
37+
* "insert" and "update". That means it will operate inserts if not present
38+
* and updates otherwise the value in the table. Note the values modified
39+
* will be either a list of values or a select statement.
40+
*
41+
*
42+
* Here is the documentation of the grammar of this operation:
43+
* http://phoenix.apache.org/language/#upsert_values
44+
* http://phoenix.apache.org/language/#upsert_select
45+
*
46+
* @author messfish
47+
*
48+
*/
49+
public class Upsert implements Statement {
50+
51+
private Table table;
52+
private List<Column> columns;
53+
private ItemsList itemsList;
54+
private boolean useValues = true;
55+
private Select select;
56+
private boolean useSelectBrackets = true;
57+
private boolean useDuplicate = false;
58+
private List<Column> duplicateUpdateColumns;
59+
private List<Expression> duplicateUpdateExpressionList;
60+
61+
@Override
62+
public void accept(StatementVisitor statementVisitor) {
63+
statementVisitor.visit(this);
64+
}
65+
66+
public void setTable(Table name) {
67+
table = name;
68+
}
69+
70+
public Table getTable() {
71+
return table;
72+
}
73+
74+
public void setColumns(List<Column> list) {
75+
columns = list;
76+
}
77+
78+
public List<Column> getColumns() {
79+
return columns;
80+
}
81+
82+
public void setItemsList(ItemsList list) {
83+
itemsList = list;
84+
}
85+
86+
public ItemsList getItemsList() {
87+
return itemsList;
88+
}
89+
90+
public void setUseValues(boolean useValues) {
91+
this.useValues = useValues;
92+
}
93+
94+
public boolean isUseValues() {
95+
return useValues;
96+
}
97+
98+
public void setSelect(Select select) {
99+
this.select = select;
100+
}
101+
102+
public Select getSelect() {
103+
return select;
104+
}
105+
106+
public void setUseSelectBrackets(boolean useSelectBrackets) {
107+
this.useSelectBrackets = useSelectBrackets;
108+
}
109+
110+
public boolean isUseSelectBrackets() {
111+
return useSelectBrackets;
112+
}
113+
114+
public void setUseDuplicate(boolean useDuplicate) {
115+
this.useDuplicate = useDuplicate;
116+
}
117+
118+
public boolean isUseDuplicate() {
119+
return useDuplicate;
120+
}
121+
122+
public void setDuplicateUpdateColumns(List<Column> duplicateUpdateColumns) {
123+
this.duplicateUpdateColumns = duplicateUpdateColumns;
124+
}
125+
126+
public List<Column> getDuplicateUpdateColumns() {
127+
return duplicateUpdateColumns;
128+
}
129+
130+
public void setDuplicateUpdateExpressionList(List<Expression> duplicateUpdateExpressionList) {
131+
this.duplicateUpdateExpressionList = duplicateUpdateExpressionList;
132+
}
133+
134+
public List<Expression> getDuplicateUpdateExpressionList() {
135+
return duplicateUpdateExpressionList;
136+
}
137+
138+
@Override
139+
public String toString() {
140+
StringBuilder sb = new StringBuilder();
141+
142+
sb.append("UPSERT INTO ");
143+
sb.append(table).append(" ");
144+
if (columns != null) {
145+
sb.append(PlainSelect.getStringList(columns, true, true)).append(" ");
146+
}
147+
if (useValues) {
148+
sb.append("VALUES ");
149+
}
150+
151+
if (itemsList != null) {
152+
sb.append(itemsList);
153+
} else {
154+
if (useSelectBrackets) {
155+
sb.append("(");
156+
}
157+
if (select != null) {
158+
sb.append(select);
159+
}
160+
if (useSelectBrackets) {
161+
sb.append(")");
162+
}
163+
}
164+
165+
if (useDuplicate) {
166+
sb.append(" ON DUPLICATE KEY UPDATE ");
167+
for (int i = 0; i < getDuplicateUpdateColumns().size(); i++) {
168+
if (i != 0) {
169+
sb.append(", ");
170+
}
171+
sb.append(duplicateUpdateColumns.get(i)).append(" = ");
172+
sb.append(duplicateUpdateExpressionList.get(i));
173+
}
174+
}
175+
176+
return sb.toString();
177+
}
178+
179+
}
180+

src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
import net.sf.jsqlparser.statement.select.WithItem;
128128
import net.sf.jsqlparser.statement.truncate.Truncate;
129129
import net.sf.jsqlparser.statement.update.Update;
130+
import net.sf.jsqlparser.statement.upsert.Upsert;
130131

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

722723
}
724+
725+
@Override
726+
public void visit(Upsert upsert) {
727+
tables.add(upsert.getTable().getName());
728+
if (upsert.getItemsList() != null) {
729+
upsert.getItemsList().accept(this);
730+
}
731+
if (upsert.getSelect() != null) {
732+
visit(upsert.getSelect());
733+
}
734+
}
723735
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import net.sf.jsqlparser.statement.select.WithItem;
4343
import net.sf.jsqlparser.statement.truncate.Truncate;
4444
import net.sf.jsqlparser.statement.update.Update;
45+
import net.sf.jsqlparser.statement.upsert.Upsert;
4546

4647
public class StatementDeParser implements StatementVisitor {
4748
private ExpressionDeParser expressionDeParser;
@@ -204,4 +205,14 @@ public void visit(Merge merge) {
204205
public void visit(Commit commit) {
205206
buffer.append(commit.toString());
206207
}
208+
209+
@Override
210+
public void visit(Upsert upsert) {
211+
selectDeParser.setBuffer(buffer);
212+
expressionDeParser.setSelectVisitor(selectDeParser);
213+
expressionDeParser.setBuffer(buffer);
214+
selectDeParser.setExpressionVisitor(expressionDeParser);
215+
UpsertDeParser upsertDeParser = new UpsertDeParser(expressionDeParser, selectDeParser, buffer);
216+
upsertDeParser.deParse(upsert);
217+
}
207218
}

0 commit comments

Comments
 (0)