Skip to content

Commit b7754e8

Browse files
committed
some cleaning up for pr #702
1 parent eacb161 commit b7754e8

File tree

4 files changed

+52
-41
lines changed

4 files changed

+52
-41
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Also I would like to know about needed examples or documentation stuff.
5151

5252
## Extensions in the latest SNAPSHOT version 1.4
5353

54+
* support of **substring(col from 2), position('test' in col), ..** and more (pull request #702)
5455
* support of db2 **VALUES** syntax (issue #561)
5556

5657
## Extensions of JSqlParser releases

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

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,17 +2347,17 @@ NamedExpressionList NamedExpressionList1():
23472347
List<String> names = new ArrayList<String>();
23482348
Expression expr1 = null;
23492349
Expression expr2 = null;
2350-
Expression expr3 = null;
2351-
Expression expr4 = null;
23522350
String name = "";
23532351
Token tk1 = null;
23542352
Token tk2 = null;
2355-
Token tk3 = null;
2356-
Token tk4 = null;
23572353
}
23582354
{
23592355
(
2360-
expr1=SimpleExpression() (tk2=<K_FROM>|tk2=<K_IN>|tk2=<K_PLACING>) expr2=SimpleExpression() { expressions.add(expr1); names.add(tk2.image); expressions.add(expr2);}
2356+
(tk1=<K_BOTH>|tk1=<K_LEADING>|tk1=<K_TRAILING>) { names.add(tk1.image); }
2357+
expr1=SimpleExpression()
2358+
(tk2=<K_FROM>|tk2=<K_IN>|tk2=<K_PLACING>)
2359+
expr2=SimpleExpression()
2360+
{ expressions.add(expr1); names.add(tk2.image); expressions.add(expr2);}
23612361
)
23622362

23632363
{
@@ -2374,7 +2374,7 @@ NamedExpressionList NamedExpressionList1():
23742374
// overlay(expr1 placing expr2 from expr3)
23752375
// overlay(expr1 placing expr2 from expr3 for expr4)
23762376
// expr1 has already been consumed
2377-
NamedExpressionList NamedExpressionList2():
2377+
NamedExpressionList NamedExpressionListExprFirst():
23782378
{
23792379
NamedExpressionList retval = new NamedExpressionList();
23802380
List<Expression> expressions = new ArrayList<Expression>();
@@ -2383,18 +2383,28 @@ NamedExpressionList NamedExpressionList2():
23832383
Expression expr2 = null;
23842384
Expression expr3 = null;
23852385
Expression expr4 = null;
2386-
String name = "";
2387-
Token tk1 = null;
23882386
Token tk2 = null;
23892387
Token tk3 = null;
23902388
Token tk4 = null;
23912389
}
23922390
{
2391+
expr1=SimpleExpression()
2392+
(tk2=<K_FROM>|tk2=<K_IN>|tk2=<K_PLACING>)
2393+
{
2394+
names.add("");
2395+
expressions.add(expr1);
2396+
names.add(tk2.image);
2397+
}
23932398
(
2394-
expr2=SimpleExpression() { names.add(""); expressions.add(expr2);}
2395-
( (tk3=<K_FOR>|tk3=<K_FROM>) expr3=SimpleExpression() {names.add(tk3.image); expressions.add(expr3);}
2396-
( (tk4=<K_FOR>) expr4=SimpleExpression() {names.add(tk4.image); expressions.add(expr4);} )?
2397-
)?
2399+
expr2=SimpleExpression() { expressions.add(expr2);}
2400+
(
2401+
(tk3=<K_FOR>|tk3=<K_FROM>)
2402+
expr3=SimpleExpression() {names.add(tk3.image); expressions.add(expr3);}
2403+
(
2404+
(tk4=<K_FOR>)
2405+
expr4=SimpleExpression() {names.add(tk4.image); expressions.add(expr4);}
2406+
)?
2407+
)?
23982408
)
23992409

24002410
{
@@ -3031,34 +3041,25 @@ Function Function() #Function:
30313041

30323042
[ "." tmp=RelObjectNameExt() { funcName+= "." + tmp; } ["." tmp=RelObjectNameExt() { funcName+= "." + tmp; }]]
30333043
"(" [ [<K_DISTINCT> { retval.setDistinct(true); } | <K_ALL> { retval.setAllColumns(true); }]
3034-
// The addition of functions with named parameters (see NamedExpressionList1, NamedExpressionList2) complicates
3035-
// the parsing of the paramter lists. JavaCC needs factorization here so that the tokens which indicate branch points
3036-
// are exposed.
30373044
( LOOKAHEAD(4)
3038-
( (tk1=<K_BOTH>|tk1=<K_LEADING>|tk1=<K_TRAILING>) namedExpressionList=NamedExpressionList1() {namedExpressionList.getNames().add(0,tk1.image);})
3039-
3040-
| ( expr1=SimpleExpression() ( ((tk2=<K_FROM>|tk2=<K_IN>|tk2=<K_PLACING>) namedExpressionList=NamedExpressionList2() {namedExpressionList.getNames().set(0,tk2.image); namedExpressionList.getNames().add(0, ""); namedExpressionList.getExpressions().add(0, expr1);})
3041-
| ("," expressionList=SimpleExpressionList() {expressionList.getExpressions().add(0,expr1);} )? ) )
3042-
3043-
| "*" { retval.setAllColumns(true); }
3044-
| expr = SubSelect() { expr.setUseBrackets(false); expressionList = new ExpressionList(expr); }
3045-
)
3046-
] ")"
3045+
namedExpressionList=NamedExpressionList1()
3046+
|
3047+
LOOKAHEAD(NamedExpressionListExprFirst()) namedExpressionList = NamedExpressionListExprFirst()
3048+
|
3049+
LOOKAHEAD(3) expressionList=SimpleExpressionList()
3050+
|
3051+
"*" { retval.setAllColumns(true); }
3052+
|
3053+
expr = SubSelect() { expr.setUseBrackets(false); expressionList = new ExpressionList(expr); }
3054+
)]
3055+
")"
30473056

30483057
[ "." tmp=RelObjectName() { retval.setAttribute(tmp); }]
30493058

30503059
[ keep = KeepExpression() ]
30513060

30523061
["}"]
30533062
{
3054-
if(expr1 != null && expressionList==null && namedExpressionList == null){
3055-
// If the function has a single parameter, it is consumed before the choice point between
3056-
// named vs. simple expression list. Put it in a simple ExpressionList here.
3057-
expressions = new ArrayList<Expression>();
3058-
expressions.add(expr1);
3059-
expressionList = new ExpressionList();
3060-
expressionList.setExpressions(expressions);
3061-
}
30623063
retval.setParameters(expressionList);
30633064
retval.setNamedParameters(namedExpressionList);
30643065
retval.setName(funcName);

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,17 @@ public void testEscapedFunctionsIssue647() throws JSQLParserException {
10351035
assertSqlCanBeParsedAndDeparsed("SELECT {fn concat(a, b)} AS COL");
10361036
}
10371037

1038+
@Test
1039+
public void testNamedParametersPR702() throws JSQLParserException {
1040+
assertSqlCanBeParsedAndDeparsed("SELECT substring(id, 2, 3), substring(id from 2 for 3), substring(id from 2), trim(BOTH ' ' from 'foo bar '), trim(LEADING ' ' from 'foo bar '), trim(TRAILING ' ' from 'foo bar '), trim(' ' from 'foo bar '), position('foo' in 'bar'), overlay('foo' placing 'bar' from 1), overlay('foo' placing 'bar' from 1 for 2) FROM my table");
1041+
}
1042+
1043+
@Test
1044+
public void testNamedParametersPR702_2() throws JSQLParserException {
1045+
assertSqlCanBeParsedAndDeparsed("SELECT substring(id, 2, 3) FROM mytable");
1046+
assertSqlCanBeParsedAndDeparsed("SELECT substring(id from 2 for 3) FROM mytable");
1047+
}
1048+
10381049
@Test
10391050
public void testWhere() throws JSQLParserException {
10401051

src/test/java/net/sf/jsqlparser/statement/select/SpecialOracleTest.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,18 @@
1818
*/
1919
package net.sf.jsqlparser.statement.select;
2020

21-
import net.sf.jsqlparser.JSQLParserException;
22-
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
23-
import net.sf.jsqlparser.statement.Statement;
24-
import org.apache.commons.io.FileUtils;
25-
import org.junit.ComparisonFailure;
26-
import org.junit.Test;
27-
2821
import java.io.File;
2922
import java.io.IOException;
3023
import java.util.logging.Level;
3124
import java.util.logging.Logger;
32-
25+
import net.sf.jsqlparser.JSQLParserException;
26+
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
27+
import net.sf.jsqlparser.statement.Statement;
3328
import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
29+
import org.apache.commons.io.FileUtils;
3430
import static org.junit.Assert.assertTrue;
31+
import org.junit.ComparisonFailure;
32+
import org.junit.Test;
3533

3634
/**
3735
* Tries to parse and deparse all statments in net.sf.jsqlparser.test.oracle-tests.
@@ -77,7 +75,7 @@ public void testAllSqlsParseDeparse() throws IOException {
7775

7876
LOG.
7977
log(Level.INFO, "tested {0} files. got {1} correct parse results", new Object[]{count, success});
80-
assertTrue(success >= 149);
78+
assertTrue(success >= 150);
8179
}
8280

8381
@Test

0 commit comments

Comments
 (0)