Skip to content

Commit 5bc39d3

Browse files
committed
implemented lateral keyword
1 parent 10e8f7f commit 5bc39d3

File tree

8 files changed

+180
-39
lines changed

8 files changed

+180
-39
lines changed

pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,24 @@
55
<artifactId>jsqlparser</artifactId>
66
<version>0.8.2-SNAPSHOT</version>
77
<name>clone of the jsqlparser library</name>
8+
<licenses>
9+
<license>
10+
<name>GNU Library or Lesser General Public License (LGPL) V2.1</name>
11+
<url>http://www.gnu.org/licenses/lgpl-2.1.html</url>
12+
</license>
13+
</licenses>
814
<dependencies>
915
<dependency>
1016
<groupId>junit</groupId>
1117
<artifactId>junit</artifactId>
1218
<version>4.10</version>
1319
</dependency>
20+
<dependency>
21+
<groupId>commons-io</groupId>
22+
<artifactId>commons-io</artifactId>
23+
<version>2.4</version>
24+
<scope>test</scope>
25+
</dependency>
1426
</dependencies>
1527

1628
<distributionManagement>
Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,34 @@
1-
/* ================================================================
2-
* JSQLParser : java based sql parser
3-
* ================================================================
4-
*
5-
* Project Info: http://jsqlparser.sourceforge.net
6-
* Project Lead: Leonardo Francalanci (leoonardoo@yahoo.it);
7-
*
8-
* (C) Copyright 2004, by Leonardo Francalanci
9-
*
10-
* This library is free software; you can redistribute it and/or modify it under the terms
11-
* of the GNU Lesser General Public License as published by the Free Software Foundation;
12-
* either version 2.1 of the License, or (at your option) any later version.
13-
*
14-
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15-
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16-
* See the GNU Lesser General Public License for more details.
17-
*
18-
* You should have received a copy of the GNU Lesser General Public License along with this
19-
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20-
* Boston, MA 02111-1307, USA.
21-
*/
22-
package net.sf.jsqlparser.statement.select;
23-
24-
import net.sf.jsqlparser.schema.Table;
25-
26-
public interface FromItemVisitor {
27-
public void visit(Table tableName);
28-
29-
public void visit(SubSelect subSelect);
30-
31-
public void visit(SubJoin subjoin);
32-
}
1+
/* ================================================================
2+
* JSQLParser : java based sql parser
3+
* ================================================================
4+
*
5+
* Project Info: http://jsqlparser.sourceforge.net
6+
* Project Lead: Leonardo Francalanci (leoonardoo@yahoo.it);
7+
*
8+
* (C) Copyright 2004, by Leonardo Francalanci
9+
*
10+
* This library is free software; you can redistribute it and/or modify it under the terms
11+
* of the GNU Lesser General Public License as published by the Free Software Foundation;
12+
* either version 2.1 of the License, or (at your option) any later version.
13+
*
14+
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15+
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16+
* See the GNU Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public License along with this
19+
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20+
* Boston, MA 02111-1307, USA.
21+
*/
22+
package net.sf.jsqlparser.statement.select;
23+
24+
import net.sf.jsqlparser.schema.Table;
25+
26+
public interface FromItemVisitor {
27+
public void visit(Table tableName);
28+
29+
public void visit(SubSelect subSelect);
30+
31+
public void visit(SubJoin subjoin);
32+
33+
public void visit(LateralSubSelect lateralSubSelect);
34+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package net.sf.jsqlparser.statement.select;
2+
3+
4+
/**
5+
* A lateral subselect followed by an alias.
6+
* @author Tobias Warneke
7+
*/
8+
public class LateralSubSelect implements FromItem {
9+
private SubSelect subSelect;
10+
private String alias;
11+
12+
public void setSubSelect(SubSelect subSelect) {
13+
this.subSelect = subSelect;
14+
}
15+
16+
public SubSelect getSubSelect() {
17+
return subSelect;
18+
}
19+
20+
@Override
21+
public void accept(FromItemVisitor fromItemVisitor) {
22+
fromItemVisitor.visit(this);
23+
}
24+
25+
@Override
26+
public String getAlias() {
27+
return alias;
28+
}
29+
30+
@Override
31+
public void setAlias(String alias) {
32+
this.alias = alias;
33+
}
34+
35+
@Override
36+
public String toString() {
37+
return "LATERAL" + subSelect.toString() + ((alias != null) ? " AS " + alias : "");
38+
}
39+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import net.sf.jsqlparser.schema.Table;
5454
import net.sf.jsqlparser.statement.select.FromItemVisitor;
5555
import net.sf.jsqlparser.statement.select.Join;
56+
import net.sf.jsqlparser.statement.select.LateralSubSelect;
5657
import net.sf.jsqlparser.statement.select.PlainSelect;
5758
import net.sf.jsqlparser.statement.select.Select;
5859
import net.sf.jsqlparser.statement.select.SelectVisitor;
@@ -361,4 +362,9 @@ public void visit(SetOperationList list) {
361362
@Override
362363
public void visit(ExtractExpression eexpr) {
363364
}
365+
366+
@Override
367+
public void visit(LateralSubSelect lateralSubSelect) {
368+
lateralSubSelect.getSubSelect().getSelectBody().accept(this);
369+
}
364370
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import net.sf.jsqlparser.statement.select.FromItem;
1313
import net.sf.jsqlparser.statement.select.FromItemVisitor;
1414
import net.sf.jsqlparser.statement.select.Join;
15+
import net.sf.jsqlparser.statement.select.LateralSubSelect;
1516
import net.sf.jsqlparser.statement.select.Limit;
1617
import net.sf.jsqlparser.statement.select.OrderByElement;
1718
import net.sf.jsqlparser.statement.select.OrderByVisitor;
@@ -300,4 +301,9 @@ public void visit(SetOperationList list) {
300301
@Override
301302
public void visit(WithItem withItem) {
302303
}
304+
305+
@Override
306+
public void visit(LateralSubSelect lateralSubSelect) {
307+
buffer.append(lateralSubSelect.toString());
308+
}
303309
}

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

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
options{
2424
IGNORE_CASE=true ;
2525
STATIC=false;
26-
// DEBUG_LOOKAHEAD= true ;
26+
// DEBUG_PARSER=true;
27+
// DEBUG_LOOKAHEAD=true ;
2728
// FORCE_LA_CHECK=true;
2829
// DEBUG_TOKEN_MANAGER=true;
2930
// UNICODE_INPUT=true;
@@ -129,6 +130,7 @@ import net.sf.jsqlparser.statement.select.SelectBody;
129130
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
130131
import net.sf.jsqlparser.statement.select.SelectItem;
131132
import net.sf.jsqlparser.statement.select.SubSelect;
133+
import net.sf.jsqlparser.statement.select.LateralSubSelect;
132134
import net.sf.jsqlparser.statement.select.Top;
133135
import net.sf.jsqlparser.statement.select.SetOperationList;
134136
import net.sf.jsqlparser.statement.select.SetOperation;
@@ -231,6 +233,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
231233
| <K_OVER:"OVER">
232234
| <K_PARTITION:"PARTITION">
233235
| <K_EXTRACT:"EXTRACT">
236+
| <K_LATERAL:"LATERAL">
234237
}
235238

236239

@@ -561,17 +564,18 @@ PlainSelect PlainSelect():
561564
)
562565
]
563566

564-
[ top = Top() { plainSelect.setTop(top); } ]
567+
[top = Top() { plainSelect.setTop(top); } ]
565568

566569

567570
selectItems=SelectItemsList()
568571

569572

570573
// TODO
571574
[IntoClause()]
572-
[<K_FROM>
573-
fromItem=FromItem()
574-
joins=JoinsList()]
575+
[ <K_FROM>
576+
fromItem=FromItem()
577+
joins=JoinsList() ]
578+
575579
[ where=WhereClause() { plainSelect.setWhere(where); }]
576580
[ groupByColumnReferences=GroupByColumnReferences() { plainSelect.setGroupByColumnReferences(groupByColumnReferences); }]
577581
[ having=Having() { plainSelect.setHaving(having); }]
@@ -769,15 +773,31 @@ FromItem FromItem():
769773
")"
770774
)
771775
|
772-
fromItem=Table()
776+
fromItem=Table()
777+
|
778+
fromItem=LateralSubSelect()
773779
)
774780

