pgsql-deparser 13.16.0 → 14.0.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 (62) hide show
  1. package/README.md +88 -45
  2. package/dist/README.md +160 -0
  3. package/dist/deparser/deparser.d.ts +301 -0
  4. package/dist/deparser/deparser.js +10005 -0
  5. package/dist/deparser/index.d.ts +9 -0
  6. package/dist/deparser/index.js +17 -0
  7. package/dist/deparser/utils/list-utils.d.ts +8 -0
  8. package/dist/deparser/utils/list-utils.js +30 -0
  9. package/dist/deparser/utils/quote-utils.d.ts +24 -0
  10. package/dist/deparser/utils/quote-utils.js +89 -0
  11. package/dist/deparser/utils/sql-formatter.d.ts +16 -0
  12. package/dist/deparser/utils/sql-formatter.js +40 -0
  13. package/dist/deparser/visitors/base.d.ts +21 -0
  14. package/dist/deparser/visitors/base.js +34 -0
  15. package/dist/esm/deparser/deparser.js +10001 -0
  16. package/dist/esm/deparser/index.js +13 -0
  17. package/dist/esm/deparser/utils/list-utils.js +26 -0
  18. package/dist/esm/deparser/utils/quote-utils.js +85 -0
  19. package/dist/esm/deparser/utils/sql-formatter.js +36 -0
  20. package/dist/esm/deparser/visitors/base.js +30 -0
  21. package/dist/esm/index.js +15 -0
  22. package/dist/esm/v14-to-v15.js +1220 -0
  23. package/dist/esm/v14-to-v17-direct.js +67 -0
  24. package/dist/esm/v15-to-v16.js +2881 -0
  25. package/dist/esm/v16-to-v17.js +1488 -0
  26. package/dist/index.d.ts +9 -0
  27. package/dist/index.js +19 -0
  28. package/dist/package.json +42 -0
  29. package/dist/v14-to-v15.d.ts +616 -0
  30. package/dist/v14-to-v15.js +1224 -0
  31. package/dist/v14-to-v17-direct.d.ts +23 -0
  32. package/dist/v14-to-v17-direct.js +71 -0
  33. package/dist/v15-to-v16.d.ts +627 -0
  34. package/dist/v15-to-v16.js +2885 -0
  35. package/dist/v16-to-v17.d.ts +638 -0
  36. package/dist/v16-to-v17.js +1492 -0
  37. package/package.json +27 -75
  38. package/src/deparser/deparser.ts +10026 -0
  39. package/src/deparser/index.ts +14 -0
  40. package/src/deparser/utils/list-utils.ts +27 -0
  41. package/src/deparser/utils/quote-utils.ts +86 -0
  42. package/src/deparser/utils/sql-formatter.ts +37 -0
  43. package/src/deparser/visitors/base.ts +40 -0
  44. package/src/index.ts +27 -3
  45. package/src/v14-to-v15.ts +1621 -0
  46. package/src/v14-to-v17-direct.ts +68 -0
  47. package/src/v15-to-v16.ts +3290 -0
  48. package/src/v16-to-v17.ts +1897 -0
  49. package/tsconfig.esm.json +8 -0
  50. package/tsconfig.json +26 -0
  51. package/main/deparser.js +0 -3495
  52. package/main/index.js +0 -10
  53. package/main/utils/index.js +0 -97
  54. package/module/deparser.js +0 -3492
  55. package/module/index.js +0 -3
  56. package/module/utils/index.js +0 -90
  57. package/src/deparser.ts +0 -4234
  58. package/src/utils/index.ts +0 -92
  59. package/types/deparser.d.ts +0 -119
  60. package/types/index.d.ts +0 -3
  61. package/types/utils/index.d.ts +0 -4
  62. /package/{LICENSE → dist/LICENSE} +0 -0
