From 9e77b6bd55ce24217c5af909b3bde5cb6953ca76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Sun, 2 Aug 2015 16:03:23 +0200 Subject: [PATCH] Add support for variable support to "SELECT SKIP FIRST ..." construct The grammar for the construct in informix [1] mentions the possibility, that can be either an integer or a host variable or local SPL variable storing the value of max. The case for plain integers and jdbc variables is covered by the first commit While this commit adds support for constructs using SPL variables. SPL variables must follow identifier rules [2][3]. [1] http://www-01.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.sqls.doc/ids_sqs_0156.htm [2] http://www-01.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.sqls.doc/ids_sqs_1306.htm?lang=de [3] http://www-01.ibm.com/support/knowledgecenter/SSGU8G_12.1.0/com.ibm.sqls.doc/ids_sqs_1660.htm%23ids_sqs_1660?lang=de --- .../sf/jsqlparser/statement/select/First.java | 17 ++++++- .../sf/jsqlparser/statement/select/Skip.java | 17 ++++++- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 2 + .../sf/jsqlparser/test/select/SelectTest.java | 47 +++++++++++++++++-- 4 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/sf/jsqlparser/statement/select/First.java b/src/main/java/net/sf/jsqlparser/statement/select/First.java index 18ba0928b..ab79dd22f 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/First.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/First.java @@ -39,6 +39,7 @@ public enum Keyword { private Keyword keyword; private Long rowCount; private JdbcParameter jdbcParameter; + private String variable; public Long getRowCount() { return rowCount; @@ -64,11 +65,25 @@ public void setKeyword(Keyword keyword) { this.keyword = keyword; } + public String getVariable() { + return variable; + } + + public void setVariable(String variable) { + this.variable = variable; + } + @Override public String toString() { String result = keyword.name() + " "; - result += jdbcParameter != null ? jdbcParameter.toString() : rowCount; + if(rowCount != null) { + result += rowCount; + } else if (jdbcParameter != null) { + result += jdbcParameter.toString(); + } else if (variable != null){ + result += variable; + } return result; } diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Skip.java b/src/main/java/net/sf/jsqlparser/statement/select/Skip.java index a7bf69263..a1162c1d8 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/Skip.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/Skip.java @@ -33,6 +33,7 @@ public class Skip { private Long rowCount; private JdbcParameter jdbcParameter; + private String variable; public Long getRowCount() { return rowCount; @@ -50,11 +51,25 @@ public void setJdbcParameter(JdbcParameter jdbcParameter) { this.jdbcParameter = jdbcParameter; } + public String getVariable() { + return variable; + } + + public void setVariable(String variable) { + this.variable = variable; + } + @Override public String toString() { String result = "SKIP "; - result += jdbcParameter != null ? jdbcParameter.toString() : rowCount; + if(rowCount != null) { + result += rowCount; + } else if (jdbcParameter != null) { + result += jdbcParameter.toString(); + } else if (variable != null){ + result += variable; + } return result; } diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index b307c7d70..61006d6c6 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -1315,6 +1315,7 @@ Skip Skip(): ( token= { skip.setRowCount(Long.parseLong(token.image)); } + | token= { skip.setVariable(token.image); } | "?" { skip.setJdbcParameter(new JdbcParameter()); } [ LOOKAHEAD(2) token = { skip.getJdbcParameter().setIndex(Integer.valueOf(token.image)); } ] ) { @@ -1333,6 +1334,7 @@ First First(): ) ( token= { first.setRowCount(Long.parseLong(token.image)); } + | token= { first.setVariable(token.image); } | "?" { first.setJdbcParameter(new JdbcParameter()); } [ LOOKAHEAD(2) token = { first.getJdbcParameter().setIndex(Integer.valueOf(token.image)); } ] ) { 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 61e965122..2d5e07639 100644 --- a/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/test/select/SelectTest.java @@ -437,6 +437,7 @@ public void testSkip() throws JSQLParserException { final Skip skip = selectBody.getSkip(); assertEquals((long) 5, (long) skip.getRowCount()); assertNull(skip.getJdbcParameter()); + assertNull(skip.getVariable()); final List selectItems = selectBody.getSelectItems(); assertEquals(2, selectItems.size()); @@ -444,6 +445,23 @@ public void testSkip() throws JSQLParserException { assertEquals(secondColumnName, selectItems.get(1).toString()); assertStatementCanBeDeparsedAs(select, statement); + + final String statement2 = "SELECT SKIP skipVar c1, c2 FROM t"; + final Select select2 = (Select) parserManager.parse(new StringReader(statement2)); + + final PlainSelect selectBody2 = (PlainSelect) select2.getSelectBody(); + + final Skip skip2 = selectBody2.getSkip(); + assertNull(skip2.getRowCount()); + assertNull(skip2.getJdbcParameter()); + assertEquals("skipVar", skip2.getVariable()); + + final List selectItems2 = selectBody2.getSelectItems(); + assertEquals(2, selectItems2.size()); + assertEquals("c1", selectItems2.get(0).toString()); + assertEquals("c2", selectItems2.get(1).toString()); + + assertStatementCanBeDeparsedAs(select2, statement2); } public void testFirst() throws JSQLParserException { @@ -465,6 +483,24 @@ public void testFirst() throws JSQLParserException { assertEquals(secondColumnName, selectItems.get(1).toString()); assertStatementCanBeDeparsedAs(select, statement); + + + final String statement2 = "SELECT FIRST firstVar c1, c2 FROM t"; + final Select select2 = (Select) parserManager.parse(new StringReader(statement2)); + + final PlainSelect selectBody2 = (PlainSelect) select2.getSelectBody(); + + final First first2 = selectBody2.getFirst(); + assertNull(first2.getRowCount()); + assertNull(first2.getJdbcParameter()); + assertEquals("firstVar", first2.getVariable()); + + final List selectItems2 = selectBody2.getSelectItems(); + assertEquals(2, selectItems2.size()); + assertEquals("c1", selectItems2.get(0).toString()); + assertEquals("c2", selectItems2.get(1).toString()); + + assertStatementCanBeDeparsedAs(select2, statement2); } public void testFirstWithKeywordLimit() throws JSQLParserException { @@ -490,7 +526,7 @@ public void testFirstWithKeywordLimit() throws JSQLParserException { } public void testSkipFirst() throws JSQLParserException { - final String statement = "SELECT SKIP ?1 FIRST ?2 c1, c2 FROM t1"; + final String statement = "SELECT SKIP ?1 FIRST f1 c1, c2 FROM t1"; final Select select = (Select) parserManager.parse(new StringReader(statement)); final PlainSelect selectBody = (PlainSelect) select.getSelectBody(); @@ -499,11 +535,12 @@ public void testSkipFirst() throws JSQLParserException { assertNotNull(skip.getJdbcParameter()); assertNotNull(skip.getJdbcParameter().getIndex()); assertEquals((int) 1, (int) skip.getJdbcParameter().getIndex()); + assertNull(skip.getVariable()); final First first = selectBody.getFirst(); - assertNotNull(first.getJdbcParameter()); - assertNotNull(first.getJdbcParameter().getIndex()); - assertEquals((int) 2, (int) first.getJdbcParameter().getIndex()); - + assertNull(first.getJdbcParameter()); + assertNull(first.getRowCount()); + assertEquals("f1", first.getVariable()); + final List selectItems = selectBody.getSelectItems(); assertEquals(2, selectItems.size()); assertEquals("c1", selectItems.get(0).toString());