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.
Files changed (35) hide show
  1. package/README.md +45 -88
  2. package/deparser.d.ts +297 -0
  3. package/{deparser/deparser.js → deparser.js} +110 -435
  4. package/esm/{deparser/deparser.js → deparser.js} +110 -435
  5. package/esm/index.js +3 -15
  6. package/esm/utils/index.js +90 -0
  7. package/esm/{deparser/utils → utils}/list-utils.js +0 -4
  8. package/esm/{deparser/utils → utils}/quote-utils.js +0 -34
  9. package/esm/utils/sql-formatter.js +23 -0
  10. package/esm/{deparser/visitors → visitors}/base.js +0 -4
  11. package/index.d.ts +3 -9
  12. package/index.js +4 -16
  13. package/package.json +27 -14
  14. package/utils/index.d.ts +4 -0
  15. package/utils/index.js +97 -0
  16. package/{deparser/utils → utils}/list-utils.d.ts +0 -4
  17. package/{deparser/utils → utils}/list-utils.js +0 -4
  18. package/utils/quote-utils.d.ts +5 -0
  19. package/{deparser/utils → utils}/quote-utils.js +0 -34
  20. package/{deparser/utils → utils}/sql-formatter.d.ts +1 -7
  21. package/{deparser/utils → utils}/sql-formatter.js +2 -15
  22. package/{deparser/visitors → visitors}/base.d.ts +5 -8
  23. package/{deparser/visitors → visitors}/base.js +0 -4
  24. package/deparser/deparser.d.ts +0 -301
  25. package/deparser/index.d.ts +0 -9
  26. package/deparser/index.js +0 -17
  27. package/deparser/utils/quote-utils.d.ts +0 -24
  28. package/esm/deparser/index.js +0 -13
  29. package/esm/deparser/utils/sql-formatter.js +0 -36
  30. package/esm/v16-to-v17-direct.js +0 -44
  31. package/esm/v16-to-v17.js +0 -1488
  32. package/v16-to-v17-direct.d.ts +0 -21
  33. package/v16-to-v17-direct.js +0 -48
  34. package/v16-to-v17.d.ts +0 -638
  35. 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, opts.pretty);
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
- if (!this.formatter.isPretty() || !node.targetList) {
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 && (((node.larg).op && (node.larg).op !== 'SETOP_NONE') ||
201
- (node.larg).sortClause ||
202
- (node.larg).limitCount ||
203
- (node.larg).limitOffset ||
204
- (node.larg).withClause);
205
- const rightNeedsParens = node.rarg && (((node.rarg).op && (node.rarg).op !== 'SETOP_NONE') ||
206
- (node.rarg).sortClause ||
207
- (node.rarg).limitCount ||
208
- (node.rarg).limitOffset ||
209
- (node.rarg).withClause);
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
- distinctPart = ' DISTINCT ON ' + this.formatter.parens(clause);
240
+ output.push(this.formatter.parens(clause));
248
241
  }
