pgsql-deparser 16.0.0 → 17.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -88
- package/deparser.d.ts +297 -0
- package/{deparser/deparser.js → deparser.js} +110 -435
- package/esm/{deparser/deparser.js → deparser.js} +110 -435
- package/esm/index.js +3 -15
- package/esm/utils/index.js +90 -0
- package/esm/{deparser/utils → utils}/list-utils.js +0 -4
- package/esm/{deparser/utils → utils}/quote-utils.js +0 -34
- package/esm/utils/sql-formatter.js +23 -0
- package/esm/{deparser/visitors → visitors}/base.js +0 -4
- package/index.d.ts +3 -9
- package/index.js +4 -16
- package/package.json +27 -14
- package/utils/index.d.ts +4 -0
- package/utils/index.js +97 -0
- package/{deparser/utils → utils}/list-utils.d.ts +0 -4
- package/{deparser/utils → utils}/list-utils.js +0 -4
- package/utils/quote-utils.d.ts +5 -0
- package/{deparser/utils → utils}/quote-utils.js +0 -34
- package/{deparser/utils → utils}/sql-formatter.d.ts +1 -7
- package/{deparser/utils → utils}/sql-formatter.js +2 -15
- package/{deparser/visitors → visitors}/base.d.ts +5 -8
- package/{deparser/visitors → visitors}/base.js +0 -4
- package/deparser/deparser.d.ts +0 -301
- package/deparser/index.d.ts +0 -9
- package/deparser/index.js +0 -17
- package/deparser/utils/quote-utils.d.ts +0 -24
- package/esm/deparser/index.js +0 -13
- package/esm/deparser/utils/sql-formatter.js +0 -36
- package/esm/v16-to-v17-direct.js +0 -44
- package/esm/v16-to-v17.js +0 -1488
- package/v16-to-v17-direct.d.ts +0 -21
- package/v16-to-v17-direct.js +0 -48
- package/v16-to-v17.d.ts +0 -638
- package/v16-to-v17.js +0 -1492
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Auto-generated file with types stripped for better tree-shaking
|
|
4
|
-
* DO NOT EDIT - Generated by strip-deparser-types.ts
|
|
5
|
-
*/
|
|
6
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
3
|
exports.Deparser = void 0;
|
|
8
4
|
const sql_formatter_1 = require("./utils/sql-formatter");
|
|
@@ -55,7 +51,7 @@ class Deparser {
|
|
|
55
51
|
tree;
|
|
56
52
|
options;
|
|
57
53
|
constructor(tree, opts = {}) {
|
|
58
|
-
this.formatter = new sql_formatter_1.SqlFormatter(opts.newline, opts.tab
|
|
54
|
+
this.formatter = new sql_formatter_1.SqlFormatter(opts.newline, opts.tab);
|
|
59
55
|
// Set default options
|
|
60
56
|
this.options = {
|
|
61
57
|
functionDelimiter: '$$',
|
|
@@ -188,25 +184,23 @@ class Deparser {
|
|
|
188
184
|
}
|
|
189
185
|
if (!node.op || node.op === 'SETOP_NONE') {
|
|
190
186
|
if (node.valuesLists == null) {
|
|
191
|
-
|
|
192
|
-
output.push('SELECT');
|
|
193
|
-
}
|
|
187
|
+
output.push('SELECT');
|
|
194
188
|
}
|
|
195
189
|
}
|
|
196
190
|
else {
|
|
197
191
|
const leftStmt = this.SelectStmt(node.larg, context);
|
|
198
192
|
const rightStmt = this.SelectStmt(node.rarg, context);
|
|
199
193
|
// Add parentheses if the operand is a set operation OR has ORDER BY/LIMIT clauses OR has WITH clause
|
|
200
|
-
const leftNeedsParens = node.larg && ((
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const rightNeedsParens = node.rarg && ((
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
194
|
+
const leftNeedsParens = node.larg && ((node.larg.op && node.larg.op !== 'SETOP_NONE') ||
|
|
195
|
+
node.larg.sortClause ||
|
|
196
|
+
node.larg.limitCount ||
|
|
197
|
+
node.larg.limitOffset ||
|
|
198
|
+
node.larg.withClause);
|
|
199
|
+
const rightNeedsParens = node.rarg && ((node.rarg.op && node.rarg.op !== 'SETOP_NONE') ||
|
|
200
|
+
node.rarg.sortClause ||
|
|
201
|
+
node.rarg.limitCount ||
|
|
202
|
+
node.rarg.limitOffset ||
|
|
203
|
+
node.rarg.withClause);
|
|
210
204
|
if (leftNeedsParens) {
|
|
211
205
|
output.push(this.formatter.parens(leftStmt));
|
|
212
206
|
}
|
|
@@ -236,82 +230,41 @@ class Deparser {
|
|
|
236
230
|
output.push(rightStmt);
|
|
237
231
|
}
|
|
238
232
|
}
|
|
239
|
-
// Handle DISTINCT clause - in pretty mode, we'll include it in the SELECT clause
|
|
240
|
-
let distinctPart = '';
|
|
241
233
|
if (node.distinctClause) {
|
|
242
234
|
const distinctClause = list_utils_1.ListUtils.unwrapList(node.distinctClause);
|
|
243
235
|
if (distinctClause.length > 0 && Object.keys(distinctClause[0]).length > 0) {
|
|
236
|
+
output.push('DISTINCT ON');
|
|
244
237
|
const clause = distinctClause
|
|
245
238
|
.map(e => this.visit(e, { ...context, select: true }))
|
|
246
239
|
.join(', ');
|
|
247
|
-
|
|
240
|
+
output.push(this.formatter.parens(clause));
|
|
248
241
|
}
|
|
249
242
|
else {
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
if (!this.formatter.isPretty()) {
|
|
253
|
-
if (distinctClause.length > 0 && Object.keys(distinctClause[0]).length > 0) {
|
|
254
|
-
output.push('DISTINCT ON');
|
|
255
|
-
const clause = distinctClause
|
|
256
|
-
.map(e => this.visit(e, { ...context, select: true }))
|
|
257
|
-
.join(', ');
|
|
258
|
-
output.push(this.formatter.parens(clause));
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
output.push('DISTINCT');
|
|
262
|
-
}
|
|
243
|
+
output.push('DISTINCT');
|
|
263
244
|
}
|
|
264
245
|
}
|
|
265
246
|
if (node.targetList) {
|
|
266
247
|
const targetList = list_utils_1.ListUtils.unwrapList(node.targetList);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (this.containsMultilineStringLiteral(targetStr)) {
|
|
272
|
-
return targetStr;
|
|
273
|
-
}
|
|
274
|
-
return this.formatter.indent(targetStr);
|
|
275
|
-
});
|
|
276
|
-
const formattedTargets = targetStrings.join(',' + this.formatter.newline());
|
|
277
|
-
output.push('SELECT' + distinctPart);
|
|
278
|
-
output.push(formattedTargets);
|
|
279
|
-
}
|
|
280
|
-
else {
|
|
281
|
-
const targets = targetList
|
|
282
|
-
.map(e => this.visit(e, { ...context, select: true }))
|
|
283
|
-
.join(', ');
|
|
284
|
-
output.push(targets);
|
|
285
|
-
}
|
|
248
|
+
const targets = targetList
|
|
249
|
+
.map(e => this.visit(e, { ...context, select: true }))
|
|
250
|
+
.join(', ');
|
|
251
|
+
output.push(targets);
|
|
286
252
|
}
|
|
287
253
|
if (node.intoClause) {
|
|
288
254
|
output.push('INTO');
|
|
289
255
|
output.push(this.IntoClause(node.intoClause, context));
|
|
290
256
|
}
|
|
291
257
|
if (node.fromClause) {
|
|
258
|
+
output.push('FROM');
|
|
292
259
|
const fromList = list_utils_1.ListUtils.unwrapList(node.fromClause);
|
|
293
260
|
const fromItems = fromList
|
|
294
261
|
.map(e => this.deparse(e, { ...context, from: true }))
|
|
295
262
|
.join(', ');
|
|
296
|
-
output.push(
|
|
263
|
+
output.push(fromItems);
|
|
297
264
|
}
|
|
298
265
|
if (node.whereClause) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const whereExpr = this.visit(node.whereClause, context);
|
|
302
|
-
const lines = whereExpr.split(this.formatter.newline());
|
|
303
|
-
const indentedLines = lines.map((line, index) => {
|
|
304
|
-
if (index === 0) {
|
|
305
|
-
return this.formatter.indent(line);
|
|
306
|
-
}
|
|
307
|
-
return line;
|
|
308
|
-
});
|
|
309
|
-
output.push(indentedLines.join(this.formatter.newline()));
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
output.push('WHERE');
|
|
313
|
-
output.push(this.visit(node.whereClause, context));
|
|
314
|
-
}
|
|
266
|
+
output.push('WHERE');
|
|
267
|
+
output.push(this.visit(node.whereClause, context));
|
|
315
268
|
}
|
|
316
269
|
if (node.valuesLists) {
|
|
317
270
|
output.push('VALUES');
|
|
@@ -322,43 +275,16 @@ class Deparser {
|
|
|
322
275
|
output.push(lists.join(', '));
|
|
323
276
|
}
|
|
324
277
|
if (node.groupClause) {
|
|
278
|
+
output.push('GROUP BY');
|
|
325
279
|
const groupList = list_utils_1.ListUtils.unwrapList(node.groupClause);
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
if (this.containsMultilineStringLiteral(groupStr)) {
|
|
331
|
-
return groupStr;
|
|
332
|
-
}
|
|
333
|
-
return this.formatter.indent(groupStr);
|
|
334
|
-
})
|
|
335
|
-
.join(',' + this.formatter.newline());
|
|
336
|
-
output.push('GROUP BY');
|
|
337
|
-
output.push(groupItems);
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
output.push('GROUP BY');
|
|
341
|
-
const groupItems = groupList
|
|
342
|
-
.map(e => this.visit(e, { ...context, group: true }))
|
|
343
|
-
.join(', ');
|
|
344
|
-
output.push(groupItems);
|
|
345
|
-
}
|
|
280
|
+
const groupItems = groupList
|
|
281
|
+
.map(e => this.visit(e, { ...context, group: true }))
|
|
282
|
+
.join(', ');
|
|
283
|
+
output.push(groupItems);
|
|
346
284
|
}
|
|
347
285
|
if (node.havingClause) {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
const havingStr = this.visit(node.havingClause, context);
|
|
351
|
-
if (this.containsMultilineStringLiteral(havingStr)) {
|
|
352
|
-
output.push(havingStr);
|
|
353
|
-
}
|
|
354
|
-
else {
|
|
355
|
-
output.push(this.formatter.indent(havingStr));
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
output.push('HAVING');
|
|
360
|
-
output.push(this.visit(node.havingClause, context));
|
|
361
|
-
}
|
|
286
|
+
output.push('HAVING');
|
|
287
|
+
output.push(this.visit(node.havingClause, context));
|
|
362
288
|
}
|
|
363
289
|
if (node.windowClause) {
|
|
364
290
|
output.push('WINDOW');
|
|
@@ -369,33 +295,20 @@ class Deparser {
|
|
|
369
295
|
output.push(windowClauses);
|
|
370
296
|
}
|
|
371
297
|
if (node.sortClause) {
|
|
298
|
+
output.push('ORDER BY');
|
|
372
299
|
const sortList = list_utils_1.ListUtils.unwrapList(node.sortClause);
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
if (this.containsMultilineStringLiteral(sortStr)) {
|
|
378
|
-
return sortStr;
|
|
379
|
-
}
|
|
380
|
-
return this.formatter.indent(sortStr);
|
|
381
|
-
})
|
|
382
|
-
.join(',' + this.formatter.newline());
|
|
383
|
-
output.push('ORDER BY');
|
|
384
|
-
output.push(sortItems);
|
|
385
|
-
}
|
|
386
|
-
else {
|
|
387
|
-
output.push('ORDER BY');
|
|
388
|
-
const sortItems = sortList
|
|
389
|
-
.map(e => this.visit(e, { ...context, sort: true }))
|
|
390
|
-
.join(', ');
|
|
391
|
-
output.push(sortItems);
|
|
392
|
-
}
|
|
300
|
+
const sortItems = sortList
|
|
301
|
+
.map(e => this.visit(e, { ...context, sort: true }))
|
|
302
|
+
.join(', ');
|
|
303
|
+
output.push(sortItems);
|
|
393
304
|
}
|
|
394
305
|
if (node.limitCount) {
|
|
395
|
-
output.push('LIMIT
|
|
306
|
+
output.push('LIMIT');
|
|
307
|
+
output.push(this.visit(node.limitCount, context));
|
|
396
308
|
}
|
|
397
309
|
if (node.limitOffset) {
|
|
398
|
-
output.push('OFFSET
|
|
310
|
+
output.push('OFFSET');
|
|
311
|
+
output.push(this.visit(node.limitOffset, context));
|
|
399
312
|
}
|
|
400
313
|
if (node.lockingClause) {
|
|
401
314
|
const lockingList = list_utils_1.ListUtils.unwrapList(node.lockingClause);
|
|
@@ -404,10 +317,6 @@ class Deparser {
|
|
|
404
317
|
.join(' ');
|
|
405
318
|
output.push(lockingClauses);
|
|
406
319
|
}
|
|
407
|
-
if (this.formatter.isPretty()) {
|
|
408
|
-
const filteredOutput = output.filter(item => item.trim() !== '');
|
|
409
|
-
return filteredOutput.join(this.formatter.newline());
|
|
410
|
-
}
|
|
411
320
|
return output.join(' ');
|
|
412
321
|
}
|
|
413
322
|
A_Expr(node, context) {
|
|
@@ -472,38 +381,18 @@ class Deparser {
|
|
|
472
381
|
'ALL',
|
|
473
382
|
this.formatter.parens(this.visit(rexpr, context))
|
|
474
383
|
]);
|
|
475
|
-
case 'AEXPR_DISTINCT':
|
|
476
|
-
let leftExpr = this.visit(lexpr, context);
|
|
477
|
-
let rightExpr = this.visit(rexpr, context);
|
|
478
|
-
// Add parentheses for complex expressions
|
|
479
|
-
if (lexpr && this.isComplexExpression(lexpr)) {
|
|
480
|
-
leftExpr = this.formatter.parens(leftExpr);
|
|
481
|
-
}
|
|
482
|
-
if (rexpr && this.isComplexExpression(rexpr)) {
|
|
483
|
-
rightExpr = this.formatter.parens(rightExpr);
|
|
484
|
-
}
|
|
384
|
+
case 'AEXPR_DISTINCT':
|
|
485
385
|
return this.formatter.format([
|
|
486
|
-
|
|
386
|
+
this.visit(lexpr, context),
|
|
487
387
|
'IS DISTINCT FROM',
|
|
488
|
-
|
|
388
|
+
this.visit(rexpr, context)
|
|
489
389
|
]);
|
|
490
|
-
|
|
491
|
-
case 'AEXPR_NOT_DISTINCT': {
|
|
492
|
-
let leftExpr = this.visit(lexpr, context);
|
|
493
|
-
let rightExpr = this.visit(rexpr, context);
|
|
494
|
-
// Add parentheses for complex expressions
|
|
495
|
-
if (lexpr && this.isComplexExpression(lexpr)) {
|
|
496
|
-
leftExpr = this.formatter.parens(leftExpr);
|
|
497
|
-
}
|
|
498
|
-
if (rexpr && this.isComplexExpression(rexpr)) {
|
|
499
|
-
rightExpr = this.formatter.parens(rightExpr);
|
|
500
|
-
}
|
|
390
|
+
case 'AEXPR_NOT_DISTINCT':
|
|
501
391
|
return this.formatter.format([
|
|
502
|
-
|
|
392
|
+
this.visit(lexpr, context),
|
|
503
393
|
'IS NOT DISTINCT FROM',
|
|
504
|
-
|
|
394
|
+
this.visit(rexpr, context)
|
|
505
395
|
]);
|
|
506
|
-
}
|
|
507
396
|
case 'AEXPR_NULLIF':
|
|
508
397
|
return this.formatter.format([
|
|
509
398
|
'NULLIF',
|
|
@@ -897,24 +786,9 @@ class Deparser {
|
|
|
897
786
|
if (node.recursive) {
|
|
898
787
|
output.push('RECURSIVE');
|
|
899
788
|
}
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
const cteStrings = ctes.map((cte, index) => {
|
|
904
|
-
const cteStr = this.visit(cte, context);
|
|
905
|
-
const prefix = index === 0 ? this.formatter.newline() : ',' + this.formatter.newline();
|
|
906
|
-
if (this.containsMultilineStringLiteral(cteStr)) {
|
|
907
|
-
return prefix + cteStr;
|
|
908
|
-
}
|
|
909
|
-
return prefix + this.formatter.indent(cteStr);
|
|
910
|
-
});
|
|
911
|
-
output.push(cteStrings.join(''));
|
|
912
|
-
}
|
|
913
|
-
else {
|
|
914
|
-
const cteStrings = ctes.map(cte => this.visit(cte, context));
|
|
915
|
-
output.push(cteStrings.join(', '));
|
|
916
|
-
}
|
|
917
|
-
}
|
|
789
|
+
const ctes = list_utils_1.ListUtils.unwrapList(node.ctes);
|
|
790
|
+
const cteStrs = ctes.map(cte => this.visit(cte, context));
|
|
791
|
+
output.push(cteStrs.join(', '));
|
|
918
792
|
return output.join(' ');
|
|
919
793
|
}
|
|
920
794
|
ResTarget(node, context) {
|
|
@@ -993,28 +867,13 @@ class Deparser {
|
|
|
993
867
|
formatStr = '(%s)';
|
|
994
868
|
}
|
|
995
869
|
const boolContext = { ...context, bool: true };
|
|
996
|
-
// explanation of our syntax/fix below:
|
|
997
|
-
// return formatStr.replace('%s', andArgs); // ❌ Interprets $ as special syntax
|
|
998
|
-
// return formatStr.replace('%s', () => andArgs); // ✅ Function callback prevents interpretation
|
|
999
870
|
switch (boolop) {
|
|
1000
871
|
case 'AND_EXPR':
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
return formatStr.replace('%s', () => andArgs);
|
|
1004
|
-
}
|
|
1005
|
-
else {
|
|
1006
|
-
const andArgs = args.map(arg => this.visit(arg, boolContext)).join(' AND ');
|
|
1007
|
-
return formatStr.replace('%s', () => andArgs);
|
|
1008
|
-
}
|
|
872
|
+
const andArgs = args.map(arg => this.visit(arg, boolContext)).join(' AND ');
|
|
873
|
+
return formatStr.replace('%s', andArgs);
|
|
1009
874
|
case 'OR_EXPR':
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
return formatStr.replace('%s', () => orArgs);
|
|
1013
|
-
}
|
|
1014
|
-
else {
|
|
1015
|
-
const orArgs = args.map(arg => this.visit(arg, boolContext)).join(' OR ');
|
|
1016
|
-
return formatStr.replace('%s', () => orArgs);
|
|
1017
|
-
}
|
|
875
|
+
const orArgs = args.map(arg => this.visit(arg, boolContext)).join(' OR ');
|
|
876
|
+
return formatStr.replace('%s', orArgs);
|
|
1018
877
|
case 'NOT_EXPR':
|
|
1019
878
|
return `NOT (${this.visit(args[0], context)})`;
|
|
1020
879
|
default:
|
|
@@ -1216,13 +1075,7 @@ class Deparser {
|
|
|
1216
1075
|
windowParts.push(frameClause);
|
|
1217
1076
|
}
|
|
1218
1077
|
if (windowParts.length > 0) {
|
|
1219
|
-
|
|
1220
|
-
const formattedParts = windowParts.map(part => this.formatter.indent(part));
|
|
1221
|
-
result += ` OVER (${this.formatter.newline()}${formattedParts.join(this.formatter.newline())}${this.formatter.newline()})`;
|
|
1222
|
-
}
|
|
1223
|
-
else {
|
|
1224
|
-
result += ` OVER (${windowParts.join(' ')})`;
|
|
1225
|
-
}
|
|
1078
|
+
result += ` OVER (${windowParts.join(' ')})`;
|
|
1226
1079
|
}
|
|
1227
1080
|
else {
|
|
1228
1081
|
result += ` OVER ()`;
|
|
@@ -1279,23 +1132,23 @@ class Deparser {
|
|
|
1279
1132
|
else if (nodeAny.sval !== undefined) {
|
|
1280
1133
|
if (typeof nodeAny.sval === 'object' && nodeAny.sval !== null) {
|
|
1281
1134
|
if (nodeAny.sval.sval !== undefined) {
|
|
1282
|
-
return quote_utils_1.QuoteUtils.
|
|
1135
|
+
return quote_utils_1.QuoteUtils.escape(nodeAny.sval.sval);
|
|
1283
1136
|
}
|
|
1284
1137
|
else if (nodeAny.sval.String && nodeAny.sval.String.sval !== undefined) {
|
|
1285
|
-
return quote_utils_1.QuoteUtils.
|
|
1138
|
+
return quote_utils_1.QuoteUtils.escape(nodeAny.sval.String.sval);
|
|
1286
1139
|
}
|
|
1287
1140
|
else if (Object.keys(nodeAny.sval).length === 0) {
|
|
1288
1141
|
return "''";
|
|
1289
1142
|
}
|
|
1290
1143
|
else {
|
|
1291
|
-
return quote_utils_1.QuoteUtils.
|
|
1144
|
+
return quote_utils_1.QuoteUtils.escape(nodeAny.sval.toString());
|
|
1292
1145
|
}
|
|
1293
1146
|
}
|
|
1294
1147
|
else if (nodeAny.sval === null) {
|
|
1295
1148
|
return 'NULL';
|
|
1296
1149
|
}
|
|
1297
1150
|
else {
|
|
1298
|
-
return quote_utils_1.QuoteUtils.
|
|
1151
|
+
return quote_utils_1.QuoteUtils.escape(nodeAny.sval);
|
|
1299
1152
|
}
|
|
1300
1153
|
}
|
|
1301
1154
|
else if (nodeAny.boolval !== undefined) {
|
|
@@ -1603,14 +1456,7 @@ class Deparser {
|
|
|
1603
1456
|
output.push('ONLY');
|
|
1604
1457
|
}
|
|
1605
1458
|
let tableName = '';
|
|
1606
|
-
if (node.
|
|
1607
|
-
tableName = quote_utils_1.QuoteUtils.quote(node.catalogname);
|
|
1608
|
-
if (node.schemaname) {
|
|
1609
|
-
tableName += '.' + quote_utils_1.QuoteUtils.quote(node.schemaname);
|
|
1610
|
-
}
|
|
1611
|
-
tableName += '.' + quote_utils_1.QuoteUtils.quote(node.relname);
|
|
1612
|
-
}
|
|
1613
|
-
else if (node.schemaname) {
|
|
1459
|
+
if (node.schemaname) {
|
|
1614
1460
|
tableName = quote_utils_1.QuoteUtils.quote(node.schemaname) + '.' + quote_utils_1.QuoteUtils.quote(node.relname);
|
|
1615
1461
|
}
|
|
1616
1462
|
else {
|
|
@@ -1846,39 +1692,15 @@ class Deparser {
|
|
|
1846
1692
|
output.push(this.visit(node.arg, context));
|
|
1847
1693
|
}
|
|
1848
1694
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
const whenClause = this.visit(arg, context);
|
|
1852
|
-
if (this.containsMultilineStringLiteral(whenClause)) {
|
|
1853
|
-
output.push(this.formatter.newline() + whenClause);
|
|
1854
|
-
}
|
|
1855
|
-
else {
|
|
1856
|
-
output.push(this.formatter.newline() + this.formatter.indent(whenClause));
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
|
-
if (node.defresult) {
|
|
1860
|
-
const elseResult = this.visit(node.defresult, context);
|
|
1861
|
-
if (this.containsMultilineStringLiteral(elseResult)) {
|
|
1862
|
-
output.push(this.formatter.newline() + 'ELSE ' + elseResult);
|
|
1863
|
-
}
|
|
1864
|
-
else {
|
|
1865
|
-
output.push(this.formatter.newline() + this.formatter.indent('ELSE ' + elseResult));
|
|
1866
|
-
}
|
|
1867
|
-
}
|
|
1868
|
-
output.push(this.formatter.newline() + 'END');
|
|
1869
|
-
return output.join(' ');
|
|
1695
|
+
for (const arg of args) {
|
|
1696
|
+
output.push(this.visit(arg, context));
|
|
1870
1697
|
}
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
}
|
|
1875
|
-
if (node.defresult) {
|
|
1876
|
-
output.push('ELSE');
|
|
1877
|
-
output.push(this.visit(node.defresult, context));
|
|
1878
|
-
}
|
|
1879
|
-
output.push('END');
|
|
1880
|
-
return output.join(' ');
|
|
1698
|
+
if (node.defresult) {
|
|
1699
|
+
output.push('ELSE');
|
|
1700
|
+
output.push(this.visit(node.defresult, context));
|
|
1881
1701
|
}
|
|
1702
|
+
output.push('END');
|
|
1703
|
+
return output.join(' ');
|
|
1882
1704
|
}
|
|
1883
1705
|
CoalesceExpr(node, context) {
|
|
1884
1706
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
@@ -2013,7 +1835,7 @@ class Deparser {
|
|
|
2013
1835
|
}
|
|
2014
1836
|
String(node, context) {
|
|
2015
1837
|
if (context.isStringLiteral || context.isEnumValue) {
|
|
2016
|
-
return
|
|
1838
|
+
return `'${node.sval || ''}'`;
|
|
2017
1839
|
}
|
|
2018
1840
|
const value = node.sval || '';
|
|
2019
1841
|
if (context.parentNodeTypes.includes('DefElem') ||
|
|
@@ -2091,13 +1913,7 @@ class Deparser {
|
|
|
2091
1913
|
const elementStrs = elements.map(el => {
|
|
2092
1914
|
return this.deparse(el, context);
|
|
2093
1915
|
});
|
|
2094
|
-
|
|
2095
|
-
const formattedElements = elementStrs.map(el => this.formatter.indent(el)).join(',' + this.formatter.newline());
|
|
2096
|
-
output.push('(' + this.formatter.newline() + formattedElements + this.formatter.newline() + ')');
|
|
2097
|
-
}
|
|
2098
|
-
else {
|
|
2099
|
-
output.push(this.formatter.parens(elementStrs.join(', ')));
|
|
2100
|
-
}
|
|
1916
|
+
output.push(this.formatter.parens(elementStrs.join(', ')));
|
|
2101
1917
|
}
|
|
2102
1918
|
else if (!node.partbound) {
|
|
2103
1919
|
output.push(this.formatter.parens(''));
|
|
@@ -2336,9 +2152,6 @@ class Deparser {
|
|
|
2336
2152
|
break;
|
|
2337
2153
|
case 'CONSTR_UNIQUE':
|
|
2338
2154
|
output.push('UNIQUE');
|
|
2339
|
-
if (node.nulls_not_distinct) {
|
|
2340
|
-
output.push('NULLS NOT DISTINCT');
|
|
2341
|
-
}
|
|
2342
2155
|
if (node.keys && node.keys.length > 0) {
|
|
2343
2156
|
const keyList = list_utils_1.ListUtils.unwrapList(node.keys)
|
|
2344
2157
|
.map(key => this.visit(key, context))
|
|
@@ -2382,52 +2195,38 @@ class Deparser {
|
|
|
2382
2195
|
}
|
|
2383
2196
|
}
|
|
2384
2197
|
if (node.fk_upd_action && node.fk_upd_action !== 'a') {
|
|
2385
|
-
|
|
2198
|
+
output.push('ON UPDATE');
|
|
2386
2199
|
switch (node.fk_upd_action) {
|
|
2387
2200
|
case 'r':
|
|
2388
|
-
|
|
2201
|
+
output.push('RESTRICT');
|
|
2389
2202
|
break;
|
|
2390
2203
|
case 'c':
|
|
2391
|
-
|
|
2204
|
+
output.push('CASCADE');
|
|
2392
2205
|
break;
|
|
2393
2206
|
case 'n':
|
|
2394
|
-
|
|
2207
|
+
output.push('SET NULL');
|
|
2395
2208
|
break;
|
|
2396
2209
|
case 'd':
|
|
2397
|
-
|
|
2210
|
+
output.push('SET DEFAULT');
|
|
2398
2211
|
break;
|
|
2399
2212
|
}
|
|
2400
|
-
if (this.formatter.isPretty()) {
|
|
2401
|
-
output.push('\n' + this.formatter.indent(updateClause));
|
|
2402
|
-
}
|
|
2403
|
-
else {
|
|
2404
|
-
output.push('ON UPDATE');
|
|
2405
|
-
output.push(updateClause.replace('ON UPDATE ', ''));
|
|
2406
|
-
}
|
|
2407
2213
|
}
|
|
2408
2214
|
if (node.fk_del_action && node.fk_del_action !== 'a') {
|
|
2409
|
-
|
|
2215
|
+
output.push('ON DELETE');
|
|
2410
2216
|
switch (node.fk_del_action) {
|
|
2411
2217
|
case 'r':
|
|
2412
|
-
|
|
2218
|
+
output.push('RESTRICT');
|
|
2413
2219
|
break;
|
|
2414
2220
|
case 'c':
|
|
2415
|
-
|
|
2221
|
+
output.push('CASCADE');
|
|
2416
2222
|
break;
|
|
2417
2223
|
case 'n':
|
|
2418
|
-
|
|
2224
|
+
output.push('SET NULL');
|
|
2419
2225
|
break;
|
|
2420
2226
|
case 'd':
|
|
2421
|
-
|
|
2227
|
+
output.push('SET DEFAULT');
|
|
2422
2228
|
break;
|
|
2423
2229
|
}
|
|
2424
|
-
if (this.formatter.isPretty()) {
|
|
2425
|
-
output.push('\n' + this.formatter.indent(deleteClause));
|
|
2426
|
-
}
|
|
2427
|
-
else {
|
|
2428
|
-
output.push('ON DELETE');
|
|
2429
|
-
output.push(deleteClause.replace('ON DELETE ', ''));
|
|
2430
|
-
}
|
|
2431
2230
|
}
|
|
2432
2231
|
// Handle NOT VALID for foreign key constraints - only for table constraints, not domain constraints
|
|
2433
2232
|
if (node.skip_validation && !context.isDomainConstraint) {
|
|
@@ -2485,48 +2284,17 @@ class Deparser {
|
|
|
2485
2284
|
// Handle deferrable constraints for all constraint types that support it
|
|
2486
2285
|
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN') {
|
|
2487
2286
|
if (node.deferrable) {
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
output.push('\n' + this.formatter.indent('INITIALLY DEFERRED'));
|
|
2492
|
-
}
|
|
2493
|
-
else if (node.initdeferred === false) {
|
|
2494
|
-
output.push('\n' + this.formatter.indent('INITIALLY IMMEDIATE'));
|
|
2495
|
-
}
|
|
2287
|
+
output.push('DEFERRABLE');
|
|
2288
|
+
if (node.initdeferred === true) {
|
|
2289
|
+
output.push('INITIALLY DEFERRED');
|
|
2496
2290
|
}
|
|
2497
|
-
else {
|
|
2498
|
-
output.push('
|
|
2499
|
-
if (node.initdeferred === true) {
|
|
2500
|
-
output.push('INITIALLY DEFERRED');
|
|
2501
|
-
}
|
|
2502
|
-
else if (node.initdeferred === false) {
|
|
2503
|
-
output.push('INITIALLY IMMEDIATE');
|
|
2504
|
-
}
|
|
2291
|
+
else if (node.initdeferred === false) {
|
|
2292
|
+
output.push('INITIALLY IMMEDIATE');
|
|
2505
2293
|
}
|
|
2506
2294
|
}
|
|
2507
2295
|
else if (node.deferrable === false) {
|
|
2508
|
-
|
|
2509
|
-
output.push('\n' + this.formatter.indent('NOT DEFERRABLE'));
|
|
2510
|
-
}
|
|
2511
|
-
else {
|
|
2512
|
-
output.push('NOT DEFERRABLE');
|
|
2513
|
-
}
|
|
2514
|
-
}
|
|
2515
|
-
}
|
|
2516
|
-
if (this.formatter.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2517
|
-
let result = '';
|
|
2518
|
-
for (let i = 0; i < output.length; i++) {
|
|
2519
|
-
if (output[i].startsWith('\n')) {
|
|
2520
|
-
result += output[i];
|
|
2521
|
-
}
|
|
2522
|
-
else {
|
|
2523
|
-
if (i > 0 && !output[i - 1].startsWith('\n')) {
|
|
2524
|
-
result += ' ';
|
|
2525
|
-
}
|
|
2526
|
-
result += output[i];
|
|
2527
|
-
}
|
|
2296
|
+
output.push('NOT DEFERRABLE');
|
|
2528
2297
|
}
|
|
2529
|
-
return result;
|
|
2530
2298
|
}
|
|
2531
2299
|
return output.join(' ');
|
|
2532
2300
|
}
|
|
@@ -3250,9 +3018,11 @@ class Deparser {
|
|
|
3250
3018
|
}
|
|
3251
3019
|
switch (node.jointype) {
|
|
3252
3020
|
case 'JOIN_INNER':
|
|
3021
|
+
// Handle NATURAL JOIN first - it has isNatural=true (NATURAL already added above)
|
|
3253
3022
|
if (node.isNatural) {
|
|
3254
3023
|
joinStr += 'JOIN';
|
|
3255
3024
|
}
|
|
3025
|
+
// Handle CROSS JOIN case - when there's no quals, no usingClause, and not natural
|
|
3256
3026
|
else if (!node.quals && (!node.usingClause || node.usingClause.length === 0)) {
|
|
3257
3027
|
joinStr += 'CROSS JOIN';
|
|
3258
3028
|
}
|
|
@@ -3272,63 +3042,26 @@ class Deparser {
|
|
|
3272
3042
|
default:
|
|
3273
3043
|
joinStr += 'JOIN';
|
|
3274
3044
|
}
|
|
3045
|
+
output.push(joinStr);
|
|
3275
3046
|
if (node.rarg) {
|
|
3276
3047
|
let rargStr = this.visit(node.rarg, context);
|
|
3277
3048
|
if (node.rarg && 'JoinExpr' in node.rarg && !node.rarg.JoinExpr.alias) {
|
|
3278
3049
|
rargStr = `(${rargStr})`;
|
|
3279
3050
|
}
|
|
3280
|
-
|
|
3281
|
-
output.push(this.formatter.newline() + joinStr + ' ' + rargStr);
|
|
3282
|
-
}
|
|
3283
|
-
else {
|
|
3284
|
-
output.push(joinStr + ' ' + rargStr);
|
|
3285
|
-
}
|
|
3286
|
-
}
|
|
3287
|
-
else {
|
|
3288
|
-
if (this.formatter.isPretty()) {
|
|
3289
|
-
output.push(this.formatter.newline() + joinStr);
|
|
3290
|
-
}
|
|
3291
|
-
else {
|
|
3292
|
-
output.push(joinStr);
|
|
3293
|
-
}
|
|
3051
|
+
output.push(rargStr);
|
|
3294
3052
|
}
|
|
3295
3053
|
if (node.usingClause && node.usingClause.length > 0) {
|
|
3054
|
+
output.push('USING');
|
|
3296
3055
|
const usingList = list_utils_1.ListUtils.unwrapList(node.usingClause);
|
|
3297
3056
|
const columnNames = usingList.map(col => this.visit(col, context));
|
|
3298
|
-
|
|
3299
|
-
output.push(` USING (${columnNames.join(', ')})`);
|
|
3300
|
-
}
|
|
3301
|
-
else {
|
|
3302
|
-
output.push(`USING (${columnNames.join(', ')})`);
|
|
3303
|
-
}
|
|
3057
|
+
output.push(`(${columnNames.join(', ')})`);
|
|
3304
3058
|
}
|
|
3305
3059
|
else if (node.quals) {
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
// For complex JOIN conditions, format with proper indentation
|
|
3309
|
-
if (qualsStr.includes('AND') || qualsStr.includes('OR') || qualsStr.length > 50) {
|
|
3310
|
-
if (this.containsMultilineStringLiteral(qualsStr)) {
|
|
3311
|
-
output.push(` ON ${qualsStr}`);
|
|
3312
|
-
}
|
|
3313
|
-
else {
|
|
3314
|
-
output.push(` ON${this.formatter.newline()}${this.formatter.indent(qualsStr)}`);
|
|
3315
|
-
}
|
|
3316
|
-
}
|
|
3317
|
-
else {
|
|
3318
|
-
output.push(` ON ${qualsStr}`);
|
|
3319
|
-
}
|
|
3320
|
-
}
|
|
3321
|
-
else {
|
|
3322
|
-
output.push(`ON ${qualsStr}`);
|
|
3323
|
-
}
|
|
3324
|
-
}
|
|
3325
|
-
let result;
|
|
3326
|
-
if (this.formatter.isPretty()) {
|
|
3327
|
-
result = output.join('');
|
|
3328
|
-
}
|
|
3329
|
-
else {
|
|
3330
|
-
result = output.join(' ');
|
|
3060
|
+
output.push('ON');
|
|
3061
|
+
output.push(this.visit(node.quals, context));
|
|
3331
3062
|
}
|
|
3063
|
+
let result = output.join(' ');
|
|
3064
|
+
// Handle join_using_alias first (for USING clause aliases like "AS x")
|
|
3332
3065
|
if (node.join_using_alias && node.join_using_alias.aliasname) {
|
|
3333
3066
|
let aliasStr = node.join_using_alias.aliasname;
|
|
3334
3067
|
if (node.join_using_alias.colnames && node.join_using_alias.colnames.length > 0) {
|
|
@@ -3338,6 +3071,7 @@ class Deparser {
|
|
|
3338
3071
|
}
|
|
3339
3072
|
result += ` AS ${aliasStr}`;
|
|
3340
3073
|
}
|
|
3074
|
+
// Handle regular alias (for outer table aliases like "y")
|
|
3341
3075
|
if (node.alias && node.alias.aliasname) {
|
|
3342
3076
|
let aliasStr = node.alias.aliasname;
|
|
3343
3077
|
if (node.alias.colnames && node.alias.colnames.length > 0) {
|
|
@@ -5320,18 +5054,6 @@ class Deparser {
|
|
|
5320
5054
|
: argValue;
|
|
5321
5055
|
return `${node.defname} = ${quotedValue}`;
|
|
5322
5056
|
}
|
|
5323
|
-
// Handle CopyStmt WITH clause options - uppercase format without quotes
|
|
5324
|
-
if (context.parentNodeTypes.includes('CopyStmt')) {
|
|
5325
|
-
if (node.defname === 'format' && node.arg && this.getNodeType(node.arg) === 'String') {
|
|
5326
|
-
const stringData = this.getNodeData(node.arg);
|
|
5327
|
-
return `FORMAT ${stringData.sval.toUpperCase()}`;
|
|
5328
|
-
}
|
|
5329
|
-
// Handle other COPY options with uppercase defname
|
|
5330
|
-
if (node.arg) {
|
|
5331
|
-
return `${node.defname.toUpperCase()} ${argValue}`;
|
|
5332
|
-
}
|
|
5333
|
-
return node.defname.toUpperCase();
|
|
5334
|
-
}
|
|
5335
5057
|
// Handle CREATE OPERATOR and CREATE TYPE context
|
|
5336
5058
|
if (context.parentNodeTypes.includes('DefineStmt')) {
|
|
5337
5059
|
const preservedName = this.preserveOperatorDefElemCase(node.defname);
|
|
@@ -6022,7 +5744,8 @@ class Deparser {
|
|
|
6022
5744
|
output.push('NULL');
|
|
6023
5745
|
}
|
|
6024
5746
|
else if (node.comment) {
|
|
6025
|
-
|
|
5747
|
+
const escapedComment = node.comment.replace(/'/g, "''");
|
|
5748
|
+
output.push(`'${escapedComment}'`);
|
|
6026
5749
|
}
|
|
6027
5750
|
return output.join(' ');
|
|
6028
5751
|
}
|
|
@@ -6056,82 +5779,38 @@ class Deparser {
|
|
|
6056
5779
|
return output.join(' ');
|
|
6057
5780
|
}
|
|
6058
5781
|
CreatePolicyStmt(node, context) {
|
|
6059
|
-
const output = [];
|
|
6060
|
-
const initialParts = ['CREATE', 'POLICY'];
|
|
5782
|
+
const output = ['CREATE', 'POLICY'];
|
|
6061
5783
|
if (node.policy_name) {
|
|
6062
|
-
|
|
5784
|
+
output.push(`"${node.policy_name}"`);
|
|
6063
5785
|
}
|
|
6064
|
-
output.push(
|
|
6065
|
-
// Add ON clause on new line in pretty mode
|
|
5786
|
+
output.push('ON');
|
|
6066
5787
|
if (node.table) {
|
|
6067
|
-
|
|
6068
|
-
output.push(this.formatter.newline() + this.formatter.indent(`ON ${this.RangeVar(node.table, context)}`));
|
|
6069
|
-
}
|
|
6070
|
-
else {
|
|
6071
|
-
output.push('ON');
|
|
6072
|
-
output.push(this.RangeVar(node.table, context));
|
|
6073
|
-
}
|
|
5788
|
+
output.push(this.RangeVar(node.table, context));
|
|
6074
5789
|
}
|
|
6075
5790
|
// Handle AS RESTRICTIVE/PERMISSIVE clause
|
|
6076
5791
|
if (node.permissive === undefined) {
|
|
6077
|
-
|
|
6078
|
-
output.push(this.formatter.newline() + this.formatter.indent('AS RESTRICTIVE'));
|
|
6079
|
-
}
|
|
6080
|
-
else {
|
|
6081
|
-
output.push('AS', 'RESTRICTIVE');
|
|
6082
|
-
}
|
|
5792
|
+
output.push('AS', 'RESTRICTIVE');
|
|
6083
5793
|
}
|
|
6084
5794
|
else if (node.permissive === true) {
|
|
6085
|
-
|
|
6086
|
-
output.push(this.formatter.newline() + this.formatter.indent('AS PERMISSIVE'));
|
|
6087
|
-
}
|
|
6088
|
-
else {
|
|
6089
|
-
output.push('AS', 'PERMISSIVE');
|
|
6090
|
-
}
|
|
5795
|
+
output.push('AS', 'PERMISSIVE');
|
|
6091
5796
|
}
|
|
6092
5797
|
if (node.cmd_name) {
|
|
6093
|
-
|
|
6094
|
-
output.push(this.formatter.newline() + this.formatter.indent(`FOR ${node.cmd_name.toUpperCase()}`));
|
|
6095
|
-
}
|
|
6096
|
-
else {
|
|
6097
|
-
output.push('FOR', node.cmd_name.toUpperCase());
|
|
6098
|
-
}
|
|
5798
|
+
output.push('FOR', node.cmd_name.toUpperCase());
|
|
6099
5799
|
}
|
|
6100
5800
|
if (node.roles && node.roles.length > 0) {
|
|
5801
|
+
output.push('TO');
|
|
6101
5802
|
const roles = list_utils_1.ListUtils.unwrapList(node.roles).map(role => this.visit(role, context));
|
|
6102
|
-
|
|
6103
|
-
output.push(this.formatter.newline() + this.formatter.indent(`TO ${roles.join(', ')}`));
|
|
6104
|
-
}
|
|
6105
|
-
else {
|
|
6106
|
-
output.push('TO');
|
|
6107
|
-
output.push(roles.join(', '));
|
|
6108
|
-
}
|
|
5803
|
+
output.push(roles.join(', '));
|
|
6109
5804
|
}
|
|
6110
5805
|
if (node.qual) {
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
output.push(this.formatter.newline() + this.formatter.indent('USING ('));
|
|
6114
|
-
output.push(this.formatter.newline() + this.formatter.indent(this.formatter.indent(qualExpr)));
|
|
6115
|
-
output.push(this.formatter.newline() + this.formatter.indent(')'));
|
|
6116
|
-
}
|
|
6117
|
-
else {
|
|
6118
|
-
output.push('USING');
|
|
6119
|
-
output.push(`(${this.visit(node.qual, context)})`);
|
|
6120
|
-
}
|
|
5806
|
+
output.push('USING');
|
|
5807
|
+
output.push(`(${this.visit(node.qual, context)})`);
|
|
6121
5808
|
}
|
|
6122
5809
|
if (node.with_check) {
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
output.push(this.formatter.newline() + this.formatter.indent('WITH CHECK ('));
|
|
6126
|
-
output.push(this.formatter.newline() + this.formatter.indent(this.formatter.indent(checkExpr)));
|
|
6127
|
-
output.push(this.formatter.newline() + this.formatter.indent(')'));
|
|
6128
|
-
}
|
|
6129
|
-
else {
|
|
6130
|
-
output.push('WITH CHECK');
|
|
6131
|
-
output.push(`(${this.visit(node.with_check, context)})`);
|
|
6132
|
-
}
|
|
5810
|
+
output.push('WITH CHECK');
|
|
5811
|
+
output.push(`(${this.visit(node.with_check, context)})`);
|
|
6133
5812
|
}
|
|
6134
|
-
return
|
|
5813
|
+
return output.join(' ');
|
|
6135
5814
|
}
|
|
6136
5815
|
AlterPolicyStmt(node, context) {
|
|
6137
5816
|
const output = ['ALTER', 'POLICY'];
|
|
@@ -9997,9 +9676,5 @@ class Deparser {
|
|
|
9997
9676
|
}
|
|
9998
9677
|
return output.join(' ');
|
|
9999
9678
|
}
|
|
10000
|
-
containsMultilineStringLiteral(content) {
|
|
10001
|
-
const stringLiteralRegex = /'[^']*\n[^']*'/g;
|
|
10002
|
-
return stringLiteralRegex.test(content);
|
|
10003
|
-
}
|
|
10004
9679
|
}
|
|
10005
9680
|
exports.Deparser = Deparser;
|