Skip to content

Commit b5849b6

Browse files
author
Pap Lőrinc
committed
Modified the TOP expression to accept parentheses also;
1 parent e143abb commit b5849b6

File tree

3 files changed

+55
-18
lines changed

3 files changed

+55
-18
lines changed

src/main/java/net/sf/jsqlparser/statement/select/Top.java

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,57 @@
2222
package net.sf.jsqlparser.statement.select;
2323

2424
/**
25-
* A top clause in the form [TOP row_count]
25+
* A top clause in the form [TOP (row_count) or TOP row_count]
2626
*/
2727
public class Top {
2828

2929
private long rowCount;
3030
private boolean rowCountJdbcParameter = false;
31+
private boolean hasParenthesis = false;
3132

3233
public long getRowCount() {
3334
return rowCount;
3435
}
3536

36-
public void setRowCount(long l) {
37-
rowCount = l;
37+
// TODO instead of a plain number, an expression should be added, which could be a NumberExpression, a GroupedExpression or a JdbcParameter
38+
public void setRowCount(long rowCount) {
39+
this.rowCount = rowCount;
3840
}
3941

4042
public boolean isRowCountJdbcParameter() {
4143
return rowCountJdbcParameter;
4244
}
4345

44-
public void setRowCountJdbcParameter(boolean b) {
45-
rowCountJdbcParameter = b;
46+
public void setRowCountJdbcParameter(boolean rowCountJdbcParameter) {
47+
this.rowCountJdbcParameter = rowCountJdbcParameter;
4648
}
4749

48-
@Override
49-
public String toString() {
50-
return "TOP " + (rowCountJdbcParameter ? "?" : rowCount + "");
51-
}
50+
public boolean hasParenthesis()
51+
{
52+
return hasParenthesis;
53+
}
54+
55+
public void setParenthesis(boolean hasParenthesis)
56+
{
57+
this.hasParenthesis = hasParenthesis;
58+
}
59+
60+
@Override
61+
public String toString() {
62+
String result = "TOP ";
63+
64+
if ( hasParenthesis) {
65+
result += "(";
66+
}
67+
68+
result += rowCountJdbcParameter ? "?"
69+
: rowCount;
70+
71+
if (hasParenthesis)
72+
{
73+
result += ")";
74+
}
75+
76+
return result;
77+
}
5278
}

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,18 +1083,24 @@ Limit Limit():
10831083
}
10841084
}
10851085

1086+
// according to http://technet.microsoft.com/en-us/library/ms189463.aspx
10861087
Top Top():
10871088
{
10881089
Top top = new Top();
10891090
Token token = null;
10901091
}
10911092
{
1093+
// TODO the inside should be extracted, ? should be added as a new JdbcParameter and the parenthesis should wrap them with a GroupedExpression
10921094
<K_TOP>
1093-
(
1094-
token=<S_LONG> { top.setRowCount(Long.parseLong(token.image)); }
1095-
|
1096-
"?" { top.setRowCountJdbcParameter(true);}
1097-
)
1095+
(
1096+
token=<S_LONG> { top.setRowCount(Long.parseLong(token.image)); }
1097+
|
1098+
"?" { top.setRowCountJdbcParameter(true);}
1099+
|
1100+
LOOKAHEAD(2) "(" token=<S_LONG> ")" { top.setRowCount(Long.parseLong(token.image)); top.setParenthesis(true);}
1101+
|
1102+
LOOKAHEAD(2) "(" "?" ")" { top.setRowCountJdbcParameter(true); top.setParenthesis(true);}
1103+
)
10981104
{
10991105
return top;
11001106
}
@@ -1116,7 +1122,7 @@ Expression Expression():
11161122
{ return retval; }
11171123
}
11181124

1119-
Expression OrExpression() :
1125+
Expression OrExpression():
11201126
{
11211127
Expression left, right, result;
11221128
}

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313

1414
import java.io.*;
1515
import java.util.*;
16-
import java.util.logging.Level;
17-
import java.util.logging.Logger;
1816

1917
import static net.sf.jsqlparser.test.TestUtils.*;
2018

@@ -265,9 +263,16 @@ public void testTop() throws JSQLParserException {
265263
statement = "select top 5 foo from bar";
266264
select = (Select) parserManager.parse(new StringReader(statement));
267265
assertEquals(5, ((PlainSelect) select.getSelectBody()).getTop().getRowCount());
268-
269266
}
270267

268+
public void testTopWithParenthesis() throws JSQLParserException {
269+
final String statement = "SELECT TOP (5) PERCENT JobTitle, HireDate FROM HumanResources.Employee ORDER BY HireDate DESC";
270+
final Select select = (Select) parserManager.parse(new StringReader(statement));
271+
272+
assertEquals(5, ((PlainSelect) select.getSelectBody()).getTop().getRowCount());
273+
assertStatementCanBeDeparsedAs(select, statement);
274+
}
275+
271276
public void testSelectItems() throws JSQLParserException {
272277
String statement = "SELECT myid AS MYID, mycol, tab.*, schema.tab.*, mytab.mycol2, myschema.mytab.mycol, myschema.mytab.* FROM mytable WHERE mytable.col = 9";
273278
Select select = (Select) parserManager.parse(new StringReader(statement));

0 commit comments

Comments
 (0)