775-
[alias=Alias() { fromItem.setAlias(alias); } ]
781+
[alias=Alias() { fromItem.setAlias(alias); } ]
776782
{
777783
return fromItem;
778784
}
779785
}
780786

787+
LateralSubSelect LateralSubSelect():
788+
{
789+
LateralSubSelect lateralSubSelect = new LateralSubSelect();
790+
SubSelect subSelect = null;
791+
}
792+
{
793+
<K_LATERAL>
794+
"(" subSelect=SubSelect() ")"
795+
{
796+
lateralSubSelect.setSubSelect(subSelect);
797+
return lateralSubSelect;
798+
}
799+
}
800+
781801
FromItem SubJoin():
782802
{
783803
FromItem fromItem = null;

src/test/java/net/sf/jsqlparser/test/select/SelectTest.java

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

3+
import java.io.IOException;
34
import java.io.StringReader;
45
import junit.framework.TestCase;
56
import net.sf.jsqlparser.JSQLParserException;
@@ -30,6 +31,7 @@
3031
import net.sf.jsqlparser.util.deparser.ExpressionDeParser;
3132
import net.sf.jsqlparser.util.deparser.SelectDeParser;
3233
import net.sf.jsqlparser.util.deparser.StatementDeParser;
34+
import org.apache.commons.io.IOUtils;
3335

3436
public class SelectTest extends TestCase {
3537

@@ -747,6 +749,22 @@ public void testAdditionalLettersGerman() throws JSQLParserException {
747749
stmt = "SELECT Äcol FROM testtableÄÖÜ";
748750
assertSqlCanBeParsedAndDeparsed(stmt);
749751
}
752+
753+
public void testMultiTableJoin() throws JSQLParserException {
754+
String stmt = "SELECT * FROM taba INNER JOIN tabb ON taba.a = tabb.a, tabc LEFT JOIN tabd ON tabc.c = tabd.c";
755+
assertSqlCanBeParsedAndDeparsed(stmt);
756+
}
757+
758+
public void testLateral1() throws JSQLParserException {
759+
String stmt = "SELECT O.ORDERID, O.CUSTNAME, OL.LINETOTAL FROM ORDERS AS O, LATERAL(SELECT SUM(NETAMT) AS LINETOTAL FROM ORDERLINES AS LINES WHERE LINES.ORDERID = O.ORDERID) AS OL";
760+
assertSqlCanBeParsedAndDeparsed(stmt);
761+
}
762+
763+
public void testLateralComplex1() throws IOException, JSQLParserException {
764+
String stmt = IOUtils.toString(SelectTest.class.getResourceAsStream("complex-lateral-select-request.txt"));
765+
Select select = (Select) parserManager.parse(new StringReader(stmt));
766+
assertEquals("SELECT O.ORDERID, O.CUSTNAME, OL.LINETOTAL, OC.ORDCHGTOTAL, OT.TAXTOTAL FROM ORDERS AS O, LATERAL(SELECT SUM(NETAMT) AS LINETOTAL FROM ORDERLINES AS LINES WHERE LINES.ORDERID = O.ORDERID) AS OL, LATERAL(SELECT SUM(CHGAMT) AS ORDCHGTOTAL FROM ORDERCHARGES AS CHARGES WHERE LINES.ORDERID = O.ORDERID) AS OC, LATERAL(SELECT SUM(TAXAMT) AS TAXTOTAL FROM ORDERTAXES AS TAXES WHERE TAXES.ORDERID = O.ORDERID) AS OT", select.toString());
767+
}
750768

751769
private void assertSqlCanBeParsedAndDeparsed(String statement) throws JSQLParserException {
752770
Statement parsed = parserManager.parse(new StringReader(statement));
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
SELECT
2+
O.ORDERID,
3+
O.CUSTNAME,
4+
OL.LINETOTAL,
5+
OC.ORDCHGTOTAL,
6+
OT.TAXTOTAL
7+
FROM
8+
ORDERS O,
9+
LATERAL (
10+
SELECT
11+
SUM(NETAMT) AS LINETOTAL
12+
13+
FROM
14+
ORDERLINES LINES
15+
16+
WHERE
17+
LINES.ORDERID=O.ORDERID
18+
) AS OL,
19+
LATERAL (
20+
SELECT
21+
SUM(CHGAMT) AS ORDCHGTOTAL
22+
23+
FROM
24+
ORDERCHARGES CHARGES
25+
26+
WHERE
27+
LINES.ORDERID=O.ORDERID
28+
) AS OC,
29+
LATERAL (
30+
SELECT
31+
SUM(TAXAMT) AS TAXTOTAL
32+
33+
FROM
34+
ORDERTAXES TAXES
35+
36+
WHERE
37+
TAXES.ORDERID=O.ORDERID
38+
) AS OT

0 commit comments

Comments
 (0)