diff --git a/README.md b/README.md index bbeea6298..067d0dd56 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,12 @@ Also I would like to know about needed examples or documentation stuff. ## Extensions in the latest SNAPSHOT version 0.9.6 +* improved **top** expression + +```java +SELECT TOP (? + 1) * FROM MyTable +``` + * allowed negative interval expressions like **INTERVAL -420 MINUTES**. * support for **ALTER VIEW** statements * improved merge statement diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Top.java b/src/main/java/net/sf/jsqlparser/statement/select/Top.java index ee1bb179a..bb283d57d 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/Top.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/Top.java @@ -21,31 +21,23 @@ */ package net.sf.jsqlparser.statement.select; +import net.sf.jsqlparser.expression.Expression; + /** * A top clause in the form [TOP (row_count) or TOP row_count] */ public class Top { - private long rowCount; - private boolean rowCountJdbcParameter = false; private boolean hasParenthesis = false; private boolean isPercentage = false; + private Expression expression; - public long getRowCount() { - return rowCount; - } - - // TODO instead of a plain number, an expression should be added, which could be a NumberExpression, a GroupedExpression or a JdbcParameter - public void setRowCount(long rowCount) { - this.rowCount = rowCount; - } - - public boolean isRowCountJdbcParameter() { - return rowCountJdbcParameter; + public Expression getExpression() { + return expression; } - public void setRowCountJdbcParameter(boolean rowCountJdbcParameter) { - this.rowCountJdbcParameter = rowCountJdbcParameter; + public void setExpression(Expression expression) { + this.expression = expression; } public boolean hasParenthesis() { @@ -72,8 +64,7 @@ public String toString() { result += "("; } - result += rowCountJdbcParameter ? "?" - : rowCount; + result += expression.toString(); if (hasParenthesis) { result += ")"; diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 946a6e120..755342cd8 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -1439,17 +1439,17 @@ Top Top(): { Top top = new Top(); Token token = null; + Expression expr = null; } { ( - token= { top.setRowCount(Long.parseLong(token.image)); } + token= { top.setExpression(new LongValue(token.image)); } | - "?" { top.setRowCountJdbcParameter(true);} + "?" { top.setExpression(new JdbcParameter()); } | "(" - ( token= { top.setRowCount(Long.parseLong(token.image)); } - | "?" { top.setRowCountJdbcParameter(true);} ) + expr=AdditiveExpression() { top.setExpression(expr); } { top.setParenthesis(true);} ")" ) [ LOOKAHEAD(2) { top.setPercentage(true); } ] diff --git a/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java index 0e76ea52f..d0e744b6e 100644 --- a/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java @@ -398,12 +398,12 @@ public void testTop() throws JSQLParserException { Select select = (Select) parserManager.parse(new StringReader(statement)); - assertEquals(3, ((PlainSelect) select.getSelectBody()).getTop().getRowCount()); + assertEquals(3, ((LongValue)((PlainSelect) select.getSelectBody()).getTop().getExpression()).getValue()); assertStatementCanBeDeparsedAs(select, statement); statement = "select top 5 foo from bar"; select = (Select) parserManager.parse(new StringReader(statement)); - assertEquals(5, ((PlainSelect) select.getSelectBody()).getTop().getRowCount()); + assertEquals(5, ((LongValue)((PlainSelect) select.getSelectBody()).getTop().getExpression()).getValue()); } public void testTopWithParenthesis() throws JSQLParserException { @@ -415,8 +415,7 @@ public void testTopWithParenthesis() throws JSQLParserException { final PlainSelect selectBody = (PlainSelect) select.getSelectBody(); final Top top = selectBody.getTop(); - assertEquals(5, top.getRowCount()); - assertFalse(top.isRowCountJdbcParameter()); + assertEquals("5", top.getExpression().toString()); assertTrue(top.hasParenthesis()); assertTrue(top.isPercentage()); @@ -2188,4 +2187,12 @@ public void testEscapedBackslashIssue253() throws JSQLParserException { public void testKeywordTableIssue261() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("SELECT column_value FROM table(VARCHAR_LIST_TYPE())"); } + + public void testTopExpressionIssue243() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("SELECT TOP (? + 1) * FROM MyTable"); + } + + public void testTopExpressionIssue243_2() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("SELECT TOP (CAST(? AS INT)) * FROM MyTable"); + } }