Skip to content

Commit a9ec3ec

Browse files
committed
feat: extend AND/OR formatting optimization to CASE WHEN conditions
- Apply same-line AND/OR formatting to CASE WHEN conditions - Maintain newline behavior for WHERE/HAVING/JOIN clauses
1 parent bafed54 commit a9ec3ec

File tree

7 files changed

+48
-7
lines changed

7 files changed

+48
-7
lines changed

src/SqlFormatter.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public function format(string $string, string $indentString = ' '): string
6666
$inlineCount = 0;
6767
$inlineIndented = false;
6868
$clauseLimit = false;
69-
$inIfCondition = false;
69+
$inBooleanExpression = false;
7070

7171
$appendNewLineIfNotAddedFx = static function () use (&$addedNewline, &$return, $tab, &$indentLevel): void {
7272
// Add a newline if not already added
@@ -316,18 +316,20 @@ public function format(string $string, string $indentString = ' '): string
316316
$increaseBlockIndent = true;
317317
}
318318

319-
// Track IF condition context only for IF/ELSEIF that are part of conditional blocks
319+
// Track boolean expression context for IF/ELSEIF/CASE WHEN conditions
320320
// (not for "IF()" function calls)
321321
if (in_array($tokenValueUpper, ['IF', 'ELSEIF', 'ELSIF'], true)) {
322322
// Check if this IF is part of a conditional block by looking at the next token
323323
$nextToken = $cursor->subCursor()->next(Token::TOKEN_TYPE_WHITESPACE);
324324
if (
325325
$nextToken !== null && $nextToken->value() !== '('
326326
) {
327-
$inIfCondition = true;
327+
$inBooleanExpression = true;
328328
}
329+
} elseif ($tokenValueUpper === 'WHEN') {
330+
$inBooleanExpression = true;
329331
} elseif ($tokenValueUpper === 'THEN' || $tokenValueUpper === 'ELSE' || $tokenValueUpper === 'END') {
330-
$inIfCondition = false;
332+
$inBooleanExpression = false;
331333
}
332334
} elseif (
333335
$clauseLimit &&
@@ -347,10 +349,10 @@ public function format(string $string, string $indentString = ' '): string
347349
$newline = true;
348350
}
349351
} elseif ($token->isOfType(Token::TOKEN_TYPE_RESERVED_NEWLINE)) {
350-
// Newline reserved words start a new line, except for AND/OR within IF conditions
352+
// Newline reserved words start a new line, except for AND/OR within boolean expressions
351353

352-
// Skip newlines for AND/OR when inside IF condition
353-
if (! $inIfCondition || ! in_array($tokenValueUpper, ['AND', 'OR'], true)) {
354+
// Skip newlines for AND/OR when inside boolean expressions (IF conditions, CASE WHEN)
355+
if (! $inBooleanExpression || ! in_array($tokenValueUpper, ['AND', 'OR'], true)) {
354356
$appendNewLineIfNotAddedFx();
355357
}
356358

tests/clihighlight.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,3 +1217,14 @@ MY_NON_TOP_LEVEL_KEYWORD_FX_3();
12171217
RETURN id;
12181218
END IF;
12191219
END;
1220+
---
1221+
SELECT
1222+
CASE WHEN status = 'active' AND priority = 'high' THEN
1223+
'urgent'
1224+
WHEN status = 'active' OR status = 'pending' THEN
1225+
'normal'
1226+
ELSE
1227+
'low'
1228+
END AS task_priority
1229+
FROM
1230+
tasks;

tests/compress.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,5 @@ SELECT t.id, t.start, t.end, t.end AS e2, t.limit, t.begin, t.case, t.when, t.th
113113
CREATE TABLE t (c VARCHAR(20)) DEFAULT CHARACTER SET utf8mb4 ENGINE = InnoDB
114114
---
115115
BEGIN IF first_name != '' AND last_name != '' THEN RETURN CONCAT(first_name, ' ', last_name); ELSEIF first_name != '' THEN RETURN first_name; ELSIF last_name != '' THEN RETURN last_name; ELSE RETURN id; END IF; END;
116+
---
117+
SELECT CASE WHEN status = 'active' AND priority = 'high' THEN 'urgent' WHEN status = 'active' OR status = 'pending' THEN 'normal' ELSE 'low' END AS task_priority FROM tasks;

tests/format-highlight.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,3 +1217,14 @@
12171217
<span style="font-weight:bold;">RETURN</span> <span style="color: #333;">id</span><span >;</span>
12181218
<span style="font-weight:bold;">END</span> <span style="font-weight:bold;">IF</span><span >;</span>
12191219
<span style="font-weight:bold;">END</span><span >;</span></pre>
1220+
---
1221+
<pre style="color: black; background-color: white;"><span style="font-weight:bold;">SELECT</span>
1222+
<span style="font-weight:bold;">CASE</span> <span style="font-weight:bold;">WHEN</span> <span style="font-weight:bold;">status</span> <span >=</span> <span style="color: blue;">'active'</span> <span style="font-weight:bold;">AND</span> <span style="color: #333;">priority</span> <span >=</span> <span style="color: blue;">'high'</span> <span style="font-weight:bold;">THEN</span>
1223+
<span style="color: blue;">'urgent'</span>
1224+
<span style="font-weight:bold;">WHEN</span> <span style="font-weight:bold;">status</span> <span >=</span> <span style="color: blue;">'active'</span> <span style="font-weight:bold;">OR</span> <span style="font-weight:bold;">status</span> <span >=</span> <span style="color: blue;">'pending'</span> <span style="font-weight:bold;">THEN</span>
1225+
<span style="color: blue;">'normal'</span>
1226+
<span style="font-weight:bold;">ELSE</span>
1227+
<span style="color: blue;">'low'</span>
1228+
<span style="font-weight:bold;">END</span> <span style="font-weight:bold;">AS</span> <span style="color: #333;">task_priority</span>
1229+
<span style="font-weight:bold;">FROM</span>
1230+
<span style="color: #333;">tasks</span><span >;</span></pre>

tests/format.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,3 +1215,14 @@ BEGIN
12151215
RETURN id;
12161216
END IF;
12171217
END;
1218+
---
1219+
SELECT
1220+
CASE WHEN status = 'active' AND priority = 'high' THEN
1221+
'urgent'
1222+
WHEN status = 'active' OR status = 'pending' THEN
1223+
'normal'
1224+
ELSE
1225+
'low'
1226+
END AS task_priority
1227+
FROM
1228+
tasks;

tests/highlight.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,3 +427,5 @@
427427
<pre style="color: black; background-color: white;"><span style="font-weight:bold;">CREATE</span> <span style="font-weight:bold;">TABLE</span> <span style="color: #333;">t</span> (<span style="color: #333;">c</span> <span style="font-weight:bold;">VARCHAR</span>(<span style="color: green;">20</span>)) <span style="font-weight:bold;">DEFAULT</span> <span style="font-weight:bold;">CHARACTER</span> <span style="font-weight:bold;">SET</span> <span style="color: #333;">utf8mb4</span> <span style="font-weight:bold;">ENGINE</span> <span >=</span> <span style="color: #333;">InnoDB</span></pre>
428428
---
429429
<pre style="color: black; background-color: white;"><span style="font-weight:bold;">BEGIN</span> <span style="font-weight:bold;">IF</span> <span style="color: #333;">first_name</span> <span >!</span><span >=</span> <span style="color: blue;">''</span> <span style="font-weight:bold;">AND</span> <span style="color: #333;">last_name</span> <span >!</span><span >=</span> <span style="color: blue;">''</span> <span style="font-weight:bold;">THEN</span> <span style="font-weight:bold;">RETURN</span> <span style="font-weight:bold;">CONCAT</span>(<span style="color: #333;">first_name</span><span >,</span> <span style="color: blue;">' '</span><span >,</span> <span style="color: #333;">last_name</span>)<span >;</span> <span style="font-weight:bold;">ELSEIF</span> <span style="color: #333;">first_name</span> <span >!</span><span >=</span> <span style="color: blue;">''</span> <span style="font-weight:bold;">THEN</span> <span style="font-weight:bold;">RETURN</span> <span style="color: #333;">first_name</span><span >;</span> <span style="font-weight:bold;">ELSIF</span> <span style="color: #333;">last_name</span> <span >!</span><span >=</span> <span style="color: blue;">''</span> <span style="font-weight:bold;">THEN</span> <span style="font-weight:bold;">RETURN</span> <span style="color: #333;">last_name</span><span >;</span> <span style="font-weight:bold;">ELSE</span> <span style="font-weight:bold;">RETURN</span> <span style="color: #333;">id</span><span >;</span> <span style="font-weight:bold;">END</span> <span style="font-weight:bold;">IF</span><span >;</span> <span style="font-weight:bold;">END</span><span >;</span></pre>
430+
---
431+
<pre style="color: black; background-color: white;"><span style="font-weight:bold;">SELECT</span> <span style="font-weight:bold;">CASE</span> <span style="font-weight:bold;">WHEN</span> <span style="font-weight:bold;">status</span> <span >=</span> <span style="color: blue;">'active'</span> <span style="font-weight:bold;">AND</span> <span style="color: #333;">priority</span> <span >=</span> <span style="color: blue;">'high'</span> <span style="font-weight:bold;">THEN</span> <span style="color: blue;">'urgent'</span> <span style="font-weight:bold;">WHEN</span> <span style="font-weight:bold;">status</span> <span >=</span> <span style="color: blue;">'active'</span> <span style="font-weight:bold;">OR</span> <span style="font-weight:bold;">status</span> <span >=</span> <span style="color: blue;">'pending'</span> <span style="font-weight:bold;">THEN</span> <span style="color: blue;">'normal'</span> <span style="font-weight:bold;">ELSE</span> <span style="color: blue;">'low'</span> <span style="font-weight:bold;">END</span> <span style="font-weight:bold;">AS</span> <span style="color: #333;">task_priority</span> <span style="font-weight:bold;">FROM</span> <span style="color: #333;">tasks</span><span >;</span></pre>

tests/sql.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,3 +427,5 @@ WHERE t.start = t.end
427427
CREATE TABLE t (c VARCHAR(20)) DEFAULT CHARACTER SET utf8mb4 ENGINE = InnoDB
428428
---
429429
BEGIN IF first_name != '' AND last_name != '' THEN RETURN CONCAT(first_name, ' ', last_name); ELSEIF first_name != '' THEN RETURN first_name; ELSIF last_name != '' THEN RETURN last_name; ELSE RETURN id; END IF; END;
430+
---
431+
SELECT CASE WHEN status = 'active' AND priority = 'high' THEN 'urgent' WHEN status = 'active' OR status = 'pending' THEN 'normal' ELSE 'low' END AS task_priority FROM tasks;

0 commit comments

Comments
 (0)