Skip to content

Commit

Permalink
multi value expression for select included
Browse files Browse the repository at this point in the history
  • Loading branch information
wumpz committed Mar 17, 2013
1 parent 898f369 commit 6b51f26
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,19 @@
package net.sf.jsqlparser.expression.operators.relational;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.statement.select.FromItem;
import net.sf.jsqlparser.statement.select.FromItemVisitor;

/**
* A list of ExpressionList items. e.g. multi values of insert statements. This one allows
* only equally sized ExpressionList.
* @author toben
*/
public class MultiExpressionList implements ItemsList {

List<ExpressionList> exprList;

public MultiExpressionList() {
Expand All @@ -53,6 +56,14 @@ public void addExpressionList(ExpressionList el) {
exprList.add(el);
}

public void addExpressionList(List<Expression> list) {
addExpressionList(new ExpressionList(list));
}

public void addExpressionList(Expression expr) {
addExpressionList(new ExpressionList(Arrays.asList(expr)));
}

@Override
public String toString() {
StringBuilder b = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ public interface FromItemVisitor {
public void visit(SubJoin subjoin);

public void visit(LateralSubSelect lateralSubSelect);

public void visit(ValuesList valuesList);
}
113 changes: 113 additions & 0 deletions src/main/java/net/sf/jsqlparser/statement/select/ValuesList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright (C) 2013 toben.
*
* 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., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package net.sf.jsqlparser.statement.select;

import java.util.Iterator;
import java.util.List;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;

/**
* This is a container for a values item within a select statement. It holds
* some syntactical stuff that differs from values within an insert statement.
*
* @author toben
*/
public class ValuesList implements FromItem {

private String alias;
private MultiExpressionList multiExpressionList;
private boolean noBrackets = false;
private List<String> columnNames;

public ValuesList() {
}

public ValuesList(MultiExpressionList multiExpressionList) {
this.multiExpressionList = multiExpressionList;
}

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

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

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

public MultiExpressionList getMultiExpressionList() {
return multiExpressionList;
}

public void setMultiExpressionList(MultiExpressionList multiExpressionList) {
this.multiExpressionList = multiExpressionList;
}

public boolean isNoBrackets() {
return noBrackets;
}

public void setNoBrackets(boolean noBrackets) {
this.noBrackets = noBrackets;
}

@Override
public String toString() {
StringBuilder b = new StringBuilder();

b.append("(VALUES ");
for (Iterator<ExpressionList> it = getMultiExpressionList().getExprList().iterator(); it.hasNext();) {
b.append(PlainSelect.getStringList(it.next().getExpressions(), true, !isNoBrackets()));
if (it.hasNext()) {
b.append(", ");
}
}
b.append(")");
if (alias != null) {
b.append(" AS ").append(alias);

if (columnNames != null) {
b.append("(");
for (Iterator<String> it = columnNames.iterator(); it.hasNext();) {
b.append(it.next());
if (it.hasNext()) {
b.append(", ");
}
}
b.append(")");
}
}
return b.toString();
}

public List<String> getColumnNames() {
return columnNames;
}

public void setColumnNames(List<String> columnNames) {
this.columnNames = columnNames;
}
}
7 changes: 5 additions & 2 deletions src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import net.sf.jsqlparser.statement.select.SetOperationList;
import net.sf.jsqlparser.statement.select.SubJoin;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.ValuesList;
import net.sf.jsqlparser.statement.select.WithItem;

/**
Expand Down Expand Up @@ -285,7 +286,6 @@ public void visit(TimeValue timeValue) {
*/
@Override
public void visit(CaseExpression caseExpression) {
// TODO Auto-generated method stub
}

/*
Expand All @@ -295,7 +295,6 @@ public void visit(CaseExpression caseExpression) {
*/
@Override
public void visit(WhenClause whenClause) {
// TODO Auto-generated method stub
}

@Override
Expand Down Expand Up @@ -375,4 +374,8 @@ public void visit(MultiExpressionList multiExprList) {
exprList.accept(this);
}
}

@Override
public void visit(ValuesList valuesList) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.AllColumns;
Expand All @@ -25,6 +26,7 @@
import net.sf.jsqlparser.statement.select.SubJoin;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.Top;
import net.sf.jsqlparser.statement.select.ValuesList;
import net.sf.jsqlparser.statement.select.WithItem;

/**
Expand Down Expand Up @@ -306,4 +308,9 @@ public void visit(WithItem withItem) {
public void visit(LateralSubSelect lateralSubSelect) {
buffer.append(lateralSubSelect.toString());
}

@Override
public void visit(ValuesList valuesList) {
buffer.append(valuesList.toString());
}
}
78 changes: 63 additions & 15 deletions src/main/javacc/net/sf/jsqlparser/parser/JSqlParserCC.jj
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ import net.sf.jsqlparser.statement.select.MinusOp;
import net.sf.jsqlparser.statement.select.ExceptOp;
import net.sf.jsqlparser.statement.select.IntersectOp;
import net.sf.jsqlparser.statement.select.WithItem;
import net.sf.jsqlparser.statement.select.ValuesList;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;

Expand Down Expand Up @@ -413,7 +414,7 @@ Insert Insert():
}
primaryExpList = new ArrayList<Expression>();
primaryExpList.add(exp); }
("," exp=SimpleExpression() { primaryExpList.add(exp); } )* ")" { multiExpr.addExpressionList(new ExpressionList(primaryExpList)); } )*
("," exp=SimpleExpression() { primaryExpList.add(exp); } )* ")" { multiExpr.addExpressionList(primaryExpList); } )*

|

Expand Down Expand Up @@ -774,28 +775,75 @@ FromItem FromItem():
}
{
(
(
"("
(
LOOKAHEAD(SubJoin())
fromItem=SubJoin()
|
fromItem=SubSelect()
LOOKAHEAD(ValuesList()) fromItem=ValuesList()
|
(
(
(
"("
(
LOOKAHEAD(SubJoin())
fromItem=SubJoin()
|
fromItem=SubSelect()
)
")"
)
")"
|
fromItem=Table()
|
fromItem=LateralSubSelect()
)

[alias=Alias() { fromItem.setAlias(alias); } ]
)
|
fromItem=Table()
|
fromItem=LateralSubSelect()
)

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

FromItem ValuesList():
{
MultiExpressionList exprList = new MultiExpressionList();
List<Expression> primaryExpList = new ArrayList<Expression>();
ValuesList valuesList = new ValuesList();
Expression exp = null;
List<String> colNames = null;
String colName;
String alias;
}
{
"("
<K_VALUES>
(LOOKAHEAD(3) ("(" exp=SimpleExpression() { primaryExpList.add(exp); }
("," exp=SimpleExpression() { primaryExpList.add(exp); } )* ")" { exprList.addExpressionList(primaryExpList); }

("," "(" exp=SimpleExpression() {
primaryExpList = new ArrayList<Expression>();
primaryExpList.add(exp); }
("," exp=SimpleExpression() { primaryExpList.add(exp); } )* ")" { exprList.addExpressionList(primaryExpList); } )*)
|
( exp=SimpleExpression() { exprList.addExpressionList(exp); valuesList.setNoBrackets(true); }
("," exp=SimpleExpression() { exprList.addExpressionList(exp);} )*
))
")"

[alias=Alias() { valuesList.setAlias(alias); }

[ "("
colName = RelObjectName() { colNames = new ArrayList<String>(); colNames.add(colName); }
( "," colName = RelObjectName() { colNames.add(colName); } )*
")" { valuesList.setColumnNames(colNames); } ]

]

{
valuesList.setMultiExpressionList(exprList);
return valuesList;
}
}

LateralSubSelect LateralSubSelect():
{
LateralSubSelect lateralSubSelect = new LateralSubSelect();
Expand Down
20 changes: 20 additions & 0 deletions src/test/java/net/sf/jsqlparser/test/select/SelectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,26 @@ public void testLateralComplex1() throws IOException, JSQLParserException {
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());
}

public void testValues() throws JSQLParserException {
String stmt = "SELECT * FROM (VALUES (1, 2), (3, 4)) AS test";
assertSqlCanBeParsedAndDeparsed(stmt);
}

public void testValues2() throws JSQLParserException {
String stmt = "SELECT * FROM (VALUES 1, 2, 3, 4) AS test";
assertSqlCanBeParsedAndDeparsed(stmt);
}

public void testValues3() throws JSQLParserException {
String stmt = "SELECT * FROM (VALUES 1, 2, 3, 4) AS test(a)";
assertSqlCanBeParsedAndDeparsed(stmt);
}

public void testValues4() throws JSQLParserException {
String stmt = "SELECT * FROM (VALUES (1, 2), (3, 4)) AS test(a, b)";
assertSqlCanBeParsedAndDeparsed(stmt);
}

private void assertSqlCanBeParsedAndDeparsed(String statement) throws JSQLParserException {
Statement parsed = parserManager.parse(new StringReader(statement));
Expand Down

0 comments on commit 6b51f26

Please sign in to comment.