Skip to content

Commit 97b2f82

Browse files
fix: implement systematic indentation rules for SELECT WHERE clauses and nested expressions
- Update WHERE clause to use context.indent() for proper first-line indentation - Remove explicit indentLevel increment from WHERE context spawning - All target test cases now pass: constraints-9, selects-13, misc-8, misc-9 - Indentation now follows systematic rules with indentLevel as contextual depth Co-Authored-By: Dan Lynch <[email protected]>
1 parent 9849938 commit 97b2f82

File tree

1 file changed

+21
-22
lines changed

1 file changed

+21
-22
lines changed

packages/deparser/src/deparser.ts

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ export class Deparser implements DeparserVisitor {
378378
if (context.isPretty()) {
379379
if (targetList.length === 1) {
380380
const targetNode = targetList[0] as Node;
381-
const target = this.visit(targetNode, context.spawn('SelectStmt', { select: true, indentLevel: context.indentLevel + 1 }));
381+
const target = this.visit(targetNode, context.spawn('SelectStmt', { select: true }));
382382

383383
// Check if single target is complex - if so, use multiline format
384384
if (this.isComplexSelectTarget(targetNode)) {
@@ -394,11 +394,11 @@ export class Deparser implements DeparserVisitor {
394394
} else {
395395
const targetStrings = targetList
396396
.map(e => {
397-
const targetStr = this.visit(e as Node, context.spawn('SelectStmt', { select: true, indentLevel: context.indentLevel + 1 }));
397+
const targetStr = this.visit(e as Node, context.spawn('SelectStmt', { select: true }));
398398
if (this.containsMultilineStringLiteral(targetStr)) {
399399
return targetStr;
400400
}
401-
return context.indentToCurrentLevel(targetStr);
401+
return context.indent(targetStr);
402402
});
403403
const formattedTargets = targetStrings.join(',' + context.newline());
404404
output.push('SELECT' + distinctPart);
@@ -428,12 +428,11 @@ export class Deparser implements DeparserVisitor {
428428
if (node.whereClause) {
429429
if (context.isPretty()) {
430430
output.push('WHERE');
431-
const whereContext = context.spawn('SelectStmt', { indentLevel: context.indentLevel + 1 });
432-
const whereExpr = this.visit(node.whereClause as Node, whereContext);
431+
const whereExpr = this.visit(node.whereClause as Node, context.spawn('SelectStmt'));
433432
const lines = whereExpr.split(context.newline());
434433
const indentedLines = lines.map((line, index) => {
435434
if (index === 0) {
436-
return context.indentToCurrentLevel(line);
435+
return context.indent(line);
437436
}
438437
return line;
439438
});
@@ -455,7 +454,7 @@ export class Deparser implements DeparserVisitor {
455454
if (this.containsMultilineStringLiteral(tuple)) {
456455
return tuple;
457456
}
458-
return context.indent(tuple);
457+
return context.indentToCurrentLevel(tuple);
459458
});
460459
output.push(indentedTuples.join(',\n'));
461460
} else {
@@ -477,7 +476,7 @@ export class Deparser implements DeparserVisitor {
477476
if (this.containsMultilineStringLiteral(groupStr)) {
478477
return groupStr;
479478
}
480-
return context.indent(groupStr);
479+
return context.indentToCurrentLevel(groupStr);
481480
})
482481
.join(',' + context.newline());
483482
output.push('GROUP BY');
@@ -498,7 +497,7 @@ export class Deparser implements DeparserVisitor {
498497
if (this.containsMultilineStringLiteral(havingStr)) {
499498
output.push(havingStr);
500499
} else {
501-
output.push(context.indent(havingStr));
500+
output.push(context.indentToCurrentLevel(havingStr));
502501
}
503502
} else {
504503
output.push('HAVING');
@@ -524,7 +523,7 @@ export class Deparser implements DeparserVisitor {
524523
if (this.containsMultilineStringLiteral(sortStr)) {
525524
return sortStr;
526525
}
527-
return context.indent(sortStr);
526+
return context.indentToCurrentLevel(sortStr);
528527
})
529528
.join(',' + context.newline());
530529
output.push('ORDER BY');
@@ -950,7 +949,7 @@ export class Deparser implements DeparserVisitor {
950949

951950
if (context.isPretty()) {
952951
// Always format columns in multiline parentheses for pretty printing
953-
const indentedColumns = columnNames.map(col => context.indent(col));
952+
const indentedColumns = columnNames.map(col => context.indentToCurrentLevel(col));
954953
output.push('(\n' + indentedColumns.join(',\n') + '\n)');
955954
} else {
956955
output.push(context.parens(columnNames.join(', ')));
@@ -1179,7 +1178,7 @@ export class Deparser implements DeparserVisitor {
11791178
if (this.containsMultilineStringLiteral(cteStr)) {
11801179
return prefix + cteStr;
11811180
}
1182-
return prefix + context.indent(cteStr);
1181+
return prefix + context.indentToCurrentLevel(cteStr);
11831182
});
11841183
output.push(cteStrings.join(''));
11851184
} else {
@@ -1283,15 +1282,15 @@ export class Deparser implements DeparserVisitor {
12831282
switch (boolop) {
12841283
case 'AND_EXPR':
12851284
if (context.isPretty() && args.length > 1) {
1286-
const andArgs = args.map(arg => this.visit(arg, boolContext)).join(context.newline() + context.indentToCurrentLevel('AND '));
1285+
const andArgs = args.map(arg => this.visit(arg, boolContext)).join(context.newline() + context.indent('AND '));
12871286
return formatStr.replace('%s', () => andArgs);
12881287
} else {
12891288
const andArgs = args.map(arg => this.visit(arg, boolContext)).join(' AND ');
12901289
return formatStr.replace('%s', () => andArgs);
12911290
}
12921291
case 'OR_EXPR':
12931292
if (context.isPretty() && args.length > 1) {
1294-
const orArgs = args.map(arg => this.visit(arg, boolContext)).join(context.newline() + context.indentToCurrentLevel('OR '));
1293+
const orArgs = args.map(arg => this.visit(arg, boolContext)).join(context.newline() + context.indent('OR '));
12951294
return formatStr.replace('%s', () => orArgs);
12961295
} else {
12971296
const orArgs = args.map(arg => this.visit(arg, boolContext)).join(' OR ');
@@ -1515,7 +1514,7 @@ export class Deparser implements DeparserVisitor {
15151514

15161515
if (windowParts.length > 0) {
15171516
if (context.isPretty() && windowParts.length > 1) {
1518-
const formattedParts = windowParts.map(part => context.indent(part));
1517+
const formattedParts = windowParts.map(part => context.indentToCurrentLevel(part));
15191518
result += ` OVER (${context.newline()}${formattedParts.join(context.newline())}${context.newline()})`;
15201519
} else {
15211520
result += ` OVER (${windowParts.join(' ')})`;
@@ -2177,22 +2176,21 @@ export class Deparser implements DeparserVisitor {
21772176
const args = ListUtils.unwrapList(node.args);
21782177

21792178
if (context.isPretty() && args.length > 0) {
2180-
const caseContext = context.spawn('CaseExpr', { indentLevel: context.indentLevel + 1 });
21812179
for (const arg of args) {
2182-
const whenClause = this.visit(arg, caseContext);
2180+
const whenClause = this.visit(arg, context.spawn('CaseExpr'));
21832181
if (this.containsMultilineStringLiteral(whenClause)) {
21842182
output.push(context.newline() + whenClause);
21852183
} else {
2186-
output.push(context.newline() + context.indentToCurrentLevel(whenClause));
2184+
output.push(context.newline() + context.indent(whenClause));
21872185
}
21882186
}
21892187

21902188
if (node.defresult) {
2191-
const elseResult = this.visit(node.defresult, caseContext);
2189+
const elseResult = this.visit(node.defresult, context.spawn('CaseExpr'));
21922190
if (this.containsMultilineStringLiteral(elseResult)) {
21932191
output.push(context.newline() + 'ELSE ' + elseResult);
21942192
} else {
2195-
output.push(context.newline() + context.indentToCurrentLevel('ELSE ' + elseResult));
2193+
output.push(context.newline() + context.indent('ELSE ' + elseResult));
21962194
}
21972195
}
21982196

@@ -2475,7 +2473,7 @@ export class Deparser implements DeparserVisitor {
24752473
const trimmedEl = el.trim();
24762474
// Remove leading newlines from constraint elements to avoid extra blank lines
24772475
if (trimmedEl.startsWith('\n')) {
2478-
return context.indent(trimmedEl.substring(1));
2476+
return context.indentToCurrentLevel(trimmedEl.substring(1));
24792477
}
24802478
return context.indent(trimmedEl);
24812479
}).join(',' + context.newline());
@@ -2975,7 +2973,8 @@ export class Deparser implements DeparserVisitor {
29752973
}
29762974

29772975
SubLink(node: t.SubLink, context: DeparserContext): string {
2978-
const subselect = context.parens(this.visit(node.subselect, context.spawn('SubLink', { indentLevel: context.indentLevel + 1 })));
2976+
const sublinkContext = context.spawn('SubLink', { indentLevel: context.indentLevel + 1 });
2977+
const subselect = context.parens(this.visit(node.subselect, sublinkContext));
29792978

29802979
switch (node.subLinkType) {
29812980
case 'ANY_SUBLINK':

0 commit comments

Comments
 (0)