Skip to content

Commit eacb161

Browse files
ted-johnsonwumpz
authored andcommitted
support named parameters (#702)
1 parent e79ccc6 commit eacb161

File tree

12 files changed

+294
-10
lines changed

12 files changed

+294
-10
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,14 @@ public void visit(ExpressionList expressionList) {
346346
}
347347
}
348348

349+
@Override
350+
public void visit(NamedExpressionList namedExpressionList) {
351+
for (Expression expr : namedExpressionList.getExpressions()) {
352+
expr.accept(this);
353+
}
354+
}
355+
356+
349357
@Override
350358
public void visit(MultiExpressionList multiExprList) {
351359
for (ExpressionList list : multiExprList.getExprList()) {

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

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
package net.sf.jsqlparser.expression;
2323

2424
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
25+
import net.sf.jsqlparser.expression.operators.relational.NamedExpressionList;
2526
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
2627

2728
/**
@@ -31,6 +32,7 @@ public class Function extends ASTNodeAccessImpl implements Expression {
3132

3233
private String name;
3334
private ExpressionList parameters;
35+
private NamedExpressionList namedParameters;
3436
private boolean allColumns = false;
3537
private boolean distinct = false;
3638
private boolean isEscaped = false;
@@ -95,6 +97,20 @@ public void setParameters(ExpressionList list) {
9597
parameters = list;
9698
}
9799

100+
/**
101+
* the parameters might be named parameters, e.g. substring('foobar' from 2 for 3)
102+
*
103+
* @return the list of named parameters of the function (if any, else null)
104+
*/
105+
106+
public NamedExpressionList getNamedParameters() {
107+
return namedParameters;
108+
}
109+
110+
public void setNamedParameters(NamedExpressionList list) {
111+
namedParameters = list;
112+
}
113+
98114
/**
99115
* Return true if it's in the form "{fn function_body() }"
100116
*
@@ -128,12 +144,16 @@ public void setKeep(KeepExpression keep) {
128144
public String toString() {
129145
String params;
130146

131-
if (parameters != null) {
132-
params = parameters.toString();
133-
if (isDistinct()) {
134-
params = params.replaceFirst("\\(", "(DISTINCT ");
135-
} else if (isAllColumns()) {
136-
params = params.replaceFirst("\\(", "(ALL ");
147+
if (parameters != null || namedParameters != null) {
148+
if(parameters != null){
149+
params = parameters.toString();
150+
if (isDistinct()) {
151+
params = params.replaceFirst("\\(", "(DISTINCT ");
152+
} else if (isAllColumns()) {
153+
params = params.replaceFirst("\\(", "(ALL ");
154+
}
155+
} else{
156+
params = namedParameters.toString();
137157
}
138158
} else if (isAllColumns()) {
139159
params = "(*)";

src/main/java/net/sf/jsqlparser/expression/operators/relational/ItemsListVisitor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,7 @@ public interface ItemsListVisitor {
2929

3030
void visit(ExpressionList expressionList);
3131

32+
void visit(NamedExpressionList namedExpressionList);
33+
3234
void visit(MultiExpressionList multiExprList);
3335
}

src/main/java/net/sf/jsqlparser/expression/operators/relational/ItemsListVisitorAdapter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ public void visit(SubSelect subSelect) {
3030

3131
}
3232

33+
@Override
34+
public void visit(NamedExpressionList namedExpressionList) {
35+
36+
}
37+
3338
@Override
3439
public void visit(ExpressionList expressionList) {
3540

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2013 JSQLParser
6+
* %%
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU Lesser General Public License as
9+
* published by the Free Software Foundation, either version 2.1 of the
10+
* License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Lesser Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Lesser Public
18+
* License along with this program. If not, see
19+
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
20+
* #L%
21+
*/
22+
package net.sf.jsqlparser.expression.operators.relational;
23+
24+
import java.util.Arrays;
25+
import java.util.List;
26+
27+
import net.sf.jsqlparser.expression.Expression;
28+
29+
/**
30+
* A list of named expressions, as in
31+
* as in select substr('xyzzy' from 2 for 3)
32+
*/
33+
public class NamedExpressionList implements ItemsList {
34+
35+
private List<Expression> expressions;
36+
private List<String> names;
37+
38+
public NamedExpressionList() {
39+
}
40+
41+
public NamedExpressionList(List<Expression> expressions) {
42+
this.expressions = expressions;
43+
}
44+
45+
public NamedExpressionList(Expression ... expressions) {
46+
this.expressions = Arrays.asList(expressions);
47+
}
48+
49+
public List<Expression> getExpressions() {
50+
return expressions;
51+
}
52+
53+
public List<String> getNames() {
54+
return names;
55+
}
56+
57+
58+
public void setExpressions(List<Expression> list) {
59+
expressions = list;
60+
}
61+
62+
public void setNames(List<String> list) {
63+
names = list;
64+
}
65+
66+
67+
@Override
68+
public void accept(ItemsListVisitor itemsListVisitor) {
69+
itemsListVisitor.visit(this);
70+
}
71+
72+
@Override
73+
public String toString() {
74+
75+
StringBuilder ret = new StringBuilder();
76+
ret.append("(");
77+
for(int i=0; i<expressions.size(); i++){
78+
if(i>0){
79+
ret.append(" ");
80+
}
81+
if(! names.get(i).equals("")){
82+
ret.append(names.get(i)).append(" ").append(expressions.get(i));
83+
}else{
84+
ret.append(expressions.get(i));
85+
}
86+
}
87+
ret.append(")");
88+
89+
return ret.toString();
90+
}
91+
}

src/main/java/net/sf/jsqlparser/util/TablesNamesFinder.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
7878
import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
7979
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
80+
import net.sf.jsqlparser.expression.operators.relational.NamedExpressionList;
8081
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
8182
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
8283
import net.sf.jsqlparser.expression.operators.relational.InExpression;
@@ -409,6 +410,13 @@ public void visit(ExpressionList expressionList) {
409410
}
410411
}
411412

413+
@Override
414+
public void visit(NamedExpressionList namedExpressionList) {
415+
for (Expression expression : namedExpressionList.getExpressions()) {
416+
expression.accept(this);
417+
}
418+
}
419+
412420
@Override
413421
public void visit(DateValue dateValue) {
414422
}

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
7878
import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
7979
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
80+
import net.sf.jsqlparser.expression.operators.relational.NamedExpressionList;
8081
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
8182
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
8283
import net.sf.jsqlparser.expression.operators.relational.InExpression;
@@ -435,7 +436,7 @@ public void visit(Function function) {
435436
buffer.append(function.getName());
436437
if (function.isAllColumns() && function.getParameters() == null) {
437438
buffer.append("(*)");
438-
} else if (function.getParameters() == null) {
439+
} else if (function.getParameters() == null && function.getNamedParameters() == null) {
439440
buffer.append("()");
440441
} else {
441442
boolean oldUseBracketsInExprList = useBracketsInExprList;
@@ -446,7 +447,12 @@ public void visit(Function function) {
446447
useBracketsInExprList = false;
447448
buffer.append("(ALL ");
448449
}
449-
visit(function.getParameters());
450+
if(function.getNamedParameters() != null){
451+
visit(function.getNamedParameters());
452+
}
453+
if(function.getParameters() != null){
454+
visit(function.getParameters());
455+
}
450456
useBracketsInExprList = oldUseBracketsInExprList;
451457
if (function.isDistinct() || function.isAllColumns()) {
452458
buffer.append(")");
@@ -482,6 +488,29 @@ public void visit(ExpressionList expressionList) {
482488
}
483489
}
484490

491+
@Override
492+
public void visit(NamedExpressionList namedExpressionList) {
493+
if (useBracketsInExprList) {
494+
buffer.append("(");
495+
}
496+
List<String> names = namedExpressionList.getNames();
497+
List<Expression> expressions = namedExpressionList.getExpressions();
498+
for (int i=0; i<names.size(); i++){
499+
if(i>0){
500+
buffer.append(" ");
501+
}
502+
String name = names.get(i);
503+
if(! name.equals("")){
504+
buffer.append(name);
505+
buffer.append(" ");
506+
}
507+
expressions.get(i).accept(this);
508+
}
509+
if (useBracketsInExprList) {
510+
buffer.append(")");
511+
}
512+
}
513+
485514
public SelectVisitor getSelectVisitor() {
486515
return selectVisitor;
487516
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import net.sf.jsqlparser.expression.Expression;
2727
import net.sf.jsqlparser.expression.ExpressionVisitor;
2828
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
29+
import net.sf.jsqlparser.expression.operators.relational.NamedExpressionList;
2930
import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor;
3031
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
3132
import net.sf.jsqlparser.schema.Column;
@@ -174,6 +175,12 @@ public void visit(ExpressionList expressionList) {
174175
buffer.append(")");
175176
}
176177

178+
// not used in a top-level insert statement
179+
@Override
180+
public void visit(NamedExpressionList NamedExpressionList) {
181+
182+
}
183+
177184
@Override
178185
public void visit(MultiExpressionList multiExprList) {
179186
buffer.append(" VALUES ");

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import net.sf.jsqlparser.expression.Expression;
2727
import net.sf.jsqlparser.expression.ExpressionVisitor;
2828
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
29+
import net.sf.jsqlparser.expression.operators.relational.NamedExpressionList;
2930
import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor;
3031
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
3132
import net.sf.jsqlparser.schema.Column;
@@ -125,6 +126,11 @@ public void visit(ExpressionList expressionList) {
125126
buffer.append(")");
126127
}
127128

129+
// NamedExpressionList not use by top-level Replace
130+
@Override
131+
public void visit(NamedExpressionList namedExpressionList) {
132+
}
133+
128134
@Override
129135
public void visit(SubSelect subSelect) {
130136
subSelect.getSelectBody().accept(selectVisitor);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import net.sf.jsqlparser.expression.Expression;
2727
import net.sf.jsqlparser.expression.ExpressionVisitor;
2828
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
29+
import net.sf.jsqlparser.expression.operators.relational.NamedExpressionList;
2930
import net.sf.jsqlparser.expression.operators.relational.ItemsListVisitor;
3031
import net.sf.jsqlparser.expression.operators.relational.MultiExpressionList;
3132
import net.sf.jsqlparser.schema.Column;
@@ -149,6 +150,11 @@ public void visit(ExpressionList expressionList) {
149150
buffer.append(")");
150151
}
151152

153+
// not used by top-level upsert
154+
@Override
155+
public void visit(NamedExpressionList namedExpressionList) {
156+
}
157+
152158
@Override
153159
public void visit(MultiExpressionList multiExprList) {
154160
buffer.append(" VALUES ");

0 commit comments

Comments
 (0)