Skip to content

Commit 4de78cd

Browse files
committed
ix subquery formatting under conditional
1 parent 69eedd0 commit 4de78cd

File tree

7 files changed

+154
-46
lines changed

7 files changed

+154
-46
lines changed

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/SqlKeywordBlock.kt

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ package org.domaframework.doma.intellij.formatter.block
1717

1818
import com.intellij.lang.ASTNode
1919
import com.intellij.psi.formatter.common.AbstractBlock
20-
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
2120
import org.domaframework.doma.intellij.formatter.block.conflict.SqlDoGroupBlock
2221
import org.domaframework.doma.intellij.formatter.block.group.SqlNewGroupBlock
2322
import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlKeywordGroupBlock
@@ -96,13 +95,7 @@ open class SqlKeywordBlock(
9695
}
9796

9897
else -> {
99-
parentBlock?.let { parent ->
100-
if (parent is SqlElConditionLoopCommentBlock) {
101-
parent.indent.groupIndentLen
102-
} else {
103-
1
104-
}
105-
} ?: 1
98+
parentBlock?.indent?.groupIndentLen ?: 1
10699
}
107100
}
108101
}

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/comment/SqlElConditionLoopCommentBlock.kt

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ class SqlElConditionLoopCommentBlock(
6767
}
6868

