From ab51a47f7d1372ed104604b771c9f84693e471d8 Mon Sep 17 00:00:00 2001 From: Joel Mukuthu Date: Fri, 25 Sep 2026 18:20:52 +0200 Subject: [PATCH 1/2] Break long WHEN/THEN/ELSE clauses into separate lines --- src/syntax/expr.ts | 17 ++++++++-- test/expr/expr.test.ts | 73 ++++++++++++++++++++++++++++++++++++++++++ test/proc/case.test.ts | 17 ++++++++++ 3 files changed, 104 insertions(+), 3 deletions(-) diff --git a/src/syntax/expr.ts b/src/syntax/expr.ts index 7c93c26..cd84c54 100644 --- a/src/syntax/expr.ts +++ b/src/syntax/expr.ts @@ -124,11 +124,22 @@ export const exprMap: CstToDocMap = { case_when: (print, node) => { if (isProgram(node.result)) { return [ - print.spaced(["whenKw", "condition", "thenKw"]), + group([ + group([print("whenKw"), indent([line, print("condition")])]), + line, + print("thenKw"), + ]), indent([hardline, stripTrailingHardline(print("result"))]), ]; } - return print.spaced(["whenKw", "condition", "thenKw", "result"]); + return group([ + group([ + group([print("whenKw"), indent([line, print("condition")])]), + line, + print("thenKw"), + ]), + indent([line, print("result")]), + ]); }, case_else: (print, node) => { if (isProgram(node.result)) { @@ -137,7 +148,7 @@ export const exprMap: CstToDocMap = { indent([hardline, stripTrailingHardline(print("result"))]), ]; } - return print.spaced(["elseKw", "result"]); + return group([print("elseKw"), indent([line, print("result")])]); }, member_expr: (print, node) => isArraySubscript(node.property) diff --git a/test/expr/expr.test.ts b/test/expr/expr.test.ts index 59865b6..cd09910 100644 --- a/test/expr/expr.test.ts +++ b/test/expr/expr.test.ts @@ -192,6 +192,79 @@ describe("expr", () => { END `); }); + + it(`breaks long WHEN/THEN into separate lines`, async () => { + await test( + dedent` + SELECT + CASE + WHEN column_name = 1 THEN + result_name + END + `, + { printWidth: 40 }, + ); + }); + + it(`breaks multiple long WHEN/THEN clauses without blank lines between them`, async () => { + await test( + dedent` + SELECT + CASE + WHEN column_name = 1 THEN + result_name + WHEN column_name = 2 THEN + other_result + ELSE foo + END + `, + { printWidth: 40 }, + ); + }); + + it(`breaks long ELSE into separate lines`, async () => { + await test( + dedent` + SELECT + CASE + WHEN x = 1 THEN 'A' + ELSE + long_fallback_expression + END + `, + { printWidth: 25 }, + ); + }); + + it(`indents long multi-condition WHEN clauses`, async () => { + await test( + dedent` + SELECT + CASE + WHEN + column_name = 1 + AND (other_name = 2 OR other_name = 3) + THEN + result_name + END + `, + { printWidth: 50 }, + ); + }); + + it(`indents long multi-expression THEN clauses`, async () => { + await test( + dedent` + SELECT + CASE + WHEN column_name = 1 THEN + result_name = 1 + AND other_name = 2 + END + `, + { printWidth: 45 }, + ); + }); }); it(`formats quantifier expressions`, async () => { diff --git a/test/proc/case.test.ts b/test/proc/case.test.ts index 68999a7..50de79b 100644 --- a/test/proc/case.test.ts +++ b/test/proc/case.test.ts @@ -12,4 +12,21 @@ describe("case", () => { END CASE `); }); + + it(`breaks long WHEN/THEN clauses into separate lines`, async () => { + await testBigquery( + dedent` + CASE foo + WHEN + column_name = 1 + AND (other_name = 2 OR other_name = 3) + THEN + SELECT CONCAT('Product one'); + ELSE + SELECT CONCAT('Invalid product'); + END CASE + `, + { printWidth: 50 }, + ); + }); }); From 95b444a4d2bdee9e72945f2dfb103d4b9d7e0189 Mon Sep 17 00:00:00 2001 From: Joel Mukuthu Date: Mon, 28 Sep 2026 08:10:28 +0200 Subject: [PATCH 2/2] Remove code duplication --- src/syntax/expr.ts | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/syntax/expr.ts b/src/syntax/expr.ts index cd84c54..7fc7c0f 100644 --- a/src/syntax/expr.ts +++ b/src/syntax/expr.ts @@ -122,24 +122,18 @@ export const exprMap: CstToDocMap = { print("endKw"), ], case_when: (print, node) => { + const whenThen = group([ + group([print("whenKw"), indent([line, print("condition")])]), + line, + print("thenKw"), + ]); if (isProgram(node.result)) { return [ - group([ - group([print("whenKw"), indent([line, print("condition")])]), - line, - print("thenKw"), - ]), + whenThen, indent([hardline, stripTrailingHardline(print("result"))]), ]; } - return group([ - group([ - group([print("whenKw"), indent([line, print("condition")])]), - line, - print("thenKw"), - ]), - indent([line, print("result")]), - ]); + return group([whenThen, indent([line, print("result")])]); }, case_else: (print, node) => { if (isProgram(node.result)) {