Skip to content

Commit bddc41c

Browse files
feat: Simplify traversing the AST bottom to top
Signed-off-by: Andreas Reichel <andreas@manticore-projects.com>
1 parent c1edf0f commit bddc41c

6 files changed

Lines changed: 204 additions & 2 deletions

File tree

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,21 @@ public StringBuilder appendTo(StringBuilder builder) {
4848
return builder;
4949
}
5050

51+
public ASTNodeAccess getParent() {
52+
SimpleNode parent = (SimpleNode) node.jjtGetParent();
53+
while (parent.jjtGetValue() == null) {
54+
parent = (SimpleNode) parent.jjtGetParent();
55+
}
56+
57+
return ASTNodeAccess.class.cast(parent.jjtGetValue());
58+
}
59+
60+
public <T extends ASTNodeAccess> T getParent(Class<T> clazz) {
61+
SimpleNode parent = (SimpleNode) node.jjtGetParent();
62+
while (parent.jjtGetValue() == null || !clazz.isInstance(parent.jjtGetValue())) {
63+
parent = (SimpleNode) parent.jjtGetParent();
64+
}
65+
66+
return clazz.cast(parent.jjtGetValue());
67+
}
5168
}

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

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,73 @@
1010
package net.sf.jsqlparser.statement.select;
1111

1212
import net.sf.jsqlparser.expression.Alias;
13+
import net.sf.jsqlparser.expression.Expression;
14+
import net.sf.jsqlparser.schema.Table;
15+
16+
import java.util.Collection;
1317

