Skip to content

Commit 8d8c0e4

Browse files
committed
merge impl started
1 parent 6ea74fd commit 8d8c0e4

File tree

8 files changed

+233
-5
lines changed

8 files changed

+233
-5
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import net.sf.jsqlparser.statement.drop.Drop;
3030
import net.sf.jsqlparser.statement.execute.Execute;
3131
import net.sf.jsqlparser.statement.insert.Insert;
32+
import net.sf.jsqlparser.statement.merge.Merge;
3233
import net.sf.jsqlparser.statement.replace.Replace;
3334
import net.sf.jsqlparser.statement.select.Select;
3435
import net.sf.jsqlparser.statement.truncate.Truncate;
@@ -63,4 +64,6 @@ public interface StatementVisitor {
6364
void visit(Execute execute);
6465

6566
void visit(SetStatement set);
67+
68+
void visit(Merge merge);
6669
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import net.sf.jsqlparser.statement.drop.Drop;
3030
import net.sf.jsqlparser.statement.execute.Execute;
3131
import net.sf.jsqlparser.statement.insert.Insert;
32+
import net.sf.jsqlparser.statement.merge.Merge;
3233
import net.sf.jsqlparser.statement.replace.Replace;
3334
import net.sf.jsqlparser.statement.select.Select;
3435
import net.sf.jsqlparser.statement.truncate.Truncate;
@@ -104,4 +105,9 @@ public void visit(Execute execute) {
104105
public void visit(SetStatement set) {
105106

106107
}
108+
109+
@Override
110+
public void visit(Merge merge) {
111+
112+
}
107113
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2015 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.merge;
23+
24+
import net.sf.jsqlparser.expression.Alias;
25+
import net.sf.jsqlparser.expression.Expression;
26+
import net.sf.jsqlparser.schema.Table;
27+
import net.sf.jsqlparser.statement.Statement;
28+
import net.sf.jsqlparser.statement.StatementVisitor;
29+
import net.sf.jsqlparser.statement.select.SubSelect;
30+
31+
/**
32+
* Merge - statement
33+
*
34+
* @author tw
35+
*/
36+
public class Merge implements Statement {
37+
38+
private Table table;
39+
40+
public Table getTable() {
41+
return table;
42+
}
43+
44+
public void setTable(Table name) {
45+
table = name;
46+
}
47+
48+
private Table usingTable;
49+
50+
public Table getUsingTable() {
51+
return usingTable;
52+
}
53+
54+
public void setUsingTable(Table usingTable) {
55+
this.usingTable = usingTable;
56+
}
57+
58+
private SubSelect usingSelect;
59+
60+
public SubSelect getUsingSelect() {
61+
return usingSelect;
62+
}
63+
64+
public void setUsingSelect(SubSelect usingSelect) {
65+
this.usingSelect = usingSelect;
66+
if (this.usingSelect != null) {
67+
this.usingSelect.setUseBrackets(false);
68+
}
69+
}
70+
71+
private Alias usingAlias;
72+
73+
public Alias getUsingAlias() {
74+
return usingAlias;
75+
}
76+
77+
public void setUsingAlias(Alias usingAlias) {
78+
this.usingAlias = usingAlias;
79+
}
80+
81+
private Expression onCondition;
82+
83+
public Expression getOnCondition() {
84+
return onCondition;
85+
}
86+
87+
public void setOnCondition(Expression onCondition) {
88+
this.onCondition = onCondition;
89+
}
90+
91+
@Override
92+
public void accept(StatementVisitor statementVisitor) {
93+
statementVisitor.visit(this);
94+
}
95+
96+
@Override
97+
public String toString() {
98+
StringBuilder b = new StringBuilder();
99+
b.append("MERGE INTO ");
100+
b.append(table);
101+
b.append(" USING (");
102+
if (usingTable != null) {
103+
b.append(usingTable.toString());
104+
} else if (usingSelect != null) {
105+
b.append(usingSelect.toString());
106+
}
107+
b.append(")");
108+
if (usingAlias != null) {
109+
b.append(usingAlias.toString());
110+
}
111+
b.append(" ON (");
112+
b.append(onCondition);
113+
b.append(")");
114+
115+
return b.toString();
116+
}
117+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import net.sf.jsqlparser.statement.create.view.CreateView;
4646
import net.sf.jsqlparser.statement.drop.Drop;
4747
import net.sf.jsqlparser.statement.execute.Execute;
48+
import net.sf.jsqlparser.statement.merge.Merge;
4849
import net.sf.jsqlparser.statement.truncate.Truncate;
4950

5051
/**
@@ -627,4 +628,9 @@ public void visit(RowConstructor rowConstructor) {
627628
public void visit(HexValue hexValue) {
628629

629630
}
631+
632+
@Override
633+
public void visit(Merge merge) {
634+
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
635+
}
630636
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import net.sf.jsqlparser.statement.drop.Drop;
3535
import net.sf.jsqlparser.statement.execute.Execute;
3636
import net.sf.jsqlparser.statement.insert.Insert;
37+
import net.sf.jsqlparser.statement.merge.Merge;
3738
import net.sf.jsqlparser.statement.replace.Replace;
3839
import net.sf.jsqlparser.statement.select.Select;
3940
import net.sf.jsqlparser.statement.select.WithItem;
@@ -175,4 +176,9 @@ public void visit(SetStatement set) {
175176
selectDeParser.setExpressionVisitor(expressionDeParser);
176177
setStatementDeparser.deParse(set);
177178
}
179+
180+
@Override
181+
public void visit(Merge merge) {
182+
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
183+
}
178184
}

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ import net.sf.jsqlparser.statement.execute.*;
7373
import net.sf.jsqlparser.statement.select.*;
7474
import net.sf.jsqlparser.statement.truncate.*;
7575
import net.sf.jsqlparser.statement.update.*;
76+
import net.sf.jsqlparser.statement.merge.*;
7677

7778
import java.util.*;
7879

@@ -222,6 +223,8 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
222223
| <K_GROUP_CONCAT:"GROUP_CONCAT">
223224
| <K_SEPARATOR:"SEPARATOR">
224225
| <K_SKIP: "SKIP">
226+
| <K_MERGE: "MERGE">
227+
| <K_MATCHED: "MATCHED">
225228
}
226229

227230
TOKEN : /* Numeric Constants */
@@ -279,6 +282,8 @@ Statement SingleStatement() :
279282
stm = Replace()
280283
|
281284
stm = Alter()
285+
|
286+
stm = Merge()
282287
|
283288
LOOKAHEAD(3)
284289
stm = CreateIndex()
@@ -516,6 +521,44 @@ Delete Delete():
516521
}
517522
}
518523

524+
Statement Merge() : {
525+
Merge merge = new Merge();
526+
Table table;
527+
SubSelect select;
528+
Alias alias;
529+
Expression condition;
530+
}
531+
{
532+
<K_MERGE> <K_INTO> table=TableWithAlias() { merge.setTable(table); }
533+
<K_USING> "("
534+
( table=Table() { merge.setUsingTable(table); }
535+
| select=SubSelect() { merge.setUsingSelect(select); } )
536+
")" [ alias = Alias() { merge.setUsingAlias(alias); } ] <K_ON>
537+
"(" condition = Condition() { merge.setOnCondition(condition); } ")"
538+
539+
[ LOOKAHEAD(2) MergeUpdateClause() ]
540+
541+
[ MergeInsertClause() ]
542+
543+
{ return merge; }
544+
}
545+
546+
void MergeUpdateClause() : {}
547+
{
548+
<K_WHEN> <K_MATCHED> <K_THEN> <K_UPDATE>
549+
<K_SET>
550+
Column() "=" SimpleExpression() ("," Column() "=" SimpleExpression() )*
551+
[ <K_WHERE> Condition() ]
552+
[ <K_DELETE> <K_WHERE> Condition() ]
553+
}
554+
555+
void MergeInsertClause() : {}
556+
{
557+
<K_WHEN> <K_NOT> <K_MATCHED> <K_THEN>
558+
<K_INSERT> "(" Column() ("," Column() )* ")" <K_VALUES>
559+
"(" SimpleExpression() ("," SimpleExpression() )* ")"
560+
}
561+
519562
// See: http://technet.microsoft.com/en-us/library/ms187879%28v=sql.105%29.aspx
520563

521564
Column Column() #Column :

src/test/java/net/sf/jsqlparser/test/insert/InsertTest.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package net.sf.jsqlparser.test.insert;
22

33
import java.io.StringReader;
4-
import static junit.framework.Assert.assertEquals;
54

65
import net.sf.jsqlparser.JSQLParserException;
76
import net.sf.jsqlparser.expression.DoubleValue;
@@ -15,10 +14,8 @@
1514
import net.sf.jsqlparser.statement.insert.Insert;
1615
import net.sf.jsqlparser.statement.select.PlainSelect;
1716
import static net.sf.jsqlparser.test.TestUtils.*;
18-
import static org.junit.Assert.assertNotNull;
19-
import static org.junit.Assert.assertNull;
20-
import static org.junit.Assert.assertTrue;
21-
import static org.junit.Assert.fail;
17+
import static org.junit.Assert.*;
18+
2219
import org.junit.Test;
2320

2421
public class InsertTest {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (C) 2015 JSQLParser.
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17+
* MA 02110-1301 USA
18+
*/
19+
package net.sf.jsqlparser.test.merge;
20+
21+
import net.sf.jsqlparser.JSQLParserException;
22+
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
23+
import net.sf.jsqlparser.statement.Statement;
24+
import org.junit.Test;
25+
26+
/**
27+
*
28+
* @author toben
29+
*/
30+
public class MergeTest {
31+
32+
@Test
33+
public void testOracleMergeIntoStatement() throws JSQLParserException {
34+
String sql = "MERGE INTO bonuses B\n"
35+
+ "USING (\n"
36+
+ " SELECT employee_id, salary\n"
37+
+ " FROM employee\n"
38+
+ " WHERE dept_no =20) E\n"
39+
+ "ON (B.employee_id = E.employee_id)\n"
40+
+ "WHEN MATCHED THEN\n"
41+
+ " UPDATE SET B.bonus = E.salary * 0.1\n"
42+
+ "WHEN NOT MATCHED THEN\n"
43+
+ " INSERT (B.employee_id, B.bonus)\n"
44+
+ " VALUES (E.employee_id, E.salary * 0.05) ";
45+
46+
Statement statement = CCJSqlParserUtil.parse(sql);
47+
48+
System.out.println(statement.toString());
49+
}
50+
}

0 commit comments

Comments
 (0)