Skip to content

Commit d2702cb

Browse files
committed
fix: AND/OR newline behavior within IF conditions
- Add context tracking to detect when inside IF conditions - Skip newlines for AND/OR tokens within IF conditions while preserving newline behavior for AND/OR in WHERE clauses and other contexts - This improves readability of formatted SQL with complex IF statements
1 parent 11292b0 commit d2702cb

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

src/SqlFormatter.php

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

7071
$appendNewLineIfNotAddedFx = static function () use (&$addedNewline, &$return, $tab, &$indentLevel): void {
7172
// Add a newline if not already added
@@ -301,8 +302,8 @@ public function format(string $string, string $indentString = ' '): string
301302
$newline = true;
302303
$increaseBlockIndent = true;
303304
}
304-
} elseif (in_array($tokenValueUpper, ['WHEN', 'THEN', 'ELSE', 'ELSEIF', 'END'], true)) {
305-
if ($tokenValueUpper !== 'THEN') {
305+
} elseif (in_array($tokenValueUpper, ['IF', 'WHEN', 'THEN', 'ELSE', 'ELSEIF', 'END'], true)) {
306+
if ($tokenValueUpper !== 'THEN' && $tokenValueUpper !== 'IF') {
306307
$decreaseIndentationLevelFx();
307308

308309
if ($prevNotWhitespaceToken !== null && strtoupper($prevNotWhitespaceToken->value()) !== 'CASE') {
@@ -314,6 +315,20 @@ public function format(string $string, string $indentString = ' '): string
314315
$newline = true;
315316
$increaseBlockIndent = true;
316317
}
318+
319+
// Track IF condition context only for IF/ELSEIF that are part of conditional blocks
320+
// (not for "IF()" function calls)
321+
if ($tokenValueUpper === 'IF' || $tokenValueUpper === 'ELSEIF') {
322+
// Check if this IF is part of a conditional block by looking at the next token
323+
$nextToken = $cursor->subCursor()->next(Token::TOKEN_TYPE_WHITESPACE);
324+
if (
325+
$nextToken !== null && $nextToken->value() !== '('
326+
) {
327+
$inIfCondition = true;
328+
}
329+
} elseif ($tokenValueUpper === 'THEN' || $tokenValueUpper === 'ELSE' || $tokenValueUpper === 'END') {
330+
$inIfCondition = false;
331+
}
317332
} elseif (
318333
$clauseLimit &&
319334
$token->value() !== ',' &&
@@ -332,9 +347,12 @@ public function format(string $string, string $indentString = ' '): string
332347
$newline = true;
333348
}
334349
} elseif ($token->isOfType(Token::TOKEN_TYPE_RESERVED_NEWLINE)) {
335-
// Newline reserved words start a new line
350+
// Newline reserved words start a new line, except for AND/OR within IF conditions
336351

337-
$appendNewLineIfNotAddedFx();
352+
// Skip newlines for AND/OR when inside IF condition
353+
if (! $inIfCondition || ! in_array($tokenValueUpper, ['AND', 'OR'], true)) {
354+
$appendNewLineIfNotAddedFx();
355+
}
338356

339357
if ($token->hasExtraWhitespace()) {
340358
$highlighted = preg_replace('/\s+/', ' ', $highlighted);

tests/SqlFormatterTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,5 +175,4 @@ public static function highlightData(): Generator
175175
{
176176
return self::fileDataProvider('highlight.html');
177177
}
178-
179178
}

0 commit comments

Comments
 (0)