pgsql-deparser 17.8.2 → 17.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/deparser.d.ts +2 -3
- package/deparser.js +304 -304
- package/esm/deparser.js +304 -304
- package/esm/visitors/base.js +87 -0
- package/package.json +11 -4
- package/visitors/base.d.ts +48 -2
- package/visitors/base.js +89 -1
- package/esm/utils/index.js +0 -90
- package/esm/utils/statement-splitter.js +0 -125
- package/utils/index.d.ts +0 -4
- package/utils/index.js +0 -97
- package/utils/statement-splitter.d.ts +0 -38
- package/utils/statement-splitter.js +0 -131
package/deparser.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Deparser = void 0;
|
|
4
|
+
const base_1 = require("./visitors/base");
|
|
4
5
|
const sql_formatter_1 = require("./utils/sql-formatter");
|
|
5
6
|
const quote_utils_1 = require("./utils/quote-utils");
|
|
6
7
|
const list_utils_1 = require("./utils/list-utils");
|
|
@@ -103,11 +104,9 @@ function isWrappedParseResult(obj) {
|
|
|
103
104
|
* compatibility and wraps them internally for consistent processing.
|
|
104
105
|
*/
|
|
105
106
|
class Deparser {
|
|
106
|
-
formatter;
|
|
107
107
|
tree;
|
|
108
108
|
options;
|
|
109
109
|
constructor(tree, opts = {}) {
|
|
110
|
-
this.formatter = new sql_formatter_1.SqlFormatter(opts.newline, opts.tab, opts.pretty);
|
|
111
110
|
// Set default options
|
|
112
111
|
this.options = {
|
|
113
112
|
functionDelimiter: '$$',
|
|
@@ -144,15 +143,17 @@ class Deparser {
|
|
|
144
143
|
return new Deparser(query, opts).deparseQuery();
|
|
145
144
|
}
|
|
146
145
|
deparseQuery() {
|
|
146
|
+
const formatter = new sql_formatter_1.SqlFormatter(this.options.newline, this.options.tab, this.options.pretty);
|
|
147
|
+
const context = new base_1.DeparserContext({ formatter, prettyMode: this.options.pretty });
|
|
147
148
|
return this.tree
|
|
148
149
|
.map(node => {
|
|
149
150
|
// All nodes should go through the standard deparse method
|
|
150
151
|
// which will route to the appropriate handler
|
|
151
|
-
const result = this.deparse(node);
|
|
152
|
+
const result = this.deparse(node, context);
|
|
152
153
|
return result || '';
|
|
153
154
|
})
|
|
154
155
|
.filter(result => result !== '')
|
|
155
|
-
.join(
|
|
156
|
+
.join(context.newline() + context.newline());
|
|
156
157
|
}
|
|
157
158
|
/**
|
|
158
159
|
* Get the appropriate function delimiter based on the body content
|
|
@@ -166,10 +167,14 @@ class Deparser {
|
|
|
166
167
|
}
|
|
167
168
|
return delimiter;
|
|
168
169
|
}
|
|
169
|
-
deparse(node, context
|
|
170
|
+
deparse(node, context) {
|
|
170
171
|
if (node == null) {
|
|
171
172
|
return null;
|
|
172
173
|
}
|
|
174
|
+
if (!context) {
|
|
175
|
+
const formatter = new sql_formatter_1.SqlFormatter(this.options.newline, this.options.tab, this.options.pretty);
|
|
176
|
+
context = new base_1.DeparserContext({ formatter, prettyMode: this.options.pretty });
|
|
177
|
+
}
|
|
173
178
|
if (typeof node === 'number' || node instanceof Number) {
|
|
174
179
|
return node.toString();
|
|
175
180
|
}
|
|
@@ -181,7 +186,11 @@ class Deparser {
|
|
|
181
186
|
throw new Error(`Error deparsing ${nodeType}: ${error.message}`);
|
|
182
187
|
}
|
|
183
188
|
}
|
|
184
|
-
visit(node, context
|
|
189
|
+
visit(node, context) {
|
|
190
|
+
if (!context) {
|
|
191
|
+
const formatter = new sql_formatter_1.SqlFormatter(this.options.newline, this.options.tab, this.options.pretty);
|
|
192
|
+
context = new base_1.DeparserContext({ formatter, prettyMode: this.options.pretty });
|
|
193
|
+
}
|
|
185
194
|
const nodeType = this.getNodeType(node);
|
|
186
195
|
// Handle empty objects
|
|
187
196
|
if (!nodeType) {
|
|
@@ -190,11 +199,7 @@ class Deparser {
|
|
|
190
199
|
const nodeData = this.getNodeData(node);
|
|
191
200
|
const methodName = nodeType;
|
|
192
201
|
if (typeof this[methodName] === 'function') {
|
|
193
|
-
const
|
|
194
|
-
...context,
|
|
195
|
-
parentNodeTypes: [...context.parentNodeTypes, nodeType]
|
|
196
|
-
};
|
|
197
|
-
const result = this[methodName](nodeData, childContext);
|
|
202
|
+
const result = this[methodName](nodeData, context);
|
|
198
203
|
return result;
|
|
199
204
|
}
|
|
200
205
|
throw new Error(`Deparser does not handle node type: ${nodeType}`);
|
|
@@ -220,7 +225,7 @@ class Deparser {
|
|
|
220
225
|
.filter((rawStmt) => rawStmt != null)
|
|
221
226
|
.map((rawStmt) => this.RawStmt(rawStmt, context))
|
|
222
227
|
.filter((result) => result !== '')
|
|
223
|
-
.join(
|
|
228
|
+
.join(context.newline() + context.newline());
|
|
224
229
|
}
|
|
225
230
|
RawStmt(node, context) {
|
|
226
231
|
if (!node.stmt) {
|
|
@@ -240,7 +245,7 @@ class Deparser {
|
|
|
240
245
|
}
|
|
241
246
|
if (!node.op || node.op === 'SETOP_NONE') {
|
|
242
247
|
if (node.valuesLists == null) {
|
|
243
|
-
if (!
|
|
248
|
+
if (!context.isPretty() || !node.targetList) {
|
|
244
249
|
output.push('SELECT');
|
|
245
250
|
}
|
|
246
251
|
}
|
|
@@ -260,7 +265,7 @@ class Deparser {
|
|
|
260
265
|
node.rarg.limitOffset ||
|
|
261
266
|
node.rarg.withClause);
|
|
262
267
|
if (leftNeedsParens) {
|
|
263
|
-
output.push(
|
|
268
|
+
output.push(context.parens(leftStmt));
|
|
264
269
|
}
|
|
265
270
|
else {
|
|
266
271
|
output.push(leftStmt);
|
|
@@ -282,7 +287,7 @@ class Deparser {
|
|
|
282
287
|
output.push('ALL');
|
|
283
288
|
}
|
|
284
289
|
if (rightNeedsParens) {
|
|
285
|
-
output.push(
|
|
290
|
+
output.push(context.parens(rightStmt));
|
|
286
291
|
}
|
|
287
292
|
else {
|
|
288
293
|
output.push(rightStmt);
|
|
@@ -294,20 +299,20 @@ class Deparser {
|
|
|
294
299
|
const distinctClause = list_utils_1.ListUtils.unwrapList(node.distinctClause);
|
|
295
300
|
if (distinctClause.length > 0 && Object.keys(distinctClause[0]).length > 0) {
|
|
296
301
|
const clause = distinctClause
|
|
297
|
-
.map(e => this.visit(e,
|
|
302
|
+
.map(e => this.visit(e, context.spawn('SelectStmt', { select: true })))
|
|
298
303
|
.join(', ');
|
|
299
|
-
distinctPart = ' DISTINCT ON ' +
|
|
304
|
+
distinctPart = ' DISTINCT ON ' + context.parens(clause);
|
|
300
305
|
}
|
|
301
306
|
else {
|
|
302
307
|
distinctPart = ' DISTINCT';
|
|
303
308
|
}
|
|
304
|
-
if (!
|
|
309
|
+
if (!context.isPretty()) {
|
|
305
310
|
if (distinctClause.length > 0 && Object.keys(distinctClause[0]).length > 0) {
|
|
306
311
|
output.push('DISTINCT ON');
|
|
307
312
|
const clause = distinctClause
|
|
308
|
-
.map(e => this.visit(e,
|
|
313
|
+
.map(e => this.visit(e, context.spawn('SelectStmt', { select: true })))
|
|
309
314
|
.join(', ');
|
|
310
|
-
output.push(
|
|
315
|
+
output.push(context.parens(clause));
|
|
311
316
|
}
|
|
312
317
|
else {
|
|
313
318
|
output.push('DISTINCT');
|
|
@@ -316,10 +321,10 @@ class Deparser {
|
|
|
316
321
|
}
|
|
317
322
|
if (node.targetList) {
|
|
318
323
|
const targetList = list_utils_1.ListUtils.unwrapList(node.targetList);
|
|
319
|
-
if (
|
|
324
|
+
if (context.isPretty()) {
|
|
320
325
|
if (targetList.length === 1) {
|
|
321
326
|
const targetNode = targetList[0];
|
|
322
|
-
const target = this.visit(targetNode,
|
|
327
|
+
const target = this.visit(targetNode, context.spawn('SelectStmt', { select: true }));
|
|
323
328
|
// Check if single target is complex - if so, use multiline format
|
|
324
329
|
if (this.isComplexSelectTarget(targetNode)) {
|
|
325
330
|
output.push('SELECT' + distinctPart);
|
|
@@ -327,7 +332,7 @@ class Deparser {
|
|
|
327
332
|
output.push(target);
|
|
328
333
|
}
|
|
329
334
|
else {
|
|
330
|
-
output.push(
|
|
335
|
+
output.push(context.indent(target));
|
|
331
336
|
}
|
|
332
337
|
}
|
|
333
338
|
else {
|
|
@@ -337,20 +342,20 @@ class Deparser {
|
|
|
337
342
|
else {
|
|
338
343
|
const targetStrings = targetList
|
|
339
344
|
.map(e => {
|
|
340
|
-
const targetStr = this.visit(e,
|
|
345
|
+
const targetStr = this.visit(e, context.spawn('SelectStmt', { select: true }));
|
|
341
346
|
if (this.containsMultilineStringLiteral(targetStr)) {
|
|
342
347
|
return targetStr;
|
|
343
348
|
}
|
|
344
|
-
return
|
|
349
|
+
return context.indent(targetStr);
|
|
345
350
|
});
|
|
346
|
-
const formattedTargets = targetStrings.join(',' +
|
|
351
|
+
const formattedTargets = targetStrings.join(',' + context.newline());
|
|
347
352
|
output.push('SELECT' + distinctPart);
|
|
348
353
|
output.push(formattedTargets);
|
|
349
354
|
}
|
|
350
355
|
}
|
|
351
356
|
else {
|
|
352
357
|
const targets = targetList
|
|
353
|
-
.map(e => this.visit(e,
|
|
358
|
+
.map(e => this.visit(e, context.spawn('SelectStmt', { select: true })))
|
|
354
359
|
.join(', ');
|
|
355
360
|
output.push(targets);
|
|
356
361
|
}
|
|
@@ -362,22 +367,22 @@ class Deparser {
|
|
|
362
367
|
if (node.fromClause) {
|
|
363
368
|
const fromList = list_utils_1.ListUtils.unwrapList(node.fromClause);
|
|
364
369
|
const fromItems = fromList
|
|
365
|
-
.map(e => this.deparse(e,
|
|
370
|
+
.map(e => this.deparse(e, context.spawn('SelectStmt', { from: true })))
|
|
366
371
|
.join(', ');
|
|
367
372
|
output.push('FROM ' + fromItems.trim());
|
|
368
373
|
}
|
|
369
374
|
if (node.whereClause) {
|
|
370
|
-
if (
|
|
375
|
+
if (context.isPretty()) {
|
|
371
376
|
output.push('WHERE');
|
|
372
377
|
const whereExpr = this.visit(node.whereClause, context);
|
|
373
|
-
const lines = whereExpr.split(
|
|
378
|
+
const lines = whereExpr.split(context.newline());
|
|
374
379
|
const indentedLines = lines.map((line, index) => {
|
|
375
380
|
if (index === 0) {
|
|
376
|
-
return
|
|
381
|
+
return context.indent(line);
|
|
377
382
|
}
|
|
378
383
|
return line;
|
|
379
384
|
});
|
|
380
|
-
output.push(indentedLines.join(
|
|
385
|
+
output.push(indentedLines.join(context.newline()));
|
|
381
386
|
}
|
|
382
387
|
else {
|
|
383
388
|
output.push('WHERE');
|
|
@@ -385,17 +390,17 @@ class Deparser {
|
|
|
385
390
|
}
|
|
386
391
|
}
|
|
387
392
|
if (node.valuesLists) {
|
|
388
|
-
if (
|
|
393
|
+
if (context.isPretty()) {
|
|
389
394
|
output.push('VALUES');
|
|
390
395
|
const lists = list_utils_1.ListUtils.unwrapList(node.valuesLists).map(list => {
|
|
391
396
|
const values = list_utils_1.ListUtils.unwrapList(list).map(val => this.visit(val, context));
|
|
392
|
-
return
|
|
397
|
+
return context.parens(values.join(', '));
|
|
393
398
|
});
|
|
394
399
|
const indentedTuples = lists.map(tuple => {
|
|
395
400
|
if (this.containsMultilineStringLiteral(tuple)) {
|
|
396
401
|
return tuple;
|
|
397
402
|
}
|
|
398
|
-
return
|
|
403
|
+
return context.indent(tuple);
|
|
399
404
|
});
|
|
400
405
|
output.push(indentedTuples.join(',\n'));
|
|
401
406
|
}
|
|
@@ -403,43 +408,43 @@ class Deparser {
|
|
|
403
408
|
output.push('VALUES');
|
|
404
409
|
const lists = list_utils_1.ListUtils.unwrapList(node.valuesLists).map(list => {
|
|
405
410
|
const values = list_utils_1.ListUtils.unwrapList(list).map(val => this.visit(val, context));
|
|
406
|
-
return
|
|
411
|
+
return context.parens(values.join(', '));
|
|
407
412
|
});
|
|
408
413
|
output.push(lists.join(', '));
|
|
409
414
|
}
|
|
410
415
|
}
|
|
411
416
|
if (node.groupClause) {
|
|
412
417
|
const groupList = list_utils_1.ListUtils.unwrapList(node.groupClause);
|
|
413
|
-
if (
|
|
418
|
+
if (context.isPretty()) {
|
|
414
419
|
const groupItems = groupList
|
|
415
420
|
.map(e => {
|
|
416
|
-
const groupStr = this.visit(e,
|
|
421
|
+
const groupStr = this.visit(e, context.spawn('SelectStmt', { group: true, indentLevel: context.indentLevel + 1 }));
|
|
417
422
|
if (this.containsMultilineStringLiteral(groupStr)) {
|
|
418
423
|
return groupStr;
|
|
419
424
|
}
|
|
420
|
-
return
|
|
425
|
+
return context.indent(groupStr);
|
|
421
426
|
})
|
|
422
|
-
.join(',' +
|
|
427
|
+
.join(',' + context.newline());
|
|
423
428
|
output.push('GROUP BY');
|
|
424
429
|
output.push(groupItems);
|
|
425
430
|
}
|
|
426
431
|
else {
|
|
427
432
|
output.push('GROUP BY');
|
|
428
433
|
const groupItems = groupList
|
|
429
|
-
.map(e => this.visit(e,
|
|
434
|
+
.map(e => this.visit(e, context.spawn('SelectStmt', { group: true })))
|
|
430
435
|
.join(', ');
|
|
431
436
|
output.push(groupItems);
|
|
432
437
|
}
|
|
433
438
|
}
|
|
434
439
|
if (node.havingClause) {
|
|
435
|
-
if (
|
|
440
|
+
if (context.isPretty()) {
|
|
436
441
|
output.push('HAVING');
|
|
437
442
|
const havingStr = this.visit(node.havingClause, context);
|
|
438
443
|
if (this.containsMultilineStringLiteral(havingStr)) {
|
|
439
444
|
output.push(havingStr);
|
|
440
445
|
}
|
|
441
446
|
else {
|
|
442
|
-
output.push(
|
|
447
|
+
output.push(context.indent(havingStr));
|
|
443
448
|
}
|
|
444
449
|
}
|
|
445
450
|
else {
|
|
@@ -457,23 +462,23 @@ class Deparser {
|
|
|
457
462
|
}
|
|
458
463
|
if (node.sortClause) {
|
|
459
464
|
const sortList = list_utils_1.ListUtils.unwrapList(node.sortClause);
|
|
460
|
-
if (
|
|
465
|
+
if (context.isPretty()) {
|
|
461
466
|
const sortItems = sortList
|
|
462
467
|
.map(e => {
|
|
463
|
-
const sortStr = this.visit(e,
|
|
468
|
+
const sortStr = this.visit(e, context.spawn('SelectStmt', { sort: true, indentLevel: context.indentLevel + 1 }));
|
|
464
469
|
if (this.containsMultilineStringLiteral(sortStr)) {
|
|
465
470
|
return sortStr;
|
|
466
471
|
}
|
|
467
|
-
return
|
|
472
|
+
return context.indent(sortStr);
|
|
468
473
|
})
|
|
469
|
-
.join(',' +
|
|
474
|
+
.join(',' + context.newline());
|
|
470
475
|
output.push('ORDER BY');
|
|
471
476
|
output.push(sortItems);
|
|
472
477
|
}
|
|
473
478
|
else {
|
|
474
479
|
output.push('ORDER BY');
|
|
475
480
|
const sortItems = sortList
|
|
476
|
-
.map(e => this.visit(e,
|
|
481
|
+
.map(e => this.visit(e, context.spawn('SelectStmt', { sort: true })))
|
|
477
482
|
.join(', ');
|
|
478
483
|
output.push(sortItems);
|
|
479
484
|
}
|
|
@@ -491,9 +496,9 @@ class Deparser {
|
|
|
491
496
|
.join(' ');
|
|
492
497
|
output.push(lockingClauses);
|
|
493
498
|
}
|
|
494
|
-
if (
|
|
499
|
+
if (context.isPretty()) {
|
|
495
500
|
const filteredOutput = output.filter(item => item.trim() !== '');
|
|
496
|
-
return filteredOutput.join(
|
|
501
|
+
return filteredOutput.join(context.newline());
|
|
497
502
|
}
|
|
498
503
|
return output.join(' ');
|
|
499
504
|
}
|
|
@@ -505,13 +510,13 @@ class Deparser {
|
|
|
505
510
|
switch (kind) {
|
|
506
511
|
case 'AEXPR_OP':
|
|
507
512
|
if (lexpr && rexpr) {
|
|
508
|
-
const operator = this.deparseOperatorName(name);
|
|
513
|
+
const operator = this.deparseOperatorName(name, context);
|
|
509
514
|
let leftExpr = this.visit(lexpr, context);
|
|
510
515
|
let rightExpr = this.visit(rexpr, context);
|
|
511
516
|
// Check if left expression needs parentheses
|
|
512
517
|
let leftNeedsParens = false;
|
|
513
518
|
if (lexpr && 'A_Expr' in lexpr && lexpr.A_Expr?.kind === 'AEXPR_OP') {
|
|
514
|
-
const leftOp = this.deparseOperatorName(list_utils_1.ListUtils.unwrapList(lexpr.A_Expr.name));
|
|
519
|
+
const leftOp = this.deparseOperatorName(list_utils_1.ListUtils.unwrapList(lexpr.A_Expr.name), context);
|
|
515
520
|
if (this.needsParentheses(leftOp, operator, 'left')) {
|
|
516
521
|
leftNeedsParens = true;
|
|
517
522
|
}
|
|
@@ -520,12 +525,12 @@ class Deparser {
|
|
|
520
525
|
leftNeedsParens = true;
|
|
521
526
|
}
|
|
522
527
|
if (leftNeedsParens) {
|
|
523
|
-
leftExpr =
|
|
528
|
+
leftExpr = context.parens(leftExpr);
|
|
524
529
|
}
|
|
525
530
|
// Check if right expression needs parentheses
|
|
526
531
|
let rightNeedsParens = false;
|
|
527
532
|
if (rexpr && 'A_Expr' in rexpr && rexpr.A_Expr?.kind === 'AEXPR_OP') {
|
|
528
|
-
const rightOp = this.deparseOperatorName(list_utils_1.ListUtils.unwrapList(rexpr.A_Expr.name));
|
|
533
|
+
const rightOp = this.deparseOperatorName(list_utils_1.ListUtils.unwrapList(rexpr.A_Expr.name), context);
|
|
529
534
|
if (this.needsParentheses(rightOp, operator, 'right')) {
|
|
530
535
|
rightNeedsParens = true;
|
|
531
536
|
}
|
|
@@ -534,42 +539,42 @@ class Deparser {
|
|
|
534
539
|
rightNeedsParens = true;
|
|
535
540
|
}
|
|
536
541
|
if (rightNeedsParens) {
|
|
537
|
-
rightExpr =
|
|
542
|
+
rightExpr = context.parens(rightExpr);
|
|
538
543
|
}
|
|
539
|
-
return
|
|
544
|
+
return context.format([leftExpr, operator, rightExpr]);
|
|
540
545
|
}
|
|
541
546
|
else if (rexpr) {
|
|
542
|
-
return
|
|
543
|
-
this.deparseOperatorName(name),
|
|
547
|
+
return context.format([
|
|
548
|
+
this.deparseOperatorName(name, context),
|
|
544
549
|
this.visit(rexpr, context)
|
|
545
550
|
]);
|
|
546
551
|
}
|
|
547
552
|
break;
|
|
548
553
|
case 'AEXPR_OP_ANY':
|
|
549
|
-
return
|
|
554
|
+
return context.format([
|
|
550
555
|
this.visit(lexpr, context),
|
|
551
|
-
this.deparseOperatorName(name),
|
|
556
|
+
this.deparseOperatorName(name, context),
|
|
552
557
|
'ANY',
|
|
553
|
-
|
|
558
|
+
context.parens(this.visit(rexpr, context))
|
|
554
559
|
]);
|
|
555
560
|
case 'AEXPR_OP_ALL':
|
|
556
|
-
return
|
|
561
|
+
return context.format([
|
|
557
562
|
this.visit(lexpr, context),
|
|
558
|
-
this.deparseOperatorName(name),
|
|
563
|
+
this.deparseOperatorName(name, context),
|
|
559
564
|
'ALL',
|
|
560
|
-
|
|
565
|
+
context.parens(this.visit(rexpr, context))
|
|
561
566
|
]);
|
|
562
567
|
case 'AEXPR_DISTINCT': {
|
|
563
568
|
let leftExpr = this.visit(lexpr, context);
|
|
564
569
|
let rightExpr = this.visit(rexpr, context);
|
|
565
570
|
// Add parentheses for complex expressions
|
|
566
571
|
if (lexpr && this.isComplexExpression(lexpr)) {
|
|
567
|
-
leftExpr =
|
|
572
|
+
leftExpr = context.parens(leftExpr);
|
|
568
573
|
}
|
|
569
574
|
if (rexpr && this.isComplexExpression(rexpr)) {
|
|
570
|
-
rightExpr =
|
|
575
|
+
rightExpr = context.parens(rightExpr);
|
|
571
576
|
}
|
|
572
|
-
return
|
|
577
|
+
return context.format([
|
|
573
578
|
leftExpr,
|
|
574
579
|
'IS DISTINCT FROM',
|
|
575
580
|
rightExpr
|
|
@@ -580,75 +585,75 @@ class Deparser {
|
|
|
580
585
|
let rightExpr = this.visit(rexpr, context);
|
|
581
586
|
// Add parentheses for complex expressions
|
|
582
587
|
if (lexpr && this.isComplexExpression(lexpr)) {
|
|
583
|
-
leftExpr =
|
|
588
|
+
leftExpr = context.parens(leftExpr);
|
|
584
589
|
}
|
|
585
590
|
if (rexpr && this.isComplexExpression(rexpr)) {
|
|
586
|
-
rightExpr =
|
|
591
|
+
rightExpr = context.parens(rightExpr);
|
|
587
592
|
}
|
|
588
|
-
return
|
|
593
|
+
return context.format([
|
|
589
594
|
leftExpr,
|
|
590
595
|
'IS NOT DISTINCT FROM',
|
|
591
596
|
rightExpr
|
|
592
597
|
]);
|
|
593
598
|
}
|
|
594
599
|
case 'AEXPR_NULLIF':
|
|
595
|
-
return
|
|
600
|
+
return context.format([
|
|
596
601
|
'NULLIF',
|
|
597
|
-
|
|
602
|
+
context.parens([
|
|
598
603
|
this.visit(lexpr, context),
|
|
599
604
|
this.visit(rexpr, context)
|
|
600
605
|
].join(', '))
|
|
601
606
|
]);
|
|
602
607
|
case 'AEXPR_IN':
|
|
603
|
-
const inOperator = this.deparseOperatorName(name);
|
|
608
|
+
const inOperator = this.deparseOperatorName(name, context);
|
|
604
609
|
if (inOperator === '<>' || inOperator === '!=') {
|
|
605
|
-
return
|
|
610
|
+
return context.format([
|
|
606
611
|
this.visit(lexpr, context),
|
|
607
612
|
'NOT IN',
|
|
608
|
-
|
|
613
|
+
context.parens(this.visit(rexpr, context))
|
|
609
614
|
]);
|
|
610
615
|
}
|
|
611
616
|
else {
|
|
612
|
-
return
|
|
617
|
+
return context.format([
|
|
613
618
|
this.visit(lexpr, context),
|
|
614
619
|
'IN',
|
|
615
|
-
|
|
620
|
+
context.parens(this.visit(rexpr, context))
|
|
616
621
|
]);
|
|
617
622
|
}
|
|
618
623
|
case 'AEXPR_LIKE':
|
|
619
|
-
const likeOp = this.deparseOperatorName(name);
|
|
624
|
+
const likeOp = this.deparseOperatorName(name, context);
|
|
620
625
|
if (likeOp === '!~~') {
|
|
621
|
-
return
|
|
626
|
+
return context.format([
|
|
622
627
|
this.visit(lexpr, context),
|
|
623
628
|
'NOT LIKE',
|
|
624
629
|
this.visit(rexpr, context)
|
|
625
630
|
]);
|
|
626
631
|
}
|
|
627
632
|
else {
|
|
628
|
-
return
|
|
633
|
+
return context.format([
|
|
629
634
|
this.visit(lexpr, context),
|
|
630
635
|
'LIKE',
|
|
631
636
|
this.visit(rexpr, context)
|
|
632
637
|
]);
|
|
633
638
|
}
|
|
634
639
|
case 'AEXPR_ILIKE':
|
|
635
|
-
const ilikeOp = this.deparseOperatorName(name);
|
|
640
|
+
const ilikeOp = this.deparseOperatorName(name, context);
|
|
636
641
|
if (ilikeOp === '!~~*') {
|
|
637
|
-
return
|
|
642
|
+
return context.format([
|
|
638
643
|
this.visit(lexpr, context),
|
|
639
644
|
'NOT ILIKE',
|
|
640
645
|
this.visit(rexpr, context)
|
|
641
646
|
]);
|
|
642
647
|
}
|
|
643
648
|
else {
|
|
644
|
-
return
|
|
649
|
+
return context.format([
|
|
645
650
|
this.visit(lexpr, context),
|
|
646
651
|
'ILIKE',
|
|
647
652
|
this.visit(rexpr, context)
|
|
648
653
|
]);
|
|
649
654
|
}
|
|
650
655
|
case 'AEXPR_SIMILAR':
|
|
651
|
-
const similarOp = this.deparseOperatorName(name);
|
|
656
|
+
const similarOp = this.deparseOperatorName(name, context);
|
|
652
657
|
let rightExpr;
|
|
653
658
|
if (rexpr && 'FuncCall' in rexpr &&
|
|
654
659
|
rexpr.FuncCall?.funcname?.length === 2 &&
|
|
@@ -664,39 +669,39 @@ class Deparser {
|
|
|
664
669
|
rightExpr = this.visit(rexpr, context);
|
|
665
670
|
}
|
|
666
671
|
if (similarOp === '!~') {
|
|
667
|
-
return
|
|
672
|
+
return context.format([
|
|
668
673
|
this.visit(lexpr, context),
|
|
669
674
|
'NOT SIMILAR TO',
|
|
670
675
|
rightExpr
|
|
671
676
|
]);
|
|
672
677
|
}
|
|
673
678
|
else {
|
|
674
|
-
return
|
|
679
|
+
return context.format([
|
|
675
680
|
this.visit(lexpr, context),
|
|
676
681
|
'SIMILAR TO',
|
|
677
682
|
rightExpr
|
|
678
683
|
]);
|
|
679
684
|
}
|
|
680
685
|
case 'AEXPR_BETWEEN':
|
|
681
|
-
return
|
|
686
|
+
return context.format([
|
|
682
687
|
this.visit(lexpr, context),
|
|
683
688
|
'BETWEEN',
|
|
684
689
|
this.visitBetweenRange(rexpr, context)
|
|
685
690
|
]);
|
|
686
691
|
case 'AEXPR_NOT_BETWEEN':
|
|
687
|
-
return
|
|
692
|
+
return context.format([
|
|
688
693
|
this.visit(lexpr, context),
|
|
689
694
|
'NOT BETWEEN',
|
|
690
695
|
this.visitBetweenRange(rexpr, context)
|
|
691
696
|
]);
|
|
692
697
|
case 'AEXPR_BETWEEN_SYM':
|
|
693
|
-
return
|
|
698
|
+
return context.format([
|
|
694
699
|
this.visit(lexpr, context),
|
|
695
700
|
'BETWEEN SYMMETRIC',
|
|
696
701
|
this.visitBetweenRange(rexpr, context)
|
|
697
702
|
]);
|
|
698
703
|
case 'AEXPR_NOT_BETWEEN_SYM':
|
|
699
|
-
return
|
|
704
|
+
return context.format([
|
|
700
705
|
this.visit(lexpr, context),
|
|
701
706
|
'NOT BETWEEN SYMMETRIC',
|
|
702
707
|
this.visitBetweenRange(rexpr, context)
|
|
@@ -704,7 +709,7 @@ class Deparser {
|
|
|
704
709
|
}
|
|
705
710
|
throw new Error(`Unhandled A_Expr kind: ${kind}`);
|
|
706
711
|
}
|
|
707
|
-
deparseOperatorName(name) {
|
|
712
|
+
deparseOperatorName(name, context) {
|
|
708
713
|
if (!name || name.length === 0) {
|
|
709
714
|
return '';
|
|
710
715
|
}
|
|
@@ -712,7 +717,7 @@ class Deparser {
|
|
|
712
717
|
if (n.String) {
|
|
713
718
|
return n.String.sval || n.String.str;
|
|
714
719
|
}
|
|
715
|
-
return this.visit(n,
|
|
720
|
+
return this.visit(n, context);
|
|
716
721
|
});
|
|
717
722
|
if (parts.length > 1) {
|
|
718
723
|
return `OPERATOR(${parts.join('.')})`;
|
|
@@ -849,15 +854,15 @@ class Deparser {
|
|
|
849
854
|
output.push(this.RangeVar(node.relation, context));
|
|
850
855
|
if (node.cols) {
|
|
851
856
|
const cols = list_utils_1.ListUtils.unwrapList(node.cols);
|
|
852
|
-
const insertContext =
|
|
857
|
+
const insertContext = context.spawn('InsertStmt', { insertColumns: true });
|
|
853
858
|
const columnNames = cols.map(col => this.visit(col, insertContext));
|
|
854
|
-
if (
|
|
859
|
+
if (context.isPretty()) {
|
|
855
860
|
// Always format columns in multiline parentheses for pretty printing
|
|
856
|
-
const indentedColumns = columnNames.map(col =>
|
|
861
|
+
const indentedColumns = columnNames.map(col => context.indent(col));
|
|
857
862
|
output.push('(\n' + indentedColumns.join(',\n') + '\n)');
|
|
858
863
|
}
|
|
859
864
|
else {
|
|
860
|
-
output.push(
|
|
865
|
+
output.push(context.parens(columnNames.join(', ')));
|
|
861
866
|
}
|
|
862
867
|
}
|
|
863
868
|
if (node.selectStmt) {
|
|
@@ -879,7 +884,7 @@ class Deparser {
|
|
|
879
884
|
else if (infer.indexElems) {
|
|
880
885
|
const elems = list_utils_1.ListUtils.unwrapList(infer.indexElems);
|
|
881
886
|
const indexElems = elems.map(elem => this.visit(elem, context));
|
|
882
|
-
output.push(
|
|
887
|
+
output.push(context.parens(indexElems.join(', ')));
|
|
883
888
|
}
|
|
884
889
|
// Handle WHERE clause for conflict detection
|
|
885
890
|
if (infer.whereClause) {
|
|
@@ -895,12 +900,12 @@ class Deparser {
|
|
|
895
900
|
if (firstTarget.ResTarget?.val?.MultiAssignRef && targetList.every(target => target.ResTarget?.val?.MultiAssignRef)) {
|
|
896
901
|
const sortedTargets = targetList.sort((a, b) => a.ResTarget.val.MultiAssignRef.colno - b.ResTarget.val.MultiAssignRef.colno);
|
|
897
902
|
const names = sortedTargets.map(target => target.ResTarget.name);
|
|
898
|
-
output.push(
|
|
903
|
+
output.push(context.parens(names.join(', ')));
|
|
899
904
|
output.push('=');
|
|
900
905
|
output.push(this.visit(firstTarget.ResTarget.val.MultiAssignRef.source, context));
|
|
901
906
|
}
|
|
902
907
|
else {
|
|
903
|
-
const updateContext =
|
|
908
|
+
const updateContext = context.spawn('UpdateStmt', { update: true });
|
|
904
909
|
const targets = targetList.map(target => this.visit(target, updateContext));
|
|
905
910
|
output.push(targets.join(', '));
|
|
906
911
|
}
|
|
@@ -954,12 +959,12 @@ class Deparser {
|
|
|
954
959
|
}
|
|
955
960
|
}
|
|
956
961
|
const names = relatedTargets.map(t => t.ResTarget.name);
|
|
957
|
-
const multiAssignment = `${
|
|
962
|
+
const multiAssignment = `${context.parens(names.join(', '))} = ${this.visit(multiAssignRef.source, context)}`;
|
|
958
963
|
assignmentParts.push(multiAssignment);
|
|
959
964
|
}
|
|
960
965
|
else {
|
|
961
966
|
// Handle regular single-column assignment
|
|
962
|
-
assignmentParts.push(this.visit(target,
|
|
967
|
+
assignmentParts.push(this.visit(target, context.spawn('UpdateStmt', { update: true })));
|
|
963
968
|
processedTargets.add(i);
|
|
964
969
|
}
|
|
965
970
|
}
|
|
@@ -1051,14 +1056,14 @@ class Deparser {
|
|
|
1051
1056
|
}
|
|
1052
1057
|
if (node.ctes && node.ctes.length > 0) {
|
|
1053
1058
|
const ctes = list_utils_1.ListUtils.unwrapList(node.ctes);
|
|
1054
|
-
if (
|
|
1059
|
+
if (context.isPretty()) {
|
|
1055
1060
|
const cteStrings = ctes.map((cte, index) => {
|
|
1056
1061
|
const cteStr = this.visit(cte, context);
|
|
1057
|
-
const prefix = index === 0 ?
|
|
1062
|
+
const prefix = index === 0 ? context.newline() : ',' + context.newline();
|
|
1058
1063
|
if (this.containsMultilineStringLiteral(cteStr)) {
|
|
1059
1064
|
return prefix + cteStr;
|
|
1060
1065
|
}
|
|
1061
|
-
return prefix +
|
|
1066
|
+
return prefix + context.indent(cteStr);
|
|
1062
1067
|
});
|
|
1063
1068
|
output.push(cteStrings.join(''));
|
|
1064
1069
|
}
|
|
@@ -1144,14 +1149,14 @@ class Deparser {
|
|
|
1144
1149
|
if (context.bool) {
|
|
1145
1150
|
formatStr = '(%s)';
|
|
1146
1151
|
}
|
|
1147
|
-
const boolContext =
|
|
1152
|
+
const boolContext = context.spawn('BoolExpr', { bool: true });
|
|
1148
1153
|
// explanation of our syntax/fix below:
|
|
1149
1154
|
// return formatStr.replace('%s', andArgs); // ❌ Interprets $ as special syntax
|
|
1150
1155
|
// return formatStr.replace('%s', () => andArgs); // ✅ Function callback prevents interpretation
|
|
1151
1156
|
switch (boolop) {
|
|
1152
1157
|
case 'AND_EXPR':
|
|
1153
|
-
if (
|
|
1154
|
-
const andArgs = args.map(arg => this.visit(arg, boolContext)).join(
|
|
1158
|
+
if (context.isPretty() && args.length > 1) {
|
|
1159
|
+
const andArgs = args.map(arg => this.visit(arg, boolContext)).join(context.newline() + context.indent('AND '));
|
|
1155
1160
|
return formatStr.replace('%s', () => andArgs);
|
|
1156
1161
|
}
|
|
1157
1162
|
else {
|
|
@@ -1159,8 +1164,8 @@ class Deparser {
|
|
|
1159
1164
|
return formatStr.replace('%s', () => andArgs);
|
|
1160
1165
|
}
|
|
1161
1166
|
case 'OR_EXPR':
|
|
1162
|
-
if (
|
|
1163
|
-
const orArgs = args.map(arg => this.visit(arg, boolContext)).join(
|
|
1167
|
+
if (context.isPretty() && args.length > 1) {
|
|
1168
|
+
const orArgs = args.map(arg => this.visit(arg, boolContext)).join(context.newline() + context.indent('OR '));
|
|
1164
1169
|
return formatStr.replace('%s', () => orArgs);
|
|
1165
1170
|
}
|
|
1166
1171
|
else {
|
|
@@ -1291,9 +1296,9 @@ class Deparser {
|
|
|
1291
1296
|
const timezone = this.visit(args[0], context);
|
|
1292
1297
|
// Add parentheses around timestamp if it contains arithmetic operations
|
|
1293
1298
|
if (args[1] && 'A_Expr' in args[1] && args[1].A_Expr?.kind === 'AEXPR_OP') {
|
|
1294
|
-
const op = this.deparseOperatorName(list_utils_1.ListUtils.unwrapList(args[1].A_Expr.name));
|
|
1299
|
+
const op = this.deparseOperatorName(list_utils_1.ListUtils.unwrapList(args[1].A_Expr.name), context);
|
|
1295
1300
|
if (op === '+' || op === '-' || op === '*' || op === '/') {
|
|
1296
|
-
timestamp =
|
|
1301
|
+
timestamp = context.parens(timestamp);
|
|
1297
1302
|
}
|
|
1298
1303
|
}
|
|
1299
1304
|
return `${timestamp} AT TIME ZONE ${timezone}`;
|
|
@@ -1363,14 +1368,14 @@ class Deparser {
|
|
|
1363
1368
|
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
1364
1369
|
}
|
|
1365
1370
|
// Handle window frame specifications using the dedicated formatWindowFrame method
|
|
1366
|
-
const frameClause = this.formatWindowFrame(node.over);
|
|
1371
|
+
const frameClause = this.formatWindowFrame(node.over, context.spawn('FuncCall'));
|
|
1367
1372
|
if (frameClause) {
|
|
1368
1373
|
windowParts.push(frameClause);
|
|
1369
1374
|
}
|
|
1370
1375
|
if (windowParts.length > 0) {
|
|
1371
|
-
if (
|
|
1372
|
-
const formattedParts = windowParts.map(part =>
|
|
1373
|
-
result += ` OVER (${
|
|
1376
|
+
if (context.isPretty() && windowParts.length > 1) {
|
|
1377
|
+
const formattedParts = windowParts.map(part => context.indent(part));
|
|
1378
|
+
result += ` OVER (${context.newline()}${formattedParts.join(context.newline())}${context.newline()})`;
|
|
1374
1379
|
}
|
|
1375
1380
|
else {
|
|
1376
1381
|
result += ` OVER (${windowParts.join(' ')})`;
|
|
@@ -1735,7 +1740,7 @@ class Deparser {
|
|
|
1735
1740
|
}
|
|
1736
1741
|
return this.quoteIfNeeded(colStr);
|
|
1737
1742
|
});
|
|
1738
|
-
output.push('AS', this.quoteIfNeeded(name) +
|
|
1743
|
+
output.push('AS', this.quoteIfNeeded(name) + context.parens(quotedColnames.join(', ')));
|
|
1739
1744
|
}
|
|
1740
1745
|
else {
|
|
1741
1746
|
output.push('AS', this.quoteIfNeeded(name));
|
|
@@ -1747,7 +1752,7 @@ class Deparser {
|
|
|
1747
1752
|
// Handle ONLY keyword for inheritance control (but not for type definitions, ALTER TYPE, or CREATE FOREIGN TABLE)
|
|
1748
1753
|
if (node && (!('inh' in node) || node.inh === undefined) &&
|
|
1749
1754
|
!context.parentNodeTypes.includes('CompositeTypeStmt') &&
|
|
1750
|
-
!context.parentNodeTypes.includes('AlterTypeStmt') &&
|
|
1755
|
+
(!context.parentNodeTypes.includes('AlterTypeStmt') && context.objtype !== 'OBJECT_TYPE') &&
|
|
1751
1756
|
!context.parentNodeTypes.includes('CreateForeignTableStmt')) {
|
|
1752
1757
|
output.push('ONLY');
|
|
1753
1758
|
}
|
|
@@ -2007,26 +2012,26 @@ class Deparser {
|
|
|
2007
2012
|
output.push(this.visit(node.arg, context));
|
|
2008
2013
|
}
|
|
2009
2014
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
2010
|
-
if (
|
|
2015
|
+
if (context.isPretty() && args.length > 0) {
|
|
2011
2016
|
for (const arg of args) {
|
|
2012
2017
|
const whenClause = this.visit(arg, context);
|
|
2013
2018
|
if (this.containsMultilineStringLiteral(whenClause)) {
|
|
2014
|
-
output.push(
|
|
2019
|
+
output.push(context.newline() + whenClause);
|
|
2015
2020
|
}
|
|
2016
2021
|
else {
|
|
2017
|
-
output.push(
|
|
2022
|
+
output.push(context.newline() + context.indent(whenClause));
|
|
2018
2023
|
}
|
|
2019
2024
|
}
|
|
2020
2025
|
if (node.defresult) {
|
|
2021
2026
|
const elseResult = this.visit(node.defresult, context);
|
|
2022
2027
|
if (this.containsMultilineStringLiteral(elseResult)) {
|
|
2023
|
-
output.push(
|
|
2028
|
+
output.push(context.newline() + 'ELSE ' + elseResult);
|
|
2024
2029
|
}
|
|
2025
2030
|
else {
|
|
2026
|
-
output.push(
|
|
2031
|
+
output.push(context.newline() + context.indent('ELSE ' + elseResult));
|
|
2027
2032
|
}
|
|
2028
2033
|
}
|
|
2029
|
-
output.push(
|
|
2034
|
+
output.push(context.newline() + 'END');
|
|
2030
2035
|
return output.join(' ');
|
|
2031
2036
|
}
|
|
2032
2037
|
else {
|
|
@@ -2094,7 +2099,7 @@ class Deparser {
|
|
|
2094
2099
|
}
|
|
2095
2100
|
BooleanTest(node, context) {
|
|
2096
2101
|
const output = [];
|
|
2097
|
-
const boolContext =
|
|
2102
|
+
const boolContext = context.spawn('BooleanTest', { bool: true });
|
|
2098
2103
|
output.push(this.visit(node.arg, boolContext));
|
|
2099
2104
|
switch (node.booltesttype) {
|
|
2100
2105
|
case 'IS_TRUE':
|
|
@@ -2245,31 +2250,31 @@ class Deparser {
|
|
|
2245
2250
|
const elementStrs = elements.map(el => {
|
|
2246
2251
|
return this.deparse(el, context);
|
|
2247
2252
|
});
|
|
2248
|
-
output.push(
|
|
2253
|
+
output.push(context.parens(elementStrs.join(', ')));
|
|
2249
2254
|
}
|
|
2250
2255
|
}
|
|
2251
2256
|
else if (node.tableElts) {
|
|
2252
2257
|
const elements = list_utils_1.ListUtils.unwrapList(node.tableElts);
|
|
2253
2258
|
const elementStrs = elements.map(el => {
|
|
2254
|
-
return this.deparse(el, context);
|
|
2259
|
+
return this.deparse(el, context.spawn('CreateStmt'));
|
|
2255
2260
|
});
|
|
2256
|
-
if (
|
|
2261
|
+
if (context.isPretty()) {
|
|
2257
2262
|
const formattedElements = elementStrs.map(el => {
|
|
2258
2263
|
const trimmedEl = el.trim();
|
|
2259
2264
|
// Remove leading newlines from constraint elements to avoid extra blank lines
|
|
2260
2265
|
if (trimmedEl.startsWith('\n')) {
|
|
2261
|
-
return
|
|
2266
|
+
return context.indent(trimmedEl.substring(1));
|
|
2262
2267
|
}
|
|
2263
|
-
return
|
|
2264
|
-
}).join(',' +
|
|
2265
|
-
output.push('(' +
|
|
2268
|
+
return context.indent(trimmedEl);
|
|
2269
|
+
}).join(',' + context.newline());
|
|
2270
|
+
output.push('(' + context.newline() + formattedElements + context.newline() + ')');
|
|
2266
2271
|
}
|
|
2267
2272
|
else {
|
|
2268
|
-
output.push(
|
|
2273
|
+
output.push(context.parens(elementStrs.join(', ')));
|
|
2269
2274
|
}
|
|
2270
2275
|
}
|
|
2271
2276
|
else if (!node.partbound) {
|
|
2272
|
-
output.push(
|
|
2277
|
+
output.push(context.parens(''));
|
|
2273
2278
|
}
|
|
2274
2279
|
if (node.partbound && node.inhRelations && node.inhRelations.length > 0) {
|
|
2275
2280
|
output.push('PARTITION OF');
|
|
@@ -2312,7 +2317,7 @@ class Deparser {
|
|
|
2312
2317
|
output.push('INHERITS');
|
|
2313
2318
|
const inherits = list_utils_1.ListUtils.unwrapList(node.inhRelations);
|
|
2314
2319
|
const inheritStrs = inherits.map(rel => this.visit(rel, context));
|
|
2315
|
-
output.push(
|
|
2320
|
+
output.push(context.parens(inheritStrs.join(', ')));
|
|
2316
2321
|
}
|
|
2317
2322
|
if (node.partspec) {
|
|
2318
2323
|
output.push('PARTITION BY');
|
|
@@ -2350,7 +2355,7 @@ class Deparser {
|
|
|
2350
2355
|
}
|
|
2351
2356
|
// Handle table options like WITH (fillfactor=10)
|
|
2352
2357
|
if (node.options && node.options.length > 0) {
|
|
2353
|
-
const createStmtContext =
|
|
2358
|
+
const createStmtContext = context.spawn('CreateStmt');
|
|
2354
2359
|
const optionStrs = node.options.map((option) => {
|
|
2355
2360
|
return this.deparse(option, createStmtContext);
|
|
2356
2361
|
});
|
|
@@ -2373,7 +2378,7 @@ class Deparser {
|
|
|
2373
2378
|
}
|
|
2374
2379
|
if (node.fdwoptions && node.fdwoptions.length > 0) {
|
|
2375
2380
|
output.push('OPTIONS');
|
|
2376
|
-
const columnContext =
|
|
2381
|
+
const columnContext = context.spawn('ColumnDef');
|
|
2377
2382
|
const options = list_utils_1.ListUtils.unwrapList(node.fdwoptions).map(opt => this.visit(opt, columnContext));
|
|
2378
2383
|
output.push(`(${options.join(', ')})`);
|
|
2379
2384
|
}
|
|
@@ -2383,7 +2388,7 @@ class Deparser {
|
|
|
2383
2388
|
if (node.constraints) {
|
|
2384
2389
|
const constraints = list_utils_1.ListUtils.unwrapList(node.constraints);
|
|
2385
2390
|
const constraintStrs = constraints.map(constraint => {
|
|
2386
|
-
const columnConstraintContext =
|
|
2391
|
+
const columnConstraintContext = context.spawn('ColumnDef', { isColumnConstraint: true });
|
|
2387
2392
|
return this.visit(constraint, columnConstraintContext);
|
|
2388
2393
|
});
|
|
2389
2394
|
output.push(...constraintStrs);
|
|
@@ -2423,24 +2428,24 @@ class Deparser {
|
|
|
2423
2428
|
}
|
|
2424
2429
|
break;
|
|
2425
2430
|
case 'CONSTR_CHECK':
|
|
2426
|
-
if (
|
|
2427
|
-
output.push('\n' +
|
|
2431
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2432
|
+
output.push('\n' + context.indent('CHECK'));
|
|
2428
2433
|
}
|
|
2429
2434
|
else {
|
|
2430
2435
|
output.push('CHECK');
|
|
2431
2436
|
}
|
|
2432
2437
|
if (node.raw_expr) {
|
|
2433
|
-
if (
|
|
2438
|
+
if (context.isPretty()) {
|
|
2434
2439
|
const checkExpr = this.visit(node.raw_expr, context);
|
|
2435
2440
|
if (checkExpr.includes('\n')) {
|
|
2436
|
-
output.push('(\n' +
|
|
2441
|
+
output.push('(\n' + context.indent(checkExpr) + '\n)');
|
|
2437
2442
|
}
|
|
2438
2443
|
else {
|
|
2439
2444
|
output.push(`(${checkExpr})`);
|
|
2440
2445
|
}
|
|
2441
2446
|
}
|
|
2442
2447
|
else {
|
|
2443
|
-
output.push(
|
|
2448
|
+
output.push(context.parens(this.visit(node.raw_expr, context)));
|
|
2444
2449
|
}
|
|
2445
2450
|
}
|
|
2446
2451
|
// Handle NOT VALID for check constraints
|
|
@@ -2462,7 +2467,7 @@ class Deparser {
|
|
|
2462
2467
|
}
|
|
2463
2468
|
output.push('AS');
|
|
2464
2469
|
if (node.raw_expr) {
|
|
2465
|
-
output.push(
|
|
2470
|
+
output.push(context.parens(this.visit(node.raw_expr, context)));
|
|
2466
2471
|
}
|
|
2467
2472
|
output.push('STORED');
|
|
2468
2473
|
break;
|
|
@@ -2520,8 +2525,8 @@ class Deparser {
|
|
|
2520
2525
|
}
|
|
2521
2526
|
break;
|
|
2522
2527
|
case 'CONSTR_UNIQUE':
|
|
2523
|
-
if (
|
|
2524
|
-
output.push('\n' +
|
|
2528
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2529
|
+
output.push('\n' + context.indent('UNIQUE'));
|
|
2525
2530
|
}
|
|
2526
2531
|
else {
|
|
2527
2532
|
output.push('UNIQUE');
|
|
@@ -2543,15 +2548,15 @@ class Deparser {
|
|
|
2543
2548
|
case 'CONSTR_FOREIGN':
|
|
2544
2549
|
// Only add "FOREIGN KEY" for table-level constraints, not column-level constraints
|
|
2545
2550
|
if (!context.isColumnConstraint) {
|
|
2546
|
-
if (
|
|
2547
|
-
output.push('\n' +
|
|
2551
|
+
if (context.isPretty()) {
|
|
2552
|
+
output.push('\n' + context.indent('FOREIGN KEY'));
|
|
2548
2553
|
if (node.fk_attrs && node.fk_attrs.length > 0) {
|
|
2549
2554
|
const fkAttrs = list_utils_1.ListUtils.unwrapList(node.fk_attrs)
|
|
2550
2555
|
.map(attr => this.visit(attr, context))
|
|
2551
2556
|
.join(', ');
|
|
2552
2557
|
output.push(`(${fkAttrs})`);
|
|
2553
2558
|
}
|
|
2554
|
-
output.push('\n' +
|
|
2559
|
+
output.push('\n' + context.indent('REFERENCES'));
|
|
2555
2560
|
}
|
|
2556
2561
|
else {
|
|
2557
2562
|
output.push('FOREIGN KEY');
|
|
@@ -2568,7 +2573,7 @@ class Deparser {
|
|
|
2568
2573
|
output.push('REFERENCES');
|
|
2569
2574
|
}
|
|
2570
2575
|
if (node.pktable) {
|
|
2571
|
-
if (
|
|
2576
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2572
2577
|
const lastIndex = output.length - 1;
|
|
2573
2578
|
if (lastIndex >= 0 && output[lastIndex].includes('REFERENCES')) {
|
|
2574
2579
|
output[lastIndex] += ' ' + this.RangeVar(node.pktable, context);
|
|
@@ -2585,7 +2590,7 @@ class Deparser {
|
|
|
2585
2590
|
const pkAttrs = list_utils_1.ListUtils.unwrapList(node.pk_attrs)
|
|
2586
2591
|
.map(attr => this.visit(attr, context))
|
|
2587
2592
|
.join(', ');
|
|
2588
|
-
if (
|
|
2593
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2589
2594
|
const lastIndex = output.length - 1;
|
|
2590
2595
|
if (lastIndex >= 0) {
|
|
2591
2596
|
output[lastIndex] += ` (${pkAttrs})`;
|
|
@@ -2608,8 +2613,8 @@ class Deparser {
|
|
|
2608
2613
|
matchClause = 'MATCH PARTIAL';
|
|
2609
2614
|
break;
|
|
2610
2615
|
}
|
|
2611
|
-
if (
|
|
2612
|
-
output.push('\n' +
|
|
2616
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2617
|
+
output.push('\n' + context.indent(matchClause));
|
|
2613
2618
|
}
|
|
2614
2619
|
else {
|
|
2615
2620
|
output.push(matchClause);
|
|
@@ -2631,8 +2636,8 @@ class Deparser {
|
|
|
2631
2636
|
updateClause += 'SET DEFAULT';
|
|
2632
2637
|
break;
|
|
2633
2638
|
}
|
|
2634
|
-
if (
|
|
2635
|
-
output.push('\n' +
|
|
2639
|
+
if (context.isPretty()) {
|
|
2640
|
+
output.push('\n' + context.indent(updateClause));
|
|
2636
2641
|
}
|
|
2637
2642
|
else {
|
|
2638
2643
|
output.push('ON UPDATE');
|
|
@@ -2655,8 +2660,8 @@ class Deparser {
|
|
|
2655
2660
|
deleteClause += 'SET DEFAULT';
|
|
2656
2661
|
break;
|
|
2657
2662
|
}
|
|
2658
|
-
if (
|
|
2659
|
-
output.push('\n' +
|
|
2663
|
+
if (context.isPretty()) {
|
|
2664
|
+
output.push('\n' + context.indent(deleteClause));
|
|
2660
2665
|
}
|
|
2661
2666
|
else {
|
|
2662
2667
|
output.push('ON DELETE');
|
|
@@ -2665,8 +2670,8 @@ class Deparser {
|
|
|
2665
2670
|
}
|
|
2666
2671
|
// Handle NOT VALID for foreign key constraints - only for table constraints, not domain constraints
|
|
2667
2672
|
if (node.skip_validation && !context.isDomainConstraint) {
|
|
2668
|
-
if (
|
|
2669
|
-
output.push('\n' +
|
|
2673
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2674
|
+
output.push('\n' + context.indent('NOT VALID'));
|
|
2670
2675
|
}
|
|
2671
2676
|
else {
|
|
2672
2677
|
output.push('NOT VALID');
|
|
@@ -2724,13 +2729,13 @@ class Deparser {
|
|
|
2724
2729
|
// Handle deferrable constraints for all constraint types that support it
|
|
2725
2730
|
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN') {
|
|
2726
2731
|
if (node.deferrable) {
|
|
2727
|
-
if (
|
|
2728
|
-
output.push('\n' +
|
|
2732
|
+
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2733
|
+
output.push('\n' + context.indent('DEFERRABLE'));
|
|
2729
2734
|
if (node.initdeferred === true) {
|
|
2730
|
-
output.push('\n' +
|
|
2735
|
+
output.push('\n' + context.indent('INITIALLY DEFERRED'));
|
|
2731
2736
|
}
|
|
2732
2737
|
else if (node.initdeferred === false) {
|
|
2733
|
-
output.push('\n' +
|
|
2738
|
+
output.push('\n' + context.indent('INITIALLY IMMEDIATE'));
|
|
2734
2739
|
}
|
|
2735
2740
|
}
|
|
2736
2741
|
else {
|
|
@@ -2744,15 +2749,15 @@ class Deparser {
|
|
|
2744
2749
|
}
|
|
2745
2750
|
}
|
|
2746
2751
|
else if (node.deferrable === false) {
|
|
2747
|
-
if (
|
|
2748
|
-
output.push('\n' +
|
|
2752
|
+
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2753
|
+
output.push('\n' + context.indent('NOT DEFERRABLE'));
|
|
2749
2754
|
}
|
|
2750
2755
|
else {
|
|
2751
2756
|
output.push('NOT DEFERRABLE');
|
|
2752
2757
|
}
|
|
2753
2758
|
}
|
|
2754
2759
|
}
|
|
2755
|
-
if (
|
|
2760
|
+
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2756
2761
|
let result = '';
|
|
2757
2762
|
for (let i = 0; i < output.length; i++) {
|
|
2758
2763
|
if (output[i].startsWith('\n')) {
|
|
@@ -2770,12 +2775,12 @@ class Deparser {
|
|
|
2770
2775
|
return output.join(' ');
|
|
2771
2776
|
}
|
|
2772
2777
|
SubLink(node, context) {
|
|
2773
|
-
const subselect =
|
|
2778
|
+
const subselect = context.parens(this.visit(node.subselect, context));
|
|
2774
2779
|
switch (node.subLinkType) {
|
|
2775
2780
|
case 'ANY_SUBLINK':
|
|
2776
2781
|
if (node.testexpr && node.operName) {
|
|
2777
2782
|
const testExpr = this.visit(node.testexpr, context);
|
|
2778
|
-
const operator = this.deparseOperatorName(node.operName);
|
|
2783
|
+
const operator = this.deparseOperatorName(node.operName, context);
|
|
2779
2784
|
return `${testExpr} ${operator} ANY ${subselect}`;
|
|
2780
2785
|
}
|
|
2781
2786
|
else if (node.testexpr) {
|
|
@@ -2786,7 +2791,7 @@ class Deparser {
|
|
|
2786
2791
|
case 'ALL_SUBLINK':
|
|
2787
2792
|
if (node.testexpr && node.operName) {
|
|
2788
2793
|
const testExpr = this.visit(node.testexpr, context);
|
|
2789
|
-
const operator = this.deparseOperatorName(node.operName);
|
|
2794
|
+
const operator = this.deparseOperatorName(node.operName, context);
|
|
2790
2795
|
return `${testExpr} ${operator} ALL ${subselect}`;
|
|
2791
2796
|
}
|
|
2792
2797
|
return subselect;
|
|
@@ -2828,7 +2833,7 @@ class Deparser {
|
|
|
2828
2833
|
}
|
|
2829
2834
|
// Only add frame clause if frameOptions indicates non-default framing
|
|
2830
2835
|
if (node.frameOptions && node.frameOptions !== 1058) {
|
|
2831
|
-
const frameClause = this.formatWindowFrame(node);
|
|
2836
|
+
const frameClause = this.formatWindowFrame(node, context.spawn('WindowDef'));
|
|
2832
2837
|
if (frameClause) {
|
|
2833
2838
|
windowParts.push(frameClause);
|
|
2834
2839
|
}
|
|
@@ -2848,7 +2853,7 @@ class Deparser {
|
|
|
2848
2853
|
}
|
|
2849
2854
|
return output.join(' ');
|
|
2850
2855
|
}
|
|
2851
|
-
formatWindowFrame(node) {
|
|
2856
|
+
formatWindowFrame(node, context) {
|
|
2852
2857
|
if (!node.frameOptions)
|
|
2853
2858
|
return null;
|
|
2854
2859
|
const frameOptions = node.frameOptions;
|
|
@@ -2857,7 +2862,7 @@ class Deparser {
|
|
|
2857
2862
|
if (frameOptions & 0x02) { // FRAMEOPTION_RANGE
|
|
2858
2863
|
frameParts.push('RANGE');
|
|
2859
2864
|
}
|
|
2860
|
-
else if (frameOptions & 0x04) { // FRAMEOPTION_ROWS
|
|
2865
|
+
else if (frameOptions & 0x04) { // FRAMEOPTION_ROWS
|
|
2861
2866
|
frameParts.push('ROWS');
|
|
2862
2867
|
}
|
|
2863
2868
|
else if (frameOptions & 0x08) { // FRAMEOPTION_GROUPS
|
|
@@ -2878,8 +2883,8 @@ class Deparser {
|
|
|
2878
2883
|
}
|
|
2879
2884
|
else if (frameOptions === 18453) {
|
|
2880
2885
|
if (node.startOffset && node.endOffset) {
|
|
2881
|
-
boundsParts.push(`${this.visit(node.startOffset,
|
|
2882
|
-
boundsParts.push(`AND ${this.visit(node.endOffset,
|
|
2886
|
+
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
|
|
2887
|
+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
2883
2888
|
}
|
|
2884
2889
|
}
|
|
2885
2890
|
else if (frameOptions === 1557) {
|
|
@@ -2889,7 +2894,7 @@ class Deparser {
|
|
|
2889
2894
|
else if (frameOptions === 16917) {
|
|
2890
2895
|
boundsParts.push('CURRENT ROW');
|
|
2891
2896
|
if (node.endOffset) {
|
|
2892
|
-
boundsParts.push(`AND ${this.visit(node.endOffset,
|
|
2897
|
+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
2893
2898
|
}
|
|
2894
2899
|
}
|
|
2895
2900
|
else if (frameOptions === 1058) {
|
|
@@ -2899,13 +2904,13 @@ class Deparser {
|
|
|
2899
2904
|
// Handle start bound - prioritize explicit offset values over bit flags
|
|
2900
2905
|
if (node.startOffset) {
|
|
2901
2906
|
if (frameOptions & 0x400) { // FRAMEOPTION_START_VALUE_PRECEDING
|
|
2902
|
-
boundsParts.push(`${this.visit(node.startOffset,
|
|
2907
|
+
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
|
|
2903
2908
|
}
|
|
2904
2909
|
else if (frameOptions & 0x800) { // FRAMEOPTION_START_VALUE_FOLLOWING
|
|
2905
|
-
boundsParts.push(`${this.visit(node.startOffset,
|
|
2910
|
+
boundsParts.push(`${this.visit(node.startOffset, context)} FOLLOWING`);
|
|
2906
2911
|
}
|
|
2907
2912
|
else {
|
|
2908
|
-
boundsParts.push(`${this.visit(node.startOffset,
|
|
2913
|
+
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
|
|
2909
2914
|
}
|
|
2910
2915
|
}
|
|
2911
2916
|
else if (frameOptions & 0x10) { // FRAMEOPTION_START_UNBOUNDED_PRECEDING
|
|
@@ -2918,13 +2923,13 @@ class Deparser {
|
|
|
2918
2923
|
if (node.endOffset) {
|
|
2919
2924
|
if (boundsParts.length > 0) {
|
|
2920
2925
|
if (frameOptions & 0x1000) { // FRAMEOPTION_END_VALUE_PRECEDING
|
|
2921
|
-
boundsParts.push(`AND ${this.visit(node.endOffset,
|
|
2926
|
+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} PRECEDING`);
|
|
2922
2927
|
}
|
|
2923
2928
|
else if (frameOptions & 0x2000) { // FRAMEOPTION_END_VALUE_FOLLOWING
|
|
2924
|
-
boundsParts.push(`AND ${this.visit(node.endOffset,
|
|
2929
|
+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
2925
2930
|
}
|
|
2926
2931
|
else {
|
|
2927
|
-
boundsParts.push(`AND ${this.visit(node.endOffset,
|
|
2932
|
+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
2928
2933
|
}
|
|
2929
2934
|
}
|
|
2930
2935
|
}
|
|
@@ -3009,7 +3014,7 @@ class Deparser {
|
|
|
3009
3014
|
const colnames = list_utils_1.ListUtils.unwrapList(node.aliascolnames);
|
|
3010
3015
|
const colnameStrs = colnames.map(col => this.visit(col, context));
|
|
3011
3016
|
// Don't add space before column list parentheses to match original formatting
|
|
3012
|
-
output[output.length - 1] +=
|
|
3017
|
+
output[output.length - 1] += context.parens(colnameStrs.join(', '));
|
|
3013
3018
|
}
|
|
3014
3019
|
output.push('AS');
|
|
3015
3020
|
// Handle materialization clauses
|
|
@@ -3020,7 +3025,7 @@ class Deparser {
|
|
|
3020
3025
|
output.push('MATERIALIZED');
|
|
3021
3026
|
}
|
|
3022
3027
|
if (node.ctequery) {
|
|
3023
|
-
output.push(
|
|
3028
|
+
output.push(context.parens(this.visit(node.ctequery, context)));
|
|
3024
3029
|
}
|
|
3025
3030
|
return output.join(' ');
|
|
3026
3031
|
}
|
|
@@ -3096,7 +3101,7 @@ class Deparser {
|
|
|
3096
3101
|
DistinctExpr(node, context) {
|
|
3097
3102
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
3098
3103
|
if (args.length === 2) {
|
|
3099
|
-
const literalContext =
|
|
3104
|
+
const literalContext = context.spawn('DistinctExpr', { isStringLiteral: true });
|
|
3100
3105
|
const left = this.visit(args[0], literalContext);
|
|
3101
3106
|
const right = this.visit(args[1], literalContext);
|
|
3102
3107
|
return `${left} IS DISTINCT FROM ${right}`;
|
|
@@ -3106,7 +3111,7 @@ class Deparser {
|
|
|
3106
3111
|
NullIfExpr(node, context) {
|
|
3107
3112
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
3108
3113
|
if (args.length === 2) {
|
|
3109
|
-
const literalContext =
|
|
3114
|
+
const literalContext = context.spawn('NullIfExpr', { isStringLiteral: true });
|
|
3110
3115
|
const left = this.visit(args[0], literalContext);
|
|
3111
3116
|
const right = this.visit(args[1], literalContext);
|
|
3112
3117
|
return `NULLIF(${left}, ${right})`;
|
|
@@ -3185,7 +3190,7 @@ class Deparser {
|
|
|
3185
3190
|
}
|
|
3186
3191
|
RelabelType(node, context) {
|
|
3187
3192
|
if (node.arg) {
|
|
3188
|
-
const literalContext =
|
|
3193
|
+
const literalContext = context.spawn('RelabelType', { isStringLiteral: true });
|
|
3189
3194
|
return this.visit(node.arg, literalContext);
|
|
3190
3195
|
}
|
|
3191
3196
|
return '';
|
|
@@ -3204,7 +3209,7 @@ class Deparser {
|
|
|
3204
3209
|
}
|
|
3205
3210
|
ConvertRowtypeExpr(node, context) {
|
|
3206
3211
|
if (node.arg) {
|
|
3207
|
-
const literalContext =
|
|
3212
|
+
const literalContext = context.spawn('ConvertRowtypeExpr', { isStringLiteral: true });
|
|
3208
3213
|
return this.visit(node.arg, literalContext);
|
|
3209
3214
|
}
|
|
3210
3215
|
return '';
|
|
@@ -3235,10 +3240,10 @@ class Deparser {
|
|
|
3235
3240
|
}
|
|
3236
3241
|
if (node.aliases && node.aliases.length > 0) {
|
|
3237
3242
|
const aliasStrs = list_utils_1.ListUtils.unwrapList(node.aliases).map(alias => this.visit(alias, context));
|
|
3238
|
-
output.push(
|
|
3243
|
+
output.push(context.parens(aliasStrs.join(', ')));
|
|
3239
3244
|
}
|
|
3240
3245
|
if (node.options && node.options.length > 0) {
|
|
3241
|
-
const viewContext =
|
|
3246
|
+
const viewContext = context.spawn('ViewStmt');
|
|
3242
3247
|
const optionStrs = list_utils_1.ListUtils.unwrapList(node.options)
|
|
3243
3248
|
.map(option => this.visit(option, viewContext));
|
|
3244
3249
|
output.push(`WITH (${optionStrs.join(', ')})`);
|
|
@@ -3285,22 +3290,22 @@ class Deparser {
|
|
|
3285
3290
|
}
|
|
3286
3291
|
if (node.indexParams && node.indexParams.length > 0) {
|
|
3287
3292
|
const paramStrs = list_utils_1.ListUtils.unwrapList(node.indexParams).map(param => this.visit(param, context));
|
|
3288
|
-
output.push(
|
|
3293
|
+
output.push(context.parens(paramStrs.join(', ')));
|
|
3289
3294
|
}
|
|
3290
3295
|
if (node.indexIncludingParams && node.indexIncludingParams.length > 0) {
|
|
3291
3296
|
const includeStrs = list_utils_1.ListUtils.unwrapList(node.indexIncludingParams).map(param => this.visit(param, context));
|
|
3292
3297
|
output.push('INCLUDE');
|
|
3293
|
-
output.push(
|
|
3298
|
+
output.push(context.parens(includeStrs.join(', ')));
|
|
3294
3299
|
}
|
|
3295
3300
|
if (node.whereClause) {
|
|
3296
3301
|
output.push('WHERE');
|
|
3297
3302
|
output.push(this.visit(node.whereClause, context));
|
|
3298
3303
|
}
|
|
3299
3304
|
if (node.options && node.options.length > 0) {
|
|
3300
|
-
const indexContext =
|
|
3305
|
+
const indexContext = context.spawn('IndexStmt');
|
|
3301
3306
|
const optionStrs = list_utils_1.ListUtils.unwrapList(node.options).map(option => this.visit(option, indexContext));
|
|
3302
3307
|
output.push('WITH');
|
|
3303
|
-
output.push(
|
|
3308
|
+
output.push(context.parens(optionStrs.join(', ')));
|
|
3304
3309
|
}
|
|
3305
3310
|
if (node.nulls_not_distinct) {
|
|
3306
3311
|
output.push('NULLS NOT DISTINCT');
|
|
@@ -3317,7 +3322,7 @@ class Deparser {
|
|
|
3317
3322
|
output.push(quote_utils_1.QuoteUtils.quote(node.name));
|
|
3318
3323
|
}
|
|
3319
3324
|
else if (node.expr) {
|
|
3320
|
-
output.push(
|
|
3325
|
+
output.push(context.parens(this.visit(node.expr, context)));
|
|
3321
3326
|
}
|
|
3322
3327
|
if (node.collation && node.collation.length > 0) {
|
|
3323
3328
|
const collationStrs = list_utils_1.ListUtils.unwrapList(node.collation).map(coll => this.visit(coll, context));
|
|
@@ -3334,7 +3339,7 @@ class Deparser {
|
|
|
3334
3339
|
const stringData = this.getNodeData(opt.DefElem.arg);
|
|
3335
3340
|
return `${opt.DefElem.defname}='${stringData.sval}'`;
|
|
3336
3341
|
}
|
|
3337
|
-
return this.visit(opt, context);
|
|
3342
|
+
return this.visit(opt, context.spawn('IndexElem'));
|
|
3338
3343
|
});
|
|
3339
3344
|
opclassStr += `(${opclassOpts.join(', ')})`;
|
|
3340
3345
|
}
|
|
@@ -3368,7 +3373,7 @@ class Deparser {
|
|
|
3368
3373
|
output.push(quote_utils_1.QuoteUtils.quote(node.name));
|
|
3369
3374
|
}
|
|
3370
3375
|
else if (node.expr) {
|
|
3371
|
-
output.push(
|
|
3376
|
+
output.push(context.parens(this.visit(node.expr, context)));
|
|
3372
3377
|
}
|
|
3373
3378
|
if (node.collation && node.collation.length > 0) {
|
|
3374
3379
|
const collationStrs = list_utils_1.ListUtils.unwrapList(node.collation).map(coll => this.visit(coll, context));
|
|
@@ -3516,16 +3521,16 @@ class Deparser {
|
|
|
3516
3521
|
if (node.rarg && 'JoinExpr' in node.rarg && !node.rarg.JoinExpr.alias) {
|
|
3517
3522
|
rargStr = `(${rargStr})`;
|
|
3518
3523
|
}
|
|
3519
|
-
if (
|
|
3520
|
-
output.push(
|
|
3524
|
+
if (context.isPretty()) {
|
|
3525
|
+
output.push(context.newline() + joinStr + ' ' + rargStr);
|
|
3521
3526
|
}
|
|
3522
3527
|
else {
|
|
3523
3528
|
output.push(joinStr + ' ' + rargStr);
|
|
3524
3529
|
}
|
|
3525
3530
|
}
|
|
3526
3531
|
else {
|
|
3527
|
-
if (
|
|
3528
|
-
output.push(
|
|
3532
|
+
if (context.isPretty()) {
|
|
3533
|
+
output.push(context.newline() + joinStr);
|
|
3529
3534
|
}
|
|
3530
3535
|
else {
|
|
3531
3536
|
output.push(joinStr);
|
|
@@ -3534,7 +3539,7 @@ class Deparser {
|
|
|
3534
3539
|
if (node.usingClause && node.usingClause.length > 0) {
|
|
3535
3540
|
const usingList = list_utils_1.ListUtils.unwrapList(node.usingClause);
|
|
3536
3541
|
const columnNames = usingList.map(col => this.visit(col, context));
|
|
3537
|
-
if (
|
|
3542
|
+
if (context.isPretty()) {
|
|
3538
3543
|
output.push(` USING (${columnNames.join(', ')})`);
|
|
3539
3544
|
}
|
|
3540
3545
|
else {
|
|
@@ -3543,14 +3548,14 @@ class Deparser {
|
|
|
3543
3548
|
}
|
|
3544
3549
|
else if (node.quals) {
|
|
3545
3550
|
const qualsStr = this.visit(node.quals, context);
|
|
3546
|
-
if (
|
|
3551
|
+
if (context.isPretty()) {
|
|
3547
3552
|
// For complex JOIN conditions, format with proper indentation
|
|
3548
3553
|
if (qualsStr.includes('AND') || qualsStr.includes('OR') || qualsStr.length > 50) {
|
|
3549
3554
|
if (this.containsMultilineStringLiteral(qualsStr)) {
|
|
3550
3555
|
output.push(` ON ${qualsStr}`);
|
|
3551
3556
|
}
|
|
3552
3557
|
else {
|
|
3553
|
-
output.push(` ON${
|
|
3558
|
+
output.push(` ON${context.newline()}${context.indent(qualsStr)}`);
|
|
3554
3559
|
}
|
|
3555
3560
|
}
|
|
3556
3561
|
else {
|
|
@@ -3562,7 +3567,7 @@ class Deparser {
|
|
|
3562
3567
|
}
|
|
3563
3568
|
}
|
|
3564
3569
|
let result;
|
|
3565
|
-
if (
|
|
3570
|
+
if (context.isPretty()) {
|
|
3566
3571
|
result = output.join('');
|
|
3567
3572
|
}
|
|
3568
3573
|
else {
|
|
@@ -4165,7 +4170,7 @@ class Deparser {
|
|
|
4165
4170
|
}).filter((name) => name && name.trim());
|
|
4166
4171
|
return items.join('.');
|
|
4167
4172
|
}
|
|
4168
|
-
const objContext =
|
|
4173
|
+
const objContext = context.spawn('DropStmt', { objtype: node.removeType });
|
|
4169
4174
|
const objName = this.visit(objList, objContext);
|
|
4170
4175
|
return objName;
|
|
4171
4176
|
}).filter((name) => name && name.trim()).join(', ');
|
|
@@ -4265,7 +4270,7 @@ class Deparser {
|
|
|
4265
4270
|
if (node.options && node.options.length > 0) {
|
|
4266
4271
|
output.push('WITH');
|
|
4267
4272
|
const optionsStr = list_utils_1.ListUtils.unwrapList(node.options)
|
|
4268
|
-
.map(opt => this.visit(opt, context))
|
|
4273
|
+
.map(opt => this.visit(opt, context.spawn('CopyStmt')))
|
|
4269
4274
|
.join(', ');
|
|
4270
4275
|
output.push(`(${optionsStr})`);
|
|
4271
4276
|
}
|
|
@@ -4311,21 +4316,19 @@ class Deparser {
|
|
|
4311
4316
|
if (node.missing_ok) {
|
|
4312
4317
|
output.push('IF EXISTS');
|
|
4313
4318
|
}
|
|
4314
|
-
const alterContext = node.objtype
|
|
4315
|
-
? { ...context, parentNodeTypes: [...context.parentNodeTypes, 'AlterTypeStmt'] }
|
|
4316
|
-
: context;
|
|
4319
|
+
const alterContext = context.spawn('AlterTableStmt', { objtype: node.objtype });
|
|
4317
4320
|
if (node.relation) {
|
|
4318
4321
|
const relationStr = this.RangeVar(node.relation, alterContext);
|
|
4319
4322
|
output.push(relationStr);
|
|
4320
4323
|
}
|
|
4321
4324
|
if (node.cmds && node.cmds.length > 0) {
|
|
4322
4325
|
const commands = list_utils_1.ListUtils.unwrapList(node.cmds);
|
|
4323
|
-
if (
|
|
4326
|
+
if (context.isPretty()) {
|
|
4324
4327
|
const commandsStr = commands
|
|
4325
4328
|
.map(cmd => {
|
|
4326
4329
|
const cmdStr = this.visit(cmd, alterContext);
|
|
4327
4330
|
if (cmdStr.startsWith('ADD CONSTRAINT') || cmdStr.startsWith('ADD ')) {
|
|
4328
|
-
return
|
|
4331
|
+
return context.newline() + context.indent(cmdStr);
|
|
4329
4332
|
}
|
|
4330
4333
|
return cmdStr;
|
|
4331
4334
|
})
|
|
@@ -4346,7 +4349,7 @@ class Deparser {
|
|
|
4346
4349
|
if (node.subtype) {
|
|
4347
4350
|
switch (node.subtype) {
|
|
4348
4351
|
case 'AT_AddColumn':
|
|
4349
|
-
if (context.
|
|
4352
|
+
if (context.objtype === 'OBJECT_TYPE') {
|
|
4350
4353
|
output.push('ADD ATTRIBUTE');
|
|
4351
4354
|
}
|
|
4352
4355
|
else {
|
|
@@ -4366,14 +4369,14 @@ class Deparser {
|
|
|
4366
4369
|
}
|
|
4367
4370
|
if (colDefData.fdwoptions && colDefData.fdwoptions.length > 0) {
|
|
4368
4371
|
parts.push('OPTIONS');
|
|
4369
|
-
const columnContext =
|
|
4372
|
+
const columnContext = context.spawn('ColumnDef');
|
|
4370
4373
|
const options = list_utils_1.ListUtils.unwrapList(colDefData.fdwoptions).map(opt => this.visit(opt, columnContext));
|
|
4371
4374
|
parts.push(`(${options.join(', ')})`);
|
|
4372
4375
|
}
|
|
4373
4376
|
if (colDefData.constraints) {
|
|
4374
4377
|
const constraints = list_utils_1.ListUtils.unwrapList(colDefData.constraints);
|
|
4375
4378
|
const constraintStrs = constraints.map(constraint => {
|
|
4376
|
-
const columnConstraintContext =
|
|
4379
|
+
const columnConstraintContext = context.spawn('ColumnDef', { isColumnConstraint: true });
|
|
4377
4380
|
return this.visit(constraint, columnConstraintContext);
|
|
4378
4381
|
});
|
|
4379
4382
|
parts.push(...constraintStrs);
|
|
@@ -4393,7 +4396,7 @@ class Deparser {
|
|
|
4393
4396
|
break;
|
|
4394
4397
|
case 'AT_DropColumn':
|
|
4395
4398
|
if (node.missing_ok) {
|
|
4396
|
-
if (context.
|
|
4399
|
+
if (context.objtype === 'OBJECT_TYPE') {
|
|
4397
4400
|
output.push('DROP ATTRIBUTE IF EXISTS');
|
|
4398
4401
|
}
|
|
4399
4402
|
else {
|
|
@@ -4401,7 +4404,7 @@ class Deparser {
|
|
|
4401
4404
|
}
|
|
4402
4405
|
}
|
|
4403
4406
|
else {
|
|
4404
|
-
if (context.
|
|
4407
|
+
if (context.objtype === 'OBJECT_TYPE') {
|
|
4405
4408
|
output.push('DROP ATTRIBUTE');
|
|
4406
4409
|
}
|
|
4407
4410
|
else {
|
|
@@ -4419,7 +4422,7 @@ class Deparser {
|
|
|
4419
4422
|
}
|
|
4420
4423
|
break;
|
|
4421
4424
|
case 'AT_AlterColumnType':
|
|
4422
|
-
if (context.
|
|
4425
|
+
if (context.objtype === 'OBJECT_TYPE') {
|
|
4423
4426
|
output.push('ALTER ATTRIBUTE');
|
|
4424
4427
|
}
|
|
4425
4428
|
else {
|
|
@@ -4483,7 +4486,7 @@ class Deparser {
|
|
|
4483
4486
|
case 'AT_SetRelOptions':
|
|
4484
4487
|
output.push('SET');
|
|
4485
4488
|
if (node.def) {
|
|
4486
|
-
const alterTableContext =
|
|
4489
|
+
const alterTableContext = context.spawn('AlterTableCmd', { subtype: 'AT_SetRelOptions' });
|
|
4487
4490
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4488
4491
|
.map(option => this.visit(option, alterTableContext))
|
|
4489
4492
|
.join(', ');
|
|
@@ -4496,7 +4499,7 @@ class Deparser {
|
|
|
4496
4499
|
case 'AT_ResetRelOptions':
|
|
4497
4500
|
output.push('RESET');
|
|
4498
4501
|
if (node.def) {
|
|
4499
|
-
const alterTableContext =
|
|
4502
|
+
const alterTableContext = context.spawn('AlterTableCmd', { subtype: 'AT_ResetRelOptions' });
|
|
4500
4503
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4501
4504
|
.map(option => this.visit(option, alterTableContext))
|
|
4502
4505
|
.join(', ');
|
|
@@ -4591,7 +4594,7 @@ class Deparser {
|
|
|
4591
4594
|
}
|
|
4592
4595
|
output.push('SET');
|
|
4593
4596
|
if (node.def) {
|
|
4594
|
-
const alterTableContext =
|
|
4597
|
+
const alterTableContext = context.spawn('AlterTableCmd', { subtype: 'AT_SetOptions' });
|
|
4595
4598
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4596
4599
|
.map(option => this.visit(option, alterTableContext))
|
|
4597
4600
|
.join(', ');
|
|
@@ -4608,7 +4611,7 @@ class Deparser {
|
|
|
4608
4611
|
}
|
|
4609
4612
|
output.push('RESET');
|
|
4610
4613
|
if (node.def) {
|
|
4611
|
-
const alterTableContext =
|
|
4614
|
+
const alterTableContext = context.spawn('AlterTableCmd', { subtype: 'AT_ResetOptions' });
|
|
4612
4615
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4613
4616
|
.map(option => this.visit(option, alterTableContext))
|
|
4614
4617
|
.join(', ');
|
|
@@ -4849,7 +4852,7 @@ class Deparser {
|
|
|
4849
4852
|
}
|
|
4850
4853
|
output.push('OPTIONS');
|
|
4851
4854
|
if (node.def) {
|
|
4852
|
-
const alterColumnContext =
|
|
4855
|
+
const alterColumnContext = context.spawn('AlterTableCmd', { alterColumnOptions: true });
|
|
4853
4856
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4854
4857
|
.map(option => this.visit(option, alterColumnContext))
|
|
4855
4858
|
.join(', ');
|
|
@@ -4889,7 +4892,7 @@ class Deparser {
|
|
|
4889
4892
|
case 'AT_GenericOptions':
|
|
4890
4893
|
output.push('OPTIONS');
|
|
4891
4894
|
if (node.def) {
|
|
4892
|
-
const alterTableContext =
|
|
4895
|
+
const alterTableContext = context.spawn('AlterTableCmd', { alterTableOptions: true });
|
|
4893
4896
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4894
4897
|
.map(option => this.visit(option, alterTableContext))
|
|
4895
4898
|
.join(', ');
|
|
@@ -4993,7 +4996,7 @@ class Deparser {
|
|
|
4993
4996
|
output.push(this.TypeName(node.returnType, context));
|
|
4994
4997
|
}
|
|
4995
4998
|
if (node.options && node.options.length > 0) {
|
|
4996
|
-
const funcContext =
|
|
4999
|
+
const funcContext = context.spawn('CreateFunctionStmt');
|
|
4997
5000
|
const options = node.options.map((opt) => this.visit(opt, funcContext));
|
|
4998
5001
|
output.push(...options);
|
|
4999
5002
|
}
|
|
@@ -5080,7 +5083,7 @@ class Deparser {
|
|
|
5080
5083
|
}
|
|
5081
5084
|
output.push('AS', 'ENUM');
|
|
5082
5085
|
if (node.vals && node.vals.length > 0) {
|
|
5083
|
-
const enumContext =
|
|
5086
|
+
const enumContext = context.spawn('CreateEnumStmt', { isEnumValue: true });
|
|
5084
5087
|
const values = list_utils_1.ListUtils.unwrapList(node.vals)
|
|
5085
5088
|
.map(val => this.visit(val, enumContext))
|
|
5086
5089
|
.join(', ');
|
|
@@ -5135,9 +5138,8 @@ class Deparser {
|
|
|
5135
5138
|
output.push(roleName);
|
|
5136
5139
|
}
|
|
5137
5140
|
if (node.options) {
|
|
5138
|
-
const roleContext = { ...context, parentNodeTypes: [...context.parentNodeTypes, 'CreateRoleStmt'] };
|
|
5139
5141
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5140
|
-
.map(option => this.visit(option,
|
|
5142
|
+
.map(option => this.visit(option, context.spawn('CreateRoleStmt')))
|
|
5141
5143
|
.join(' ');
|
|
5142
5144
|
if (options) {
|
|
5143
5145
|
output.push('WITH');
|
|
@@ -5168,7 +5170,7 @@ class Deparser {
|
|
|
5168
5170
|
const stringData = this.getNodeData(node.arg);
|
|
5169
5171
|
return `${node.defname}='${stringData.sval}'`;
|
|
5170
5172
|
}
|
|
5171
|
-
return `${node.defname}=${this.visit(node.arg,
|
|
5173
|
+
return `${node.defname}=${this.visit(node.arg, context.spawn('DefElem'))}`;
|
|
5172
5174
|
}
|
|
5173
5175
|
// Handle CREATE OPERATOR boolean flags - MUST be first to preserve case
|
|
5174
5176
|
if (context.parentNodeTypes.includes('DefineStmt') &&
|
|
@@ -5184,13 +5186,13 @@ class Deparser {
|
|
|
5184
5186
|
if (!node.arg) {
|
|
5185
5187
|
return `NO ${node.defname.toUpperCase()}`;
|
|
5186
5188
|
}
|
|
5187
|
-
const defElemContext =
|
|
5189
|
+
const defElemContext = context.spawn('DefElem');
|
|
5188
5190
|
const argValue = this.visit(node.arg, defElemContext);
|
|
5189
5191
|
return `${node.defname.toUpperCase()} ${argValue}`;
|
|
5190
5192
|
}
|
|
5191
5193
|
// Handle OPTIONS clause - use space format, not equals format
|
|
5192
5194
|
if (node.arg) {
|
|
5193
|
-
const defElemContext =
|
|
5195
|
+
const defElemContext = context.spawn('DefElem');
|
|
5194
5196
|
const argValue = this.visit(node.arg, defElemContext);
|
|
5195
5197
|
if (context.parentNodeTypes.includes('CreateFdwStmt') || context.parentNodeTypes.includes('AlterFdwStmt')) {
|
|
5196
5198
|
const finalValue = typeof argValue === 'string' && !argValue.startsWith("'")
|
|
@@ -5244,7 +5246,7 @@ class Deparser {
|
|
|
5244
5246
|
if (!node.arg) {
|
|
5245
5247
|
return 'PASSWORD NULL';
|
|
5246
5248
|
}
|
|
5247
|
-
const defElemContext =
|
|
5249
|
+
const defElemContext = context.spawn('DefElem');
|
|
5248
5250
|
const argValue = this.visit(node.arg, defElemContext);
|
|
5249
5251
|
const quotedValue = typeof argValue === 'string' && !argValue.startsWith("'")
|
|
5250
5252
|
? `'${argValue}'`
|
|
@@ -5253,7 +5255,7 @@ class Deparser {
|
|
|
5253
5255
|
}
|
|
5254
5256
|
}
|
|
5255
5257
|
if (node.arg) {
|
|
5256
|
-
const defElemContext =
|
|
5258
|
+
const defElemContext = context.spawn('DefElem');
|
|
5257
5259
|
const argValue = this.visit(node.arg, defElemContext);
|
|
5258
5260
|
if (context.parentNodeTypes.includes('AlterOperatorStmt')) {
|
|
5259
5261
|
if (node.arg && this.getNodeType(node.arg) === 'TypeName') {
|
|
@@ -5329,7 +5331,7 @@ class Deparser {
|
|
|
5329
5331
|
if (node.defname === 'sysid') {
|
|
5330
5332
|
return `SYSID ${argValue}`;
|
|
5331
5333
|
}
|
|
5332
|
-
if (argValue === 'true') {
|
|
5334
|
+
if (String(argValue) === 'true') {
|
|
5333
5335
|
// Handle special cases where the positive form has a different name
|
|
5334
5336
|
if (node.defname === 'isreplication') {
|
|
5335
5337
|
return 'REPLICATION';
|
|
@@ -5339,7 +5341,7 @@ class Deparser {
|
|
|
5339
5341
|
}
|
|
5340
5342
|
return node.defname.toUpperCase();
|
|
5341
5343
|
}
|
|
5342
|
-
else if (argValue === 'false') {
|
|
5344
|
+
else if (String(argValue) === 'false') {
|
|
5343
5345
|
// Handle special cases where the negative form has a different name
|
|
5344
5346
|
if (node.defname === 'canlogin') {
|
|
5345
5347
|
return 'NOLOGIN';
|
|
@@ -5403,7 +5405,7 @@ class Deparser {
|
|
|
5403
5405
|
}
|
|
5404
5406
|
if (context.parentNodeTypes.includes('DoStmt')) {
|
|
5405
5407
|
if (node.defname === 'as') {
|
|
5406
|
-
const defElemContext =
|
|
5408
|
+
const defElemContext = context.spawn('DefElem');
|
|
5407
5409
|
const argValue = node.arg ? this.visit(node.arg, defElemContext) : '';
|
|
5408
5410
|
if (Array.isArray(argValue)) {
|
|
5409
5411
|
const bodyParts = argValue;
|
|
@@ -5694,7 +5696,7 @@ class Deparser {
|
|
|
5694
5696
|
}
|
|
5695
5697
|
if (node.options && node.options.length > 0) {
|
|
5696
5698
|
output.push('WITH');
|
|
5697
|
-
const tsContext =
|
|
5699
|
+
const tsContext = context.spawn('CreateTableSpaceStmt');
|
|
5698
5700
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5699
5701
|
.map(option => this.visit(option, tsContext))
|
|
5700
5702
|
.join(', ');
|
|
@@ -5724,7 +5726,7 @@ class Deparser {
|
|
|
5724
5726
|
output.push('SET');
|
|
5725
5727
|
}
|
|
5726
5728
|
if (node.options && node.options.length > 0) {
|
|
5727
|
-
const tablespaceContext =
|
|
5729
|
+
const tablespaceContext = context.spawn('AlterTableSpaceOptionsStmt');
|
|
5728
5730
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5729
5731
|
.map(option => this.visit(option, tablespaceContext))
|
|
5730
5732
|
.join(', ');
|
|
@@ -5741,7 +5743,7 @@ class Deparser {
|
|
|
5741
5743
|
output.push(this.quoteIfNeeded(node.extname));
|
|
5742
5744
|
}
|
|
5743
5745
|
if (node.options && node.options.length > 0) {
|
|
5744
|
-
const extContext =
|
|
5746
|
+
const extContext = context.spawn('CreateExtensionStmt');
|
|
5745
5747
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5746
5748
|
.map(option => this.visit(option, extContext))
|
|
5747
5749
|
.join(' ');
|
|
@@ -5755,7 +5757,7 @@ class Deparser {
|
|
|
5755
5757
|
output.push(this.quoteIfNeeded(node.extname));
|
|
5756
5758
|
}
|
|
5757
5759
|
if (node.options && node.options.length > 0) {
|
|
5758
|
-
const extContext =
|
|
5760
|
+
const extContext = context.spawn('AlterExtensionStmt');
|
|
5759
5761
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5760
5762
|
.map(option => this.visit(option, extContext))
|
|
5761
5763
|
.join(' ');
|
|
@@ -5769,7 +5771,7 @@ class Deparser {
|
|
|
5769
5771
|
output.push(node.fdwname);
|
|
5770
5772
|
}
|
|
5771
5773
|
if (node.func_options && node.func_options.length > 0) {
|
|
5772
|
-
const fdwContext =
|
|
5774
|
+
const fdwContext = context.spawn('CreateFdwStmt');
|
|
5773
5775
|
const funcOptions = list_utils_1.ListUtils.unwrapList(node.func_options)
|
|
5774
5776
|
.map(option => this.visit(option, fdwContext))
|
|
5775
5777
|
.join(' ');
|
|
@@ -5777,7 +5779,7 @@ class Deparser {
|
|
|
5777
5779
|
}
|
|
5778
5780
|
if (node.options && node.options.length > 0) {
|
|
5779
5781
|
output.push('OPTIONS');
|
|
5780
|
-
const fdwContext =
|
|
5782
|
+
const fdwContext = context.spawn('CreateFdwStmt');
|
|
5781
5783
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5782
5784
|
.map(option => this.visit(option, fdwContext))
|
|
5783
5785
|
.join(', ');
|
|
@@ -5879,7 +5881,7 @@ class Deparser {
|
|
|
5879
5881
|
output.push('ADD');
|
|
5880
5882
|
if (node.def) {
|
|
5881
5883
|
// Pass domain context to avoid adding constraint names for domain constraints
|
|
5882
|
-
const domainContext =
|
|
5884
|
+
const domainContext = context.spawn('CreateDomainStmt', { isDomainConstraint: true });
|
|
5883
5885
|
output.push(this.visit(node.def, domainContext));
|
|
5884
5886
|
}
|
|
5885
5887
|
break;
|
|
@@ -5905,7 +5907,7 @@ class Deparser {
|
|
|
5905
5907
|
output.push('ADD');
|
|
5906
5908
|
if (node.def) {
|
|
5907
5909
|
// Pass domain context to avoid adding constraint names for domain constraints
|
|
5908
|
-
const domainContext =
|
|
5910
|
+
const domainContext = context.spawn('CreateDomainStmt', { isDomainConstraint: true });
|
|
5909
5911
|
output.push(this.visit(node.def, domainContext));
|
|
5910
5912
|
}
|
|
5911
5913
|
break;
|
|
@@ -6267,7 +6269,7 @@ class Deparser {
|
|
|
6267
6269
|
output.push(`${operatorName}(${args.join(', ')})`);
|
|
6268
6270
|
}
|
|
6269
6271
|
else {
|
|
6270
|
-
const objContext =
|
|
6272
|
+
const objContext = context.spawn('CommentStmt', { objtype: node.objtype });
|
|
6271
6273
|
output.push(this.visit(node.object, objContext));
|
|
6272
6274
|
}
|
|
6273
6275
|
}
|
|
@@ -6318,8 +6320,8 @@ class Deparser {
|
|
|
6318
6320
|
output.push(initialParts.join(' '));
|
|
6319
6321
|
// Add ON clause on new line in pretty mode
|
|
6320
6322
|
if (node.table) {
|
|
6321
|
-
if (
|
|
6322
|
-
output.push(
|
|
6323
|
+
if (context.isPretty()) {
|
|
6324
|
+
output.push(context.newline() + context.indent(`ON ${this.RangeVar(node.table, context)}`));
|
|
6323
6325
|
}
|
|
6324
6326
|
else {
|
|
6325
6327
|
output.push('ON');
|
|
@@ -6328,24 +6330,24 @@ class Deparser {
|
|
|
6328
6330
|
}
|
|
6329
6331
|
// Handle AS RESTRICTIVE/PERMISSIVE clause
|
|
6330
6332
|
if (node.permissive === undefined) {
|
|
6331
|
-
if (
|
|
6332
|
-
output.push(
|
|
6333
|
+
if (context.isPretty()) {
|
|
6334
|
+
output.push(context.newline() + context.indent('AS RESTRICTIVE'));
|
|
6333
6335
|
}
|
|
6334
6336
|
else {
|
|
6335
6337
|
output.push('AS', 'RESTRICTIVE');
|
|
6336
6338
|
}
|
|
6337
6339
|
}
|
|
6338
6340
|
else if (node.permissive === true) {
|
|
6339
|
-
if (
|
|
6340
|
-
output.push(
|
|
6341
|
+
if (context.isPretty()) {
|
|
6342
|
+
output.push(context.newline() + context.indent('AS PERMISSIVE'));
|
|
6341
6343
|
}
|
|
6342
6344
|
else {
|
|
6343
6345
|
output.push('AS', 'PERMISSIVE');
|
|
6344
6346
|
}
|
|
6345
6347
|
}
|
|
6346
6348
|
if (node.cmd_name) {
|
|
6347
|
-
if (
|
|
6348
|
-
output.push(
|
|
6349
|
+
if (context.isPretty()) {
|
|
6350
|
+
output.push(context.newline() + context.indent(`FOR ${node.cmd_name.toUpperCase()}`));
|
|
6349
6351
|
}
|
|
6350
6352
|
else {
|
|
6351
6353
|
output.push('FOR', node.cmd_name.toUpperCase());
|
|
@@ -6353,8 +6355,8 @@ class Deparser {
|
|
|
6353
6355
|
}
|
|
6354
6356
|
if (node.roles && node.roles.length > 0) {
|
|
6355
6357
|
const roles = list_utils_1.ListUtils.unwrapList(node.roles).map(role => this.visit(role, context));
|
|
6356
|
-
if (
|
|
6357
|
-
output.push(
|
|
6358
|
+
if (context.isPretty()) {
|
|
6359
|
+
output.push(context.newline() + context.indent(`TO ${roles.join(', ')}`));
|
|
6358
6360
|
}
|
|
6359
6361
|
else {
|
|
6360
6362
|
output.push('TO');
|
|
@@ -6362,11 +6364,11 @@ class Deparser {
|
|
|
6362
6364
|
}
|
|
6363
6365
|
}
|
|
6364
6366
|
if (node.qual) {
|
|
6365
|
-
if (
|
|
6367
|
+
if (context.isPretty()) {
|
|
6366
6368
|
const qualExpr = this.visit(node.qual, context);
|
|
6367
|
-
output.push(
|
|
6368
|
-
output.push(
|
|
6369
|
-
output.push(
|
|
6369
|
+
output.push(context.newline() + context.indent('USING ('));
|
|
6370
|
+
output.push(context.newline() + context.indent(context.indent(qualExpr)));
|
|
6371
|
+
output.push(context.newline() + context.indent(')'));
|
|
6370
6372
|
}
|
|
6371
6373
|
else {
|
|
6372
6374
|
output.push('USING');
|
|
@@ -6374,18 +6376,18 @@ class Deparser {
|
|
|
6374
6376
|
}
|
|
6375
6377
|
}
|
|
6376
6378
|
if (node.with_check) {
|
|
6377
|
-
if (
|
|
6379
|
+
if (context.isPretty()) {
|
|
6378
6380
|
const checkExpr = this.visit(node.with_check, context);
|
|
6379
|
-
output.push(
|
|
6380
|
-
output.push(
|
|
6381
|
-
output.push(
|
|
6381
|
+
output.push(context.newline() + context.indent('WITH CHECK ('));
|
|
6382
|
+
output.push(context.newline() + context.indent(context.indent(checkExpr)));
|
|
6383
|
+
output.push(context.newline() + context.indent(')'));
|
|
6382
6384
|
}
|
|
6383
6385
|
else {
|
|
6384
6386
|
output.push('WITH CHECK');
|
|
6385
6387
|
output.push(`(${this.visit(node.with_check, context)})`);
|
|
6386
6388
|
}
|
|
6387
6389
|
}
|
|
6388
|
-
return
|
|
6390
|
+
return context.isPretty() ? output.join('') : output.join(' ');
|
|
6389
6391
|
}
|
|
6390
6392
|
AlterPolicyStmt(node, context) {
|
|
6391
6393
|
const output = ['ALTER', 'POLICY'];
|
|
@@ -6430,7 +6432,7 @@ class Deparser {
|
|
|
6430
6432
|
}
|
|
6431
6433
|
if (node.options && node.options.length > 0) {
|
|
6432
6434
|
output.push('OPTIONS');
|
|
6433
|
-
const userMappingContext =
|
|
6435
|
+
const userMappingContext = context.spawn('CreateUserMappingStmt');
|
|
6434
6436
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, userMappingContext));
|
|
6435
6437
|
output.push(`(${options.join(', ')})`);
|
|
6436
6438
|
}
|
|
@@ -6613,7 +6615,7 @@ class Deparser {
|
|
|
6613
6615
|
DoStmt(node, context) {
|
|
6614
6616
|
const output = ['DO'];
|
|
6615
6617
|
if (node.args && node.args.length > 0) {
|
|
6616
|
-
const doContext =
|
|
6618
|
+
const doContext = context.spawn('DoStmt');
|
|
6617
6619
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
6618
6620
|
const processedArgs = [];
|
|
6619
6621
|
for (const arg of args) {
|
|
@@ -6918,7 +6920,7 @@ class Deparser {
|
|
|
6918
6920
|
ObjectWithArgs(node, context) {
|
|
6919
6921
|
let result = '';
|
|
6920
6922
|
if (node.objname && node.objname.length > 0) {
|
|
6921
|
-
const objContext =
|
|
6923
|
+
const objContext = context.spawn('ObjectWithArgs');
|
|
6922
6924
|
const names = list_utils_1.ListUtils.unwrapList(node.objname).map(name => this.visit(name, objContext));
|
|
6923
6925
|
result = names.join('.');
|
|
6924
6926
|
}
|
|
@@ -6960,7 +6962,7 @@ class Deparser {
|
|
|
6960
6962
|
}
|
|
6961
6963
|
output.push('SET');
|
|
6962
6964
|
if (node.options && node.options.length > 0) {
|
|
6963
|
-
const alterOpContext =
|
|
6965
|
+
const alterOpContext = context.spawn('AlterOperatorStmt');
|
|
6964
6966
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, alterOpContext));
|
|
6965
6967
|
output.push(`(${options.join(', ')})`);
|
|
6966
6968
|
}
|
|
@@ -6972,13 +6974,13 @@ class Deparser {
|
|
|
6972
6974
|
output.push(quote_utils_1.QuoteUtils.quote(node.fdwname));
|
|
6973
6975
|
}
|
|
6974
6976
|
if (node.func_options && node.func_options.length > 0) {
|
|
6975
|
-
const fdwContext =
|
|
6977
|
+
const fdwContext = context.spawn('AlterFdwStmt');
|
|
6976
6978
|
const funcOptions = list_utils_1.ListUtils.unwrapList(node.func_options).map(opt => this.visit(opt, fdwContext));
|
|
6977
6979
|
output.push(funcOptions.join(' '));
|
|
6978
6980
|
}
|
|
6979
6981
|
if (node.options && node.options.length > 0) {
|
|
6980
6982
|
output.push('OPTIONS');
|
|
6981
|
-
const fdwContext =
|
|
6983
|
+
const fdwContext = context.spawn('AlterFdwStmt');
|
|
6982
6984
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, fdwContext));
|
|
6983
6985
|
output.push(`(${options.join(', ')})`);
|
|
6984
6986
|
}
|
|
@@ -7004,7 +7006,7 @@ class Deparser {
|
|
|
7004
7006
|
if (node.options && node.options.length > 0) {
|
|
7005
7007
|
output.push('OPTIONS');
|
|
7006
7008
|
output.push('(');
|
|
7007
|
-
const optionsContext =
|
|
7009
|
+
const optionsContext = context.spawn('CreateForeignServerStmt');
|
|
7008
7010
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, optionsContext));
|
|
7009
7011
|
output.push(options.join(', '));
|
|
7010
7012
|
output.push(')');
|
|
@@ -7022,7 +7024,7 @@ class Deparser {
|
|
|
7022
7024
|
if (node.options && node.options.length > 0) {
|
|
7023
7025
|
output.push('OPTIONS');
|
|
7024
7026
|
output.push('(');
|
|
7025
|
-
const optionsContext =
|
|
7027
|
+
const optionsContext = context.spawn('AlterForeignServerStmt');
|
|
7026
7028
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, optionsContext));
|
|
7027
7029
|
output.push(options.join(', '));
|
|
7028
7030
|
output.push(')');
|
|
@@ -7043,7 +7045,7 @@ class Deparser {
|
|
|
7043
7045
|
}
|
|
7044
7046
|
if (node.options && node.options.length > 0) {
|
|
7045
7047
|
output.push('OPTIONS');
|
|
7046
|
-
const userMappingContext =
|
|
7048
|
+
const userMappingContext = context.spawn('AlterUserMappingStmt');
|
|
7047
7049
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, userMappingContext));
|
|
7048
7050
|
output.push(`(${options.join(', ')})`);
|
|
7049
7051
|
}
|
|
@@ -7103,7 +7105,7 @@ class Deparser {
|
|
|
7103
7105
|
output.push(quote_utils_1.QuoteUtils.quote(node.local_schema));
|
|
7104
7106
|
}
|
|
7105
7107
|
if (node.options && node.options.length > 0) {
|
|
7106
|
-
const importSchemaContext =
|
|
7108
|
+
const importSchemaContext = context.spawn('ImportForeignSchemaStmt');
|
|
7107
7109
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, importSchemaContext));
|
|
7108
7110
|
output.push(`OPTIONS (${options.join(', ')})`);
|
|
7109
7111
|
}
|
|
@@ -7138,7 +7140,7 @@ class Deparser {
|
|
|
7138
7140
|
ExplainStmt(node, context) {
|
|
7139
7141
|
const output = ['EXPLAIN'];
|
|
7140
7142
|
if (node.options && node.options.length > 0) {
|
|
7141
|
-
const explainContext =
|
|
7143
|
+
const explainContext = context.spawn('ExplainStmt');
|
|
7142
7144
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(option => this.visit(option, explainContext));
|
|
7143
7145
|
output.push(`(${options.join(', ')})`);
|
|
7144
7146
|
}
|
|
@@ -7396,9 +7398,7 @@ class Deparser {
|
|
|
7396
7398
|
output.push(this.RangeVar(node.relation, context));
|
|
7397
7399
|
}
|
|
7398
7400
|
else if (node.relation) {
|
|
7399
|
-
const rangeVarContext = node.relationType
|
|
7400
|
-
? { ...context, parentNodeTypes: [...context.parentNodeTypes, 'AlterTypeStmt'] }
|
|
7401
|
-
: context;
|
|
7401
|
+
const rangeVarContext = context.spawn('RenameStmt', { objtype: node.relationType });
|
|
7402
7402
|
// Add ON keyword for policy operations
|
|
7403
7403
|
if (node.renameType === 'OBJECT_POLICY') {
|
|
7404
7404
|
output.push('ON');
|
|
@@ -7580,7 +7580,7 @@ class Deparser {
|
|
|
7580
7580
|
}
|
|
7581
7581
|
}
|
|
7582
7582
|
if (node.privileges && node.privileges.length > 0) {
|
|
7583
|
-
const privilegeContext =
|
|
7583
|
+
const privilegeContext = context.spawn('GrantStmt');
|
|
7584
7584
|
const privileges = list_utils_1.ListUtils.unwrapList(node.privileges)
|
|
7585
7585
|
.map(priv => this.visit(priv, privilegeContext))
|
|
7586
7586
|
.join(', ');
|
|
@@ -7888,8 +7888,8 @@ class Deparser {
|
|
|
7888
7888
|
}
|
|
7889
7889
|
if (node.action) {
|
|
7890
7890
|
const actionStr = this.GrantStmt(node.action, context);
|
|
7891
|
-
if (
|
|
7892
|
-
return output.join(' ') +
|
|
7891
|
+
if (context.isPretty()) {
|
|
7892
|
+
return output.join(' ') + context.newline() + context.indent(actionStr);
|
|
7893
7893
|
}
|
|
7894
7894
|
else {
|
|
7895
7895
|
output.push(actionStr);
|
|
@@ -8040,7 +8040,7 @@ class Deparser {
|
|
|
8040
8040
|
if (node.trigname) {
|
|
8041
8041
|
output.push(quote_utils_1.QuoteUtils.quote(node.trigname));
|
|
8042
8042
|
}
|
|
8043
|
-
if (
|
|
8043
|
+
if (context.isPretty()) {
|
|
8044
8044
|
const components = [];
|
|
8045
8045
|
const timing = [];
|
|
8046
8046
|
if (node.timing & 2)
|
|
@@ -8066,31 +8066,31 @@ class Deparser {
|
|
|
8066
8066
|
}
|
|
8067
8067
|
if (node.events & 32)
|
|
8068
8068
|
events.push('TRUNCATE');
|
|
8069
|
-
components.push(
|
|
8069
|
+
components.push(context.indent(timing.join(' ') + ' ' + events.join(' OR ')));
|
|
8070
8070
|
if (node.relation) {
|
|
8071
|
-
components.push(
|
|
8071
|
+
components.push(context.indent('ON ' + this.RangeVar(node.relation, context)));
|
|
8072
8072
|
}
|
|
8073
8073
|
if (node.transitionRels && node.transitionRels.length > 0) {
|
|
8074
8074
|
const transitionClauses = list_utils_1.ListUtils.unwrapList(node.transitionRels)
|
|
8075
8075
|
.map(rel => this.visit(rel, context))
|
|
8076
8076
|
.join(' ');
|
|
8077
|
-
components.push(
|
|
8077
|
+
components.push(context.indent('REFERENCING ' + transitionClauses));
|
|
8078
8078
|
}
|
|
8079
8079
|
if (node.deferrable) {
|
|
8080
|
-
components.push(
|
|
8080
|
+
components.push(context.indent('DEFERRABLE'));
|
|
8081
8081
|
}
|
|
8082
8082
|
if (node.initdeferred) {
|
|
8083
|
-
components.push(
|
|
8083
|
+
components.push(context.indent('INITIALLY DEFERRED'));
|
|
8084
8084
|
}
|
|
8085
8085
|
if (node.row) {
|
|
8086
|
-
components.push(
|
|
8086
|
+
components.push(context.indent('FOR EACH ROW'));
|
|
8087
8087
|
}
|
|
8088
8088
|
else {
|
|
8089
|
-
components.push(
|
|
8089
|
+
components.push(context.indent('FOR EACH STATEMENT'));
|
|
8090
8090
|
}
|
|
8091
8091
|
if (node.whenClause) {
|
|
8092
8092
|
const whenStr = 'WHEN (' + this.visit(node.whenClause, context) + ')';
|
|
8093
|
-
components.push(
|
|
8093
|
+
components.push(context.indent(whenStr));
|
|
8094
8094
|
}
|
|
8095
8095
|
let executeStr = 'EXECUTE';
|
|
8096
8096
|
if (node.funcname && node.funcname.length > 0) {
|
|
@@ -8100,7 +8100,7 @@ class Deparser {
|
|
|
8100
8100
|
executeStr += ' PROCEDURE ' + funcName;
|
|
8101
8101
|
}
|
|
8102
8102
|
if (node.args && node.args.length > 0) {
|
|
8103
|
-
const argContext =
|
|
8103
|
+
const argContext = context.spawn('CreateTrigStmt', { isStringLiteral: true });
|
|
8104
8104
|
const args = list_utils_1.ListUtils.unwrapList(node.args)
|
|
8105
8105
|
.map(arg => this.visit(arg, argContext))
|
|
8106
8106
|
.join(', ');
|
|
@@ -8109,8 +8109,8 @@ class Deparser {
|
|
|
8109
8109
|
else {
|
|
8110
8110
|
executeStr += '()';
|
|
8111
8111
|
}
|
|
8112
|
-
components.push(
|
|
8113
|
-
return output.join(' ') +
|
|
8112
|
+
components.push(context.indent(executeStr));
|
|
8113
|
+
return output.join(' ') + context.newline() + components.join(context.newline());
|
|
8114
8114
|
}
|
|
8115
8115
|
else {
|
|
8116
8116
|
const timing = [];
|
|
@@ -8180,7 +8180,7 @@ class Deparser {
|
|
|
8180
8180
|
}
|
|
8181
8181
|
if (node.args && node.args.length > 0) {
|
|
8182
8182
|
output.push('(');
|
|
8183
|
-
const argContext =
|
|
8183
|
+
const argContext = context.spawn('CreateTrigStmt', { isStringLiteral: true });
|
|
8184
8184
|
const args = list_utils_1.ListUtils.unwrapList(node.args)
|
|
8185
8185
|
.map(arg => this.visit(arg, argContext))
|
|
8186
8186
|
.join(', ');
|
|
@@ -8217,7 +8217,7 @@ class Deparser {
|
|
|
8217
8217
|
}
|
|
8218
8218
|
if (node.whenclause && node.whenclause.length > 0) {
|
|
8219
8219
|
output.push('WHEN');
|
|
8220
|
-
const eventTriggerContext =
|
|
8220
|
+
const eventTriggerContext = context.spawn('CreateEventTrigStmt');
|
|
8221
8221
|
const conditions = list_utils_1.ListUtils.unwrapList(node.whenclause)
|
|
8222
8222
|
.map(condition => this.visit(condition, eventTriggerContext))
|
|
8223
8223
|
.join(' AND ');
|
|
@@ -8406,7 +8406,7 @@ class Deparser {
|
|
|
8406
8406
|
output.push(sequenceName.join('.'));
|
|
8407
8407
|
}
|
|
8408
8408
|
if (node.options && node.options.length > 0) {
|
|
8409
|
-
const seqContext =
|
|
8409
|
+
const seqContext = context.spawn('CreateSeqStmt');
|
|
8410
8410
|
const optionStrs = list_utils_1.ListUtils.unwrapList(node.options)
|
|
8411
8411
|
.filter(option => option != null && this.getNodeType(option) !== 'undefined')
|
|
8412
8412
|
.map(option => {
|
|
@@ -8443,7 +8443,7 @@ class Deparser {
|
|
|
8443
8443
|
output.push(sequenceName.join('.'));
|
|
8444
8444
|
}
|
|
8445
8445
|
if (node.options && node.options.length > 0) {
|
|
8446
|
-
const seqContext =
|
|
8446
|
+
const seqContext = context.spawn('AlterSeqStmt');
|
|
8447
8447
|
const optionStrs = list_utils_1.ListUtils.unwrapList(node.options)
|
|
8448
8448
|
.filter(option => option && option !== undefined)
|
|
8449
8449
|
.map(option => {
|
|
@@ -8472,7 +8472,7 @@ class Deparser {
|
|
|
8472
8472
|
CompositeTypeStmt(node, context) {
|
|
8473
8473
|
const output = ['CREATE', 'TYPE'];
|
|
8474
8474
|
if (node.typevar) {
|
|
8475
|
-
const typeContext =
|
|
8475
|
+
const typeContext = context.spawn('CompositeTypeStmt');
|
|
8476
8476
|
output.push(this.RangeVar(node.typevar, typeContext));
|
|
8477
8477
|
}
|
|
8478
8478
|
output.push('AS');
|
|
@@ -8573,7 +8573,7 @@ class Deparser {
|
|
|
8573
8573
|
output.push(this.RoleSpec(node.role, context));
|
|
8574
8574
|
}
|
|
8575
8575
|
if (node.options) {
|
|
8576
|
-
const roleContext =
|
|
8576
|
+
const roleContext = context.spawn('AlterRoleStmt');
|
|
8577
8577
|
// Handle GROUP operations specially based on action value
|
|
8578
8578
|
if (isGroupStatement) {
|
|
8579
8579
|
const roleMembersOption = list_utils_1.ListUtils.unwrapList(node.options).find(option => option.DefElem && option.DefElem.defname === 'rolemembers');
|
|
@@ -8776,7 +8776,7 @@ class Deparser {
|
|
|
8776
8776
|
}
|
|
8777
8777
|
if (node.cols && node.cols.length > 0) {
|
|
8778
8778
|
output.push('(');
|
|
8779
|
-
const colContext =
|
|
8779
|
+
const colContext = context.spawn('AccessPriv');
|
|
8780
8780
|
const columns = list_utils_1.ListUtils.unwrapList(node.cols).map(col => this.visit(col, colContext));
|
|
8781
8781
|
output.push(columns.join(', '));
|
|
8782
8782
|
output.push(')');
|
|
@@ -8856,7 +8856,7 @@ class Deparser {
|
|
|
8856
8856
|
output.push(list_utils_1.ListUtils.unwrapList(node.defnames).map(name => this.visit(name, context)).join('.'));
|
|
8857
8857
|
}
|
|
8858
8858
|
if (node.definition && node.definition.length > 0) {
|
|
8859
|
-
const defineStmtContext =
|
|
8859
|
+
const defineStmtContext = context.spawn('DefineStmt');
|
|
8860
8860
|
const definitions = list_utils_1.ListUtils.unwrapList(node.definition).map(def => {
|
|
8861
8861
|
return this.visit(def, defineStmtContext);
|
|
8862
8862
|
});
|
|
@@ -9342,7 +9342,7 @@ class Deparser {
|
|
|
9342
9342
|
const operatorNumber = node.number !== undefined ? node.number : 0;
|
|
9343
9343
|
output.push(operatorNumber.toString());
|
|
9344
9344
|
if (node.name) {
|
|
9345
|
-
const opClassContext =
|
|
9345
|
+
const opClassContext = context.spawn('CreateOpClassItem');
|
|
9346
9346
|
output.push(this.ObjectWithArgs(node.name, opClassContext));
|
|
9347
9347
|
}
|
|
9348
9348
|
}
|
|
@@ -9352,7 +9352,7 @@ class Deparser {
|
|
|
9352
9352
|
const functionNumber = node.number !== undefined ? node.number : 0;
|
|
9353
9353
|
output.push(functionNumber.toString());
|
|
9354
9354
|
if (node.name) {
|
|
9355
|
-
const opClassContext =
|
|
9355
|
+
const opClassContext = context.spawn('CreateOpClassItem');
|
|
9356
9356
|
output.push(this.ObjectWithArgs(node.name, opClassContext));
|
|
9357
9357
|
}
|
|
9358
9358
|
}
|
|
@@ -10050,7 +10050,7 @@ class Deparser {
|
|
|
10050
10050
|
output.push(this.ObjectWithArgs(node.func, context));
|
|
10051
10051
|
}
|
|
10052
10052
|
if (node.actions && node.actions.length > 0) {
|
|
10053
|
-
const alterFunctionContext =
|
|
10053
|
+
const alterFunctionContext = context.spawn('AlterFunctionStmt');
|
|
10054
10054
|
const actionStrs = list_utils_1.ListUtils.unwrapList(node.actions).map(action => this.visit(action, alterFunctionContext));
|
|
10055
10055
|
output.push(actionStrs.join(' '));
|
|
10056
10056
|
}
|
|
@@ -10294,7 +10294,7 @@ class Deparser {
|
|
|
10294
10294
|
CreateForeignTableStmt(node, context) {
|
|
10295
10295
|
const output = ['CREATE FOREIGN TABLE'];
|
|
10296
10296
|
if (node.base && node.base.relation) {
|
|
10297
|
-
const relationContext =
|
|
10297
|
+
const relationContext = context.spawn('CreateForeignTableStmt');
|
|
10298
10298
|
// Handle relation node directly as RangeVar since it contains the RangeVar properties
|
|
10299
10299
|
output.push(this.RangeVar(node.base.relation, relationContext));
|
|
10300
10300
|
}
|
|
@@ -10324,7 +10324,7 @@ class Deparser {
|
|
|
10324
10324
|
output.push(quote_utils_1.QuoteUtils.quote(node.servername));
|
|
10325
10325
|
}
|
|
10326
10326
|
if (node.options && node.options.length > 0) {
|
|
10327
|
-
const foreignTableContext =
|
|
10327
|
+
const foreignTableContext = context.spawn('CreateForeignTableStmt');
|
|
10328
10328
|
const optionStrs = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, foreignTableContext));
|
|
10329
10329
|
output.push(`OPTIONS (${optionStrs.join(', ')})`);
|
|
10330
10330
|
}
|