pgsql-deparser 17.8.0 → 17.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deparser.d.ts +2 -0
- package/deparser.js +543 -163
- package/esm/deparser.js +543 -163
- package/package.json +3 -3
- package/visitors/base.d.ts +1 -0
package/esm/deparser.js
CHANGED
|
@@ -1,6 +1,62 @@
|
|
|
1
1
|
import { SqlFormatter } from './utils/sql-formatter';
|
|
2
2
|
import { QuoteUtils } from './utils/quote-utils';
|
|
3
3
|
import { ListUtils } from './utils/list-utils';
|
|
4
|
+
/**
|
|
5
|
+
* List of real PostgreSQL built-in types as they appear in pg_catalog.pg_type.typname.
|
|
6
|
+
* These are stored in lowercase in PostgreSQL system catalogs.
|
|
7
|
+
* Use these for lookups, validations, or introspection logic.
|
|
8
|
+
*/
|
|
9
|
+
const pgCatalogTypes = [
|
|
10
|
+
// Integers
|
|
11
|
+
'int2', // smallint
|
|
12
|
+
'int4', // integer
|
|
13
|
+
'int8', // bigint
|
|
14
|
+
// Floating-point & numeric
|
|
15
|
+
'float4', // real
|
|
16
|
+
'float8', // double precision
|
|
17
|
+
'numeric', // arbitrary precision (aka "decimal")
|
|
18
|
+
// Text & string
|
|
19
|
+
'varchar', // variable-length string
|
|
20
|
+
'char', // internal one-byte type (used in special cases)
|
|
21
|
+
'bpchar', // blank-padded char(n)
|
|
22
|
+
'text', // unlimited string
|
|
23
|
+
'bool', // boolean
|
|
24
|
+
// Dates & times
|
|
25
|
+
'date', // calendar date
|
|
26
|
+
'time', // time without time zone
|
|
27
|
+
'timetz', // time with time zone
|
|
28
|
+
'timestamp', // timestamp without time zone
|
|
29
|
+
'timestamptz', // timestamp with time zone
|
|
30
|
+
'interval', // duration
|
|
31
|
+
// Binary & structured
|
|
32
|
+
'bytea', // binary data
|
|
33
|
+
'uuid', // universally unique identifier
|
|
34
|
+
// JSON & XML
|
|
35
|
+
'json', // textual JSON
|
|
36
|
+
'jsonb', // binary JSON
|
|
37
|
+
'xml', // XML format
|
|
38
|
+
// Money & bitstrings
|
|
39
|
+
'money', // currency value
|
|
40
|
+
'bit', // fixed-length bit string
|
|
41
|
+
'varbit', // variable-length bit string
|
|
42
|
+
// Network types
|
|
43
|
+
'inet', // IPv4 or IPv6 address
|
|
44
|
+
'cidr', // network address
|
|
45
|
+
'macaddr', // MAC address (6 bytes)
|
|
46
|
+
'macaddr8' // MAC address (8 bytes)
|
|
47
|
+
];
|
|
48
|
+
/**
|
|
49
|
+
* Parser-level type aliases accepted by PostgreSQL SQL syntax,
|
|
50
|
+
* but not present in pg_catalog.pg_type. These are resolved to
|
|
51
|
+
* real types during parsing and never appear in introspection.
|
|
52
|
+
*/
|
|
53
|
+
const pgCatalogTypeAliases = [
|
|
54
|
+
['numeric', ['decimal', 'dec']],
|
|
55
|
+
['int4', ['int', 'integer']],
|
|
56
|
+
['float8', ['float']],
|
|
57
|
+
['bpchar', ['character']],
|
|
58
|
+
['varchar', ['character varying']]
|
|
59
|
+
];
|
|
4
60
|
// Type guards for better type safety
|
|
5
61
|
function isParseResult(obj) {
|
|
6
62
|
// A ParseResult is an object that could have stmts (but not required)
|
|
@@ -258,17 +314,36 @@ export class Deparser {
|
|
|
258
314
|
if (node.targetList) {
|
|
259
315
|
const targetList = ListUtils.unwrapList(node.targetList);
|
|
260
316
|
if (this.formatter.isPretty()) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const
|
|
264
|
-
if
|
|
265
|
-
|
|
317
|
+
if (targetList.length === 1) {
|
|
318
|
+
const targetNode = targetList[0];
|
|
319
|
+
const target = this.visit(targetNode, { ...context, select: true });
|
|
320
|
+
// Check if single target is complex - if so, use multiline format
|
|
321
|
+
if (this.isComplexSelectTarget(targetNode)) {
|
|
322
|
+
output.push('SELECT' + distinctPart);
|
|
323
|
+
if (this.containsMultilineStringLiteral(target)) {
|
|
324
|
+
output.push(target);
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
output.push(this.formatter.indent(target));
|
|
328
|
+
}
|
|
266
329
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
330
|
+
else {
|
|
331
|
+
output.push('SELECT' + distinctPart + ' ' + target);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
const targetStrings = targetList
|
|
336
|
+
.map(e => {
|
|
337
|
+
const targetStr = this.visit(e, { ...context, select: true });
|
|
338
|
+
if (this.containsMultilineStringLiteral(targetStr)) {
|
|
339
|
+
return targetStr;
|
|
340
|
+
}
|
|
341
|
+
return this.formatter.indent(targetStr);
|
|
342
|
+
});
|
|
343
|
+
const formattedTargets = targetStrings.join(',' + this.formatter.newline());
|
|
344
|
+
output.push('SELECT' + distinctPart);
|
|
345
|
+
output.push(formattedTargets);
|
|
346
|
+
}
|
|
272
347
|
}
|
|
273
348
|
else {
|
|
274
349
|
const targets = targetList
|
|
@@ -307,12 +382,28 @@ export class Deparser {
|
|
|
307
382
|
}
|
|
308
383
|
}
|
|
309
384
|
if (node.valuesLists) {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
385
|
+
if (this.formatter.isPretty()) {
|
|
386
|
+
output.push('VALUES');
|
|
387
|
+
const lists = ListUtils.unwrapList(node.valuesLists).map(list => {
|
|
388
|
+
const values = ListUtils.unwrapList(list).map(val => this.visit(val, context));
|
|
389
|
+
return this.formatter.parens(values.join(', '));
|
|
390
|
+
});
|
|
391
|
+
const indentedTuples = lists.map(tuple => {
|
|
392
|
+
if (this.containsMultilineStringLiteral(tuple)) {
|
|
393
|
+
return tuple;
|
|
394
|
+
}
|
|
395
|
+
return this.formatter.indent(tuple);
|
|
396
|
+
});
|
|
397
|
+
output.push(indentedTuples.join(',\n'));
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
output.push('VALUES');
|
|
401
|
+
const lists = ListUtils.unwrapList(node.valuesLists).map(list => {
|
|
402
|
+
const values = ListUtils.unwrapList(list).map(val => this.visit(val, context));
|
|
403
|
+
return this.formatter.parens(values.join(', '));
|
|
404
|
+
});
|
|
405
|
+
output.push(lists.join(', '));
|
|
406
|
+
}
|
|
316
407
|
}
|
|
317
408
|
if (node.groupClause) {
|
|
318
409
|
const groupList = ListUtils.unwrapList(node.groupClause);
|
|
@@ -681,6 +772,64 @@ export class Deparser {
|
|
|
681
772
|
node.SubLink ||
|
|
682
773
|
node.A_Expr);
|
|
683
774
|
}
|
|
775
|
+
isComplexSelectTarget(node) {
|
|
776
|
+
if (!node)
|
|
777
|
+
return false;
|
|
778
|
+
if (node.ResTarget?.val) {
|
|
779
|
+
return this.isComplexExpression(node.ResTarget.val);
|
|
780
|
+
}
|
|
781
|
+
// Always complex: CASE expressions
|
|
782
|
+
if (node.CaseExpr)
|
|
783
|
+
return true;
|
|
784
|
+
// Always complex: Subqueries and subselects
|
|
785
|
+
if (node.SubLink)
|
|
786
|
+
return true;
|
|
787
|
+
// Always complex: Boolean tests and expressions
|
|
788
|
+
if (node.NullTest || node.BooleanTest || node.BoolExpr)
|
|
789
|
+
return true;
|
|
790
|
+
// COALESCE and similar functions - complex if multiple arguments
|
|
791
|
+
if (node.CoalesceExpr) {
|
|
792
|
+
const args = node.CoalesceExpr.args;
|
|
793
|
+
if (args && Array.isArray(args) && args.length > 1)
|
|
794
|
+
return true;
|
|
795
|
+
}
|
|
796
|
+
// Function calls - complex if multiple args or has clauses
|
|
797
|
+
if (node.FuncCall) {
|
|
798
|
+
const funcCall = node.FuncCall;
|
|
799
|
+
const args = funcCall.args ? (Array.isArray(funcCall.args) ? funcCall.args : [funcCall.args]) : [];
|
|
800
|
+
// Complex if has window clause, filter, order by, etc.
|
|
801
|
+
if (funcCall.over || funcCall.agg_filter || funcCall.agg_order || funcCall.agg_distinct) {
|
|
802
|
+
return true;
|
|
803
|
+
}
|
|
804
|
+
// Complex if multiple arguments
|
|
805
|
+
if (args.length > 1)
|
|
806
|
+
return true;
|
|
807
|
+
if (args.length === 1) {
|
|
808
|
+
return this.isComplexSelectTarget(args[0]);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
if (node.A_Expr) {
|
|
812
|
+
const expr = node.A_Expr;
|
|
813
|
+
// Check if operands are complex
|
|
814
|
+
if (expr.lexpr && this.isComplexSelectTarget(expr.lexpr))
|
|
815
|
+
return true;
|
|
816
|
+
if (expr.rexpr && this.isComplexSelectTarget(expr.rexpr))
|
|
817
|
+
return true;
|
|
818
|
+
return false;
|
|
819
|
+
}
|
|
820
|
+
if (node.TypeCast) {
|
|
821
|
+
return this.isComplexSelectTarget(node.TypeCast.arg);
|
|
822
|
+
}
|
|
823
|
+
if (node.A_ArrayExpr)
|
|
824
|
+
return true;
|
|
825
|
+
if (node.A_Indirection) {
|
|
826
|
+
return this.isComplexSelectTarget(node.A_Indirection.arg);
|
|
827
|
+
}
|
|
828
|
+
if (node.A_Const || node.ColumnRef || node.ParamRef || node.A_Star) {
|
|
829
|
+
return false;
|
|
830
|
+
}
|
|
831
|
+
return false;
|
|
832
|
+
}
|
|
684
833
|
visitBetweenRange(rexpr, context) {
|
|
685
834
|
if (rexpr && 'List' in rexpr && rexpr.List?.items) {
|
|
686
835
|
const items = rexpr.List.items.map((item) => this.visit(item, context));
|
|
@@ -699,7 +848,14 @@ export class Deparser {
|
|
|
699
848
|
const cols = ListUtils.unwrapList(node.cols);
|
|
700
849
|
const insertContext = { ...context, insertColumns: true };
|
|
701
850
|
const columnNames = cols.map(col => this.visit(col, insertContext));
|
|
702
|
-
|
|
851
|
+
if (this.formatter.isPretty()) {
|
|
852
|
+
// Always format columns in multiline parentheses for pretty printing
|
|
853
|
+
const indentedColumns = columnNames.map(col => this.formatter.indent(col));
|
|
854
|
+
output.push('(\n' + indentedColumns.join(',\n') + '\n)');
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
output.push(this.formatter.parens(columnNames.join(', ')));
|
|
858
|
+
}
|
|
703
859
|
}
|
|
704
860
|
if (node.selectStmt) {
|
|
705
861
|
output.push(this.visit(node.selectStmt, context));
|
|
@@ -893,14 +1049,15 @@ export class Deparser {
|
|
|
893
1049
|
if (node.ctes && node.ctes.length > 0) {
|
|
894
1050
|
const ctes = ListUtils.unwrapList(node.ctes);
|
|
895
1051
|
if (this.formatter.isPretty()) {
|
|
896
|
-
const cteStrings = ctes.map(cte => {
|
|
1052
|
+
const cteStrings = ctes.map((cte, index) => {
|
|
897
1053
|
const cteStr = this.visit(cte, context);
|
|
1054
|
+
const prefix = index === 0 ? this.formatter.newline() : ',' + this.formatter.newline();
|
|
898
1055
|
if (this.containsMultilineStringLiteral(cteStr)) {
|
|
899
|
-
return
|
|
1056
|
+
return prefix + cteStr;
|
|
900
1057
|
}
|
|
901
|
-
return
|
|
1058
|
+
return prefix + this.formatter.indent(cteStr);
|
|
902
1059
|
});
|
|
903
|
-
output.push(cteStrings.join('
|
|
1060
|
+
output.push(cteStrings.join(''));
|
|
904
1061
|
}
|
|
905
1062
|
else {
|
|
906
1063
|
const cteStrings = ctes.map(cte => this.visit(cte, context));
|
|
@@ -1208,7 +1365,13 @@ export class Deparser {
|
|
|
1208
1365
|
windowParts.push(frameClause);
|
|
1209
1366
|
}
|
|
1210
1367
|
if (windowParts.length > 0) {
|
|
1211
|
-
|
|
1368
|
+
if (this.formatter.isPretty() && windowParts.length > 1) {
|
|
1369
|
+
const formattedParts = windowParts.map(part => this.formatter.indent(part));
|
|
1370
|
+
result += ` OVER (${this.formatter.newline()}${formattedParts.join(this.formatter.newline())}${this.formatter.newline()})`;
|
|
1371
|
+
}
|
|
1372
|
+
else {
|
|
1373
|
+
result += ` OVER (${windowParts.join(' ')})`;
|
|
1374
|
+
}
|
|
1212
1375
|
}
|
|
1213
1376
|
else {
|
|
1214
1377
|
result += ` OVER ()`;
|
|
@@ -1484,9 +1647,6 @@ export class Deparser {
|
|
|
1484
1647
|
return output.join(' ');
|
|
1485
1648
|
}
|
|
1486
1649
|
if (catalog === 'pg_catalog') {
|
|
1487
|
-
const builtinTypes = ['int2', 'int4', 'int8', 'float4', 'float8', 'numeric', 'decimal',
|
|
1488
|
-
'varchar', 'char', 'bpchar', 'text', 'bool', 'date', 'time', 'timestamp',
|
|
1489
|
-
'timestamptz', 'interval', 'bytea', 'uuid', 'json', 'jsonb'];
|
|
1490
1650
|
let typeName = `${catalog}.${type}`;
|
|
1491
1651
|
if (type === 'bpchar' && args) {
|
|
1492
1652
|
typeName = 'char';
|
|
@@ -1781,6 +1941,18 @@ export class Deparser {
|
|
|
1781
1941
|
return `pg_catalog.${typeName}`;
|
|
1782
1942
|
}
|
|
1783
1943
|
}
|
|
1944
|
+
isPgCatalogType(typeName) {
|
|
1945
|
+
const cleanTypeName = typeName.replace(/^pg_catalog\./, '');
|
|
1946
|
+
if (pgCatalogTypes.includes(cleanTypeName)) {
|
|
1947
|
+
return true;
|
|
1948
|
+
}
|
|
1949
|
+
for (const [realType, aliases] of pgCatalogTypeAliases) {
|
|
1950
|
+
if (aliases.includes(cleanTypeName)) {
|
|
1951
|
+
return true;
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
return false;
|
|
1955
|
+
}
|
|
1784
1956
|
A_ArrayExpr(node, context) {
|
|
1785
1957
|
const elements = ListUtils.unwrapList(node.elements);
|
|
1786
1958
|
const elementStrs = elements.map(el => this.visit(el, context));
|
|
@@ -1832,15 +2004,39 @@ export class Deparser {
|
|
|
1832
2004
|
output.push(this.visit(node.arg, context));
|
|
1833
2005
|
}
|
|
1834
2006
|
const args = ListUtils.unwrapList(node.args);
|
|
1835
|
-
|
|
1836
|
-
|
|
2007
|
+
if (this.formatter.isPretty() && args.length > 0) {
|
|
2008
|
+
for (const arg of args) {
|
|
2009
|
+
const whenClause = this.visit(arg, context);
|
|
2010
|
+
if (this.containsMultilineStringLiteral(whenClause)) {
|
|
2011
|
+
output.push(this.formatter.newline() + whenClause);
|
|
2012
|
+
}
|
|
2013
|
+
else {
|
|
2014
|
+
output.push(this.formatter.newline() + this.formatter.indent(whenClause));
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
if (node.defresult) {
|
|
2018
|
+
const elseResult = this.visit(node.defresult, context);
|
|
2019
|
+
if (this.containsMultilineStringLiteral(elseResult)) {
|
|
2020
|
+
output.push(this.formatter.newline() + 'ELSE ' + elseResult);
|
|
2021
|
+
}
|
|
2022
|
+
else {
|
|
2023
|
+
output.push(this.formatter.newline() + this.formatter.indent('ELSE ' + elseResult));
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
output.push(this.formatter.newline() + 'END');
|
|
2027
|
+
return output.join(' ');
|
|
1837
2028
|
}
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
2029
|
+
else {
|
|
2030
|
+
for (const arg of args) {
|
|
2031
|
+
output.push(this.visit(arg, context));
|
|
2032
|
+
}
|
|
2033
|
+
if (node.defresult) {
|
|
2034
|
+
output.push('ELSE');
|
|
2035
|
+
output.push(this.visit(node.defresult, context));
|
|
2036
|
+
}
|
|
2037
|
+
output.push('END');
|
|
2038
|
+
return output.join(' ');
|
|
1841
2039
|
}
|
|
1842
|
-
output.push('END');
|
|
1843
|
-
return output.join(' ');
|
|
1844
2040
|
}
|
|
1845
2041
|
CoalesceExpr(node, context) {
|
|
1846
2042
|
const args = ListUtils.unwrapList(node.args);
|
|
@@ -1850,28 +2046,29 @@ export class Deparser {
|
|
|
1850
2046
|
TypeCast(node, context) {
|
|
1851
2047
|
const arg = this.visit(node.arg, context);
|
|
1852
2048
|
const typeName = this.TypeName(node.typeName, context);
|
|
1853
|
-
// Check if this is a bpchar typecast that should
|
|
1854
|
-
if (typeName === 'bpchar'
|
|
1855
|
-
const names =
|
|
1856
|
-
|
|
1857
|
-
names[0]
|
|
1858
|
-
names[1]
|
|
1859
|
-
|
|
2049
|
+
// Check if this is a bpchar typecast that should preserve original syntax for AST consistency
|
|
2050
|
+
if (typeName === 'bpchar' || typeName === 'pg_catalog.bpchar') {
|
|
2051
|
+
const names = node.typeName?.names;
|
|
2052
|
+
const isQualifiedBpchar = names && names.length === 2 &&
|
|
2053
|
+
names[0]?.String?.sval === 'pg_catalog' &&
|
|
2054
|
+
names[1]?.String?.sval === 'bpchar';
|
|
2055
|
+
if (isQualifiedBpchar) {
|
|
2056
|
+
return `CAST(${arg} AS ${typeName})`;
|
|
1860
2057
|
}
|
|
1861
2058
|
}
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
2059
|
+
if (this.isPgCatalogType(typeName)) {
|
|
2060
|
+
const argType = this.getNodeType(node.arg);
|
|
2061
|
+
const isSimpleArgument = argType === 'A_Const' || argType === 'ColumnRef';
|
|
2062
|
+
const isFunctionCall = argType === 'FuncCall';
|
|
2063
|
+
if (isSimpleArgument || isFunctionCall) {
|
|
2064
|
+
// For simple arguments, avoid :: syntax if they have complex structure
|
|
2065
|
+
if (isSimpleArgument && (arg.includes('(') || arg.startsWith('-'))) {
|
|
2066
|
+
}
|
|
2067
|
+
else {
|
|
2068
|
+
const cleanTypeName = typeName.replace('pg_catalog.', '');
|
|
2069
|
+
return `${arg}::${cleanTypeName}`;
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
1875
2072
|
}
|
|
1876
2073
|
return `CAST(${arg} AS ${typeName})`;
|
|
1877
2074
|
}
|
|
@@ -2054,7 +2251,14 @@ export class Deparser {
|
|
|
2054
2251
|
return this.deparse(el, context);
|
|
2055
2252
|
});
|
|
2056
2253
|
if (this.formatter.isPretty()) {
|
|
2057
|
-
const formattedElements = elementStrs.map(el =>
|
|
2254
|
+
const formattedElements = elementStrs.map(el => {
|
|
2255
|
+
const trimmedEl = el.trim();
|
|
2256
|
+
// Remove leading newlines from constraint elements to avoid extra blank lines
|
|
2257
|
+
if (trimmedEl.startsWith('\n')) {
|
|
2258
|
+
return this.formatter.indent(trimmedEl.substring(1));
|
|
2259
|
+
}
|
|
2260
|
+
return this.formatter.indent(trimmedEl);
|
|
2261
|
+
}).join(',' + this.formatter.newline());
|
|
2058
2262
|
output.push('(' + this.formatter.newline() + formattedElements + this.formatter.newline() + ')');
|
|
2059
2263
|
}
|
|
2060
2264
|
else {
|
|
@@ -2216,9 +2420,25 @@ export class Deparser {
|
|
|
2216
2420
|
}
|
|
2217
2421
|
break;
|
|
2218
2422
|
case 'CONSTR_CHECK':
|
|
2219
|
-
|
|
2423
|
+
if (this.formatter.isPretty() && !context.isColumnConstraint) {
|
|
2424
|
+
output.push('\n' + this.formatter.indent('CHECK'));
|
|
2425
|
+
}
|
|
2426
|
+
else {
|
|
2427
|
+
output.push('CHECK');
|
|
2428
|
+
}
|
|
2220
2429
|
if (node.raw_expr) {
|
|
2221
|
-
|
|
2430
|
+
if (this.formatter.isPretty()) {
|
|
2431
|
+
const checkExpr = this.visit(node.raw_expr, context);
|
|
2432
|
+
if (checkExpr.includes('\n')) {
|
|
2433
|
+
output.push('(\n' + this.formatter.indent(checkExpr) + '\n)');
|
|
2434
|
+
}
|
|
2435
|
+
else {
|
|
2436
|
+
output.push(`(${checkExpr})`);
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
else {
|
|
2440
|
+
output.push(this.formatter.parens(this.visit(node.raw_expr, context)));
|
|
2441
|
+
}
|
|
2222
2442
|
}
|
|
2223
2443
|
// Handle NOT VALID for check constraints
|
|
2224
2444
|
if (node.skip_validation) {
|
|
@@ -2297,7 +2517,12 @@ export class Deparser {
|
|
|
2297
2517
|
}
|
|
2298
2518
|
break;
|
|
2299
2519
|
case 'CONSTR_UNIQUE':
|
|
2300
|
-
|
|
2520
|
+
if (this.formatter.isPretty() && !context.isColumnConstraint) {
|
|
2521
|
+
output.push('\n' + this.formatter.indent('UNIQUE'));
|
|
2522
|
+
}
|
|
2523
|
+
else {
|
|
2524
|
+
output.push('UNIQUE');
|
|
2525
|
+
}
|
|
2301
2526
|
if (node.nulls_not_distinct) {
|
|
2302
2527
|
output.push('NULLS NOT DISTINCT');
|
|
2303
2528
|
}
|
|
@@ -2315,33 +2540,77 @@ export class Deparser {
|
|
|
2315
2540
|
case 'CONSTR_FOREIGN':
|
|
2316
2541
|
// Only add "FOREIGN KEY" for table-level constraints, not column-level constraints
|
|
2317
2542
|
if (!context.isColumnConstraint) {
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2543
|
+
if (this.formatter.isPretty()) {
|
|
2544
|
+
output.push('\n' + this.formatter.indent('FOREIGN KEY'));
|
|
2545
|
+
if (node.fk_attrs && node.fk_attrs.length > 0) {
|
|
2546
|
+
const fkAttrs = ListUtils.unwrapList(node.fk_attrs)
|
|
2547
|
+
.map(attr => this.visit(attr, context))
|
|
2548
|
+
.join(', ');
|
|
2549
|
+
output.push(`(${fkAttrs})`);
|
|
2550
|
+
}
|
|
2551
|
+
output.push('\n' + this.formatter.indent('REFERENCES'));
|
|
2552
|
+
}
|
|
2553
|
+
else {
|
|
2554
|
+
output.push('FOREIGN KEY');
|
|
2555
|
+
if (node.fk_attrs && node.fk_attrs.length > 0) {
|
|
2556
|
+
const fkAttrs = ListUtils.unwrapList(node.fk_attrs)
|
|
2557
|
+
.map(attr => this.visit(attr, context))
|
|
2558
|
+
.join(', ');
|
|
2559
|
+
output.push(`(${fkAttrs})`);
|
|
2560
|
+
}
|
|
2561
|
+
output.push('REFERENCES');
|
|
2324
2562
|
}
|
|
2325
2563
|
}
|
|
2326
|
-
|
|
2564
|
+
else {
|
|
2565
|
+
output.push('REFERENCES');
|
|
2566
|
+
}
|
|
2327
2567
|
if (node.pktable) {
|
|
2328
|
-
|
|
2568
|
+
if (this.formatter.isPretty() && !context.isColumnConstraint) {
|
|
2569
|
+
const lastIndex = output.length - 1;
|
|
2570
|
+
if (lastIndex >= 0 && output[lastIndex].includes('REFERENCES')) {
|
|
2571
|
+
output[lastIndex] += ' ' + this.RangeVar(node.pktable, context);
|
|
2572
|
+
}
|
|
2573
|
+
else {
|
|
2574
|
+
output.push(this.RangeVar(node.pktable, context));
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
else {
|
|
2578
|
+
output.push(this.RangeVar(node.pktable, context));
|
|
2579
|
+
}
|
|
2329
2580
|
}
|
|
2330
2581
|
if (node.pk_attrs && node.pk_attrs.length > 0) {
|
|
2331
2582
|
const pkAttrs = ListUtils.unwrapList(node.pk_attrs)
|
|
2332
2583
|
.map(attr => this.visit(attr, context))
|
|
2333
2584
|
.join(', ');
|
|
2334
|
-
|
|
2585
|
+
if (this.formatter.isPretty() && !context.isColumnConstraint) {
|
|
2586
|
+
const lastIndex = output.length - 1;
|
|
2587
|
+
if (lastIndex >= 0) {
|
|
2588
|
+
output[lastIndex] += ` (${pkAttrs})`;
|
|
2589
|
+
}
|
|
2590
|
+
else {
|
|
2591
|
+
output.push(`(${pkAttrs})`);
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
else {
|
|
2595
|
+
output.push(`(${pkAttrs})`);
|
|
2596
|
+
}
|
|
2335
2597
|
}
|
|
2336
2598
|
if (node.fk_matchtype && node.fk_matchtype !== 's') {
|
|
2599
|
+
let matchClause = '';
|
|
2337
2600
|
switch (node.fk_matchtype) {
|
|
2338
2601
|
case 'f':
|
|
2339
|
-
|
|
2602
|
+
matchClause = 'MATCH FULL';
|
|
2340
2603
|
break;
|
|
2341
2604
|
case 'p':
|
|
2342
|
-
|
|
2605
|
+
matchClause = 'MATCH PARTIAL';
|
|
2343
2606
|
break;
|
|
2344
2607
|
}
|
|
2608
|
+
if (this.formatter.isPretty() && !context.isColumnConstraint) {
|
|
2609
|
+
output.push('\n' + this.formatter.indent(matchClause));
|
|
2610
|
+
}
|
|
2611
|
+
else {
|
|
2612
|
+
output.push(matchClause);
|
|
2613
|
+
}
|
|
2345
2614
|
}
|
|
2346
2615
|
if (node.fk_upd_action && node.fk_upd_action !== 'a') {
|
|
2347
2616
|
let updateClause = 'ON UPDATE ';
|
|
@@ -2393,7 +2662,12 @@ export class Deparser {
|
|
|
2393
2662
|
}
|
|
2394
2663
|
// Handle NOT VALID for foreign key constraints - only for table constraints, not domain constraints
|
|
2395
2664
|
if (node.skip_validation && !context.isDomainConstraint) {
|
|
2396
|
-
|
|
2665
|
+
if (this.formatter.isPretty() && !context.isColumnConstraint) {
|
|
2666
|
+
output.push('\n' + this.formatter.indent('NOT VALID'));
|
|
2667
|
+
}
|
|
2668
|
+
else {
|
|
2669
|
+
output.push('NOT VALID');
|
|
2670
|
+
}
|
|
2397
2671
|
}
|
|
2398
2672
|
break;
|
|
2399
2673
|
case 'CONSTR_ATTR_DEFERRABLE':
|
|
@@ -3265,11 +3539,23 @@ export class Deparser {
|
|
|
3265
3539
|
}
|
|
3266
3540
|
}
|
|
3267
3541
|
else if (node.quals) {
|
|
3542
|
+
const qualsStr = this.visit(node.quals, context);
|
|
3268
3543
|
if (this.formatter.isPretty()) {
|
|
3269
|
-
|
|
3544
|
+
// For complex JOIN conditions, format with proper indentation
|
|
3545
|
+
if (qualsStr.includes('AND') || qualsStr.includes('OR') || qualsStr.length > 50) {
|
|
3546
|
+
if (this.containsMultilineStringLiteral(qualsStr)) {
|
|
3547
|
+
output.push(` ON ${qualsStr}`);
|
|
3548
|
+
}
|
|
3549
|
+
else {
|
|
3550
|
+
output.push(` ON${this.formatter.newline()}${this.formatter.indent(qualsStr)}`);
|
|
3551
|
+
}
|
|
3552
|
+
}
|
|
3553
|
+
else {
|
|
3554
|
+
output.push(` ON ${qualsStr}`);
|
|
3555
|
+
}
|
|
3270
3556
|
}
|
|
3271
3557
|
else {
|
|
3272
|
-
output.push(`ON ${
|
|
3558
|
+
output.push(`ON ${qualsStr}`);
|
|
3273
3559
|
}
|
|
3274
3560
|
}
|
|
3275
3561
|
let result;
|
|
@@ -3380,8 +3666,8 @@ export class Deparser {
|
|
|
3380
3666
|
else if (nodeData.sval !== undefined) {
|
|
3381
3667
|
// Handle nested sval structure: { sval: { sval: "value" } }
|
|
3382
3668
|
const svalValue = typeof nodeData.sval === 'object' ? nodeData.sval.sval : nodeData.sval;
|
|
3383
|
-
const stringValue = svalValue.replace(/'/g, '')
|
|
3384
|
-
boolValue = stringValue === 'on' || stringValue === 'true';
|
|
3669
|
+
const stringValue = svalValue.replace(/'/g, '');
|
|
3670
|
+
boolValue = stringValue.toLowerCase() === 'on' || stringValue.toLowerCase() === 'true';
|
|
3385
3671
|
}
|
|
3386
3672
|
}
|
|
3387
3673
|
return boolValue ? 'READ ONLY' : 'READ WRITE';
|
|
@@ -3404,8 +3690,8 @@ export class Deparser {
|
|
|
3404
3690
|
else if (nodeData.sval !== undefined) {
|
|
3405
3691
|
// Handle nested sval structure: { sval: { sval: "value" } }
|
|
3406
3692
|
const svalValue = typeof nodeData.sval === 'object' ? nodeData.sval.sval : nodeData.sval;
|
|
3407
|
-
const stringValue = svalValue.replace(/'/g, '')
|
|
3408
|
-
boolValue = stringValue === 'on' || stringValue === 'true';
|
|
3693
|
+
const stringValue = svalValue.replace(/'/g, '');
|
|
3694
|
+
boolValue = stringValue.toLowerCase() === 'on' || stringValue.toLowerCase() === 'true';
|
|
3409
3695
|
}
|
|
3410
3696
|
}
|
|
3411
3697
|
return boolValue ? 'DEFERRABLE' : 'NOT DEFERRABLE';
|
|
@@ -3472,8 +3758,8 @@ export class Deparser {
|
|
|
3472
3758
|
else if (nodeData.sval !== undefined) {
|
|
3473
3759
|
// Handle nested sval structure: { sval: { sval: "value" } }
|
|
3474
3760
|
const svalValue = typeof nodeData.sval === 'object' ? nodeData.sval.sval : nodeData.sval;
|
|
3475
|
-
const stringValue = svalValue.replace(/'/g, '')
|
|
3476
|
-
boolValue = stringValue === 'on' || stringValue === 'true';
|
|
3761
|
+
const stringValue = svalValue.replace(/'/g, '');
|
|
3762
|
+
boolValue = stringValue.toLowerCase() === 'on' || stringValue.toLowerCase() === 'true';
|
|
3477
3763
|
}
|
|
3478
3764
|
}
|
|
3479
3765
|
transactionOptions.push(boolValue ? 'READ ONLY' : 'READ WRITE');
|
|
@@ -3491,8 +3777,8 @@ export class Deparser {
|
|
|
3491
3777
|
else if (nodeData.sval !== undefined) {
|
|
3492
3778
|
// Handle nested sval structure: { sval: { sval: "value" } }
|
|
3493
3779
|
const svalValue = typeof nodeData.sval === 'object' ? nodeData.sval.sval : nodeData.sval;
|
|
3494
|
-
const stringValue = svalValue.replace(/'/g, '')
|
|
3495
|
-
boolValue = stringValue === 'on' || stringValue === 'true';
|
|
3780
|
+
const stringValue = svalValue.replace(/'/g, '');
|
|
3781
|
+
boolValue = stringValue.toLowerCase() === 'on' || stringValue.toLowerCase() === 'true';
|
|
3496
3782
|
}
|
|
3497
3783
|
}
|
|
3498
3784
|
transactionOptions.push(boolValue ? 'DEFERRABLE' : 'NOT DEFERRABLE');
|
|
@@ -3558,7 +3844,7 @@ export class Deparser {
|
|
|
3558
3844
|
}
|
|
3559
3845
|
switch (node.roletype) {
|
|
3560
3846
|
case 'ROLESPEC_PUBLIC':
|
|
3561
|
-
return '
|
|
3847
|
+
return 'PUBLIC';
|
|
3562
3848
|
case 'ROLESPEC_CURRENT_USER':
|
|
3563
3849
|
return 'CURRENT_USER';
|
|
3564
3850
|
case 'ROLESPEC_SESSION_USER':
|
|
@@ -3566,7 +3852,7 @@ export class Deparser {
|
|
|
3566
3852
|
case 'ROLESPEC_CURRENT_ROLE':
|
|
3567
3853
|
return 'CURRENT_ROLE';
|
|
3568
3854
|
default:
|
|
3569
|
-
return '
|
|
3855
|
+
return 'PUBLIC';
|
|
3570
3856
|
}
|
|
3571
3857
|
}
|
|
3572
3858
|
roletype(node, context) {
|
|
@@ -4030,10 +4316,25 @@ export class Deparser {
|
|
|
4030
4316
|
output.push(relationStr);
|
|
4031
4317
|
}
|
|
4032
4318
|
if (node.cmds && node.cmds.length > 0) {
|
|
4033
|
-
const
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4319
|
+
const commands = ListUtils.unwrapList(node.cmds);
|
|
4320
|
+
if (this.formatter.isPretty()) {
|
|
4321
|
+
const commandsStr = commands
|
|
4322
|
+
.map(cmd => {
|
|
4323
|
+
const cmdStr = this.visit(cmd, alterContext);
|
|
4324
|
+
if (cmdStr.startsWith('ADD CONSTRAINT') || cmdStr.startsWith('ADD ')) {
|
|
4325
|
+
return this.formatter.newline() + this.formatter.indent(cmdStr);
|
|
4326
|
+
}
|
|
4327
|
+
return cmdStr;
|
|
4328
|
+
})
|
|
4329
|
+
.join(',');
|
|
4330
|
+
output.push(commandsStr);
|
|
4331
|
+
}
|
|
4332
|
+
else {
|
|
4333
|
+
const commandsStr = commands
|
|
4334
|
+
.map(cmd => this.visit(cmd, alterContext))
|
|
4335
|
+
.join(', ');
|
|
4336
|
+
output.push(commandsStr);
|
|
4337
|
+
}
|
|
4037
4338
|
}
|
|
4038
4339
|
return output.join(' ');
|
|
4039
4340
|
}
|
|
@@ -6009,7 +6310,7 @@ export class Deparser {
|
|
|
6009
6310
|
const output = [];
|
|
6010
6311
|
const initialParts = ['CREATE', 'POLICY'];
|
|
6011
6312
|
if (node.policy_name) {
|
|
6012
|
-
initialParts.push(
|
|
6313
|
+
initialParts.push(QuoteUtils.quote(node.policy_name));
|
|
6013
6314
|
}
|
|
6014
6315
|
output.push(initialParts.join(' '));
|
|
6015
6316
|
// Add ON clause on new line in pretty mode
|
|
@@ -6086,7 +6387,7 @@ export class Deparser {
|
|
|
6086
6387
|
AlterPolicyStmt(node, context) {
|
|
6087
6388
|
const output = ['ALTER', 'POLICY'];
|
|
6088
6389
|
if (node.policy_name) {
|
|
6089
|
-
output.push(
|
|
6390
|
+
output.push(QuoteUtils.quote(node.policy_name));
|
|
6090
6391
|
}
|
|
6091
6392
|
if (node.table) {
|
|
6092
6393
|
output.push('ON');
|
|
@@ -7584,7 +7885,12 @@ export class Deparser {
|
|
|
7584
7885
|
}
|
|
7585
7886
|
if (node.action) {
|
|
7586
7887
|
const actionStr = this.GrantStmt(node.action, context);
|
|
7587
|
-
|
|
7888
|
+
if (this.formatter.isPretty()) {
|
|
7889
|
+
return output.join(' ') + this.formatter.newline() + this.formatter.indent(actionStr);
|
|
7890
|
+
}
|
|
7891
|
+
else {
|
|
7892
|
+
output.push(actionStr);
|
|
7893
|
+
}
|
|
7588
7894
|
}
|
|
7589
7895
|
return output.join(' ');
|
|
7590
7896
|
}
|
|
@@ -7731,84 +8037,158 @@ export class Deparser {
|
|
|
7731
8037
|
if (node.trigname) {
|
|
7732
8038
|
output.push(QuoteUtils.quote(node.trigname));
|
|
7733
8039
|
}
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
timing
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
events
|
|
7745
|
-
|
|
7746
|
-
events
|
|
7747
|
-
|
|
7748
|
-
events
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
.
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
.
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
output.push(args);
|
|
7806
|
-
output.push(')');
|
|
8040
|
+
if (this.formatter.isPretty()) {
|
|
8041
|
+
const components = [];
|
|
8042
|
+
const timing = [];
|
|
8043
|
+
if (node.timing & 2)
|
|
8044
|
+
timing.push('BEFORE');
|
|
8045
|
+
else if (node.timing & 64)
|
|
8046
|
+
timing.push('INSTEAD OF');
|
|
8047
|
+
else
|
|
8048
|
+
timing.push('AFTER');
|
|
8049
|
+
const events = [];
|
|
8050
|
+
if (node.events & 4)
|
|
8051
|
+
events.push('INSERT');
|
|
8052
|
+
if (node.events & 8)
|
|
8053
|
+
events.push('DELETE');
|
|
8054
|
+
if (node.events & 16) {
|
|
8055
|
+
let updateStr = 'UPDATE';
|
|
8056
|
+
if (node.columns && node.columns.length > 0) {
|
|
8057
|
+
const columnNames = ListUtils.unwrapList(node.columns)
|
|
8058
|
+
.map(col => this.visit(col, context))
|
|
8059
|
+
.join(', ');
|
|
8060
|
+
updateStr += ' OF ' + columnNames;
|
|
8061
|
+
}
|
|
8062
|
+
events.push(updateStr);
|
|
8063
|
+
}
|
|
8064
|
+
if (node.events & 32)
|
|
8065
|
+
events.push('TRUNCATE');
|
|
8066
|
+
components.push(this.formatter.indent(timing.join(' ') + ' ' + events.join(' OR ')));
|
|
8067
|
+
if (node.relation) {
|
|
8068
|
+
components.push(this.formatter.indent('ON ' + this.RangeVar(node.relation, context)));
|
|
8069
|
+
}
|
|
8070
|
+
if (node.transitionRels && node.transitionRels.length > 0) {
|
|
8071
|
+
const transitionClauses = ListUtils.unwrapList(node.transitionRels)
|
|
8072
|
+
.map(rel => this.visit(rel, context))
|
|
8073
|
+
.join(' ');
|
|
8074
|
+
components.push(this.formatter.indent('REFERENCING ' + transitionClauses));
|
|
8075
|
+
}
|
|
8076
|
+
if (node.deferrable) {
|
|
8077
|
+
components.push(this.formatter.indent('DEFERRABLE'));
|
|
8078
|
+
}
|
|
8079
|
+
if (node.initdeferred) {
|
|
8080
|
+
components.push(this.formatter.indent('INITIALLY DEFERRED'));
|
|
8081
|
+
}
|
|
8082
|
+
if (node.row) {
|
|
8083
|
+
components.push(this.formatter.indent('FOR EACH ROW'));
|
|
8084
|
+
}
|
|
8085
|
+
else {
|
|
8086
|
+
components.push(this.formatter.indent('FOR EACH STATEMENT'));
|
|
8087
|
+
}
|
|
8088
|
+
if (node.whenClause) {
|
|
8089
|
+
const whenStr = 'WHEN (' + this.visit(node.whenClause, context) + ')';
|
|
8090
|
+
components.push(this.formatter.indent(whenStr));
|
|
8091
|
+
}
|
|
8092
|
+
let executeStr = 'EXECUTE';
|
|
8093
|
+
if (node.funcname && node.funcname.length > 0) {
|
|
8094
|
+
const funcName = ListUtils.unwrapList(node.funcname)
|
|
8095
|
+
.map(name => this.visit(name, context))
|
|
8096
|
+
.join('.');
|
|
8097
|
+
executeStr += ' PROCEDURE ' + funcName;
|
|
8098
|
+
}
|
|
8099
|
+
if (node.args && node.args.length > 0) {
|
|
8100
|
+
const argContext = { ...context, isStringLiteral: true };
|
|
8101
|
+
const args = ListUtils.unwrapList(node.args)
|
|
8102
|
+
.map(arg => this.visit(arg, argContext))
|
|
8103
|
+
.join(', ');
|
|
8104
|
+
executeStr += '(' + args + ')';
|
|
8105
|
+
}
|
|
8106
|
+
else {
|
|
8107
|
+
executeStr += '()';
|
|
8108
|
+
}
|
|
8109
|
+
components.push(this.formatter.indent(executeStr));
|
|
8110
|
+
return output.join(' ') + this.formatter.newline() + components.join(this.formatter.newline());
|
|
7807
8111
|
}
|
|
7808
8112
|
else {
|
|
7809
|
-
|
|
8113
|
+
const timing = [];
|
|
8114
|
+
if (node.timing & 2)
|
|
8115
|
+
timing.push('BEFORE');
|
|
8116
|
+
else if (node.timing & 64)
|
|
8117
|
+
timing.push('INSTEAD OF');
|
|
8118
|
+
else
|
|
8119
|
+
timing.push('AFTER');
|
|
8120
|
+
output.push(timing.join(' '));
|
|
8121
|
+
const events = [];
|
|
8122
|
+
if (node.events & 4)
|
|
8123
|
+
events.push('INSERT');
|
|
8124
|
+
if (node.events & 8)
|
|
8125
|
+
events.push('DELETE');
|
|
8126
|
+
if (node.events & 16)
|
|
8127
|
+
events.push('UPDATE');
|
|
8128
|
+
if (node.events & 32)
|
|
8129
|
+
events.push('TRUNCATE');
|
|
8130
|
+
output.push(events.join(' OR '));
|
|
8131
|
+
if (node.columns && node.columns.length > 0) {
|
|
8132
|
+
output.push('OF');
|
|
8133
|
+
const columnNames = ListUtils.unwrapList(node.columns)
|
|
8134
|
+
.map(col => this.visit(col, context))
|
|
8135
|
+
.join(', ');
|
|
8136
|
+
output.push(columnNames);
|
|
8137
|
+
}
|
|
8138
|
+
output.push('ON');
|
|
8139
|
+
if (node.relation) {
|
|
8140
|
+
output.push(this.RangeVar(node.relation, context));
|
|
8141
|
+
}
|
|
8142
|
+
if (node.constrrel) {
|
|
8143
|
+
output.push('FROM');
|
|
8144
|
+
output.push(this.RangeVar(node.constrrel, context));
|
|
8145
|
+
}
|
|
8146
|
+
if (node.deferrable) {
|
|
8147
|
+
output.push('DEFERRABLE');
|
|
8148
|
+
}
|
|
8149
|
+
if (node.initdeferred) {
|
|
8150
|
+
output.push('INITIALLY DEFERRED');
|
|
8151
|
+
}
|
|
8152
|
+
if (node.transitionRels && node.transitionRels.length > 0) {
|
|
8153
|
+
output.push('REFERENCING');
|
|
8154
|
+
const transitionClauses = ListUtils.unwrapList(node.transitionRels)
|
|
8155
|
+
.map(rel => this.visit(rel, context))
|
|
8156
|
+
.join(' ');
|
|
8157
|
+
output.push(transitionClauses);
|
|
8158
|
+
}
|
|
8159
|
+
if (node.row) {
|
|
8160
|
+
output.push('FOR EACH ROW');
|
|
8161
|
+
}
|
|
8162
|
+
else {
|
|
8163
|
+
output.push('FOR EACH STATEMENT');
|
|
8164
|
+
}
|
|
8165
|
+
if (node.whenClause) {
|
|
8166
|
+
output.push('WHEN');
|
|
8167
|
+
output.push('(');
|
|
8168
|
+
output.push(this.visit(node.whenClause, context));
|
|
8169
|
+
output.push(')');
|
|
8170
|
+
}
|
|
8171
|
+
output.push('EXECUTE');
|
|
8172
|
+
if (node.funcname && node.funcname.length > 0) {
|
|
8173
|
+
const funcName = ListUtils.unwrapList(node.funcname)
|
|
8174
|
+
.map(name => this.visit(name, context))
|
|
8175
|
+
.join('.');
|
|
8176
|
+
output.push('FUNCTION', funcName);
|
|
8177
|
+
}
|
|
8178
|
+
if (node.args && node.args.length > 0) {
|
|
8179
|
+
output.push('(');
|
|
8180
|
+
const argContext = { ...context, isStringLiteral: true };
|
|
8181
|
+
const args = ListUtils.unwrapList(node.args)
|
|
8182
|
+
.map(arg => this.visit(arg, argContext))
|
|
8183
|
+
.join(', ');
|
|
8184
|
+
output.push(args);
|
|
8185
|
+
output.push(')');
|
|
8186
|
+
}
|
|
8187
|
+
else {
|
|
8188
|
+
output.push('()');
|
|
8189
|
+
}
|
|
8190
|
+
return output.join(' ');
|
|
7810
8191
|
}
|
|
7811
|
-
return output.join(' ');
|
|
7812
8192
|
}
|
|
7813
8193
|
TriggerTransition(node, context) {
|
|
7814
8194
|
const output = [];
|
|
@@ -8386,7 +8766,7 @@ export class Deparser {
|
|
|
8386
8766
|
AccessPriv(node, context) {
|
|
8387
8767
|
const output = [];
|
|
8388
8768
|
if (node.priv_name) {
|
|
8389
|
-
output.push(node.priv_name);
|
|
8769
|
+
output.push(node.priv_name.toUpperCase());
|
|
8390
8770
|
}
|
|
8391
8771
|
else {
|
|
8392
8772
|
output.push('ALL');
|