pgsql-deparser 17.8.1 → 17.8.3
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/deparser.d.ts +4 -3
- package/deparser.js +742 -405
- package/esm/deparser.js +742 -405
- package/esm/visitors/base.js +87 -0
- package/package.json +3 -3
- package/visitors/base.d.ts +49 -2
- package/visitors/base.js +89 -1
package/deparser.js
CHANGED
|
@@ -1,9 +1,66 @@
|
|
|
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");
|
|
8
|
+
/**
|
|
9
|
+
* List of real PostgreSQL built-in types as they appear in pg_catalog.pg_type.typname.
|
|
10
|
+
* These are stored in lowercase in PostgreSQL system catalogs.
|
|
11
|
+
* Use these for lookups, validations, or introspection logic.
|
|
12
|
+
*/
|
|
13
|
+
const pgCatalogTypes = [
|
|
14
|
+
// Integers
|
|
15
|
+
'int2', // smallint
|
|
16
|
+
'int4', // integer
|
|
17
|
+
'int8', // bigint
|
|
18
|
+
// Floating-point & numeric
|
|
19
|
+
'float4', // real
|
|
20
|
+
'float8', // double precision
|
|
21
|
+
'numeric', // arbitrary precision (aka "decimal")
|
|
22
|
+
// Text & string
|
|
23
|
+
'varchar', // variable-length string
|
|
24
|
+
'char', // internal one-byte type (used in special cases)
|
|
25
|
+
'bpchar', // blank-padded char(n)
|
|
26
|
+
'text', // unlimited string
|
|
27
|
+
'bool', // boolean
|
|
28
|
+
// Dates & times
|
|
29
|
+
'date', // calendar date
|
|
30
|
+
'time', // time without time zone
|
|
31
|
+
'timetz', // time with time zone
|
|
32
|
+
'timestamp', // timestamp without time zone
|
|
33
|
+
'timestamptz', // timestamp with time zone
|
|
34
|
+
'interval', // duration
|
|
35
|
+
// Binary & structured
|
|
36
|
+
'bytea', // binary data
|
|
37
|
+
'uuid', // universally unique identifier
|
|
38
|
+
// JSON & XML
|
|
39
|
+
'json', // textual JSON
|
|
40
|
+
'jsonb', // binary JSON
|
|
41
|
+
'xml', // XML format
|
|
42
|
+
// Money & bitstrings
|
|
43
|
+
'money', // currency value
|
|
44
|
+
'bit', // fixed-length bit string
|
|
45
|
+
'varbit', // variable-length bit string
|
|
46
|
+
// Network types
|
|
47
|
+
'inet', // IPv4 or IPv6 address
|
|
48
|
+
'cidr', // network address
|
|
49
|
+
'macaddr', // MAC address (6 bytes)
|
|
50
|
+
'macaddr8' // MAC address (8 bytes)
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Parser-level type aliases accepted by PostgreSQL SQL syntax,
|
|
54
|
+
* but not present in pg_catalog.pg_type. These are resolved to
|
|
55
|
+
* real types during parsing and never appear in introspection.
|
|
56
|
+
*/
|
|
57
|
+
const pgCatalogTypeAliases = [
|
|
58
|
+
['numeric', ['decimal', 'dec']],
|
|
59
|
+
['int4', ['int', 'integer']],
|
|
60
|
+
['float8', ['float']],
|
|
61
|
+
['bpchar', ['character']],
|
|
62
|
+
['varchar', ['character varying']]
|
|
63
|
+
];
|
|
7
64
|
// Type guards for better type safety
|
|
8
65
|
function isParseResult(obj) {
|
|
9
66
|
// A ParseResult is an object that could have stmts (but not required)
|
|
@@ -47,11 +104,9 @@ function isWrappedParseResult(obj) {
|
|
|
47
104
|
* compatibility and wraps them internally for consistent processing.
|
|
48
105
|
*/
|
|
49
106
|
class Deparser {
|
|
50
|
-
formatter;
|
|
51
107
|
tree;
|
|
52
108
|
options;
|
|
53
109
|
constructor(tree, opts = {}) {
|
|
54
|
-
this.formatter = new sql_formatter_1.SqlFormatter(opts.newline, opts.tab, opts.pretty);
|
|
55
110
|
// Set default options
|
|
56
111
|
this.options = {
|
|
57
112
|
functionDelimiter: '$$',
|
|
@@ -88,15 +143,17 @@ class Deparser {
|
|
|
88
143
|
return new Deparser(query, opts).deparseQuery();
|
|
89
144
|
}
|
|
90
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 });
|
|
91
148
|
return this.tree
|
|
92
149
|
.map(node => {
|
|
93
150
|
// All nodes should go through the standard deparse method
|
|
94
151
|
// which will route to the appropriate handler
|
|
95
|
-
const result = this.deparse(node);
|
|
152
|
+
const result = this.deparse(node, context);
|
|
96
153
|
return result || '';
|
|
97
154
|
})
|
|
98
155
|
.filter(result => result !== '')
|
|
99
|
-
.join(
|
|
156
|
+
.join(context.newline() + context.newline());
|
|
100
157
|
}
|
|
101
158
|
/**
|
|
102
159
|
* Get the appropriate function delimiter based on the body content
|
|
@@ -110,10 +167,14 @@ class Deparser {
|
|
|
110
167
|
}
|
|
111
168
|
return delimiter;
|
|
112
169
|
}
|
|
113
|
-
deparse(node, context
|
|
170
|
+
deparse(node, context) {
|
|
114
171
|
if (node == null) {
|
|
115
172
|
return null;
|
|
116
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
|
+
}
|
|
117
178
|
if (typeof node === 'number' || node instanceof Number) {
|
|
118
179
|
return node.toString();
|
|
119
180
|
}
|
|
@@ -125,7 +186,11 @@ class Deparser {
|
|
|
125
186
|
throw new Error(`Error deparsing ${nodeType}: ${error.message}`);
|
|
126
187
|
}
|
|
127
188
|
}
|
|
128
|
-
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
|
+
}
|
|
129
194
|
const nodeType = this.getNodeType(node);
|
|
130
195
|
// Handle empty objects
|
|
131
196
|
if (!nodeType) {
|
|
@@ -134,11 +199,7 @@ class Deparser {
|
|
|
134
199
|
const nodeData = this.getNodeData(node);
|
|
135
200
|
const methodName = nodeType;
|
|
136
201
|
if (typeof this[methodName] === 'function') {
|
|
137
|
-
const
|
|
138
|
-
...context,
|
|
139
|
-
parentNodeTypes: [...context.parentNodeTypes, nodeType]
|
|
140
|
-
};
|
|
141
|
-
const result = this[methodName](nodeData, childContext);
|
|
202
|
+
const result = this[methodName](nodeData, context);
|
|
142
203
|
return result;
|
|
143
204
|
}
|
|
144
205
|
throw new Error(`Deparser does not handle node type: ${nodeType}`);
|
|
@@ -164,7 +225,7 @@ class Deparser {
|
|
|
164
225
|
.filter((rawStmt) => rawStmt != null)
|
|
165
226
|
.map((rawStmt) => this.RawStmt(rawStmt, context))
|
|
166
227
|
.filter((result) => result !== '')
|
|
167
|
-
.join(
|
|
228
|
+
.join(context.newline() + context.newline());
|
|
168
229
|
}
|
|
169
230
|
RawStmt(node, context) {
|
|
170
231
|
if (!node.stmt) {
|
|
@@ -184,7 +245,7 @@ class Deparser {
|
|
|
184
245
|
}
|
|
185
246
|
if (!node.op || node.op === 'SETOP_NONE') {
|
|
186
247
|
if (node.valuesLists == null) {
|
|
187
|
-
if (!
|
|
248
|
+
if (!context.isPretty() || !node.targetList) {
|
|
188
249
|
output.push('SELECT');
|
|
189
250
|
}
|
|
190
251
|
}
|
|
@@ -204,7 +265,7 @@ class Deparser {
|
|
|
204
265
|
node.rarg.limitOffset ||
|
|
205
266
|
node.rarg.withClause);
|
|
206
267
|
if (leftNeedsParens) {
|
|
207
|
-
output.push(
|
|
268
|
+
output.push(context.parens(leftStmt));
|
|
208
269
|
}
|
|
209
270
|
else {
|
|
210
271
|
output.push(leftStmt);
|
|
@@ -226,7 +287,7 @@ class Deparser {
|
|
|
226
287
|
output.push('ALL');
|
|
227
288
|
}
|
|
228
289
|
if (rightNeedsParens) {
|
|
229
|
-
output.push(
|
|
290
|
+
output.push(context.parens(rightStmt));
|
|
230
291
|
}
|
|
231
292
|
else {
|
|
232
293
|
output.push(rightStmt);
|
|
@@ -238,20 +299,20 @@ class Deparser {
|
|
|
238
299
|
const distinctClause = list_utils_1.ListUtils.unwrapList(node.distinctClause);
|
|
239
300
|
if (distinctClause.length > 0 && Object.keys(distinctClause[0]).length > 0) {
|
|
240
301
|
const clause = distinctClause
|
|
241
|
-
.map(e => this.visit(e,
|
|
302
|
+
.map(e => this.visit(e, context.spawn('SelectStmt', { select: true })))
|
|
242
303
|
.join(', ');
|
|
243
|
-
distinctPart = ' DISTINCT ON ' +
|
|
304
|
+
distinctPart = ' DISTINCT ON ' + context.parens(clause);
|
|
244
305
|
}
|
|
245
306
|
else {
|
|
246
307
|
distinctPart = ' DISTINCT';
|
|
247
308
|
}
|
|
248
|
-
if (!
|
|
309
|
+
if (!context.isPretty()) {
|
|
249
310
|
if (distinctClause.length > 0 && Object.keys(distinctClause[0]).length > 0) {
|
|
250
311
|
output.push('DISTINCT ON');
|
|
251
312
|
const clause = distinctClause
|
|
252
|
-
.map(e => this.visit(e,
|
|
313
|
+
.map(e => this.visit(e, context.spawn('SelectStmt', { select: true })))
|
|
253
314
|
.join(', ');
|
|
254
|
-
output.push(
|
|
315
|
+
output.push(context.parens(clause));
|
|
255
316
|
}
|
|
256
317
|
else {
|
|
257
318
|
output.push('DISTINCT');
|
|
@@ -260,22 +321,41 @@ class Deparser {
|
|
|
260
321
|
}
|
|
261
322
|
if (node.targetList) {
|
|
262
323
|
const targetList = list_utils_1.ListUtils.unwrapList(node.targetList);
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const
|
|
267
|
-
if
|
|
268
|
-
|
|
324
|
+
if (context.isPretty()) {
|
|
325
|
+
if (targetList.length === 1) {
|
|
326
|
+
const targetNode = targetList[0];
|
|
327
|
+
const target = this.visit(targetNode, context.spawn('SelectStmt', { select: true }));
|
|
328
|
+
// Check if single target is complex - if so, use multiline format
|
|
329
|
+
if (this.isComplexSelectTarget(targetNode)) {
|
|
330
|
+
output.push('SELECT' + distinctPart);
|
|
331
|
+
if (this.containsMultilineStringLiteral(target)) {
|
|
332
|
+
output.push(target);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
output.push(context.indent(target));
|
|
336
|
+
}
|
|
269
337
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
338
|
+
else {
|
|
339
|
+
output.push('SELECT' + distinctPart + ' ' + target);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
const targetStrings = targetList
|
|
344
|
+
.map(e => {
|
|
345
|
+
const targetStr = this.visit(e, context.spawn('SelectStmt', { select: true }));
|
|
346
|
+
if (this.containsMultilineStringLiteral(targetStr)) {
|
|
347
|
+
return targetStr;
|
|
348
|
+
}
|
|
349
|
+
return context.indent(targetStr);
|
|
350
|
+
});
|
|
351
|
+
const formattedTargets = targetStrings.join(',' + context.newline());
|
|
352
|
+
output.push('SELECT' + distinctPart);
|
|
353
|
+
output.push(formattedTargets);
|
|
354
|
+
}
|
|
275
355
|
}
|
|
276
356
|
else {
|
|
277
357
|
const targets = targetList
|
|
278
|
-
.map(e => this.visit(e,
|
|
358
|
+
.map(e => this.visit(e, context.spawn('SelectStmt', { select: true })))
|
|
279
359
|
.join(', ');
|
|
280
360
|
output.push(targets);
|
|
281
361
|
}
|
|
@@ -287,22 +367,22 @@ class Deparser {
|
|
|
287
367
|
if (node.fromClause) {
|
|
288
368
|
const fromList = list_utils_1.ListUtils.unwrapList(node.fromClause);
|
|
289
369
|
const fromItems = fromList
|
|
290
|
-
.map(e => this.deparse(e,
|
|
370
|
+
.map(e => this.deparse(e, context.spawn('SelectStmt', { from: true })))
|
|
291
371
|
.join(', ');
|
|
292
372
|
output.push('FROM ' + fromItems.trim());
|
|
293
373
|
}
|
|
294
374
|
if (node.whereClause) {
|
|
295
|
-
if (
|
|
375
|
+
if (context.isPretty()) {
|
|
296
376
|
output.push('WHERE');
|
|
297
377
|
const whereExpr = this.visit(node.whereClause, context);
|
|
298
|
-
const lines = whereExpr.split(
|
|
378
|
+
const lines = whereExpr.split(context.newline());
|
|
299
379
|
const indentedLines = lines.map((line, index) => {
|
|
300
380
|
if (index === 0) {
|
|
301
|
-
return
|
|
381
|
+
return context.indent(line);
|
|
302
382
|
}
|
|
303
383
|
return line;
|
|
304
384
|
});
|
|
305
|
-
output.push(indentedLines.join(
|
|
385
|
+
output.push(indentedLines.join(context.newline()));
|
|
306
386
|
}
|
|
307
387
|
else {
|
|
308
388
|
output.push('WHERE');
|
|
@@ -310,45 +390,61 @@ class Deparser {
|
|
|
310
390
|
}
|
|
311
391
|
}
|
|
312
392
|
if (node.valuesLists) {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
393
|
+
if (context.isPretty()) {
|
|
394
|
+
output.push('VALUES');
|
|
395
|
+
const lists = list_utils_1.ListUtils.unwrapList(node.valuesLists).map(list => {
|
|
396
|
+
const values = list_utils_1.ListUtils.unwrapList(list).map(val => this.visit(val, context));
|
|
397
|
+
return context.parens(values.join(', '));
|
|
398
|
+
});
|
|
399
|
+
const indentedTuples = lists.map(tuple => {
|
|
400
|
+
if (this.containsMultilineStringLiteral(tuple)) {
|
|
401
|
+
return tuple;
|
|
402
|
+
}
|
|
403
|
+
return context.indent(tuple);
|
|
404
|
+
});
|
|
405
|
+
output.push(indentedTuples.join(',\n'));
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
output.push('VALUES');
|
|
409
|
+
const lists = list_utils_1.ListUtils.unwrapList(node.valuesLists).map(list => {
|
|
410
|
+
const values = list_utils_1.ListUtils.unwrapList(list).map(val => this.visit(val, context));
|
|
411
|
+
return context.parens(values.join(', '));
|
|
412
|
+
});
|
|
413
|
+
output.push(lists.join(', '));
|
|
414
|
+
}
|
|
319
415
|
}
|
|
320
416
|
if (node.groupClause) {
|
|
321
417
|
const groupList = list_utils_1.ListUtils.unwrapList(node.groupClause);
|
|
322
|
-
if (
|
|
418
|
+
if (context.isPretty()) {
|
|
323
419
|
const groupItems = groupList
|
|
324
420
|
.map(e => {
|
|
325
|
-
const groupStr = this.visit(e,
|
|
421
|
+
const groupStr = this.visit(e, context.spawn('SelectStmt', { group: true, indentLevel: context.indentLevel + 1 }));
|
|
326
422
|
if (this.containsMultilineStringLiteral(groupStr)) {
|
|
327
423
|
return groupStr;
|
|
328
424
|
}
|
|
329
|
-
return
|
|
425
|
+
return context.indent(groupStr);
|
|
330
426
|
})
|
|
331
|
-
.join(',' +
|
|
427
|
+
.join(',' + context.newline());
|
|
332
428
|
output.push('GROUP BY');
|
|
333
429
|
output.push(groupItems);
|
|
334
430
|
}
|
|
335
431
|
else {
|
|
336
432
|
output.push('GROUP BY');
|
|
337
433
|
const groupItems = groupList
|
|
338
|
-
.map(e => this.visit(e,
|
|
434
|
+
.map(e => this.visit(e, context.spawn('SelectStmt', { group: true })))
|
|
339
435
|
.join(', ');
|
|
340
436
|
output.push(groupItems);
|
|
341
437
|
}
|
|
342
438
|
}
|
|
343
439
|
if (node.havingClause) {
|
|
344
|
-
if (
|
|
440
|
+
if (context.isPretty()) {
|
|
345
441
|
output.push('HAVING');
|
|
346
442
|
const havingStr = this.visit(node.havingClause, context);
|
|
347
443
|
if (this.containsMultilineStringLiteral(havingStr)) {
|
|
348
444
|
output.push(havingStr);
|
|
349
445
|
}
|
|
350
446
|
else {
|
|
351
|
-
output.push(
|
|
447
|
+
output.push(context.indent(havingStr));
|
|
352
448
|
}
|
|
353
449
|
}
|
|
354
450
|
else {
|
|
@@ -366,23 +462,23 @@ class Deparser {
|
|
|
366
462
|
}
|
|
367
463
|
if (node.sortClause) {
|
|
368
464
|
const sortList = list_utils_1.ListUtils.unwrapList(node.sortClause);
|
|
369
|
-
if (
|
|
465
|
+
if (context.isPretty()) {
|
|
370
466
|
const sortItems = sortList
|
|
371
467
|
.map(e => {
|
|
372
|
-
const sortStr = this.visit(e,
|
|
468
|
+
const sortStr = this.visit(e, context.spawn('SelectStmt', { sort: true, indentLevel: context.indentLevel + 1 }));
|
|
373
469
|
if (this.containsMultilineStringLiteral(sortStr)) {
|
|
374
470
|
return sortStr;
|
|
375
471
|
}
|
|
376
|
-
return
|
|
472
|
+
return context.indent(sortStr);
|
|
377
473
|
})
|
|
378
|
-
.join(',' +
|
|
474
|
+
.join(',' + context.newline());
|
|
379
475
|
output.push('ORDER BY');
|
|
380
476
|
output.push(sortItems);
|
|
381
477
|
}
|
|
382
478
|
else {
|
|
383
479
|
output.push('ORDER BY');
|
|
384
480
|
const sortItems = sortList
|
|
385
|
-
.map(e => this.visit(e,
|
|
481
|
+
.map(e => this.visit(e, context.spawn('SelectStmt', { sort: true })))
|
|
386
482
|
.join(', ');
|
|
387
483
|
output.push(sortItems);
|
|
388
484
|
}
|
|
@@ -400,9 +496,9 @@ class Deparser {
|
|
|
400
496
|
.join(' ');
|
|
401
497
|
output.push(lockingClauses);
|
|
402
498
|
}
|
|
403
|
-
if (
|
|
499
|
+
if (context.isPretty()) {
|
|
404
500
|
const filteredOutput = output.filter(item => item.trim() !== '');
|
|
405
|
-
return filteredOutput.join(
|
|
501
|
+
return filteredOutput.join(context.newline());
|
|
406
502
|
}
|
|
407
503
|
return output.join(' ');
|
|
408
504
|
}
|
|
@@ -414,13 +510,13 @@ class Deparser {
|
|
|
414
510
|
switch (kind) {
|
|
415
511
|
case 'AEXPR_OP':
|
|
416
512
|
if (lexpr && rexpr) {
|
|
417
|
-
const operator = this.deparseOperatorName(name);
|
|
513
|
+
const operator = this.deparseOperatorName(name, context);
|
|
418
514
|
let leftExpr = this.visit(lexpr, context);
|
|
419
515
|
let rightExpr = this.visit(rexpr, context);
|
|
420
516
|
// Check if left expression needs parentheses
|
|
421
517
|
let leftNeedsParens = false;
|
|
422
518
|
if (lexpr && 'A_Expr' in lexpr && lexpr.A_Expr?.kind === 'AEXPR_OP') {
|
|
423
|
-
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);
|
|
424
520
|
if (this.needsParentheses(leftOp, operator, 'left')) {
|
|
425
521
|
leftNeedsParens = true;
|
|
426
522
|
}
|
|
@@ -429,12 +525,12 @@ class Deparser {
|
|
|
429
525
|
leftNeedsParens = true;
|
|
430
526
|
}
|
|
431
527
|
if (leftNeedsParens) {
|
|
432
|
-
leftExpr =
|
|
528
|
+
leftExpr = context.parens(leftExpr);
|
|
433
529
|
}
|
|
434
530
|
// Check if right expression needs parentheses
|
|
435
531
|
let rightNeedsParens = false;
|
|
436
532
|
if (rexpr && 'A_Expr' in rexpr && rexpr.A_Expr?.kind === 'AEXPR_OP') {
|
|
437
|
-
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);
|
|
438
534
|
if (this.needsParentheses(rightOp, operator, 'right')) {
|
|
439
535
|
rightNeedsParens = true;
|
|
440
536
|
}
|
|
@@ -443,42 +539,42 @@ class Deparser {
|
|
|
443
539
|
rightNeedsParens = true;
|
|
444
540
|
}
|
|
445
541
|
if (rightNeedsParens) {
|
|
446
|
-
rightExpr =
|
|
542
|
+
rightExpr = context.parens(rightExpr);
|
|
447
543
|
}
|
|
448
|
-
return
|
|
544
|
+
return context.format([leftExpr, operator, rightExpr]);
|
|
449
545
|
}
|
|
450
546
|
else if (rexpr) {
|
|
451
|
-
return
|
|
452
|
-
this.deparseOperatorName(name),
|
|
547
|
+
return context.format([
|
|
548
|
+
this.deparseOperatorName(name, context),
|
|
453
549
|
this.visit(rexpr, context)
|
|
454
550
|
]);
|
|
455
551
|
}
|
|
456
552
|
break;
|
|
457
553
|
case 'AEXPR_OP_ANY':
|
|
458
|
-
return
|
|
554
|
+
return context.format([
|
|
459
555
|
this.visit(lexpr, context),
|
|
460
|
-
this.deparseOperatorName(name),
|
|
556
|
+
this.deparseOperatorName(name, context),
|
|
461
557
|
'ANY',
|
|
462
|
-
|
|
558
|
+
context.parens(this.visit(rexpr, context))
|
|
463
559
|
]);
|
|
464
560
|
case 'AEXPR_OP_ALL':
|
|
465
|
-
return
|
|
561
|
+
return context.format([
|
|
466
562
|
this.visit(lexpr, context),
|
|
467
|
-
this.deparseOperatorName(name),
|
|
563
|
+
this.deparseOperatorName(name, context),
|
|
468
564
|
'ALL',
|
|
469
|
-
|
|
565
|
+
context.parens(this.visit(rexpr, context))
|
|
470
566
|
]);
|
|
471
567
|
case 'AEXPR_DISTINCT': {
|
|
472
568
|
let leftExpr = this.visit(lexpr, context);
|
|
473
569
|
let rightExpr = this.visit(rexpr, context);
|
|
474
570
|
// Add parentheses for complex expressions
|
|
475
571
|
if (lexpr && this.isComplexExpression(lexpr)) {
|
|
476
|
-
leftExpr =
|
|
572
|
+
leftExpr = context.parens(leftExpr);
|
|
477
573
|
}
|
|
478
574
|
if (rexpr && this.isComplexExpression(rexpr)) {
|
|
479
|
-
rightExpr =
|
|
575
|
+
rightExpr = context.parens(rightExpr);
|
|
480
576
|
}
|
|
481
|
-
return
|
|
577
|
+
return context.format([
|
|
482
578
|
leftExpr,
|
|
483
579
|
'IS DISTINCT FROM',
|
|
484
580
|
rightExpr
|
|
@@ -489,75 +585,75 @@ class Deparser {
|
|
|
489
585
|
let rightExpr = this.visit(rexpr, context);
|
|
490
586
|
// Add parentheses for complex expressions
|
|
491
587
|
if (lexpr && this.isComplexExpression(lexpr)) {
|
|
492
|
-
leftExpr =
|
|
588
|
+
leftExpr = context.parens(leftExpr);
|
|
493
589
|
}
|
|
494
590
|
if (rexpr && this.isComplexExpression(rexpr)) {
|
|
495
|
-
rightExpr =
|
|
591
|
+
rightExpr = context.parens(rightExpr);
|
|
496
592
|
}
|
|
497
|
-
return
|
|
593
|
+
return context.format([
|
|
498
594
|
leftExpr,
|
|
499
595
|
'IS NOT DISTINCT FROM',
|
|
500
596
|
rightExpr
|
|
501
597
|
]);
|
|
502
598
|
}
|
|
503
599
|
case 'AEXPR_NULLIF':
|
|
504
|
-
return
|
|
600
|
+
return context.format([
|
|
505
601
|
'NULLIF',
|
|
506
|
-
|
|
602
|
+
context.parens([
|
|
507
603
|
this.visit(lexpr, context),
|
|
508
604
|
this.visit(rexpr, context)
|
|
509
605
|
].join(', '))
|
|
510
606
|
]);
|
|
511
607
|
case 'AEXPR_IN':
|
|
512
|
-
const inOperator = this.deparseOperatorName(name);
|
|
608
|
+
const inOperator = this.deparseOperatorName(name, context);
|
|
513
609
|
if (inOperator === '<>' || inOperator === '!=') {
|
|
514
|
-
return
|
|
610
|
+
return context.format([
|
|
515
611
|
this.visit(lexpr, context),
|
|
516
612
|
'NOT IN',
|
|
517
|
-
|
|
613
|
+
context.parens(this.visit(rexpr, context))
|
|
518
614
|
]);
|
|
519
615
|
}
|
|
520
616
|
else {
|
|
521
|
-
return
|
|
617
|
+
return context.format([
|
|
522
618
|
this.visit(lexpr, context),
|
|
523
619
|
'IN',
|
|
524
|
-
|
|
620
|
+
context.parens(this.visit(rexpr, context))
|
|
525
621
|
]);
|
|
526
622
|
}
|
|
527
623
|
case 'AEXPR_LIKE':
|
|
528
|
-
const likeOp = this.deparseOperatorName(name);
|
|
624
|
+
const likeOp = this.deparseOperatorName(name, context);
|
|
529
625
|
if (likeOp === '!~~') {
|
|
530
|
-
return
|
|
626
|
+
return context.format([
|
|
531
627
|
this.visit(lexpr, context),
|
|
532
628
|
'NOT LIKE',
|
|
533
629
|
this.visit(rexpr, context)
|
|
534
630
|
]);
|
|
535
631
|
}
|
|
536
632
|
else {
|
|
537
|
-
return
|
|
633
|
+
return context.format([
|
|
538
634
|
this.visit(lexpr, context),
|
|
539
635
|
'LIKE',
|
|
540
636
|
this.visit(rexpr, context)
|
|
541
637
|
]);
|
|
542
638
|
}
|
|
543
639
|
case 'AEXPR_ILIKE':
|
|
544
|
-
const ilikeOp = this.deparseOperatorName(name);
|
|
640
|
+
const ilikeOp = this.deparseOperatorName(name, context);
|
|
545
641
|
if (ilikeOp === '!~~*') {
|
|
546
|
-
return
|
|
642
|
+
return context.format([
|
|
547
643
|
this.visit(lexpr, context),
|
|
548
644
|
'NOT ILIKE',
|
|
549
645
|
this.visit(rexpr, context)
|
|
550
646
|
]);
|
|
551
647
|
}
|
|
552
648
|
else {
|
|
553
|
-
return
|
|
649
|
+
return context.format([
|
|
554
650
|
this.visit(lexpr, context),
|
|
555
651
|
'ILIKE',
|
|
556
652
|
this.visit(rexpr, context)
|
|
557
653
|
]);
|
|
558
654
|
}
|
|
559
655
|
case 'AEXPR_SIMILAR':
|
|
560
|
-
const similarOp = this.deparseOperatorName(name);
|
|
656
|
+
const similarOp = this.deparseOperatorName(name, context);
|
|
561
657
|
let rightExpr;
|
|
562
658
|
if (rexpr && 'FuncCall' in rexpr &&
|
|
563
659
|
rexpr.FuncCall?.funcname?.length === 2 &&
|
|
@@ -573,39 +669,39 @@ class Deparser {
|
|
|
573
669
|
rightExpr = this.visit(rexpr, context);
|
|
574
670
|
}
|
|
575
671
|
if (similarOp === '!~') {
|
|
576
|
-
return
|
|
672
|
+
return context.format([
|
|
577
673
|
this.visit(lexpr, context),
|
|
578
674
|
'NOT SIMILAR TO',
|
|
579
675
|
rightExpr
|
|
580
676
|
]);
|
|
581
677
|
}
|
|
582
678
|
else {
|
|
583
|
-
return
|
|
679
|
+
return context.format([
|
|
584
680
|
this.visit(lexpr, context),
|
|
585
681
|
'SIMILAR TO',
|
|
586
682
|
rightExpr
|
|
587
683
|
]);
|
|
588
684
|
}
|
|
589
685
|
case 'AEXPR_BETWEEN':
|
|
590
|
-
return
|
|
686
|
+
return context.format([
|
|
591
687
|
this.visit(lexpr, context),
|
|
592
688
|
'BETWEEN',
|
|
593
689
|
this.visitBetweenRange(rexpr, context)
|
|
594
690
|
]);
|
|
595
691
|
case 'AEXPR_NOT_BETWEEN':
|
|
596
|
-
return
|
|
692
|
+
return context.format([
|
|
597
693
|
this.visit(lexpr, context),
|
|
598
694
|
'NOT BETWEEN',
|
|
599
695
|
this.visitBetweenRange(rexpr, context)
|
|
600
696
|
]);
|
|
601
697
|
case 'AEXPR_BETWEEN_SYM':
|
|
602
|
-
return
|
|
698
|
+
return context.format([
|
|
603
699
|
this.visit(lexpr, context),
|
|
604
700
|
'BETWEEN SYMMETRIC',
|
|
605
701
|
this.visitBetweenRange(rexpr, context)
|
|
606
702
|
]);
|
|
607
703
|
case 'AEXPR_NOT_BETWEEN_SYM':
|
|
608
|
-
return
|
|
704
|
+
return context.format([
|
|
609
705
|
this.visit(lexpr, context),
|
|
610
706
|
'NOT BETWEEN SYMMETRIC',
|
|
611
707
|
this.visitBetweenRange(rexpr, context)
|
|
@@ -613,7 +709,7 @@ class Deparser {
|
|
|
613
709
|
}
|
|
614
710
|
throw new Error(`Unhandled A_Expr kind: ${kind}`);
|
|
615
711
|
}
|
|
616
|
-
deparseOperatorName(name) {
|
|
712
|
+
deparseOperatorName(name, context) {
|
|
617
713
|
if (!name || name.length === 0) {
|
|
618
714
|
return '';
|
|
619
715
|
}
|
|
@@ -621,7 +717,7 @@ class Deparser {
|
|
|
621
717
|
if (n.String) {
|
|
622
718
|
return n.String.sval || n.String.str;
|
|
623
719
|
}
|
|
624
|
-
return this.visit(n,
|
|
720
|
+
return this.visit(n, context);
|
|
625
721
|
});
|
|
626
722
|
if (parts.length > 1) {
|
|
627
723
|
return `OPERATOR(${parts.join('.')})`;
|
|
@@ -684,6 +780,64 @@ class Deparser {
|
|
|
684
780
|
node.SubLink ||
|
|
685
781
|
node.A_Expr);
|
|
686
782
|
}
|
|
783
|
+
isComplexSelectTarget(node) {
|
|
784
|
+
if (!node)
|
|
785
|
+
return false;
|
|
786
|
+
if (node.ResTarget?.val) {
|
|
787
|
+
return this.isComplexExpression(node.ResTarget.val);
|
|
788
|
+
}
|
|
789
|
+
// Always complex: CASE expressions
|
|
790
|
+
if (node.CaseExpr)
|
|
791
|
+
return true;
|
|
792
|
+
// Always complex: Subqueries and subselects
|
|
793
|
+
if (node.SubLink)
|
|
794
|
+
return true;
|
|
795
|
+
// Always complex: Boolean tests and expressions
|
|
796
|
+
if (node.NullTest || node.BooleanTest || node.BoolExpr)
|
|
797
|
+
return true;
|
|
798
|
+
// COALESCE and similar functions - complex if multiple arguments
|
|
799
|
+
if (node.CoalesceExpr) {
|
|
800
|
+
const args = node.CoalesceExpr.args;
|
|
801
|
+
if (args && Array.isArray(args) && args.length > 1)
|
|
802
|
+
return true;
|
|
803
|
+
}
|
|
804
|
+
// Function calls - complex if multiple args or has clauses
|
|
805
|
+
if (node.FuncCall) {
|
|
806
|
+
const funcCall = node.FuncCall;
|
|
807
|
+
const args = funcCall.args ? (Array.isArray(funcCall.args) ? funcCall.args : [funcCall.args]) : [];
|
|
808
|
+
// Complex if has window clause, filter, order by, etc.
|
|
809
|
+
if (funcCall.over || funcCall.agg_filter || funcCall.agg_order || funcCall.agg_distinct) {
|
|
810
|
+
return true;
|
|
811
|
+
}
|
|
812
|
+
// Complex if multiple arguments
|
|
813
|
+
if (args.length > 1)
|
|
814
|
+
return true;
|
|
815
|
+
if (args.length === 1) {
|
|
816
|
+
return this.isComplexSelectTarget(args[0]);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (node.A_Expr) {
|
|
820
|
+
const expr = node.A_Expr;
|
|
821
|
+
// Check if operands are complex
|
|
822
|
+
if (expr.lexpr && this.isComplexSelectTarget(expr.lexpr))
|
|
823
|
+
return true;
|
|
824
|
+
if (expr.rexpr && this.isComplexSelectTarget(expr.rexpr))
|
|
825
|
+
return true;
|
|
826
|
+
return false;
|
|
827
|
+
}
|
|
828
|
+
if (node.TypeCast) {
|
|
829
|
+
return this.isComplexSelectTarget(node.TypeCast.arg);
|
|
830
|
+
}
|
|
831
|
+
if (node.A_ArrayExpr)
|
|
832
|
+
return true;
|
|
833
|
+
if (node.A_Indirection) {
|
|
834
|
+
return this.isComplexSelectTarget(node.A_Indirection.arg);
|
|
835
|
+
}
|
|
836
|
+
if (node.A_Const || node.ColumnRef || node.ParamRef || node.A_Star) {
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
return false;
|
|
840
|
+
}
|
|
687
841
|
visitBetweenRange(rexpr, context) {
|
|
688
842
|
if (rexpr && 'List' in rexpr && rexpr.List?.items) {
|
|
689
843
|
const items = rexpr.List.items.map((item) => this.visit(item, context));
|
|
@@ -700,9 +854,16 @@ class Deparser {
|
|
|
700
854
|
output.push(this.RangeVar(node.relation, context));
|
|
701
855
|
if (node.cols) {
|
|
702
856
|
const cols = list_utils_1.ListUtils.unwrapList(node.cols);
|
|
703
|
-
const insertContext =
|
|
857
|
+
const insertContext = context.spawn('InsertStmt', { insertColumns: true });
|
|
704
858
|
const columnNames = cols.map(col => this.visit(col, insertContext));
|
|
705
|
-
|
|
859
|
+
if (context.isPretty()) {
|
|
860
|
+
// Always format columns in multiline parentheses for pretty printing
|
|
861
|
+
const indentedColumns = columnNames.map(col => context.indent(col));
|
|
862
|
+
output.push('(\n' + indentedColumns.join(',\n') + '\n)');
|
|
863
|
+
}
|
|
864
|
+
else {
|
|
865
|
+
output.push(context.parens(columnNames.join(', ')));
|
|
866
|
+
}
|
|
706
867
|
}
|
|
707
868
|
if (node.selectStmt) {
|
|
708
869
|
output.push(this.visit(node.selectStmt, context));
|
|
@@ -723,7 +884,7 @@ class Deparser {
|
|
|
723
884
|
else if (infer.indexElems) {
|
|
724
885
|
const elems = list_utils_1.ListUtils.unwrapList(infer.indexElems);
|
|
725
886
|
const indexElems = elems.map(elem => this.visit(elem, context));
|
|
726
|
-
output.push(
|
|
887
|
+
output.push(context.parens(indexElems.join(', ')));
|
|
727
888
|
}
|
|
728
889
|
// Handle WHERE clause for conflict detection
|
|
729
890
|
if (infer.whereClause) {
|
|
@@ -739,12 +900,12 @@ class Deparser {
|
|
|
739
900
|
if (firstTarget.ResTarget?.val?.MultiAssignRef && targetList.every(target => target.ResTarget?.val?.MultiAssignRef)) {
|
|
740
901
|
const sortedTargets = targetList.sort((a, b) => a.ResTarget.val.MultiAssignRef.colno - b.ResTarget.val.MultiAssignRef.colno);
|
|
741
902
|
const names = sortedTargets.map(target => target.ResTarget.name);
|
|
742
|
-
output.push(
|
|
903
|
+
output.push(context.parens(names.join(', ')));
|
|
743
904
|
output.push('=');
|
|
744
905
|
output.push(this.visit(firstTarget.ResTarget.val.MultiAssignRef.source, context));
|
|
745
906
|
}
|
|
746
907
|
else {
|
|
747
|
-
const updateContext =
|
|
908
|
+
const updateContext = context.spawn('UpdateStmt', { update: true });
|
|
748
909
|
const targets = targetList.map(target => this.visit(target, updateContext));
|
|
749
910
|
output.push(targets.join(', '));
|
|
750
911
|
}
|
|
@@ -798,12 +959,12 @@ class Deparser {
|
|
|
798
959
|
}
|
|
799
960
|
}
|
|
800
961
|
const names = relatedTargets.map(t => t.ResTarget.name);
|
|
801
|
-
const multiAssignment = `${
|
|
962
|
+
const multiAssignment = `${context.parens(names.join(', '))} = ${this.visit(multiAssignRef.source, context)}`;
|
|
802
963
|
assignmentParts.push(multiAssignment);
|
|
803
964
|
}
|
|
804
965
|
else {
|
|
805
966
|
// Handle regular single-column assignment
|
|
806
|
-
assignmentParts.push(this.visit(target,
|
|
967
|
+
assignmentParts.push(this.visit(target, context.spawn('UpdateStmt', { update: true })));
|
|
807
968
|
processedTargets.add(i);
|
|
808
969
|
}
|
|
809
970
|
}
|
|
@@ -895,14 +1056,14 @@ class Deparser {
|
|
|
895
1056
|
}
|
|
896
1057
|
if (node.ctes && node.ctes.length > 0) {
|
|
897
1058
|
const ctes = list_utils_1.ListUtils.unwrapList(node.ctes);
|
|
898
|
-
if (
|
|
1059
|
+
if (context.isPretty()) {
|
|
899
1060
|
const cteStrings = ctes.map((cte, index) => {
|
|
900
1061
|
const cteStr = this.visit(cte, context);
|
|
901
|
-
const prefix = index === 0 ?
|
|
1062
|
+
const prefix = index === 0 ? context.newline() : ',' + context.newline();
|
|
902
1063
|
if (this.containsMultilineStringLiteral(cteStr)) {
|
|
903
1064
|
return prefix + cteStr;
|
|
904
1065
|
}
|
|
905
|
-
return prefix +
|
|
1066
|
+
return prefix + context.indent(cteStr);
|
|
906
1067
|
});
|
|
907
1068
|
output.push(cteStrings.join(''));
|
|
908
1069
|
}
|
|
@@ -988,14 +1149,14 @@ class Deparser {
|
|
|
988
1149
|
if (context.bool) {
|
|
989
1150
|
formatStr = '(%s)';
|
|
990
1151
|
}
|
|
991
|
-
const boolContext =
|
|
1152
|
+
const boolContext = context.spawn('BoolExpr', { bool: true });
|
|
992
1153
|
// explanation of our syntax/fix below:
|
|
993
1154
|
// return formatStr.replace('%s', andArgs); // ❌ Interprets $ as special syntax
|
|
994
1155
|
// return formatStr.replace('%s', () => andArgs); // ✅ Function callback prevents interpretation
|
|
995
1156
|
switch (boolop) {
|
|
996
1157
|
case 'AND_EXPR':
|
|
997
|
-
if (
|
|
998
|
-
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 '));
|
|
999
1160
|
return formatStr.replace('%s', () => andArgs);
|
|
1000
1161
|
}
|
|
1001
1162
|
else {
|
|
@@ -1003,8 +1164,8 @@ class Deparser {
|
|
|
1003
1164
|
return formatStr.replace('%s', () => andArgs);
|
|
1004
1165
|
}
|
|
1005
1166
|
case 'OR_EXPR':
|
|
1006
|
-
if (
|
|
1007
|
-
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 '));
|
|
1008
1169
|
return formatStr.replace('%s', () => orArgs);
|
|
1009
1170
|
}
|
|
1010
1171
|
else {
|
|
@@ -1135,9 +1296,9 @@ class Deparser {
|
|
|
1135
1296
|
const timezone = this.visit(args[0], context);
|
|
1136
1297
|
// Add parentheses around timestamp if it contains arithmetic operations
|
|
1137
1298
|
if (args[1] && 'A_Expr' in args[1] && args[1].A_Expr?.kind === 'AEXPR_OP') {
|
|
1138
|
-
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);
|
|
1139
1300
|
if (op === '+' || op === '-' || op === '*' || op === '/') {
|
|
1140
|
-
timestamp =
|
|
1301
|
+
timestamp = context.parens(timestamp);
|
|
1141
1302
|
}
|
|
1142
1303
|
}
|
|
1143
1304
|
return `${timestamp} AT TIME ZONE ${timezone}`;
|
|
@@ -1207,14 +1368,14 @@ class Deparser {
|
|
|
1207
1368
|
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
1208
1369
|
}
|
|
1209
1370
|
// Handle window frame specifications using the dedicated formatWindowFrame method
|
|
1210
|
-
const frameClause = this.formatWindowFrame(node.over);
|
|
1371
|
+
const frameClause = this.formatWindowFrame(node.over, context.spawn('FuncCall'));
|
|
1211
1372
|
if (frameClause) {
|
|
1212
1373
|
windowParts.push(frameClause);
|
|
1213
1374
|
}
|
|
1214
1375
|
if (windowParts.length > 0) {
|
|
1215
|
-
if (
|
|
1216
|
-
const formattedParts = windowParts.map(part =>
|
|
1217
|
-
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()})`;
|
|
1218
1379
|
}
|
|
1219
1380
|
else {
|
|
1220
1381
|
result += ` OVER (${windowParts.join(' ')})`;
|
|
@@ -1494,9 +1655,6 @@ class Deparser {
|
|
|
1494
1655
|
return output.join(' ');
|
|
1495
1656
|
}
|
|
1496
1657
|
if (catalog === 'pg_catalog') {
|
|
1497
|
-
const builtinTypes = ['int2', 'int4', 'int8', 'float4', 'float8', 'numeric', 'decimal',
|
|
1498
|
-
'varchar', 'char', 'bpchar', 'text', 'bool', 'date', 'time', 'timestamp',
|
|
1499
|
-
'timestamptz', 'interval', 'bytea', 'uuid', 'json', 'jsonb'];
|
|
1500
1658
|
let typeName = `${catalog}.${type}`;
|
|
1501
1659
|
if (type === 'bpchar' && args) {
|
|
1502
1660
|
typeName = 'char';
|
|
@@ -1582,7 +1740,7 @@ class Deparser {
|
|
|
1582
1740
|
}
|
|
1583
1741
|
return this.quoteIfNeeded(colStr);
|
|
1584
1742
|
});
|
|
1585
|
-
output.push('AS', this.quoteIfNeeded(name) +
|
|
1743
|
+
output.push('AS', this.quoteIfNeeded(name) + context.parens(quotedColnames.join(', ')));
|
|
1586
1744
|
}
|
|
1587
1745
|
else {
|
|
1588
1746
|
output.push('AS', this.quoteIfNeeded(name));
|
|
@@ -1594,7 +1752,7 @@ class Deparser {
|
|
|
1594
1752
|
// Handle ONLY keyword for inheritance control (but not for type definitions, ALTER TYPE, or CREATE FOREIGN TABLE)
|
|
1595
1753
|
if (node && (!('inh' in node) || node.inh === undefined) &&
|
|
1596
1754
|
!context.parentNodeTypes.includes('CompositeTypeStmt') &&
|
|
1597
|
-
!context.parentNodeTypes.includes('AlterTypeStmt') &&
|
|
1755
|
+
(!context.parentNodeTypes.includes('AlterTypeStmt') && context.objtype !== 'OBJECT_TYPE') &&
|
|
1598
1756
|
!context.parentNodeTypes.includes('CreateForeignTableStmt')) {
|
|
1599
1757
|
output.push('ONLY');
|
|
1600
1758
|
}
|
|
@@ -1791,6 +1949,18 @@ class Deparser {
|
|
|
1791
1949
|
return `pg_catalog.${typeName}`;
|
|
1792
1950
|
}
|
|
1793
1951
|
}
|
|
1952
|
+
isPgCatalogType(typeName) {
|
|
1953
|
+
const cleanTypeName = typeName.replace(/^pg_catalog\./, '');
|
|
1954
|
+
if (pgCatalogTypes.includes(cleanTypeName)) {
|
|
1955
|
+
return true;
|
|
1956
|
+
}
|
|
1957
|
+
for (const [realType, aliases] of pgCatalogTypeAliases) {
|
|
1958
|
+
if (aliases.includes(cleanTypeName)) {
|
|
1959
|
+
return true;
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
return false;
|
|
1963
|
+
}
|
|
1794
1964
|
A_ArrayExpr(node, context) {
|
|
1795
1965
|
const elements = list_utils_1.ListUtils.unwrapList(node.elements);
|
|
1796
1966
|
const elementStrs = elements.map(el => this.visit(el, context));
|
|
@@ -1842,26 +2012,26 @@ class Deparser {
|
|
|
1842
2012
|
output.push(this.visit(node.arg, context));
|
|
1843
2013
|
}
|
|
1844
2014
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
1845
|
-
if (
|
|
2015
|
+
if (context.isPretty() && args.length > 0) {
|
|
1846
2016
|
for (const arg of args) {
|
|
1847
2017
|
const whenClause = this.visit(arg, context);
|
|
1848
2018
|
if (this.containsMultilineStringLiteral(whenClause)) {
|
|
1849
|
-
output.push(
|
|
2019
|
+
output.push(context.newline() + whenClause);
|
|
1850
2020
|
}
|
|
1851
2021
|
else {
|
|
1852
|
-
output.push(
|
|
2022
|
+
output.push(context.newline() + context.indent(whenClause));
|
|
1853
2023
|
}
|
|
1854
2024
|
}
|
|
1855
2025
|
if (node.defresult) {
|
|
1856
2026
|
const elseResult = this.visit(node.defresult, context);
|
|
1857
2027
|
if (this.containsMultilineStringLiteral(elseResult)) {
|
|
1858
|
-
output.push(
|
|
2028
|
+
output.push(context.newline() + 'ELSE ' + elseResult);
|
|
1859
2029
|
}
|
|
1860
2030
|
else {
|
|
1861
|
-
output.push(
|
|
2031
|
+
output.push(context.newline() + context.indent('ELSE ' + elseResult));
|
|
1862
2032
|
}
|
|
1863
2033
|
}
|
|
1864
|
-
output.push(
|
|
2034
|
+
output.push(context.newline() + 'END');
|
|
1865
2035
|
return output.join(' ');
|
|
1866
2036
|
}
|
|
1867
2037
|
else {
|
|
@@ -1884,28 +2054,29 @@ class Deparser {
|
|
|
1884
2054
|
TypeCast(node, context) {
|
|
1885
2055
|
const arg = this.visit(node.arg, context);
|
|
1886
2056
|
const typeName = this.TypeName(node.typeName, context);
|
|
1887
|
-
// Check if this is a bpchar typecast that should
|
|
1888
|
-
if (typeName === 'bpchar'
|
|
1889
|
-
const names =
|
|
1890
|
-
|
|
1891
|
-
names[0]
|
|
1892
|
-
names[1]
|
|
1893
|
-
|
|
2057
|
+
// Check if this is a bpchar typecast that should preserve original syntax for AST consistency
|
|
2058
|
+
if (typeName === 'bpchar' || typeName === 'pg_catalog.bpchar') {
|
|
2059
|
+
const names = node.typeName?.names;
|
|
2060
|
+
const isQualifiedBpchar = names && names.length === 2 &&
|
|
2061
|
+
names[0]?.String?.sval === 'pg_catalog' &&
|
|
2062
|
+
names[1]?.String?.sval === 'bpchar';
|
|
2063
|
+
if (isQualifiedBpchar) {
|
|
2064
|
+
return `CAST(${arg} AS ${typeName})`;
|
|
1894
2065
|
}
|
|
1895
2066
|
}
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
2067
|
+
if (this.isPgCatalogType(typeName)) {
|
|
2068
|
+
const argType = this.getNodeType(node.arg);
|
|
2069
|
+
const isSimpleArgument = argType === 'A_Const' || argType === 'ColumnRef';
|
|
2070
|
+
const isFunctionCall = argType === 'FuncCall';
|
|
2071
|
+
if (isSimpleArgument || isFunctionCall) {
|
|
2072
|
+
// For simple arguments, avoid :: syntax if they have complex structure
|
|
2073
|
+
if (isSimpleArgument && (arg.includes('(') || arg.startsWith('-'))) {
|
|
2074
|
+
}
|
|
2075
|
+
else {
|
|
2076
|
+
const cleanTypeName = typeName.replace('pg_catalog.', '');
|
|
2077
|
+
return `${arg}::${cleanTypeName}`;
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
1909
2080
|
}
|
|
1910
2081
|
return `CAST(${arg} AS ${typeName})`;
|
|
1911
2082
|
}
|
|
@@ -1928,7 +2099,7 @@ class Deparser {
|
|
|
1928
2099
|
}
|
|
1929
2100
|
BooleanTest(node, context) {
|
|
1930
2101
|
const output = [];
|
|
1931
|
-
const boolContext =
|
|
2102
|
+
const boolContext = context.spawn('BooleanTest', { bool: true });
|
|
1932
2103
|
output.push(this.visit(node.arg, boolContext));
|
|
1933
2104
|
switch (node.booltesttype) {
|
|
1934
2105
|
case 'IS_TRUE':
|
|
@@ -2079,24 +2250,31 @@ class Deparser {
|
|
|
2079
2250
|
const elementStrs = elements.map(el => {
|
|
2080
2251
|
return this.deparse(el, context);
|
|
2081
2252
|
});
|
|
2082
|
-
output.push(
|
|
2253
|
+
output.push(context.parens(elementStrs.join(', ')));
|
|
2083
2254
|
}
|
|
2084
2255
|
}
|
|
2085
2256
|
else if (node.tableElts) {
|
|
2086
2257
|
const elements = list_utils_1.ListUtils.unwrapList(node.tableElts);
|
|
2087
2258
|
const elementStrs = elements.map(el => {
|
|
2088
|
-
return this.deparse(el, context);
|
|
2259
|
+
return this.deparse(el, context.spawn('CreateStmt'));
|
|
2089
2260
|
});
|
|
2090
|
-
if (
|
|
2091
|
-
const formattedElements = elementStrs.map(el =>
|
|
2092
|
-
|
|
2261
|
+
if (context.isPretty()) {
|
|
2262
|
+
const formattedElements = elementStrs.map(el => {
|
|
2263
|
+
const trimmedEl = el.trim();
|
|
2264
|
+
// Remove leading newlines from constraint elements to avoid extra blank lines
|
|
2265
|
+
if (trimmedEl.startsWith('\n')) {
|
|
2266
|
+
return context.indent(trimmedEl.substring(1));
|
|
2267
|
+
}
|
|
2268
|
+
return context.indent(trimmedEl);
|
|
2269
|
+
}).join(',' + context.newline());
|
|
2270
|
+
output.push('(' + context.newline() + formattedElements + context.newline() + ')');
|
|
2093
2271
|
}
|
|
2094
2272
|
else {
|
|
2095
|
-
output.push(
|
|
2273
|
+
output.push(context.parens(elementStrs.join(', ')));
|
|
2096
2274
|
}
|
|
2097
2275
|
}
|
|
2098
2276
|
else if (!node.partbound) {
|
|
2099
|
-
output.push(
|
|
2277
|
+
output.push(context.parens(''));
|
|
2100
2278
|
}
|
|
2101
2279
|
if (node.partbound && node.inhRelations && node.inhRelations.length > 0) {
|
|
2102
2280
|
output.push('PARTITION OF');
|
|
@@ -2139,7 +2317,7 @@ class Deparser {
|
|
|
2139
2317
|
output.push('INHERITS');
|
|
2140
2318
|
const inherits = list_utils_1.ListUtils.unwrapList(node.inhRelations);
|
|
2141
2319
|
const inheritStrs = inherits.map(rel => this.visit(rel, context));
|
|
2142
|
-
output.push(
|
|
2320
|
+
output.push(context.parens(inheritStrs.join(', ')));
|
|
2143
2321
|
}
|
|
2144
2322
|
if (node.partspec) {
|
|
2145
2323
|
output.push('PARTITION BY');
|
|
@@ -2177,7 +2355,7 @@ class Deparser {
|
|
|
2177
2355
|
}
|
|
2178
2356
|
// Handle table options like WITH (fillfactor=10)
|
|
2179
2357
|
if (node.options && node.options.length > 0) {
|
|
2180
|
-
const createStmtContext =
|
|
2358
|
+
const createStmtContext = context.spawn('CreateStmt');
|
|
2181
2359
|
const optionStrs = node.options.map((option) => {
|
|
2182
2360
|
return this.deparse(option, createStmtContext);
|
|
2183
2361
|
});
|
|
@@ -2200,7 +2378,7 @@ class Deparser {
|
|
|
2200
2378
|
}
|
|
2201
2379
|
if (node.fdwoptions && node.fdwoptions.length > 0) {
|
|
2202
2380
|
output.push('OPTIONS');
|
|
2203
|
-
const columnContext =
|
|
2381
|
+
const columnContext = context.spawn('ColumnDef');
|
|
2204
2382
|
const options = list_utils_1.ListUtils.unwrapList(node.fdwoptions).map(opt => this.visit(opt, columnContext));
|
|
2205
2383
|
output.push(`(${options.join(', ')})`);
|
|
2206
2384
|
}
|
|
@@ -2210,7 +2388,7 @@ class Deparser {
|
|
|
2210
2388
|
if (node.constraints) {
|
|
2211
2389
|
const constraints = list_utils_1.ListUtils.unwrapList(node.constraints);
|
|
2212
2390
|
const constraintStrs = constraints.map(constraint => {
|
|
2213
|
-
const columnConstraintContext =
|
|
2391
|
+
const columnConstraintContext = context.spawn('ColumnDef', { isColumnConstraint: true });
|
|
2214
2392
|
return this.visit(constraint, columnConstraintContext);
|
|
2215
2393
|
});
|
|
2216
2394
|
output.push(...constraintStrs);
|
|
@@ -2250,9 +2428,25 @@ class Deparser {
|
|
|
2250
2428
|
}
|
|
2251
2429
|
break;
|
|
2252
2430
|
case 'CONSTR_CHECK':
|
|
2253
|
-
|
|
2431
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2432
|
+
output.push('\n' + context.indent('CHECK'));
|
|
2433
|
+
}
|
|
2434
|
+
else {
|
|
2435
|
+
output.push('CHECK');
|
|
2436
|
+
}
|
|
2254
2437
|
if (node.raw_expr) {
|
|
2255
|
-
|
|
2438
|
+
if (context.isPretty()) {
|
|
2439
|
+
const checkExpr = this.visit(node.raw_expr, context);
|
|
2440
|
+
if (checkExpr.includes('\n')) {
|
|
2441
|
+
output.push('(\n' + context.indent(checkExpr) + '\n)');
|
|
2442
|
+
}
|
|
2443
|
+
else {
|
|
2444
|
+
output.push(`(${checkExpr})`);
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
else {
|
|
2448
|
+
output.push(context.parens(this.visit(node.raw_expr, context)));
|
|
2449
|
+
}
|
|
2256
2450
|
}
|
|
2257
2451
|
// Handle NOT VALID for check constraints
|
|
2258
2452
|
if (node.skip_validation) {
|
|
@@ -2273,7 +2467,7 @@ class Deparser {
|
|
|
2273
2467
|
}
|
|
2274
2468
|
output.push('AS');
|
|
2275
2469
|
if (node.raw_expr) {
|
|
2276
|
-
output.push(
|
|
2470
|
+
output.push(context.parens(this.visit(node.raw_expr, context)));
|
|
2277
2471
|
}
|
|
2278
2472
|
output.push('STORED');
|
|
2279
2473
|
break;
|
|
@@ -2331,7 +2525,12 @@ class Deparser {
|
|
|
2331
2525
|
}
|
|
2332
2526
|
break;
|
|
2333
2527
|
case 'CONSTR_UNIQUE':
|
|
2334
|
-
|
|
2528
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2529
|
+
output.push('\n' + context.indent('UNIQUE'));
|
|
2530
|
+
}
|
|
2531
|
+
else {
|
|
2532
|
+
output.push('UNIQUE');
|
|
2533
|
+
}
|
|
2335
2534
|
if (node.nulls_not_distinct) {
|
|
2336
2535
|
output.push('NULLS NOT DISTINCT');
|
|
2337
2536
|
}
|
|
@@ -2349,33 +2548,77 @@ class Deparser {
|
|
|
2349
2548
|
case 'CONSTR_FOREIGN':
|
|
2350
2549
|
// Only add "FOREIGN KEY" for table-level constraints, not column-level constraints
|
|
2351
2550
|
if (!context.isColumnConstraint) {
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2551
|
+
if (context.isPretty()) {
|
|
2552
|
+
output.push('\n' + context.indent('FOREIGN KEY'));
|
|
2553
|
+
if (node.fk_attrs && node.fk_attrs.length > 0) {
|
|
2554
|
+
const fkAttrs = list_utils_1.ListUtils.unwrapList(node.fk_attrs)
|
|
2555
|
+
.map(attr => this.visit(attr, context))
|
|
2556
|
+
.join(', ');
|
|
2557
|
+
output.push(`(${fkAttrs})`);
|
|
2558
|
+
}
|
|
2559
|
+
output.push('\n' + context.indent('REFERENCES'));
|
|
2358
2560
|
}
|
|
2561
|
+
else {
|
|
2562
|
+
output.push('FOREIGN KEY');
|
|
2563
|
+
if (node.fk_attrs && node.fk_attrs.length > 0) {
|
|
2564
|
+
const fkAttrs = list_utils_1.ListUtils.unwrapList(node.fk_attrs)
|
|
2565
|
+
.map(attr => this.visit(attr, context))
|
|
2566
|
+
.join(', ');
|
|
2567
|
+
output.push(`(${fkAttrs})`);
|
|
2568
|
+
}
|
|
2569
|
+
output.push('REFERENCES');
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
else {
|
|
2573
|
+
output.push('REFERENCES');
|
|
2359
2574
|
}
|
|
2360
|
-
output.push('REFERENCES');
|
|
2361
2575
|
if (node.pktable) {
|
|
2362
|
-
|
|
2576
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2577
|
+
const lastIndex = output.length - 1;
|
|
2578
|
+
if (lastIndex >= 0 && output[lastIndex].includes('REFERENCES')) {
|
|
2579
|
+
output[lastIndex] += ' ' + this.RangeVar(node.pktable, context);
|
|
2580
|
+
}
|
|
2581
|
+
else {
|
|
2582
|
+
output.push(this.RangeVar(node.pktable, context));
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
else {
|
|
2586
|
+
output.push(this.RangeVar(node.pktable, context));
|
|
2587
|
+
}
|
|
2363
2588
|
}
|
|
2364
2589
|
if (node.pk_attrs && node.pk_attrs.length > 0) {
|
|
2365
2590
|
const pkAttrs = list_utils_1.ListUtils.unwrapList(node.pk_attrs)
|
|
2366
2591
|
.map(attr => this.visit(attr, context))
|
|
2367
2592
|
.join(', ');
|
|
2368
|
-
|
|
2593
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2594
|
+
const lastIndex = output.length - 1;
|
|
2595
|
+
if (lastIndex >= 0) {
|
|
2596
|
+
output[lastIndex] += ` (${pkAttrs})`;
|
|
2597
|
+
}
|
|
2598
|
+
else {
|
|
2599
|
+
output.push(`(${pkAttrs})`);
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2602
|
+
else {
|
|
2603
|
+
output.push(`(${pkAttrs})`);
|
|
2604
|
+
}
|
|
2369
2605
|
}
|
|
2370
2606
|
if (node.fk_matchtype && node.fk_matchtype !== 's') {
|
|
2607
|
+
let matchClause = '';
|
|
2371
2608
|
switch (node.fk_matchtype) {
|
|
2372
2609
|
case 'f':
|
|
2373
|
-
|
|
2610
|
+
matchClause = 'MATCH FULL';
|
|
2374
2611
|
break;
|
|
2375
2612
|
case 'p':
|
|
2376
|
-
|
|
2613
|
+
matchClause = 'MATCH PARTIAL';
|
|
2377
2614
|
break;
|
|
2378
2615
|
}
|
|
2616
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2617
|
+
output.push('\n' + context.indent(matchClause));
|
|
2618
|
+
}
|
|
2619
|
+
else {
|
|
2620
|
+
output.push(matchClause);
|
|
2621
|
+
}
|
|
2379
2622
|
}
|
|
2380
2623
|
if (node.fk_upd_action && node.fk_upd_action !== 'a') {
|
|
2381
2624
|
let updateClause = 'ON UPDATE ';
|
|
@@ -2393,8 +2636,8 @@ class Deparser {
|
|
|
2393
2636
|
updateClause += 'SET DEFAULT';
|
|
2394
2637
|
break;
|
|
2395
2638
|
}
|
|
2396
|
-
if (
|
|
2397
|
-
output.push('\n' +
|
|
2639
|
+
if (context.isPretty()) {
|
|
2640
|
+
output.push('\n' + context.indent(updateClause));
|
|
2398
2641
|
}
|
|
2399
2642
|
else {
|
|
2400
2643
|
output.push('ON UPDATE');
|
|
@@ -2417,8 +2660,8 @@ class Deparser {
|
|
|
2417
2660
|
deleteClause += 'SET DEFAULT';
|
|
2418
2661
|
break;
|
|
2419
2662
|
}
|
|
2420
|
-
if (
|
|
2421
|
-
output.push('\n' +
|
|
2663
|
+
if (context.isPretty()) {
|
|
2664
|
+
output.push('\n' + context.indent(deleteClause));
|
|
2422
2665
|
}
|
|
2423
2666
|
else {
|
|
2424
2667
|
output.push('ON DELETE');
|
|
@@ -2427,7 +2670,12 @@ class Deparser {
|
|
|
2427
2670
|
}
|
|
2428
2671
|
// Handle NOT VALID for foreign key constraints - only for table constraints, not domain constraints
|
|
2429
2672
|
if (node.skip_validation && !context.isDomainConstraint) {
|
|
2430
|
-
|
|
2673
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2674
|
+
output.push('\n' + context.indent('NOT VALID'));
|
|
2675
|
+
}
|
|
2676
|
+
else {
|
|
2677
|
+
output.push('NOT VALID');
|
|
2678
|
+
}
|
|
2431
2679
|
}
|
|
2432
2680
|
break;
|
|
2433
2681
|
case 'CONSTR_ATTR_DEFERRABLE':
|
|
@@ -2481,13 +2729,13 @@ class Deparser {
|
|
|
2481
2729
|
// Handle deferrable constraints for all constraint types that support it
|
|
2482
2730
|
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN') {
|
|
2483
2731
|
if (node.deferrable) {
|
|
2484
|
-
if (
|
|
2485
|
-
output.push('\n' +
|
|
2732
|
+
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2733
|
+
output.push('\n' + context.indent('DEFERRABLE'));
|
|
2486
2734
|
if (node.initdeferred === true) {
|
|
2487
|
-
output.push('\n' +
|
|
2735
|
+
output.push('\n' + context.indent('INITIALLY DEFERRED'));
|
|
2488
2736
|
}
|
|
2489
2737
|
else if (node.initdeferred === false) {
|
|
2490
|
-
output.push('\n' +
|
|
2738
|
+
output.push('\n' + context.indent('INITIALLY IMMEDIATE'));
|
|
2491
2739
|
}
|
|
2492
2740
|
}
|
|
2493
2741
|
else {
|
|
@@ -2501,15 +2749,15 @@ class Deparser {
|
|
|
2501
2749
|
}
|
|
2502
2750
|
}
|
|
2503
2751
|
else if (node.deferrable === false) {
|
|
2504
|
-
if (
|
|
2505
|
-
output.push('\n' +
|
|
2752
|
+
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2753
|
+
output.push('\n' + context.indent('NOT DEFERRABLE'));
|
|
2506
2754
|
}
|
|
2507
2755
|
else {
|
|
2508
2756
|
output.push('NOT DEFERRABLE');
|
|
2509
2757
|
}
|
|
2510
2758
|
}
|
|
2511
2759
|
}
|
|
2512
|
-
if (
|
|
2760
|
+
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2513
2761
|
let result = '';
|
|
2514
2762
|
for (let i = 0; i < output.length; i++) {
|
|
2515
2763
|
if (output[i].startsWith('\n')) {
|
|
@@ -2527,12 +2775,12 @@ class Deparser {
|
|
|
2527
2775
|
return output.join(' ');
|
|
2528
2776
|
}
|
|
2529
2777
|
SubLink(node, context) {
|
|
2530
|
-
const subselect =
|
|
2778
|
+
const subselect = context.parens(this.visit(node.subselect, context));
|
|
2531
2779
|
switch (node.subLinkType) {
|
|
2532
2780
|
case 'ANY_SUBLINK':
|
|
2533
2781
|
if (node.testexpr && node.operName) {
|
|
2534
2782
|
const testExpr = this.visit(node.testexpr, context);
|
|
2535
|
-
const operator = this.deparseOperatorName(node.operName);
|
|
2783
|
+
const operator = this.deparseOperatorName(node.operName, context);
|
|
2536
2784
|
return `${testExpr} ${operator} ANY ${subselect}`;
|
|
2537
2785
|
}
|
|
2538
2786
|
else if (node.testexpr) {
|
|
@@ -2543,7 +2791,7 @@ class Deparser {
|
|
|
2543
2791
|
case 'ALL_SUBLINK':
|
|
2544
2792
|
if (node.testexpr && node.operName) {
|
|
2545
2793
|
const testExpr = this.visit(node.testexpr, context);
|
|
2546
|
-
const operator = this.deparseOperatorName(node.operName);
|
|
2794
|
+
const operator = this.deparseOperatorName(node.operName, context);
|
|
2547
2795
|
return `${testExpr} ${operator} ALL ${subselect}`;
|
|
2548
2796
|
}
|
|
2549
2797
|
return subselect;
|
|
@@ -2585,7 +2833,7 @@ class Deparser {
|
|
|
2585
2833
|
}
|
|
2586
2834
|
// Only add frame clause if frameOptions indicates non-default framing
|
|
2587
2835
|
if (node.frameOptions && node.frameOptions !== 1058) {
|
|
2588
|
-
const frameClause = this.formatWindowFrame(node);
|
|
2836
|
+
const frameClause = this.formatWindowFrame(node, context.spawn('WindowDef'));
|
|
2589
2837
|
if (frameClause) {
|
|
2590
2838
|
windowParts.push(frameClause);
|
|
2591
2839
|
}
|
|
@@ -2605,7 +2853,7 @@ class Deparser {
|
|
|
2605
2853
|
}
|
|
2606
2854
|
return output.join(' ');
|
|
2607
2855
|
}
|
|
2608
|
-
formatWindowFrame(node) {
|
|
2856
|
+
formatWindowFrame(node, context) {
|
|
2609
2857
|
if (!node.frameOptions)
|
|
2610
2858
|
return null;
|
|
2611
2859
|
const frameOptions = node.frameOptions;
|
|
@@ -2614,7 +2862,7 @@ class Deparser {
|
|
|
2614
2862
|
if (frameOptions & 0x02) { // FRAMEOPTION_RANGE
|
|
2615
2863
|
frameParts.push('RANGE');
|
|
2616
2864
|
}
|
|
2617
|
-
else if (frameOptions & 0x04) { // FRAMEOPTION_ROWS
|
|
2865
|
+
else if (frameOptions & 0x04) { // FRAMEOPTION_ROWS
|
|
2618
2866
|
frameParts.push('ROWS');
|
|
2619
2867
|
}
|
|
2620
2868
|
else if (frameOptions & 0x08) { // FRAMEOPTION_GROUPS
|
|
@@ -2635,8 +2883,8 @@ class Deparser {
|
|
|
2635
2883
|
}
|
|
2636
2884
|
else if (frameOptions === 18453) {
|
|
2637
2885
|
if (node.startOffset && node.endOffset) {
|
|
2638
|
-
boundsParts.push(`${this.visit(node.startOffset,
|
|
2639
|
-
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`);
|
|
2640
2888
|
}
|
|
2641
2889
|
}
|
|
2642
2890
|
else if (frameOptions === 1557) {
|
|
@@ -2646,7 +2894,7 @@ class Deparser {
|
|
|
2646
2894
|
else if (frameOptions === 16917) {
|
|
2647
2895
|
boundsParts.push('CURRENT ROW');
|
|
2648
2896
|
if (node.endOffset) {
|
|
2649
|
-
boundsParts.push(`AND ${this.visit(node.endOffset,
|
|
2897
|
+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
2650
2898
|
}
|
|
2651
2899
|
}
|
|
2652
2900
|
else if (frameOptions === 1058) {
|
|
@@ -2656,13 +2904,13 @@ class Deparser {
|
|
|
2656
2904
|
// Handle start bound - prioritize explicit offset values over bit flags
|
|
2657
2905
|
if (node.startOffset) {
|
|
2658
2906
|
if (frameOptions & 0x400) { // FRAMEOPTION_START_VALUE_PRECEDING
|
|
2659
|
-
boundsParts.push(`${this.visit(node.startOffset,
|
|
2907
|
+
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
|
|
2660
2908
|
}
|
|
2661
2909
|
else if (frameOptions & 0x800) { // FRAMEOPTION_START_VALUE_FOLLOWING
|
|
2662
|
-
boundsParts.push(`${this.visit(node.startOffset,
|
|
2910
|
+
boundsParts.push(`${this.visit(node.startOffset, context)} FOLLOWING`);
|
|
2663
2911
|
}
|
|
2664
2912
|
else {
|
|
2665
|
-
boundsParts.push(`${this.visit(node.startOffset,
|
|
2913
|
+
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
|
|
2666
2914
|
}
|
|
2667
2915
|
}
|
|
2668
2916
|
else if (frameOptions & 0x10) { // FRAMEOPTION_START_UNBOUNDED_PRECEDING
|
|
@@ -2675,13 +2923,13 @@ class Deparser {
|
|
|
2675
2923
|
if (node.endOffset) {
|
|
2676
2924
|
if (boundsParts.length > 0) {
|
|
2677
2925
|
if (frameOptions & 0x1000) { // FRAMEOPTION_END_VALUE_PRECEDING
|
|
2678
|
-
boundsParts.push(`AND ${this.visit(node.endOffset,
|
|
2926
|
+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} PRECEDING`);
|
|
2679
2927
|
}
|
|
2680
2928
|
else if (frameOptions & 0x2000) { // FRAMEOPTION_END_VALUE_FOLLOWING
|
|
2681
|
-
boundsParts.push(`AND ${this.visit(node.endOffset,
|
|
2929
|
+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
2682
2930
|
}
|
|
2683
2931
|
else {
|
|
2684
|
-
boundsParts.push(`AND ${this.visit(node.endOffset,
|
|
2932
|
+
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
2685
2933
|
}
|
|
2686
2934
|
}
|
|
2687
2935
|
}
|
|
@@ -2766,7 +3014,7 @@ class Deparser {
|
|
|
2766
3014
|
const colnames = list_utils_1.ListUtils.unwrapList(node.aliascolnames);
|
|
2767
3015
|
const colnameStrs = colnames.map(col => this.visit(col, context));
|
|
2768
3016
|
// Don't add space before column list parentheses to match original formatting
|
|
2769
|
-
output[output.length - 1] +=
|
|
3017
|
+
output[output.length - 1] += context.parens(colnameStrs.join(', '));
|
|
2770
3018
|
}
|
|
2771
3019
|
output.push('AS');
|
|
2772
3020
|
// Handle materialization clauses
|
|
@@ -2777,7 +3025,7 @@ class Deparser {
|
|
|
2777
3025
|
output.push('MATERIALIZED');
|
|
2778
3026
|
}
|
|
2779
3027
|
if (node.ctequery) {
|
|
2780
|
-
output.push(
|
|
3028
|
+
output.push(context.parens(this.visit(node.ctequery, context)));
|
|
2781
3029
|
}
|
|
2782
3030
|
return output.join(' ');
|
|
2783
3031
|
}
|
|
@@ -2853,7 +3101,7 @@ class Deparser {
|
|
|
2853
3101
|
DistinctExpr(node, context) {
|
|
2854
3102
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
2855
3103
|
if (args.length === 2) {
|
|
2856
|
-
const literalContext =
|
|
3104
|
+
const literalContext = context.spawn('DistinctExpr', { isStringLiteral: true });
|
|
2857
3105
|
const left = this.visit(args[0], literalContext);
|
|
2858
3106
|
const right = this.visit(args[1], literalContext);
|
|
2859
3107
|
return `${left} IS DISTINCT FROM ${right}`;
|
|
@@ -2863,7 +3111,7 @@ class Deparser {
|
|
|
2863
3111
|
NullIfExpr(node, context) {
|
|
2864
3112
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
2865
3113
|
if (args.length === 2) {
|
|
2866
|
-
const literalContext =
|
|
3114
|
+
const literalContext = context.spawn('NullIfExpr', { isStringLiteral: true });
|
|
2867
3115
|
const left = this.visit(args[0], literalContext);
|
|
2868
3116
|
const right = this.visit(args[1], literalContext);
|
|
2869
3117
|
return `NULLIF(${left}, ${right})`;
|
|
@@ -2942,7 +3190,7 @@ class Deparser {
|
|
|
2942
3190
|
}
|
|
2943
3191
|
RelabelType(node, context) {
|
|
2944
3192
|
if (node.arg) {
|
|
2945
|
-
const literalContext =
|
|
3193
|
+
const literalContext = context.spawn('RelabelType', { isStringLiteral: true });
|
|
2946
3194
|
return this.visit(node.arg, literalContext);
|
|
2947
3195
|
}
|
|
2948
3196
|
return '';
|
|
@@ -2961,7 +3209,7 @@ class Deparser {
|
|
|
2961
3209
|
}
|
|
2962
3210
|
ConvertRowtypeExpr(node, context) {
|
|
2963
3211
|
if (node.arg) {
|
|
2964
|
-
const literalContext =
|
|
3212
|
+
const literalContext = context.spawn('ConvertRowtypeExpr', { isStringLiteral: true });
|
|
2965
3213
|
return this.visit(node.arg, literalContext);
|
|
2966
3214
|
}
|
|
2967
3215
|
return '';
|
|
@@ -2992,10 +3240,10 @@ class Deparser {
|
|
|
2992
3240
|
}
|
|
2993
3241
|
if (node.aliases && node.aliases.length > 0) {
|
|
2994
3242
|
const aliasStrs = list_utils_1.ListUtils.unwrapList(node.aliases).map(alias => this.visit(alias, context));
|
|
2995
|
-
output.push(
|
|
3243
|
+
output.push(context.parens(aliasStrs.join(', ')));
|
|
2996
3244
|
}
|
|
2997
3245
|
if (node.options && node.options.length > 0) {
|
|
2998
|
-
const viewContext =
|
|
3246
|
+
const viewContext = context.spawn('ViewStmt');
|
|
2999
3247
|
const optionStrs = list_utils_1.ListUtils.unwrapList(node.options)
|
|
3000
3248
|
.map(option => this.visit(option, viewContext));
|
|
3001
3249
|
output.push(`WITH (${optionStrs.join(', ')})`);
|
|
@@ -3042,22 +3290,22 @@ class Deparser {
|
|
|
3042
3290
|
}
|
|
3043
3291
|
if (node.indexParams && node.indexParams.length > 0) {
|
|
3044
3292
|
const paramStrs = list_utils_1.ListUtils.unwrapList(node.indexParams).map(param => this.visit(param, context));
|
|
3045
|
-
output.push(
|
|
3293
|
+
output.push(context.parens(paramStrs.join(', ')));
|
|
3046
3294
|
}
|
|
3047
3295
|
if (node.indexIncludingParams && node.indexIncludingParams.length > 0) {
|
|
3048
3296
|
const includeStrs = list_utils_1.ListUtils.unwrapList(node.indexIncludingParams).map(param => this.visit(param, context));
|
|
3049
3297
|
output.push('INCLUDE');
|
|
3050
|
-
output.push(
|
|
3298
|
+
output.push(context.parens(includeStrs.join(', ')));
|
|
3051
3299
|
}
|
|
3052
3300
|
if (node.whereClause) {
|
|
3053
3301
|
output.push('WHERE');
|
|
3054
3302
|
output.push(this.visit(node.whereClause, context));
|
|
3055
3303
|
}
|
|
3056
3304
|
if (node.options && node.options.length > 0) {
|
|
3057
|
-
const indexContext =
|
|
3305
|
+
const indexContext = context.spawn('IndexStmt');
|
|
3058
3306
|
const optionStrs = list_utils_1.ListUtils.unwrapList(node.options).map(option => this.visit(option, indexContext));
|
|
3059
3307
|
output.push('WITH');
|
|
3060
|
-
output.push(
|
|
3308
|
+
output.push(context.parens(optionStrs.join(', ')));
|
|
3061
3309
|
}
|
|
3062
3310
|
if (node.nulls_not_distinct) {
|
|
3063
3311
|
output.push('NULLS NOT DISTINCT');
|
|
@@ -3074,7 +3322,7 @@ class Deparser {
|
|
|
3074
3322
|
output.push(quote_utils_1.QuoteUtils.quote(node.name));
|
|
3075
3323
|
}
|
|
3076
3324
|
else if (node.expr) {
|
|
3077
|
-
output.push(
|
|
3325
|
+
output.push(context.parens(this.visit(node.expr, context)));
|
|
3078
3326
|
}
|
|
3079
3327
|
if (node.collation && node.collation.length > 0) {
|
|
3080
3328
|
const collationStrs = list_utils_1.ListUtils.unwrapList(node.collation).map(coll => this.visit(coll, context));
|
|
@@ -3091,7 +3339,7 @@ class Deparser {
|
|
|
3091
3339
|
const stringData = this.getNodeData(opt.DefElem.arg);
|
|
3092
3340
|
return `${opt.DefElem.defname}='${stringData.sval}'`;
|
|
3093
3341
|
}
|
|
3094
|
-
return this.visit(opt, context);
|
|
3342
|
+
return this.visit(opt, context.spawn('IndexElem'));
|
|
3095
3343
|
});
|
|
3096
3344
|
opclassStr += `(${opclassOpts.join(', ')})`;
|
|
3097
3345
|
}
|
|
@@ -3125,7 +3373,7 @@ class Deparser {
|
|
|
3125
3373
|
output.push(quote_utils_1.QuoteUtils.quote(node.name));
|
|
3126
3374
|
}
|
|
3127
3375
|
else if (node.expr) {
|
|
3128
|
-
output.push(
|
|
3376
|
+
output.push(context.parens(this.visit(node.expr, context)));
|
|
3129
3377
|
}
|
|
3130
3378
|
if (node.collation && node.collation.length > 0) {
|
|
3131
3379
|
const collationStrs = list_utils_1.ListUtils.unwrapList(node.collation).map(coll => this.visit(coll, context));
|
|
@@ -3273,16 +3521,16 @@ class Deparser {
|
|
|
3273
3521
|
if (node.rarg && 'JoinExpr' in node.rarg && !node.rarg.JoinExpr.alias) {
|
|
3274
3522
|
rargStr = `(${rargStr})`;
|
|
3275
3523
|
}
|
|
3276
|
-
if (
|
|
3277
|
-
output.push(
|
|
3524
|
+
if (context.isPretty()) {
|
|
3525
|
+
output.push(context.newline() + joinStr + ' ' + rargStr);
|
|
3278
3526
|
}
|
|
3279
3527
|
else {
|
|
3280
3528
|
output.push(joinStr + ' ' + rargStr);
|
|
3281
3529
|
}
|
|
3282
3530
|
}
|
|
3283
3531
|
else {
|
|
3284
|
-
if (
|
|
3285
|
-
output.push(
|
|
3532
|
+
if (context.isPretty()) {
|
|
3533
|
+
output.push(context.newline() + joinStr);
|
|
3286
3534
|
}
|
|
3287
3535
|
else {
|
|
3288
3536
|
output.push(joinStr);
|
|
@@ -3291,7 +3539,7 @@ class Deparser {
|
|
|
3291
3539
|
if (node.usingClause && node.usingClause.length > 0) {
|
|
3292
3540
|
const usingList = list_utils_1.ListUtils.unwrapList(node.usingClause);
|
|
3293
3541
|
const columnNames = usingList.map(col => this.visit(col, context));
|
|
3294
|
-
if (
|
|
3542
|
+
if (context.isPretty()) {
|
|
3295
3543
|
output.push(` USING (${columnNames.join(', ')})`);
|
|
3296
3544
|
}
|
|
3297
3545
|
else {
|
|
@@ -3300,14 +3548,14 @@ class Deparser {
|
|
|
3300
3548
|
}
|
|
3301
3549
|
else if (node.quals) {
|
|
3302
3550
|
const qualsStr = this.visit(node.quals, context);
|
|
3303
|
-
if (
|
|
3551
|
+
if (context.isPretty()) {
|
|
3304
3552
|
// For complex JOIN conditions, format with proper indentation
|
|
3305
3553
|
if (qualsStr.includes('AND') || qualsStr.includes('OR') || qualsStr.length > 50) {
|
|
3306
3554
|
if (this.containsMultilineStringLiteral(qualsStr)) {
|
|
3307
3555
|
output.push(` ON ${qualsStr}`);
|
|
3308
3556
|
}
|
|
3309
3557
|
else {
|
|
3310
|
-
output.push(` ON${
|
|
3558
|
+
output.push(` ON${context.newline()}${context.indent(qualsStr)}`);
|
|
3311
3559
|
}
|
|
3312
3560
|
}
|
|
3313
3561
|
else {
|
|
@@ -3319,7 +3567,7 @@ class Deparser {
|
|
|
3319
3567
|
}
|
|
3320
3568
|
}
|
|
3321
3569
|
let result;
|
|
3322
|
-
if (
|
|
3570
|
+
if (context.isPretty()) {
|
|
3323
3571
|
result = output.join('');
|
|
3324
3572
|
}
|
|
3325
3573
|
else {
|
|
@@ -3426,8 +3674,8 @@ class Deparser {
|
|
|
3426
3674
|
else if (nodeData.sval !== undefined) {
|
|
3427
3675
|
// Handle nested sval structure: { sval: { sval: "value" } }
|
|
3428
3676
|
const svalValue = typeof nodeData.sval === 'object' ? nodeData.sval.sval : nodeData.sval;
|
|
3429
|
-
const stringValue = svalValue.replace(/'/g, '')
|
|
3430
|
-
boolValue = stringValue === 'on' || stringValue === 'true';
|
|
3677
|
+
const stringValue = svalValue.replace(/'/g, '');
|
|
3678
|
+
boolValue = stringValue.toLowerCase() === 'on' || stringValue.toLowerCase() === 'true';
|
|
3431
3679
|
}
|
|
3432
3680
|
}
|
|
3433
3681
|
return boolValue ? 'READ ONLY' : 'READ WRITE';
|
|
@@ -3450,8 +3698,8 @@ class Deparser {
|
|
|
3450
3698
|
else if (nodeData.sval !== undefined) {
|
|
3451
3699
|
// Handle nested sval structure: { sval: { sval: "value" } }
|
|
3452
3700
|
const svalValue = typeof nodeData.sval === 'object' ? nodeData.sval.sval : nodeData.sval;
|
|
3453
|
-
const stringValue = svalValue.replace(/'/g, '')
|
|
3454
|
-
boolValue = stringValue === 'on' || stringValue === 'true';
|
|
3701
|
+
const stringValue = svalValue.replace(/'/g, '');
|
|
3702
|
+
boolValue = stringValue.toLowerCase() === 'on' || stringValue.toLowerCase() === 'true';
|
|
3455
3703
|
}
|
|
3456
3704
|
}
|
|
3457
3705
|
return boolValue ? 'DEFERRABLE' : 'NOT DEFERRABLE';
|
|
@@ -3518,8 +3766,8 @@ class Deparser {
|
|
|
3518
3766
|
else if (nodeData.sval !== undefined) {
|
|
3519
3767
|
// Handle nested sval structure: { sval: { sval: "value" } }
|
|
3520
3768
|
const svalValue = typeof nodeData.sval === 'object' ? nodeData.sval.sval : nodeData.sval;
|
|
3521
|
-
const stringValue = svalValue.replace(/'/g, '')
|
|
3522
|
-
boolValue = stringValue === 'on' || stringValue === 'true';
|
|
3769
|
+
const stringValue = svalValue.replace(/'/g, '');
|
|
3770
|
+
boolValue = stringValue.toLowerCase() === 'on' || stringValue.toLowerCase() === 'true';
|
|
3523
3771
|
}
|
|
3524
3772
|
}
|
|
3525
3773
|
transactionOptions.push(boolValue ? 'READ ONLY' : 'READ WRITE');
|
|
@@ -3537,8 +3785,8 @@ class Deparser {
|
|
|
3537
3785
|
else if (nodeData.sval !== undefined) {
|
|
3538
3786
|
// Handle nested sval structure: { sval: { sval: "value" } }
|
|
3539
3787
|
const svalValue = typeof nodeData.sval === 'object' ? nodeData.sval.sval : nodeData.sval;
|
|
3540
|
-
const stringValue = svalValue.replace(/'/g, '')
|
|
3541
|
-
boolValue = stringValue === 'on' || stringValue === 'true';
|
|
3788
|
+
const stringValue = svalValue.replace(/'/g, '');
|
|
3789
|
+
boolValue = stringValue.toLowerCase() === 'on' || stringValue.toLowerCase() === 'true';
|
|
3542
3790
|
}
|
|
3543
3791
|
}
|
|
3544
3792
|
transactionOptions.push(boolValue ? 'DEFERRABLE' : 'NOT DEFERRABLE');
|
|
@@ -3604,7 +3852,7 @@ class Deparser {
|
|
|
3604
3852
|
}
|
|
3605
3853
|
switch (node.roletype) {
|
|
3606
3854
|
case 'ROLESPEC_PUBLIC':
|
|
3607
|
-
return '
|
|
3855
|
+
return 'PUBLIC';
|
|
3608
3856
|
case 'ROLESPEC_CURRENT_USER':
|
|
3609
3857
|
return 'CURRENT_USER';
|
|
3610
3858
|
case 'ROLESPEC_SESSION_USER':
|
|
@@ -3612,7 +3860,7 @@ class Deparser {
|
|
|
3612
3860
|
case 'ROLESPEC_CURRENT_ROLE':
|
|
3613
3861
|
return 'CURRENT_ROLE';
|
|
3614
3862
|
default:
|
|
3615
|
-
return '
|
|
3863
|
+
return 'PUBLIC';
|
|
3616
3864
|
}
|
|
3617
3865
|
}
|
|
3618
3866
|
roletype(node, context) {
|
|
@@ -3922,7 +4170,7 @@ class Deparser {
|
|
|
3922
4170
|
}).filter((name) => name && name.trim());
|
|
3923
4171
|
return items.join('.');
|
|
3924
4172
|
}
|
|
3925
|
-
const objContext =
|
|
4173
|
+
const objContext = context.spawn('DropStmt', { objtype: node.removeType });
|
|
3926
4174
|
const objName = this.visit(objList, objContext);
|
|
3927
4175
|
return objName;
|
|
3928
4176
|
}).filter((name) => name && name.trim()).join(', ');
|
|
@@ -4022,7 +4270,7 @@ class Deparser {
|
|
|
4022
4270
|
if (node.options && node.options.length > 0) {
|
|
4023
4271
|
output.push('WITH');
|
|
4024
4272
|
const optionsStr = list_utils_1.ListUtils.unwrapList(node.options)
|
|
4025
|
-
.map(opt => this.visit(opt, context))
|
|
4273
|
+
.map(opt => this.visit(opt, context.spawn('CopyStmt')))
|
|
4026
4274
|
.join(', ');
|
|
4027
4275
|
output.push(`(${optionsStr})`);
|
|
4028
4276
|
}
|
|
@@ -4068,18 +4316,31 @@ class Deparser {
|
|
|
4068
4316
|
if (node.missing_ok) {
|
|
4069
4317
|
output.push('IF EXISTS');
|
|
4070
4318
|
}
|
|
4071
|
-
const alterContext = node.objtype
|
|
4072
|
-
? { ...context, parentNodeTypes: [...context.parentNodeTypes, 'AlterTypeStmt'] }
|
|
4073
|
-
: context;
|
|
4319
|
+
const alterContext = context.spawn('AlterTableStmt', { objtype: node.objtype });
|
|
4074
4320
|
if (node.relation) {
|
|
4075
4321
|
const relationStr = this.RangeVar(node.relation, alterContext);
|
|
4076
4322
|
output.push(relationStr);
|
|
4077
4323
|
}
|
|
4078
4324
|
if (node.cmds && node.cmds.length > 0) {
|
|
4079
|
-
const
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4325
|
+
const commands = list_utils_1.ListUtils.unwrapList(node.cmds);
|
|
4326
|
+
if (context.isPretty()) {
|
|
4327
|
+
const commandsStr = commands
|
|
4328
|
+
.map(cmd => {
|
|
4329
|
+
const cmdStr = this.visit(cmd, alterContext);
|
|
4330
|
+
if (cmdStr.startsWith('ADD CONSTRAINT') || cmdStr.startsWith('ADD ')) {
|
|
4331
|
+
return context.newline() + context.indent(cmdStr);
|
|
4332
|
+
}
|
|
4333
|
+
return cmdStr;
|
|
4334
|
+
})
|
|
4335
|
+
.join(',');
|
|
4336
|
+
output.push(commandsStr);
|
|
4337
|
+
}
|
|
4338
|
+
else {
|
|
4339
|
+
const commandsStr = commands
|
|
4340
|
+
.map(cmd => this.visit(cmd, alterContext))
|
|
4341
|
+
.join(', ');
|
|
4342
|
+
output.push(commandsStr);
|
|
4343
|
+
}
|
|
4083
4344
|
}
|
|
4084
4345
|
return output.join(' ');
|
|
4085
4346
|
}
|
|
@@ -4088,7 +4349,7 @@ class Deparser {
|
|
|
4088
4349
|
if (node.subtype) {
|
|
4089
4350
|
switch (node.subtype) {
|
|
4090
4351
|
case 'AT_AddColumn':
|
|
4091
|
-
if (context.
|
|
4352
|
+
if (context.objtype === 'OBJECT_TYPE') {
|
|
4092
4353
|
output.push('ADD ATTRIBUTE');
|
|
4093
4354
|
}
|
|
4094
4355
|
else {
|
|
@@ -4108,14 +4369,14 @@ class Deparser {
|
|
|
4108
4369
|
}
|
|
4109
4370
|
if (colDefData.fdwoptions && colDefData.fdwoptions.length > 0) {
|
|
4110
4371
|
parts.push('OPTIONS');
|
|
4111
|
-
const columnContext =
|
|
4372
|
+
const columnContext = context.spawn('ColumnDef');
|
|
4112
4373
|
const options = list_utils_1.ListUtils.unwrapList(colDefData.fdwoptions).map(opt => this.visit(opt, columnContext));
|
|
4113
4374
|
parts.push(`(${options.join(', ')})`);
|
|
4114
4375
|
}
|
|
4115
4376
|
if (colDefData.constraints) {
|
|
4116
4377
|
const constraints = list_utils_1.ListUtils.unwrapList(colDefData.constraints);
|
|
4117
4378
|
const constraintStrs = constraints.map(constraint => {
|
|
4118
|
-
const columnConstraintContext =
|
|
4379
|
+
const columnConstraintContext = context.spawn('ColumnDef', { isColumnConstraint: true });
|
|
4119
4380
|
return this.visit(constraint, columnConstraintContext);
|
|
4120
4381
|
});
|
|
4121
4382
|
parts.push(...constraintStrs);
|
|
@@ -4135,7 +4396,7 @@ class Deparser {
|
|
|
4135
4396
|
break;
|
|
4136
4397
|
case 'AT_DropColumn':
|
|
4137
4398
|
if (node.missing_ok) {
|
|
4138
|
-
if (context.
|
|
4399
|
+
if (context.objtype === 'OBJECT_TYPE') {
|
|
4139
4400
|
output.push('DROP ATTRIBUTE IF EXISTS');
|
|
4140
4401
|
}
|
|
4141
4402
|
else {
|
|
@@ -4143,7 +4404,7 @@ class Deparser {
|
|
|
4143
4404
|
}
|
|
4144
4405
|
}
|
|
4145
4406
|
else {
|
|
4146
|
-
if (context.
|
|
4407
|
+
if (context.objtype === 'OBJECT_TYPE') {
|
|
4147
4408
|
output.push('DROP ATTRIBUTE');
|
|
4148
4409
|
}
|
|
4149
4410
|
else {
|
|
@@ -4161,7 +4422,7 @@ class Deparser {
|
|
|
4161
4422
|
}
|
|
4162
4423
|
break;
|
|
4163
4424
|
case 'AT_AlterColumnType':
|
|
4164
|
-
if (context.
|
|
4425
|
+
if (context.objtype === 'OBJECT_TYPE') {
|
|
4165
4426
|
output.push('ALTER ATTRIBUTE');
|
|
4166
4427
|
}
|
|
4167
4428
|
else {
|
|
@@ -4225,7 +4486,7 @@ class Deparser {
|
|
|
4225
4486
|
case 'AT_SetRelOptions':
|
|
4226
4487
|
output.push('SET');
|
|
4227
4488
|
if (node.def) {
|
|
4228
|
-
const alterTableContext =
|
|
4489
|
+
const alterTableContext = context.spawn('AlterTableCmd', { subtype: 'AT_SetRelOptions' });
|
|
4229
4490
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4230
4491
|
.map(option => this.visit(option, alterTableContext))
|
|
4231
4492
|
.join(', ');
|
|
@@ -4238,7 +4499,7 @@ class Deparser {
|
|
|
4238
4499
|
case 'AT_ResetRelOptions':
|
|
4239
4500
|
output.push('RESET');
|
|
4240
4501
|
if (node.def) {
|
|
4241
|
-
const alterTableContext =
|
|
4502
|
+
const alterTableContext = context.spawn('AlterTableCmd', { subtype: 'AT_ResetRelOptions' });
|
|
4242
4503
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4243
4504
|
.map(option => this.visit(option, alterTableContext))
|
|
4244
4505
|
.join(', ');
|
|
@@ -4333,7 +4594,7 @@ class Deparser {
|
|
|
4333
4594
|
}
|
|
4334
4595
|
output.push('SET');
|
|
4335
4596
|
if (node.def) {
|
|
4336
|
-
const alterTableContext =
|
|
4597
|
+
const alterTableContext = context.spawn('AlterTableCmd', { subtype: 'AT_SetOptions' });
|
|
4337
4598
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4338
4599
|
.map(option => this.visit(option, alterTableContext))
|
|
4339
4600
|
.join(', ');
|
|
@@ -4350,7 +4611,7 @@ class Deparser {
|
|
|
4350
4611
|
}
|
|
4351
4612
|
output.push('RESET');
|
|
4352
4613
|
if (node.def) {
|
|
4353
|
-
const alterTableContext =
|
|
4614
|
+
const alterTableContext = context.spawn('AlterTableCmd', { subtype: 'AT_ResetOptions' });
|
|
4354
4615
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4355
4616
|
.map(option => this.visit(option, alterTableContext))
|
|
4356
4617
|
.join(', ');
|
|
@@ -4591,7 +4852,7 @@ class Deparser {
|
|
|
4591
4852
|
}
|
|
4592
4853
|
output.push('OPTIONS');
|
|
4593
4854
|
if (node.def) {
|
|
4594
|
-
const alterColumnContext =
|
|
4855
|
+
const alterColumnContext = context.spawn('AlterTableCmd', { alterColumnOptions: true });
|
|
4595
4856
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4596
4857
|
.map(option => this.visit(option, alterColumnContext))
|
|
4597
4858
|
.join(', ');
|
|
@@ -4631,7 +4892,7 @@ class Deparser {
|
|
|
4631
4892
|
case 'AT_GenericOptions':
|
|
4632
4893
|
output.push('OPTIONS');
|
|
4633
4894
|
if (node.def) {
|
|
4634
|
-
const alterTableContext =
|
|
4895
|
+
const alterTableContext = context.spawn('AlterTableCmd', { alterTableOptions: true });
|
|
4635
4896
|
const options = list_utils_1.ListUtils.unwrapList(node.def)
|
|
4636
4897
|
.map(option => this.visit(option, alterTableContext))
|
|
4637
4898
|
.join(', ');
|
|
@@ -4735,7 +4996,7 @@ class Deparser {
|
|
|
4735
4996
|
output.push(this.TypeName(node.returnType, context));
|
|
4736
4997
|
}
|
|
4737
4998
|
if (node.options && node.options.length > 0) {
|
|
4738
|
-
const funcContext =
|
|
4999
|
+
const funcContext = context.spawn('CreateFunctionStmt');
|
|
4739
5000
|
const options = node.options.map((opt) => this.visit(opt, funcContext));
|
|
4740
5001
|
output.push(...options);
|
|
4741
5002
|
}
|
|
@@ -4822,7 +5083,7 @@ class Deparser {
|
|
|
4822
5083
|
}
|
|
4823
5084
|
output.push('AS', 'ENUM');
|
|
4824
5085
|
if (node.vals && node.vals.length > 0) {
|
|
4825
|
-
const enumContext =
|
|
5086
|
+
const enumContext = context.spawn('CreateEnumStmt', { isEnumValue: true });
|
|
4826
5087
|
const values = list_utils_1.ListUtils.unwrapList(node.vals)
|
|
4827
5088
|
.map(val => this.visit(val, enumContext))
|
|
4828
5089
|
.join(', ');
|
|
@@ -4877,9 +5138,8 @@ class Deparser {
|
|
|
4877
5138
|
output.push(roleName);
|
|
4878
5139
|
}
|
|
4879
5140
|
if (node.options) {
|
|
4880
|
-
const roleContext = { ...context, parentNodeTypes: [...context.parentNodeTypes, 'CreateRoleStmt'] };
|
|
4881
5141
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
4882
|
-
.map(option => this.visit(option,
|
|
5142
|
+
.map(option => this.visit(option, context.spawn('CreateRoleStmt')))
|
|
4883
5143
|
.join(' ');
|
|
4884
5144
|
if (options) {
|
|
4885
5145
|
output.push('WITH');
|
|
@@ -4910,7 +5170,7 @@ class Deparser {
|
|
|
4910
5170
|
const stringData = this.getNodeData(node.arg);
|
|
4911
5171
|
return `${node.defname}='${stringData.sval}'`;
|
|
4912
5172
|
}
|
|
4913
|
-
return `${node.defname}=${this.visit(node.arg,
|
|
5173
|
+
return `${node.defname}=${this.visit(node.arg, context.spawn('DefElem'))}`;
|
|
4914
5174
|
}
|
|
4915
5175
|
// Handle CREATE OPERATOR boolean flags - MUST be first to preserve case
|
|
4916
5176
|
if (context.parentNodeTypes.includes('DefineStmt') &&
|
|
@@ -4926,13 +5186,13 @@ class Deparser {
|
|
|
4926
5186
|
if (!node.arg) {
|
|
4927
5187
|
return `NO ${node.defname.toUpperCase()}`;
|
|
4928
5188
|
}
|
|
4929
|
-
const defElemContext =
|
|
5189
|
+
const defElemContext = context.spawn('DefElem');
|
|
4930
5190
|
const argValue = this.visit(node.arg, defElemContext);
|
|
4931
5191
|
return `${node.defname.toUpperCase()} ${argValue}`;
|
|
4932
5192
|
}
|
|
4933
5193
|
// Handle OPTIONS clause - use space format, not equals format
|
|
4934
5194
|
if (node.arg) {
|
|
4935
|
-
const defElemContext =
|
|
5195
|
+
const defElemContext = context.spawn('DefElem');
|
|
4936
5196
|
const argValue = this.visit(node.arg, defElemContext);
|
|
4937
5197
|
if (context.parentNodeTypes.includes('CreateFdwStmt') || context.parentNodeTypes.includes('AlterFdwStmt')) {
|
|
4938
5198
|
const finalValue = typeof argValue === 'string' && !argValue.startsWith("'")
|
|
@@ -4986,7 +5246,7 @@ class Deparser {
|
|
|
4986
5246
|
if (!node.arg) {
|
|
4987
5247
|
return 'PASSWORD NULL';
|
|
4988
5248
|
}
|
|
4989
|
-
const defElemContext =
|
|
5249
|
+
const defElemContext = context.spawn('DefElem');
|
|
4990
5250
|
const argValue = this.visit(node.arg, defElemContext);
|
|
4991
5251
|
const quotedValue = typeof argValue === 'string' && !argValue.startsWith("'")
|
|
4992
5252
|
? `'${argValue}'`
|
|
@@ -4995,7 +5255,7 @@ class Deparser {
|
|
|
4995
5255
|
}
|
|
4996
5256
|
}
|
|
4997
5257
|
if (node.arg) {
|
|
4998
|
-
const defElemContext =
|
|
5258
|
+
const defElemContext = context.spawn('DefElem');
|
|
4999
5259
|
const argValue = this.visit(node.arg, defElemContext);
|
|
5000
5260
|
if (context.parentNodeTypes.includes('AlterOperatorStmt')) {
|
|
5001
5261
|
if (node.arg && this.getNodeType(node.arg) === 'TypeName') {
|
|
@@ -5071,7 +5331,7 @@ class Deparser {
|
|
|
5071
5331
|
if (node.defname === 'sysid') {
|
|
5072
5332
|
return `SYSID ${argValue}`;
|
|
5073
5333
|
}
|
|
5074
|
-
if (argValue === 'true') {
|
|
5334
|
+
if (String(argValue) === 'true') {
|
|
5075
5335
|
// Handle special cases where the positive form has a different name
|
|
5076
5336
|
if (node.defname === 'isreplication') {
|
|
5077
5337
|
return 'REPLICATION';
|
|
@@ -5081,7 +5341,7 @@ class Deparser {
|
|
|
5081
5341
|
}
|
|
5082
5342
|
return node.defname.toUpperCase();
|
|
5083
5343
|
}
|
|
5084
|
-
else if (argValue === 'false') {
|
|
5344
|
+
else if (String(argValue) === 'false') {
|
|
5085
5345
|
// Handle special cases where the negative form has a different name
|
|
5086
5346
|
if (node.defname === 'canlogin') {
|
|
5087
5347
|
return 'NOLOGIN';
|
|
@@ -5145,7 +5405,7 @@ class Deparser {
|
|
|
5145
5405
|
}
|
|
5146
5406
|
if (context.parentNodeTypes.includes('DoStmt')) {
|
|
5147
5407
|
if (node.defname === 'as') {
|
|
5148
|
-
const defElemContext =
|
|
5408
|
+
const defElemContext = context.spawn('DefElem');
|
|
5149
5409
|
const argValue = node.arg ? this.visit(node.arg, defElemContext) : '';
|
|
5150
5410
|
if (Array.isArray(argValue)) {
|
|
5151
5411
|
const bodyParts = argValue;
|
|
@@ -5436,7 +5696,7 @@ class Deparser {
|
|
|
5436
5696
|
}
|
|
5437
5697
|
if (node.options && node.options.length > 0) {
|
|
5438
5698
|
output.push('WITH');
|
|
5439
|
-
const tsContext =
|
|
5699
|
+
const tsContext = context.spawn('CreateTableSpaceStmt');
|
|
5440
5700
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5441
5701
|
.map(option => this.visit(option, tsContext))
|
|
5442
5702
|
.join(', ');
|
|
@@ -5466,7 +5726,7 @@ class Deparser {
|
|
|
5466
5726
|
output.push('SET');
|
|
5467
5727
|
}
|
|
5468
5728
|
if (node.options && node.options.length > 0) {
|
|
5469
|
-
const tablespaceContext =
|
|
5729
|
+
const tablespaceContext = context.spawn('AlterTableSpaceOptionsStmt');
|
|
5470
5730
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5471
5731
|
.map(option => this.visit(option, tablespaceContext))
|
|
5472
5732
|
.join(', ');
|
|
@@ -5483,7 +5743,7 @@ class Deparser {
|
|
|
5483
5743
|
output.push(this.quoteIfNeeded(node.extname));
|
|
5484
5744
|
}
|
|
5485
5745
|
if (node.options && node.options.length > 0) {
|
|
5486
|
-
const extContext =
|
|
5746
|
+
const extContext = context.spawn('CreateExtensionStmt');
|
|
5487
5747
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5488
5748
|
.map(option => this.visit(option, extContext))
|
|
5489
5749
|
.join(' ');
|
|
@@ -5497,7 +5757,7 @@ class Deparser {
|
|
|
5497
5757
|
output.push(this.quoteIfNeeded(node.extname));
|
|
5498
5758
|
}
|
|
5499
5759
|
if (node.options && node.options.length > 0) {
|
|
5500
|
-
const extContext =
|
|
5760
|
+
const extContext = context.spawn('AlterExtensionStmt');
|
|
5501
5761
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5502
5762
|
.map(option => this.visit(option, extContext))
|
|
5503
5763
|
.join(' ');
|
|
@@ -5511,7 +5771,7 @@ class Deparser {
|
|
|
5511
5771
|
output.push(node.fdwname);
|
|
5512
5772
|
}
|
|
5513
5773
|
if (node.func_options && node.func_options.length > 0) {
|
|
5514
|
-
const fdwContext =
|
|
5774
|
+
const fdwContext = context.spawn('CreateFdwStmt');
|
|
5515
5775
|
const funcOptions = list_utils_1.ListUtils.unwrapList(node.func_options)
|
|
5516
5776
|
.map(option => this.visit(option, fdwContext))
|
|
5517
5777
|
.join(' ');
|
|
@@ -5519,7 +5779,7 @@ class Deparser {
|
|
|
5519
5779
|
}
|
|
5520
5780
|
if (node.options && node.options.length > 0) {
|
|
5521
5781
|
output.push('OPTIONS');
|
|
5522
|
-
const fdwContext =
|
|
5782
|
+
const fdwContext = context.spawn('CreateFdwStmt');
|
|
5523
5783
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
5524
5784
|
.map(option => this.visit(option, fdwContext))
|
|
5525
5785
|
.join(', ');
|
|
@@ -5621,7 +5881,7 @@ class Deparser {
|
|
|
5621
5881
|
output.push('ADD');
|
|
5622
5882
|
if (node.def) {
|
|
5623
5883
|
// Pass domain context to avoid adding constraint names for domain constraints
|
|
5624
|
-
const domainContext =
|
|
5884
|
+
const domainContext = context.spawn('CreateDomainStmt', { isDomainConstraint: true });
|
|
5625
5885
|
output.push(this.visit(node.def, domainContext));
|
|
5626
5886
|
}
|
|
5627
5887
|
break;
|
|
@@ -5647,7 +5907,7 @@ class Deparser {
|
|
|
5647
5907
|
output.push('ADD');
|
|
5648
5908
|
if (node.def) {
|
|
5649
5909
|
// Pass domain context to avoid adding constraint names for domain constraints
|
|
5650
|
-
const domainContext =
|
|
5910
|
+
const domainContext = context.spawn('CreateDomainStmt', { isDomainConstraint: true });
|
|
5651
5911
|
output.push(this.visit(node.def, domainContext));
|
|
5652
5912
|
}
|
|
5653
5913
|
break;
|
|
@@ -6009,7 +6269,7 @@ class Deparser {
|
|
|
6009
6269
|
output.push(`${operatorName}(${args.join(', ')})`);
|
|
6010
6270
|
}
|
|
6011
6271
|
else {
|
|
6012
|
-
const objContext =
|
|
6272
|
+
const objContext = context.spawn('CommentStmt', { objtype: node.objtype });
|
|
6013
6273
|
output.push(this.visit(node.object, objContext));
|
|
6014
6274
|
}
|
|
6015
6275
|
}
|
|
@@ -6055,13 +6315,13 @@ class Deparser {
|
|
|
6055
6315
|
const output = [];
|
|
6056
6316
|
const initialParts = ['CREATE', 'POLICY'];
|
|
6057
6317
|
if (node.policy_name) {
|
|
6058
|
-
initialParts.push(
|
|
6318
|
+
initialParts.push(quote_utils_1.QuoteUtils.quote(node.policy_name));
|
|
6059
6319
|
}
|
|
6060
6320
|
output.push(initialParts.join(' '));
|
|
6061
6321
|
// Add ON clause on new line in pretty mode
|
|
6062
6322
|
if (node.table) {
|
|
6063
|
-
if (
|
|
6064
|
-
output.push(
|
|
6323
|
+
if (context.isPretty()) {
|
|
6324
|
+
output.push(context.newline() + context.indent(`ON ${this.RangeVar(node.table, context)}`));
|
|
6065
6325
|
}
|
|
6066
6326
|
else {
|
|
6067
6327
|
output.push('ON');
|
|
@@ -6070,24 +6330,24 @@ class Deparser {
|
|
|
6070
6330
|
}
|
|
6071
6331
|
// Handle AS RESTRICTIVE/PERMISSIVE clause
|
|
6072
6332
|
if (node.permissive === undefined) {
|
|
6073
|
-
if (
|
|
6074
|
-
output.push(
|
|
6333
|
+
if (context.isPretty()) {
|
|
6334
|
+
output.push(context.newline() + context.indent('AS RESTRICTIVE'));
|
|
6075
6335
|
}
|
|
6076
6336
|
else {
|
|
6077
6337
|
output.push('AS', 'RESTRICTIVE');
|
|
6078
6338
|
}
|
|
6079
6339
|
}
|
|
6080
6340
|
else if (node.permissive === true) {
|
|
6081
|
-
if (
|
|
6082
|
-
output.push(
|
|
6341
|
+
if (context.isPretty()) {
|
|
6342
|
+
output.push(context.newline() + context.indent('AS PERMISSIVE'));
|
|
6083
6343
|
}
|
|
6084
6344
|
else {
|
|
6085
6345
|
output.push('AS', 'PERMISSIVE');
|
|
6086
6346
|
}
|
|
6087
6347
|
}
|
|
6088
6348
|
if (node.cmd_name) {
|
|
6089
|
-
if (
|
|
6090
|
-
output.push(
|
|
6349
|
+
if (context.isPretty()) {
|
|
6350
|
+
output.push(context.newline() + context.indent(`FOR ${node.cmd_name.toUpperCase()}`));
|
|
6091
6351
|
}
|
|
6092
6352
|
else {
|
|
6093
6353
|
output.push('FOR', node.cmd_name.toUpperCase());
|
|
@@ -6095,8 +6355,8 @@ class Deparser {
|
|
|
6095
6355
|
}
|
|
6096
6356
|
if (node.roles && node.roles.length > 0) {
|
|
6097
6357
|
const roles = list_utils_1.ListUtils.unwrapList(node.roles).map(role => this.visit(role, context));
|
|
6098
|
-
if (
|
|
6099
|
-
output.push(
|
|
6358
|
+
if (context.isPretty()) {
|
|
6359
|
+
output.push(context.newline() + context.indent(`TO ${roles.join(', ')}`));
|
|
6100
6360
|
}
|
|
6101
6361
|
else {
|
|
6102
6362
|
output.push('TO');
|
|
@@ -6104,11 +6364,11 @@ class Deparser {
|
|
|
6104
6364
|
}
|
|
6105
6365
|
}
|
|
6106
6366
|
if (node.qual) {
|
|
6107
|
-
if (
|
|
6367
|
+
if (context.isPretty()) {
|
|
6108
6368
|
const qualExpr = this.visit(node.qual, context);
|
|
6109
|
-
output.push(
|
|
6110
|
-
output.push(
|
|
6111
|
-
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(')'));
|
|
6112
6372
|
}
|
|
6113
6373
|
else {
|
|
6114
6374
|
output.push('USING');
|
|
@@ -6116,23 +6376,23 @@ class Deparser {
|
|
|
6116
6376
|
}
|
|
6117
6377
|
}
|
|
6118
6378
|
if (node.with_check) {
|
|
6119
|
-
if (
|
|
6379
|
+
if (context.isPretty()) {
|
|
6120
6380
|
const checkExpr = this.visit(node.with_check, context);
|
|
6121
|
-
output.push(
|
|
6122
|
-
output.push(
|
|
6123
|
-
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(')'));
|
|
6124
6384
|
}
|
|
6125
6385
|
else {
|
|
6126
6386
|
output.push('WITH CHECK');
|
|
6127
6387
|
output.push(`(${this.visit(node.with_check, context)})`);
|
|
6128
6388
|
}
|
|
6129
6389
|
}
|
|
6130
|
-
return
|
|
6390
|
+
return context.isPretty() ? output.join('') : output.join(' ');
|
|
6131
6391
|
}
|
|
6132
6392
|
AlterPolicyStmt(node, context) {
|
|
6133
6393
|
const output = ['ALTER', 'POLICY'];
|
|
6134
6394
|
if (node.policy_name) {
|
|
6135
|
-
output.push(
|
|
6395
|
+
output.push(quote_utils_1.QuoteUtils.quote(node.policy_name));
|
|
6136
6396
|
}
|
|
6137
6397
|
if (node.table) {
|
|
6138
6398
|
output.push('ON');
|
|
@@ -6172,7 +6432,7 @@ class Deparser {
|
|
|
6172
6432
|
}
|
|
6173
6433
|
if (node.options && node.options.length > 0) {
|
|
6174
6434
|
output.push('OPTIONS');
|
|
6175
|
-
const userMappingContext =
|
|
6435
|
+
const userMappingContext = context.spawn('CreateUserMappingStmt');
|
|
6176
6436
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, userMappingContext));
|
|
6177
6437
|
output.push(`(${options.join(', ')})`);
|
|
6178
6438
|
}
|
|
@@ -6355,7 +6615,7 @@ class Deparser {
|
|
|
6355
6615
|
DoStmt(node, context) {
|
|
6356
6616
|
const output = ['DO'];
|
|
6357
6617
|
if (node.args && node.args.length > 0) {
|
|
6358
|
-
const doContext =
|
|
6618
|
+
const doContext = context.spawn('DoStmt');
|
|
6359
6619
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
6360
6620
|
const processedArgs = [];
|
|
6361
6621
|
for (const arg of args) {
|
|
@@ -6660,7 +6920,7 @@ class Deparser {
|
|
|
6660
6920
|
ObjectWithArgs(node, context) {
|
|
6661
6921
|
let result = '';
|
|
6662
6922
|
if (node.objname && node.objname.length > 0) {
|
|
6663
|
-
const objContext =
|
|
6923
|
+
const objContext = context.spawn('ObjectWithArgs');
|
|
6664
6924
|
const names = list_utils_1.ListUtils.unwrapList(node.objname).map(name => this.visit(name, objContext));
|
|
6665
6925
|
result = names.join('.');
|
|
6666
6926
|
}
|
|
@@ -6702,7 +6962,7 @@ class Deparser {
|
|
|
6702
6962
|
}
|
|
6703
6963
|
output.push('SET');
|
|
6704
6964
|
if (node.options && node.options.length > 0) {
|
|
6705
|
-
const alterOpContext =
|
|
6965
|
+
const alterOpContext = context.spawn('AlterOperatorStmt');
|
|
6706
6966
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, alterOpContext));
|
|
6707
6967
|
output.push(`(${options.join(', ')})`);
|
|
6708
6968
|
}
|
|
@@ -6714,13 +6974,13 @@ class Deparser {
|
|
|
6714
6974
|
output.push(quote_utils_1.QuoteUtils.quote(node.fdwname));
|
|
6715
6975
|
}
|
|
6716
6976
|
if (node.func_options && node.func_options.length > 0) {
|
|
6717
|
-
const fdwContext =
|
|
6977
|
+
const fdwContext = context.spawn('AlterFdwStmt');
|
|
6718
6978
|
const funcOptions = list_utils_1.ListUtils.unwrapList(node.func_options).map(opt => this.visit(opt, fdwContext));
|
|
6719
6979
|
output.push(funcOptions.join(' '));
|
|
6720
6980
|
}
|
|
6721
6981
|
if (node.options && node.options.length > 0) {
|
|
6722
6982
|
output.push('OPTIONS');
|
|
6723
|
-
const fdwContext =
|
|
6983
|
+
const fdwContext = context.spawn('AlterFdwStmt');
|
|
6724
6984
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, fdwContext));
|
|
6725
6985
|
output.push(`(${options.join(', ')})`);
|
|
6726
6986
|
}
|
|
@@ -6746,7 +7006,7 @@ class Deparser {
|
|
|
6746
7006
|
if (node.options && node.options.length > 0) {
|
|
6747
7007
|
output.push('OPTIONS');
|
|
6748
7008
|
output.push('(');
|
|
6749
|
-
const optionsContext =
|
|
7009
|
+
const optionsContext = context.spawn('CreateForeignServerStmt');
|
|
6750
7010
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, optionsContext));
|
|
6751
7011
|
output.push(options.join(', '));
|
|
6752
7012
|
output.push(')');
|
|
@@ -6764,7 +7024,7 @@ class Deparser {
|
|
|
6764
7024
|
if (node.options && node.options.length > 0) {
|
|
6765
7025
|
output.push('OPTIONS');
|
|
6766
7026
|
output.push('(');
|
|
6767
|
-
const optionsContext =
|
|
7027
|
+
const optionsContext = context.spawn('AlterForeignServerStmt');
|
|
6768
7028
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, optionsContext));
|
|
6769
7029
|
output.push(options.join(', '));
|
|
6770
7030
|
output.push(')');
|
|
@@ -6785,7 +7045,7 @@ class Deparser {
|
|
|
6785
7045
|
}
|
|
6786
7046
|
if (node.options && node.options.length > 0) {
|
|
6787
7047
|
output.push('OPTIONS');
|
|
6788
|
-
const userMappingContext =
|
|
7048
|
+
const userMappingContext = context.spawn('AlterUserMappingStmt');
|
|
6789
7049
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, userMappingContext));
|
|
6790
7050
|
output.push(`(${options.join(', ')})`);
|
|
6791
7051
|
}
|
|
@@ -6845,7 +7105,7 @@ class Deparser {
|
|
|
6845
7105
|
output.push(quote_utils_1.QuoteUtils.quote(node.local_schema));
|
|
6846
7106
|
}
|
|
6847
7107
|
if (node.options && node.options.length > 0) {
|
|
6848
|
-
const importSchemaContext =
|
|
7108
|
+
const importSchemaContext = context.spawn('ImportForeignSchemaStmt');
|
|
6849
7109
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, importSchemaContext));
|
|
6850
7110
|
output.push(`OPTIONS (${options.join(', ')})`);
|
|
6851
7111
|
}
|
|
@@ -6880,7 +7140,7 @@ class Deparser {
|
|
|
6880
7140
|
ExplainStmt(node, context) {
|
|
6881
7141
|
const output = ['EXPLAIN'];
|
|
6882
7142
|
if (node.options && node.options.length > 0) {
|
|
6883
|
-
const explainContext =
|
|
7143
|
+
const explainContext = context.spawn('ExplainStmt');
|
|
6884
7144
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(option => this.visit(option, explainContext));
|
|
6885
7145
|
output.push(`(${options.join(', ')})`);
|
|
6886
7146
|
}
|
|
@@ -7138,9 +7398,7 @@ class Deparser {
|
|
|
7138
7398
|
output.push(this.RangeVar(node.relation, context));
|
|
7139
7399
|
}
|
|
7140
7400
|
else if (node.relation) {
|
|
7141
|
-
const rangeVarContext = node.relationType
|
|
7142
|
-
? { ...context, parentNodeTypes: [...context.parentNodeTypes, 'AlterTypeStmt'] }
|
|
7143
|
-
: context;
|
|
7401
|
+
const rangeVarContext = context.spawn('RenameStmt', { objtype: node.relationType });
|
|
7144
7402
|
// Add ON keyword for policy operations
|
|
7145
7403
|
if (node.renameType === 'OBJECT_POLICY') {
|
|
7146
7404
|
output.push('ON');
|
|
@@ -7322,7 +7580,7 @@ class Deparser {
|
|
|
7322
7580
|
}
|
|
7323
7581
|
}
|
|
7324
7582
|
if (node.privileges && node.privileges.length > 0) {
|
|
7325
|
-
const privilegeContext =
|
|
7583
|
+
const privilegeContext = context.spawn('GrantStmt');
|
|
7326
7584
|
const privileges = list_utils_1.ListUtils.unwrapList(node.privileges)
|
|
7327
7585
|
.map(priv => this.visit(priv, privilegeContext))
|
|
7328
7586
|
.join(', ');
|
|
@@ -7630,7 +7888,12 @@ class Deparser {
|
|
|
7630
7888
|
}
|
|
7631
7889
|
if (node.action) {
|
|
7632
7890
|
const actionStr = this.GrantStmt(node.action, context);
|
|
7633
|
-
|
|
7891
|
+
if (context.isPretty()) {
|
|
7892
|
+
return output.join(' ') + context.newline() + context.indent(actionStr);
|
|
7893
|
+
}
|
|
7894
|
+
else {
|
|
7895
|
+
output.push(actionStr);
|
|
7896
|
+
}
|
|
7634
7897
|
}
|
|
7635
7898
|
return output.join(' ');
|
|
7636
7899
|
}
|
|
@@ -7777,84 +8040,158 @@ class Deparser {
|
|
|
7777
8040
|
if (node.trigname) {
|
|
7778
8041
|
output.push(quote_utils_1.QuoteUtils.quote(node.trigname));
|
|
7779
8042
|
}
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
timing
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
events
|
|
7791
|
-
|
|
7792
|
-
events
|
|
7793
|
-
|
|
7794
|
-
events
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
.
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
|
|
7808
|
-
|
|
7809
|
-
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
.
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
output.push(args);
|
|
7852
|
-
output.push(')');
|
|
8043
|
+
if (context.isPretty()) {
|
|
8044
|
+
const components = [];
|
|
8045
|
+
const timing = [];
|
|
8046
|
+
if (node.timing & 2)
|
|
8047
|
+
timing.push('BEFORE');
|
|
8048
|
+
else if (node.timing & 64)
|
|
8049
|
+
timing.push('INSTEAD OF');
|
|
8050
|
+
else
|
|
8051
|
+
timing.push('AFTER');
|
|
8052
|
+
const events = [];
|
|
8053
|
+
if (node.events & 4)
|
|
8054
|
+
events.push('INSERT');
|
|
8055
|
+
if (node.events & 8)
|
|
8056
|
+
events.push('DELETE');
|
|
8057
|
+
if (node.events & 16) {
|
|
8058
|
+
let updateStr = 'UPDATE';
|
|
8059
|
+
if (node.columns && node.columns.length > 0) {
|
|
8060
|
+
const columnNames = list_utils_1.ListUtils.unwrapList(node.columns)
|
|
8061
|
+
.map(col => this.visit(col, context))
|
|
8062
|
+
.join(', ');
|
|
8063
|
+
updateStr += ' OF ' + columnNames;
|
|
8064
|
+
}
|
|
8065
|
+
events.push(updateStr);
|
|
8066
|
+
}
|
|
8067
|
+
if (node.events & 32)
|
|
8068
|
+
events.push('TRUNCATE');
|
|
8069
|
+
components.push(context.indent(timing.join(' ') + ' ' + events.join(' OR ')));
|
|
8070
|
+
if (node.relation) {
|
|
8071
|
+
components.push(context.indent('ON ' + this.RangeVar(node.relation, context)));
|
|
8072
|
+
}
|
|
8073
|
+
if (node.transitionRels && node.transitionRels.length > 0) {
|
|
8074
|
+
const transitionClauses = list_utils_1.ListUtils.unwrapList(node.transitionRels)
|
|
8075
|
+
.map(rel => this.visit(rel, context))
|
|
8076
|
+
.join(' ');
|
|
8077
|
+
components.push(context.indent('REFERENCING ' + transitionClauses));
|
|
8078
|
+
}
|
|
8079
|
+
if (node.deferrable) {
|
|
8080
|
+
components.push(context.indent('DEFERRABLE'));
|
|
8081
|
+
}
|
|
8082
|
+
if (node.initdeferred) {
|
|
8083
|
+
components.push(context.indent('INITIALLY DEFERRED'));
|
|
8084
|
+
}
|
|
8085
|
+
if (node.row) {
|
|
8086
|
+
components.push(context.indent('FOR EACH ROW'));
|
|
8087
|
+
}
|
|
8088
|
+
else {
|
|
8089
|
+
components.push(context.indent('FOR EACH STATEMENT'));
|
|
8090
|
+
}
|
|
8091
|
+
if (node.whenClause) {
|
|
8092
|
+
const whenStr = 'WHEN (' + this.visit(node.whenClause, context) + ')';
|
|
8093
|
+
components.push(context.indent(whenStr));
|
|
8094
|
+
}
|
|
8095
|
+
let executeStr = 'EXECUTE';
|
|
8096
|
+
if (node.funcname && node.funcname.length > 0) {
|
|
8097
|
+
const funcName = list_utils_1.ListUtils.unwrapList(node.funcname)
|
|
8098
|
+
.map(name => this.visit(name, context))
|
|
8099
|
+
.join('.');
|
|
8100
|
+
executeStr += ' PROCEDURE ' + funcName;
|
|
8101
|
+
}
|
|
8102
|
+
if (node.args && node.args.length > 0) {
|
|
8103
|
+
const argContext = context.spawn('CreateTrigStmt', { isStringLiteral: true });
|
|
8104
|
+
const args = list_utils_1.ListUtils.unwrapList(node.args)
|
|
8105
|
+
.map(arg => this.visit(arg, argContext))
|
|
8106
|
+
.join(', ');
|
|
8107
|
+
executeStr += '(' + args + ')';
|
|
8108
|
+
}
|
|
8109
|
+
else {
|
|
8110
|
+
executeStr += '()';
|
|
8111
|
+
}
|
|
8112
|
+
components.push(context.indent(executeStr));
|
|
8113
|
+
return output.join(' ') + context.newline() + components.join(context.newline());
|
|
7853
8114
|
}
|
|
7854
8115
|
else {
|
|
7855
|
-
|
|
8116
|
+
const timing = [];
|
|
8117
|
+
if (node.timing & 2)
|
|
8118
|
+
timing.push('BEFORE');
|
|
8119
|
+
else if (node.timing & 64)
|
|
8120
|
+
timing.push('INSTEAD OF');
|
|
8121
|
+
else
|
|
8122
|
+
timing.push('AFTER');
|
|
8123
|
+
output.push(timing.join(' '));
|
|
8124
|
+
const events = [];
|
|
8125
|
+
if (node.events & 4)
|
|
8126
|
+
events.push('INSERT');
|
|
8127
|
+
if (node.events & 8)
|
|
8128
|
+
events.push('DELETE');
|
|
8129
|
+
if (node.events & 16)
|
|
8130
|
+
events.push('UPDATE');
|
|
8131
|
+
if (node.events & 32)
|
|
8132
|
+
events.push('TRUNCATE');
|
|
8133
|
+
output.push(events.join(' OR '));
|
|
8134
|
+
if (node.columns && node.columns.length > 0) {
|
|
8135
|
+
output.push('OF');
|
|
8136
|
+
const columnNames = list_utils_1.ListUtils.unwrapList(node.columns)
|
|
8137
|
+
.map(col => this.visit(col, context))
|
|
8138
|
+
.join(', ');
|
|
8139
|
+
output.push(columnNames);
|
|
8140
|
+
}
|
|
8141
|
+
output.push('ON');
|
|
8142
|
+
if (node.relation) {
|
|
8143
|
+
output.push(this.RangeVar(node.relation, context));
|
|
8144
|
+
}
|
|
8145
|
+
if (node.constrrel) {
|
|
8146
|
+
output.push('FROM');
|
|
8147
|
+
output.push(this.RangeVar(node.constrrel, context));
|
|
8148
|
+
}
|
|
8149
|
+
if (node.deferrable) {
|
|
8150
|
+
output.push('DEFERRABLE');
|
|
8151
|
+
}
|
|
8152
|
+
if (node.initdeferred) {
|
|
8153
|
+
output.push('INITIALLY DEFERRED');
|
|
8154
|
+
}
|
|
8155
|
+
if (node.transitionRels && node.transitionRels.length > 0) {
|
|
8156
|
+
output.push('REFERENCING');
|
|
8157
|
+
const transitionClauses = list_utils_1.ListUtils.unwrapList(node.transitionRels)
|
|
8158
|
+
.map(rel => this.visit(rel, context))
|
|
8159
|
+
.join(' ');
|
|
8160
|
+
output.push(transitionClauses);
|
|
8161
|
+
}
|
|
8162
|
+
if (node.row) {
|
|
8163
|
+
output.push('FOR EACH ROW');
|
|
8164
|
+
}
|
|
8165
|
+
else {
|
|
8166
|
+
output.push('FOR EACH STATEMENT');
|
|
8167
|
+
}
|
|
8168
|
+
if (node.whenClause) {
|
|
8169
|
+
output.push('WHEN');
|
|
8170
|
+
output.push('(');
|
|
8171
|
+
output.push(this.visit(node.whenClause, context));
|
|
8172
|
+
output.push(')');
|
|
8173
|
+
}
|
|
8174
|
+
output.push('EXECUTE');
|
|
8175
|
+
if (node.funcname && node.funcname.length > 0) {
|
|
8176
|
+
const funcName = list_utils_1.ListUtils.unwrapList(node.funcname)
|
|
8177
|
+
.map(name => this.visit(name, context))
|
|
8178
|
+
.join('.');
|
|
8179
|
+
output.push('FUNCTION', funcName);
|
|
8180
|
+
}
|
|
8181
|
+
if (node.args && node.args.length > 0) {
|
|
8182
|
+
output.push('(');
|
|
8183
|
+
const argContext = context.spawn('CreateTrigStmt', { isStringLiteral: true });
|
|
8184
|
+
const args = list_utils_1.ListUtils.unwrapList(node.args)
|
|
8185
|
+
.map(arg => this.visit(arg, argContext))
|
|
8186
|
+
.join(', ');
|
|
8187
|
+
output.push(args);
|
|
8188
|
+
output.push(')');
|
|
8189
|
+
}
|
|
8190
|
+
else {
|
|
8191
|
+
output.push('()');
|
|
8192
|
+
}
|
|
8193
|
+
return output.join(' ');
|
|
7856
8194
|
}
|
|
7857
|
-
return output.join(' ');
|
|
7858
8195
|
}
|
|
7859
8196
|
TriggerTransition(node, context) {
|
|
7860
8197
|
const output = [];
|
|
@@ -7880,7 +8217,7 @@ class Deparser {
|
|
|
7880
8217
|
}
|
|
7881
8218
|
if (node.whenclause && node.whenclause.length > 0) {
|
|
7882
8219
|
output.push('WHEN');
|
|
7883
|
-
const eventTriggerContext =
|
|
8220
|
+
const eventTriggerContext = context.spawn('CreateEventTrigStmt');
|
|
7884
8221
|
const conditions = list_utils_1.ListUtils.unwrapList(node.whenclause)
|
|
7885
8222
|
.map(condition => this.visit(condition, eventTriggerContext))
|
|
7886
8223
|
.join(' AND ');
|
|
@@ -8069,7 +8406,7 @@ class Deparser {
|
|
|
8069
8406
|
output.push(sequenceName.join('.'));
|
|
8070
8407
|
}
|
|
8071
8408
|
if (node.options && node.options.length > 0) {
|
|
8072
|
-
const seqContext =
|
|
8409
|
+
const seqContext = context.spawn('CreateSeqStmt');
|
|
8073
8410
|
const optionStrs = list_utils_1.ListUtils.unwrapList(node.options)
|
|
8074
8411
|
.filter(option => option != null && this.getNodeType(option) !== 'undefined')
|
|
8075
8412
|
.map(option => {
|
|
@@ -8106,7 +8443,7 @@ class Deparser {
|
|
|
8106
8443
|
output.push(sequenceName.join('.'));
|
|
8107
8444
|
}
|
|
8108
8445
|
if (node.options && node.options.length > 0) {
|
|
8109
|
-
const seqContext =
|
|
8446
|
+
const seqContext = context.spawn('AlterSeqStmt');
|
|
8110
8447
|
const optionStrs = list_utils_1.ListUtils.unwrapList(node.options)
|
|
8111
8448
|
.filter(option => option && option !== undefined)
|
|
8112
8449
|
.map(option => {
|
|
@@ -8135,7 +8472,7 @@ class Deparser {
|
|
|
8135
8472
|
CompositeTypeStmt(node, context) {
|
|
8136
8473
|
const output = ['CREATE', 'TYPE'];
|
|
8137
8474
|
if (node.typevar) {
|
|
8138
|
-
const typeContext =
|
|
8475
|
+
const typeContext = context.spawn('CompositeTypeStmt');
|
|
8139
8476
|
output.push(this.RangeVar(node.typevar, typeContext));
|
|
8140
8477
|
}
|
|
8141
8478
|
output.push('AS');
|
|
@@ -8236,7 +8573,7 @@ class Deparser {
|
|
|
8236
8573
|
output.push(this.RoleSpec(node.role, context));
|
|
8237
8574
|
}
|
|
8238
8575
|
if (node.options) {
|
|
8239
|
-
const roleContext =
|
|
8576
|
+
const roleContext = context.spawn('AlterRoleStmt');
|
|
8240
8577
|
// Handle GROUP operations specially based on action value
|
|
8241
8578
|
if (isGroupStatement) {
|
|
8242
8579
|
const roleMembersOption = list_utils_1.ListUtils.unwrapList(node.options).find(option => option.DefElem && option.DefElem.defname === 'rolemembers');
|
|
@@ -8432,14 +8769,14 @@ class Deparser {
|
|
|
8432
8769
|
AccessPriv(node, context) {
|
|
8433
8770
|
const output = [];
|
|
8434
8771
|
if (node.priv_name) {
|
|
8435
|
-
output.push(node.priv_name);
|
|
8772
|
+
output.push(node.priv_name.toUpperCase());
|
|
8436
8773
|
}
|
|
8437
8774
|
else {
|
|
8438
8775
|
output.push('ALL');
|
|
8439
8776
|
}
|
|
8440
8777
|
if (node.cols && node.cols.length > 0) {
|
|
8441
8778
|
output.push('(');
|
|
8442
|
-
const colContext =
|
|
8779
|
+
const colContext = context.spawn('AccessPriv');
|
|
8443
8780
|
const columns = list_utils_1.ListUtils.unwrapList(node.cols).map(col => this.visit(col, colContext));
|
|
8444
8781
|
output.push(columns.join(', '));
|
|
8445
8782
|
output.push(')');
|
|
@@ -8519,7 +8856,7 @@ class Deparser {
|
|
|
8519
8856
|
output.push(list_utils_1.ListUtils.unwrapList(node.defnames).map(name => this.visit(name, context)).join('.'));
|
|
8520
8857
|
}
|
|
8521
8858
|
if (node.definition && node.definition.length > 0) {
|
|
8522
|
-
const defineStmtContext =
|
|
8859
|
+
const defineStmtContext = context.spawn('DefineStmt');
|
|
8523
8860
|
const definitions = list_utils_1.ListUtils.unwrapList(node.definition).map(def => {
|
|
8524
8861
|
return this.visit(def, defineStmtContext);
|
|
8525
8862
|
});
|
|
@@ -9005,7 +9342,7 @@ class Deparser {
|
|
|
9005
9342
|
const operatorNumber = node.number !== undefined ? node.number : 0;
|
|
9006
9343
|
output.push(operatorNumber.toString());
|
|
9007
9344
|
if (node.name) {
|
|
9008
|
-
const opClassContext =
|
|
9345
|
+
const opClassContext = context.spawn('CreateOpClassItem');
|
|
9009
9346
|
output.push(this.ObjectWithArgs(node.name, opClassContext));
|
|
9010
9347
|
}
|
|
9011
9348
|
}
|
|
@@ -9015,7 +9352,7 @@ class Deparser {
|
|
|
9015
9352
|
const functionNumber = node.number !== undefined ? node.number : 0;
|
|
9016
9353
|
output.push(functionNumber.toString());
|
|
9017
9354
|
if (node.name) {
|
|
9018
|
-
const opClassContext =
|
|
9355
|
+
const opClassContext = context.spawn('CreateOpClassItem');
|
|
9019
9356
|
output.push(this.ObjectWithArgs(node.name, opClassContext));
|
|
9020
9357
|
}
|
|
9021
9358
|
}
|
|
@@ -9713,7 +10050,7 @@ class Deparser {
|
|
|
9713
10050
|
output.push(this.ObjectWithArgs(node.func, context));
|
|
9714
10051
|
}
|
|
9715
10052
|
if (node.actions && node.actions.length > 0) {
|
|
9716
|
-
const alterFunctionContext =
|
|
10053
|
+
const alterFunctionContext = context.spawn('AlterFunctionStmt');
|
|
9717
10054
|
const actionStrs = list_utils_1.ListUtils.unwrapList(node.actions).map(action => this.visit(action, alterFunctionContext));
|
|
9718
10055
|
output.push(actionStrs.join(' '));
|
|
9719
10056
|
}
|
|
@@ -9957,7 +10294,7 @@ class Deparser {
|
|
|
9957
10294
|
CreateForeignTableStmt(node, context) {
|
|
9958
10295
|
const output = ['CREATE FOREIGN TABLE'];
|
|
9959
10296
|
if (node.base && node.base.relation) {
|
|
9960
|
-
const relationContext =
|
|
10297
|
+
const relationContext = context.spawn('CreateForeignTableStmt');
|
|
9961
10298
|
// Handle relation node directly as RangeVar since it contains the RangeVar properties
|
|
9962
10299
|
output.push(this.RangeVar(node.base.relation, relationContext));
|
|
9963
10300
|
}
|
|
@@ -9987,7 +10324,7 @@ class Deparser {
|
|
|
9987
10324
|
output.push(quote_utils_1.QuoteUtils.quote(node.servername));
|
|
9988
10325
|
}
|
|
9989
10326
|
if (node.options && node.options.length > 0) {
|
|
9990
|
-
const foreignTableContext =
|
|
10327
|
+
const foreignTableContext = context.spawn('CreateForeignTableStmt');
|
|
9991
10328
|
const optionStrs = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, foreignTableContext));
|
|
9992
10329
|
output.push(`OPTIONS (${optionStrs.join(', ')})`);
|
|
9993
10330
|
}
|