Skip to content

Commit e1193a6

Browse files
committed
fixes #169
1 parent 0b5f586 commit e1193a6

File tree

5 files changed

+46
-13
lines changed

5 files changed

+46
-13
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ JSqlParser is dual licensed under **LGPL V2.1** or **Apache Software License, Ve
2222
Please provide feedback on https://github.com/JSQLParser/JSqlParser/issues/677, about removing bracket identifier quotation to support array processing.
2323

2424
## News
25+
* breaking **API** change: to support chained functions attribute type was changed to **Expression**
2526
* Released version **1.4** of JSqlParser
2627
* Released version **1.3** of JSqlParser
2728
* Changed behaviour of dotted multipart names for user variables, tables and columns to accept e.g. ORM class names. To achieve this some behaviour of name parsing had to be changed. Before this the parser would fail missing databasenames for SqlServer queries (server..schema.table). But this is allowed for the schema (server.database..table). Now the parser accepts missing inner names per se to avoid some very complicated parsing rules.
@@ -58,6 +59,7 @@ Also I would like to know about needed examples or documentation stuff.
5859

5960
## Extensions in the latest SNAPSHOT version 2.0
6061

62+
* support for chained functions
6163
* first support for **FOR XML PATH**
6264
* support for **NEXTVAL FOR**
6365
* changed all source code license headers to reflect the dual license of JSqlParser more correctly

src/main/java/net/sf/jsqlparser/expression/Function.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ public class Function extends ASTNodeAccessImpl implements Expression {
2121
private boolean allColumns = false;
2222
private boolean distinct = false;
2323
private boolean isEscaped = false;
24-
private String attribute;
24+
private Expression attribute;
25+
private String attributeName;
2526
private KeepExpression keep = null;
2627

2728
@Override
@@ -77,7 +78,6 @@ public void setParameters(ExpressionList list) {
7778
*
7879
* @return the list of named parameters of the function (if any, else null)
7980
*/
80-
8181
public NamedExpressionList getNamedParameters() {
8282
return namedParameters;
8383
}
@@ -99,14 +99,22 @@ public void setEscaped(boolean isEscaped) {
9999
this.isEscaped = isEscaped;
100100
}
101101

102-
public String getAttribute() {
102+
public Expression getAttribute() {
103103
return attribute;
104104
}
105105

106-
public void setAttribute(String attribute) {
106+
public void setAttribute(Expression attribute) {
107107
this.attribute = attribute;
108108
}
109109

110+
public String getAttributeName() {
111+
return attributeName;
112+
}
113+
114+
public void setAttributeName(String attributeName) {
115+
this.attributeName = attributeName;
116+
}
117+
110118
public KeepExpression getKeep() {
111119
return keep;
112120
}
@@ -120,14 +128,14 @@ public String toString() {
120128
String params;
121129

122130
if (parameters != null || namedParameters != null) {
123-
if(parameters != null){
131+
if (parameters != null) {
124132
params = parameters.toString();
125133
if (isDistinct()) {
126134
params = params.replaceFirst("\\(", "(DISTINCT ");
127135
} else if (isAllColumns()) {
128136
params = params.replaceFirst("\\(", "(ALL ");
129137
}
130-
} else{
138+
} else {
131139
params = namedParameters.toString();
132140
}
133141
} else if (isAllColumns()) {
@@ -139,7 +147,9 @@ public String toString() {
139147
String ans = name + "" + params + "";
140148

141149
if (attribute != null) {
142-
ans += "." + attribute;
150+
ans += "." + attribute.toString();
151+
} else if (attributeName != null) {
152+
ans += "." + attributeName;
143153
}
144154

145155
if (keep != null) {

src/main/java/net/sf/jsqlparser/util/deparser/ExpressionDeParser.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,8 @@ public void visit(Function function) {
431431

432432
if (function.getAttribute() != null) {
433433
buffer.append(".").append(function.getAttribute());
434+
} else if (function.getAttributeName() != null) {
435+
buffer.append(".").append(function.getAttributeName());
434436
}
435437
if (function.getKeep() != null) {
436438
buffer.append(" ").append(function.getKeep());

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

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3111,6 +3111,20 @@ Function FunctionWithCondParams() #Function: {
31113111
Function Function() #Function:
31123112
{
31133113
Function retval = new Function();
3114+
}
3115+
{
3116+
(
3117+
"{" <K_FN> { retval.setEscaped(true); } InternalFunction(retval) "}"
3118+
| InternalFunction(retval)
3119+
)
3120+
{
3121+
linkAST(retval,jjtThis);
3122+
return retval;
3123+
}
3124+
}
3125+
3126+
Function InternalFunction(Function retval) :
3127+
{
31143128
String funcName = null;
31153129
String tmp = null;
31163130
List<Expression> expressions = new ArrayList<Expression>();
@@ -3123,8 +3137,6 @@ Function Function() #Function:
31233137
Expression expr1 = null;
31243138
}
31253139
{
3126-
["{" <K_FN> { retval.setEscaped(true); } ]
3127-
31283140
funcName=RelObjectNameExt()
31293141

31303142
[ "." tmp=RelObjectNameExt() { funcName+= "." + tmp; } ["." tmp=RelObjectNameExt() { funcName+= "." + tmp; }]]
@@ -3144,17 +3156,19 @@ Function Function() #Function:
31443156
)]
31453157
")"
31463158

3147-
[ "." tmp=RelObjectName() { retval.setAttribute(tmp); }]
3159+
[ "." (
3160+
LOOKAHEAD(2) expr1=Function() { retval.setAttribute(expr1); }
3161+
| tmp=RelObjectName() { retval.setAttributeName(tmp); }
3162+
)
3163+
]
31483164

3149-
[ keep = KeepExpression() ]
3165+
[ LOOKAHEAD(2) keep = KeepExpression() ]
31503166

3151-
["}"]
31523167
{
31533168
retval.setParameters(expressionList);
31543169
retval.setNamedParameters(namedExpressionList);
31553170
retval.setName(funcName);
31563171
retval.setKeep(keep);
3157-
linkAST(retval,jjtThis);
31583172
return retval;
31593173
}
31603174
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3412,6 +3412,11 @@ public void testForXmlPath() throws JSQLParserException {
34123412
assertSqlCanBeParsedAndDeparsed("SELECT '|' + person_name FROM person JOIN person_group ON person.person_id = person_group.person_id WHERE person_group.group_id = 1 FOR XML PATH('')");
34133413
}
34143414

3415+
@Test
3416+
public void testChainedunctions() throws JSQLParserException {
3417+
assertSqlCanBeParsedAndDeparsed("SELECT func('').func2('') AS foo FROM some_tables");
3418+
}
3419+
34153420
// @Test
34163421
// public void testIntervalExpression() throws JSQLParserException {
34173422
// assertSqlCanBeParsedAndDeparsed("SELECT count(emails.id) FROM emails WHERE (emails.date_entered + 30 DAYS) > CURRENT_DATE");

0 commit comments

Comments
 (0)