Skip to content

Commit ec2c150

Browse files
committed
Split into lines on commas in SELECT clause
1 parent b610cda commit ec2c150

File tree

6 files changed

+89
-8
lines changed

6 files changed

+89
-8
lines changed

headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/hql/HqlQueryFormatter.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,17 @@ private void walkTree(ParseTree node, StringBuilder sb, FormatState state, int b
224224
return;
225225
}
226226

227+
// Handle commas in SELECT list - newline after comma
228+
if (isSelectListComma(terminal)) {
229+
sb.append(text);
230+
sb.append('\n');
231+
appendIndent(sb, baseIndent + 1);
232+
state.needsSpace = false;
233+
state.atLineStart = true;
234+
state.lastTokenType = tokenType;
235+
return;
236+
}
237+
227238
// Determine spacing
228239
boolean spaceNeeded = state.needsSpace
229240
&& !state.atLineStart
@@ -279,6 +290,19 @@ private void walkTree(ParseTree node, StringBuilder sb, FormatState state, int b
279290
}
280291
}
281292

293+
/**
294+
* Checks whether a terminal node is a comma inside the selectionList rule
295+
* (i.e., separating SELECT list items).
296+
*/
297+
private boolean isSelectListComma(TerminalNode terminal) {
298+
if (terminal.getSymbol().getType() != HqlParser.T__0) { // ','
299+
return false;
300+
}
301+
ParseTree parent = terminal.getParent();
302+
return parent instanceof ParserRuleContext parentCtx
303+
&& parentCtx.getRuleIndex() == HqlParser.RULE_selectionList;
304+
}
305+
282306
/**
283307
* Checks whether a terminal node is an AND or OR inside the predicate rule
284308
* used as a logical combinator (not AND in BETWEEN...AND...).

headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/jpql/JpqlQueryFormatter.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,17 @@ private void walkTree(ParseTree node, StringBuilder sb, FormatState state, int b
213213
return;
214214
}
215215

216+
// Handle commas in SELECT list - newline after comma
217+
if (isSelectListComma(terminal)) {
218+
sb.append(text);
219+
sb.append('\n');
220+
appendIndent(sb, baseIndent + 1);
221+
state.needsSpace = false;
222+
state.atLineStart = true;
223+
state.lastTokenType = tokenType;
224+
return;
225+
}
226+
216227
// Determine spacing
217228
boolean spaceNeeded = state.needsSpace
218229
&& !state.atLineStart
@@ -269,6 +280,19 @@ private void walkTree(ParseTree node, StringBuilder sb, FormatState state, int b
269280
}
270281
}
271282

283+
/**
284+
* Checks whether a terminal node is a comma inside the select_clause rule
285+
* (i.e., separating SELECT list items).
286+
*/
287+
private boolean isSelectListComma(TerminalNode terminal) {
288+
if (terminal.getSymbol().getType() != JpqlParser.T__0) { // ','
289+
return false;
290+
}
291+
ParseTree parent = terminal.getParent();
292+
return parent instanceof ParserRuleContext
293+
&& ((ParserRuleContext) parent).getRuleIndex() == JpqlParser.RULE_select_clause;
294+
}
295+
272296
/**
273297
* Checks whether a terminal node is an AND or OR inside a conditional_expression
274298
* or conditional_term (i.e., a WHERE/HAVING condition combinator, not AND in BETWEEN).

headless-services/commons/jpql/src/main/java/org/springframework/ide/vscode/parser/postgresql/PostgreSqlQueryFormatter.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,17 @@ private void walkTree(ParseTree node, StringBuilder sb, FormatState state, int b
223223
return;
224224
}
225225

226+
// Handle commas in SELECT list - newline after comma
227+
if (isSelectListComma(terminal)) {
228+
sb.append(text);
229+
sb.append('\n');
230+
appendIndent(sb, baseIndent + 1);
231+
state.needsSpace = false;
232+
state.atLineStart = true;
233+
state.lastTokenType = tokenType;
234+
return;
235+
}
236+
226237
// Determine spacing
227238
boolean spaceNeeded = state.needsSpace
228239
&& !state.atLineStart
@@ -284,6 +295,19 @@ && isInsideParens(ctx)) {
284295
}
285296
}
286297

298+
/**
299+
* Checks whether a terminal node is a comma inside the target_list rule
300+
* (i.e., separating SELECT list items).
301+
*/
302+
private boolean isSelectListComma(TerminalNode terminal) {
303+
if (terminal.getSymbol().getType() != PostgreSqlLexer.COMMA) {
304+
return false;
305+
}
306+
ParseTree parent = terminal.getParent();
307+
return parent instanceof ParserRuleContext parentCtx
308+
&& parentCtx.getRuleIndex() == PostgreSqlParser.RULE_target_list;
309+
}
310+
287311
/**
288312
* Checks whether a terminal node is an AND or OR inside the expression rules
289313
* a_expr_and or a_expr_or (i.e., a WHERE/HAVING condition combinator,

headless-services/commons/jpql/src/test/java/org/springframework/ide/vscode/parser/hql/HqlQueryFormatterTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ void selectWithFetchJoin() {
8787
@Test
8888
void selectWithGroupByHavingOrderBy() {
8989
assertEquals("""
90-
SELECT d.name, COUNT(e)
90+
SELECT d.name,
91+
COUNT(e)
9192
FROM Employee e
9293
JOIN e.department d
9394
GROUP BY d.name
@@ -132,7 +133,8 @@ void updateStatement() {
132133
@Test
133134
void insertStatement() {
134135
assertEquals("""
135-
INSERT INTO Employee(name, salary) SELECT p.name, p.salary
136+
INSERT INTO Employee(name, salary) SELECT p.name,
137+
p.salary
136138
FROM Prospect p
137139
WHERE p.approved = true""",
138140
formatter.format("INSERT INTO Employee(name, salary) SELECT p.name, p.salary FROM Prospect p WHERE p.approved = true"));
@@ -239,7 +241,8 @@ void queryPreservesKeywordCase() {
239241
@Test
240242
void queryWithCrossJoin() {
241243
assertEquals("""
242-
SELECT e, d
244+
SELECT e,
245+
d
243246
FROM Employee e
244247
CROSS JOIN Department d
245248
WHERE e.active = true""",

headless-services/commons/jpql/src/test/java/org/springframework/ide/vscode/parser/jpql/JpqlQueryFormatterTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ void selectWithFetchJoin() {
8787
@Test
8888
void selectWithGroupByHavingOrderBy() {
8989
assertEquals("""
90-
SELECT d.name, COUNT(e)
90+
SELECT d.name,
91+
COUNT(e)
9192
FROM Employee e
9293
JOIN e.department d
9394
GROUP BY d.name

headless-services/commons/jpql/src/test/java/org/springframework/ide/vscode/parser/postgresql/PostgreSqlQueryFormatterTest.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ void simpleSelectFrom() {
3535
@Test
3636
void selectFromWhere() {
3737
assertEquals("""
38-
SELECT e.name, e.salary
38+
SELECT e.name,
39+
e.salary
3940
FROM employees e
4041
WHERE e.active = true""",
4142
formatter.format("SELECT e.name, e.salary FROM employees e WHERE e.active = true"));
@@ -55,7 +56,8 @@ void selectFromWhereWithAndOr() {
5556
@Test
5657
void selectWithJoin() {
5758
assertEquals("""
58-
SELECT e.name, d.name
59+
SELECT e.name,
60+
d.name
5961
FROM employees e
6062
JOIN departments d ON e.dept_id = d.id
6163
WHERE d.active = true""",
@@ -65,7 +67,9 @@ void selectWithJoin() {
6567
@Test
6668
void selectWithMultipleJoins() {
6769
assertEquals("""
68-
SELECT o.id, c.name, i.product
70+
SELECT o.id,
71+
c.name,
72+
i.product
6973
FROM orders o
7074
JOIN customers c ON o.customer_id = c.id
7175
LEFT JOIN order_items i ON o.id = i.order_id
@@ -77,7 +81,8 @@ void selectWithMultipleJoins() {
7781
@Test
7882
void selectWithGroupByHavingOrderBy() {
7983
assertEquals("""
80-
SELECT d.name, COUNT(*)
84+
SELECT d.name,
85+
COUNT(*)
8186
FROM employees e
8287
JOIN departments d ON e.dept_id = d.id
8388
GROUP BY d.name

0 commit comments

Comments
 (0)