Skip to content

Commit 733ff6d

Browse files
committed
returning implemented, column as identifier allowed
1 parent dfda139 commit 733ff6d

5 files changed

Lines changed: 90 additions & 9 deletions

File tree

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<groupId>junit</groupId>
2424
<artifactId>junit</artifactId>
2525
<version>4.11</version>
26+
<scope>test</scope>
2627
</dependency>
2728
<dependency>
2829
<groupId>commons-io</groupId>

src/main/java/net/sf/jsqlparser/statement/insert/Insert.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import net.sf.jsqlparser.statement.Statement;
3030
import net.sf.jsqlparser.statement.StatementVisitor;
3131
import net.sf.jsqlparser.statement.select.PlainSelect;
32+
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
3233

3334
/**
3435
* The insert statement. Every column name in
@@ -41,6 +42,10 @@ public class Insert implements Statement {
4142
private List<Column> columns;
4243
private ItemsList itemsList;
4344
private boolean useValues = true;
45+
46+
private boolean returningAllColumns = false;
47+
48+
private List<SelectExpressionItem> returningExpressionList = null;
4449

4550
@Override
4651
public void accept(StatementVisitor statementVisitor) {
@@ -89,6 +94,22 @@ public void setUseValues(boolean useValues) {
8994
this.useValues = useValues;
9095
}
9196

97+
public boolean isReturningAllColumns() {
98+
return returningAllColumns;
99+
}
100+
101+
public void setReturningAllColumns(boolean returningAllColumns) {
102+
this.returningAllColumns = returningAllColumns;
103+
}
104+
105+
public List<SelectExpressionItem> getReturningExpressionList() {
106+
return returningExpressionList;
107+
}
108+
109+
public void setReturningExpressionList(List<SelectExpressionItem> returningExpressionList) {
110+
this.returningExpressionList = returningExpressionList;
111+
}
112+
92113
@Override
93114
public String toString() {
94115
String sql = "";
@@ -102,6 +123,12 @@ public String toString() {
102123
} else {
103124
sql += "" + itemsList + "";
104125
}
126+
127+
if (isReturningAllColumns())
128+
sql += " RETURNING *";
129+
else if (getReturningExpressionList()!=null) {
130+
sql+= " RETURNING " + PlainSelect.getStringList(getReturningExpressionList(), true, false);
131+
}
105132

106133
return sql;
107134
}

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
3131
import net.sf.jsqlparser.schema.Column;
3232
import net.sf.jsqlparser.statement.insert.Insert;
33+
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
3334
import net.sf.jsqlparser.statement.select.SelectVisitor;
3435
import net.sf.jsqlparser.statement.select.SubSelect;
3536

@@ -87,7 +88,17 @@ public void deParse(Insert insert) {
8788
}
8889

8990
insert.getItemsList().accept(this);
90-
91+
92+
if (insert.isReturningAllColumns())
93+
buffer.append(" RETURNING *");
94+
else if (insert.getReturningExpressionList()!=null) {
95+
buffer.append(" RETURNING ");
96+
for (Iterator<SelectExpressionItem> iter = insert.getReturningExpressionList().iterator();iter.hasNext();) {
97+
buffer.append(iter.next().toString());
98+
if (iter.hasNext())
99+
buffer.append(", ");
100+
}
101+
}
91102
}
92103

93104
@Override

src/main/javacc/net/sf/jsqlparser/parser/JSqlParserCC.jj

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
194194
| <K_FOLLOWING: "FOLLOWING">
195195
| <K_CURRENT: "CURRENT">
196196
| <K_ROW: "ROW">
197+
| <K_RETURNING: "RETURNING">
197198
}
198199

199200
TOKEN : /* Numeric Constants */
@@ -372,6 +373,17 @@ Replace Replace():
372373
}
373374
}
374375

376+
List<SelectExpressionItem> ListExpressionItem():
377+
{
378+
List<SelectExpressionItem> retval = new ArrayList<SelectExpressionItem>();
379+
SelectExpressionItem item;
380+
}
381+
{
382+
item = SelectExpressionItem() {retval.add(item);}
383+
("," item = SelectExpressionItem() {retval.add(item);} )*
384+
{ return retval; }
385+
}
386+
375387
Insert Insert():
376388
{
377389
Insert insert = new Insert();
@@ -382,6 +394,7 @@ Insert Insert():
382394
ItemsList itemsList = null;
383395
Expression exp = null;
384396
MultiExpressionList multiExpr = null;
397+
List<SelectExpressionItem> returning = null;
385398
}
386399
{
387400
<K_INSERT> [<K_INTO>] table=Table()
@@ -408,14 +421,21 @@ Insert Insert():
408421
{ insert.setUseValues(false); }
409422
itemsList= SubSelect()
410423
)
411-
[ ")" ]
424+
[ ")" ]
412425
)
413426

