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