Skip to content

Commit 432c0ef

Browse files
committed
fixed #160
1 parent 768f7cb commit 432c0ef

File tree

4 files changed

+68
-50
lines changed

4 files changed

+68
-50
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ Also I would like to know about needed examples or documentation stuff.
3737

3838
## Extensions in the latest SNAPSHOT version 0.9.4
3939

40+
* support of signed parameters added
41+
42+
~~~sql
43+
SELECT * FROM mytable WHERE -? < 4
44+
~~~
45+
4046
* support for **SELECT SKIP <OFFSET> FIRST <LIMIT>...**
4147
* Completely rewritten S_IDENTIFIER rule to accept hopefully all possible UTF-8 letters without
4248
specifying some additional rules.

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,11 @@ public String toString() {
332332
sql.append(" OF ").append(forUpdateTable);
333333
}
334334
}
335+
} else {
336+
//without from
337+
if (where != null) {
338+
sql.append(" WHERE ").append(where);
339+
}
335340
}
336341
if (useBrackets) {
337342
sql.append(")");

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,13 +1843,13 @@ Expression PrimaryExpression():
18431843

18441844
| retval=CaseWhenExpression()
18451845

1846-
| "?" { retval = new JdbcParameter(); } [ LOOKAHEAD(2) token = <S_LONG> { ((JdbcParameter)retval).setIndex(Integer.valueOf(token.image)); } ]
1846+
| LOOKAHEAD(3) [sign="+" | sign="-"] "?" { retval = new JdbcParameter(); } [ LOOKAHEAD(2) token = <S_LONG> { ((JdbcParameter)retval).setIndex(Integer.valueOf(token.image)); } ]
18471847

1848-
| LOOKAHEAD(2) retval=JdbcNamedParameter()
1848+
| LOOKAHEAD(3) [sign="+" | sign="-"] retval=JdbcNamedParameter()
18491849

1850-
| retval=UserVariable()
1850+
| LOOKAHEAD(3) [sign="+" | sign="-"] retval=UserVariable()
18511851

1852-
| retval=NumericBind()
1852+
| LOOKAHEAD(3) [sign="+" | sign="-"] retval=NumericBind()
18531853

18541854
| LOOKAHEAD(AnalyticExpression()) retval=AnalyticExpression()
18551855

@@ -1873,7 +1873,7 @@ Expression PrimaryExpression():
18731873

18741874
| LOOKAHEAD([sign="+" | sign="-"] "(" SubSelect() ")") [sign="+" | sign="-"] "(" retval=SubSelect() ")"
18751875

1876-
| LOOKAHEAD(3) [sign="+" | sign="-"] "(" retval=BitwiseAndOr() ")" {retval = new Parenthesis(retval); }
1876+
| LOOKAHEAD(3) [sign="+" | sign="-"] "(" retval=BitwiseAndOr() ")" {retval = new Parenthesis(retval); }
18771877

18781878
| token=<S_CHAR_LITERAL> { retval = new StringValue(token.image); }
18791879

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

Lines changed: 52 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public void testMultiPartTableNameWithServerNameAndSchemaName() throws Exception
4545

4646
assertStatementCanBeDeparsedAs(select, statement);
4747
}
48-
48+
4949
public void testMultiPartTableNameWithServerProblem() throws Exception {
5050
final String statement = "SELECT * FROM LINK_100.htsac.dbo.t_transfer_num a";
5151
assertSqlCanBeParsedAndDeparsed(statement);
@@ -425,7 +425,7 @@ public void testTopWithParenthesis() throws JSQLParserException {
425425

426426
assertStatementCanBeDeparsedAs(select, statement);
427427
}
428-
428+
429429
public void testSkip() throws JSQLParserException {
430430
final String firstColumnName = "alias.columnName1";
431431
final String secondColumnName = "alias.columnName2";
@@ -445,7 +445,7 @@ public void testSkip() throws JSQLParserException {
445445
assertEquals(secondColumnName, selectItems.get(1).toString());
446446

447447
assertStatementCanBeDeparsedAs(select, statement);
448-
448+
449449
final String statement2 = "SELECT SKIP skipVar c1, c2 FROM t";
450450
final Select select2 = (Select) parserManager.parse(new StringReader(statement2));
451451

@@ -463,7 +463,7 @@ public void testSkip() throws JSQLParserException {
463463

464464
assertStatementCanBeDeparsedAs(select2, statement2);
465465
}
466-
466+
467467
public void testFirst() throws JSQLParserException {
468468
final String firstColumnName = "alias.columnName1";
469469
final String secondColumnName = "alias.columnName2";
@@ -483,8 +483,7 @@ public void testFirst() throws JSQLParserException {
483483
assertEquals(secondColumnName, selectItems.get(1).toString());
484484

485485
assertStatementCanBeDeparsedAs(select, statement);
486-
487-
486+
488487
final String statement2 = "SELECT FIRST firstVar c1, c2 FROM t";
489488
final Select select2 = (Select) parserManager.parse(new StringReader(statement2));
490489

@@ -524,7 +523,7 @@ public void testFirstWithKeywordLimit() throws JSQLParserException {
524523

525524
assertStatementCanBeDeparsedAs(select, statement);
526525
}
527-
526+
528527
public void testSkipFirst() throws JSQLParserException {
529528
final String statement = "SELECT SKIP ?1 FIRST f1 c1, c2 FROM t1";
530529
final Select select = (Select) parserManager.parse(new StringReader(statement));
@@ -540,15 +539,15 @@ public void testSkipFirst() throws JSQLParserException {
540539
assertNull(first.getJdbcParameter());
541540
assertNull(first.getRowCount());
542541
assertEquals("f1", first.getVariable());
543-
542+
544543
final List<SelectItem> selectItems = selectBody.getSelectItems();
545544
assertEquals(2, selectItems.size());
546545
assertEquals("c1", selectItems.get(0).toString());
547546
assertEquals("c2", selectItems.get(1).toString());
548-
547+
549548
assertStatementCanBeDeparsedAs(select, statement);
550549
}
551-
550+
552551
public void testSelectItems() throws JSQLParserException {
553552
String statement = "SELECT myid AS MYID, mycol, tab.*, schema.tab.*, mytab.mycol2, myschema.mytab.mycol, myschema.mytab.* FROM mytable WHERE mytable.col = 9";
554553
Select select = (Select) parserManager.parse(new StringReader(statement));
@@ -585,10 +584,10 @@ public void testUnion() throws JSQLParserException {
585584
Select select = (Select) parserManager.parse(new StringReader(statement));
586585
SetOperationList setList = (SetOperationList) select.getSelectBody();
587586
assertEquals(3, setList.getSelects().size());
588-
assertEquals("mytable", ((Table) ((PlainSelect)setList.getSelects().get(0)).getFromItem()).getName());
589-
assertEquals("mytable3", ((Table) ((PlainSelect)setList.getSelects().get(1)).getFromItem()).getName());
590-
assertEquals("mytable2", ((Table) ((PlainSelect)setList.getSelects().get(2)).getFromItem()).getName());
591-
assertEquals(3, ((PlainSelect)setList.getSelects().get(2)).getLimit().getOffset());
587+
assertEquals("mytable", ((Table) ((PlainSelect) setList.getSelects().get(0)).getFromItem()).getName());
588+
assertEquals("mytable3", ((Table) ((PlainSelect) setList.getSelects().get(1)).getFromItem()).getName());
589+
assertEquals("mytable2", ((Table) ((PlainSelect) setList.getSelects().get(2)).getFromItem()).getName());
590+
assertEquals(3, ((PlainSelect) setList.getSelects().get(2)).getLimit().getOffset());
592591

593592
// use brakets for toString
594593
// use standard limit syntax
@@ -947,7 +946,7 @@ public void testLike() throws JSQLParserException {
947946
assertEquals("test", ((StringValue) ((LikeExpression) plainSelect.getWhere()).getRightExpression()).getValue());
948947
assertEquals("test2", ((LikeExpression) plainSelect.getWhere()).getEscape());
949948
}
950-
949+
951950
public void testIlike() throws JSQLParserException {
952951
String statement = "SELECT col1 FROM table1 WHERE col1 ILIKE '%hello%'";
953952
assertSqlCanBeParsedAndDeparsed(statement);
@@ -1024,7 +1023,7 @@ public void testWith() throws JSQLParserException {
10241023
+ "WHERE THIS_EMP.JOB = 'SALESREP' AND THIS_EMP.WORKDEPT = DINFO.DEPTNO";
10251024
assertSqlCanBeParsedAndDeparsed(statement);
10261025
}
1027-
1026+
10281027
public void testWithRecursive() throws JSQLParserException {
10291028
assertSqlCanBeParsedAndDeparsed("WITH RECURSIVE t (n) AS ((SELECT 1) UNION ALL (SELECT n + 1 FROM t WHERE n < 100)) SELECT sum(n) FROM t");
10301029
}
@@ -1340,12 +1339,12 @@ public void testAnalyticFunctionProblem1b() throws JSQLParserException {
13401339
String statement = "SELECT last_value(s.revenue_hold) OVER (PARTITION BY s.id_d_insertion_order, s.id_d_product_ad_attr, trunc(s.date_id, 'mm') ORDER BY s.date_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS col FROM s";
13411340
assertSqlCanBeParsedAndDeparsed(statement);
13421341
}
1343-
1342+
13441343
public void testFunctionLeft() throws JSQLParserException {
13451344
String statement = "SELECT left(table1.col1, 4) FROM table1";
13461345
assertSqlCanBeParsedAndDeparsed(statement);
13471346
}
1348-
1347+
13491348
public void testFunctionRight() throws JSQLParserException {
13501349
String statement = "SELECT right(table1.col1, 4) FROM table1";
13511350
assertSqlCanBeParsedAndDeparsed(statement);
@@ -1362,14 +1361,14 @@ public void testOracleJoin2() throws JSQLParserException {
13621361
}
13631362

13641363
public void testOracleJoin2_1() throws JSQLParserException {
1365-
String[] values = new String[]{"(+)", "( +)", "(+ )", "( + )"," (+) "};
1364+
String[] values = new String[]{"(+)", "( +)", "(+ )", "( + )", " (+) "};
13661365
for (String value : values) {
13671366
assertSqlCanBeParsedAndDeparsed("SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.a" + value + " = tabelle2.b", true);
13681367
}
13691368
}
1370-
1369+
13711370
public void testOracleJoin2_2() throws JSQLParserException {
1372-
String[] values = new String[]{"(+)", "( +)", "(+ )", "( + )"," (+) "};
1371+
String[] values = new String[]{"(+)", "( +)", "(+ )", "( + )", " (+) "};
13731372
for (String value : values) {
13741373
assertSqlCanBeParsedAndDeparsed("SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.a = tabelle2.b" + value, true);
13751374
}
@@ -1503,11 +1502,11 @@ public void testAdditionalLettersGerman() throws JSQLParserException {
15031502

15041503
stmt = "SELECT Äcol FROM testtableÄÖÜ";
15051504
assertSqlCanBeParsedAndDeparsed(stmt);
1506-
1505+
15071506
stmt = "SELECT ßcolß FROM testtableß";
15081507
assertSqlCanBeParsedAndDeparsed(stmt);
15091508
}
1510-
1509+
15111510
public void testAdditionalLettersSpanish() throws JSQLParserException {
15121511
String stmt = "SELECT * FROM años";
15131512
assertSqlCanBeParsedAndDeparsed(stmt);
@@ -1596,7 +1595,7 @@ public void testInterval2() throws JSQLParserException {
15961595

15971596
assertEquals("'45 MINUTE'", iexpr.getParameter());
15981597
}
1599-
1598+
16001599
public void testInterval3() throws JSQLParserException {
16011600
String stmt = "SELECT 5 + INTERVAL '3' day";
16021601
assertSqlCanBeParsedAndDeparsed(stmt);
@@ -1818,11 +1817,11 @@ public void testSelectJoin() throws JSQLParserException {
18181817
public void testSelectJoin2() throws JSQLParserException {
18191818
assertSqlCanBeParsedAndDeparsed("SELECT * FROM pg_constraint WHERE pg_attribute.attnum = ANY(pg_constraint.conkey)");
18201819
}
1821-
1820+
18221821
public void testAnyConditionSubSelect() throws JSQLParserException {
18231822
assertSqlCanBeParsedAndDeparsed("SELECT e1.empno, e1.sal FROM emp e1 WHERE e1.sal > ANY (SELECT e2.sal FROM emp e2 WHERE e2.deptno = 10)");
18241823
}
1825-
1824+
18261825
public void testAllConditionSubSelect() throws JSQLParserException {
18271826
assertSqlCanBeParsedAndDeparsed("SELECT e1.empno, e1.sal FROM emp e1 WHERE e1.sal > ALL (SELECT e2.sal FROM emp e2 WHERE e2.deptno = 10)");
18281827
}
@@ -1846,72 +1845,80 @@ public void testSelectUserVariable() throws JSQLParserException {
18461845
public void testSelectNumericBind() throws JSQLParserException {
18471846
assertSqlCanBeParsedAndDeparsed("SELECT a FROM b WHERE c = :1");
18481847
}
1849-
1848+
18501849
public void testSelectBrackets() throws JSQLParserException {
18511850
assertSqlCanBeParsedAndDeparsed("SELECT avg((123.250)::numeric)");
18521851
}
1853-
1852+
18541853
public void testSelectBrackets2() throws JSQLParserException {
18551854
assertSqlCanBeParsedAndDeparsed("SELECT (EXTRACT(epoch FROM age(d1, d2)) / 2)::numeric");
18561855
}
1857-
1856+
18581857
public void testSelectBrackets3() throws JSQLParserException {
18591858
assertSqlCanBeParsedAndDeparsed("SELECT avg((EXTRACT(epoch FROM age(d1, d2)) / 2)::numeric)");
18601859
}
1861-
1860+
18621861
public void testSelectBrackets4() throws JSQLParserException {
18631862
assertSqlCanBeParsedAndDeparsed("SELECT (1 / 2)::numeric");
18641863
}
1865-
1864+
18661865
public void testSelectForUpdateOfTable() throws JSQLParserException {
18671866
assertSqlCanBeParsedAndDeparsed("SELECT foo.*, bar.* FROM foo, bar WHERE foo.id = bar.foo_id FOR UPDATE OF foo");
18681867
}
1869-
1868+
18701869
public void testSelectWithBrackets() throws JSQLParserException {
18711870
assertSqlCanBeParsedAndDeparsed("(SELECT 1 FROM mytable)");
18721871
}
1873-
1872+
18741873
public void testSelectWithBrackets2() throws JSQLParserException {
18751874
assertSqlCanBeParsedAndDeparsed("(SELECT 1)");
18761875
}
1877-
1876+
18781877
public void testSelectWithoutFrom() throws JSQLParserException {
18791878
assertSqlCanBeParsedAndDeparsed("SELECT footable.foocolumn");
18801879
}
1881-
1880+
18821881
public void testSelectKeywordPercent() throws JSQLParserException {
18831882
assertSqlCanBeParsedAndDeparsed("SELECT percent FROM MY_TABLE");
18841883
}
1885-
1884+
18861885
public void testSelectJPQLPositionalParameter() throws JSQLParserException {
18871886
assertSqlCanBeParsedAndDeparsed("SELECT email FROM users WHERE (type LIKE 'B') AND (username LIKE ?1)");
18881887
}
1889-
1888+
18901889
public void testSelectKeep() throws JSQLParserException {
18911890
assertSqlCanBeParsedAndDeparsed("SELECT col1, min(col2) KEEP (DENSE_RANK FIRST ORDER BY col3), col4 FROM table1 GROUP BY col5 ORDER BY col3");
18921891
}
1893-
1892+
18941893
public void testSelectKeepOver() throws JSQLParserException {
18951894
assertSqlCanBeParsedAndDeparsed("SELECT MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY commission_pct) OVER (PARTITION BY department_id ) \"Worst\" FROM employees ORDER BY department_id, salary");
18961895
}
1897-
1896+
18981897
public void testGroupConcat() throws JSQLParserException {
18991898
assertSqlCanBeParsedAndDeparsed("SELECT student_name, GROUP_CONCAT(DISTINCT test_score ORDER BY test_score DESC SEPARATOR ' ') FROM student GROUP BY student_name");
19001899
}
1901-
1900+
19021901
public void testRowConstructor1() throws JSQLParserException {
19031902
assertSqlCanBeParsedAndDeparsed("SELECT * FROM t1 WHERE (col1, col2) = (SELECT col3, col4 FROM t2 WHERE id = 10)");
19041903
}
1905-
1906-
public void testRowConstructor2() throws JSQLParserException {
1904+
1905+
public void testRowConstructor2() throws JSQLParserException {
19071906
assertSqlCanBeParsedAndDeparsed("SELECT * FROM t1 WHERE ROW(col1, col2) = (SELECT col3, col4 FROM t2 WHERE id = 10)");
19081907
}
1909-
1908+
19101909
public void testIssue154() throws JSQLParserException {
19111910
assertSqlCanBeParsedAndDeparsed("SELECT d.id, d.uuid, d.name, d.amount, d.percentage, d.modified_time FROM discount d LEFT OUTER JOIN discount_category dc ON d.id = dc.discount_id WHERE merchant_id = ? AND deleted = ? AND dc.discount_id IS NULL AND modified_time < ? AND modified_time >= ? ORDER BY modified_time");
19121911
}
1913-
1914-
public void testIssue154_2() throws JSQLParserException {
1912+
1913+
public void testIssue154_2() throws JSQLParserException {
19151914
assertSqlCanBeParsedAndDeparsed("SELECT r.id, r.uuid, r.name, r.system_role FROM role r WHERE r.merchant_id = ? AND r.deleted_time IS NULL ORDER BY r.id DESC");
19161915
}
1916+
1917+
public void testIssue160_signedParameter() throws JSQLParserException {
1918+
assertSqlCanBeParsedAndDeparsed("SELECT start_date WHERE start_date > DATEADD(HH, -?, GETDATE())");
1919+
}
1920+
1921+
public void testIssue160_signedParameter2() throws JSQLParserException {
1922+
assertSqlCanBeParsedAndDeparsed("SELECT * FROM mytable WHERE -? = 5");
1923+
}
19171924
}

0 commit comments

Comments
 (0)