427+
[ <K_RETURNING> (
428+
"*" { insert.setReturningAllColumns(true); }
429+
| returning=ListExpressionItem()
430+
)
431+
]
432+
414433
{
415434
insert.setItemsList(itemsList);
416435
insert.setTable(table);
417436
if (columns.size() > 0)
418437
insert.setColumns(columns);
438+
insert.setReturningExpressionList(returning);
419439
return insert;
420440
}
421441
}
@@ -459,7 +479,10 @@ String RelObjectName():
459479
{ Token tk = null; }
460480
{
461481
(tk=<S_IDENTIFIER> | tk=<S_QUOTED_IDENTIFIER>
462-
| tk=<K_CAST> | tk=<K_DO> | tk=<K_EXTRACT> | tk=<K_FIRST> | tk=<K_FOLLOWING> | tk=<K_LAST> | tk=<K_MATERIALIZED> | tk=<K_NULLS> | tk=<K_PARTITION> | tk=<K_RANGE> | tk=<K_ROW> | tk=<K_ROWS> | tk=<K_SIBLINGS> | tk=<K_VALUE> | tk=<K_XML>)
482+
| tk=<K_CAST> | tk=<K_DO> | tk=<K_EXTRACT> | tk=<K_FIRST> | tk=<K_FOLLOWING>
483+
| tk=<K_LAST> | tk=<K_MATERIALIZED> | tk=<K_NULLS> | tk=<K_PARTITION> | tk=<K_RANGE>
484+
| tk=<K_ROW> | tk=<K_ROWS> | tk=<K_SIBLINGS> | tk=<K_VALUE> | tk=<K_XML>
485+
| tk=<K_COLUMN> )
463486

464487
{ return tk.image; }
465488
}

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

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import java.io.StringReader;
44
import static junit.framework.Assert.assertEquals;
55

6-
import junit.framework.TestCase;
76
import net.sf.jsqlparser.JSQLParserException;
87
import net.sf.jsqlparser.expression.DoubleValue;
98
import net.sf.jsqlparser.expression.JdbcParameter;
@@ -17,15 +16,15 @@
1716
import net.sf.jsqlparser.statement.select.PlainSelect;
1817
import net.sf.jsqlparser.statement.select.SubSelect;
1918
import static net.sf.jsqlparser.test.TestUtils.*;
19+
import static org.junit.Assert.assertTrue;
20+
import static org.junit.Assert.fail;
21+
import org.junit.Test;
2022

21-
public class InsertTest extends TestCase {
23+
public class InsertTest {
2224

2325
CCJSqlParserManager parserManager = new CCJSqlParserManager();
2426

25-
public InsertTest(String arg0) {
26-
super(arg0);
27-
}
28-
27+
@Test
2928
public void testRegularInsert() throws JSQLParserException {
3029
String statement = "INSERT INTO mytable (col1, col2, col3) VALUES (?, 'sadfsd', 234)";
3130
Insert insert = (Insert) parserManager.parse(new StringReader(statement));
@@ -52,6 +51,7 @@ public void testRegularInsert() throws JSQLParserException {
5251

5352
}
5453

54+
@Test
5555
public void testInsertWithKeywordValue() throws JSQLParserException {
5656
String statement = "INSERT INTO mytable (col1) VALUE ('val1')";
5757
Insert insert = (Insert) parserManager.parse(new StringReader(statement));
@@ -63,6 +63,7 @@ public void testInsertWithKeywordValue() throws JSQLParserException {
6363
assertEquals("INSERT INTO mytable (col1) VALUES ('val1')", insert.toString());
6464
}
6565

66+
@Test
6667
public void testInsertFromSelect() throws JSQLParserException {
6768
String statement = "INSERT INTO mytable (col1, col2, col3) SELECT * FROM mytable2";
6869
Insert insert = (Insert) parserManager.parse(new StringReader(statement));
@@ -80,10 +81,12 @@ public void testInsertFromSelect() throws JSQLParserException {
8081
assertEquals(statementToString, "" + insert);
8182
}
8283

84+
@Test
8385
public void testInsertMultiRowValue() throws JSQLParserException {
8486
assertSqlCanBeParsedAndDeparsed("INSERT INTO mytable (col1, col2) VALUES (a, b), (d, e)");
8587
}
8688

89+
@Test
8790
public void testInsertMultiRowValueDifferent() throws JSQLParserException {
8891
try {
8992
assertSqlCanBeParsedAndDeparsed("INSERT INTO mytable (col1, col2) VALUES (a, b), (d, e, c)");
@@ -94,7 +97,23 @@ public void testInsertMultiRowValueDifferent() throws JSQLParserException {
9497
fail("should not work");
9598
}
9699

100+
@Test
97101
public void testSimpleInsert() throws JSQLParserException {
98102
assertSqlCanBeParsedAndDeparsed("INSERT INTO example (num, name, address, tel) VALUES (1, 'name', 'test ', '1234-1234')");
99103
}
104+
105+
@Test
106+
public void testInsertWithReturning() throws JSQLParserException {
107+
assertSqlCanBeParsedAndDeparsed("INSERT INTO mytable (mycolumn) VALUES ('1') RETURNING id");
108+
}
109+
110+
@Test
111+
public void testInsertWithReturning2() throws JSQLParserException {
112+
assertSqlCanBeParsedAndDeparsed("INSERT INTO mytable (mycolumn) VALUES ('1') RETURNING *");
113+
}
114+
115+
@Test
116+
public void testInsertWithReturning3() throws JSQLParserException {
117+
assertSqlCanBeParsedAndDeparsed("INSERT INTO mytable (mycolumn) VALUES ('1') RETURNING id AS a1, id2 AS a2");
118+
}
100119
}

0 commit comments

Comments
 (0)