Skip to content

Commit 6ce95d5

Browse files
davyboyhayesDavid Hayes
andauthored
Fix[2306] - Adds support for Trino UDF (#2307)
* Fix[2306] - Adds support for Trino UDF Trino SQL allows you to specify User Defined functions in the WITH clause ahead of a statement. This adds support for this type of statement. * Fix[2306] - Adds support for Trino UDF Trino SQL allows you to specify User Defined functions in the WITH clause ahead of a statement. This adds support for this type of statement. --------- Co-authored-by: David Hayes <[email protected]>
1 parent 49958b6 commit 6ce95d5

File tree

10 files changed

+476
-53
lines changed

10 files changed

+476
-53
lines changed

src/main/java/net/sf/jsqlparser/parser/ParserKeywordsUtils.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ public class ParserKeywordsUtils {
124124
{"PRIOR", RESTRICTED_ALIAS},
125125
{"PROCEDURE", RESTRICTED_ALIAS},
126126
{"PUBLIC", RESTRICTED_ALIAS},
127+
{"RETURNS", RESTRICTED_JSQLPARSER},
127128
{"RETURNING", RESTRICTED_JSQLPARSER},
128129
{"RIGHT", RESTRICTED_SQL2016},
129130
{"SAMPLE", RESTRICTED_ALIAS},
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2025 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement.select;
11+
12+
import net.sf.jsqlparser.expression.Expression;
13+
14+
import java.io.Serializable;
15+
import java.util.List;
16+
17+
public class WithFunctionDeclaration implements Serializable {
18+
private String functionName;
19+
private List<WithFunctionParameter> parameters;
20+
private String returnType;
21+
private Expression returnExpression;
22+
23+
public WithFunctionDeclaration() {}
24+
25+
public WithFunctionDeclaration(String functionName, List<WithFunctionParameter> parameters,
26+
String returnType, Expression returnExpression) {
27+
this.functionName = functionName;
28+
this.parameters = parameters;
29+
this.returnType = returnType;
30+
this.returnExpression = returnExpression;
31+
}
32+
33+
public String getFunctionName() {
34+
return functionName;
35+
}
36+
37+
public void setFunctionName(String functionName) {
38+
this.functionName = functionName;
39+
}
40+
41+
public List<WithFunctionParameter> getParameters() {
42+
return parameters;
43+
}
44+
45+
public void setParameters(List<WithFunctionParameter> parameters) {
46+
this.parameters = parameters;
47+
}
48+
49+
public String getReturnType() {
50+
return returnType;
51+
}
52+
53+
public void setReturnType(String returnType) {
54+
this.returnType = returnType;
55+
}
56+
57+
public Expression getReturnExpression() {
58+
return returnExpression;
59+
}
60+
61+
public void setReturnExpression(Expression returnExpression) {
62+
this.returnExpression = returnExpression;
63+
}
64+
65+
public WithFunctionDeclaration withFunctionName(String functionName) {
66+
this.setFunctionName(functionName);
67+
return this;
68+
}
69+
70+
public WithFunctionDeclaration withParameters(List<WithFunctionParameter> parameters) {
71+
this.setParameters(parameters);
72+
return this;
73+
}
74+
75+
public WithFunctionDeclaration withReturnType(String returnType) {
76+
this.setReturnType(returnType);
77+
return this;
78+
}
79+
80+
public WithFunctionDeclaration withReturnExpression(Expression returnExpression) {
81+
this.setReturnExpression(returnExpression);
82+
return this;
83+
}
84+
85+
public StringBuilder appendTo(StringBuilder builder) {
86+
builder
87+
.append("FUNCTION ")
88+
.append(functionName)
89+
.append("(");
90+
for (int i = 0; parameters != null && i < parameters.size(); i++) {
91+
if (i > 0) {
92+
builder.append(", ");
93+
}
94+
parameters.get(i).appendTo(builder);
95+
}
96+
return builder
97+
.append(") RETURNS ")
98+
.append(returnType)
99+
.append(" RETURN ")
100+
.append(returnExpression);
101+
}
102+
103+
@Override
104+
public String toString() {
105+
return appendTo(new StringBuilder()).toString();
106+
}
107+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2025 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement.select;
11+
12+
import java.io.Serializable;
13+
14+
public class WithFunctionParameter implements Serializable {
15+
private String name;
16+
private String type; // e.g., INT
17+
18+
public WithFunctionParameter() {}
19+
20+
public WithFunctionParameter(String name, String type) {
21+
this.name = name;
22+
this.type = type;
23+
}
24+
25+
public String getName() {
26+
return name;
27+
}
28+
29+
public void setName(String name) {
30+
this.name = name;
31+
}
32+
33+
public WithFunctionParameter withName(String name) {
34+
this.name = name;
35+
return this;
36+
}
37+
38+
public String getType() {
39+
return type;
40+
}
41+
42+
public void setType(String type) {
43+
this.type = type;
44+
}
45+
46+
public WithFunctionParameter withType(String type) {
47+
this.type = type;
48+
return this;
49+
}
50+
51+
public StringBuilder appendTo(StringBuilder builder) {
52+
return builder.append(name).append(" ").append(type);
53+
}
54+
55+
@Override
56+
public String toString() {
57+
return appendTo(new StringBuilder()).toString();
58+
}
59+
}

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

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class WithItem<K extends ParenthesedStatement> implements Serializable {
2727
private K statement;
2828
private Alias alias;
2929
private List<SelectItem<?>> withItemList;
30+
private WithFunctionDeclaration withFunctionDeclaration;
3031
private boolean recursive = false;
3132
private boolean usingNot = false;
3233
private boolean materialized = false;
@@ -121,28 +122,46 @@ public void setWithItemList(List<SelectItem<?>> withItemList) {
121122
this.withItemList = withItemList;
122123
}
123124

125+
public WithFunctionDeclaration getWithFunctionDeclaration() {
126+
return withFunctionDeclaration;
127+
}
128+
129+
public void setWithFunctionDeclaration(WithFunctionDeclaration withFunctionDeclaration) {
130+
this.withFunctionDeclaration = withFunctionDeclaration;
131+
}
132+
133+
public WithItem<K> withWithFunctionDeclaration(
134+
WithFunctionDeclaration withFunctionDeclaration) {
135+
this.setWithFunctionDeclaration(withFunctionDeclaration);
136+
return this;
137+
}
138+
124139
@Override
125140
public String toString() {
126141
StringBuilder builder = new StringBuilder();
127-
builder.append(recursive ? "RECURSIVE " : "");
128-
if (alias != null) {
129-
builder.append(alias.getName());
130-
}
131-
if (withItemList != null) {
132-
builder.append("(");
133-
int size = withItemList.size();
134-
for (int i = 0; i < size; i++) {
135-
builder.append(withItemList.get(i)).append(i < size - 1 ? "," : "");
142+
if (withFunctionDeclaration != null) {
143+
builder.append(withFunctionDeclaration);
144+
} else {
145+
builder.append(recursive ? "RECURSIVE " : "");
146+
if (alias != null) {
147+
builder.append(alias.getName());
136148
}
137-
builder.append(")");
138-
}
139-
builder.append(" AS ");
140-
if (materialized) {
141-
builder.append(usingNot
142-
? "NOT MATERIALIZED "
143-
: "MATERIALIZED ");
149+
if (withItemList != null) {
150+
builder.append("(");
151+
int size = withItemList.size();
152+
for (int i = 0; i < size; i++) {
153+
builder.append(withItemList.get(i)).append(i < size - 1 ? "," : "");
154+
}
155+
builder.append(")");
156+
}
157+
builder.append(" AS ");
158+
if (materialized) {
159+
builder.append(usingNot
160+
? "NOT MATERIALIZED "
161+
: "MATERIALIZED ");
162+
}
163+
builder.append(statement);
144164
}
145-
builder.append(statement);
146165
return builder.toString();
147166
}
148167

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

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -717,23 +717,27 @@ public <S> StringBuilder visit(SetOperationList list, S context) {
717717

718718
@Override
719719
public <S> StringBuilder visit(WithItem<?> withItem, S context) {
720-
if (withItem.isRecursive()) {
721-
builder.append("RECURSIVE ");
722-
}
723-
builder.append(withItem.getAlias().getName());
724-
if (withItem.getWithItemList() != null) {
725-
builder.append(" ")
726-
.append(PlainSelect.getStringList(withItem.getWithItemList(), true, true));
727-
}
728-
builder.append(" AS ");
729-
if (withItem.isMaterialized()) {
730-
builder.append(withItem.isUsingNot()
731-
? "NOT MATERIALIZED "
732-
: "MATERIALIZED ");
733-
}
734-
StatementDeParser statementDeParser =
735-
new StatementDeParser((ExpressionDeParser) expressionVisitor, this, builder);
736-
statementDeParser.deParse(withItem.getParenthesedStatement());
720+
if (withItem.getWithFunctionDeclaration() == null) {
721+
if (withItem.isRecursive()) {
722+
builder.append("RECURSIVE ");
723+
}
724+
builder.append(withItem.getAlias().getName());
725+
if (withItem.getWithItemList() != null) {
726+
builder.append(" ")
727+
.append(PlainSelect.getStringList(withItem.getWithItemList(), true, true));
728+
}
729+
builder.append(" AS ");
730+
if (withItem.isMaterialized()) {
731+
builder.append(withItem.isUsingNot()
732+
? "NOT MATERIALIZED "
733+
: "MATERIALIZED ");
734+
}
735+
StatementDeParser statementDeParser =
736+
new StatementDeParser((ExpressionDeParser) expressionVisitor, this, builder);
737+
statementDeParser.deParse(withItem.getParenthesedStatement());
738+
} else {
739+
builder.append(withItem.getWithFunctionDeclaration().toString());
740+
}
737741
return builder;
738742
}
739743

0 commit comments

Comments
 (0)