package/main/deparser.js DELETED
@@ -1,3495 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- // @ts-nocheck
4
- const util_1 = require("util");
5
- const pgsql_enums_1 = require("pgsql-enums");
6
- let TAB_CHAR = '\t';
7
- let NEWLINE_CHAR = '\n';
8
- const isEmptyObject = (obj) => {
9
- return !obj || (typeof obj === 'object' && !Object.keys(obj).length);
10
- };
11
- const dotty = require('dotty');
12
- const fail = (type, node) => {
13
- throw new Error((0, util_1.format)('Unhandled %s node: %s', type, JSON.stringify(node)));
14
- };
15
- // select word from pg_get_keywords() where catcode = 'R';
16
- const RESERVED_WORDS = new Set([
17
- 'all',
18
- 'analyse',
19
- 'analyze',
20
- 'and',
21
- 'any',
22
- 'array',
23
- 'as',
24
- 'asc',
25
- 'asymmetric',
26
- 'both',
27
- 'case',
28
- 'cast',
29
- 'check',
30
- 'collate',
31
- 'column',
32
- 'constraint',
33
- 'create',
34
- 'current_catalog',
35
- 'current_date',
36
- 'current_role',
37
- 'current_time',
38
- 'current_timestamp',
39
- 'current_user',
40
- 'default',
41
- 'deferrable',
42
- 'desc',
43
- 'distinct',
44
- 'do',
45
- 'else',
46
- 'end',
47
- 'except',
48
- 'false',
49
- 'fetch',
50
- 'for',
51
- 'foreign',
52
- 'from',
53
- 'grant',
54
- 'group',
55
- 'having',
56
- 'in',
57
- 'initially',
58
- 'intersect',
59
- 'into',
60
- 'lateral',
61
- 'leading',
62
- 'limit',
63
- 'localtime',
64
- 'localtimestamp',
65
- 'not',
66
- 'null',
67
- 'offset',
68
- 'on',
69
- 'only',
70
- 'or',
71
- 'order',
72
- 'placing',
73
- 'primary',
74
- 'references',
75
- 'returning',
76
- 'select',
77
- 'session_user',
78
- 'some',
79
- 'symmetric',
80
- 'table',
81
- 'then',
82
- 'to',
83
- 'trailing',
84
- 'true',
85
- 'union',
86
- 'unique',
87
- 'user',
88
- 'using',
89
- 'variadic',
90
- 'when',
91
- 'where',
92
- 'window',
93
- 'with'
94
- ]);
95
- // https://github.com/pganalyze/libpg_query/blob/b2790f8140721ff7f047167ecd7d44267b0a3880/src/postgres/include/storage/lockdefs.h
96
- const LOCK_MODES = {
97
- 1: 'ACCESS SHARE',
98
- 2: 'ROW SHARE',
99
- 3: 'ROW EXCLUSIVE',
100
- 4: 'SHARE UPDATE EXCLUSIVE',
101
- 5: 'SHARE',
102
- 6: 'SHARE ROW',
103
- 7: 'EXCLUSIVE',
104
- 8: 'ACCESS EXCLUSIVE'
105
- };
106
- const isReserved = (value) => RESERVED_WORDS.has(value.toLowerCase());
107
- // has uppercase and lowercase, or non word characters
108
- const needsQuotesRegex = /[a-z]+[\W\w]*[A-Z]+|[A-Z]+[\W\w]*[a-z]+|\W/;
109
- // usually the AST lowercases all the things, so if we
110
- // have both, the author most likely used double quotes
111
- const needsQuotes = (value) => needsQuotesRegex.test(value) || isReserved(value);
112
- const compact = (o) => o.filter((e) => {
113
- const isFalsy = !e;
114
- return !isFalsy && e.toString().length;
115
- });
116
- const flatten = (o) => {
117
- const flattened = [];
118
- for (let i = 0; i < o.length; i++) {
119
- if (Array.isArray(o[i])) {
120
- for (let j = 0; j < o[i].length; j++) {
121
- flattened.push(o[i][j]);
122
- }
123
- }
124
- else {
125
- flattened.push(o[i]);
126
- }
127
- }
128
- return flattened;
129
- };
130
- const inverted = (o) => {
131
- const objInverted = {};
132
- const keys = Object.keys(o);
133
- for (let i = 0; i < keys.length; i++) {
134
- const key = keys[i];
135
- objInverted[o[key]] = key;
136
- }
137
- return objInverted;
138
- };
139
- const parens = (string) => {
140
- return '(' + string + ')';
141
- };
142
- const indent = (text, count = 1) => text;
143
- const unwrapList = (obj) => obj !== undefined && obj.List !== undefined ? obj.List.items : obj;
144
- class Deparser {
145
- static deparse(query, opts) {
146
- return new Deparser(query, opts).deparseQuery();
147
- }
148
- constructor(tree, opts = {}) {
149
- this.tree = tree;
150
- if (opts.hasOwnProperty('newline')) {
151
- NEWLINE_CHAR = opts.newline;
152
- }
153
- if (opts.hasOwnProperty('tab')) {
154
- TAB_CHAR = opts.tab;
155
- }
156
- if (!Array.isArray(this.tree))
157
- this.tree = [this.tree];
158
- }
159
- deparseQuery() {
160
- return this.tree
161
- .map((node) => this.deparse(node))
162
- .join(NEWLINE_CHAR + NEWLINE_CHAR);
163
- }
164
- deparseNodes(nodes, context) {
165
- return unwrapList(nodes).map((node) => {
166
- const unwrapped = unwrapList(node);
167
- return Array.isArray(unwrapped)
168
- ? this.list(unwrapped, ', ', '', context)
169
- : this.deparse(node, context);
170
- });
171
- }
172
- deparseReturningList(list, context) {
173
- return unwrapList(list)
174
- .map((returning) => this.deparse(returning.ResTarget.val, context) +
175
- (returning.ResTarget.name
176
- ? ' AS ' + this.quote(returning.ResTarget.name)
177
- : ''))
178
- .join(',');
179
- }
180
- list(nodes, separator = ', ', prefix = '', context) {
181
- if (!nodes) {
182
- return '';
183
- }
184
- return this.deparseNodes(nodes, context)
185
- .map((l) => `${prefix}${l}`)
186
- .join(separator);
187
- }
188
- listQuotes(nodes, separator = ', ') {
189
- return this.list(unwrapList(nodes), separator)
190
- .split(separator)
191
- .map((a) => this.quote(a.trim()))
192
- .join(separator);
193
- }
194
- quote(value) {
195
- if (value == null) {
196
- return null;
197
- }
198
- const unwrapped = unwrapList(value);
199
- if (Array.isArray(unwrapped)) {
200
- return unwrapped.map((o) => this.quote(o));
201
- }
202
- if (needsQuotes(value)) {
203
- return '"' + value + '"';
204
- }
205
- return value;
206
- }
207
- // SELECT encode(E'''123\\000\\001', 'base64')
208
- escape(literal) {
209
- return "'" + literal.replace(/'/g, "''") + "'";
210
- }
211
- getPgCatalogTypeName(typeName, size) {
212
- switch (typeName) {
213
- case 'bpchar':
214
- if (size != null) {
215
- return 'char';
216
- }
217
- // return `pg_catalog.bpchar` below so that the following is symmetric
218
- // SELECT char 'c' = char 'c' AS true
219
- return 'pg_catalog.bpchar';
220
- case 'varchar':
221
- return 'varchar';
222
- case 'numeric':
223
- return 'numeric';
224
- case 'bool':
225
- return 'boolean';
226
- case 'int2':
227
- return 'smallint';
228
- case 'int4':
229
- return 'int';
230
- case 'int8':
231
- return 'bigint';
232
- case 'real':
233
- return 'pg_catalog.float4';
234
- case 'time':
235
- return 'time';
236
- case 'timestamp':
237
- return 'timestamp';
238
- case 'interval':
239
- return 'interval';
240
- case 'bit':
241
- return 'bit';
242
- default:
243
- return 'pg_catalog.' + typeName;
244
- }
245
- }
246
- type(names, args) {
247
- const catalogAndType = unwrapList(names).map((name) => this.deparse(name));
248
- const catalog = catalogAndType[0];
249
- const type = catalogAndType[1];
250
- const mods = (name, size) => {
251
- if (size != null) {
252
- return name + '(' + size + ')';
253
- }
254
- return name;
255
- };
256
- // handle the special "char" (in quotes) type
257
- if (catalog === 'char' && !type) {
258
- return mods('"char"', args);
259
- }
260
- if (catalog === 'pg_catalog' && type === 'char') {
261
- return mods('pg_catalog."char"', args);
262
- }
263
- if (catalog !== 'pg_catalog') {
264
- return mods(this.listQuotes(names, '.'), args);
265
- }
266
- const res = this.getPgCatalogTypeName(type, args);
267
- return mods(res, args);
268
- }
269
- deparse(item, context) {
270
- if (item == null) {
271
- return null;
272
- }
273
- if (typeof item === 'number' || item instanceof Number) {
274
- return item;
275
- }
276
- const type = Object.keys(item)[0];
277
- const node = item[type];
278
- if (this[type] == null) {
279
- throw new Error(type + ' is not implemented: ' + JSON.stringify(node));
280
- }
281
- return this[type](node, context);
282
- }
283
- RawStmt(node, context = {}) {
284
- if (node.stmt_len) {
285
- return this.deparse(node.stmt, context) + ';';
286
- }
287
- return this.deparse(node.stmt, context);
288
- }
289
- RuleStmt(node, context = {}) {
290
- const output = [];
291
- output.push('CREATE');
292
- output.push('RULE');
293
- if (node.rulename === '_RETURN') {
294
- // special rules
295
- output.push('"_RETURN"');
296
- }
297
- else {
298
- output.push(node.rulename);
299
- }
300
- output.push('AS');
301
- output.push('ON');
302
- switch (node.event) {
303
- case 'CMD_SELECT':
304
- output.push('SELECT');
305
- break;
306
- case 'CMD_UPDATE':
307
- output.push('UPDATE');
308
- break;
309
- case 'CMD_INSERT':
310
- output.push('INSERT');
311
- break;
312
- case 'CMD_DELETE':
313
- output.push('DELETE');
314
- break;
315
- default:
316
- throw new Error('event type not yet implemented for RuleStmt');
317
- }
318
- output.push('TO');
319
- output.push(this.RangeVar(node.relation, context));
320
- if (node.whereClause) {
321
- output.push('WHERE');
322
- output.push(this.deparse(node.whereClause, context));
323
- }
324
- output.push('DO');
325
- if (node.instead) {
326
- output.push('INSTEAD');
327
- }
328
- const actions = unwrapList(node.actions);
329
- if (!actions || !actions.length) {
330
- output.push('NOTHING');
331
- }
332
- else {
333
- // TODO how do multiple actions happen?
334
- output.push(this.deparse(actions[0], context));
335
- }
336
- return output.join(' ');
337
- }
338
- A_Expr(node, context = {}) {
339
- const output = [];
340
- const nodeName = unwrapList(node.name);
341
- switch (node.kind) {
342
- case 'AEXPR_OP': {
343
- let operator;
344
- if (node.lexpr) {
345
- // PARENS
346
- if (node.lexpr !== undefined && node.lexpr.A_Expr !== undefined) {
347
- output.push(parens(this.deparse(node.lexpr, context)));
348
- }
349
- else {
350
- output.push(this.deparse(node.lexpr, context));
351
- }
352
- }
353
- if (nodeName.length > 1) {
354
- const schema = this.deparse(nodeName[0], context);
355
- operator = this.deparse(nodeName[1], context);
356
- output.push(`OPERATOR(${schema}.${operator})`);
357
- }
358
- else {
359
- operator = this.deparse(nodeName[0], context);
360
- output.push(operator);
361
- }
362
- if (node.rexpr) {
363
- // PARENS
364
- if (node.rexpr !== undefined && node.rexpr.A_Expr !== undefined) {
365
- output.push(parens(this.deparse(node.rexpr, context)));
366
- }
367
- else {
368
- output.push(this.deparse(node.rexpr, context));
369
- }
370
- }
371
- if (output.length === 2) {
372
- return output.join('');
373
- }
374
- if (['->', '->>'].includes(operator)) {
375
- return output.join('');
376
- }
377
- return output.join(' ');
378
- }
379
- case 'AEXPR_OP_ANY':
380
- /* scalar op ANY (array) */
381
- output.push(this.deparse(node.lexpr, context));
382
- output.push((0, util_1.format)('ANY (%s)', this.deparse(node.rexpr, context)));
383
- return output.join(` ${this.deparse(nodeName[0], context)} `);
384
- case 'AEXPR_OP_ALL':
385
- /* scalar op ALL (array) */
386
- output.push(this.deparse(node.lexpr, context));
387
- output.push((0, util_1.format)('ALL (%s)', this.deparse(node.rexpr, context)));
388
- return output.join(` ${this.deparse(nodeName[0], context)} `);
389
- case 'AEXPR_DISTINCT':
390
- /* IS DISTINCT FROM - name must be "=" */
391
- return (0, util_1.format)('%s IS DISTINCT FROM %s', this.deparse(node.lexpr, context), this.deparse(node.rexpr, context));
392
- case 'AEXPR_NOT_DISTINCT':
393
- /* IS NOT DISTINCT FROM - name must be "=" */
394
- return (0, util_1.format)('%s IS NOT DISTINCT FROM %s', this.deparse(node.lexpr, context), this.deparse(node.rexpr, context));
395
- case 'AEXPR_NULLIF':
396
- /* NULLIF - name must be "=" */
397
- return (0, util_1.format)('NULLIF(%s, %s)', this.deparse(node.lexpr, context), this.deparse(node.rexpr, context));
398
- case 'AEXPR_OF': {
399
- /* IS [NOT] OF - name must be "=" or "<>" */
400
- const op = nodeName[0].String.str === '=' ? 'IS OF' : 'IS NOT OF';
401
- return (0, util_1.format)('%s %s (%s)', this.deparse(node.lexpr, context), op, this.list(node.rexpr, ', ', '', context));
402
- }
403
- case 'AEXPR_IN': {
404
- /* [NOT] IN - name must be "=" or "<>" */
405
- const operator = nodeName[0].String.str === '=' ? 'IN' : 'NOT IN';
406
- return (0, util_1.format)('%s %s (%s)', this.deparse(node.lexpr, context), operator, this.list(node.rexpr, ', ', '', context));
407
- }
408
- case 'AEXPR_LIKE':
409
- /* [NOT] LIKE - name must be "~~" or "!~~" */
410
- output.push(this.deparse(node.lexpr, context));
411
- if (nodeName[0].String.str === '!~~') {
412
- output.push((0, util_1.format)('NOT LIKE (%s)', this.deparse(node.rexpr, context)));
413
- }
414
- else {
415
- output.push((0, util_1.format)('LIKE (%s)', this.deparse(node.rexpr, context)));
416
- }
417
- return output.join(' ');
418
- case 'AEXPR_ILIKE':
419
- /* [NOT] ILIKE - name must be "~~*" or "!~~*" */
420
- output.push(this.deparse(node.lexpr, context));
421
- if (nodeName[0].String.str === '!~~*') {
422
- output.push((0, util_1.format)('NOT ILIKE (%s)', this.deparse(node.rexpr, context)));
423
- }
424
- else {
425
- output.push((0, util_1.format)('ILIKE (%s)', this.deparse(node.rexpr, context)));
426
- }
427
- return output.join(' ');
428
- case 'AEXPR_SIMILAR':
429
- // SIMILAR TO emits a similar_escape FuncCall node with the first argument
430
- output.push(this.deparse(node.lexpr, context));
431
- if (nodeName[0].String.str === '~') {
432
- if (unwrapList(node.rexpr.FuncCall.args).length > 1) {
433
- output.push((0, util_1.format)('SIMILAR TO %s ESCAPE %s', this.deparse(unwrapList(node.rexpr.FuncCall.args)[0], context), this.deparse(unwrapList(node.rexpr.FuncCall.args)[1], context)));
434
- }
435
- else {
436
- output.push((0, util_1.format)('SIMILAR TO %s', this.deparse(unwrapList(node.rexpr.FuncCall.args)[0], context)));
437
- }
438
- }
439
- else {
440
- if (unwrapList(node.rexpr.FuncCall.args).length > 1) {
441
- output.push((0, util_1.format)('NOT SIMILAR TO %s ESCAPE %s', this.deparse(unwrapList(node.rexpr.FuncCall.args)[0], context), this.deparse(unwrapList(node.rexpr.FuncCall.args)[1], context)));
442
- }
443
- else {
444
- output.push((0, util_1.format)('NOT SIMILAR TO %s', this.deparse(unwrapList(node.rexpr.FuncCall.args)[0], context)));
445
- }
446
- }
447
- return output.join(' ');
448
- case 'AEXPR_BETWEEN':
449
- output.push(this.deparse(node.lexpr, context));
450
- output.push((0, util_1.format)('BETWEEN %s AND %s', this.deparse(unwrapList(node.rexpr)[0], context), this.deparse(unwrapList(node.rexpr)[1], context)));
451
- return output.join(' ');
452
- case 'AEXPR_NOT_BETWEEN':
453
- output.push(this.deparse(node.lexpr, context));
454
- output.push((0, util_1.format)('NOT BETWEEN %s AND %s', this.deparse(unwrapList(node.rexpr)[0], context), this.deparse(unwrapList(node.rexpr)[1], context)));
455
- return output.join(' ');
456
- case 'AEXPR_BETWEEN_SYM':
457
- output.push(this.deparse(node.lexpr, context));
458
- output.push((0, util_1.format)('BETWEEN SYMMETRIC %s AND %s', this.deparse(unwrapList(node.rexpr)[0], context), this.deparse(unwrapList(node.rexpr)[1], context)));
459
- return output.join(' ');
460
- case 'AEXPR_NOT_BETWEEN_SYM':
461
- output.push(this.deparse(node.lexpr, context));
462
- output.push((0, util_1.format)('NOT BETWEEN SYMMETRIC %s AND %s', this.deparse(unwrapList(node.rexpr)[0], context), this.deparse(unwrapList(node.rexpr)[1], context)));
463
- return output.join(' ');
464
- // case 15:
465
- // AEXPR_PAREN
466
- default:
467
- return fail('A_Expr', node);
468
- }
469
- }
470
- Alias(node, context = {}) {
471
- const name = node.aliasname;
472
- const output = ['AS'];
473
- if (node.colnames) {
474
- output.push(this.quote(name) + parens(this.listQuotes(node.colnames)));
475
- }
476
- else {
477
- output.push(this.quote(name));
478
- }
479
- return output.join(' ');
480
- }
481
- A_ArrayExpr(node) {
482
- return (0, util_1.format)('ARRAY[%s]', this.list(node.elements));
483
- }
484
- A_Const(node, context = {}) {
485
- if (node.val.String) {
486
- return this.escape(this.deparse(node.val, context));
487
- }
488
- return this.deparse(node.val, context);
489
- }
490
- A_Indices(node, context = {}) {
491
- if (node.lidx) {
492
- return (0, util_1.format)('[%s:%s]', this.deparse(node.lidx, context), this.deparse(node.uidx, context));
493
- }
494
- return (0, util_1.format)('[%s]', this.deparse(node.uidx, context));
495
- }
496
- A_Indirection(node, context = {}) {
497
- const output = [`(${this.deparse(node.arg, context)})`];
498
- // TODO(zhm) figure out the actual rules for when a '.' is needed
499
- //
500
- // select a.b[0] from a;
501
- // select (select row(1)).*
502
- // select c2[2].f2 from comptable
503
- // select c2.a[2].f2[1].f3[0].a1 from comptable
504
- const indirection = unwrapList(node.indirection);
505
- for (let i = 0; i < indirection.length; i++) {
506
- const subnode = indirection[i];
507
- if (subnode.String || subnode.A_Star) {
508
- const value = subnode.A_Star ? '*' : this.quote(subnode.String.str);
509
- output.push(`.${value}`);
510
- }
511
- else {
512
- output.push(this.deparse(subnode, context));
513
- }
514
- }
515
- return output.join('');
516
- }
517
- A_Star(node) {
518
- return '*';
519
- }
520
- BitString(node) {
521
- const prefix = node.str[0];
522
- return `${prefix}'${node.str.substring(1)}'`;
523
- }
524
- BoolExpr(node, context = {}) {
525
- let fmt_str = '%s';
526
- if (context.bool) {
527
- fmt_str = '(%s)';
528
- }
529
- const ctx = Object.assign({}, context);
530
- ctx.bool = true;
531
- switch (node.boolop) {
532
- case 'AND_EXPR':
533
- return (0, util_1.format)(fmt_str, this.list(node.args, ' AND ', '', ctx));
534
- case 'OR_EXPR':
535
- return (0, util_1.format)(fmt_str, this.list(node.args, ' OR ', '', ctx));
536
- case 'NOT_EXPR':
537
- return (0, util_1.format)('NOT (%s)', this.deparse(unwrapList(node.args)[0], context));
538
- default:
539
- return fail('BoolExpr', node);
540
- }
541
- }
542
- BooleanTest(node, context = {}) {
543
- const output = [];
544
- const ctx = Object.assign({}, context);
545
- ctx.bool = true;
546
- output.push(this.deparse(node.arg, ctx));
547
- switch (node.booltesttype) {
548
- case 'IS_TRUE':
549
- output.push('IS TRUE');
550
- break;
551
- case 'IS_NOT_TRUE':
552
- output.push('IS NOT TRUE');
553
- break;
554
- case 'IS_FALSE':
555
- output.push('IS FALSE');
556
- break;
557
- case 'IS_NOT_FALSE':
558
- output.push('IS NOT FALSE');
559
- break;
560
- case 'IS_UNKNOWN':
561
- output.push('IS UNKNOWN');
562
- break;
563
- case 'IS_NOT_UNKNOWN':
564
- output.push('IS NOT UNKNOWN');
565
- break;
566
- }
567
- return output.join(' ');
568
- }
569
- CaseExpr(node, context = {}) {
570
- const output = ['CASE'];
571
- if (node.arg) {
572
- output.push(this.deparse(node.arg, context));
573
- }
574
- const args = unwrapList(node.args);
575
- for (let i = 0; i < args.length; i++) {
576
- output.push(this.deparse(args[i], context));
577
- }
578
- if (node.defresult) {
579
- output.push('ELSE');
580
- output.push(this.deparse(node.defresult, context));
581
- }
582
- output.push('END');
583
- return output.join(' ');
584
- }
585
- CoalesceExpr(node, context = {}) {
586
- return (0, util_1.format)('COALESCE(%s)', this.list(node.args, ', ', '', context));
587
- }
588
- CollateClause(node, context = {}) {
589
- const output = [];
590
- if (node.arg) {
591
- output.push(this.deparse(node.arg, context));
592
- }
593
- output.push('COLLATE');
594
- if (node.collname) {
595
- output.push(this.quote(this.deparseNodes(node.collname, context)));
596
- }
597
- return output.join(' ');
598
- }
599
- CompositeTypeStmt(node, context = {}) {
600
- const output = [];
601
- output.push('CREATE TYPE');
602
- output.push(this.RangeVar(node.typevar, context));
603
- output.push('AS');
604
- output.push('(');
605
- output.push(this.list(node.coldeflist, `,${NEWLINE_CHAR}`, TAB_CHAR, context));
606
- output.push(')');
607
- return output.join(' ');
608
- }
609
- RenameStmt(node, context = {}) {
610
- const output = [];
611
- if (node.renameType === 'OBJECT_FUNCTION' ||
612
- node.renameType === 'OBJECT_FOREIGN_TABLE' ||
613
- node.renameType === 'OBJECT_FDW' ||
614
- node.renameType === 'OBJECT_FOREIGN_SERVER') {
615
- output.push('ALTER');
616
- output.push((0, pgsql_enums_1.objtypeName)(node.renameType));
617
- if (node.missing_ok) {
618
- output.push('IF EXISTS');
619
- }
620
- output.push(this.deparse(node.object, context));
621
- output.push('RENAME');
622
- output.push('TO');
623
- output.push(this.quote(node.newname));
624
- }
625
- else if (node.renameType === 'OBJECT_ATTRIBUTE') {
626
- output.push('ALTER');
627
- output.push((0, pgsql_enums_1.objtypeName)(node.relationType));
628
- if (node.missing_ok) {
629
- output.push('IF EXISTS');
630
- }
631
- output.push(this.RangeVar(node.relation, context));
632
- output.push('RENAME');
633
- output.push((0, pgsql_enums_1.objtypeName)(node.renameType));
634
- output.push(this.quote(node.subname));
635
- output.push('TO');
636
- output.push(this.quote(node.newname));
637
- }
638
- else if (node.renameType === 'OBJECT_DOMAIN' ||
639
- node.renameType === 'OBJECT_TYPE') {
640
- output.push('ALTER');
641
- output.push((0, pgsql_enums_1.objtypeName)(node.renameType));
642
- if (node.missing_ok) {
643
- output.push('IF EXISTS');
644
- }
645
- const typObj = {
646
- TypeName: {
647
- names: node.object
648
- }
649
- };
650
- output.push(this.deparse(typObj, context));
651
- output.push('RENAME');
652
- output.push('TO');
653
- output.push(this.quote(node.newname));
654
- }
655
- else if (node.renameType === 'OBJECT_SCHEMA') {
656
- output.push('ALTER');
657
- output.push((0, pgsql_enums_1.objtypeName)(node.renameType));
658
- if (node.missing_ok) {
659
- output.push('IF EXISTS');
660
- }
661
- output.push(this.quote(node.subname));
662
- output.push('RENAME');
663
- output.push('TO');
664
- output.push(this.quote(node.newname));
665
- }
666
- else if (node.renameType === 'OBJECT_DOMCONSTRAINT') {
667
- output.push('ALTER');
668
- output.push('DOMAIN');
669
- if (node.missing_ok) {
670
- output.push('IF EXISTS');
671
- }
672
- const typObj = {
673
- TypeName: {
674
- names: node.object
675
- }
676
- };
677
- output.push(this.deparse(typObj, context));
678
- output.push('RENAME CONSTRAINT');
679
- output.push(this.quote(node.subname));
680
- output.push('TO');
681
- output.push(this.quote(node.newname));
682
- }
683
- else {
684
- output.push('ALTER');
685
- output.push('TABLE');
686
- if (node.missing_ok) {
687
- output.push('IF EXISTS');
688
- }
689
- output.push(this.RangeVar(node.relation, context));
690
- output.push('RENAME');
691
- output.push(this.quote(node.subname));
692
- output.push('TO');
693
- output.push(this.quote(node.newname));
694
- }
695
- if (node.behavior === 'DROP_CASCADE') {
696
- output.push('CASCADE');
697
- }
698
- return output.join(' ');
699
- }
700
- AlterOwnerStmt(node, context = {}) {
701
- const output = [];
702
- output.push('ALTER');
703
- output.push((0, pgsql_enums_1.objtypeName)(node.objectType));
704
- const unwrapped = unwrapList(node.object);
705
- if (Array.isArray(unwrapped)) {
706
- output.push(this.listQuotes(unwrapped, '.'));
707
- }
708
- else {
709
- output.push(this.deparse(node.object, context));
710
- }
711
- output.push('OWNER TO');
712
- output.push(this.RoleSpec(node.newowner, context));
713
- return output.join(' ');
714
- }
715
- AlterObjectSchemaStmt(node, context = {}) {
716
- const output = [];
717
- if (node.objectType === 'OBJECT_TABLE') {
718
- output.push('ALTER');
719
- output.push((0, pgsql_enums_1.objtypeName)(node.objectType));
720
- if (node.missing_ok) {
721
- output.push('IF EXISTS');
722
- }
723
- output.push(this.RangeVar(node.relation, context));
724
- output.push('SET SCHEMA');
725
- output.push(this.quote(node.newschema));
726
- }
727
- else {
728
- output.push('ALTER');
729
- output.push((0, pgsql_enums_1.objtypeName)(node.objectType));
730
- if (node.missing_ok) {
731
- output.push('IF EXISTS');
732
- }
733
- const unwrapped = unwrapList(node.object);
734
- if (Array.isArray(unwrapped)) {
735
- output.push(this.listQuotes(unwrapped, '.'));
736
- }
737
- else {
738
- output.push(this.deparse(node.object, context));
739
- }
740
- output.push('SET SCHEMA');
741
- output.push(this.quote(node.newschema));
742
- }
743
- return output.join(' ');
744
- }
745
- ColumnDef(node, context = {}) {
746
- const output = [this.quote(node.colname)];
747
- output.push(this.TypeName(node.typeName, context));
748
- if (node.raw_default) {
749
- output.push('USING');
750
- output.push(this.deparse(node.raw_default, context));
751
- }
752
- if (node.constraints) {
753
- output.push(this.list(node.constraints, ' ', '', context));
754
- }
755
- if (node.collClause) {
756
- output.push('COLLATE');
757
- const str = unwrapList(node.collClause.collname)[0].String.str;
758
- output.push(this.quote(str));
759
- }
760
- return compact(output).join(' ');
761
- }
762
- SQLValueFunction(node) {
763
- if (node.op === 'SVFOP_CURRENT_DATE') {
764
- return 'CURRENT_DATE';
765
- }
766
- if (node.op === 'SVFOP_CURRENT_TIMESTAMP') {
767
- return 'CURRENT_TIMESTAMP';
768
- }
769
- if (node.op === 'SVFOP_CURRENT_USER') {
770
- return 'CURRENT_USER';
771
- }
772
- if (node.op === 'SVFOP_SESSION_USER') {
773
- return 'SESSION_USER';
774
- }
775
- throw new Error(`op=${node.op} SQLValueFunction not implemented`);
776
- }
777
- ColumnRef(node, context = {}) {
778
- const KEYWORDS = ['old', 'new'];
779
- const fields = unwrapList(node.fields).map((field) => {
780
- if (field.String) {
781
- const value = this.deparse(field, context);
782
- if (context === 'trigger' && KEYWORDS.includes(value.toLowerCase())) {
783
- return value.toUpperCase();
784
- }
785
- return this.quote(value);
786
- }
787
- return this.deparse(field, context);
788
- });
789
- return fields.join('.');
790
- }
791
- CommentStmt(node, context = {}) {
792
- const output = [];
793
- output.push('COMMENT');
794
- output.push('ON');
795
- output.push((0, pgsql_enums_1.objtypeName)(node.objtype));
796
- const object = unwrapList(node.object);
797
- if (node.objtype === 'OBJECT_CAST') {
798
- output.push('(');
799
- output.push(this.deparse(object[0], context));
800
- output.push('AS');
801
- output.push(this.deparse(object[1], context));
802
- output.push(')');
803
- }
804
- else if (node.objtype === 'OBJECT_DOMCONSTRAINT') {
805
- output.push(this.deparse(object[1], context));
806
- output.push('ON');
807
- output.push('DOMAIN');
808
- output.push(this.deparse(object[0], context));
809
- }
810
- else if (node.objtype === 'OBJECT_OPCLASS' ||
811
- node.objtype === 'OBJECT_OPFAMILY') {
812
- output.push(this.deparse(object[1], context));
813
- output.push('USING');
814
- output.push(this.deparse(object[0], context));
815
- }
816
- else if (node.objtype === 'OBJECT_OPERATOR') {
817
- output.push(this.deparse(object, 'noquotes'));
818
- }
819
- else if (node.objtype === 'OBJECT_POLICY') {
820
- output.push(this.deparse(object[1], context));
821
- output.push('ON');
822
- output.push(this.deparse(object[0], context));
823
- }
824
- else if (node.objtype === 'OBJECT_ROLE') {
825
- output.push(this.deparse(object, context));
826
- }
827
- else if (node.objtype === 'OBJECT_RULE') {
828
- output.push(this.deparse(object[1], context));
829
- output.push('ON');
830
- output.push(this.deparse(object[0], context));
831
- }
832
- else if (node.objtype === 'OBJECT_TABCONSTRAINT') {
833
- if (object.length === 3) {
834
- output.push(this.deparse(object[2], context));
835
- output.push('ON');
836
- output.push(this.deparse(object[0], context) +
837
- '.' +
838
- this.deparse(object[1], context));
839
- }
840
- else {
841
- output.push(this.deparse(object[1], context));
842
- output.push('ON');
843
- output.push(this.deparse(object[0], context));
844
- }
845
- }
846
- else if (node.objtype === 'OBJECT_TRANSFORM') {
847
- output.push('FOR');
848
- output.push(this.deparse(object[0], context));
849
- output.push('LANGUAGE');
850
- output.push(this.deparse(object[1], context));
851
- }
852
- else if (node.objtype === 'OBJECT_TRIGGER') {
853
- output.push(this.deparse(object[1], context));
854
- output.push('ON');
855
- output.push(this.deparse(object[0], context));
856
- }
857
- else {
858
- if (node.objtype === 'OBJECT_LARGEOBJECT') {
859
- output.push(dotty.get(node, 'object.Integer.ival'));
860
- }
861
- else if (object instanceof Array) {
862
- output.push(this.listQuotes(object, '.'));
863
- }
864
- else {
865
- output.push(this.deparse(object, context));
866
- }
867
- if (node.objargs) {
868
- output.push('(');
869
- output.push(this.list(node.objargs, ', ', '', context));
870
- output.push(')');
871
- }
872
- }
873
- output.push('IS');
874
- const escapeComment = (str) => {
875
- return str.replace(/\\/g, '\\');
876
- };
877
- if (node.comment) {
878
- if (/[^a-zA-Z0-9]/.test(node.comment)) {
879
- // special chars we care about...
880
- output.push(`E'${escapeComment(node.comment)}'`);
881
- }
882
- else {
883
- // find a double \\n or \\ something...
884
- output.push(`'${node.comment}'`);
885
- }
886
- }
887
- else {
888
- output.push('NULL');
889
- }
890
- return output.join(' ');
891
- }
892
- CommonTableExpr(node, context = {}) {
893
- const output = [];
894
- output.push(node.ctename);
895
- if (node.aliascolnames) {
896
- const colnames = this.quote(this.deparseNodes(node.aliascolnames, context));
897
- output.push(`(${colnames.join(', ')})`);
898
- }
899
- output.push('AS');
900
- if (node.ctematerialized === 'CTEMaterializeAlways') {
901
- output.push('MATERIALIZED');
902
- }
903
- else if (node.ctematerialized === 'CTEMaterializeNever') {
904
- output.push('NOT MATERIALIZED');
905
- }
906
- output.push((0, util_1.format)('(%s)', this.deparse(node.ctequery)));
907
- return output.join(' ');
908
- }
909
- DefineStmt(node, context = {}) {
910
- const output = [];
911
- output.push('CREATE');
912
- if (node.replace) {
913
- output.push('OR REPLACE');
914
- }
915
- switch (node.kind) {
916
- case 'OBJECT_AGGREGATE':
917
- output.push('AGGREGATE');
918
- break;
919
- case 'OBJECT_OPERATOR':
920
- output.push('OPERATOR');
921
- break;
922
- case 'OBJECT_TYPE':
923
- output.push('TYPE');
924
- break;
925
- case 'OBJECT_TSPARSER':
926
- output.push('TEXT SEARCH PARSER');
927
- break;
928
- case 'OBJECT_TSDICTIONARY':
929
- output.push('TEXT SEARCH DICTIONARY');
930
- break;
931
- case 'OBJECT_TSTEMPLATE':
932
- output.push('TEXT SEARCH TEMPLATE');
933
- break;
934
- case 'OBJECT_TSCONFIGURATION':
935
- output.push('TEXT SEARCH CONFIGURATION');
936
- break;
937
- case 'OBJECT_COLLATION':
938
- output.push('COLLATION');
939
- break;
940
- default:
941
- throw new Error('DefineStmt not recognized');
942
- }
943
- if (node.if_not_exists) {
944
- output.push('IF NOT EXISTS');
945
- }
946
- switch (node.kind) {
947
- case 'OBJECT_AGGREGATE':
948
- // output.push(this.deparse(node.defnames));
949
- output.push(this.list(node.defnames, '.', '', context));
950
- break;
951
- case 'OBJECT_OPERATOR':
952
- output.push(this.list(node.defnames, '.', '', context));
953
- // output.push(this.deparse(node.defnames));
954
- break;
955
- case 'OBJECT_TYPE':
956
- case 'OBJECT_TSPARSER':
957
- case 'OBJECT_TSDICTIONARY':
958
- case 'OBJECT_TSTEMPLATE':
959
- case 'OBJECT_TSCONFIGURATION':
960
- case 'OBJECT_COLLATION':
961
- output.push(this.deparse(node.defnames));
962
- break;
963
- default:
964
- throw new Error('DefineStmt not recognized');
965
- }
966
- if (!node.oldstyle && node.kind == 'OBJECT_AGGREGATE') {
967
- output.push('(');
968
- output.push(`${this.listQuotes(node.args[0], ',')}`);
969
- output.push(')');
970
- }
971
- const definition = unwrapList(node.definition);
972
- if (definition.length > 0) {
973
- output.push('(');
974
- for (let n = 0; n < definition.length; n++) {
975
- const defElement = definition[n].DefElem;
976
- output.push(defElement.defname);
977
- if (defElement.arg) {
978
- output.push('=');
979
- output.push(this.deparse(defElement.arg));
980
- }
981
- if (n !== definition.length - 1) {
982
- output.push(',');
983
- }
984
- }
985
- output.push(')');
986
- }
987
- return output.join(' ');
988
- }
989
- DefElem(node, context = {}) {
990
- if (node.defname === 'transaction_isolation') {
991
- return (0, util_1.format)('ISOLATION LEVEL %s', node.arg.A_Const.val.String.str.toUpperCase());
992
- }
993
- if (node.defname === 'transaction_read_only') {
994
- return node.arg.A_Const.val.Integer.ival === 0
995
- ? 'READ WRITE'
996
- : 'READ ONLY';
997
- }
998
- if (node.defname === 'transaction_deferrable') {
999
- return node.arg.A_Const.val.Integer.ival === 0
1000
- ? 'NOT DEFERRABLE'
1001
- : 'DEFERRABLE';
1002
- }
1003
- if (node.defname === 'set') {
1004
- return this.deparse(node.arg, context);
1005
- }
1006
- let name = node.defname;
1007
- if (node.defnamespace) {
1008
- name = `${node.defnamespace}.${node.defname}`;
1009
- }
1010
- if (context === 'generated' || context === 'sequence') {
1011
- switch (name) {
1012
- case 'start': {
1013
- const start = this.deparse(node.arg, context);
1014
- return `START WITH ${start}`;
1015
- }
1016
- case 'increment': {
1017
- const inc = this.deparse(node.arg, context);
1018
- if (context === 'sequence') {
1019
- // we need 'simple' so it doesn't wrap negative numbers in parens
1020
- return `${name} ${this.deparse(node.arg, 'simple')}`;
1021
- }
1022
- return `INCREMENT BY ${inc}`;
1023
- }
1024
- case 'sequence_name': {
1025
- return `SEQUENCE NAME ${this.listQuotes(node.arg, '.')}`;
1026
- }
1027
- case 'cycle': {
1028
- const on = this.deparse(node.arg, context) + '' === '1';
1029
- return on ? 'CYCLE' : 'NO CYCLE';
1030
- }
1031
- case 'minvalue': {
1032
- const off = !node.hasOwnProperty('arg');
1033
- return off
1034
- ? 'NO MINVALUE'
1035
- : `${name} ${this.deparse(node.arg, 'simple')}`;
1036
- }
1037
- case 'maxvalue': {
1038
- const off = !node.hasOwnProperty('arg');
1039
- return off
1040
- ? 'NO MAXVALUE'
1041
- : `${name} ${this.deparse(node.arg, 'simple')}`;
1042
- }
1043
- // alter
1044
- case 'owned_by': {
1045
- const output = [];
1046
- unwrapList(node.arg).forEach((opt) => {
1047
- output.push(this.quote(this.deparse(opt, context)));
1048
- });
1049
- return `OWNED BY ${output.join('.')}`;
1050
- }
1051
- // alter
1052
- case 'restart': {
1053
- if (node.arg) {
1054
- return `RESTART WITH ${this.deparse(node.arg, context)}`;
1055
- }
1056
- return `RESTART`;
1057
- }
1058
- default:
1059
- if (node.arg) {
1060
- // we need 'simple' so it doesn't wrap negative numbers in parens
1061
- return `${name} ${this.deparse(node.arg, 'simple')}`;
1062
- }
1063
- }
1064
- }
1065
- else if (context === 'explain') {
1066
- if (node.arg) {
1067
- return `${name} ${this.deparse(node.arg)}`;
1068
- }
1069
- }
1070
- else if (node.arg) {
1071
- return `${name} = ${this.deparse(node.arg, context)}`;
1072
- }
1073
- return name;
1074
- }
1075
- DoStmt(node) {
1076
- return `DO $$${NEWLINE_CHAR} ${dotty
1077
- .get(node, 'args.0.DefElem.arg.String.str')
1078
- .trim()} $$`;
1079
- }
1080
- Float(node) {
1081
- // wrap negative numbers in parens, SELECT (-2147483648)::int4 * (-1)::int4
1082
- if (node.str[0] === '-') {
1083
- return `(${node.str})`;
1084
- }
1085
- return node.str;
1086
- }
1087
- FuncCall(node, context = {}) {
1088
- const output = [];
1089
- let params = [];
1090
- if (node.args) {
1091
- params = unwrapList(node.args).map((item) => {
1092
- return this.deparse(item, context);
1093
- });
1094
- }
1095
- // COUNT(*)
1096
- if (node.agg_star) {
1097
- params.push('*');
1098
- }
1099
- const name = this.list(node.funcname, '.', '', context);
1100
- const order = [];
1101
- const withinGroup = node.agg_within_group;
1102
- if (node.agg_order) {
1103
- order.push('ORDER BY');
1104
- order.push(this.list(node.agg_order, ', ', '', context));
1105
- }
1106
- const call = [];
1107
- call.push(name + '(');
1108
- if (node.agg_distinct) {
1109
- call.push('DISTINCT ');
1110
- }
1111
- // prepend variadic before the last parameter
1112
- // SELECT CONCAT('|', VARIADIC ARRAY['1','2','3'])
1113
- if (node.func_variadic) {
1114
- params[params.length - 1] = 'VARIADIC ' + params[params.length - 1];
1115
- }
1116
- call.push(params.join(', '));
1117
- if (order.length && !withinGroup) {
1118
- call.push(' ');
1119
- call.push(order.join(' '));
1120
- }
1121
- call.push(')');
1122
- output.push(compact(call).join(''));
1123
- if (order.length && withinGroup) {
1124
- output.push('WITHIN GROUP');
1125
- output.push(parens(order.join(' ')));
1126
- }
1127
- if (node.agg_filter != null) {
1128
- output.push((0, util_1.format)('FILTER (WHERE %s)', this.deparse(node.agg_filter, context)));
1129
- }
1130
- if (node.over != null) {
1131
- output.push((0, util_1.format)('OVER %s', this.WindowDef(node.over, context)));
1132
- }
1133
- return output.join(' ');
1134
- }
1135
- GroupingFunc(node, context = {}) {
1136
- return 'GROUPING(' + this.list(node.args, ', ', '', context) + ')';
1137
- }
1138
- GroupingSet(node, context = {}) {
1139
- switch (node.kind) {
1140
- case 'GROUPING_SET_EMPTY':
1141
- return '()';
1142
- case 'GROUPING_SET_SIMPLE':
1143
- return fail('GroupingSet', node);
1144
- case 'GROUPING_SET_ROLLUP':
1145
- return 'ROLLUP (' + this.list(node.content, ', ', '', context) + ')';
1146
- case 'GROUPING_SET_CUBE':
1147
- return 'CUBE (' + this.list(node.content, ', ', '', context) + ')';
1148
- case 'GROUPING_SET_SETS':
1149
- return ('GROUPING SETS (' + this.list(node.content, ', ', '', context) + ')');
1150
- default:
1151
- return fail('GroupingSet', node);
1152
- }
1153
- }
1154
- IndexStmt(node, context = {}) {
1155
- const output = [];
1156
- output.push('CREATE');
1157
- if (node.unique) {
1158
- output.push('UNIQUE');
1159
- }
1160
- output.push('INDEX');
1161
- if (node.concurrent) {
1162
- output.push('CONCURRENTLY');
1163
- }
1164
- if (node.if_not_exists) {
1165
- output.push('IF NOT EXISTS');
1166
- }
1167
- if (node.idxname) {
1168
- output.push(node.idxname);
1169
- }
1170
- output.push('ON');
1171
- output.push(this.RangeVar(node.relation, context));
1172
- if (node.accessMethod) {
1173
- const accessMethod = node.accessMethod.toUpperCase();
1174
- if (accessMethod !== 'BTREE') {
1175
- output.push('USING');
1176
- output.push(accessMethod);
1177
- }
1178
- }
1179
- if (node.indexParams) {
1180
- output.push('(');
1181
- output.push(this.list(node.indexParams, ', ', '', context));
1182
- output.push(')');
1183
- }
1184
- if (node.indexIncludingParams) {
1185
- output.push('INCLUDE (');
1186
- output.push(this.list(node.indexIncludingParams, ', ', '', context));
1187
- output.push(')');
1188
- }
1189
- if (node.whereClause) {
1190
- output.push('WHERE');
1191
- output.push(this.deparse(node.whereClause, context));
1192
- }
1193
- return output.join(' ');
1194
- }
1195
- IndexElem(node, context = {}) {
1196
- const output = [];
1197
- if (node.name) {
1198
- output.push(node.name);
1199
- if (node.opclass && node.opclass.length) {
1200
- output.push(this.deparse(node.opclass[0]));
1201
- }
1202
- if (node.opclassopts && node.opclassopts.length) {
1203
- output.push('(');
1204
- output.push(node.opclassopts.map((opclassopt) => this.deparse(opclassopt)).join(', '));
1205
- output.push(')');
1206
- }
1207
- if (node.ordering === 'SORTBY_DESC') {
1208
- output.push('DESC');
1209
- }
1210
- else if (node.ordering === 'SORTBY_ASC') {
1211
- output.push('ASC');
1212
- }
1213
- return output.join(' ');
1214
- }
1215
- if (node.expr) {
1216
- return this.deparse(node.expr, context);
1217
- }
1218
- return fail('IndexElem', node);
1219
- }
1220
- InsertStmt(node, context = {}) {
1221
- const output = [];
1222
- if (node.withClause) {
1223
- output.push(this.WithClause(node.withClause, context));
1224
- }
1225
- output.push('INSERT INTO');
1226
- output.push(this.RangeVar(node.relation, context));
1227
- const cols = unwrapList(node.cols);
1228
- if (cols && cols.length) {
1229
- output.push('(');
1230
- output.push(this.list(cols, ', ', '', context));
1231
- output.push(')');
1232
- }
1233
- if (node.selectStmt) {
1234
- output.push(this.deparse(node.selectStmt, context));
1235
- }
1236
- else {
1237
- output.push('DEFAULT VALUES');
1238
- }
1239
- if (node.onConflictClause) {
1240
- const clause = node.onConflictClause;
1241
- output.push('ON CONFLICT');
1242
- if (clause.infer.indexElems) {
1243
- output.push('(');
1244
- output.push(this.list(clause.infer.indexElems, ', ', '', context));
1245
- output.push(')');
1246
- }
1247
- else if (clause.infer.conname) {
1248
- output.push('ON CONSTRAINT');
1249
- output.push(clause.infer.conname);
1250
- }
1251
- switch (clause.action) {
1252
- case 'ONCONFLICT_NOTHING':
1253
- output.push('DO NOTHING');
1254
- break;
1255
- case 'ONCONFLICT_UPDATE':
1256
- output.push('DO');
1257
- output.push(this.UpdateStmt(clause, context));
1258
- break;
1259
- default:
1260
- throw new Error('unhandled CONFLICT CLAUSE');
1261
- }
1262
- }
1263
- if (node.returningList) {
1264
- output.push('RETURNING');
1265
- output.push(this.deparseReturningList(node.returningList, context));
1266
- }
1267
- return output.join(' ');
1268
- }
1269
- SetToDefault(node) {
1270
- return 'DEFAULT';
1271
- }
1272
- MultiAssignRef(node, context = {}) {
1273
- const output = [];
1274
- output.push(this.deparse(node.source, context));
1275
- return output.join(' ');
1276
- }
1277
- DeleteStmt(node, context = {}) {
1278
- const output = [''];
1279
- if (node.withClause) {
1280
- output.push(this.WithClause(node.withClause, context));
1281
- }
1282
- output.push('DELETE');
1283
- output.push('FROM');
1284
- output.push(this.RangeVar(node.relation, context));
1285
- if (node.usingClause) {
1286
- output.push('USING');
1287
- output.push(this.list(node.usingClause, ', ', '', context));
1288
- }
1289
- if (node.whereClause) {
1290
- output.push('WHERE');
1291
- output.push(this.deparse(node.whereClause, context));
1292
- }
1293
- if (node.returningList) {
1294
- output.push('RETURNING');
1295
- output.push(this.deparseReturningList(node.returningList, context));
1296
- }
1297
- return output.join(' ');
1298
- }
1299
- UpdateStmt(node, context = {}) {
1300
- const output = [];
1301
- if (node.withClause) {
1302
- output.push(this.WithClause(node.withClause, context));
1303
- }
1304
- output.push('UPDATE');
1305
- if (node.relation) {
1306
- // onConflictClause no relation..
1307
- output.push(this.RangeVar(node.relation, context));
1308
- }
1309
- output.push('SET');
1310
- const targetList = unwrapList(node.targetList);
1311
- if (targetList && targetList.length) {
1312
- if (targetList[0].ResTarget &&
1313
- targetList[0].ResTarget.val &&
1314
- targetList[0].ResTarget.val.MultiAssignRef) {
1315
- output.push('(');
1316
- output.push(targetList.map((target) => target.ResTarget.name).join(','));
1317
- output.push(')');
1318
- output.push('=');
1319
- output.push(this.deparse(targetList[0].ResTarget.val, context));
1320
- }
1321
- else {
1322
- output.push(targetList.map((target) => this.deparse(target, 'update')).join(','));
1323
- }
1324
- }
1325
- if (node.fromClause) {
1326
- output.push('FROM');
1327
- output.push(this.list(node.fromClause, ', ', '', context));
1328
- }
1329
- if (node.whereClause) {
1330
- output.push('WHERE');
1331
- output.push(this.deparse(node.whereClause, context));
1332
- }
1333
- if (node.returningList) {
1334
- output.push('RETURNING');
1335
- output.push(this.deparseReturningList(node.returningList, context));
1336
- }
1337
- return output.join(' ');
1338
- }
1339
- Integer(node, context = {}) {
1340
- if (node.ival < 0 && context !== 'simple') {
1341
- return `(${node.ival})`;
1342
- }
1343
- return node.ival.toString();
1344
- }
1345
- IntoClause(node, context = {}) {
1346
- return this.RangeVar(node.rel, context);
1347
- }
1348
- JoinExpr(node, context = {}) {
1349
- const output = [];
1350
- output.push(this.deparse(node.larg, context));
1351
- if (node.isNatural) {
1352
- output.push('NATURAL');
1353
- }
1354
- let join = null;
1355
- switch (true) {
1356
- case node.jointype === 'JOIN_INNER' && node.quals != null:
1357
- join = 'INNER JOIN';
1358
- break;
1359
- case node.jointype === 'JOIN_INNER' &&
1360
- !node.isNatural &&
1361
- !(node.quals != null) &&
1362
- !(node.usingClause != null):
1363
- join = 'CROSS JOIN';
1364
- break;
1365
- case node.jointype === 'JOIN_INNER':
1366
- join = 'JOIN';
1367
- break;
1368
- case node.jointype === 'JOIN_LEFT':
1369
- join = 'LEFT OUTER JOIN';
1370
- break;
1371
- case node.jointype === 'JOIN_FULL':
1372
- join = 'FULL OUTER JOIN';
1373
- break;
1374
- case node.jointype === 'JOIN_RIGHT':
1375
- join = 'RIGHT OUTER JOIN';
1376
- break;
1377
- default:
1378
- fail('JoinExpr', node);
1379
- break;
1380
- }
1381
- output.push(join);
1382
- if (node.rarg) {
1383
- // wrap nested join expressions in parens to make the following symmetric:
1384
- // select * from int8_tbl x cross join (int4_tbl x cross join lateral (select x.f1) ss)
1385
- if (node.rarg.JoinExpr != null && !(node.rarg.JoinExpr.alias != null)) {
1386
- output.push(`(${this.deparse(node.rarg, context)})`);
1387
- }
1388
- else {
1389
- output.push(this.deparse(node.rarg, context));
1390
- }
1391
- }
1392
- if (node.quals) {
1393
- output.push(`ON ${this.deparse(node.quals, context)}`);
1394
- }
1395
- if (node.usingClause) {
1396
- const using = this.quote(this.deparseNodes(node.usingClause, context)).join(', ');
1397
- output.push(`USING (${using})`);
1398
- }
1399
- const wrapped = node.rarg.JoinExpr != null || node.alias
1400
- ? '(' + output.join(' ') + ')'
1401
- : output.join(' ');
1402
- if (node.alias) {
1403
- return wrapped + ' ' + this.Alias(node.alias, context);
1404
- }
1405
- return wrapped;
1406
- }
1407
- LockingClause(node, context = {}) {
1408
- const output = [];
1409
- switch (node.strength) {
1410
- case 'LCS_NONE':
1411
- output.push('NONE');
1412
- break;
1413
- case 'LCS_FORKEYSHARE':
1414
- output.push('FOR KEY SHARE');
1415
- break;
1416
- case 'LCS_FORSHARE':
1417
- output.push('FOR SHARE');
1418
- break;
1419
- case 'LCS_FORNOKEYUPDATE':
1420
- output.push('FOR NO KEY UPDATE');
1421
- break;
1422
- case 'LCS_FORUPDATE':
1423
- output.push('FOR UPDATE');
1424
- break;
1425
- default:
1426
- return fail('LockingClause', node);
1427
- }
1428
- if (node.lockedRels) {
1429
- output.push('OF');
1430
- output.push(this.list(node.lockedRels, ', ', '', context));
1431
- }
1432
- return output.join(' ');
1433
- }
1434
- LockStmt(node, context = {}) {
1435
- const output = ['LOCK'];
1436
- output.push(this.list(node.relations, ', ', '', { lock: true }));
1437
- output.push('IN');
1438
- output.push(LOCK_MODES[node.mode]);
1439
- output.push('MODE');
1440
- if (node.nowait) {
1441
- output.push('NOWAIT');
1442
- }
1443
- return output.join(' ');
1444
- }
1445
- MinMaxExpr(node, context = {}) {
1446
- const output = [];
1447
- if (node.op === 'IS_GREATEST') {
1448
- output.push('GREATEST');
1449
- }
1450
- else {
1451
- output.push('LEAST');
1452
- }
1453
- output.push(parens(this.list(node.args, ', ', '', context)));
1454
- return output.join('');
1455
- }
1456
- NamedArgExpr(node, context = {}) {
1457
- const output = [];
1458
- output.push(node.name);
1459
- output.push(':=');
1460
- output.push(this.deparse(node.arg, context));
1461
- return output.join(' ');
1462
- }
1463
- Null(node) {
1464
- return 'NULL';
1465
- }
1466
- NullTest(node, context = {}) {
1467
- const output = [this.deparse(node.arg, context)];
1468
- if (node.nulltesttype === 'IS_NULL') {
1469
- output.push('IS NULL');
1470
- }
1471
- else if (node.nulltesttype === 'IS_NOT_NULL') {
1472
- output.push('IS NOT NULL');
1473
- }
1474
- return output.join(' ');
1475
- }
1476
- ParamRef(node) {
1477
- if (node.number >= 0) {
1478
- return ['$', node.number].join('');
1479
- }
1480
- return '?';
1481
- }
1482
- RangeFunction(node, context = {}) {
1483
- const output = [];
1484
- if (node.lateral) {
1485
- output.push('LATERAL');
1486
- }
1487
- const funcs = [];
1488
- const functions = unwrapList(node.functions);
1489
- for (let i = 0; i < functions.length; i++) {
1490
- const funcCall = unwrapList(functions[i]);
1491
- const call = [this.deparse(funcCall[0], context)];
1492
- const secondFuncCall = unwrapList(funcCall[1]);
1493
- if (secondFuncCall && secondFuncCall.length) {
1494
- call.push((0, util_1.format)('AS (%s)', this.list(secondFuncCall, ', ', '', context)));
1495
- }
1496
- funcs.push(call.join(' '));
1497
- }
1498
- const calls = funcs.join(', ');
1499
- if (node.is_rowsfrom) {
1500
- output.push(`ROWS FROM (${calls})`);
1501
- }
1502
- else {
1503
- output.push(calls);
1504
- }
1505
- if (node.ordinality) {
1506
- output.push('WITH ORDINALITY');
1507
- }
1508
- if (node.alias) {
1509
- output.push(this.Alias(node.alias, context));
1510
- }
1511
- if (node.coldeflist) {
1512
- const defList = this.list(node.coldeflist, ', ', '', context);
1513
- if (!node.alias) {
1514
- output.push(` AS (${defList})`);
1515
- }
1516
- else {
1517
- output.push(`(${defList})`);
1518
- }
1519
- }
1520
- return output.join(' ');
1521
- }
1522
- RangeSubselect(node, context = {}) {
1523
- let output = '';
1524
- if (node.lateral) {
1525
- output += 'LATERAL ';
1526
- }
1527
- output += parens(this.deparse(node.subquery, context));
1528
- if (node.alias) {
1529
- return output + ' ' + this.Alias(node.alias, context);
1530
- }
1531
- return output;
1532
- }
1533
- RangeTableSample(node, context = {}) {
1534
- const output = [];
1535
- output.push(this.deparse(node.relation, context));
1536
- output.push('TABLESAMPLE');
1537
- output.push(this.deparse(unwrapList(node.method)[0], context));
1538
- if (node.args) {
1539
- output.push(parens(this.list(node.args, ', ', '', context)));
1540
- }
1541
- if (node.repeatable) {
1542
- output.push('REPEATABLE(' + this.deparse(node.repeatable, context) + ')');
1543
- }
1544
- return output.join(' ');
1545
- }
1546
- RangeVar(node, context = {}) {
1547
- const output = [];
1548
- if (node.inhOpt === 0) {
1549
- output.push('ONLY');
1550
- }
1551
- if (!node.inh && (context.lock || context === 'truncate')) {
1552
- output.push('ONLY');
1553
- }
1554
- if (node.relpersistence === 'u') {
1555
- output.push('UNLOGGED');
1556
- }
1557
- if (node.relpersistence === 't' && context !== 'view') {
1558
- output.push('TEMPORARY TABLE');
1559
- }
1560
- if (node.schemaname != null) {
1561
- output.push(`${this.quote(node.schemaname)}.${this.quote(node.relname)}`);
1562
- }
1563
- else {
1564
- output.push(this.quote(node.relname));
1565
- }
1566
- if (node.alias) {
1567
- output.push(this.Alias(node.alias, context));
1568
- }
1569
- return output.join(' ');
1570
- }
1571
- ResTarget(node, context = {}) {
1572
- if (context === 'select') {
1573
- return compact([
1574
- this.deparse(node.val, context),
1575
- this.quote(node.name)
1576
- ]).join(' AS ');
1577
- }
1578
- else if (context === 'update') {
1579
- return compact([node.name, this.deparse(node.val, context)]).join(' = ');
1580
- }
1581
- else if (!(node.val != null)) {
1582
- return this.quote(node.name);
1583
- }
1584
- return fail('ResTarget', node);
1585
- }
1586
- RowExpr(node, context = {}) {
1587
- if (node.row_format === 'COERCE_IMPLICIT_CAST') {
1588
- return parens(this.list(node.args, ', ', '', context));
1589
- }
1590
- return (0, util_1.format)('ROW(%s)', this.list(node.args, ', ', '', context));
1591
- }
1592
- ExplainStmt(node, context = {}) {
1593
- const output = [];
1594
- output.push('EXPLAIN');
1595
- if (node.options) {
1596
- output.push('(');
1597
- output.push(this.list(node.options, ', ', '', 'explain'));
1598
- output.push(')');
1599
- }
1600
- output.push(this.deparse(node.query, context));
1601
- return output.join(' ');
1602
- }
1603
- SelectStmt(node, context = {}) {
1604
- const output = [];
1605
- if (node.withClause) {
1606
- output.push(this.WithClause(node.withClause, context));
1607
- }
1608
- if (node.op === 'SETOP_NONE') {
1609
- // VALUES select's don't get SELECT
1610
- if (node.valuesLists == null) {
1611
- output.push('SELECT');
1612
- }
1613
- }
1614
- else {
1615
- output.push(parens(this.SelectStmt(node.larg, context)));
1616
- switch (node.op) {
1617
- case 'SETOP_NONE':
1618
- output.push('NONE');
1619
- break;
1620
- case 'SETOP_UNION':
1621
- output.push('UNION');
1622
- break;
1623
- case 'SETOP_INTERSECT':
1624
- output.push('INTERSECT');
1625
- break;
1626
- case 'SETOP_EXCEPT':
1627
- output.push('EXCEPT');
1628
- break;
1629
- default:
1630
- throw new Error('bad SelectStmt op');
1631
- }
1632
- if (node.all) {
1633
- output.push('ALL');
1634
- }
1635
- output.push(parens(this.SelectStmt(node.rarg, context)));
1636
- }
1637
- if (node.distinctClause) {
1638
- const distinctClause = unwrapList(node.distinctClause);
1639
- if (!isEmptyObject(distinctClause[0])
1640
- // new change distinctClause can be {}
1641
- ) {
1642
- output.push('DISTINCT ON');
1643
- const clause = distinctClause
1644
- .map((e) => this.deparse(e, 'select'))
1645
- .join(`,${NEWLINE_CHAR}`);
1646
- output.push(`(${clause})`);
1647
- }
1648
- else {
1649
- output.push('DISTINCT');
1650
- }
1651
- }
1652
- if (node.targetList) {
1653
- output.push(indent(unwrapList(node.targetList)
1654
- .map((e) => this.deparse(e, 'select'))
1655
- .join(`,${NEWLINE_CHAR}`)));
1656
- }
1657
- if (node.intoClause) {
1658
- output.push('INTO');
1659
- output.push(indent(this.IntoClause(node.intoClause, context)));
1660
- }
1661
- if (node.fromClause) {
1662
- output.push('FROM');
1663
- output.push(indent(unwrapList(node.fromClause)
1664
- .map((e) => this.deparse(e, 'from'))
1665
- .join(`,${NEWLINE_CHAR}`)));
1666
- }
1667
- if (node.whereClause) {
1668
- output.push('WHERE');
1669
- output.push(indent(this.deparse(node.whereClause, context)));
1670
- }
1671
- if (node.valuesLists) {
1672
- output.push('VALUES');
1673
- const lists = unwrapList(node.valuesLists).map((list) => {
1674
- return `(${this.list(list, ', ', '', context)})`;
1675
- });
1676
- output.push(lists.join(', '));
1677
- }
1678
- if (node.groupClause) {
1679
- output.push('GROUP BY');
1680
- output.push(indent(unwrapList(node.groupClause)
1681
- .map((e) => this.deparse(e, 'group'))
1682
- .join(`,${NEWLINE_CHAR}`)));
1683
- }
1684
- if (node.havingClause) {
1685
- output.push('HAVING');
1686
- output.push(indent(this.deparse(node.havingClause, context)));
1687
- }
1688
- if (node.windowClause) {
1689
- output.push('WINDOW');
1690
- const windows = [];
1691
- const windowClause = unwrapList(node.windowClause);
1692
- for (let i = 0; i < windowClause.length; i++) {
1693
- const w = windowClause[i];
1694
- const window = [];
1695
- if (w.WindowDef.name) {
1696
- window.push(this.quote(w.WindowDef.name) + ' AS');
1697
- }
1698
- window.push(parens(this.deparse(w, 'window')));
1699
- windows.push(window.join(' '));
1700
- }
1701
- output.push(windows.join(', '));
1702
- }
1703
- if (node.sortClause) {
1704
- output.push('ORDER BY');
1705
- output.push(indent(unwrapList(node.sortClause)
1706
- .map((e) => this.deparse(e, 'sort'))
1707
- .join(`,${NEWLINE_CHAR}`)));
1708
- }
1709
- if (node.limitCount) {
1710
- output.push('LIMIT');
1711
- output.push(indent(this.deparse(node.limitCount, context)));
1712
- }
1713
- if (node.limitOffset) {
1714
- output.push('OFFSET');
1715
- output.push(indent(this.deparse(node.limitOffset, context)));
1716
- }
1717
- if (node.lockingClause) {
1718
- node.lockingClause.forEach((item) => {
1719
- return output.push(this.deparse(item, context));
1720
- });
1721
- }
1722
- return output.join(' ');
1723
- }
1724
- TruncateStmt(node, context = {}) {
1725
- const output = ['TRUNCATE TABLE'];
1726
- output.push(this.list(node.relations, ', ', '', 'truncate'));
1727
- if (node.restart_seqs) {
1728
- output.push('RESTART IDENTITY');
1729
- }
1730
- if (node.behavior === 'DROP_CASCADE') {
1731
- output.push('CASCADE');
1732
- }
1733
- return output.join(' ');
1734
- }
1735
- AlterDefaultPrivilegesStmt(node, context = {}) {
1736
- const output = [];
1737
- output.push('ALTER DEFAULT PRIVILEGES');
1738
- const options = unwrapList(dotty.get(node, 'options'));
1739
- if (options) {
1740
- const elem = options.find((el) => el.hasOwnProperty('DefElem'));
1741
- const elemDefElemArg = unwrapList(elem.DefElem.arg);
1742
- if (elem.DefElem.defname === 'schemas') {
1743
- output.push('IN SCHEMA');
1744
- output.push(elemDefElemArg[0].String.str);
1745
- }
1746
- if (elem.DefElem.defname === 'roles') {
1747
- output.push('FOR ROLE');
1748
- const roleSpec = elemDefElemArg[0];
1749
- output.push(this.deparse(roleSpec, context));
1750
- }
1751
- output.push(NEWLINE_CHAR);
1752
- }
1753
- output.push(this.GrantStmt(node.action, context));
1754
- return output.join(' ');
1755
- }
1756
- AlterTableStmt(node, context = {}) {
1757
- const output = [];
1758
- const ctx = Object.assign({}, context);
1759
- output.push('ALTER');
1760
- if (node.relkind === 'OBJECT_TABLE') {
1761
- output.push('TABLE');
1762
- const inh = dotty.get(node, 'relation.inh');
1763
- if (!inh) {
1764
- output.push('ONLY');
1765
- }
1766
- }
1767
- else if (node.relkind === 'OBJECT_TYPE') {
1768
- output.push('TYPE');
1769
- }
1770
- else {
1771
- fail('AlterTableStmt', node);
1772
- }
1773
- if (node.missing_ok) {
1774
- output.push('IF EXISTS');
1775
- }
1776
- ctx.alterType = node.relkind;
1777
- output.push(this.RangeVar(node.relation, ctx));
1778
- output.push(this.list(node.cmds, ', ', '', ctx));
1779
- return output.join(' ');
1780
- }
1781
- AlterTableCmd(node, context = {}) {
1782
- const output = [];
1783
- let subType = 'COLUMN';
1784
- if (context && context.alterType === 'OBJECT_TYPE') {
1785
- subType = 'ATTRIBUTE';
1786
- }
1787
- if (node.subtype === 'AT_AddColumn') {
1788
- output.push('ADD');
1789
- output.push(subType);
1790
- if (node.missing_ok) {
1791
- output.push('IF NOT EXISTS');
1792
- }
1793
- output.push(this.quote(node.name));
1794
- output.push(this.deparse(node.def, context));
1795
- }
1796
- else if (node.subtype === 'AT_ColumnDefault') {
1797
- output.push('ALTER');
1798
- output.push(subType);
1799
- output.push(this.quote(node.name));
1800
- if (node.def) {
1801
- output.push('SET DEFAULT');
1802
- output.push(this.deparse(node.def, context));
1803
- }
1804
- else {
1805
- output.push('DROP DEFAULT');
1806
- }
1807
- }
1808
- else if (node.subtype === 'AT_DropNotNull') {
1809
- output.push('ALTER');
1810
- output.push(subType);
1811
- output.push(this.quote(node.name));
1812
- output.push('DROP NOT NULL');
1813
- }
1814
- else if (node.subtype === 'AT_SetNotNull') {
1815
- output.push('ALTER');
1816
- output.push(subType);
1817
- output.push(this.quote(node.name));
1818
- output.push('SET NOT NULL');
1819
- }
1820
- else if (node.subtype === 'AT_SetStatistics') {
1821
- output.push('ALTER');
1822
- output.push(this.quote(node.name));
1823
- output.push('SET STATISTICS');
1824
- output.push(dotty.get(node, 'def.Integer.ival'));
1825
- }
1826
- else if (node.subtype === 'AT_SetOptions') {
1827
- output.push('ALTER');
1828
- output.push(subType);
1829
- output.push(this.quote(node.name));
1830
- output.push('SET');
1831
- output.push('(');
1832
- output.push(this.list(node.def, ', ', '', context));
1833
- output.push(')');
1834
- }
1835
- else if (node.subtype === 'AT_SetStorage') {
1836
- output.push('ALTER');
1837
- output.push(this.quote(node.name));
1838
- output.push('SET STORAGE');
1839
- if (node.def) {
1840
- output.push(this.deparse(node.def, context));
1841
- }
1842
- else {
1843
- output.push('PLAIN');
1844
- }
1845
- }
1846
- else if (node.subtype === 'AT_DropColumn') {
1847
- output.push('DROP');
1848
- output.push(subType);
1849
- if (node.missing_ok) {
1850
- output.push('IF EXISTS');
1851
- }
1852
- output.push(this.quote(node.name));
1853
- }
1854
- else if (node.subtype === 'AT_AddConstraint') {
1855
- // output.push('ADD CONSTRAINT');
1856
- output.push('ADD');
1857
- output.push(this.deparse(node.def, context));
1858
- }
1859
- else if (node.subtype === 'AT_ValidateConstraint') {
1860
- output.push('VALIDATE CONSTRAINT');
1861
- output.push(this.quote(node.name, context));
1862
- }
1863
- else if (node.subtype === 'AT_DropConstraint') {
1864
- output.push('DROP CONSTRAINT');
1865
- if (node.missing_ok) {
1866
- output.push('IF EXISTS');
1867
- }
1868
- output.push(this.quote(node.name));
1869
- }
1870
- else if (node.subtype === 'AT_AlterColumnType') {
1871
- output.push('ALTER');
1872
- output.push(subType);
1873
- output.push(this.quote(node.name));
1874
- output.push('TYPE');
1875
- output.push(this.deparse(node.def, context));
1876
- }
1877
- else if (node.subtype === 'AT_ChangeOwner') {
1878
- output.push('OWNER');
1879
- output.push('TO');
1880
- output.push(this.RoleSpec(node.newowner, context));
1881
- }
1882
- else if (node.subtype === 'AT_ClusterOn') {
1883
- output.push('CLUSTER ON');
1884
- output.push(this.quote(node.name));
1885
- }
1886
- else if (node.subtype === 'AT_DropCluster') {
1887
- output.push('SET WITHOUT CLUSTER');
1888
- }
1889
- else if (node.subtype === 'AT_AddOids') {
1890
- output.push('SET WITH OIDS');
1891
- }
1892
- else if (node.subtype === 'AT_DropOids') {
1893
- output.push('SET WITHOUT OIDS');
1894
- }
1895
- else if (node.subtype === 'AT_SetRelOptions') {
1896
- output.push('SET');
1897
- output.push('(');
1898
- output.push(this.list(node.def, ', ', '', context));
1899
- output.push(')');
1900
- }
1901
- else if (node.subtype === 'AT_ResetRelOptions') {
1902
- output.push('RESET');
1903
- output.push('(');
1904
- output.push(this.list(node.def, ', ', '', context));
1905
- output.push(')');
1906
- }
1907
- else if (node.subtype === 'AT_AddIdentity') {
1908
- output.push('ALTER COLUMN');
1909
- output.push(this.quote(node.name));
1910
- output.push('ADD');
1911
- output.push(this.deparse(node.def, context));
1912
- }
1913
- else if (node.subtype === 'AT_AddInherit') {
1914
- output.push('INHERIT');
1915
- output.push(this.deparse(node.def, context));
1916
- }
1917
- else if (node.subtype === 'AT_DropInherit') {
1918
- output.push('NO INHERIT');
1919
- output.push(this.deparse(node.def, context));
1920
- }
1921
- else if (node.subtype === 'AT_AddOf') {
1922
- output.push('OF');
1923
- output.push(this.deparse(node.def, context));
1924
- }
1925
- else if (node.subtype === 'AT_DropOf') {
1926
- output.push('NOT OF');
1927
- //output.push(this.deparse(node.def));
1928
- }
1929
- else if (node.subtype === 'AT_EnableRowSecurity') {
1930
- output.push('ENABLE ROW LEVEL SECURITY');
1931
- }
1932
- else if (node.subtype === 'AT_DisableRowSecurity') {
1933
- output.push('DISABLE ROW LEVEL SECURITY');
1934
- }
1935
- else if (node.subtype === 'AT_ForceRowSecurity') {
1936
- output.push('FORCE ROW SECURITY');
1937
- }
1938
- else if (node.subtype === 'AT_NoForceRowSecurity') {
1939
- output.push('NO FORCE ROW SECURITY');
1940
- }
1941
- if (node.behavior === 'DROP_CASCADE') {
1942
- output.push('CASCADE');
1943
- }
1944
- return output.join(' ');
1945
- }
1946
- CreateEnumStmt(node, context = {}) {
1947
- const output = [];
1948
- output.push('CREATE TYPE');
1949
- output.push(this.list(node.typeName, '.', '', context));
1950
- output.push('AS ENUM');
1951
- output.push(`(${NEWLINE_CHAR}`);
1952
- const vals = unwrapList(node.vals).map((val) => {
1953
- return { String: { str: `'${val.String.str}'` } };
1954
- });
1955
- output.push(this.list(vals, `,${NEWLINE_CHAR}`, TAB_CHAR));
1956
- output.push(`${NEWLINE_CHAR})`);
1957
- return output.join(' ');
1958
- }
1959
- AlterEnumStmt(node, context = {}) {
1960
- const output = [];
1961
- output.push('ALTER TYPE');
1962
- const typObj = {
1963
- TypeName: {
1964
- names: node.typeName
1965
- }
1966
- };
1967
- output.push(this.deparse(typObj, context));
1968
- if (node.newVal) {
1969
- output.push('ADD VALUE');
1970
- const result = node.newVal.replace(/'/g, "''");
1971
- output.push(`'${result}'`);
1972
- }
1973
- if (node.newValNeighbor) {
1974
- if (node.newValIsAfter) {
1975
- output.push('AFTER');
1976
- }
1977
- else {
1978
- output.push('BEFORE');
1979
- }
1980
- const result = node.newValNeighbor.replace(/'/g, "''");
1981
- output.push(`'${result}'`);
1982
- }
1983
- if (node.behavior === 'DROP_CASCADE') {
1984
- output.push('CASCADE');
1985
- }
1986
- return output.join(' ');
1987
- }
1988
- AlterDomainStmt(node, context = {}) {
1989
- const output = [];
1990
- output.push('ALTER DOMAIN');
1991
- const typObj = {
1992
- TypeName: {
1993
- names: node.typeName
1994
- }
1995
- };
1996
- output.push(this.deparse(typObj, context));
1997
- if (node.subtype === 'C') {
1998
- output.push('ADD');
1999
- output.push(this.deparse(node.def, context));
2000
- }
2001
- else if (node.subtype === 'V') {
2002
- output.push('VALIDATE');
2003
- output.push('CONSTRAINT');
2004
- output.push(this.quote(node.name));
2005
- }
2006
- else if (node.subtype === 'X') {
2007
- output.push('DROP');
2008
- output.push('CONSTRAINT');
2009
- output.push(this.quote(node.name));
2010
- }
2011
- if (node.behavior === 'DROP_CASCADE') {
2012
- output.push('CASCADE');
2013
- }
2014
- return output.join(' ');
2015
- }
2016
- CreateExtensionStmt(node) {
2017
- const output = [];
2018
- output.push('CREATE EXTENSION');
2019
- if (node.if_not_exists) {
2020
- output.push('IF NOT EXISTS');
2021
- }
2022
- output.push(this.quote(node.extname));
2023
- if (node.options) {
2024
- node.options.forEach((opt) => {
2025
- if (opt.DefElem.defname === 'cascade' &&
2026
- opt.DefElem.arg.Integer.ival === 1) {
2027
- output.push('CASCADE');
2028
- }
2029
- if (opt.DefElem.defname === 'schema') {
2030
- output.push('WITH SCHEMA');
2031
- output.push(this.quote(this.deparse(opt.DefElem.arg)));
2032
- }
2033
- });
2034
- }
2035
- return output.join(' ');
2036
- }
2037
- DropStmt(node, context = {}) {
2038
- const output = [];
2039
- output.push('DROP');
2040
- output.push((0, pgsql_enums_1.objtypeName)(node.removeType));
2041
- if (node.concurrent) {
2042
- output.push('CONCURRENTLY');
2043
- }
2044
- if (node.missing_ok) {
2045
- output.push('IF EXISTS');
2046
- }
2047
- const stmts = [];
2048
- const objects = unwrapList(node.objects);
2049
- for (let s = 0; s < objects.length; s++) {
2050
- const children = unwrapList(objects[s]);
2051
- const stmt = [];
2052
- if (node.removeType === 'OBJECT_TABLE' ||
2053
- node.removeType === 'OBJECT_CONVERSION' ||
2054
- node.removeType === 'OBJECT_COLLATION' ||
2055
- node.removeType === 'OBJECT_MATVIEW' ||
2056
- node.removeType === 'OBJECT_INDEX' ||
2057
- node.removeType === 'OBJECT_FOREIGN_TABLE') {
2058
- if (children.length === 1) {
2059
- stmt.push(this.quote(this.deparse(children[0])));
2060
- }
2061
- else if (children.length === 2) {
2062
- stmt.push(this.listQuotes(children, '.'));
2063
- }
2064
- else {
2065
- throw new Error('bad case 2 drop stmt' + JSON.stringify(node, null, 2));
2066
- }
2067
- }
2068
- else if (node.removeType === 'OBJECT_SCHEMA') {
2069
- stmt.push(this.quote(this.deparse(children)));
2070
- }
2071
- else if (node.removeType === 'OBJECT_SEQUENCE') {
2072
- stmt.push(this.listQuotes(children, '.'));
2073
- }
2074
- else if (node.removeType === 'OBJECT_POLICY') {
2075
- if (children.length === 2) {
2076
- stmt.push(this.quote(this.deparse(children[1], context)));
2077
- stmt.push('ON');
2078
- stmt.push(this.quote(this.deparse(children[0], context)));
2079
- }
2080
- else if (children.length === 3) {
2081
- stmt.push(this.quote(this.deparse(children[2], context)));
2082
- stmt.push('ON');
2083
- stmt.push(this.listQuotes([children[0], children[1]], '.'));
2084
- }
2085
- else {
2086
- throw new Error('bad drop policy stmt: ' + JSON.stringify(node, null, 2));
2087
- }
2088
- }
2089
- else if (node.removeType === 'OBJECT_TRIGGER') {
2090
- if (children.length === 2) {
2091
- stmt.push(this.quote(this.deparse(children[1], context)));
2092
- stmt.push('ON');
2093
- stmt.push(this.quote(this.deparse(children[0], context)));
2094
- }
2095
- else if (children.length === 3) {
2096
- stmt.push(this.quote(this.deparse(children[2], context)));
2097
- stmt.push('ON');
2098
- stmt.push(this.listQuotes([children[0], children[1]], '.'));
2099
- }
2100
- else {
2101
- throw new Error('bad drop trigger stmt: ' + JSON.stringify(node, null, 2));
2102
- }
2103
- }
2104
- else if (node.removeType === 'OBJECT_RULE') {
2105
- if (children.length === 2) {
2106
- stmt.push(this.quote(this.deparse(children[1], context)));
2107
- stmt.push('ON');
2108
- stmt.push(this.quote(this.deparse(children[0], context)));
2109
- }
2110
- else if (children.length === 3) {
2111
- stmt.push(this.quote(this.deparse(children[2], context)));
2112
- stmt.push('ON');
2113
- stmt.push(this.listQuotes([children[0], children[1]], '.'));
2114
- }
2115
- else {
2116
- throw new Error('bad drop rule stmt: ' + JSON.stringify(node, null, 2));
2117
- }
2118
- }
2119
- else if (node.removeType === 'OBJECT_VIEW') {
2120
- if (children.length === 1) {
2121
- stmt.push(this.quote(this.deparse(children[0], context)));
2122
- }
2123
- else if (children.length === 2) {
2124
- stmt.push(this.listQuotes(children, '.'));
2125
- }
2126
- else {
2127
- throw new Error('bad drop value stmt: ' + JSON.stringify(node, null, 2));
2128
- }
2129
- // } else if (node.removeType === 'OBJECT_OPERATOR') {
2130
- }
2131
- else if (node.removeType === 'OBJECT_CAST') {
2132
- stmt.push('(');
2133
- stmt.push(this.deparse(children[0], context));
2134
- stmt.push('AS');
2135
- stmt.push(this.deparse(children[1], context));
2136
- stmt.push(')');
2137
- // } else if (node.removeType === 'OBJECT_OPERATOR') {
2138
- // stmt.push(this.deparse(children, 'noquotes')); // in this case children is not an array
2139
- }
2140
- else if (node.removeType === 'OBJECT_AGGREGATE') {
2141
- stmt.push(this.deparse(children, context)); // in this case children is not an array
2142
- }
2143
- else if (node.removeType === 'OBJECT_FDW') {
2144
- stmt.push(this.deparse(children, context)); // in this case children is not an array
2145
- }
2146
- else if (node.removeType === 'OBJECT_FOREIGN_SERVER') {
2147
- stmt.push(this.deparse(children, context)); // in this case children is not an array
2148
- }
2149
- else if (node.removeType === 'OBJECT_EXTENSION') {
2150
- stmt.push(this.deparse(children, context)); // in this case children is not an array
2151
- }
2152
- else if (node.removeType === 'OBJECT_DOMAIN') {
2153
- stmt.push(this.deparse(children, context)); // in this case children is not an array
2154
- }
2155
- else if (node.removeType === 'OBJECT_FUNCTION') {
2156
- stmt.push(this.deparse(children, context)); // in this case children is not an array
2157
- }
2158
- else if (node.removeType === 'OBJECT_TYPE') {
2159
- stmt.push(this.deparse(children, context)); // in this case children is not an array
2160
- }
2161
- else {
2162
- throw new Error('bad drop stmt: ' + JSON.stringify(node, null, 2));
2163
- }
2164
- stmts.push(stmt.join(' '));
2165
- }
2166
- output.push(stmts.join(','));
2167
- if (node.behavior === 'DROP_CASCADE') {
2168
- output.push('CASCADE');
2169
- }
2170
- return output.join(' ');
2171
- }
2172
- CreatePolicyStmt(node, context = {}) {
2173
- const output = [];
2174
- output.push('CREATE POLICY');
2175
- output.push(this.quote(node.policy_name));
2176
- if (node.table) {
2177
- output.push('ON');
2178
- output.push(this.RangeVar(node.table, context));
2179
- }
2180
- if (node.permissive) {
2181
- // permissive is the default!
2182
- }
2183
- else {
2184
- output.push('AS');
2185
- output.push('RESTRICTIVE');
2186
- }
2187
- if (node.cmd_name) {
2188
- output.push('FOR');
2189
- output.push(node.cmd_name.toUpperCase());
2190
- }
2191
- output.push('TO');
2192
- output.push(this.list(node.roles));
2193
- if (node.qual) {
2194
- output.push('USING');
2195
- output.push('(');
2196
- output.push(this.deparse(node.qual, context));
2197
- output.push(')');
2198
- }
2199
- if (node.with_check) {
2200
- output.push('WITH CHECK');
2201
- output.push('(');
2202
- output.push(this.deparse(node.with_check, context));
2203
- output.push(')');
2204
- }
2205
- return output.join(' ');
2206
- }
2207
- AlterPolicyStmt(node, context = {}) {
2208
- const output = [];
2209
- output.push('ALTER POLICY');
2210
- output.push(this.quote(node.policy_name));
2211
- if (node.table) {
2212
- output.push('ON');
2213
- output.push(this.RangeVar(node.table, context));
2214
- }
2215
- output.push('TO');
2216
- output.push(this.list(node.roles));
2217
- if (node.qual) {
2218
- output.push('USING');
2219
- output.push('(');
2220
- output.push(this.deparse(node.qual, context));
2221
- output.push(')');
2222
- }
2223
- if (node.with_check) {
2224
- output.push('WITH CHECK');
2225
- output.push('(');
2226
- output.push(this.deparse(node.with_check, context));
2227
- output.push(')');
2228
- }
2229
- return output.join(' ');
2230
- }
2231
- ViewStmt(node, context = {}) {
2232
- const output = [];
2233
- output.push('CREATE');
2234
- if (node.replace)
2235
- output.push('OR REPLACE');
2236
- if (node.view.relpersistence === 't') {
2237
- output.push('TEMPORARY');
2238
- }
2239
- output.push('VIEW');
2240
- output.push(this.RangeVar(node.view, 'view'));
2241
- if (node.aliases) {
2242
- output.push('(');
2243
- output.push(this.list(node.aliases, ', ', '', context));
2244
- output.push(')');
2245
- }
2246
- output.push('AS');
2247
- output.push(this.deparse(node.query, context));
2248
- if (node.withCheckOption === 'LOCAL_CHECK_OPTION') {
2249
- output.push('WITH LOCAL CHECK OPTION');
2250
- }
2251
- else if (node.withCheckOption === 'CASCADED_CHECK_OPTION') {
2252
- output.push('WITH CASCADED CHECK OPTION');
2253
- }
2254
- return output.join(' ');
2255
- }
2256
- CreateSeqStmt(node, context = {}) {
2257
- const output = [];
2258
- output.push('CREATE SEQUENCE');
2259
- output.push(this.RangeVar(node.sequence, context));
2260
- const options = unwrapList(node.options);
2261
- if (options && options.length) {
2262
- options.forEach((opt) => {
2263
- output.push(this.deparse(opt, 'sequence'));
2264
- });
2265
- }
2266
- return output.join(' ');
2267
- }
2268
- AlterSeqStmt(node, context = {}) {
2269
- const output = [];
2270
- output.push('ALTER SEQUENCE');
2271
- output.push(this.RangeVar(node.sequence, context));
2272
- const options = unwrapList(node.options);
2273
- if (options && options.length) {
2274
- options.forEach((opt) => {
2275
- output.push(this.deparse(opt, 'sequence'));
2276
- });
2277
- }
2278
- return output.join(' ');
2279
- }
2280
- CreateTableAsStmt(node, context = {}) {
2281
- const output = ['CREATE'];
2282
- const relpersistence = dotty.get(node, 'into.rel.relpersistence');
2283
- if (node.relkind === 'OBJECT_MATVIEW') {
2284
- output.push('MATERIALIZED VIEW');
2285
- }
2286
- else if (relpersistence !== 't') {
2287
- output.push('TABLE');
2288
- if (node.if_not_exists) {
2289
- output.push('IF NOT EXISTS');
2290
- }
2291
- }
2292
- output.push(this.IntoClause(node.into, context));
2293
- output.push('AS');
2294
- output.push(this.deparse(node.query, context));
2295
- return output.join(' ');
2296
- }
2297
- CreateTrigStmt(node, context = {}) {
2298
- const output = [];
2299
- output.push('CREATE');
2300
- if (node.isconstraint) {
2301
- output.push('CONSTRAINT');
2302
- }
2303
- output.push('TRIGGER');
2304
- output.push(this.quote(node.trigname));
2305
- output.push(NEWLINE_CHAR);
2306
- // int16 timing; BEFORE, AFTER, or INSTEAD
2307
- if (node.timing === 64) {
2308
- output.push('INSTEAD OF');
2309
- }
2310
- else if (node.timing === 2) {
2311
- output.push('BEFORE');
2312
- }
2313
- else {
2314
- output.push('AFTER');
2315
- }
2316
- // int16 events; "OR" of INSERT/UPDATE/DELETE/TRUNCATE
2317
- // 4 = 0b000100 (insert)
2318
- // 8 = 0b001000 (delete)
2319
- // 16 = 0b010000 (update)
2320
- // 32 = 0b100000 (TRUNCATE)
2321
- const TRIGGER_EVENTS = {
2322
- INSERT: 4,
2323
- DELETE: 8,
2324
- UPDATE: 16,
2325
- TRUNCATE: 32
2326
- };
2327
- const events = [];
2328
- if ((TRIGGER_EVENTS.INSERT & node.events) === TRIGGER_EVENTS.INSERT) {
2329
- events.push('INSERT');
2330
- }
2331
- if ((TRIGGER_EVENTS.UPDATE & node.events) === TRIGGER_EVENTS.UPDATE) {
2332
- events.push('UPDATE');
2333
- }
2334
- if ((TRIGGER_EVENTS.DELETE & node.events) === TRIGGER_EVENTS.DELETE) {
2335
- events.push('DELETE');
2336
- }
2337
- if ((TRIGGER_EVENTS.TRUNCATE & node.events) === TRIGGER_EVENTS.TRUNCATE) {
2338
- events.push('TRUNCATE');
2339
- }
2340
- // events
2341
- output.push(events.join(' OR '));
2342
- // columns
2343
- if (node.columns) {
2344
- output.push('OF');
2345
- output.push(this.list(node.columns, ', ', '', context));
2346
- }
2347
- // ON
2348
- output.push('ON');
2349
- output.push(this.RangeVar(node.relation, context));
2350
- output.push(NEWLINE_CHAR);
2351
- if (node.transitionRels) {
2352
- output.push('REFERENCING');
2353
- node.transitionRels.forEach(({ TriggerTransition }) => {
2354
- if (TriggerTransition.isNew === true &&
2355
- TriggerTransition.isTable === true) {
2356
- output.push(`NEW TABLE AS ${TriggerTransition.name}`);
2357
- }
2358
- else if (TriggerTransition.isNew !== true &&
2359
- TriggerTransition.isTable === true) {
2360
- output.push(`OLD TABLE AS ${TriggerTransition.name}`);
2361
- }
2362
- });
2363
- }
2364
- // opts
2365
- if (node.deferrable || node.initdeferred) {
2366
- if (node.deferrable) {
2367
- output.push('DEFERRABLE');
2368
- }
2369
- if (node.deferrable) {
2370
- output.push('INITIALLY DEFERRED');
2371
- }
2372
- output.push(NEWLINE_CHAR);
2373
- }
2374
- if (node.row) {
2375
- output.push(`FOR EACH ROW${NEWLINE_CHAR}`);
2376
- }
2377
- else {
2378
- output.push(`FOR EACH STATEMENT${NEWLINE_CHAR}`);
2379
- }
2380
- if (node.whenClause) {
2381
- output.push('WHEN');
2382
- output.push('(');
2383
- output.push(this.deparse(node.whenClause, 'trigger'));
2384
- output.push(')');
2385
- output.push(NEWLINE_CHAR);
2386
- }
2387
- output.push('EXECUTE PROCEDURE');
2388
- output.push(this.listQuotes(node.funcname).split(',').join('.'));
2389
- output.push('(');
2390
- let args = [];
2391
- if (node.args) {
2392
- args = unwrapList(node.args);
2393
- }
2394
- // seems that it's only parsing strings?
2395
- args = args
2396
- .map((arg) => {
2397
- if (arg.String !== undefined && arg.String.str !== undefined) {
2398
- return `'${arg.String.str}'`;
2399
- }
2400
- return this.deparse(arg, context);
2401
- })
2402
- .filter((a) => a);
2403
- output.push(args.join(','));
2404
- output.push(')');
2405
- return output.join(' ');
2406
- }
2407
- CreateDomainStmt(node, context = {}) {
2408
- const output = [];
2409
- output.push('CREATE DOMAIN');
2410
- output.push(this.list(node.domainname, '.', '', context));
2411
- output.push('AS');
2412
- output.push(this.TypeName(node.typeName, context));
2413
- if (node.constraints) {
2414
- output.push(this.list(node.constraints, ', ', '', context));
2415
- }
2416
- return output.join(' ');
2417
- }
2418
- CreateStmt(node, context = {}) {
2419
- const output = [];
2420
- const relpersistence = dotty.get(node, 'relation.relpersistence');
2421
- if (relpersistence === 't') {
2422
- output.push('CREATE');
2423
- }
2424
- else {
2425
- output.push('CREATE TABLE');
2426
- if (node.if_not_exists) {
2427
- output.push('IF NOT EXISTS');
2428
- }
2429
- }
2430
- output.push(this.RangeVar(node.relation, context));
2431
- output.push(`(${NEWLINE_CHAR}`);
2432
- output.push(this.list(node.tableElts, `,${NEWLINE_CHAR}`, TAB_CHAR, context));
2433
- output.push(`${NEWLINE_CHAR})`);
2434
- if (node.hasOwnProperty('inhRelations')) {
2435
- output.push('INHERITS');
2436
- output.push('(');
2437
- output.push(this.list(node.inhRelations, ', ', '', context));
2438
- output.push(')');
2439
- }
2440
- if (node.options) {
2441
- // TODO was this deprecated?
2442
- node.options.forEach((opt) => {
2443
- if (dotty.get(opt, 'DefElem.defname') === 'oids') {
2444
- if (Number(dotty.get(opt, 'DefElem.arg.Integer.ival')) === 1) {
2445
- output.push('WITH OIDS');
2446
- }
2447
- else {
2448
- output.push('WITHOUT OIDS');
2449
- }
2450
- }
2451
- });
2452
- }
2453
- return output.join(' ');
2454
- }
2455
- ConstraintStmt(node) {
2456
- const output = [];
2457
- const constraint = (0, pgsql_enums_1.getConstraintFromConstrType)(node.contype);
2458
- if (node.conname) {
2459
- output.push('CONSTRAINT');
2460
- output.push(node.conname);
2461
- if (!node.pktable) {
2462
- output.push(constraint);
2463
- }
2464
- }
2465
- else if (node.contype === 'CONSTR_IDENTITY') {
2466
- // IDENTITY
2467
- output.push('GENERATED');
2468
- if (node.generated_when == 'a') {
2469
- output.push('ALWAYS AS');
2470
- }
2471
- else {
2472
- output.push('BY DEFAULT AS');
2473
- }
2474
- output.push('IDENTITY');
2475
- const options = unwrapList(node.options);
2476
- if (options && options.length) {
2477
- output.push('(');
2478
- output.push(this.list(options, ' ', '', 'generated'));
2479
- output.push(')');
2480
- }
2481
- }
2482
- else if (node.contype === 'CONSTR_GENERATED') {
2483
- output.push('GENERATED');
2484
- if (node.generated_when == 'a') {
2485
- output.push('ALWAYS AS');
2486
- }
2487
- }
2488
- else {
2489
- output.push(constraint);
2490
- }
2491
- return output.join(' ');
2492
- }
2493
- ReferenceConstraint(node, context = {}) {
2494
- const output = [];
2495
- if (node.pk_attrs && node.fk_attrs) {
2496
- if (node.conname) {
2497
- output.push('CONSTRAINT');
2498
- output.push(node.conname);
2499
- }
2500
- output.push('FOREIGN KEY');
2501
- output.push('(');
2502
- output.push(this.listQuotes(node.fk_attrs));
2503
- output.push(')');
2504
- output.push('REFERENCES');
2505
- output.push(this.RangeVar(node.pktable, context));
2506
- output.push('(');
2507
- output.push(this.listQuotes(node.pk_attrs));
2508
- output.push(')');
2509
- }
2510
- else if (node.pk_attrs) {
2511
- output.push(this.ConstraintStmt(node, context));
2512
- output.push(this.RangeVar(node.pktable, context));
2513
- output.push('(');
2514
- output.push(this.listQuotes(node.pk_attrs));
2515
- output.push(')');
2516
- }
2517
- else if (node.fk_attrs) {
2518
- if (node.conname) {
2519
- output.push('CONSTRAINT');
2520
- output.push(node.conname);
2521
- }
2522
- output.push('FOREIGN KEY');
2523
- output.push('(');
2524
- output.push(this.listQuotes(node.fk_attrs));
2525
- output.push(')');
2526
- output.push('REFERENCES');
2527
- output.push(this.RangeVar(node.pktable, context));
2528
- }
2529
- else {
2530
- output.push(this.ConstraintStmt(node, context));
2531
- output.push(this.RangeVar(node.pktable, context));
2532
- }
2533
- return output.join(' ');
2534
- }
2535
- ExclusionConstraint(node, context = {}) {
2536
- const output = [];
2537
- function getExclusionGroup(nde) {
2538
- const exclusions = unwrapList(nde.exclusions);
2539
- const a = exclusions.map((excl) => {
2540
- const firstExcl = unwrapList(excl)[0];
2541
- if (firstExcl.IndexElem.name) {
2542
- return firstExcl.IndexElem.name;
2543
- }
2544
- return firstExcl.IndexElem.expr
2545
- ? this.deparse(firstExcl.IndexElem.expr, context)
2546
- : null;
2547
- });
2548
- const b = exclusions.map((excl) => this.deparse(unwrapList(unwrapList(excl)[1])[0], context));
2549
- const stmts = a.map((_v, i) => `${a[i]} WITH ${b[i]}`);
2550
- return stmts.join(', ');
2551
- }
2552
- if (node.exclusions && node.access_method) {
2553
- output.push('USING');
2554
- output.push(node.access_method);
2555
- output.push('(');
2556
- output.push(getExclusionGroup.call(this, node));
2557
- output.push(')');
2558
- }
2559
- return output.join(' ');
2560
- }
2561
- Constraint(node, context = {}) {
2562
- const output = [];
2563
- if (node.contype === 'CONSTR_FOREIGN') {
2564
- output.push(this.ReferenceConstraint(node, context));
2565
- }
2566
- else {
2567
- output.push(this.ConstraintStmt(node, context));
2568
- }
2569
- if (node.keys) {
2570
- output.push('(');
2571
- output.push(this.listQuotes(node.keys));
2572
- output.push(')');
2573
- }
2574
- if (node.raw_expr) {
2575
- output.push('(');
2576
- output.push(this.deparse(node.raw_expr, context));
2577
- output.push(')');
2578
- if (node.contype == 'CONSTR_GENERATED') {
2579
- output.push('STORED');
2580
- }
2581
- }
2582
- if (node.fk_del_action) {
2583
- switch (node.fk_del_action) {
2584
- case 'r':
2585
- output.push('ON DELETE RESTRICT');
2586
- break;
2587
- case 'c':
2588
- output.push('ON DELETE CASCADE');
2589
- break;
2590
- case 'n':
2591
- output.push('ON DELETE SET NULL');
2592
- break;
2593
- case 'd':
2594
- output.push('ON DELETE SET DEFAULT');
2595
- break;
2596
- case 'a':
2597
- // output.push('ON DELETE NO ACTION');
2598
- break;
2599
- default:
2600
- }
2601
- }
2602
- if (node.fk_upd_action) {
2603
- switch (node.fk_upd_action) {
2604
- case 'r':
2605
- output.push('ON UPDATE RESTRICT');
2606
- break;
2607
- case 'c':
2608
- output.push('ON UPDATE CASCADE');
2609
- break;
2610
- case 'n':
2611
- output.push('ON UPDATE SET NULL');
2612
- break;
2613
- case 'd':
2614
- output.push('ON UPDATE SET DEFAULT');
2615
- break;
2616
- case 'a':
2617
- // output.push('ON UPDATE NO ACTION');
2618
- break;
2619
- default:
2620
- }
2621
- }
2622
- if (node.fk_matchtype === 'f') {
2623
- output.push('MATCH FULL');
2624
- }
2625
- if (node.is_no_inherit === true) {
2626
- output.push('NO INHERIT');
2627
- }
2628
- if (node.skip_validation === true) {
2629
- output.push('NOT VALID');
2630
- }
2631
- if (node.contype === 'CONSTR_EXCLUSION') {
2632
- output.push(this.ExclusionConstraint(node, context));
2633
- }
2634
- if (node.deferrable) {
2635
- output.push('deferrable');
2636
- }
2637
- return output.join(' ');
2638
- }
2639
- AccessPriv(node) {
2640
- const output = [];
2641
- if (node.priv_name) {
2642
- output.push(node.priv_name.toUpperCase());
2643
- }
2644
- else {
2645
- output.push('ALL');
2646
- }
2647
- if (node.cols) {
2648
- output.push('(');
2649
- output.push(this.listQuotes(node.cols));
2650
- output.push(')');
2651
- }
2652
- return output.join(' ');
2653
- }
2654
- VariableSetStmt(node) {
2655
- switch (node.kind) {
2656
- case 'VAR_SET_VALUE':
2657
- return (0, util_1.format)('SET %s%s = %s', node.is_local ? 'LOCAL ' : '', node.name, this.deparseNodes(node.args, 'simple').join(', '));
2658
- case 'VAR_SET_DEFAULT':
2659
- return (0, util_1.format)('SET %s TO DEFAULT', node.name);
2660
- case 'VAR_SET_CURRENT':
2661
- return (0, util_1.format)('SET %s FROM CURRENT', node.name);
2662
- case 'VAR_SET_MULTI': {
2663
- const name = {
2664
- TRANSACTION: 'TRANSACTION',
2665
- 'SESSION CHARACTERISTICS': 'SESSION CHARACTERISTICS AS TRANSACTION'
2666
- }[node.name];
2667
- return (0, util_1.format)('SET %s %s', name, this.deparseNodes(node.args, 'simple').join(', '));
2668
- }
2669
- case 'VAR_RESET':
2670
- return (0, util_1.format)('RESET %s', node.name);
2671
- case 'VAR_RESET_ALL':
2672
- return 'RESET ALL';
2673
- default:
2674
- return fail('VariableSetKind', node);
2675
- }
2676
- }
2677
- VariableShowStmt(node) {
2678
- return (0, util_1.format)('SHOW %s', node.name);
2679
- }
2680
- FuncWithArgs(node, context = {}) {
2681
- const output = [];
2682
- output.push(this.deparse(unwrapList(node.funcname)[0], context));
2683
- output.push('(');
2684
- output.push(this.list(node.funcargs, ', ', '', context));
2685
- output.push(')');
2686
- return output.join(' ');
2687
- }
2688
- FunctionParameter(node, context = {}) {
2689
- const output = [];
2690
- if (node.mode === 'FUNC_PARAM_VARIADIC') {
2691
- output.push('VARIADIC');
2692
- }
2693
- if (node.mode === 'FUNC_PARAM_OUT') {
2694
- output.push('OUT');
2695
- }
2696
- if (node.mode === 'FUNC_PARAM_INOUT') {
2697
- output.push('INOUT');
2698
- }
2699
- output.push(node.name);
2700
- output.push(this.TypeName(node.argType, context));
2701
- if (node.defexpr) {
2702
- output.push('DEFAULT');
2703
- output.push(this.deparse(node.defexpr, context));
2704
- }
2705
- return output.join(' ');
2706
- }
2707
- CreateFunctionStmt(node, context = {}) {
2708
- const output = [];
2709
- output.push('CREATE');
2710
- if (node.replace) {
2711
- output.push('OR REPLACE');
2712
- }
2713
- output.push('FUNCTION');
2714
- output.push(unwrapList(node.funcname)
2715
- .map((name) => this.deparse(name, context))
2716
- .join('.'));
2717
- output.push('(');
2718
- let parameters = [];
2719
- if (node.parameters) {
2720
- parameters = unwrapList(node.parameters);
2721
- }
2722
- const parametersList = parameters.filter(({ FunctionParameter }) => FunctionParameter.mode === 'FUNC_PARAM_VARIADIC' ||
2723
- FunctionParameter.mode === 'FUNC_PARAM_OUT' ||
2724
- FunctionParameter.mode === 'FUNC_PARAM_INOUT' ||
2725
- FunctionParameter.mode === 'FUNC_PARAM_IN');
2726
- output.push(this.list(parametersList));
2727
- output.push(')');
2728
- const returns = parameters.filter(({ FunctionParameter }) => FunctionParameter.mode === 'FUNC_PARAM_TABLE');
2729
- if (returns.length > 0) {
2730
- output.push('RETURNS');
2731
- output.push('TABLE');
2732
- output.push('(');
2733
- output.push(this.list(returns, ', ', '', context));
2734
- output.push(')');
2735
- }
2736
- else if (node.returnType) {
2737
- output.push('RETURNS');
2738
- output.push(this.TypeName(node.returnType, context));
2739
- }
2740
- node.options.forEach((option, i) => {
2741
- if (option && option.DefElem) {
2742
- let value = '';
2743
- switch (option.DefElem.defname) {
2744
- case 'as':
2745
- value = this.deparse(unwrapList(option.DefElem.arg)[0], context);
2746
- output.push(`AS $EOFCODE$${value}$EOFCODE$`);
2747
- break;
2748
- case 'language':
2749
- value = this.deparse(option.DefElem.arg, context);
2750
- output.push('LANGUAGE');
2751
- output.push(value);
2752
- break;
2753
- case 'security':
2754
- output.push('SECURITY');
2755
- value = Number(option.DefElem.arg.Integer.ival);
2756
- if (value > 0) {
2757
- output.push('DEFINER');
2758
- }
2759
- else {
2760
- output.push('INVOKER');
2761
- }
2762
- break;
2763
- case 'leakproof':
2764
- value = Number(option.DefElem.arg.Integer.ival);
2765
- if (value > 0) {
2766
- output.push('LEAKPROOF');
2767
- }
2768
- break;
2769
- case 'window':
2770
- value = Number(option.DefElem.arg.Integer.ival);
2771
- if (value > 0) {
2772
- output.push('WINDOW');
2773
- }
2774
- break;
2775
- case 'strict':
2776
- value = Number(option.DefElem.arg.Integer.ival);
2777
- if (value > 0) {
2778
- output.push('STRICT');
2779
- }
2780
- else {
2781
- output.push('CALLED ON NULL INPUT');
2782
- }
2783
- break;
2784
- case 'set':
2785
- output.push(this.deparse(option, context));
2786
- break;
2787
- case 'volatility':
2788
- value = this.deparse(option.DefElem.arg, context);
2789
- output.push(value.toUpperCase());
2790
- break;
2791
- default:
2792
- }
2793
- }
2794
- });
2795
- return output.join(' ');
2796
- }
2797
- CreateSchemaStmt(node) {
2798
- const output = [];
2799
- output.push('CREATE');
2800
- if (node.replace) {
2801
- output.push('OR REPLACE');
2802
- }
2803
- output.push('SCHEMA');
2804
- if (node.if_not_exists) {
2805
- output.push('IF NOT EXISTS');
2806
- }
2807
- output.push(node.schemaname);
2808
- return output.join(' ');
2809
- }
2810
- RoleSpec(node) {
2811
- switch (node.roletype) {
2812
- case 'ROLESPEC_CSTRING':
2813
- return this.quote(node.rolename);
2814
- case 'ROLESPEC_CURRENT_USER':
2815
- return 'CURRENT_USER';
2816
- case 'ROLESPEC_SESSION_USER':
2817
- return 'SESSION_USER';
2818
- case 'ROLESPEC_PUBLIC':
2819
- return 'PUBLIC';
2820
- default:
2821
- return fail('RoleSpec', node);
2822
- }
2823
- }
2824
- GrantStmt(node) {
2825
- const output = [];
2826
- const getTypeFromNode = (nodeObj) => {
2827
- switch (nodeObj.objtype) {
2828
- case 'OBJECT_TABLE':
2829
- if (nodeObj.targtype === 'ACL_TARGET_ALL_IN_SCHEMA') {
2830
- return 'ALL TABLES IN SCHEMA';
2831
- }
2832
- if (nodeObj.targtype === 'ACL_TARGET_DEFAULTS') {
2833
- return 'TABLES';
2834
- }
2835
- // todo could be view
2836
- return 'TABLE';
2837
- case 'OBJECT_SEQUENCE':
2838
- if (nodeObj.targtype === 'ACL_TARGET_ALL_IN_SCHEMA') {
2839
- return 'ALL SEQUENCES IN SCHEMA';
2840
- }
2841
- if (nodeObj.targtype === 'ACL_TARGET_DEFAULTS') {
2842
- return 'SEQUENCES';
2843
- }
2844
- return 'SEQUENCE';
2845
- case 'OBJECT_DATABASE':
2846
- return 'DATABASE';
2847
- case 'OBJECT_DOMAIN':
2848
- return 'DOMAIN';
2849
- case 'OBJECT_FDW':
2850
- return 'FOREIGN DATA WRAPPER';
2851
- case 'OBJECT_FOREIGN_SERVER':
2852
- return 'FOREIGN SERVER';
2853
- case 'OBJECT_FUNCTION':
2854
- if (nodeObj.targtype === 'ACL_TARGET_ALL_IN_SCHEMA') {
2855
- return 'ALL FUNCTIONS IN SCHEMA';
2856
- }
2857
- if (nodeObj.targtype === 'ACL_TARGET_DEFAULTS') {
2858
- return 'FUNCTIONS';
2859
- }
2860
- return 'FUNCTION';
2861
- case 'OBJECT_LANGUAGE':
2862
- return 'LANGUAGE';
2863
- case 'OBJECT_LARGEOBJECT':
2864
- return 'LARGE OBJECT';
2865
- case 'OBJECT_SCHEMA':
2866
- return 'SCHEMA';
2867
- case 'OBJECT_TABLESPACE':
2868
- return 'TABLESPACE';
2869
- case 'OBJECT_TYPE':
2870
- return 'TYPE';
2871
- default:
2872
- }
2873
- return fail('GrantStmt', node);
2874
- };
2875
- if (node.objtype !== 'OBJECT_COLUMN') {
2876
- if (!node.is_grant) {
2877
- output.push('REVOKE');
2878
- if (node.grant_option) {
2879
- output.push('GRANT OPTION');
2880
- output.push('FOR');
2881
- }
2882
- if (node.privileges) {
2883
- output.push(this.list(node.privileges));
2884
- }
2885
- else {
2886
- output.push('ALL');
2887
- }
2888
- output.push('ON');
2889
- output.push(getTypeFromNode(node));
2890
- output.push(this.list(node.objects));
2891
- output.push('FROM');
2892
- output.push(this.list(node.grantees));
2893
- }
2894
- else {
2895
- output.push('GRANT');
2896
- if (node.privileges) {
2897
- output.push(this.list(node.privileges));
2898
- }
2899
- else {
2900
- output.push('ALL');
2901
- }
2902
- output.push('ON');
2903
- output.push(getTypeFromNode(node));
2904
- output.push(this.list(node.objects));
2905
- output.push('TO');
2906
- output.push(this.list(node.grantees));
2907
- if (node.grant_option) {
2908
- output.push('WITH GRANT OPTION');
2909
- }
2910
- }
2911
- if (node.behavior === 'DROP_CASCADE') {
2912
- output.push('CASCADE');
2913
- }
2914
- }
2915
- return output.join(' ');
2916
- }
2917
- GrantRoleStmt(node, context = {}) {
2918
- const output = [];
2919
- if (!node.is_grant) {
2920
- output.push('REVOKE');
2921
- output.push(this.list(node.granted_roles, ', ', '', context));
2922
- output.push('FROM');
2923
- output.push(this.list(node.grantee_roles, ', ', '', context));
2924
- }
2925
- else {
2926
- output.push('GRANT');
2927
- output.push(this.list(node.granted_roles, ', ', '', context));
2928
- output.push('TO');
2929
- output.push(this.list(node.grantee_roles, ', ', '', context));
2930
- }
2931
- if (node.admin_opt) {
2932
- output.push('WITH ADMIN OPTION');
2933
- }
2934
- return output.join(' ');
2935
- }
2936
- CreateRoleStmt(node, context = {}) {
2937
- const output = [];
2938
- const roleOption = (nodeObj, i, val1, val2) => {
2939
- const val = Number(dotty.get(unwrapList(nodeObj.options), `${i}.DefElem.arg.Integer.ival`));
2940
- if (val > 0) {
2941
- output.push(val1);
2942
- }
2943
- else {
2944
- output.push(val2);
2945
- }
2946
- };
2947
- output.push('CREATE');
2948
- switch (node.stmt_type) {
2949
- case 'ROLESTMT_USER':
2950
- output.push('USER');
2951
- break;
2952
- case 'ROLESTMT_GROUP':
2953
- output.push('GROUP');
2954
- break;
2955
- default:
2956
- output.push('ROLE');
2957
- }
2958
- output.push(`"${node.role}"`);
2959
- if (node.options) {
2960
- const options = unwrapList(node.options);
2961
- const opts = dotty.search(options, '*.DefElem.defname');
2962
- if (opts.length === 1 && opts[0] === 'addroleto') {
2963
- // only one case
2964
- }
2965
- else {
2966
- output.push('WITH');
2967
- }
2968
- opts.forEach((option, i) => {
2969
- let value = '';
2970
- switch (option) {
2971
- case 'canlogin':
2972
- roleOption(node, i, 'LOGIN', 'NOLOGIN');
2973
- break;
2974
- case 'addroleto':
2975
- output.push('IN ROLE');
2976
- output.push(dotty
2977
- .search(flatten(dotty.search(options, `${i}.DefElem.arg`).map(unwrapList)), '*.RoleSpec.rolename')
2978
- .join(','));
2979
- break;
2980
- case 'password':
2981
- output.push('PASSWORD');
2982
- value = dotty.get(options, `${i}.DefElem.arg.String.str`);
2983
- output.push(`'${value}'`);
2984
- break;
2985
- case 'adminmembers':
2986
- output.push('ADMIN');
2987
- output.push(this.list(options[i].DefElem.arg, ', ', '', context));
2988
- break;
2989
- case 'rolemembers':
2990
- output.push('USER');
2991
- output.push(this.list(options[i].DefElem.arg, ', ', '', context));
2992
- break;
2993
- case 'createdb':
2994
- roleOption(node, i, 'CREATEDB', 'NOCREATEDB');
2995
- break;
2996
- case 'isreplication':
2997
- roleOption(node, i, 'REPLICATION', 'NOREPLICATION');
2998
- break;
2999
- case 'bypassrls':
3000
- roleOption(node, i, 'BYPASSRLS', 'NOBYPASSRLS');
3001
- break;
3002
- case 'inherit':
3003
- roleOption(node, i, 'INHERIT', 'NOINHERIT');
3004
- break;
3005
- case 'superuser':
3006
- roleOption(node, i, 'SUPERUSER', 'NOSUPERUSER');
3007
- break;
3008
- case 'createrole':
3009
- roleOption(node, i, 'CREATEROLE', 'NOCREATEROLE');
3010
- break;
3011
- case 'validUntil':
3012
- output.push('VALID UNTIL');
3013
- value = dotty.get(options[i], `DefElem.arg.String.str`);
3014
- output.push(`'${value}'`);
3015
- break;
3016
- default:
3017
- }
3018
- });
3019
- }
3020
- return output.join(' ');
3021
- }
3022
- TransactionStmt(node, context = {}) {
3023
- const output = [];
3024
- const begin = (nodeOpts) => {
3025
- const options = unwrapList(nodeOpts.options);
3026
- const opts = options ? dotty.search(options, '*.DefElem.defname') : [];
3027
- if (opts.includes('transaction_read_only')) {
3028
- const index = opts.indexOf('transaction_read_only');
3029
- const obj = options[index];
3030
- let set = false;
3031
- const flag = Number(this.deparse(dotty.get(obj, 'DefElem.arg'), context));
3032
- if (flag > 0) {
3033
- set = true;
3034
- }
3035
- if (set) {
3036
- return 'BEGIN TRANSACTION READ ONLY';
3037
- }
3038
- return 'BEGIN TRANSACTION READ WRITE';
3039
- }
3040
- if (opts.includes('transaction_isolation')) {
3041
- const index = opts.indexOf('transaction_isolation');
3042
- const obj = options[index];
3043
- const lopts = this.deparse(dotty.get(obj, 'DefElem.arg'), context).replace(/['"]+/g, '');
3044
- return `BEGIN TRANSACTION ISOLATION LEVEL ${lopts.toUpperCase()}`;
3045
- }
3046
- return 'BEGIN';
3047
- };
3048
- const start = (nodeOpts) => {
3049
- const options = unwrapList(nodeOpts.options);
3050
- const opts = options ? dotty.search(options, '*.DefElem.defname') : [];
3051
- if (opts.includes('transaction_read_only')) {
3052
- const index = opts.indexOf('transaction_read_only');
3053
- const obj = options[index];
3054
- let set = false;
3055
- const flag = Number(this.deparse(dotty.get(obj, 'DefElem.arg'), context));
3056
- if (flag > 0) {
3057
- set = true;
3058
- }
3059
- if (set) {
3060
- return 'START TRANSACTION READ ONLY';
3061
- }
3062
- return 'START TRANSACTION READ WRITE';
3063
- }
3064
- return 'START TRANSACTION';
3065
- };
3066
- const nodeOptions = unwrapList(node.options);
3067
- switch (node.kind) {
3068
- case 'TRANS_STMT_BEGIN':
3069
- return begin(node);
3070
- case 'TRANS_STMT_START':
3071
- return start(node);
3072
- case 'TRANS_STMT_COMMIT':
3073
- return 'COMMIT';
3074
- case 'TRANS_STMT_ROLLBACK':
3075
- return 'ROLLBACK';
3076
- case 'TRANS_STMT_SAVEPOINT':
3077
- output.push('SAVEPOINT');
3078
- output.push(this.deparse(nodeOptions[0].DefElem.arg, context));
3079
- break;
3080
- case 'TRANS_STMT_RELEASE':
3081
- output.push('RELEASE SAVEPOINT');
3082
- output.push(this.deparse(nodeOptions[0].DefElem.arg, context));
3083
- break;
3084
- case 'TRANS_STMT_ROLLBACK_TO':
3085
- output.push('ROLLBACK TO');
3086
- output.push(this.deparse(nodeOptions[0].DefElem.arg, context));
3087
- break;
3088
- case 'TRANS_STMT_PREPARE':
3089
- output.push('PREPARE TRANSACTION');
3090
- output.push(`'${node.gid}'`);
3091
- break;
3092
- case 'TRANS_STMT_COMMIT_PREPARED':
3093
- output.push('COMMIT PREPARED');
3094
- output.push(`'${node.gid}'`);
3095
- break;
3096
- case 'TRANS_STMT_ROLLBACK_PREPARED':
3097
- output.push('ROLLBACK PREPARED');
3098
- output.push(`'${node.gid}'`);
3099
- break;
3100
- default:
3101
- }
3102
- return output.join(' ');
3103
- }
3104
- SortBy(node, context = {}) {
3105
- const output = [];
3106
- output.push(this.deparse(node.node, context));
3107
- switch (node.sortby_dir) {
3108
- case 'SORTBY_ASC':
3109
- output.push('ASC');
3110
- break;
3111
- case 'SORTBY_DESC':
3112
- output.push('DESC');
3113
- break;
3114
- case 'SORTBY_USING':
3115
- output.push(`USING ${this.deparseNodes(node.useOp, context)}`);
3116
- break;
3117
- case 'SORTBY_DEFAULT':
3118
- break;
3119
- default:
3120
- return fail('SortBy', node);
3121
- }
3122
- if (node.sortby_nulls === 'SORTBY_NULLS_FIRST') {
3123
- output.push('NULLS FIRST');
3124
- }
3125
- if (node.sortby_nulls === 'SORTBY_NULLS_LAST') {
3126
- output.push('NULLS LAST');
3127
- }
3128
- return output.join(' ');
3129
- }
3130
- ObjectWithArgs(node, context = {}) {
3131
- const output = [];
3132
- if (context === 'noquotes') {
3133
- output.push(this.list(node.objname, ', ', '', context));
3134
- }
3135
- else {
3136
- output.push(this.listQuotes(node.objname, '.'));
3137
- }
3138
- const objargs = unwrapList(node.objargs);
3139
- if (objargs && objargs.length) {
3140
- output.push('(');
3141
- output.push(objargs
3142
- .map((arg) => {
3143
- if (isEmptyObject(arg)) {
3144
- return 'NONE';
3145
- }
3146
- return this.deparse(arg, context);
3147
- })
3148
- .join(','));
3149
- output.push(')');
3150
- }
3151
- else if (!node.args_unspecified) {
3152
- output.push('()');
3153
- }
3154
- return output.join(' ');
3155
- }
3156
- String(node) {
3157
- return node.str;
3158
- }
3159
- SubLink(node, context = {}) {
3160
- switch (true) {
3161
- case node.subLinkType === 'EXISTS_SUBLINK':
3162
- return (0, util_1.format)('EXISTS (%s)', this.deparse(node.subselect, context));
3163
- case node.subLinkType === 'ALL_SUBLINK':
3164
- return (0, util_1.format)('%s %s ALL (%s)', this.deparse(node.testexpr, context), this.deparse(node.operName[0], context), this.deparse(node.subselect, context));
3165
- case node.subLinkType === 'ANY_SUBLINK' && !(node.operName != null):
3166
- return (0, util_1.format)('%s IN (%s)', this.deparse(node.testexpr, context), this.deparse(node.subselect, context));
3167
- case node.subLinkType === 'ANY_SUBLINK':
3168
- return (0, util_1.format)('%s %s ANY (%s)', this.deparse(node.testexpr, context), this.deparse(node.operName[0], context), this.deparse(node.subselect, context));
3169
- case node.subLinkType === 'ROWCOMPARE_SUBLINK':
3170
- return (0, util_1.format)('%s %s (%s)', this.deparse(node.testexpr, context), this.deparse(node.operName[0], context), this.deparse(node.subselect, context));
3171
- case node.subLinkType === 'EXPR_SUBLINK':
3172
- return (0, util_1.format)('(%s)', this.deparse(node.subselect, context));
3173
- case node.subLinkType === 'MULTIEXPR_SUBLINK':
3174
- // TODO(zhm) what is this?
3175
- return fail('SubLink', node);
3176
- // MULTIEXPR_SUBLINK
3177
- // format('(%s)', @deparse(node.subselect))
3178
- case node.subLinkType === 'ARRAY_SUBLINK':
3179
- return (0, util_1.format)('ARRAY (%s)', this.deparse(node.subselect, context));
3180
- default:
3181
- return fail('SubLink', node);
3182
- }
3183
- }
3184
- TypeCast(node, context = {}) {
3185
- const type = this.TypeName(node.typeName, context);
3186
- let arg = this.deparse(node.arg, context);
3187
- if (node.arg !== undefined && node.arg.A_Expr !== undefined) {
3188
- arg = (0, util_1.format)('(%s)', arg);
3189
- }
3190
- if (type === 'boolean') {
3191
- const value = dotty.get(node, 'arg.A_Const.val.String.str');
3192
- if (value === 'f') {
3193
- return 'FALSE';
3194
- }
3195
- if (value === 't') {
3196
- return 'TRUE';
3197
- }
3198
- }
3199
- return (0, util_1.format)('%s::%s', arg, type);
3200
- }
3201
- TypeName(node, context = {}) {
3202
- const names = unwrapList(node.names);
3203
- if (names[names.length - 1].String.str === 'interval') {
3204
- return this.deparseInterval(node);
3205
- }
3206
- const output = [];
3207
- if (node.setof) {
3208
- output.push('SETOF');
3209
- }
3210
- let args = null;
3211
- if (node.typmods != null) {
3212
- args = unwrapList(node.typmods).map((item) => {
3213
- return this.deparse(item, context);
3214
- });
3215
- }
3216
- const type = [];
3217
- type.push(this.type(names, args && args.join(', ')));
3218
- if (node.arrayBounds != null) {
3219
- type.push('[]');
3220
- }
3221
- output.push(type.join(''));
3222
- return output.join(' ');
3223
- }
3224
- CaseWhen(node, context = {}) {
3225
- const output = ['WHEN'];
3226
- output.push(this.deparse(node.expr, context));
3227
- output.push('THEN');
3228
- output.push(this.deparse(node.result, context));
3229
- return output.join(' ');
3230
- }
3231
- WindowDef(node, context = {}) {
3232
- const output = [];
3233
- if (context !== 'window') {
3234
- if (node.name) {
3235
- output.push(node.name);
3236
- }
3237
- }
3238
- const empty = !(node.partitionClause != null) && !(node.orderClause != null);
3239
- const frameOptions = this.deparseFrameOptions(node.frameOptions, node.refname, node.startOffset, node.endOffset);
3240
- if (empty &&
3241
- context !== 'window' &&
3242
- !(node.name != null) &&
3243
- frameOptions.length === 0) {
3244
- return '()';
3245
- }
3246
- const windowParts = [];
3247
- let useParens = false;
3248
- if (node.partitionClause) {
3249
- const partition = ['PARTITION BY'];
3250
- const clause = unwrapList(node.partitionClause).map((item) => this.deparse(item, context));
3251
- partition.push(clause.join(', '));
3252
- windowParts.push(partition.join(' '));
3253
- useParens = true;
3254
- }
3255
- if (node.orderClause) {
3256
- windowParts.push('ORDER BY');
3257
- const orders = unwrapList(node.orderClause).map((item) => {
3258
- return this.deparse(item);
3259
- });
3260
- windowParts.push(orders.join(', '));
3261
- useParens = true;
3262
- }
3263
- if (frameOptions.length) {
3264
- useParens = true;
3265
- windowParts.push(frameOptions);
3266
- }
3267
- if (useParens && context !== 'window') {
3268
- return output.join(' ') + ' (' + windowParts.join(' ') + ')';
3269
- }
3270
- return output.join(' ') + windowParts.join(' ');
3271
- }
3272
- WithClause(node, context = {}) {
3273
- const output = ['WITH'];
3274
- if (node.recursive) {
3275
- output.push('RECURSIVE');
3276
- }
3277
- output.push(this.list(node.ctes, ', ', '', context));
3278
- return output.join(' ');
3279
- }
3280
- CopyStmt(node, context = {}) {
3281
- const output = ['COPY'];
3282
- output.push('(' + this.deparse(node.query, context) + ')');
3283
- output.push('TO');
3284
- output.push(`'${node.filename}'`);
3285
- const options = unwrapList(node.options);
3286
- if (options?.length > 0 && options[0].DefElem.defname === 'format') {
3287
- output.push(`(FORMAT '${this.deparse(options[0].DefElem.arg)}')`);
3288
- }
3289
- return output.join(' ');
3290
- }
3291
- CallStmt(node, context = {}) {
3292
- const output = ['CALL'];
3293
- output.push(this.deparse(unwrapList(node.funccall.funcname)[0]));
3294
- const funccallArgs = unwrapList(node.funccall.args);
3295
- if (funccallArgs && funccallArgs.length) {
3296
- // we have arguments
3297
- output.push('(' + this.list(funccallArgs, ', ', '', context) + ')');
3298
- }
3299
- else {
3300
- // just close parens
3301
- output.push('()');
3302
- }
3303
- return output.join(' ');
3304
- }
3305
- deparseFrameOptions(options, refName, startOffset, endOffset) {
3306
- // https://github.com/pganalyze/libpg_query/blob/442b1748d06364ecd3779bc558899176c02efaf0/src/postgres/include/nodes/parsenodes.h#L505-L522
3307
- const FRAMEOPTION_NONDEFAULT = 0x00001; /* any specified? */
3308
- const FRAMEOPTION_RANGE = 0x00002; /* RANGE behavior */
3309
- const FRAMEOPTION_ROWS = 0x00004; /* ROWS behavior */
3310
- const FRAMEOPTION_GROUPS = 0x00008; /* GROUPS behavior */
3311
- const FRAMEOPTION_BETWEEN = 0x00010; /* BETWEEN given? */
3312
- const FRAMEOPTION_START_UNBOUNDED_PRECEDING = 0x00020; /* start is U. P. */
3313
- const FRAMEOPTION_END_UNBOUNDED_PRECEDING = 0x00040; /* (disallowed) */
3314
- const FRAMEOPTION_START_UNBOUNDED_FOLLOWING = 0x00080; /* (disallowed) */
3315
- const FRAMEOPTION_END_UNBOUNDED_FOLLOWING = 0x00100; /* end is U. F. */
3316
- const FRAMEOPTION_START_CURRENT_ROW = 0x00200; /* start is C. R. */
3317
- const FRAMEOPTION_END_CURRENT_ROW = 0x00400; /* end is C. R. */
3318
- const FRAMEOPTION_START_OFFSET_PRECEDING = 0x00800; /* start is O. P. */
3319
- const FRAMEOPTION_END_OFFSET_PRECEDING = 0x01000; /* end is O. P. */
3320
- const FRAMEOPTION_START_OFFSET_FOLLOWING = 0x02000; /* start is O. F. */
3321
- const FRAMEOPTION_END_OFFSET_FOLLOWING = 0x04000; /* end is O. F. */
3322
- const FRAMEOPTION_EXCLUDE_CURRENT_ROW = 0x08000; /* omit C.R. */
3323
- const FRAMEOPTION_EXCLUDE_GROUP = 0x10000; /* omit C.R. & peers */
3324
- const FRAMEOPTION_EXCLUDE_TIES = 0x20000; /* omit C.R.'s peers */
3325
- // const FRAMEOPTION_START_OFFSET =
3326
- // FRAMEOPTION_START_OFFSET_PRECEDING | FRAMEOPTION_START_OFFSET_FOLLOWING;
3327
- // const FRAMEOPTION_END_OFFSET =
3328
- // FRAMEOPTION_END_OFFSET_PRECEDING | FRAMEOPTION_END_OFFSET_FOLLOWING;
3329
- // const FRAMEOPTION_EXCLUSION =
3330
- // FRAMEOPTION_EXCLUDE_CURRENT_ROW |
3331
- // FRAMEOPTION_EXCLUDE_GROUP |
3332
- // FRAMEOPTION_EXCLUDE_TIES;
3333
- // const FRAMEOPTION_DEFAULTS =
3334
- // FRAMEOPTION_RANGE |
3335
- // FRAMEOPTION_START_UNBOUNDED_PRECEDING |
3336
- // FRAMEOPTION_END_CURRENT_ROW;
3337
- if (!(options & FRAMEOPTION_NONDEFAULT)) {
3338
- return '';
3339
- }
3340
- const output = [];
3341
- if (refName != null) {
3342
- output.push(refName);
3343
- }
3344
- if (options & FRAMEOPTION_RANGE) {
3345
- output.push('RANGE');
3346
- }
3347
- if (options & FRAMEOPTION_ROWS) {
3348
- output.push('ROWS');
3349
- }
3350
- const between = options & FRAMEOPTION_BETWEEN;
3351
- if (between) {
3352
- output.push('BETWEEN');
3353
- }
3354
- if (options & FRAMEOPTION_START_UNBOUNDED_PRECEDING) {
3355
- output.push('UNBOUNDED PRECEDING');
3356
- }
3357
- if (options & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) {
3358
- output.push('UNBOUNDED FOLLOWING');
3359
- }
3360
- if (options & FRAMEOPTION_START_CURRENT_ROW) {
3361
- output.push('CURRENT ROW');
3362
- }
3363
- if (options & FRAMEOPTION_START_OFFSET_PRECEDING) {
3364
- output.push(this.deparse(startOffset) + ' PRECEDING');
3365
- }
3366
- if (options & FRAMEOPTION_START_OFFSET_FOLLOWING) {
3367
- output.push(this.deparse(startOffset) + ' FOLLOWING');
3368
- }
3369
- if (between) {
3370
- output.push('AND');
3371
- if (options & FRAMEOPTION_END_UNBOUNDED_PRECEDING) {
3372
- output.push('UNBOUNDED PRECEDING');
3373
- }
3374
- if (options & FRAMEOPTION_END_UNBOUNDED_FOLLOWING) {
3375
- output.push('UNBOUNDED FOLLOWING');
3376
- }
3377
- if (options & FRAMEOPTION_END_CURRENT_ROW) {
3378
- output.push('CURRENT ROW');
3379
- }
3380
- if (options & FRAMEOPTION_END_OFFSET_PRECEDING) {
3381
- output.push(this.deparse(endOffset) + ' PRECEDING');
3382
- }
3383
- if (options & FRAMEOPTION_END_OFFSET_FOLLOWING) {
3384
- output.push(this.deparse(endOffset) + ' FOLLOWING');
3385
- }
3386
- }
3387
- return output.join(' ');
3388
- }
3389
- deparseInterval(node) {
3390
- const type = ['interval'];
3391
- if (node.arrayBounds != null) {
3392
- type.push('[]');
3393
- }
3394
- if (node.typmods) {
3395
- const nodeTypmods = unwrapList(node.typmods);
3396
- const typmods = nodeTypmods.map((item) => this.deparse(item));
3397
- let intervals = this.interval(typmods[0]);
3398
- // SELECT interval(0) '1 day 01:23:45.6789'
3399
- if (nodeTypmods[0] &&
3400
- nodeTypmods[0].A_Const &&
3401
- nodeTypmods[0].A_Const.val.Integer.ival === 32767 &&
3402
- nodeTypmods[1] &&
3403
- nodeTypmods[1].A_Const != null) {
3404
- intervals = [`(${nodeTypmods[1].A_Const.val.Integer.ival})`];
3405
- }
3406
- else {
3407
- intervals = unwrapList(intervals).map((part) => {
3408
- if (part === 'second' && typmods.length === 2) {
3409
- return 'second(' + typmods[typmods.length - 1] + ')';
3410
- }
3411
- return part;
3412
- });
3413
- }
3414
- type.push(intervals.join(' to '));
3415
- }
3416
- return type.join(' ');
3417
- }
3418
- interval(mask) {
3419
- // ported from https://github.com/lfittl/pg_query/blob/master/lib/pg_query/deparse/interval.rb
3420
- if (this.MASKS == null) {
3421
- this.MASKS = {
3422
- 0: 'RESERV',
3423
- 1: 'MONTH',
3424
- 2: 'YEAR',
3425
- 3: 'DAY',
3426
- 4: 'JULIAN',
3427
- 5: 'TZ',
3428
- 6: 'DTZ',
3429
- 7: 'DYNTZ',
3430
- 8: 'IGNORE_DTF',
3431
- 9: 'AMPM',
3432
- 10: 'HOUR',
3433
- 11: 'MINUTE',
3434
- 12: 'SECOND',
3435
- 13: 'MILLISECOND',
3436
- 14: 'MICROSECOND',
3437
- 15: 'DOY',
3438
- 16: 'DOW',
3439
- 17: 'UNITS',
3440
- 18: 'ADBC',
3441
- 19: 'AGO',
3442
- 20: 'ABS_BEFORE',
3443
- 21: 'ABS_AFTER',
3444
- 22: 'ISODATE',
3445
- 23: 'ISOTIME',
3446
- 24: 'WEEK',
3447
- 25: 'DECADE',
3448
- 26: 'CENTURY',
3449
- 27: 'MILLENNIUM',
3450
- 28: 'DTZMOD'
3451
- };
3452
- }
3453
- if (this.BITS == null) {
3454
- this.BITS = inverted(this.MASKS);
3455
- }
3456
- if (this.INTERVALS == null) {
3457
- this.INTERVALS = {};
3458
- this.INTERVALS[1 << this.BITS.YEAR] = ['year'];
3459
- this.INTERVALS[1 << this.BITS.MONTH] = ['month'];
3460
- this.INTERVALS[1 << this.BITS.DAY] = ['day'];
3461
- this.INTERVALS[1 << this.BITS.HOUR] = ['hour'];
3462
- this.INTERVALS[1 << this.BITS.MINUTE] = ['minute'];
3463
- this.INTERVALS[1 << this.BITS.SECOND] = ['second'];
3464
- this.INTERVALS[(1 << this.BITS.YEAR) | (1 << this.BITS.MONTH)] = [
3465
- 'year',
3466
- 'month'
3467
- ];
3468
- this.INTERVALS[(1 << this.BITS.DAY) | (1 << this.BITS.HOUR)] = [
3469
- 'day',
3470
- 'hour'
3471
- ];
3472
- this.INTERVALS[(1 << this.BITS.DAY) | (1 << this.BITS.HOUR) | (1 << this.BITS.MINUTE)] = ['day', 'minute'];
3473
- this.INTERVALS[(1 << this.BITS.DAY) |
3474
- (1 << this.BITS.HOUR) |
3475
- (1 << this.BITS.MINUTE) |
3476
- (1 << this.BITS.SECOND)] = ['day', 'second'];
3477
- this.INTERVALS[(1 << this.BITS.HOUR) | (1 << this.BITS.MINUTE)] = [
3478
- 'hour',
3479
- 'minute'
3480
- ];
3481
- this.INTERVALS[(1 << this.BITS.HOUR) |
3482
- (1 << this.BITS.MINUTE) |
3483
- (1 << this.BITS.SECOND)] = ['hour', 'second'];
3484
- this.INTERVALS[(1 << this.BITS.MINUTE) | (1 << this.BITS.SECOND)] = [
3485
- 'minute',
3486
- 'second'
3487
- ];
3488
- // utils/timestamp.h
3489
- // #define INTERVAL_FULL_RANGE (0x7FFF)
3490
- this.INTERVALS[(this.INTERVAL_FULL_RANGE = '32767')] = [];
3491
- }
3492
- return this.INTERVALS[mask.toString()];
3493
- }
3494
- }
3495
- exports.default = Deparser;