249
242
  else {
250
- distinctPart = ' DISTINCT';
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
- if (this.formatter.isPretty()) {
268
- const targetStrings = targetList
269
- .map(e => {
270
- const targetStr = this.visit(e, { ...context, select: true });
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('FROM ' + fromItems.trim());
263
+ output.push(fromItems);
297
264
  }
298
265
  if (node.whereClause) {
299
- if (this.formatter.isPretty()) {
300
- output.push('WHERE');
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
- if (this.formatter.isPretty()) {
327
- const groupItems = groupList
328
- .map(e => {
329
- const groupStr = this.visit(e, { ...context, group: true });
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
- if (this.formatter.isPretty()) {
349
- output.push('HAVING');
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
- if (this.formatter.isPretty()) {
374
- const sortItems = sortList
375
- .map(e => {
376
- const sortStr = this.visit(e, { ...context, sort: true });
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 ' + this.visit(node.limitCount, context));
306
+ output.push('LIMIT');
307
+ output.push(this.visit(node.limitCount, context));
396
308
  }
397
309
  if (node.limitOffset) {
398
- output.push('OFFSET ' + this.visit(node.limitOffset, context));
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
- leftExpr,
386
+ this.visit(lexpr, context),
487
387
  'IS DISTINCT FROM',
488
- rightExpr
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
- leftExpr,
392
+ this.visit(lexpr, context),
503
393
  'IS NOT DISTINCT FROM',
504
- rightExpr
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
- if (node.ctes && node.ctes.length > 0) {
901
- const ctes = list_utils_1.ListUtils.unwrapList(node.ctes);
902
- if (this.formatter.isPretty()) {
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
- if (this.formatter.isPretty() && args.length > 1) {
1002
- const andArgs = args.map(arg => this.visit(arg, boolContext)).join(this.formatter.newline() + ' AND ');
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
- if (this.formatter.isPretty() && args.length > 1) {
1011
- const orArgs = args.map(arg => this.visit(arg, boolContext)).join(this.formatter.newline() + ' OR ');
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
- if (this.formatter.isPretty() && windowParts.length > 1) {
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.formatEString(nodeAny.sval.sval);
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.formatEString(nodeAny.sval.String.sval);
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.formatEString(nodeAny.sval.toString());
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.formatEString(nodeAny.sval);
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.catalogname) {
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
- if (this.formatter.isPretty() && args.length > 0) {
1850
- for (const arg of args) {
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
- else {
1872
- for (const arg of args) {
1873
- output.push(this.visit(arg, context));
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 quote_utils_1.QuoteUtils.formatEString(node.sval || '');
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
- if (this.formatter.isPretty()) {
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
- let updateClause = 'ON UPDATE ';
2198
+ output.push('ON UPDATE');
2386
2199
  switch (node.fk_upd_action) {
2387
2200
  case 'r':
2388
- updateClause += 'RESTRICT';
2201
+ output.push('RESTRICT');
2389
2202
  break;
2390
2203
  case 'c':
2391
- updateClause += 'CASCADE';
2204
+ output.push('CASCADE');
2392
2205
  break;
2393
2206
  case 'n':
2394
- updateClause += 'SET NULL';
2207
+ output.push('SET NULL');
2395
2208
  break;
2396
2209
  case 'd':
2397
- updateClause += 'SET DEFAULT';
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
- let deleteClause = 'ON DELETE ';
2215
+ output.push('ON DELETE');
2410
2216
  switch (node.fk_del_action) {
2411
2217
  case 'r':
2412
- deleteClause += 'RESTRICT';
2218
+ output.push('RESTRICT');
2413
2219
  break;
2414
2220
  case 'c':
2415
- deleteClause += 'CASCADE';
2221
+ output.push('CASCADE');
2416
2222
  break;
2417
2223
  case 'n':
2418
- deleteClause += 'SET NULL';
2224
+ output.push('SET NULL');
2419
2225
  break;
2420
2226
  case 'd':
2421
- deleteClause += 'SET DEFAULT';
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
- if (this.formatter.isPretty() && node.contype === 'CONSTR_FOREIGN') {
2489
- output.push('\n' + this.formatter.indent('DEFERRABLE'));
2490
- if (node.initdeferred === true) {
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('DEFERRABLE');
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
- if (this.formatter.isPretty() && node.contype === 'CONSTR_FOREIGN') {
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
- if (this.formatter.isPretty()) {
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
- if (this.formatter.isPretty()) {
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
- const qualsStr = this.visit(node.quals, context);
3307
- if (this.formatter.isPretty()) {
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
- output.push(quote_utils_1.QuoteUtils.formatEString(node.comment));
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
- initialParts.push(`"${node.policy_name}"`);
5784
+ output.push(`"${node.policy_name}"`);
6063
5785
  }
6064
- output.push(initialParts.join(' '));
6065
- // Add ON clause on new line in pretty mode
5786
+ output.push('ON');
6066
5787
  if (node.table) {
6067
- if (this.formatter.isPretty()) {
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
- if (this.formatter.isPretty()) {
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
- if (this.formatter.isPretty()) {
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
- if (this.formatter.isPretty()) {
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
- if (this.formatter.isPretty()) {
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
- if (this.formatter.isPretty()) {
6112
- const qualExpr = this.visit(node.qual, context);
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
- if (this.formatter.isPretty()) {
6124
- const checkExpr = this.visit(node.with_check, context);
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 this.formatter.isPretty() ? output.join('') : output.join(' ');
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;