pgsql-deparser 18.3.7 → 18.3.8
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 +20 -0
- package/deparser.js +533 -316
- package/esm/deparser.js +533 -316
- package/package.json +2 -2
package/deparser.js
CHANGED
|
@@ -5,6 +5,25 @@ const quotes_1 = require("@pgsql/quotes");
|
|
|
5
5
|
const list_utils_1 = require("./utils/list-utils");
|
|
6
6
|
const sql_formatter_1 = require("./utils/sql-formatter");
|
|
7
7
|
const base_1 = require("./visitors/base");
|
|
8
|
+
// WindowDef.frameOptions bit flags (src/include/nodes/parsenodes.h)
|
|
9
|
+
const FRAMEOPTION_NONDEFAULT = 0x00001;
|
|
10
|
+
const FRAMEOPTION_RANGE = 0x00002;
|
|
11
|
+
const FRAMEOPTION_ROWS = 0x00004;
|
|
12
|
+
const FRAMEOPTION_GROUPS = 0x00008;
|
|
13
|
+
const FRAMEOPTION_BETWEEN = 0x00010;
|
|
14
|
+
const FRAMEOPTION_START_UNBOUNDED_PRECEDING = 0x00020;
|
|
15
|
+
const FRAMEOPTION_END_UNBOUNDED_PRECEDING = 0x00040;
|
|
16
|
+
const FRAMEOPTION_START_UNBOUNDED_FOLLOWING = 0x00080;
|
|
17
|
+
const FRAMEOPTION_END_UNBOUNDED_FOLLOWING = 0x00100;
|
|
18
|
+
const FRAMEOPTION_START_CURRENT_ROW = 0x00200;
|
|
19
|
+
const FRAMEOPTION_END_CURRENT_ROW = 0x00400;
|
|
20
|
+
const FRAMEOPTION_START_OFFSET_PRECEDING = 0x00800;
|
|
21
|
+
const FRAMEOPTION_END_OFFSET_PRECEDING = 0x01000;
|
|
22
|
+
const FRAMEOPTION_START_OFFSET_FOLLOWING = 0x02000;
|
|
23
|
+
const FRAMEOPTION_END_OFFSET_FOLLOWING = 0x04000;
|
|
24
|
+
const FRAMEOPTION_EXCLUDE_CURRENT_ROW = 0x08000;
|
|
25
|
+
const FRAMEOPTION_EXCLUDE_GROUP = 0x10000;
|
|
26
|
+
const FRAMEOPTION_EXCLUDE_TIES = 0x20000;
|
|
8
27
|
/**
|
|
9
28
|
* List of real PostgreSQL built-in types as they appear in pg_catalog.pg_type.typname.
|
|
10
29
|
* These are stored in lowercase in PostgreSQL system catalogs.
|
|
@@ -984,6 +1003,12 @@ class Deparser {
|
|
|
984
1003
|
output.push(context.parens(columnNames.join(', ')));
|
|
985
1004
|
}
|
|
986
1005
|
}
|
|
1006
|
+
if (node.override === 'OVERRIDING_USER_VALUE') {
|
|
1007
|
+
output.push('OVERRIDING USER VALUE');
|
|
1008
|
+
}
|
|
1009
|
+
else if (node.override === 'OVERRIDING_SYSTEM_VALUE') {
|
|
1010
|
+
output.push('OVERRIDING SYSTEM VALUE');
|
|
1011
|
+
}
|
|
987
1012
|
if (node.selectStmt) {
|
|
988
1013
|
output.push(this.visit(node.selectStmt, context));
|
|
989
1014
|
}
|
|
@@ -1060,38 +1085,8 @@ class Deparser {
|
|
|
1060
1085
|
output.push(this.RangeVar(node.relation, context));
|
|
1061
1086
|
}
|
|
1062
1087
|
output.push('SET');
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
const firstTarget = targetList[0];
|
|
1066
|
-
const processedTargets = new Set();
|
|
1067
|
-
const assignmentParts = [];
|
|
1068
|
-
for (let i = 0; i < targetList.length; i++) {
|
|
1069
|
-
if (processedTargets.has(i))
|
|
1070
|
-
continue;
|
|
1071
|
-
const target = targetList[i];
|
|
1072
|
-
const multiAssignRef = target.ResTarget?.val?.MultiAssignRef;
|
|
1073
|
-
if (multiAssignRef) {
|
|
1074
|
-
const relatedTargets = [];
|
|
1075
|
-
for (let j = i; j < targetList.length; j++) {
|
|
1076
|
-
const otherTarget = targetList[j];
|
|
1077
|
-
const otherMultiAssignRef = otherTarget.ResTarget?.val?.MultiAssignRef;
|
|
1078
|
-
if (otherMultiAssignRef &&
|
|
1079
|
-
JSON.stringify(otherMultiAssignRef.source) === JSON.stringify(multiAssignRef.source)) {
|
|
1080
|
-
relatedTargets.push(otherTarget);
|
|
1081
|
-
processedTargets.add(j);
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
const names = relatedTargets.map(t => t.ResTarget.name);
|
|
1085
|
-
const multiAssignment = `${context.parens(names.join(', '))} = ${this.visit(multiAssignRef.source, context)}`;
|
|
1086
|
-
assignmentParts.push(multiAssignment);
|
|
1087
|
-
}
|
|
1088
|
-
else {
|
|
1089
|
-
// Handle regular single-column assignment
|
|
1090
|
-
assignmentParts.push(this.visit(target, context.spawn('UpdateStmt', { update: true })));
|
|
1091
|
-
processedTargets.add(i);
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
1094
|
-
output.push(assignmentParts.join(','));
|
|
1088
|
+
if (node.targetList && node.targetList.length > 0) {
|
|
1089
|
+
output.push(this.formatUpdateAssignments(node.targetList, context));
|
|
1095
1090
|
}
|
|
1096
1091
|
if (node.fromClause) {
|
|
1097
1092
|
output.push('FROM');
|
|
@@ -1108,6 +1103,36 @@ class Deparser {
|
|
|
1108
1103
|
}
|
|
1109
1104
|
return output.join(' ');
|
|
1110
1105
|
}
|
|
1106
|
+
formatUpdateAssignments(targets, context) {
|
|
1107
|
+
const targetList = list_utils_1.ListUtils.unwrapList(targets);
|
|
1108
|
+
const processedTargets = new Set();
|
|
1109
|
+
const assignmentParts = [];
|
|
1110
|
+
for (let i = 0; i < targetList.length; i++) {
|
|
1111
|
+
if (processedTargets.has(i))
|
|
1112
|
+
continue;
|
|
1113
|
+
const target = targetList[i];
|
|
1114
|
+
const multiAssignRef = target.ResTarget?.val?.MultiAssignRef;
|
|
1115
|
+
if (multiAssignRef) {
|
|
1116
|
+
const relatedTargets = [];
|
|
1117
|
+
for (let j = i; j < targetList.length; j++) {
|
|
1118
|
+
const otherTarget = targetList[j];
|
|
1119
|
+
const otherMultiAssignRef = otherTarget.ResTarget?.val?.MultiAssignRef;
|
|
1120
|
+
if (otherMultiAssignRef &&
|
|
1121
|
+
JSON.stringify(otherMultiAssignRef.source) === JSON.stringify(multiAssignRef.source)) {
|
|
1122
|
+
relatedTargets.push(otherTarget);
|
|
1123
|
+
processedTargets.add(j);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
const names = relatedTargets.map(t => quotes_1.QuoteUtils.quoteIdentifier(t.ResTarget.name));
|
|
1127
|
+
assignmentParts.push(`${context.parens(names.join(', '))} = ${this.visit(multiAssignRef.source, context)}`);
|
|
1128
|
+
}
|
|
1129
|
+
else {
|
|
1130
|
+
assignmentParts.push(this.visit(target, context.spawn('UpdateStmt', { update: true })));
|
|
1131
|
+
processedTargets.add(i);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
return assignmentParts.join(', ');
|
|
1135
|
+
}
|
|
1111
1136
|
DeleteStmt(node, context) {
|
|
1112
1137
|
try {
|
|
1113
1138
|
const output = [];
|
|
@@ -1520,43 +1545,41 @@ class Deparser {
|
|
|
1520
1545
|
result += ` FILTER (WHERE ${this.visit(node.agg_filter, context)})`;
|
|
1521
1546
|
}
|
|
1522
1547
|
if (node.over) {
|
|
1523
|
-
|
|
1524
|
-
if (node.over.name) {
|
|
1525
|
-
result += ` OVER ${node.over.name}`;
|
|
1526
|
-
}
|
|
1527
|
-
else {
|
|
1528
|
-
const windowParts = [];
|
|
1529
|
-
if (node.over.partitionClause) {
|
|
1530
|
-
const partitions = list_utils_1.ListUtils.unwrapList(node.over.partitionClause);
|
|
1531
|
-
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
1532
|
-
windowParts.push(`PARTITION BY ${partitionStrs.join(', ')}`);
|
|
1533
|
-
}
|
|
1534
|
-
if (node.over.orderClause) {
|
|
1535
|
-
const orders = list_utils_1.ListUtils.unwrapList(node.over.orderClause);
|
|
1536
|
-
const orderStrs = orders.map(o => this.visit(o, context));
|
|
1537
|
-
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
1538
|
-
}
|
|
1539
|
-
// Handle window frame specifications using the dedicated formatWindowFrame method
|
|
1540
|
-
const frameClause = this.formatWindowFrame(node.over, context.spawn('FuncCall'));
|
|
1541
|
-
if (frameClause) {
|
|
1542
|
-
windowParts.push(frameClause);
|
|
1543
|
-
}
|
|
1544
|
-
if (windowParts.length > 0) {
|
|
1545
|
-
if (context.isPretty() && windowParts.length > 1) {
|
|
1546
|
-
const formattedParts = windowParts.map(part => context.indent(part));
|
|
1547
|
-
result += ` OVER (${context.newline()}${formattedParts.join(context.newline())}${context.newline()})`;
|
|
1548
|
-
}
|
|
1549
|
-
else {
|
|
1550
|
-
result += ` OVER (${windowParts.join(' ')})`;
|
|
1551
|
-
}
|
|
1552
|
-
}
|
|
1553
|
-
else {
|
|
1554
|
-
result += ` OVER ()`;
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1548
|
+
result += this.formatOverClause(node.over, context);
|
|
1557
1549
|
}
|
|
1558
1550
|
return result;
|
|
1559
1551
|
}
|
|
1552
|
+
formatOverClause(over, context) {
|
|
1553
|
+
if (over.name) {
|
|
1554
|
+
return ` OVER ${over.name}`;
|
|
1555
|
+
}
|
|
1556
|
+
const windowParts = [];
|
|
1557
|
+
if (over.refname) {
|
|
1558
|
+
windowParts.push(over.refname);
|
|
1559
|
+
}
|
|
1560
|
+
if (over.partitionClause) {
|
|
1561
|
+
const partitions = list_utils_1.ListUtils.unwrapList(over.partitionClause);
|
|
1562
|
+
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
1563
|
+
windowParts.push(`PARTITION BY ${partitionStrs.join(', ')}`);
|
|
1564
|
+
}
|
|
1565
|
+
if (over.orderClause) {
|
|
1566
|
+
const orders = list_utils_1.ListUtils.unwrapList(over.orderClause);
|
|
1567
|
+
const orderStrs = orders.map(o => this.visit(o, context));
|
|
1568
|
+
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
1569
|
+
}
|
|
1570
|
+
const frameClause = this.formatWindowFrame(over, context.spawn('FuncCall'));
|
|
1571
|
+
if (frameClause) {
|
|
1572
|
+
windowParts.push(frameClause);
|
|
1573
|
+
}
|
|
1574
|
+
if (windowParts.length === 0) {
|
|
1575
|
+
return ' OVER ()';
|
|
1576
|
+
}
|
|
1577
|
+
if (context.isPretty() && windowParts.length > 1) {
|
|
1578
|
+
const formattedParts = windowParts.map(part => context.indent(part));
|
|
1579
|
+
return ` OVER (${context.newline()}${formattedParts.join(context.newline())}${context.newline()})`;
|
|
1580
|
+
}
|
|
1581
|
+
return ` OVER (${windowParts.join(' ')})`;
|
|
1582
|
+
}
|
|
1560
1583
|
FuncExpr(node, context) {
|
|
1561
1584
|
const funcName = `func_${node.funcid}`;
|
|
1562
1585
|
const args = node.args ? list_utils_1.ListUtils.unwrapList(node.args).map(arg => this.visit(arg, context)).join(', ') : '';
|
|
@@ -2419,7 +2442,7 @@ class Deparser {
|
|
|
2419
2442
|
output.push(context.parens(elementStrs.join(', ')));
|
|
2420
2443
|
}
|
|
2421
2444
|
}
|
|
2422
|
-
else if (node.tableElts) {
|
|
2445
|
+
else if (node.tableElts && !node.partbound) {
|
|
2423
2446
|
const elements = list_utils_1.ListUtils.unwrapList(node.tableElts);
|
|
2424
2447
|
const elementStrs = elements.map(el => {
|
|
2425
2448
|
return this.deparse(el, context.spawn('CreateStmt'));
|
|
@@ -2447,7 +2470,16 @@ class Deparser {
|
|
|
2447
2470
|
const inherits = list_utils_1.ListUtils.unwrapList(node.inhRelations);
|
|
2448
2471
|
const inheritStrs = inherits.map(rel => this.visit(rel, context));
|
|
2449
2472
|
output.push(inheritStrs[0]);
|
|
2450
|
-
if (node.
|
|
2473
|
+
if (node.tableElts) {
|
|
2474
|
+
const elementStrs = list_utils_1.ListUtils.unwrapList(node.tableElts).map(el => {
|
|
2475
|
+
return this.deparse(el, context.spawn('CreateStmt'));
|
|
2476
|
+
});
|
|
2477
|
+
output.push(context.parens(elementStrs.join(', ')));
|
|
2478
|
+
}
|
|
2479
|
+
if (node.partbound.is_default) {
|
|
2480
|
+
output.push('DEFAULT');
|
|
2481
|
+
}
|
|
2482
|
+
else if (node.partbound.strategy === 'l' && node.partbound.listdatums) {
|
|
2451
2483
|
output.push('FOR VALUES IN');
|
|
2452
2484
|
const listValues = list_utils_1.ListUtils.unwrapList(node.partbound.listdatums)
|
|
2453
2485
|
.map(datum => this.visit(datum, context))
|
|
@@ -2470,13 +2502,9 @@ class Deparser {
|
|
|
2470
2502
|
output.push(`(${upperValues})`);
|
|
2471
2503
|
}
|
|
2472
2504
|
}
|
|
2473
|
-
else if (node.partbound.strategy === 'h'
|
|
2505
|
+
else if (node.partbound.strategy === 'h') {
|
|
2474
2506
|
output.push('FOR VALUES WITH');
|
|
2475
|
-
|
|
2476
|
-
output.push(`(MODULUS ${node.partbound.modulus}, REMAINDER ${remainder})`);
|
|
2477
|
-
}
|
|
2478
|
-
else if (node.partbound.is_default) {
|
|
2479
|
-
output.push('DEFAULT');
|
|
2507
|
+
output.push(`(MODULUS ${node.partbound.modulus ?? 0}, REMAINDER ${node.partbound.remainder ?? 0})`);
|
|
2480
2508
|
}
|
|
2481
2509
|
}
|
|
2482
2510
|
else if (node.inhRelations) {
|
|
@@ -2542,6 +2570,12 @@ class Deparser {
|
|
|
2542
2570
|
if (node.typeName) {
|
|
2543
2571
|
output.push(this.TypeName(node.typeName, context));
|
|
2544
2572
|
}
|
|
2573
|
+
if (node.storage_name) {
|
|
2574
|
+
output.push('STORAGE', node.storage_name.toUpperCase());
|
|
2575
|
+
}
|
|
2576
|
+
if (node.compression) {
|
|
2577
|
+
output.push('COMPRESSION', quotes_1.QuoteUtils.quoteIdentifier(node.compression));
|
|
2578
|
+
}
|
|
2545
2579
|
if (node.fdwoptions && node.fdwoptions.length > 0) {
|
|
2546
2580
|
output.push('OPTIONS');
|
|
2547
2581
|
const columnContext = context.spawn('ColumnDef');
|
|
@@ -2602,7 +2636,8 @@ class Deparser {
|
|
|
2602
2636
|
case 'CONSTR_DEFAULT':
|
|
2603
2637
|
output.push('DEFAULT');
|
|
2604
2638
|
if (node.raw_expr) {
|
|
2605
|
-
|
|
2639
|
+
const defaultExpr = this.visit(node.raw_expr, context);
|
|
2640
|
+
output.push(this.needsBExprParens(node.raw_expr) ? `(${defaultExpr})` : defaultExpr);
|
|
2606
2641
|
}
|
|
2607
2642
|
break;
|
|
2608
2643
|
case 'CONSTR_CHECK':
|
|
@@ -2966,7 +3001,7 @@ class Deparser {
|
|
|
2966
3001
|
break;
|
|
2967
3002
|
}
|
|
2968
3003
|
// Handle deferrable constraints for all constraint types that support it
|
|
2969
|
-
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN') {
|
|
3004
|
+
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN' || node.contype === 'CONSTR_EXCLUSION') {
|
|
2970
3005
|
if (node.deferrable) {
|
|
2971
3006
|
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2972
3007
|
output.push('\n' + context.indent('DEFERRABLE'));
|
|
@@ -2995,6 +3030,9 @@ class Deparser {
|
|
|
2995
3030
|
output.push('NOT DEFERRABLE');
|
|
2996
3031
|
}
|
|
2997
3032
|
}
|
|
3033
|
+
else if (node.initdeferred) {
|
|
3034
|
+
output.push('INITIALLY DEFERRED');
|
|
3035
|
+
}
|
|
2998
3036
|
}
|
|
2999
3037
|
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
3000
3038
|
let result = '';
|
|
@@ -3060,6 +3098,9 @@ class Deparser {
|
|
|
3060
3098
|
output.push(node.name);
|
|
3061
3099
|
}
|
|
3062
3100
|
const windowParts = [];
|
|
3101
|
+
if (node.refname) {
|
|
3102
|
+
windowParts.push(node.refname);
|
|
3103
|
+
}
|
|
3063
3104
|
if (node.partitionClause) {
|
|
3064
3105
|
const partitions = list_utils_1.ListUtils.unwrapList(node.partitionClause);
|
|
3065
3106
|
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
@@ -3070,12 +3111,9 @@ class Deparser {
|
|
|
3070
3111
|
const orderStrs = orders.map(o => this.visit(o, context));
|
|
3071
3112
|
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
3072
3113
|
}
|
|
3073
|
-
|
|
3074
|
-
if (
|
|
3075
|
-
|
|
3076
|
-
if (frameClause) {
|
|
3077
|
-
windowParts.push(frameClause);
|
|
3078
|
-
}
|
|
3114
|
+
const frameClause = this.formatWindowFrame(node, context.spawn('WindowDef'));
|
|
3115
|
+
if (frameClause) {
|
|
3116
|
+
windowParts.push(frameClause);
|
|
3079
3117
|
}
|
|
3080
3118
|
if (windowParts.length > 0) {
|
|
3081
3119
|
if (node.name) {
|
|
@@ -3092,114 +3130,96 @@ class Deparser {
|
|
|
3092
3130
|
}
|
|
3093
3131
|
return output.join(' ');
|
|
3094
3132
|
}
|
|
3133
|
+
formatIdentityColumnOptions(def, context) {
|
|
3134
|
+
const seqContext = context.spawn('AlterSeqStmt');
|
|
3135
|
+
return list_utils_1.ListUtils.unwrapList(def).map(item => {
|
|
3136
|
+
const el = item.DefElem;
|
|
3137
|
+
if (!el)
|
|
3138
|
+
return this.visit(item, context);
|
|
3139
|
+
if (el.defname === 'generated') {
|
|
3140
|
+
const ival = el.arg?.Integer?.ival ?? 0;
|
|
3141
|
+
return ival === 97 ? 'SET GENERATED ALWAYS' : 'SET GENERATED BY DEFAULT';
|
|
3142
|
+
}
|
|
3143
|
+
if (el.defname === 'restart') {
|
|
3144
|
+
return el.arg ? `RESTART WITH ${this.visit(el.arg, context)}` : 'RESTART';
|
|
3145
|
+
}
|
|
3146
|
+
return `SET ${this.visit(item, seqContext)}`;
|
|
3147
|
+
}).join(' ');
|
|
3148
|
+
}
|
|
3149
|
+
// b_expr (used by DEFAULT) excludes IN/LIKE/BETWEEN and boolean operators.
|
|
3150
|
+
needsBExprParens(node) {
|
|
3151
|
+
const nodeType = this.getNodeType(node);
|
|
3152
|
+
if (nodeType === 'BoolExpr')
|
|
3153
|
+
return true;
|
|
3154
|
+
if (nodeType === 'A_Expr') {
|
|
3155
|
+
const kind = this.getNodeData(node).kind;
|
|
3156
|
+
return kind !== 'AEXPR_OP' && kind !== 'AEXPR_DISTINCT' && kind !== 'AEXPR_NOT_DISTINCT';
|
|
3157
|
+
}
|
|
3158
|
+
return false;
|
|
3159
|
+
}
|
|
3095
3160
|
formatWindowFrame(node, context) {
|
|
3096
|
-
if (!node.frameOptions)
|
|
3161
|
+
if (!node.frameOptions || !(node.frameOptions & FRAMEOPTION_NONDEFAULT))
|
|
3097
3162
|
return null;
|
|
3098
3163
|
const frameOptions = node.frameOptions;
|
|
3099
|
-
const EXCLUDE_MASK = 0x8000 | 0x10000 | 0x20000;
|
|
3100
|
-
const baseFrameOptions = frameOptions & ~EXCLUDE_MASK;
|
|
3101
3164
|
const frameParts = [];
|
|
3102
|
-
if (frameOptions &
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
frameParts.push('GROUPS');
|
|
3111
|
-
}
|
|
3165
|
+
if (frameOptions & FRAMEOPTION_RANGE) {
|
|
3166
|
+
frameParts.push('RANGE');
|
|
3167
|
+
}
|
|
3168
|
+
else if (frameOptions & FRAMEOPTION_ROWS) {
|
|
3169
|
+
frameParts.push('ROWS');
|
|
3170
|
+
}
|
|
3171
|
+
else if (frameOptions & FRAMEOPTION_GROUPS) {
|
|
3172
|
+
frameParts.push('GROUPS');
|
|
3112
3173
|
}
|
|
3113
3174
|
if (frameParts.length === 0)
|
|
3114
3175
|
return null;
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
boundsParts.push('CURRENT ROW');
|
|
3119
|
-
boundsParts.push('AND UNBOUNDED FOLLOWING');
|
|
3176
|
+
let start = null;
|
|
3177
|
+
if (frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) {
|
|
3178
|
+
start = 'UNBOUNDED PRECEDING';
|
|
3120
3179
|
}
|
|
3121
|
-
else if (
|
|
3122
|
-
|
|
3123
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3180
|
+
else if (frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) {
|
|
3181
|
+
start = 'UNBOUNDED FOLLOWING';
|
|
3124
3182
|
}
|
|
3125
|
-
else if (
|
|
3126
|
-
|
|
3127
|
-
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
|
|
3128
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3129
|
-
}
|
|
3183
|
+
else if (frameOptions & FRAMEOPTION_START_CURRENT_ROW) {
|
|
3184
|
+
start = 'CURRENT ROW';
|
|
3130
3185
|
}
|
|
3131
|
-
else if (
|
|
3132
|
-
|
|
3133
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3186
|
+
else if (frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING && node.startOffset) {
|
|
3187
|
+
start = `${this.visit(node.startOffset, context)} PRECEDING`;
|
|
3134
3188
|
}
|
|
3135
|
-
else if (
|
|
3136
|
-
|
|
3137
|
-
if (node.endOffset) {
|
|
3138
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3139
|
-
}
|
|
3189
|
+
else if (frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING && node.startOffset) {
|
|
3190
|
+
start = `${this.visit(node.startOffset, context)} FOLLOWING`;
|
|
3140
3191
|
}
|
|
3141
|
-
|
|
3142
|
-
|
|
3192
|
+
let end = null;
|
|
3193
|
+
if (frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING) {
|
|
3194
|
+
end = 'UNBOUNDED PRECEDING';
|
|
3143
3195
|
}
|
|
3144
|
-
else {
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
}
|
|
3160
|
-
else if (frameOptions & 0x20) { // FRAMEOPTION_START_CURRENT_ROW
|
|
3161
|
-
boundsParts.push('CURRENT ROW');
|
|
3162
|
-
}
|
|
3163
|
-
// Handle end bound - prioritize explicit offset values over bit flags
|
|
3164
|
-
if (node.endOffset) {
|
|
3165
|
-
if (boundsParts.length > 0) {
|
|
3166
|
-
if (frameOptions & 0x1000) { // FRAMEOPTION_END_VALUE_PRECEDING
|
|
3167
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} PRECEDING`);
|
|
3168
|
-
}
|
|
3169
|
-
else if (frameOptions & 0x2000) { // FRAMEOPTION_END_VALUE_FOLLOWING
|
|
3170
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3171
|
-
}
|
|
3172
|
-
else {
|
|
3173
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3174
|
-
}
|
|
3175
|
-
}
|
|
3176
|
-
}
|
|
3177
|
-
else if (frameOptions & 0x80) { // FRAMEOPTION_END_UNBOUNDED_FOLLOWING
|
|
3178
|
-
if (boundsParts.length > 0) {
|
|
3179
|
-
boundsParts.push('AND UNBOUNDED FOLLOWING');
|
|
3180
|
-
}
|
|
3181
|
-
}
|
|
3182
|
-
else if (frameOptions & 0x100) { // FRAMEOPTION_END_CURRENT_ROW
|
|
3183
|
-
if (boundsParts.length > 0) {
|
|
3184
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3185
|
-
}
|
|
3196
|
+
else if (frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING) {
|
|
3197
|
+
end = 'UNBOUNDED FOLLOWING';
|
|
3198
|
+
}
|
|
3199
|
+
else if (frameOptions & FRAMEOPTION_END_CURRENT_ROW) {
|
|
3200
|
+
end = 'CURRENT ROW';
|
|
3201
|
+
}
|
|
3202
|
+
else if (frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING && node.endOffset) {
|
|
3203
|
+
end = `${this.visit(node.endOffset, context)} PRECEDING`;
|
|
3204
|
+
}
|
|
3205
|
+
else if (frameOptions & FRAMEOPTION_END_OFFSET_FOLLOWING && node.endOffset) {
|
|
3206
|
+
end = `${this.visit(node.endOffset, context)} FOLLOWING`;
|
|
3207
|
+
}
|
|
3208
|
+
if (start) {
|
|
3209
|
+
if (frameOptions & FRAMEOPTION_BETWEEN) {
|
|
3210
|
+
frameParts.push(`BETWEEN ${start} AND ${end ?? 'CURRENT ROW'}`);
|
|
3186
3211
|
}
|
|
3187
|
-
else
|
|
3188
|
-
|
|
3212
|
+
else {
|
|
3213
|
+
frameParts.push(start);
|
|
3189
3214
|
}
|
|
3190
3215
|
}
|
|
3191
|
-
if (
|
|
3192
|
-
frameParts.push('BETWEEN');
|
|
3193
|
-
frameParts.push(boundsParts.join(' '));
|
|
3194
|
-
}
|
|
3195
|
-
// EXCLUDE clause
|
|
3196
|
-
if (frameOptions & 0x8000) { // FRAMEOPTION_EXCLUDE_CURRENT_ROW
|
|
3216
|
+
if (frameOptions & FRAMEOPTION_EXCLUDE_CURRENT_ROW) {
|
|
3197
3217
|
frameParts.push('EXCLUDE CURRENT ROW');
|
|
3198
3218
|
}
|
|
3199
|
-
else if (frameOptions &
|
|
3219
|
+
else if (frameOptions & FRAMEOPTION_EXCLUDE_GROUP) {
|
|
3200
3220
|
frameParts.push('EXCLUDE GROUP');
|
|
3201
3221
|
}
|
|
3202
|
-
else if (frameOptions &
|
|
3222
|
+
else if (frameOptions & FRAMEOPTION_EXCLUDE_TIES) {
|
|
3203
3223
|
frameParts.push('EXCLUDE TIES');
|
|
3204
3224
|
}
|
|
3205
3225
|
return frameParts.join(' ');
|
|
@@ -3278,8 +3298,35 @@ class Deparser {
|
|
|
3278
3298
|
if (node.ctequery) {
|
|
3279
3299
|
output.push(context.parens(this.visit(node.ctequery, context)));
|
|
3280
3300
|
}
|
|
3301
|
+
if (node.search_clause) {
|
|
3302
|
+
const sc = node.search_clause;
|
|
3303
|
+
const cols = list_utils_1.ListUtils.unwrapList(sc.search_col_list).map(c => this.visit(c, context));
|
|
3304
|
+
output.push('SEARCH', sc.search_breadth_first ? 'BREADTH' : 'DEPTH', 'FIRST BY');
|
|
3305
|
+
output.push(cols.join(', '));
|
|
3306
|
+
output.push('SET', quotes_1.QuoteUtils.quoteIdentifier(sc.search_seq_column));
|
|
3307
|
+
}
|
|
3308
|
+
if (node.cycle_clause) {
|
|
3309
|
+
const cc = node.cycle_clause;
|
|
3310
|
+
const cols = list_utils_1.ListUtils.unwrapList(cc.cycle_col_list).map(c => this.visit(c, context));
|
|
3311
|
+
output.push('CYCLE', cols.join(', '));
|
|
3312
|
+
output.push('SET', quotes_1.QuoteUtils.quoteIdentifier(cc.cycle_mark_column));
|
|
3313
|
+
if (cc.cycle_mark_value && cc.cycle_mark_default) {
|
|
3314
|
+
output.push('TO', this.formatAexprConst(cc.cycle_mark_value, context));
|
|
3315
|
+
output.push('DEFAULT', this.formatAexprConst(cc.cycle_mark_default, context));
|
|
3316
|
+
}
|
|
3317
|
+
output.push('USING', quotes_1.QuoteUtils.quoteIdentifier(cc.cycle_path_column));
|
|
3318
|
+
}
|
|
3281
3319
|
return output.join(' ');
|
|
3282
3320
|
}
|
|
3321
|
+
// Renders a constant in the restricted AexprConst grammar (e.g. `point '(1,1)'`
|
|
3322
|
+
// rather than `CAST('(1,1)' AS point)`).
|
|
3323
|
+
formatAexprConst(node, context) {
|
|
3324
|
+
const cast = node.TypeCast;
|
|
3325
|
+
if (cast?.arg?.A_Const?.sval && cast.typeName) {
|
|
3326
|
+
return `${this.TypeName(cast.typeName, context)} ${this.visit(cast.arg, context)}`;
|
|
3327
|
+
}
|
|
3328
|
+
return this.visit(node, context);
|
|
3329
|
+
}
|
|
3283
3330
|
ParamRef(node, context) {
|
|
3284
3331
|
return `$${node.number}`;
|
|
3285
3332
|
}
|
|
@@ -3669,9 +3716,9 @@ class Deparser {
|
|
|
3669
3716
|
output.push(`(${upperValues})`);
|
|
3670
3717
|
}
|
|
3671
3718
|
}
|
|
3672
|
-
else if (node.bound.strategy === 'h'
|
|
3719
|
+
else if (node.bound.strategy === 'h') {
|
|
3673
3720
|
output.push('FOR VALUES WITH');
|
|
3674
|
-
output.push(`(MODULUS ${node.bound.modulus}, REMAINDER ${node.bound.remainder ?? 0})`);
|
|
3721
|
+
output.push(`(MODULUS ${node.bound.modulus ?? 0}, REMAINDER ${node.bound.remainder ?? 0})`);
|
|
3675
3722
|
}
|
|
3676
3723
|
else if (node.bound.is_default) {
|
|
3677
3724
|
output.push('DEFAULT');
|
|
@@ -4524,10 +4571,10 @@ class Deparser {
|
|
|
4524
4571
|
output.push('PROGRAM');
|
|
4525
4572
|
}
|
|
4526
4573
|
if (node.filename) {
|
|
4527
|
-
output.push(
|
|
4574
|
+
output.push(quotes_1.QuoteUtils.escape(node.filename));
|
|
4528
4575
|
}
|
|
4529
4576
|
else {
|
|
4530
|
-
output.push('STDIN');
|
|
4577
|
+
output.push(node.is_from ? 'STDIN' : 'STDOUT');
|
|
4531
4578
|
}
|
|
4532
4579
|
if (node.options && node.options.length > 0) {
|
|
4533
4580
|
output.push('WITH');
|
|
@@ -4759,6 +4806,9 @@ class Deparser {
|
|
|
4759
4806
|
const nodeData = this.getNodeData(node.def);
|
|
4760
4807
|
if (nodeData && nodeData.typeName) {
|
|
4761
4808
|
output.push(this.TypeName(nodeData.typeName, context));
|
|
4809
|
+
if (nodeData.collClause) {
|
|
4810
|
+
output.push(this.CollateClause(nodeData.collClause, context));
|
|
4811
|
+
}
|
|
4762
4812
|
// Handle USING clause (stored in raw_default for ALTER COLUMN TYPE)
|
|
4763
4813
|
if (nodeData.raw_default) {
|
|
4764
4814
|
output.push('USING');
|
|
@@ -5239,9 +5289,8 @@ class Deparser {
|
|
|
5239
5289
|
if (node.name) {
|
|
5240
5290
|
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5241
5291
|
}
|
|
5242
|
-
output.push('SET');
|
|
5243
5292
|
if (node.def) {
|
|
5244
|
-
output.push(this.
|
|
5293
|
+
output.push(this.formatIdentityColumnOptions(node.def, context));
|
|
5245
5294
|
}
|
|
5246
5295
|
break;
|
|
5247
5296
|
case 'AT_DropIdentity':
|
|
@@ -5250,11 +5299,8 @@ class Deparser {
|
|
|
5250
5299
|
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5251
5300
|
}
|
|
5252
5301
|
output.push('DROP IDENTITY');
|
|
5253
|
-
if (node.
|
|
5254
|
-
output.push('
|
|
5255
|
-
}
|
|
5256
|
-
else if (node.behavior === 'DROP_RESTRICT') {
|
|
5257
|
-
output.push('RESTRICT');
|
|
5302
|
+
if (node.missing_ok) {
|
|
5303
|
+
output.push('IF EXISTS');
|
|
5258
5304
|
}
|
|
5259
5305
|
break;
|
|
5260
5306
|
case 'AT_ReAddStatistics':
|
|
@@ -5690,6 +5736,9 @@ class Deparser {
|
|
|
5690
5736
|
if (node.arg && this.getNodeType(node.arg) === 'List') {
|
|
5691
5737
|
const listData = this.getNodeData(node.arg);
|
|
5692
5738
|
const listItems = list_utils_1.ListUtils.unwrapList(listData.items);
|
|
5739
|
+
if (listItems.length === 1 && listItems[0].String?.sval === 'none') {
|
|
5740
|
+
return 'OWNED BY NONE';
|
|
5741
|
+
}
|
|
5693
5742
|
const parts = listItems.map(item => {
|
|
5694
5743
|
const itemData = this.getNodeData(item);
|
|
5695
5744
|
if (this.getNodeType(item) === 'String') {
|
|
@@ -5867,12 +5916,15 @@ class Deparser {
|
|
|
5867
5916
|
}
|
|
5868
5917
|
// Handle CreateStmt table options - no quotes, compact formatting
|
|
5869
5918
|
if (context.parentNodeTypes.includes('CreateStmt')) {
|
|
5919
|
+
const relOptName = node.defnamespace
|
|
5920
|
+
? `${quotes_1.QuoteUtils.quoteIdentifier(node.defnamespace)}.${quotes_1.QuoteUtils.quoteIdentifier(node.defname)}`
|
|
5921
|
+
: quotes_1.QuoteUtils.quoteIdentifier(node.defname);
|
|
5870
5922
|
// For numeric values, use the raw value without quotes
|
|
5871
5923
|
if (node.arg && this.getNodeType(node.arg) === 'Integer') {
|
|
5872
5924
|
const integerData = this.getNodeData(node.arg);
|
|
5873
|
-
return `${
|
|
5925
|
+
return `${relOptName}=${integerData.ival}`;
|
|
5874
5926
|
}
|
|
5875
|
-
return `${
|
|
5927
|
+
return `${relOptName}=${argValue}`;
|
|
5876
5928
|
}
|
|
5877
5929
|
// Handle CreateEventTrigStmt WHEN clause - use IN syntax for List arguments
|
|
5878
5930
|
if (context.parentNodeTypes.includes('CreateEventTrigStmt')) {
|
|
@@ -5911,15 +5963,27 @@ class Deparser {
|
|
|
5911
5963
|
}
|
|
5912
5964
|
// Handle CopyStmt WITH clause options - uppercase format without quotes
|
|
5913
5965
|
if (context.parentNodeTypes.includes('CopyStmt')) {
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
return
|
|
5966
|
+
const optName = node.defname.toUpperCase();
|
|
5967
|
+
if (!node.arg) {
|
|
5968
|
+
return optName;
|
|
5969
|
+
}
|
|
5970
|
+
const copyArgType = this.getNodeType(node.arg);
|
|
5971
|
+
if (copyArgType === 'Boolean' && this.getNodeData(node.arg).boolval !== false) {
|
|
5972
|
+
return optName;
|
|
5973
|
+
}
|
|
5974
|
+
if (copyArgType === 'List') {
|
|
5975
|
+
const items = list_utils_1.ListUtils.unwrapList(this.getNodeData(node.arg).items)
|
|
5976
|
+
.map(item => this.visit(item, context));
|
|
5977
|
+
return `${optName} (${items.join(', ')})`;
|
|
5917
5978
|
}
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5979
|
+
if (copyArgType === 'String') {
|
|
5980
|
+
const sval = this.getNodeData(node.arg).sval;
|
|
5981
|
+
if (node.defname === 'format') {
|
|
5982
|
+
return `${optName} ${sval}`;
|
|
5983
|
+
}
|
|
5984
|
+
return `${optName} ${quotes_1.QuoteUtils.escape(sval)}`;
|
|
5921
5985
|
}
|
|
5922
|
-
return
|
|
5986
|
+
return `${optName} ${argValue}`;
|
|
5923
5987
|
}
|
|
5924
5988
|
// Handle CREATE OPERATOR and CREATE TYPE context
|
|
5925
5989
|
if (context.parentNodeTypes.includes('DefineStmt')) {
|
|
@@ -6000,6 +6064,10 @@ class Deparser {
|
|
|
6000
6064
|
return `${node.defname} = ${argValue}`;
|
|
6001
6065
|
}
|
|
6002
6066
|
}
|
|
6067
|
+
const argType = this.getNodeType(node.arg);
|
|
6068
|
+
if (argType === 'TypeName' || argType === 'Integer' || argType === 'Float' || argType === 'Boolean') {
|
|
6069
|
+
return `${node.defname} = ${argValue}`;
|
|
6070
|
+
}
|
|
6003
6071
|
const quotedValue = typeof argValue === 'string'
|
|
6004
6072
|
? quotes_1.QuoteUtils.escape(argValue)
|
|
6005
6073
|
: argValue;
|
|
@@ -6433,6 +6501,9 @@ class Deparser {
|
|
|
6433
6501
|
case 'OBJECT_TABCONSTRAINT':
|
|
6434
6502
|
output.push('CONSTRAINT');
|
|
6435
6503
|
break;
|
|
6504
|
+
case 'OBJECT_DOMCONSTRAINT':
|
|
6505
|
+
output.push('CONSTRAINT');
|
|
6506
|
+
break;
|
|
6436
6507
|
case 'OBJECT_TRIGGER':
|
|
6437
6508
|
output.push('TRIGGER');
|
|
6438
6509
|
break;
|
|
@@ -6509,6 +6580,15 @@ class Deparser {
|
|
|
6509
6580
|
output.push(objectParts.join('.'));
|
|
6510
6581
|
}
|
|
6511
6582
|
}
|
|
6583
|
+
else if (node.objtype === 'OBJECT_DOMCONSTRAINT') {
|
|
6584
|
+
if (objectParts.length === 2) {
|
|
6585
|
+
const [domain, constraint] = objectParts;
|
|
6586
|
+
output.push(constraint, 'ON DOMAIN', domain);
|
|
6587
|
+
}
|
|
6588
|
+
else {
|
|
6589
|
+
output.push(objectParts.join('.'));
|
|
6590
|
+
}
|
|
6591
|
+
}
|
|
6512
6592
|
else if (node.objtype === 'OBJECT_TRIGGER') {
|
|
6513
6593
|
if (objectParts.length === 2) {
|
|
6514
6594
|
const [table, trigger] = objectParts;
|
|
@@ -6840,7 +6920,7 @@ class Deparser {
|
|
|
6840
6920
|
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.pubname));
|
|
6841
6921
|
}
|
|
6842
6922
|
if (node.pubobjects && node.pubobjects.length > 0) {
|
|
6843
|
-
output.push('FOR'
|
|
6923
|
+
output.push('FOR');
|
|
6844
6924
|
const tables = list_utils_1.ListUtils.unwrapList(node.pubobjects).map(table => this.visit(table, context));
|
|
6845
6925
|
output.push(tables.join(', '));
|
|
6846
6926
|
}
|
|
@@ -6880,8 +6960,9 @@ class Deparser {
|
|
|
6880
6960
|
if (node.pubname) {
|
|
6881
6961
|
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.pubname));
|
|
6882
6962
|
}
|
|
6883
|
-
|
|
6884
|
-
|
|
6963
|
+
const hasObjects = node.pubobjects && node.pubobjects.length > 0;
|
|
6964
|
+
if (hasObjects) {
|
|
6965
|
+
switch (node.action || 'AP_AddObjects') {
|
|
6885
6966
|
case 'AP_AddObjects':
|
|
6886
6967
|
output.push('ADD');
|
|
6887
6968
|
break;
|
|
@@ -6894,17 +6975,11 @@ class Deparser {
|
|
|
6894
6975
|
default:
|
|
6895
6976
|
throw new Error(`Unsupported AlterPublicationStmt action: ${node.action}`);
|
|
6896
6977
|
}
|
|
6897
|
-
}
|
|
6898
|
-
if (node.for_all_tables) {
|
|
6899
|
-
output.push('FOR ALL TABLES');
|
|
6900
|
-
}
|
|
6901
|
-
else if (node.pubobjects && node.pubobjects.length > 0) {
|
|
6902
|
-
output.push('FOR TABLE');
|
|
6903
6978
|
const objects = list_utils_1.ListUtils.unwrapList(node.pubobjects).map(obj => this.visit(obj, context));
|
|
6904
6979
|
output.push(objects.join(', '));
|
|
6905
6980
|
}
|
|
6906
|
-
if (node.options && node.options.length > 0) {
|
|
6907
|
-
output.push('
|
|
6981
|
+
else if (node.options && node.options.length > 0) {
|
|
6982
|
+
output.push('SET');
|
|
6908
6983
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context));
|
|
6909
6984
|
output.push(`(${options.join(', ')})`);
|
|
6910
6985
|
}
|
|
@@ -6915,42 +6990,67 @@ class Deparser {
|
|
|
6915
6990
|
if (node.subname) {
|
|
6916
6991
|
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.subname));
|
|
6917
6992
|
}
|
|
6918
|
-
|
|
6919
|
-
|
|
6993
|
+
const options = node.options && node.options.length > 0
|
|
6994
|
+
? `(${list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context)).join(', ')})`
|
|
6995
|
+
: null;
|
|
6996
|
+
const publications = node.publication && node.publication.length > 0
|
|
6997
|
+
? list_utils_1.ListUtils.unwrapList(node.publication).map(pub => this.visit(pub, context)).join(', ')
|
|
6998
|
+
: null;
|
|
6999
|
+
{
|
|
7000
|
+
switch (node.kind || 'ALTER_SUBSCRIPTION_OPTIONS') {
|
|
6920
7001
|
case 'ALTER_SUBSCRIPTION_OPTIONS':
|
|
6921
7002
|
output.push('SET');
|
|
7003
|
+
if (options)
|
|
7004
|
+
output.push(options);
|
|
6922
7005
|
break;
|
|
6923
7006
|
case 'ALTER_SUBSCRIPTION_CONNECTION':
|
|
6924
7007
|
output.push('CONNECTION');
|
|
6925
7008
|
if (node.conninfo) {
|
|
6926
|
-
output.push(
|
|
7009
|
+
output.push(quotes_1.QuoteUtils.escape(node.conninfo));
|
|
6927
7010
|
}
|
|
6928
7011
|
break;
|
|
6929
7012
|
case 'ALTER_SUBSCRIPTION_SET_PUBLICATION':
|
|
6930
7013
|
output.push('SET PUBLICATION');
|
|
6931
|
-
if (
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
7014
|
+
if (publications)
|
|
7015
|
+
output.push(publications);
|
|
7016
|
+
if (options)
|
|
7017
|
+
output.push('WITH', options);
|
|
7018
|
+
break;
|
|
7019
|
+
case 'ALTER_SUBSCRIPTION_ADD_PUBLICATION':
|
|
7020
|
+
output.push('ADD PUBLICATION');
|
|
7021
|
+
if (publications)
|
|
7022
|
+
output.push(publications);
|
|
7023
|
+
if (options)
|
|
7024
|
+
output.push('WITH', options);
|
|
7025
|
+
break;
|
|
7026
|
+
case 'ALTER_SUBSCRIPTION_DROP_PUBLICATION':
|
|
7027
|
+
output.push('DROP PUBLICATION');
|
|
7028
|
+
if (publications)
|
|
7029
|
+
output.push(publications);
|
|
7030
|
+
if (options)
|
|
7031
|
+
output.push('WITH', options);
|
|
6935
7032
|
break;
|
|
6936
7033
|
case 'ALTER_SUBSCRIPTION_REFRESH':
|
|
6937
7034
|
output.push('REFRESH PUBLICATION');
|
|
7035
|
+
if (options)
|
|
7036
|
+
output.push('WITH', options);
|
|
6938
7037
|
break;
|
|
6939
|
-
case 'ALTER_SUBSCRIPTION_ENABLED':
|
|
6940
|
-
|
|
7038
|
+
case 'ALTER_SUBSCRIPTION_ENABLED': {
|
|
7039
|
+
const enabled = list_utils_1.ListUtils.unwrapList(node.options).find(opt => opt.DefElem?.defname === 'enabled');
|
|
7040
|
+
const arg = enabled?.DefElem?.arg;
|
|
7041
|
+
const isEnabled = arg?.Boolean ? arg.Boolean.boolval !== false : true;
|
|
7042
|
+
output.push(isEnabled ? 'ENABLE' : 'DISABLE');
|
|
6941
7043
|
break;
|
|
7044
|
+
}
|
|
6942
7045
|
case 'ALTER_SUBSCRIPTION_SKIP':
|
|
6943
7046
|
output.push('SKIP');
|
|
7047
|
+
if (options)
|
|
7048
|
+
output.push(options);
|
|
6944
7049
|
break;
|
|
6945
7050
|
default:
|
|
6946
7051
|
throw new Error(`Unsupported AlterSubscriptionStmt kind: ${node.kind}`);
|
|
6947
7052
|
}
|
|
6948
7053
|
}
|
|
6949
|
-
if (node.options && node.options.length > 0) {
|
|
6950
|
-
output.push('WITH');
|
|
6951
|
-
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context));
|
|
6952
|
-
output.push(`(${options.join(', ')})`);
|
|
6953
|
-
}
|
|
6954
7054
|
return output.join(' ');
|
|
6955
7055
|
}
|
|
6956
7056
|
DropSubscriptionStmt(node, context) {
|
|
@@ -8016,6 +8116,9 @@ class Deparser {
|
|
|
8016
8116
|
if (node.grant_option && node.is_grant) {
|
|
8017
8117
|
output.push('WITH GRANT OPTION');
|
|
8018
8118
|
}
|
|
8119
|
+
if (node.grantor) {
|
|
8120
|
+
output.push('GRANTED BY', this.RoleSpec(node.grantor, context));
|
|
8121
|
+
}
|
|
8019
8122
|
// Only add behavior clauses for REVOKE statements, not for GRANT statements in ALTER DEFAULT PRIVILEGES
|
|
8020
8123
|
if (!node.is_grant) {
|
|
8021
8124
|
if (node.behavior === 'DROP_CASCADE') {
|
|
@@ -8029,57 +8132,34 @@ class Deparser {
|
|
|
8029
8132
|
}
|
|
8030
8133
|
GrantRoleStmt(node, context) {
|
|
8031
8134
|
const output = [];
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
if (adminOption.DefElem && adminOption.DefElem.arg) {
|
|
8052
|
-
adminValue = adminOption.DefElem.arg.Boolean?.boolval;
|
|
8053
|
-
}
|
|
8054
|
-
}
|
|
8055
|
-
if (setOption && setOption.DefElem) {
|
|
8056
|
-
hasSetOption = true;
|
|
8057
|
-
setValue = setOption.DefElem.arg?.Boolean?.boolval;
|
|
8058
|
-
}
|
|
8059
|
-
}
|
|
8135
|
+
const options = list_utils_1.ListUtils.unwrapList(node.opt)
|
|
8136
|
+
.map(opt => opt.DefElem)
|
|
8137
|
+
.filter((opt) => !!opt && !!opt.defname);
|
|
8138
|
+
const optionValue = (opt) => {
|
|
8139
|
+
if (!opt.arg)
|
|
8140
|
+
return true;
|
|
8141
|
+
const argType = this.getNodeType(opt.arg);
|
|
8142
|
+
const argData = this.getNodeData(opt.arg);
|
|
8143
|
+
if (argType === 'Boolean')
|
|
8144
|
+
return argData.boolval !== false;
|
|
8145
|
+
if (argType === 'String')
|
|
8146
|
+
return argData.sval !== 'false';
|
|
8147
|
+
return true;
|
|
8148
|
+
};
|
|
8149
|
+
const roles = list_utils_1.ListUtils.unwrapList(node.granted_roles)
|
|
8150
|
+
.map(role => role.AccessPriv?.priv_name
|
|
8151
|
+
? quotes_1.QuoteUtils.quoteIdentifier(role.AccessPriv.priv_name)
|
|
8152
|
+
: this.visit(role, context))
|
|
8153
|
+
.join(', ');
|
|
8060
8154
|
if (node.is_grant) {
|
|
8061
|
-
output.push('GRANT');
|
|
8155
|
+
output.push('GRANT', roles, 'TO');
|
|
8062
8156
|
}
|
|
8063
8157
|
else {
|
|
8064
8158
|
output.push('REVOKE');
|
|
8065
|
-
if (
|
|
8066
|
-
output.push(
|
|
8067
|
-
}
|
|
8068
|
-
else if (hasAdminOption) {
|
|
8069
|
-
output.push('ADMIN OPTION FOR');
|
|
8159
|
+
if (options.length > 0) {
|
|
8160
|
+
output.push(`${options[0].defname.toUpperCase()} OPTION FOR`);
|
|
8070
8161
|
}
|
|
8071
|
-
|
|
8072
|
-
if (node.granted_roles && node.granted_roles.length > 0) {
|
|
8073
|
-
const roles = list_utils_1.ListUtils.unwrapList(node.granted_roles)
|
|
8074
|
-
.map(role => this.visit(role, context))
|
|
8075
|
-
.join(', ');
|
|
8076
|
-
output.push(roles);
|
|
8077
|
-
}
|
|
8078
|
-
if (node.is_grant) {
|
|
8079
|
-
output.push('TO');
|
|
8080
|
-
}
|
|
8081
|
-
else {
|
|
8082
|
-
output.push('FROM');
|
|
8162
|
+
output.push(roles, 'FROM');
|
|
8083
8163
|
}
|
|
8084
8164
|
if (node.grantee_roles && node.grantee_roles.length > 0) {
|
|
8085
8165
|
const grantees = list_utils_1.ListUtils.unwrapList(node.grantee_roles)
|
|
@@ -8087,38 +8167,15 @@ class Deparser {
|
|
|
8087
8167
|
.join(', ');
|
|
8088
8168
|
output.push(grantees);
|
|
8089
8169
|
}
|
|
8090
|
-
if (node.is_grant) {
|
|
8091
|
-
const withOptions =
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
else {
|
|
8100
|
-
withOptions.push('ADMIN OPTION');
|
|
8101
|
-
}
|
|
8102
|
-
}
|
|
8103
|
-
if (hasInheritOption) {
|
|
8104
|
-
if (inheritValue === true) {
|
|
8105
|
-
withOptions.push('INHERIT OPTION');
|
|
8106
|
-
}
|
|
8107
|
-
else if (inheritValue === false) {
|
|
8108
|
-
withOptions.push('INHERIT FALSE');
|
|
8109
|
-
}
|
|
8110
|
-
}
|
|
8111
|
-
if (hasSetOption) {
|
|
8112
|
-
if (setValue === true) {
|
|
8113
|
-
withOptions.push('SET TRUE');
|
|
8114
|
-
}
|
|
8115
|
-
else if (setValue === false) {
|
|
8116
|
-
withOptions.push('SET FALSE');
|
|
8117
|
-
}
|
|
8118
|
-
}
|
|
8119
|
-
if (withOptions.length > 0) {
|
|
8120
|
-
output.push('WITH', withOptions.join(', '));
|
|
8121
|
-
}
|
|
8170
|
+
if (node.is_grant && options.length > 0) {
|
|
8171
|
+
const withOptions = options.map(opt => `${opt.defname.toUpperCase()} ${optionValue(opt) ? 'TRUE' : 'FALSE'}`);
|
|
8172
|
+
output.push('WITH', withOptions.join(', '));
|
|
8173
|
+
}
|
|
8174
|
+
if (node.grantor) {
|
|
8175
|
+
output.push('GRANTED BY', this.RoleSpec(node.grantor, context));
|
|
8176
|
+
}
|
|
8177
|
+
if (!node.is_grant && node.behavior === 'DROP_CASCADE') {
|
|
8178
|
+
output.push('CASCADE');
|
|
8122
8179
|
}
|
|
8123
8180
|
return output.join(' ');
|
|
8124
8181
|
}
|
|
@@ -8698,10 +8755,9 @@ class Deparser {
|
|
|
8698
8755
|
switch (node.commandType) {
|
|
8699
8756
|
case 'CMD_UPDATE': {
|
|
8700
8757
|
output.push('UPDATE SET');
|
|
8701
|
-
|
|
8702
|
-
.
|
|
8703
|
-
|
|
8704
|
-
output.push(assignments);
|
|
8758
|
+
if (node.targetList && node.targetList.length > 0) {
|
|
8759
|
+
output.push(this.formatUpdateAssignments(node.targetList, context));
|
|
8760
|
+
}
|
|
8705
8761
|
break;
|
|
8706
8762
|
}
|
|
8707
8763
|
case 'CMD_INSERT': {
|
|
@@ -9106,6 +9162,13 @@ class Deparser {
|
|
|
9106
9162
|
output.push('USING');
|
|
9107
9163
|
output.push(node.into.accessMethod);
|
|
9108
9164
|
}
|
|
9165
|
+
if (node.into && node.into.options && node.into.options.length > 0) {
|
|
9166
|
+
output.push('WITH');
|
|
9167
|
+
const options = list_utils_1.ListUtils.unwrapList(node.into.options)
|
|
9168
|
+
.map(option => this.visit(option, context.spawn('CreateStmt')))
|
|
9169
|
+
.join(', ');
|
|
9170
|
+
output.push(`(${options})`);
|
|
9171
|
+
}
|
|
9109
9172
|
if (node.into && node.into.onCommit && node.into.onCommit !== 'ONCOMMIT_NOOP') {
|
|
9110
9173
|
output.push('ON COMMIT');
|
|
9111
9174
|
switch (node.into.onCommit) {
|
|
@@ -9120,17 +9183,13 @@ class Deparser {
|
|
|
9120
9183
|
break;
|
|
9121
9184
|
}
|
|
9122
9185
|
}
|
|
9186
|
+
if (node.into && node.into.tableSpaceName) {
|
|
9187
|
+
output.push('TABLESPACE', quotes_1.QuoteUtils.quoteIdentifier(node.into.tableSpaceName));
|
|
9188
|
+
}
|
|
9123
9189
|
output.push('AS');
|
|
9124
9190
|
if (node.query) {
|
|
9125
9191
|
output.push(this.visit(node.query, context));
|
|
9126
9192
|
}
|
|
9127
|
-
if (node.into && node.into.options && node.into.options.length > 0) {
|
|
9128
|
-
output.push('WITH');
|
|
9129
|
-
const options = list_utils_1.ListUtils.unwrapList(node.into.options)
|
|
9130
|
-
.map(option => this.visit(option, context))
|
|
9131
|
-
.join(', ');
|
|
9132
|
-
output.push(`(${options})`);
|
|
9133
|
-
}
|
|
9134
9193
|
if (node.into && node.into.skipData) {
|
|
9135
9194
|
output.push('WITH NO DATA');
|
|
9136
9195
|
}
|
|
@@ -9603,7 +9662,7 @@ class Deparser {
|
|
|
9603
9662
|
}
|
|
9604
9663
|
if (node.whereClause) {
|
|
9605
9664
|
output.push('WHERE');
|
|
9606
|
-
output.push(this.visit(node.whereClause, context));
|
|
9665
|
+
output.push(`(${this.visit(node.whereClause, context)})`);
|
|
9607
9666
|
}
|
|
9608
9667
|
return output.join(' ');
|
|
9609
9668
|
}
|
|
@@ -9846,24 +9905,182 @@ class Deparser {
|
|
|
9846
9905
|
}
|
|
9847
9906
|
return output.join(' ');
|
|
9848
9907
|
}
|
|
9908
|
+
formatJsonFormat(format) {
|
|
9909
|
+
if (!format || !format.format_type || format.format_type === 'JS_FORMAT_DEFAULT') {
|
|
9910
|
+
return null;
|
|
9911
|
+
}
|
|
9912
|
+
const parts = ['FORMAT JSON'];
|
|
9913
|
+
switch (format.encoding) {
|
|
9914
|
+
case 'JS_ENC_UTF8':
|
|
9915
|
+
parts.push('ENCODING UTF8');
|
|
9916
|
+
break;
|
|
9917
|
+
case 'JS_ENC_UTF16':
|
|
9918
|
+
parts.push('ENCODING UTF16');
|
|
9919
|
+
break;
|
|
9920
|
+
case 'JS_ENC_UTF32':
|
|
9921
|
+
parts.push('ENCODING UTF32');
|
|
9922
|
+
break;
|
|
9923
|
+
}
|
|
9924
|
+
return parts.join(' ');
|
|
9925
|
+
}
|
|
9926
|
+
formatJsonOutput(output, context) {
|
|
9927
|
+
if (!output || !output.typeName)
|
|
9928
|
+
return null;
|
|
9929
|
+
const parts = ['RETURNING', this.TypeName(output.typeName, context)];
|
|
9930
|
+
const format = this.formatJsonFormat(output.returning?.format);
|
|
9931
|
+
if (format)
|
|
9932
|
+
parts.push(format);
|
|
9933
|
+
return parts.join(' ');
|
|
9934
|
+
}
|
|
9935
|
+
formatJsonNullClause(absentOnNull) {
|
|
9936
|
+
return absentOnNull ? 'ABSENT ON NULL' : 'NULL ON NULL';
|
|
9937
|
+
}
|
|
9938
|
+
formatJsonUniqueClause(unique) {
|
|
9939
|
+
return unique ? 'WITH UNIQUE KEYS' : null;
|
|
9940
|
+
}
|
|
9941
|
+
JsonValueExpr(node, context) {
|
|
9942
|
+
const parts = [];
|
|
9943
|
+
if (node.raw_expr) {
|
|
9944
|
+
parts.push(this.visit(node.raw_expr, context));
|
|
9945
|
+
}
|
|
9946
|
+
const format = this.formatJsonFormat(node.format);
|
|
9947
|
+
if (format)
|
|
9948
|
+
parts.push(format);
|
|
9949
|
+
return parts.join(' ');
|
|
9950
|
+
}
|
|
9951
|
+
JsonKeyValue(node, context) {
|
|
9952
|
+
const key = node.key ? this.visit(node.key, context) : '';
|
|
9953
|
+
const value = node.value ? this.JsonValueExpr(node.value, context) : '';
|
|
9954
|
+
return `${key} : ${value}`;
|
|
9955
|
+
}
|
|
9956
|
+
JsonObjectConstructor(node, context) {
|
|
9957
|
+
const args = [];
|
|
9958
|
+
if (node.exprs && node.exprs.length > 0) {
|
|
9959
|
+
args.push(list_utils_1.ListUtils.unwrapList(node.exprs).map(e => this.visit(e, context)).join(', '));
|
|
9960
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
9961
|
+
const unique = this.formatJsonUniqueClause(node.unique);
|
|
9962
|
+
if (unique)
|
|
9963
|
+
args.push(unique);
|
|
9964
|
+
}
|
|
9965
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
9966
|
+
if (output)
|
|
9967
|
+
args.push(output);
|
|
9968
|
+
return `JSON_OBJECT(${args.join(' ')})`;
|
|
9969
|
+
}
|
|
9970
|
+
JsonArrayConstructor(node, context) {
|
|
9971
|
+
const args = [];
|
|
9972
|
+
if (node.exprs && node.exprs.length > 0) {
|
|
9973
|
+
args.push(list_utils_1.ListUtils.unwrapList(node.exprs).map(e => this.visit(e, context)).join(', '));
|
|
9974
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
9975
|
+
}
|
|
9976
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
9977
|
+
if (output)
|
|
9978
|
+
args.push(output);
|
|
9979
|
+
return `JSON_ARRAY(${args.join(' ')})`;
|
|
9980
|
+
}
|
|
9849
9981
|
JsonArrayQueryConstructor(node, context) {
|
|
9850
|
-
const
|
|
9982
|
+
const args = [];
|
|
9851
9983
|
if (node.query) {
|
|
9852
|
-
|
|
9984
|
+
args.push(this.visit(node.query, context));
|
|
9985
|
+
}
|
|
9986
|
+
const format = this.formatJsonFormat(node.format);
|
|
9987
|
+
if (format)
|
|
9988
|
+
args.push(format);
|
|
9989
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
9990
|
+
if (output)
|
|
9991
|
+
args.push(output);
|
|
9992
|
+
return `JSON_ARRAY(${args.join(' ')})`;
|
|
9993
|
+
}
|
|
9994
|
+
formatJsonAggSuffix(ctor, context) {
|
|
9995
|
+
if (!ctor)
|
|
9996
|
+
return '';
|
|
9997
|
+
let result = '';
|
|
9998
|
+
if (ctor.agg_filter) {
|
|
9999
|
+
result += ` FILTER (WHERE ${this.visit(ctor.agg_filter, context)})`;
|
|
9853
10000
|
}
|
|
9854
|
-
if (
|
|
9855
|
-
|
|
10001
|
+
if (ctor.over) {
|
|
10002
|
+
result += this.formatOverClause(ctor.over, context);
|
|
9856
10003
|
}
|
|
9857
|
-
|
|
9858
|
-
|
|
10004
|
+
return result;
|
|
10005
|
+
}
|
|
10006
|
+
JsonObjectAgg(node, context) {
|
|
10007
|
+
const args = [];
|
|
10008
|
+
if (node.arg) {
|
|
10009
|
+
args.push(this.JsonKeyValue(node.arg, context));
|
|
10010
|
+
}
|
|
10011
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
10012
|
+
const unique = this.formatJsonUniqueClause(node.unique);
|
|
10013
|
+
if (unique)
|
|
10014
|
+
args.push(unique);
|
|
10015
|
+
const output = this.formatJsonOutput(node.constructor?.output, context);
|
|
10016
|
+
if (output)
|
|
10017
|
+
args.push(output);
|
|
10018
|
+
return `JSON_OBJECTAGG(${args.join(' ')})${this.formatJsonAggSuffix(node.constructor, context)}`;
|
|
10019
|
+
}
|
|
10020
|
+
JsonArrayAgg(node, context) {
|
|
10021
|
+
const args = [];
|
|
10022
|
+
if (node.arg) {
|
|
10023
|
+
args.push(this.JsonValueExpr(node.arg, context));
|
|
9859
10024
|
}
|
|
9860
|
-
|
|
9861
|
-
|
|
10025
|
+
const aggOrder = node.constructor?.agg_order;
|
|
10026
|
+
if (aggOrder && aggOrder.length > 0) {
|
|
10027
|
+
const orderItems = list_utils_1.ListUtils.unwrapList(aggOrder).map(item => this.visit(item, context));
|
|
10028
|
+
args.push(`ORDER BY ${orderItems.join(', ')}`);
|
|
9862
10029
|
}
|
|
9863
|
-
|
|
9864
|
-
|
|
10030
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
10031
|
+
const output = this.formatJsonOutput(node.constructor?.output, context);
|
|
10032
|
+
if (output)
|
|
10033
|
+
args.push(output);
|
|
10034
|
+
return `JSON_ARRAYAGG(${args.join(' ')})${this.formatJsonAggSuffix(node.constructor, context)}`;
|
|
10035
|
+
}
|
|
10036
|
+
JsonParseExpr(node, context) {
|
|
10037
|
+
const args = [];
|
|
10038
|
+
if (node.expr) {
|
|
10039
|
+
args.push(this.JsonValueExpr(node.expr, context));
|
|
9865
10040
|
}
|
|
9866
|
-
|
|
10041
|
+
const unique = this.formatJsonUniqueClause(node.unique_keys);
|
|
10042
|
+
if (unique)
|
|
10043
|
+
args.push(unique);
|
|
10044
|
+
return `JSON(${args.join(' ')})`;
|
|
10045
|
+
}
|
|
10046
|
+
JsonScalarExpr(node, context) {
|
|
10047
|
+
const expr = node.expr ? this.visit(node.expr, context) : '';
|
|
10048
|
+
return `JSON_SCALAR(${expr})`;
|
|
10049
|
+
}
|
|
10050
|
+
JsonSerializeExpr(node, context) {
|
|
10051
|
+
const args = [];
|
|
10052
|
+
if (node.expr) {
|
|
10053
|
+
args.push(this.JsonValueExpr(node.expr, context));
|
|
10054
|
+
}
|
|
10055
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
10056
|
+
if (output)
|
|
10057
|
+
args.push(output);
|
|
10058
|
+
return `JSON_SERIALIZE(${args.join(' ')})`;
|
|
10059
|
+
}
|
|
10060
|
+
JsonIsPredicate(node, context) {
|
|
10061
|
+
const parts = [];
|
|
10062
|
+
if (node.expr) {
|
|
10063
|
+
parts.push(this.visit(node.expr, context));
|
|
10064
|
+
}
|
|
10065
|
+
const format = this.formatJsonFormat(node.format);
|
|
10066
|
+
if (format)
|
|
10067
|
+
parts.push(format);
|
|
10068
|
+
parts.push('IS JSON');
|
|
10069
|
+
switch (node.item_type) {
|
|
10070
|
+
case 'JS_TYPE_OBJECT':
|
|
10071
|
+
parts.push('OBJECT');
|
|
10072
|
+
break;
|
|
10073
|
+
case 'JS_TYPE_ARRAY':
|
|
10074
|
+
parts.push('ARRAY');
|
|
10075
|
+
break;
|
|
10076
|
+
case 'JS_TYPE_SCALAR':
|
|
10077
|
+
parts.push('SCALAR');
|
|
10078
|
+
break;
|
|
10079
|
+
}
|
|
10080
|
+
if (node.unique_keys) {
|
|
10081
|
+
parts.push('WITH UNIQUE KEYS');
|
|
10082
|
+
}
|
|
10083
|
+
return parts.join(' ');
|
|
9867
10084
|
}
|
|
9868
10085
|
RangeFunction(node, context) {
|
|
9869
10086
|
const output = [];
|