Skip to content

Commit

Permalink
implemented lateral keyword
Browse files Browse the repository at this point in the history
  • Loading branch information
wumpz committed Feb 27, 2013
1 parent 10e8f7f commit 5bc39d3
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 39 deletions.
12 changes: 12 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,24 @@
<artifactId>jsqlparser</artifactId>
<version>0.8.2-SNAPSHOT</version>
<name>clone of the jsqlparser library</name>
<licenses>
<license>
<name>GNU Library or Lesser General Public License (LGPL) V2.1</name>
<url>http://www.gnu.org/licenses/lgpl-2.1.html</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
<scope>test</scope>
</dependency>
</dependencies>

<distributionManagement>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
/* ================================================================
* JSQLParser : java based sql parser
* ================================================================
*
* Project Info: http://jsqlparser.sourceforge.net
* Project Lead: Leonardo Francalanci (leoonardoo@yahoo.it);
*
* (C) Copyright 2004, by Leonardo Francalanci
*
* This library 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 library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
package net.sf.jsqlparser.statement.select;

import net.sf.jsqlparser.schema.Table;

public interface FromItemVisitor {
public void visit(Table tableName);

public void visit(SubSelect subSelect);

public void visit(SubJoin subjoin);
}
/* ================================================================
* JSQLParser : java based sql parser
* ================================================================
*
* Project Info: http://jsqlparser.sourceforge.net
* Project Lead: Leonardo Francalanci (leoonardoo@yahoo.it);
*
* (C) Copyright 2004, by Leonardo Francalanci
*
* This library 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 library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
package net.sf.jsqlparser.statement.select;

import net.sf.jsqlparser.schema.Table;

public interface FromItemVisitor {
public void visit(Table tableName);

public void visit(SubSelect subSelect);

public void visit(SubJoin subjoin);

public void visit(LateralSubSelect lateralSubSelect);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package net.sf.jsqlparser.statement.select;


/**
* A lateral subselect followed by an alias.
* @author Tobias Warneke
*/
public class LateralSubSelect implements FromItem {
private SubSelect subSelect;
private String alias;

public void setSubSelect(SubSelect subSelect) {
this.subSelect = subSelect;
}

public SubSelect getSubSelect() {
return subSelect;
}

@Override
public void accept(FromItemVisitor fromItemVisitor) {
fromItemVisitor.visit(this);
}

@Override
public String getAlias() {
return alias;
}

@Override
public void setAlias(String alias) {
this.alias = alias;
}

@Override
public String toString() {
return "LATERAL" + subSelect.toString() + ((alias != null) ? " AS " + alias : "");
}
}
6 changes: 6 additions & 0 deletions src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.FromItemVisitor;
import net.sf.jsqlparser.statement.select.Join;
import net.sf.jsqlparser.statement.select.LateralSubSelect;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectVisitor;
Expand Down Expand Up @@ -361,4 +362,9 @@ public void visit(SetOperationList list) {
@Override
public void visit(ExtractExpression eexpr) {
}

@Override
public void visit(LateralSubSelect lateralSubSelect) {
lateralSubSelect.getSubSelect().getSelectBody().accept(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import net.sf.jsqlparser.statement.select.FromItem;
import net.sf.jsqlparser.statement.select.FromItemVisitor;
import net.sf.jsqlparser.statement.select.Join;
import net.sf.jsqlparser.statement.select.LateralSubSelect;
import net.sf.jsqlparser.statement.select.Limit;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.OrderByVisitor;
Expand Down Expand Up @@ -300,4 +301,9 @@ public void visit(SetOperationList list) {
@Override
public void visit(WithItem withItem) {
}

@Override
public void visit(LateralSubSelect lateralSubSelect) {
buffer.append(lateralSubSelect.toString());
}
}
34 changes: 27 additions & 7 deletions src/main/javacc/net/sf/jsqlparser/parser/JSqlParserCC.jj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
options{
IGNORE_CASE=true ;
STATIC=false;
// DEBUG_LOOKAHEAD= true ;
// DEBUG_PARSER=true;
// DEBUG_LOOKAHEAD=true ;
// FORCE_LA_CHECK=true;
// DEBUG_TOKEN_MANAGER=true;
// UNICODE_INPUT=true;
Expand Down Expand Up @@ -129,6 +130,7 @@ import net.sf.jsqlparser.statement.select.SelectBody;
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
import net.sf.jsqlparser.statement.select.SelectItem;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.LateralSubSelect;
import net.sf.jsqlparser.statement.select.Top;
import net.sf.jsqlparser.statement.select.SetOperationList;
import net.sf.jsqlparser.statement.select.SetOperation;
Expand Down Expand Up @@ -231,6 +233,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
| <K_OVER:"OVER">
| <K_PARTITION:"PARTITION">
| <K_EXTRACT:"EXTRACT">
| <K_LATERAL:"LATERAL">
}


Expand Down Expand Up @@ -561,17 +564,18 @@ PlainSelect PlainSelect():
)
]

[ top = Top() { plainSelect.setTop(top); } ]
[top = Top() { plainSelect.setTop(top); } ]


selectItems=SelectItemsList()


// TODO
[IntoClause()]
[<K_FROM>
fromItem=FromItem()
joins=JoinsList()]
[ <K_FROM>
fromItem=FromItem()
joins=JoinsList() ]

[ where=WhereClause() { plainSelect.setWhere(where); }]
[ groupByColumnReferences=GroupByColumnReferences() { plainSelect.setGroupByColumnReferences(groupByColumnReferences); }]
[ having=Having() { plainSelect.setHaving(having); }]
Expand Down Expand Up @@ -769,15 +773,31 @@ FromItem FromItem():
")"
)
|
fromItem=Table()
fromItem=Table()
|
fromItem=LateralSubSelect()
)