6969
companion object {
70+
private const val DIRECTIVE_INDENT_STEP = 2
71+
private const val DEFAULT_INDENT_OFFSET = 1
72+
7073
private val LINE_BREAK_PARENT_TYPES =
7174
listOf(
7275
SqlSubGroupBlock::class,
@@ -121,7 +124,7 @@ class SqlElConditionLoopCommentBlock(
121124
childBlocks.forEach { child ->
122125
if (child is SqlElConditionLoopCommentBlock && child.conditionType.isStartDirective()) {
123126
// If the child is a condition loop directive, align its indentation with the parent directive
124-
child.indent.indentLen = indent.indentLen.plus(2)
127+
child.indent.indentLen = indent.indentLen.plus(DIRECTIVE_INDENT_STEP)
125128
} else if (child is SqlLineCommentBlock) {
126129
if (PsiTreeUtil.prevLeaf(child.node.psi, false)?.text?.contains(StringUtil.LINE_SEPARATE) == true) {
127130
child.indent.indentLen = indent.groupIndentLen
@@ -201,37 +204,7 @@ class SqlElConditionLoopCommentBlock(
201204
}
202205
val openConditionLoopDirectiveCount = getOpenDirectiveCount(parent)
203206
when (parent) {
204-
is SqlSubGroupBlock -> {
205-
val parentGroupIndentLen = parent.indent.groupIndentLen
206-
val grand = parent.parentBlock
207-
grand?.let { grand ->
208-
if (grand is SqlCreateKeywordGroupBlock) {
209-
val grandIndentLen = grand.indent.groupIndentLen
210-
return grandIndentLen.plus(parentGroupIndentLen).minus(1)
211-
}
212-
if (grand is SqlInsertQueryGroupBlock) {
213-
return parentGroupIndentLen
214-
}
215-
if (grand is SqlColumnRawGroupBlock) {
216-
val grandIndentLen = grand.indent.groupIndentLen
217-
var prevTextLen = 1
218-
parent.prevChildren?.dropLast(1)?.forEach { prev ->
219-
prevTextLen = prevTextLen.plus(prev.getNodeText().length)
220-
}
221-
return grandIndentLen.plus(prevTextLen)
222-
}
223-
}
224-
return if (TypeUtil.isExpectedClassType(
225-
SqlRightPatternBlock.NOT_INDENT_EXPECTED_TYPES,
226-
parent,
227-
) ||
228-
parent is SqlWithCommonTableGroupBlock
229-
) {
230-
parentGroupIndentLen.plus(openConditionLoopDirectiveCount * 2)
231-
} else {
232-
parentGroupIndentLen.plus(openConditionLoopDirectiveCount * 2).plus(1)
233-
}
234-
}
207+
is SqlSubGroupBlock -> return calculateSubGroupBlockIndent(parent, openConditionLoopDirectiveCount)
235208

236209
is SqlElConditionLoopCommentBlock -> {
237210
if (conditionType.isEnd()) {
@@ -241,7 +214,7 @@ class SqlElConditionLoopCommentBlock(
241214
} else if (conditionType.isElse()) {
242215
return parent.indent.indentLen
243216
} else {
244-
return parent.indent.indentLen.plus(2)
217+
return parent.indent.indentLen.plus(DIRECTIVE_INDENT_STEP)
245218
}
246219
}
247220

@@ -256,14 +229,14 @@ class SqlElConditionLoopCommentBlock(
256229
// The child branch applies in cases where a conditional directive is included as a child of this block.
257230
val questOffset = if (parent is SqlWithQueryGroupBlock) 0 else 1
258231
parent.indent.groupIndentLen
259-
.plus(openConditionLoopDirectiveCount * 2)
232+
.plus(openConditionLoopDirectiveCount * DIRECTIVE_INDENT_STEP)
260233
.plus(questOffset)
261234
}
262235
} else {
263-
parent.indent.indentLen.plus(openConditionLoopDirectiveCount * 2)
236+
parent.indent.indentLen.plus(openConditionLoopDirectiveCount * DIRECTIVE_INDENT_STEP)
264237
}
265238
}
266-
else -> return parent.indent.indentLen.plus(openConditionLoopDirectiveCount * 2)
239+
else -> return parent.indent.indentLen.plus(openConditionLoopDirectiveCount * DIRECTIVE_INDENT_STEP)
267240
}
268241
}
269242
return 0
@@ -298,4 +271,44 @@ class SqlElConditionLoopCommentBlock(
298271
}
299272
return false
300273
}
274+
275+
fun checkConditionLoopDirectiveParentBlock(block: SqlBlock): Boolean = isBeforeParentBlock() && parentBlock == block
276+
277+
private fun calculateSubGroupBlockIndent(parent: SqlSubGroupBlock, openDirectiveCount: Int): Int {
278+
val parentGroupIndentLen = parent.indent.groupIndentLen
279+
val grand = parent.parentBlock
280+
281+
grand?.let { grandParent ->
282+
when (grandParent) {
283+
is SqlCreateKeywordGroupBlock -> {
284+
val grandIndentLen = grandParent.indent.groupIndentLen
285+
return grandIndentLen.plus(parentGroupIndentLen).minus(DEFAULT_INDENT_OFFSET)
286+
}
287+
is SqlInsertQueryGroupBlock -> return parentGroupIndentLen
288+
is SqlColumnRawGroupBlock -> {
289+
val grandIndentLen = grandParent.indent.groupIndentLen
290+
val prevTextLen = calculatePreviousTextLength(parent)
291+
return grandIndentLen.plus(prevTextLen)
292+
}
293+
}
294+
}
295+
296+
return if (shouldNotIndent(parent)) {
297+
parentGroupIndentLen.plus(openDirectiveCount * DIRECTIVE_INDENT_STEP)
298+
} else {
299+
parentGroupIndentLen.plus(openDirectiveCount * DIRECTIVE_INDENT_STEP).plus(DEFAULT_INDENT_OFFSET)
300+
}
301+
}
302+
303+
private fun calculatePreviousTextLength(parent: SqlSubGroupBlock): Int {
304+
var prevTextLen = DEFAULT_INDENT_OFFSET
305+
parent.prevChildren?.dropLast(1)?.forEach { prev ->
306+
prevTextLen = prevTextLen.plus(prev.getNodeText().length)
307+
}
308+
return prevTextLen
309+
}
310+
311+
private fun shouldNotIndent(parent: SqlSubGroupBlock): Boolean =
312+
TypeUtil.isExpectedClassType(SqlRightPatternBlock.NOT_INDENT_EXPECTED_TYPES, parent) ||
313+
parent is SqlWithCommonTableGroupBlock
301314
}

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/subgroup/SqlSubGroupBlock.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,10 @@ abstract class SqlSubGroupBlock(
123123
lastGroup?.let { lastBlock ->
124124
if (lastBlock is SqlJoinQueriesGroupBlock) return true
125125
if (lastGroup is SqlInGroupBlock) return false
126-
if (lastGroup is SqlElConditionLoopCommentBlock) return true
126+
if (lastGroup is SqlElConditionLoopCommentBlock) {
127+
return lastGroup.checkConditionLoopDirectiveParentBlock(this) ||
128+
lastGroup.conditionType.isElse()
129+
}
127130
val grand = lastBlock.parentBlock
128131
if (grand is SqlElConditionLoopCommentBlock) {
129132
if (grand.conditionType.isElse()) {

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/subgroup/SqlSubQueryGroupBlock.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,17 @@ open class SqlSubQueryGroupBlock(
5151
override fun createBlockIndentLen(): Int =
5252
parentBlock?.let { parent ->
5353
return when (parent) {
54-
is SqlElConditionLoopCommentBlock, is SqlWithQuerySubGroupBlock -> return parent.indent.groupIndentLen
54+
is SqlElConditionLoopCommentBlock -> {
55+
return if (parent.isBeforeParentBlock()) {
56+
parent.parentBlock
57+
?.indent
58+
?.groupIndentLen
59+
?.plus(1) ?: 1
60+
} else {
61+
parent.indent.indentLen
62+
}
63+
}
64+
is SqlWithQuerySubGroupBlock -> return parent.indent.groupIndentLen
5565
is SqlJoinQueriesGroupBlock -> return parent.indent.indentLen
5666
is SqlJoinGroupBlock -> return parent.indent.groupIndentLen.plus(1)
5767
else -> {

src/test/kotlin/org/domaframework/doma/intellij/formatter/SqlFormatterTest.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ class SqlFormatterTest : BasePlatformTestCase() {
246246
formatSqlFile("ConditionalUnion.sql", "ConditionalUnion$formatDataPrefix.sql")
247247
}
248248

249+
fun testConditionalSubqueryFormatter() {
250+
formatSqlFile("ConditionalSubquery.sql", "ConditionalSubquery$formatDataPrefix.sql")
251+
}
252+
249253
private fun formatSqlFile(
250254
beforeFile: String,
251255
afterFile: String,
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
SELECT e.id
2+
, e.name
3+
,
4+
/*%if includeSkillCount */
5+
( SELECT COUNT(DISTINCT es.skill_id)
6+
FROM employee_skills es
7+
/*%if onlyActiveSkills */
8+
INNER JOIN skills sk ON es.skill_id = sk.id
9+
WHERE es.employee_id = e.id
10+
AND sk.is_active = true
11+
/*%if skillCategories != null && skillCategories.size() > 0 */
12+
AND sk.category IN /* skillCategories */('technical', 'management')
13+
/*%end*/
14+
/*%else*/
15+
WHERE es.employee_id = e.id
16+
/*%end*/ ),
17+
/*%end*/
18+
d.department_name
19+
FROM employees e
20+
INNER JOIN departments d ON e.department_id = d.id
21+
WHERE/*%if filterByHighPerformers */
22+
ids IN ( SELECT id
23+
FROM performance_reviews pr
24+
WHERE pr.employee_id = e.id
25+
/*%if reviewPeriod != null */
26+
AND pr.review_date BETWEEN /* reviewPeriod.startDate */'2023-01-01' AND /* reviewPeriod.endDate */'2023-12-31'
27+
/*%end*/
28+
/*%if minScore != null */
29+
AND pr.performance_score >= /* minScore */4.0
30+
/*%end*/ )
31+
/*%else*/
32+
e.is_active = true
33+
/*%end*/
34+
/*%if excludeDepartments != null && excludeDepartments.size() > 0 */
35+
AND e.department_id NOT IN ( SELECT d2.id
36+
FROM departments d2
37+
WHERE d2.name IN /* excludeDepartments */('HR', 'Finance')
38+
/*%if onlyActiveDepartments */
39+
AND d2.is_active = true
40+
/*%end*/ )
41+
/*%end*/
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
SELECT e.id
2+
, e.name
3+
, /*%if includeSkillCount */
4+
( SELECT COUNT(DISTINCT es.skill_id)
5+
FROM employee_skills es
6+
/*%if onlyActiveSkills */
7+
INNER JOIN skills sk
8+
ON es.skill_id = sk.id
9+
WHERE es.employee_id = e.id
10+
AND sk.is_active = true
11+
/*%if skillCategories != null && skillCategories.size() > 0 */
12+
AND sk.category IN /* skillCategories */('technical', 'management')
13+
/*%end*/
14+
/*%else*/
15+
WHERE es.employee_id = e.id
16+
/*%end*/ )
17+
,
18+
/*%end*/
19+
d.department_name
20+
FROM employees e
21+
INNER JOIN departments d
22+
ON e.department_id = d.id
23+
WHERE
24+
/*%if filterByHighPerformers */
25+
ids IN ( SELECT id
26+
FROM performance_reviews pr
27+
WHERE pr.employee_id = e.id
28+
/*%if reviewPeriod != null */
29+
AND pr.review_date BETWEEN /* reviewPeriod.startDate */'2023-01-01' AND /* reviewPeriod.endDate */'2023-12-31'
30+
/*%end*/
31+
/*%if minScore != null */
32+
AND pr.performance_score >= /* minScore */4.0
33+
/*%end*/ )
34+
/*%else*/
35+
e.is_active = true
36+
/*%end*/
37+
/*%if excludeDepartments != null && excludeDepartments.size() > 0 */
38+
AND e.department_id NOT IN ( SELECT d2.id
39+
FROM departments d2
40+
WHERE d2.name IN /* excludeDepartments */('HR', 'Finance')
41+
/*%if onlyActiveDepartments */
42+
AND d2.is_active = true
43+
/*%end*/ )
44+
/*%end*/

0 commit comments

Comments
 (0)