1418
public class ParenthesedSelect extends Select implements FromItem {
1519
Alias alias;
1620
Pivot pivot;
1721
UnPivot unPivot;
1822
Select select;
1923

24+
private static Alias getAliasFromItem(FromItem fromItem) {
25+
if (fromItem instanceof Table && fromItem.getAlias() == null) {
26+
Table t = (Table) fromItem;
27+
return new Alias(t.getName(), true);
28+
} else {
29+
return new Alias(fromItem.getAlias().getName(), true);
30+
}
31+
}
32+
33+
public ParenthesedSelect() {}
34+
35+
public ParenthesedSelect(FromItem fromItem) {
36+
this.select = new PlainSelect(fromItem);
37+
this.alias = getAliasFromItem(fromItem);
38+
}
39+
40+
public ParenthesedSelect(FromItem fromItem, Expression whereExpressions) {
41+
this.select = new PlainSelect(fromItem, whereExpressions);
42+
this.alias = getAliasFromItem(fromItem);
43+
}
44+
45+
public ParenthesedSelect(FromItem fromItem, Collection<Expression> orderByExpressions) {
46+
this.select = new PlainSelect(fromItem, orderByExpressions);
47+
this.alias = getAliasFromItem(fromItem);
48+
}
49+
50+
public ParenthesedSelect(FromItem fromItem, Expression whereExpressions,
51+
Collection<Expression> orderByExpressions) {
52+
this.select = new PlainSelect(fromItem, whereExpressions, orderByExpressions);
53+
this.alias = getAliasFromItem(fromItem);
54+
}
55+
56+
public ParenthesedSelect(Collection<Expression> selectExpressions, FromItem fromItem) {
57+
this.select = new PlainSelect(selectExpressions, fromItem);
58+
this.alias = getAliasFromItem(fromItem);
59+
}
60+
61+
public ParenthesedSelect(Collection<Expression> selectExpressions, FromItem fromItem,
62+
Expression whereExpressions) {
63+
this.select = new PlainSelect(selectExpressions, fromItem, whereExpressions);
64+
this.alias = getAliasFromItem(fromItem);
65+
}
66+
67+
public ParenthesedSelect(Collection<Expression> selectExpressions, FromItem fromItem,
68+
Collection<Expression> orderByExpressions) {
69+
this.select = new PlainSelect(selectExpressions, fromItem, orderByExpressions);
70+
this.alias = getAliasFromItem(fromItem);
71+
}
72+
73+
public ParenthesedSelect(Collection<Expression> selectExpressions, FromItem fromItem,
74+
Expression whereExpressions, Collection<Expression> orderByExpressions) {
75+
this.select =
76+
new PlainSelect(selectExpressions, fromItem, whereExpressions, orderByExpressions);
77+
this.alias = getAliasFromItem(fromItem);
78+
}
79+
2080
@Override
2181
public Alias getAlias() {
2282
return alias;

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

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,60 @@ public class PlainSelect extends Select {
6767

6868
private Table intoTempTable = null;
6969

70+
public PlainSelect() {}
71+
72+
public PlainSelect(FromItem fromItem) {
73+
addSelectItem(new AllColumns());
74+
setFromItem(fromItem);
75+
}
76+
77+
public PlainSelect(FromItem fromItem, Expression whereExpressions) {
78+
addSelectItem(new AllColumns());
79+
setFromItem(fromItem);
80+
setWhere(whereExpressions);
81+
}
82+
83+
public PlainSelect(FromItem fromItem, Collection<Expression> orderByExpressions) {
84+
addSelectItem(new AllColumns());
85+
setFromItem(fromItem);
86+
addOrderByExpressions(orderByExpressions);
87+
}
88+
89+
public PlainSelect(FromItem fromItem, Expression whereExpressions,
90+
Collection<Expression> orderByExpressions) {
91+
addSelectItem(new AllColumns());
92+
setFromItem(fromItem);
93+
setWhere(whereExpressions);
94+
addOrderByExpressions(orderByExpressions);
95+
}
96+
97+
public PlainSelect(Collection<Expression> selectExpressions, FromItem fromItem) {
98+
addSelectExpressions(selectExpressions);
99+
setFromItem(fromItem);
100+
}
101+
102+
public PlainSelect(Collection<Expression> selectExpressions, FromItem fromItem,
103+
Expression whereExpressions) {
104+
addSelectExpressions(selectExpressions);
105+
setFromItem(fromItem);
106+
setWhere(whereExpressions);
107+
}
108+
109+
public PlainSelect(Collection<Expression> selectExpressions, FromItem fromItem,
110+
Collection<Expression> orderByExpressions) {
111+
addSelectExpressions(selectExpressions);
112+
setFromItem(fromItem);
113+
addOrderByExpressions(orderByExpressions);
114+
}
115+
116+
public PlainSelect(Collection<Expression> selectExpressions, FromItem fromItem,
117+
Expression whereExpressions, Collection<Expression> orderByExpressions) {
118+
addSelectExpressions(selectExpressions);
119+
setFromItem(fromItem);
120+
setWhere(whereExpressions);
121+
addOrderByExpressions(orderByExpressions);
122+
}
123+
70124
@Deprecated
71125
public boolean isUseBrackets() {
72126
return false;
@@ -124,14 +178,18 @@ public PlainSelect addSelectItems(SelectItem<?>... items) {
124178
return this;
125179
}
126180

127-
public PlainSelect addSelectItems(Expression... expressions) {
181+
public PlainSelect addSelectExpressions(Collection<Expression> expressions) {
128182
selectItems = Optional.ofNullable(selectItems).orElseGet(ArrayList::new);
129183
for (Expression expression : expressions) {
130184
selectItems.add(SelectItem.from(expression));
131185
}
132186
return this;
133187
}
134188

189+
public PlainSelect addSelectItems(Expression... expressions) {
190+
return this.addSelectExpressions(Arrays.asList(expressions));
191+
}
192+
135193
public PlainSelect addSelectItem(Expression expression, Alias alias) {
136194
selectItems = Optional.ofNullable(selectItems).orElseGet(ArrayList::new);
137195
selectItems.add(new SelectItem<>(expression, alias));

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,18 @@ public Select addOrderByElements(Collection<? extends OrderByElement> orderByEle
201201
}
202202

203203
public Select addOrderByElements(OrderByElement... orderByElements) {
204-
return addOrderByElements(Arrays.asList(orderByElements));
204+
return this.addOrderByElements(Arrays.asList(orderByElements));
205+
}
206+
207+
public Select addOrderByExpressions(Collection<Expression> orderByExpressions) {
208+
for (Expression e : orderByExpressions) {
209+
addOrderByElements(new OrderByElement().withExpression(e));
210+
}
211+
return this;
212+
}
213+
214+
public Select addOrderByElements(Expression... orderByExpressions) {
215+
return addOrderByExpressions(Arrays.asList(orderByExpressions));
205216
}
206217

207218
public Limit getLimit() {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package net.sf.jsqlparser.parser;
2+
3+
import net.sf.jsqlparser.JSQLParserException;
4+
import net.sf.jsqlparser.expression.AnalyticExpression;
5+
import net.sf.jsqlparser.statement.select.PlainSelect;
6+
import net.sf.jsqlparser.statement.select.Select;
7+
import net.sf.jsqlparser.statement.select.SelectItem;
8+
import org.junit.jupiter.api.Test;
9+
10+
import static org.junit.jupiter.api.Assertions.assertEquals;
11+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
12+
13+
class ASTNodeAccessImplTest {
14+
@Test
15+
void testGetParent() throws JSQLParserException {
16+
String sqlStr = "select listagg(sellerid)\n"
17+
+ "within group (order by sellerid)\n"
18+
+ "over() AS list from winsales;";
19+
20+
PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse(sqlStr);
21+
AnalyticExpression expression =
22+
(AnalyticExpression) select.getSelectItem(0).getExpression();
23+
24+
assertInstanceOf(SelectItem.class, expression.getParent());
25+
assertEquals(select, expression.getParent(Select.class));
26+
}
27+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package net.sf.jsqlparser.statement.select;
2+
3+
import net.sf.jsqlparser.JSQLParserException;
4+
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
5+
import net.sf.jsqlparser.test.TestUtils;
6+
import org.junit.jupiter.api.Test;
7+
8+
import static org.junit.jupiter.api.Assertions.*;
9+
10+
class ParenthesedSelectTest {
11+
@Test
12+
void testConstructFromItem() throws JSQLParserException {
13+
String sqlStr = "select winsales.* from winsales;";
14+
15+
PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse(sqlStr);
16+
select.setFromItem(new ParenthesedSelect(select.getFromItem()));
17+
18+
TestUtils.assertStatementCanBeDeparsedAs(select,
19+
"select winsales.* from (select * from winsales) AS winsales;", true);
20+
21+
sqlStr = "select a.* from winsales AS a;";
22+
23+
select = (PlainSelect) CCJSqlParserUtil.parse(sqlStr);
24+
select.setFromItem(new ParenthesedSelect(select.getFromItem()));
25+
26+
TestUtils.assertStatementCanBeDeparsedAs(select,
27+
"select a.* from (select * from winsales AS a) AS a;", true);
28+
}
29+
}

0 commit comments

Comments
 (0)