[alias=Alias() { fromItem.setAlias(alias); } ]
[alias=Alias() { fromItem.setAlias(alias); } ]
{
return fromItem;
}
}

LateralSubSelect LateralSubSelect():
{
LateralSubSelect lateralSubSelect = new LateralSubSelect();
SubSelect subSelect = null;
}
{
<K_LATERAL>
"(" subSelect=SubSelect() ")"
{
lateralSubSelect.setSubSelect(subSelect);
return lateralSubSelect;
}
}

FromItem SubJoin():
{
FromItem fromItem = null;
Expand Down
18 changes: 18 additions & 0 deletions src/test/java/net/sf/jsqlparser/test/select/SelectTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.sf.jsqlparser.test.select;

import java.io.IOException;
import java.io.StringReader;
import junit.framework.TestCase;
import net.sf.jsqlparser.JSQLParserException;
Expand Down Expand Up @@ -30,6 +31,7 @@
import net.sf.jsqlparser.util.deparser.ExpressionDeParser;
import net.sf.jsqlparser.util.deparser.SelectDeParser;
import net.sf.jsqlparser.util.deparser.StatementDeParser;
import org.apache.commons.io.IOUtils;

public class SelectTest extends TestCase {

Expand Down Expand Up @@ -747,6 +749,22 @@ public void testAdditionalLettersGerman() throws JSQLParserException {
stmt = "SELECT Äcol FROM testtableÄÖÜ";
assertSqlCanBeParsedAndDeparsed(stmt);
}

public void testMultiTableJoin() throws JSQLParserException {
String stmt = "SELECT * FROM taba INNER JOIN tabb ON taba.a = tabb.a, tabc LEFT JOIN tabd ON tabc.c = tabd.c";
assertSqlCanBeParsedAndDeparsed(stmt);
}

public void testLateral1() throws JSQLParserException {
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";
assertSqlCanBeParsedAndDeparsed(stmt);
}

public void testLateralComplex1() throws IOException, JSQLParserException {
String stmt = IOUtils.toString(SelectTest.class.getResourceAsStream("complex-lateral-select-request.txt"));
Select select = (Select) parserManager.parse(new StringReader(stmt));
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());
}

private void assertSqlCanBeParsedAndDeparsed(String statement) throws JSQLParserException {
Statement parsed = parserManager.parse(new StringReader(statement));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
SELECT
O.ORDERID,
O.CUSTNAME,
OL.LINETOTAL,
OC.ORDCHGTOTAL,
OT.TAXTOTAL
FROM
ORDERS O,
LATERAL (
SELECT
SUM(NETAMT) AS LINETOTAL

FROM
ORDERLINES LINES

WHERE
LINES.ORDERID=O.ORDERID
) AS OL,
LATERAL (
SELECT
SUM(CHGAMT) AS ORDCHGTOTAL

FROM
ORDERCHARGES CHARGES

WHERE
LINES.ORDERID=O.ORDERID
) AS OC,
LATERAL (
SELECT
SUM(TAXAMT) AS TAXTOTAL

FROM
ORDERTAXES TAXES

WHERE
TAXES.ORDERID=O.ORDERID
) AS OT

0 comments on commit 5bc39d3

Please sign in to comment.