Skip to content

Commit 268f751

Browse files
fix: update formatWindowFrame and deparseOperatorName to accept context parameters
- Update formatWindowFrame method signature to accept DeparserContext parameter - Update deparseOperatorName method signature to accept DeparserContext parameter - Replace all empty context creation with passed context in both methods - Update all call sites to pass properly spawned context instead of creating empty contexts - Ensures consistent context propagation in helper methods that are not actual node types Co-Authored-By: Dan Lynch <[email protected]>
1 parent 0955753 commit 268f751

File tree

1 file changed

+27
-27
lines changed

1 file changed

+27
-27
lines changed

packages/deparser/src/deparser.ts

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -559,14 +559,14 @@ export class Deparser implements DeparserVisitor {
559559
switch (kind) {
560560
case 'AEXPR_OP':
561561
if (lexpr && rexpr) {
562-
const operator = this.deparseOperatorName(name);
562+
const operator = this.deparseOperatorName(name, context);
563563
let leftExpr = this.visit(lexpr, context);
564564
let rightExpr = this.visit(rexpr, context);
565565

566566
// Check if left expression needs parentheses
567567
let leftNeedsParens = false;
568568
if (lexpr && 'A_Expr' in lexpr && lexpr.A_Expr?.kind === 'AEXPR_OP') {
569-
const leftOp = this.deparseOperatorName(ListUtils.unwrapList(lexpr.A_Expr.name));
569+
const leftOp = this.deparseOperatorName(ListUtils.unwrapList(lexpr.A_Expr.name), context);
570570
if (this.needsParentheses(leftOp, operator, 'left')) {
571571
leftNeedsParens = true;
572572
}
@@ -581,7 +581,7 @@ export class Deparser implements DeparserVisitor {
581581
// Check if right expression needs parentheses
582582
let rightNeedsParens = false;
583583
if (rexpr && 'A_Expr' in rexpr && rexpr.A_Expr?.kind === 'AEXPR_OP') {
584-
const rightOp = this.deparseOperatorName(ListUtils.unwrapList(rexpr.A_Expr.name));
584+
const rightOp = this.deparseOperatorName(ListUtils.unwrapList(rexpr.A_Expr.name), context);
585585
if (this.needsParentheses(rightOp, operator, 'right')) {
586586
rightNeedsParens = true;
587587
}
@@ -596,22 +596,22 @@ export class Deparser implements DeparserVisitor {
596596
return this.formatter.format([leftExpr, operator, rightExpr]);
597597
}else if (rexpr) {
598598
return this.formatter.format([
599-
this.deparseOperatorName(name),
599+
this.deparseOperatorName(name, context),
600600
this.visit(rexpr, context)
601601
]);
602602
}
603603
break;
604604
case 'AEXPR_OP_ANY':
605605
return this.formatter.format([
606606
this.visit(lexpr, context),
607-
this.deparseOperatorName(name),
607+
this.deparseOperatorName(name, context),
608608
'ANY',
609609
this.formatter.parens(this.visit(rexpr, context))
610610
]);
611611
case 'AEXPR_OP_ALL':
612612
return this.formatter.format([
613613
this.visit(lexpr, context),
614-
this.deparseOperatorName(name),
614+
this.deparseOperatorName(name, context),
615615
'ALL',
616616
this.formatter.parens(this.visit(rexpr, context))
617617
]);
@@ -660,7 +660,7 @@ export class Deparser implements DeparserVisitor {
660660
].join(', '))
661661
]);
662662
case 'AEXPR_IN':
663-
const inOperator = this.deparseOperatorName(name);
663+
const inOperator = this.deparseOperatorName(name, context);
664664
if (inOperator === '<>' || inOperator === '!=') {
665665
return this.formatter.format([
666666
this.visit(lexpr, context),
@@ -675,7 +675,7 @@ export class Deparser implements DeparserVisitor {
675675
]);
676676
}
677677
case 'AEXPR_LIKE':
678-
const likeOp = this.deparseOperatorName(name);
678+
const likeOp = this.deparseOperatorName(name, context);
679679
if (likeOp === '!~~') {
680680
return this.formatter.format([
681681
this.visit(lexpr, context),
@@ -690,7 +690,7 @@ export class Deparser implements DeparserVisitor {
690690
]);
691691
}
692692
case 'AEXPR_ILIKE':
693-
const ilikeOp = this.deparseOperatorName(name);
693+
const ilikeOp = this.deparseOperatorName(name, context);
694694
if (ilikeOp === '!~~*') {
695695
return this.formatter.format([
696696
this.visit(lexpr, context),
@@ -705,7 +705,7 @@ export class Deparser implements DeparserVisitor {
705705
]);
706706
}
707707
case 'AEXPR_SIMILAR':
708-
const similarOp = this.deparseOperatorName(name);
708+
const similarOp = this.deparseOperatorName(name, context);
709709
let rightExpr: string;
710710

711711
if (rexpr && 'FuncCall' in rexpr &&
@@ -763,7 +763,7 @@ export class Deparser implements DeparserVisitor {
763763
throw new Error(`Unhandled A_Expr kind: ${kind}`);
764764
}
765765

766-
deparseOperatorName(name: t.Node[]): string {
766+
deparseOperatorName(name: t.Node[], context: DeparserContext): string {
767767
if (!name || name.length === 0) {
768768
return '';
769769
}
@@ -772,7 +772,7 @@ export class Deparser implements DeparserVisitor {
772772
if (n.String) {
773773
return n.String.sval || n.String.str;
774774
}
775-
return this.visit(n, new DeparserContext({}));
775+
return this.visit(n, context);
776776
});
777777

778778
if (parts.length > 1) {
@@ -1420,7 +1420,7 @@ export class Deparser implements DeparserVisitor {
14201420

14211421
// Add parentheses around timestamp if it contains arithmetic operations
14221422
if (args[1] && 'A_Expr' in args[1] && args[1].A_Expr?.kind === 'AEXPR_OP') {
1423-
const op = this.deparseOperatorName(ListUtils.unwrapList(args[1].A_Expr.name));
1423+
const op = this.deparseOperatorName(ListUtils.unwrapList(args[1].A_Expr.name), context);
14241424
if (op === '+' || op === '-' || op === '*' || op === '/') {
14251425
timestamp = this.formatter.parens(timestamp);
14261426
}
@@ -1497,7 +1497,7 @@ export class Deparser implements DeparserVisitor {
14971497
}
14981498

14991499
// Handle window frame specifications using the dedicated formatWindowFrame method
1500-
const frameClause = this.formatWindowFrame(node.over);
1500+
const frameClause = this.formatWindowFrame(node.over, context.spawn('FuncCall'));
15011501
if (frameClause) {
15021502
windowParts.push(frameClause);
15031503
}
@@ -2969,7 +2969,7 @@ export class Deparser implements DeparserVisitor {
29692969
case 'ANY_SUBLINK':
29702970
if (node.testexpr && node.operName) {
29712971
const testExpr = this.visit(node.testexpr, context);
2972-
const operator = this.deparseOperatorName(node.operName);
2972+
const operator = this.deparseOperatorName(node.operName, context);
29732973
return `${testExpr} ${operator} ANY ${subselect}`;
29742974
} else if (node.testexpr) {
29752975
const testExpr = this.visit(node.testexpr, context);
@@ -2979,7 +2979,7 @@ export class Deparser implements DeparserVisitor {
29792979
case 'ALL_SUBLINK':
29802980
if (node.testexpr && node.operName) {
29812981
const testExpr = this.visit(node.testexpr, context);
2982-
const operator = this.deparseOperatorName(node.operName);
2982+
const operator = this.deparseOperatorName(node.operName, context);
29832983
return `${testExpr} ${operator} ALL ${subselect}`;
29842984
}
29852985
return subselect;
@@ -3032,7 +3032,7 @@ export class Deparser implements DeparserVisitor {
30323032

30333033
// Only add frame clause if frameOptions indicates non-default framing
30343034
if (node.frameOptions && node.frameOptions !== 1058) {
3035-
const frameClause = this.formatWindowFrame(node);
3035+
const frameClause = this.formatWindowFrame(node, context.spawn('WindowDef'));
30363036
if (frameClause) {
30373037
windowParts.push(frameClause);
30383038
}
@@ -3053,7 +3053,7 @@ export class Deparser implements DeparserVisitor {
30533053
return output.join(' ');
30543054
}
30553055

3056-
formatWindowFrame(node: any): string | null {
3056+
formatWindowFrame(node: any, context: DeparserContext): string | null {
30573057
if (!node.frameOptions) return null;
30583058

30593059
const frameOptions = node.frameOptions;
@@ -3082,28 +3082,28 @@ export class Deparser implements DeparserVisitor {
30823082
boundsParts.push('AND CURRENT ROW');
30833083
} else if (frameOptions === 18453) {
30843084
if (node.startOffset && node.endOffset) {
3085-
boundsParts.push(`${this.visit(node.startOffset, new DeparserContext({}))} PRECEDING`);
3086-
boundsParts.push(`AND ${this.visit(node.endOffset, new DeparserContext({}))} FOLLOWING`);
3085+
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
3086+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
30873087
}
30883088
} else if (frameOptions === 1557) {
30893089
boundsParts.push('CURRENT ROW');
30903090
boundsParts.push('AND CURRENT ROW');
30913091
} else if (frameOptions === 16917) {
30923092
boundsParts.push('CURRENT ROW');
30933093
if (node.endOffset) {
3094-
boundsParts.push(`AND ${this.visit(node.endOffset, new DeparserContext({}))} FOLLOWING`);
3094+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
30953095
}
30963096
} else if (frameOptions === 1058) {
30973097
return null;
30983098
} else {
30993099
// Handle start bound - prioritize explicit offset values over bit flags
31003100
if (node.startOffset) {
31013101
if (frameOptions & 0x400) { // FRAMEOPTION_START_VALUE_PRECEDING
3102-
boundsParts.push(`${this.visit(node.startOffset, new DeparserContext({}))} PRECEDING`);
3102+
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
31033103
} else if (frameOptions & 0x800) { // FRAMEOPTION_START_VALUE_FOLLOWING
3104-
boundsParts.push(`${this.visit(node.startOffset, new DeparserContext({}))} FOLLOWING`);
3104+
boundsParts.push(`${this.visit(node.startOffset, context)} FOLLOWING`);
31053105
} else {
3106-
boundsParts.push(`${this.visit(node.startOffset, new DeparserContext({}))} PRECEDING`);
3106+
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
31073107
}
31083108
} else if (frameOptions & 0x10) { // FRAMEOPTION_START_UNBOUNDED_PRECEDING
31093109
boundsParts.push('UNBOUNDED PRECEDING');
@@ -3115,11 +3115,11 @@ export class Deparser implements DeparserVisitor {
31153115
if (node.endOffset) {
31163116
if (boundsParts.length > 0) {
31173117
if (frameOptions & 0x1000) { // FRAMEOPTION_END_VALUE_PRECEDING
3118-
boundsParts.push(`AND ${this.visit(node.endOffset, new DeparserContext({}))} PRECEDING`);
3118+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} PRECEDING`);
31193119
} else if (frameOptions & 0x2000) { // FRAMEOPTION_END_VALUE_FOLLOWING
3120-
boundsParts.push(`AND ${this.visit(node.endOffset, new DeparserContext({}))} FOLLOWING`);
3120+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
31213121
} else {
3122-
boundsParts.push(`AND ${this.visit(node.endOffset, new DeparserContext({}))} FOLLOWING`);
3122+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
31233123
}
31243124
}
31253125
} else if (frameOptions & 0x80) { // FRAMEOPTION_END_UNBOUNDED_FOLLOWING

0 commit comments

Comments
 (0)