pgsql-deparser 15.1.1 → 15.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -7
- package/deparser/deparser.d.ts +31 -28
- package/deparser/deparser.js +1253 -814
- package/deparser/index.d.ts +3 -1
- package/deparser/index.js +5 -1
- package/deparser/utils/sql-formatter.d.ts +8 -0
- package/deparser/utils/sql-formatter.js +104 -1
- package/esm/deparser/deparser.js +1236 -797
- package/esm/deparser/index.js +3 -1
- package/esm/deparser/utils/sql-formatter.js +103 -1
- package/esm/index.js +63 -7
- package/esm/v15-to-v16.js +16 -5
- package/esm/v15-to-v18-direct.js +66 -0
- package/esm/v16-to-v17.js +50 -1
- package/esm/v17-to-v18.js +209 -0
- package/index.d.ts +13 -4
- package/index.js +66 -6
- package/package.json +3 -2
- package/v15-to-v16.js +16 -5
- package/v15-to-v18-direct.d.ts +23 -0
- package/v15-to-v18-direct.js +70 -0
- package/v16-to-v17.d.ts +3 -0
- package/v16-to-v17.js +50 -1
- package/v17-to-v18.d.ts +55 -0
- package/v17-to-v18.js +213 -0
package/deparser/deparser.js
CHANGED
|
@@ -5,10 +5,29 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.Deparser = void 0;
|
|
8
|
-
const
|
|
9
|
-
const sql_formatter_1 = require("./utils/sql-formatter");
|
|
10
|
-
const quote_utils_1 = require("./utils/quote-utils");
|
|
8
|
+
const quotes_1 = require("@pgsql/quotes");
|
|
11
9
|
const list_utils_1 = require("./utils/list-utils");
|
|
10
|
+
const sql_formatter_1 = require("./utils/sql-formatter");
|
|
11
|
+
const base_1 = require("./visitors/base");
|
|
12
|
+
// WindowDef.frameOptions bit flags (src/include/nodes/parsenodes.h)
|
|
13
|
+
const FRAMEOPTION_NONDEFAULT = 0x00001;
|
|
14
|
+
const FRAMEOPTION_RANGE = 0x00002;
|
|
15
|
+
const FRAMEOPTION_ROWS = 0x00004;
|
|
16
|
+
const FRAMEOPTION_GROUPS = 0x00008;
|
|
17
|
+
const FRAMEOPTION_BETWEEN = 0x00010;
|
|
18
|
+
const FRAMEOPTION_START_UNBOUNDED_PRECEDING = 0x00020;
|
|
19
|
+
const FRAMEOPTION_END_UNBOUNDED_PRECEDING = 0x00040;
|
|
20
|
+
const FRAMEOPTION_START_UNBOUNDED_FOLLOWING = 0x00080;
|
|
21
|
+
const FRAMEOPTION_END_UNBOUNDED_FOLLOWING = 0x00100;
|
|
22
|
+
const FRAMEOPTION_START_CURRENT_ROW = 0x00200;
|
|
23
|
+
const FRAMEOPTION_END_CURRENT_ROW = 0x00400;
|
|
24
|
+
const FRAMEOPTION_START_OFFSET_PRECEDING = 0x00800;
|
|
25
|
+
const FRAMEOPTION_END_OFFSET_PRECEDING = 0x01000;
|
|
26
|
+
const FRAMEOPTION_START_OFFSET_FOLLOWING = 0x02000;
|
|
27
|
+
const FRAMEOPTION_END_OFFSET_FOLLOWING = 0x04000;
|
|
28
|
+
const FRAMEOPTION_EXCLUDE_CURRENT_ROW = 0x08000;
|
|
29
|
+
const FRAMEOPTION_EXCLUDE_GROUP = 0x10000;
|
|
30
|
+
const FRAMEOPTION_EXCLUDE_TIES = 0x20000;
|
|
12
31
|
/**
|
|
13
32
|
* List of real PostgreSQL built-in types as they appear in pg_catalog.pg_type.typname.
|
|
14
33
|
* These are stored in lowercase in PostgreSQL system catalogs.
|
|
@@ -107,6 +126,36 @@ function isWrappedParseResult(obj) {
|
|
|
107
126
|
* The deparser automatically detects bare ParseResult objects for backward
|
|
108
127
|
* compatibility and wraps them internally for consistent processing.
|
|
109
128
|
*/
|
|
129
|
+
function formatBitString(bsval) {
|
|
130
|
+
const quote = (value) => value.replace(/'/g, "''");
|
|
131
|
+
if (/^x[0-9A-Fa-f]*$/.test(bsval)) {
|
|
132
|
+
return `x'${bsval.substring(1)}'`;
|
|
133
|
+
}
|
|
134
|
+
if (bsval.startsWith('b')) {
|
|
135
|
+
return `b'${quote(bsval.substring(1))}'`;
|
|
136
|
+
}
|
|
137
|
+
return `b'${quote(bsval)}'`;
|
|
138
|
+
}
|
|
139
|
+
// A dollar-quoted body ends at the first occurrence of its tag, including one
|
|
140
|
+
// formed by the body's trailing characters plus the closing tag (`...$` + `$$`).
|
|
141
|
+
function dollarTagConflicts(body, tag) {
|
|
142
|
+
return (body + tag).indexOf(tag) < body.length;
|
|
143
|
+
}
|
|
144
|
+
const NUMERIC_LITERAL = /^[+-]?(?:0[xX](?:_?[0-9A-Fa-f])+|0[oO](?:_?[0-7])+|0[bB](?:_?[01])+|(?:\d(?:_?\d)*(?:\.(?:\d(?:_?\d)*)?)?|\.\d(?:_?\d)*)(?:[eE][+-]?\d(?:_?\d)*)?)$/;
|
|
145
|
+
function formatInteger(ival) {
|
|
146
|
+
const value = String(ival);
|
|
147
|
+
if (!/^[+-]?\d+$/.test(value)) {
|
|
148
|
+
throw new Error(`Invalid integer literal: ${value}`);
|
|
149
|
+
}
|
|
150
|
+
return value;
|
|
151
|
+
}
|
|
152
|
+
function formatNumeric(fval) {
|
|
153
|
+
const value = String(fval);
|
|
154
|
+
if (!NUMERIC_LITERAL.test(value)) {
|
|
155
|
+
throw new Error(`Invalid numeric literal: ${value}`);
|
|
156
|
+
}
|
|
157
|
+
return value;
|
|
158
|
+
}
|
|
110
159
|
class Deparser {
|
|
111
160
|
tree;
|
|
112
161
|
options;
|
|
@@ -166,10 +215,19 @@ class Deparser {
|
|
|
166
215
|
*/
|
|
167
216
|
getFunctionDelimiter(body) {
|
|
168
217
|
const delimiter = this.options.functionDelimiter || '$$';
|
|
169
|
-
if (body
|
|
170
|
-
return
|
|
218
|
+
if (!dollarTagConflicts(body, delimiter)) {
|
|
219
|
+
return delimiter;
|
|
171
220
|
}
|
|
172
|
-
|
|
221
|
+
const fallback = this.options.functionDelimiterFallback || '$EOFCODE$';
|
|
222
|
+
if (!dollarTagConflicts(body, fallback)) {
|
|
223
|
+
return fallback;
|
|
224
|
+
}
|
|
225
|
+
const base = fallback.slice(0, -1);
|
|
226
|
+
let counter = 1;
|
|
227
|
+
while (dollarTagConflicts(body, `${base}${counter}$`)) {
|
|
228
|
+
counter++;
|
|
229
|
+
}
|
|
230
|
+
return `${base}${counter}$`;
|
|
173
231
|
}
|
|
174
232
|
/**
|
|
175
233
|
* Maps ObjectType enum values to their corresponding SQL keywords
|
|
@@ -446,12 +504,7 @@ class Deparser {
|
|
|
446
504
|
// Check if single target is complex - if so, use multiline format
|
|
447
505
|
if (this.isComplexSelectTarget(targetNode)) {
|
|
448
506
|
output.push('SELECT' + distinctPart);
|
|
449
|
-
|
|
450
|
-
output.push(target);
|
|
451
|
-
}
|
|
452
|
-
else {
|
|
453
|
-
output.push(context.indent(target));
|
|
454
|
-
}
|
|
507
|
+
output.push(context.indent(target));
|
|
455
508
|
}
|
|
456
509
|
else {
|
|
457
510
|
output.push('SELECT' + distinctPart + ' ' + target);
|
|
@@ -461,9 +514,6 @@ class Deparser {
|
|
|
461
514
|
const targetStrings = targetList
|
|
462
515
|
.map(e => {
|
|
463
516
|
const targetStr = this.visit(e, context.spawn('SelectStmt', { select: true }));
|
|
464
|
-
if (this.containsMultilineStringLiteral(targetStr)) {
|
|
465
|
-
return targetStr;
|
|
466
|
-
}
|
|
467
517
|
return context.indent(targetStr);
|
|
468
518
|
});
|
|
469
519
|
const formattedTargets = targetStrings.join(',' + context.newline());
|
|
@@ -515,9 +565,6 @@ class Deparser {
|
|
|
515
565
|
return context.parens(values.join(', '));
|
|
516
566
|
});
|
|
517
567
|
const indentedTuples = lists.map(tuple => {
|
|
518
|
-
if (this.containsMultilineStringLiteral(tuple)) {
|
|
519
|
-
return tuple;
|
|
520
|
-
}
|
|
521
568
|
return context.indent(tuple);
|
|
522
569
|
});
|
|
523
570
|
output.push(indentedTuples.join(',\n'));
|
|
@@ -537,9 +584,6 @@ class Deparser {
|
|
|
537
584
|
const groupItems = groupList
|
|
538
585
|
.map(e => {
|
|
539
586
|
const groupStr = this.visit(e, context.spawn('SelectStmt', { group: true, indentLevel: context.indentLevel + 1 }));
|
|
540
|
-
if (this.containsMultilineStringLiteral(groupStr)) {
|
|
541
|
-
return groupStr;
|
|
542
|
-
}
|
|
543
587
|
return context.indent(groupStr);
|
|
544
588
|
})
|
|
545
589
|
.join(',' + context.newline());
|
|
@@ -558,12 +602,7 @@ class Deparser {
|
|
|
558
602
|
if (context.isPretty()) {
|
|
559
603
|
output.push('HAVING');
|
|
560
604
|
const havingStr = this.visit(node.havingClause, context);
|
|
561
|
-
|
|
562
|
-
output.push(havingStr);
|
|
563
|
-
}
|
|
564
|
-
else {
|
|
565
|
-
output.push(context.indent(havingStr));
|
|
566
|
-
}
|
|
605
|
+
output.push(context.indent(havingStr));
|
|
567
606
|
}
|
|
568
607
|
else {
|
|
569
608
|
output.push('HAVING');
|
|
@@ -584,9 +623,6 @@ class Deparser {
|
|
|
584
623
|
const sortItems = sortList
|
|
585
624
|
.map(e => {
|
|
586
625
|
const sortStr = this.visit(e, context.spawn('SelectStmt', { sort: true, indentLevel: context.indentLevel + 1 }));
|
|
587
|
-
if (this.containsMultilineStringLiteral(sortStr)) {
|
|
588
|
-
return sortStr;
|
|
589
|
-
}
|
|
590
626
|
return context.indent(sortStr);
|
|
591
627
|
})
|
|
592
628
|
.join(',' + context.newline());
|
|
@@ -662,10 +698,15 @@ class Deparser {
|
|
|
662
698
|
return context.format([leftExpr, operator, rightExpr]);
|
|
663
699
|
}
|
|
664
700
|
else if (rexpr) {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
701
|
+
// Unary operator (e.g., unary minus: - expr)
|
|
702
|
+
const operator = this.deparseOperatorName(name, context);
|
|
703
|
+
let rightExpr = this.visit(rexpr, context);
|
|
704
|
+
// Wrap in parentheses if rexpr is a binary A_Expr to preserve semantics
|
|
705
|
+
// e.g., -(a - b) must stay -(a - b), not become -a - b
|
|
706
|
+
if (rexpr && 'A_Expr' in rexpr && rexpr.A_Expr?.kind === 'AEXPR_OP' && rexpr.A_Expr?.lexpr) {
|
|
707
|
+
rightExpr = context.parens(rightExpr);
|
|
708
|
+
}
|
|
709
|
+
return context.format([operator, rightExpr]);
|
|
669
710
|
}
|
|
670
711
|
break;
|
|
671
712
|
case 'AEXPR_OP_ANY':
|
|
@@ -845,15 +886,15 @@ class Deparser {
|
|
|
845
886
|
getOperatorPrecedence(operator) {
|
|
846
887
|
const precedence = {
|
|
847
888
|
'||': 1, // string concatenation
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
889
|
+
OR: 2, // logical OR
|
|
890
|
+
AND: 3, // logical AND
|
|
891
|
+
NOT: 4, // logical NOT
|
|
892
|
+
IS: 5, // IS NULL, IS NOT NULL, etc.
|
|
893
|
+
IN: 5, // IN, NOT IN
|
|
894
|
+
BETWEEN: 5, // BETWEEN, NOT BETWEEN
|
|
895
|
+
LIKE: 5, // LIKE, ILIKE, SIMILAR TO
|
|
896
|
+
ILIKE: 5,
|
|
897
|
+
SIMILAR: 5,
|
|
857
898
|
'<': 6, // comparison operators
|
|
858
899
|
'<=': 6,
|
|
859
900
|
'>': 6,
|
|
@@ -983,6 +1024,12 @@ class Deparser {
|
|
|
983
1024
|
output.push(context.parens(columnNames.join(', ')));
|
|
984
1025
|
}
|
|
985
1026
|
}
|
|
1027
|
+
if (node.override === 'OVERRIDING_USER_VALUE') {
|
|
1028
|
+
output.push('OVERRIDING USER VALUE');
|
|
1029
|
+
}
|
|
1030
|
+
else if (node.override === 'OVERRIDING_SYSTEM_VALUE') {
|
|
1031
|
+
output.push('OVERRIDING SYSTEM VALUE');
|
|
1032
|
+
}
|
|
986
1033
|
if (node.selectStmt) {
|
|
987
1034
|
output.push(this.visit(node.selectStmt, context));
|
|
988
1035
|
}
|
|
@@ -1025,7 +1072,14 @@ class Deparser {
|
|
|
1025
1072
|
else {
|
|
1026
1073
|
const updateContext = context.spawn('UpdateStmt', { update: true });
|
|
1027
1074
|
const targets = targetList.map(target => this.visit(target, updateContext));
|
|
1028
|
-
|
|
1075
|
+
if (context.isPretty()) {
|
|
1076
|
+
// Put each assignment on its own line for pretty printing
|
|
1077
|
+
const indentedTargets = targets.map(target => context.indent(target));
|
|
1078
|
+
output[output.length - 1] += '\n' + indentedTargets.join(',\n');
|
|
1079
|
+
}
|
|
1080
|
+
else {
|
|
1081
|
+
output.push(targets.join(', '));
|
|
1082
|
+
}
|
|
1029
1083
|
}
|
|
1030
1084
|
}
|
|
1031
1085
|
if (node.onConflictClause.whereClause) {
|
|
@@ -1037,11 +1091,8 @@ class Deparser {
|
|
|
1037
1091
|
output.push('DO NOTHING');
|
|
1038
1092
|
}
|
|
1039
1093
|
}
|
|
1040
|
-
if (node.
|
|
1041
|
-
output.push(
|
|
1042
|
-
const returningList = list_utils_1.ListUtils.unwrapList(node.returningList);
|
|
1043
|
-
const returns = returningList.map(ret => this.visit(ret, context));
|
|
1044
|
-
output.push(returns.join(', '));
|
|
1094
|
+
if (node.returningClause) {
|
|
1095
|
+
output.push(this.ReturningClause(node.returningClause, context));
|
|
1045
1096
|
}
|
|
1046
1097
|
return output.join(' ');
|
|
1047
1098
|
}
|
|
@@ -1055,38 +1106,8 @@ class Deparser {
|
|
|
1055
1106
|
output.push(this.RangeVar(node.relation, context));
|
|
1056
1107
|
}
|
|
1057
1108
|
output.push('SET');
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
const firstTarget = targetList[0];
|
|
1061
|
-
const processedTargets = new Set();
|
|
1062
|
-
const assignmentParts = [];
|
|
1063
|
-
for (let i = 0; i < targetList.length; i++) {
|
|
1064
|
-
if (processedTargets.has(i))
|
|
1065
|
-
continue;
|
|
1066
|
-
const target = targetList[i];
|
|
1067
|
-
const multiAssignRef = target.ResTarget?.val?.MultiAssignRef;
|
|
1068
|
-
if (multiAssignRef) {
|
|
1069
|
-
const relatedTargets = [];
|
|
1070
|
-
for (let j = i; j < targetList.length; j++) {
|
|
1071
|
-
const otherTarget = targetList[j];
|
|
1072
|
-
const otherMultiAssignRef = otherTarget.ResTarget?.val?.MultiAssignRef;
|
|
1073
|
-
if (otherMultiAssignRef &&
|
|
1074
|
-
JSON.stringify(otherMultiAssignRef.source) === JSON.stringify(multiAssignRef.source)) {
|
|
1075
|
-
relatedTargets.push(otherTarget);
|
|
1076
|
-
processedTargets.add(j);
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
const names = relatedTargets.map(t => t.ResTarget.name);
|
|
1080
|
-
const multiAssignment = `${context.parens(names.join(', '))} = ${this.visit(multiAssignRef.source, context)}`;
|
|
1081
|
-
assignmentParts.push(multiAssignment);
|
|
1082
|
-
}
|
|
1083
|
-
else {
|
|
1084
|
-
// Handle regular single-column assignment
|
|
1085
|
-
assignmentParts.push(this.visit(target, context.spawn('UpdateStmt', { update: true })));
|
|
1086
|
-
processedTargets.add(i);
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
output.push(assignmentParts.join(','));
|
|
1109
|
+
if (node.targetList && node.targetList.length > 0) {
|
|
1110
|
+
output.push(this.formatUpdateAssignments(node.targetList, context));
|
|
1090
1111
|
}
|
|
1091
1112
|
if (node.fromClause) {
|
|
1092
1113
|
output.push('FROM');
|
|
@@ -1098,12 +1119,41 @@ class Deparser {
|
|
|
1098
1119
|
output.push('WHERE');
|
|
1099
1120
|
output.push(this.visit(node.whereClause, context));
|
|
1100
1121
|
}
|
|
1101
|
-
if (node.
|
|
1102
|
-
output.push(
|
|
1103
|
-
output.push(this.deparseReturningList(node.returningList, context));
|
|
1122
|
+
if (node.returningClause) {
|
|
1123
|
+
output.push(this.ReturningClause(node.returningClause, context));
|
|
1104
1124
|
}
|
|
1105
1125
|
return output.join(' ');
|
|
1106
1126
|
}
|
|
1127
|
+
formatUpdateAssignments(targets, context) {
|
|
1128
|
+
const targetList = list_utils_1.ListUtils.unwrapList(targets);
|
|
1129
|
+
const processedTargets = new Set();
|
|
1130
|
+
const assignmentParts = [];
|
|
1131
|
+
for (let i = 0; i < targetList.length; i++) {
|
|
1132
|
+
if (processedTargets.has(i))
|
|
1133
|
+
continue;
|
|
1134
|
+
const target = targetList[i];
|
|
1135
|
+
const multiAssignRef = target.ResTarget?.val?.MultiAssignRef;
|
|
1136
|
+
if (multiAssignRef) {
|
|
1137
|
+
const relatedTargets = [];
|
|
1138
|
+
for (let j = i; j < targetList.length; j++) {
|
|
1139
|
+
const otherTarget = targetList[j];
|
|
1140
|
+
const otherMultiAssignRef = otherTarget.ResTarget?.val?.MultiAssignRef;
|
|
1141
|
+
if (otherMultiAssignRef &&
|
|
1142
|
+
JSON.stringify(otherMultiAssignRef.source) === JSON.stringify(multiAssignRef.source)) {
|
|
1143
|
+
relatedTargets.push(otherTarget);
|
|
1144
|
+
processedTargets.add(j);
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
const names = relatedTargets.map(t => quotes_1.QuoteUtils.quoteIdentifier(t.ResTarget.name));
|
|
1148
|
+
assignmentParts.push(`${context.parens(names.join(', '))} = ${this.visit(multiAssignRef.source, context)}`);
|
|
1149
|
+
}
|
|
1150
|
+
else {
|
|
1151
|
+
assignmentParts.push(this.visit(target, context.spawn('UpdateStmt', { update: true })));
|
|
1152
|
+
processedTargets.add(i);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
return assignmentParts.join(', ');
|
|
1156
|
+
}
|
|
1107
1157
|
DeleteStmt(node, context) {
|
|
1108
1158
|
try {
|
|
1109
1159
|
const output = [];
|
|
@@ -1151,13 +1201,12 @@ class Deparser {
|
|
|
1151
1201
|
throw new Error(`Error deparsing DeleteStmt: ${error instanceof Error ? error.message : String(error)}`);
|
|
1152
1202
|
}
|
|
1153
1203
|
}
|
|
1154
|
-
if (node.
|
|
1155
|
-
output.push('RETURNING');
|
|
1204
|
+
if (node.returningClause) {
|
|
1156
1205
|
try {
|
|
1157
|
-
output.push(this.
|
|
1206
|
+
output.push(this.ReturningClause(node.returningClause, context));
|
|
1158
1207
|
}
|
|
1159
1208
|
catch (error) {
|
|
1160
|
-
console.warn(`Error processing
|
|
1209
|
+
console.warn(`Error processing returningClause in DeleteStmt: ${error instanceof Error ? error.message : String(error)}`);
|
|
1161
1210
|
throw new Error(`Error deparsing DeleteStmt: ${error instanceof Error ? error.message : String(error)}`);
|
|
1162
1211
|
}
|
|
1163
1212
|
}
|
|
@@ -1178,9 +1227,6 @@ class Deparser {
|
|
|
1178
1227
|
const cteStrings = ctes.map((cte, index) => {
|
|
1179
1228
|
const cteStr = this.visit(cte, context);
|
|
1180
1229
|
const prefix = index === 0 ? context.newline() : ',' + context.newline();
|
|
1181
|
-
if (this.containsMultilineStringLiteral(cteStr)) {
|
|
1182
|
-
return prefix + cteStr;
|
|
1183
|
-
}
|
|
1184
1230
|
return prefix + context.indent(cteStr);
|
|
1185
1231
|
});
|
|
1186
1232
|
output.push(cteStrings.join(''));
|
|
@@ -1195,12 +1241,12 @@ class Deparser {
|
|
|
1195
1241
|
ResTarget(node, context) {
|
|
1196
1242
|
const output = [];
|
|
1197
1243
|
if (context.update && node.name) {
|
|
1198
|
-
output.push(
|
|
1244
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
1199
1245
|
// Handle indirection (array indexing, field access, etc.)
|
|
1200
1246
|
if (node.indirection && node.indirection.length > 0) {
|
|
1201
1247
|
const indirectionStrs = list_utils_1.ListUtils.unwrapList(node.indirection).map(item => {
|
|
1202
1248
|
if (item.String) {
|
|
1203
|
-
return `.${
|
|
1249
|
+
return `.${quotes_1.QuoteUtils.quoteIdentifierAfterDot(item.String.sval || item.String.str)}`;
|
|
1204
1250
|
}
|
|
1205
1251
|
return this.visit(item, context);
|
|
1206
1252
|
});
|
|
@@ -1212,12 +1258,12 @@ class Deparser {
|
|
|
1212
1258
|
}
|
|
1213
1259
|
}
|
|
1214
1260
|
else if (context.insertColumns && node.name) {
|
|
1215
|
-
output.push(
|
|
1261
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
1216
1262
|
// Handle indirection for INSERT column lists (e.g., q.c1.r)
|
|
1217
1263
|
if (node.indirection && node.indirection.length > 0) {
|
|
1218
1264
|
const indirectionStrs = list_utils_1.ListUtils.unwrapList(node.indirection).map(item => {
|
|
1219
1265
|
if (item.String) {
|
|
1220
|
-
return `.${
|
|
1266
|
+
return `.${quotes_1.QuoteUtils.quoteIdentifierAfterDot(item.String.sval || item.String.str)}`;
|
|
1221
1267
|
}
|
|
1222
1268
|
return this.visit(item, context);
|
|
1223
1269
|
});
|
|
@@ -1230,11 +1276,53 @@ class Deparser {
|
|
|
1230
1276
|
}
|
|
1231
1277
|
if (node.name) {
|
|
1232
1278
|
output.push('AS');
|
|
1233
|
-
output.push(
|
|
1279
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
1234
1280
|
}
|
|
1235
1281
|
}
|
|
1236
1282
|
return output.join(' ');
|
|
1237
1283
|
}
|
|
1284
|
+
ATAlterConstraint(node, context) {
|
|
1285
|
+
const output = ['ALTER CONSTRAINT'];
|
|
1286
|
+
if (node.conname) {
|
|
1287
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.conname));
|
|
1288
|
+
}
|
|
1289
|
+
if (node.alterEnforceability) {
|
|
1290
|
+
output.push(node.is_enforced ? 'ENFORCED' : 'NOT ENFORCED');
|
|
1291
|
+
}
|
|
1292
|
+
if (node.alterDeferrability) {
|
|
1293
|
+
output.push(node.deferrable ? 'DEFERRABLE' : 'NOT DEFERRABLE');
|
|
1294
|
+
if (node.initdeferred) {
|
|
1295
|
+
output.push('INITIALLY DEFERRED');
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
if (node.alterInheritability) {
|
|
1299
|
+
output.push(node.noinherit ? 'NO INHERIT' : 'INHERIT');
|
|
1300
|
+
}
|
|
1301
|
+
return output.join(' ');
|
|
1302
|
+
}
|
|
1303
|
+
deparseKeyAttrs(attrs, withPeriod, context) {
|
|
1304
|
+
const items = list_utils_1.ListUtils.unwrapList(attrs).map(attr => this.visit(attr, context));
|
|
1305
|
+
if (withPeriod && items.length > 0) {
|
|
1306
|
+
items[items.length - 1] = `PERIOD ${items[items.length - 1]}`;
|
|
1307
|
+
}
|
|
1308
|
+
return items.join(', ');
|
|
1309
|
+
}
|
|
1310
|
+
ReturningClause(node, context) {
|
|
1311
|
+
const output = ['RETURNING'];
|
|
1312
|
+
if (node.options && node.options.length > 0) {
|
|
1313
|
+
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
1314
|
+
.map(option => this.visit(option, context));
|
|
1315
|
+
output.push(`WITH (${options.join(', ')})`);
|
|
1316
|
+
}
|
|
1317
|
+
if (node.exprs && node.exprs.length > 0) {
|
|
1318
|
+
output.push(this.deparseReturningList(node.exprs, context));
|
|
1319
|
+
}
|
|
1320
|
+
return output.join(' ');
|
|
1321
|
+
}
|
|
1322
|
+
ReturningOption(node, context) {
|
|
1323
|
+
const keyword = node.option === 'RETURNING_OPTION_NEW' ? 'NEW' : 'OLD';
|
|
1324
|
+
return `${keyword} AS ${quotes_1.QuoteUtils.quoteIdentifier(node.value)}`;
|
|
1325
|
+
}
|
|
1238
1326
|
deparseReturningList(list, context) {
|
|
1239
1327
|
return list_utils_1.ListUtils.unwrapList(list)
|
|
1240
1328
|
.filter(item => item != null && this.getNodeType(item) !== 'undefined')
|
|
@@ -1244,7 +1332,7 @@ class Deparser {
|
|
|
1244
1332
|
if (this.getNodeType(item) === 'ResTarget') {
|
|
1245
1333
|
const resTarget = this.getNodeData(item);
|
|
1246
1334
|
const val = resTarget.val ? this.visit(resTarget.val, context) : '';
|
|
1247
|
-
const alias = resTarget.name ? ` AS ${
|
|
1335
|
+
const alias = resTarget.name ? ` AS ${quotes_1.QuoteUtils.quoteIdentifier(resTarget.name)}` : '';
|
|
1248
1336
|
return val + alias;
|
|
1249
1337
|
}
|
|
1250
1338
|
else {
|
|
@@ -1299,7 +1387,8 @@ class Deparser {
|
|
|
1299
1387
|
FuncCall(node, context) {
|
|
1300
1388
|
const funcname = list_utils_1.ListUtils.unwrapList(node.funcname);
|
|
1301
1389
|
const args = list_utils_1.ListUtils.unwrapList(node.args);
|
|
1302
|
-
const
|
|
1390
|
+
const funcnameParts = funcname.map((n) => n.String?.sval || n.String?.str || '').filter((s) => s);
|
|
1391
|
+
const name = quotes_1.QuoteUtils.quoteDottedName(funcnameParts);
|
|
1303
1392
|
// Handle special SQL syntax functions like XMLEXISTS and EXTRACT
|
|
1304
1393
|
if (node.funcformat === 'COERCE_SQL_SYNTAX' && name === 'pg_catalog.xmlexists' && args.length >= 2) {
|
|
1305
1394
|
const xpath = this.visit(args[0], context);
|
|
@@ -1308,8 +1397,15 @@ class Deparser {
|
|
|
1308
1397
|
}
|
|
1309
1398
|
// Handle EXTRACT function with SQL syntax
|
|
1310
1399
|
if (node.funcformat === 'COERCE_SQL_SYNTAX' && name === 'pg_catalog.extract' && args.length >= 2) {
|
|
1311
|
-
|
|
1400
|
+
let field = this.visit(args[0], context);
|
|
1312
1401
|
const source = this.visit(args[1], context);
|
|
1402
|
+
// EXTRACT requires an unquoted uppercase keyword (EPOCH, YEAR, etc.)
|
|
1403
|
+
// but A_Const sval deparsing wraps it in single quotes — strip and uppercase
|
|
1404
|
+
// only when it is spelled the way the bare-keyword form parses back
|
|
1405
|
+
if (/^'(?:year|month|day|hour|minute|second)'$/.test(field)
|
|
1406
|
+
|| (/^'[a-z_][a-z0-9_]*'$/.test(field) && (0, quotes_1.keywordKindOf)(field.slice(1, -1)) === 'NO_KEYWORD')) {
|
|
1407
|
+
field = field.slice(1, -1).toUpperCase();
|
|
1408
|
+
}
|
|
1313
1409
|
return `EXTRACT(${field} FROM ${source})`;
|
|
1314
1410
|
}
|
|
1315
1411
|
// Handle TRIM function with SQL syntax (TRIM TRAILING/LEADING/BOTH)
|
|
@@ -1469,43 +1565,41 @@ class Deparser {
|
|
|
1469
1565
|
result += ` FILTER (WHERE ${this.visit(node.agg_filter, context)})`;
|
|
1470
1566
|
}
|
|
1471
1567
|
if (node.over) {
|
|
1472
|
-
|
|
1473
|
-
if (node.over.name) {
|
|
1474
|
-
result += ` OVER ${node.over.name}`;
|
|
1475
|
-
}
|
|
1476
|
-
else {
|
|
1477
|
-
const windowParts = [];
|
|
1478
|
-
if (node.over.partitionClause) {
|
|
1479
|
-
const partitions = list_utils_1.ListUtils.unwrapList(node.over.partitionClause);
|
|
1480
|
-
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
1481
|
-
windowParts.push(`PARTITION BY ${partitionStrs.join(', ')}`);
|
|
1482
|
-
}
|
|
1483
|
-
if (node.over.orderClause) {
|
|
1484
|
-
const orders = list_utils_1.ListUtils.unwrapList(node.over.orderClause);
|
|
1485
|
-
const orderStrs = orders.map(o => this.visit(o, context));
|
|
1486
|
-
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
1487
|
-
}
|
|
1488
|
-
// Handle window frame specifications using the dedicated formatWindowFrame method
|
|
1489
|
-
const frameClause = this.formatWindowFrame(node.over, context.spawn('FuncCall'));
|
|
1490
|
-
if (frameClause) {
|
|
1491
|
-
windowParts.push(frameClause);
|
|
1492
|
-
}
|
|
1493
|
-
if (windowParts.length > 0) {
|
|
1494
|
-
if (context.isPretty() && windowParts.length > 1) {
|
|
1495
|
-
const formattedParts = windowParts.map(part => context.indent(part));
|
|
1496
|
-
result += ` OVER (${context.newline()}${formattedParts.join(context.newline())}${context.newline()})`;
|
|
1497
|
-
}
|
|
1498
|
-
else {
|
|
1499
|
-
result += ` OVER (${windowParts.join(' ')})`;
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
|
-
else {
|
|
1503
|
-
result += ` OVER ()`;
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1568
|
+
result += this.formatOverClause(node.over, context);
|
|
1506
1569
|
}
|
|
1507
1570
|
return result;
|
|
1508
1571
|
}
|
|
1572
|
+
formatOverClause(over, context) {
|
|
1573
|
+
if (over.name) {
|
|
1574
|
+
return ` OVER ${over.name}`;
|
|
1575
|
+
}
|
|
1576
|
+
const windowParts = [];
|
|
1577
|
+
if (over.refname) {
|
|
1578
|
+
windowParts.push(over.refname);
|
|
1579
|
+
}
|
|
1580
|
+
if (over.partitionClause) {
|
|
1581
|
+
const partitions = list_utils_1.ListUtils.unwrapList(over.partitionClause);
|
|
1582
|
+
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
1583
|
+
windowParts.push(`PARTITION BY ${partitionStrs.join(', ')}`);
|
|
1584
|
+
}
|
|
1585
|
+
if (over.orderClause) {
|
|
1586
|
+
const orders = list_utils_1.ListUtils.unwrapList(over.orderClause);
|
|
1587
|
+
const orderStrs = orders.map(o => this.visit(o, context));
|
|
1588
|
+
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
1589
|
+
}
|
|
1590
|
+
const frameClause = this.formatWindowFrame(over, context.spawn('FuncCall'));
|
|
1591
|
+
if (frameClause) {
|
|
1592
|
+
windowParts.push(frameClause);
|
|
1593
|
+
}
|
|
1594
|
+
if (windowParts.length === 0) {
|
|
1595
|
+
return ' OVER ()';
|
|
1596
|
+
}
|
|
1597
|
+
if (context.isPretty() && windowParts.length > 1) {
|
|
1598
|
+
const formattedParts = windowParts.map(part => context.indent(part));
|
|
1599
|
+
return ` OVER (${context.newline()}${formattedParts.join(context.newline())}${context.newline()})`;
|
|
1600
|
+
}
|
|
1601
|
+
return ` OVER (${windowParts.join(' ')})`;
|
|
1602
|
+
}
|
|
1509
1603
|
FuncExpr(node, context) {
|
|
1510
1604
|
const funcName = `func_${node.funcid}`;
|
|
1511
1605
|
const args = node.args ? list_utils_1.ListUtils.unwrapList(node.args).map(arg => this.visit(arg, context)).join(', ') : '';
|
|
@@ -1516,61 +1610,61 @@ class Deparser {
|
|
|
1516
1610
|
if (nodeAny.ival !== undefined) {
|
|
1517
1611
|
if (typeof nodeAny.ival === 'object' && nodeAny.ival !== null) {
|
|
1518
1612
|
if (nodeAny.ival.ival !== undefined) {
|
|
1519
|
-
return nodeAny.ival.ival
|
|
1613
|
+
return formatInteger(nodeAny.ival.ival);
|
|
1520
1614
|
}
|
|
1521
1615
|
else if (Object.keys(nodeAny.ival).length === 0) {
|
|
1522
1616
|
return '0';
|
|
1523
1617
|
}
|
|
1524
1618
|
else {
|
|
1525
|
-
return nodeAny.ival
|
|
1619
|
+
return formatInteger(nodeAny.ival);
|
|
1526
1620
|
}
|
|
1527
1621
|
}
|
|
1528
1622
|
else if (nodeAny.ival === null) {
|
|
1529
1623
|
return 'NULL';
|
|
1530
1624
|
}
|
|
1531
1625
|
else {
|
|
1532
|
-
return nodeAny.ival
|
|
1626
|
+
return formatInteger(nodeAny.ival);
|
|
1533
1627
|
}
|
|
1534
1628
|
}
|
|
1535
1629
|
else if (nodeAny.fval !== undefined) {
|
|
1536
1630
|
if (typeof nodeAny.fval === 'object' && nodeAny.fval !== null) {
|
|
1537
1631
|
if (nodeAny.fval.fval !== undefined) {
|
|
1538
|
-
return nodeAny.fval.fval
|
|
1632
|
+
return formatNumeric(nodeAny.fval.fval);
|
|
1539
1633
|
}
|
|
1540
1634
|
else if (Object.keys(nodeAny.fval).length === 0) {
|
|
1541
1635
|
return '0.0';
|
|
1542
1636
|
}
|
|
1543
1637
|
else {
|
|
1544
|
-
return nodeAny.fval
|
|
1638
|
+
return formatNumeric(nodeAny.fval);
|
|
1545
1639
|
}
|
|
1546
1640
|
}
|
|
1547
1641
|
else if (nodeAny.fval === null) {
|
|
1548
1642
|
return 'NULL';
|
|
1549
1643
|
}
|
|
1550
1644
|
else {
|
|
1551
|
-
return nodeAny.fval
|
|
1645
|
+
return formatNumeric(nodeAny.fval);
|
|
1552
1646
|
}
|
|
1553
1647
|
}
|
|
1554
1648
|
else if (nodeAny.sval !== undefined) {
|
|
1555
1649
|
if (typeof nodeAny.sval === 'object' && nodeAny.sval !== null) {
|
|
1556
1650
|
if (nodeAny.sval.sval !== undefined) {
|
|
1557
|
-
return
|
|
1651
|
+
return quotes_1.QuoteUtils.formatEString(nodeAny.sval.sval);
|
|
1558
1652
|
}
|
|
1559
1653
|
else if (nodeAny.sval.String && nodeAny.sval.String.sval !== undefined) {
|
|
1560
|
-
return
|
|
1654
|
+
return quotes_1.QuoteUtils.formatEString(nodeAny.sval.String.sval);
|
|
1561
1655
|
}
|
|
1562
1656
|
else if (Object.keys(nodeAny.sval).length === 0) {
|
|
1563
1657
|
return "''";
|
|
1564
1658
|
}
|
|
1565
1659
|
else {
|
|
1566
|
-
return
|
|
1660
|
+
return quotes_1.QuoteUtils.formatEString(nodeAny.sval.toString());
|
|
1567
1661
|
}
|
|
1568
1662
|
}
|
|
1569
1663
|
else if (nodeAny.sval === null) {
|
|
1570
1664
|
return 'NULL';
|
|
1571
1665
|
}
|
|
1572
1666
|
else {
|
|
1573
|
-
return
|
|
1667
|
+
return quotes_1.QuoteUtils.formatEString(nodeAny.sval);
|
|
1574
1668
|
}
|
|
1575
1669
|
}
|
|
1576
1670
|
else if (nodeAny.boolval !== undefined) {
|
|
@@ -1595,15 +1689,7 @@ class Deparser {
|
|
|
1595
1689
|
else if (nodeAny.bsval !== undefined) {
|
|
1596
1690
|
if (typeof nodeAny.bsval === 'object' && nodeAny.bsval !== null) {
|
|
1597
1691
|
if (nodeAny.bsval.bsval !== undefined) {
|
|
1598
|
-
|
|
1599
|
-
// Check if this is a hexadecimal bit string (starts with x and contains only hex digits)
|
|
1600
|
-
if (bsval.startsWith('x') && /^x[0-9A-Fa-f]+$/.test(bsval)) {
|
|
1601
|
-
return `x'${bsval.substring(1)}'`;
|
|
1602
|
-
}
|
|
1603
|
-
if (bsval.startsWith('b')) {
|
|
1604
|
-
return `b'${bsval.substring(1)}'`;
|
|
1605
|
-
}
|
|
1606
|
-
return `b'${bsval}'`;
|
|
1692
|
+
return formatBitString(nodeAny.bsval.bsval);
|
|
1607
1693
|
}
|
|
1608
1694
|
else if (Object.keys(nodeAny.bsval).length === 0) {
|
|
1609
1695
|
return "''";
|
|
@@ -1616,32 +1702,24 @@ class Deparser {
|
|
|
1616
1702
|
return 'NULL';
|
|
1617
1703
|
}
|
|
1618
1704
|
else {
|
|
1619
|
-
|
|
1620
|
-
// Check if this is a hexadecimal bit string (starts with x and contains only hex digits)
|
|
1621
|
-
if (bsval.startsWith('x') && /^x[0-9A-Fa-f]+$/.test(bsval)) {
|
|
1622
|
-
return `x'${bsval.substring(1)}'`;
|
|
1623
|
-
}
|
|
1624
|
-
if (bsval.startsWith('b')) {
|
|
1625
|
-
return `b'${bsval.substring(1)}'`;
|
|
1626
|
-
}
|
|
1627
|
-
return `b'${bsval}'`;
|
|
1705
|
+
return formatBitString(nodeAny.bsval);
|
|
1628
1706
|
}
|
|
1629
1707
|
}
|
|
1630
1708
|
if (nodeAny.val) {
|
|
1631
1709
|
if (nodeAny.val.Integer?.ival !== undefined) {
|
|
1632
|
-
return nodeAny.val.Integer.ival
|
|
1710
|
+
return formatInteger(nodeAny.val.Integer.ival);
|
|
1633
1711
|
}
|
|
1634
1712
|
else if (nodeAny.val.Float?.fval !== undefined) {
|
|
1635
|
-
return nodeAny.val.Float.fval
|
|
1713
|
+
return formatNumeric(nodeAny.val.Float.fval);
|
|
1636
1714
|
}
|
|
1637
1715
|
else if (nodeAny.val.String?.sval !== undefined) {
|
|
1638
|
-
return
|
|
1716
|
+
return quotes_1.QuoteUtils.escape(nodeAny.val.String.sval);
|
|
1639
1717
|
}
|
|
1640
1718
|
else if (nodeAny.val.Boolean?.boolval !== undefined) {
|
|
1641
1719
|
return nodeAny.val.Boolean.boolval ? 'true' : 'false';
|
|
1642
1720
|
}
|
|
1643
1721
|
else if (nodeAny.val.BitString?.bsval !== undefined) {
|
|
1644
|
-
return nodeAny.val.BitString.bsval;
|
|
1722
|
+
return formatBitString(nodeAny.val.BitString.bsval);
|
|
1645
1723
|
}
|
|
1646
1724
|
}
|
|
1647
1725
|
if (nodeAny.isnull === true) {
|
|
@@ -1653,21 +1731,21 @@ class Deparser {
|
|
|
1653
1731
|
}
|
|
1654
1732
|
if (nodeAny.Integer !== undefined) {
|
|
1655
1733
|
if (typeof nodeAny.Integer === 'object' && nodeAny.Integer.ival !== undefined) {
|
|
1656
|
-
return nodeAny.Integer.ival
|
|
1734
|
+
return formatInteger(nodeAny.Integer.ival);
|
|
1657
1735
|
}
|
|
1658
|
-
return nodeAny.Integer
|
|
1736
|
+
return formatInteger(nodeAny.Integer);
|
|
1659
1737
|
}
|
|
1660
1738
|
if (nodeAny.Float !== undefined) {
|
|
1661
1739
|
if (typeof nodeAny.Float === 'object' && nodeAny.Float.fval !== undefined) {
|
|
1662
|
-
return nodeAny.Float.fval
|
|
1740
|
+
return formatNumeric(nodeAny.Float.fval);
|
|
1663
1741
|
}
|
|
1664
|
-
return nodeAny.Float
|
|
1742
|
+
return formatNumeric(nodeAny.Float);
|
|
1665
1743
|
}
|
|
1666
1744
|
if (nodeAny.String !== undefined) {
|
|
1667
1745
|
if (typeof nodeAny.String === 'object' && nodeAny.String.sval !== undefined) {
|
|
1668
|
-
return
|
|
1746
|
+
return quotes_1.QuoteUtils.escape(nodeAny.String.sval);
|
|
1669
1747
|
}
|
|
1670
|
-
return
|
|
1748
|
+
return quotes_1.QuoteUtils.escape(nodeAny.String);
|
|
1671
1749
|
}
|
|
1672
1750
|
if (Object.keys(nodeAny).length === 0) {
|
|
1673
1751
|
return 'NULL';
|
|
@@ -1681,7 +1759,7 @@ class Deparser {
|
|
|
1681
1759
|
const fields = list_utils_1.ListUtils.unwrapList(node.fields);
|
|
1682
1760
|
return fields.map(field => {
|
|
1683
1761
|
if (field.String) {
|
|
1684
|
-
return
|
|
1762
|
+
return quotes_1.QuoteUtils.quoteIdentifier(field.String.sval || field.String.str);
|
|
1685
1763
|
}
|
|
1686
1764
|
else if (field.A_Star) {
|
|
1687
1765
|
return '*';
|
|
@@ -1758,8 +1836,7 @@ class Deparser {
|
|
|
1758
1836
|
}
|
|
1759
1837
|
return output.join(' ');
|
|
1760
1838
|
}
|
|
1761
|
-
|
|
1762
|
-
let result = mods(quotedTypeName, args);
|
|
1839
|
+
let result = mods(quotes_1.QuoteUtils.quoteIdentifierTypeName(typeName), args);
|
|
1763
1840
|
if (node.arrayBounds && node.arrayBounds.length > 0) {
|
|
1764
1841
|
result += formatArrayBounds(node.arrayBounds);
|
|
1765
1842
|
}
|
|
@@ -1855,8 +1932,9 @@ class Deparser {
|
|
|
1855
1932
|
return output.join(' ');
|
|
1856
1933
|
}
|
|
1857
1934
|
}
|
|
1858
|
-
|
|
1859
|
-
|
|
1935
|
+
// Use type-name quoting for non-pg_catalog types
|
|
1936
|
+
// This allows keywords like 'json', 'int', 'boolean' to remain unquoted in type positions
|
|
1937
|
+
let result = mods(quotes_1.QuoteUtils.quoteTypeDottedName(names), args);
|
|
1860
1938
|
if (node.arrayBounds && node.arrayBounds.length > 0) {
|
|
1861
1939
|
result += formatArrayBounds(node.arrayBounds);
|
|
1862
1940
|
}
|
|
@@ -1894,17 +1972,17 @@ class Deparser {
|
|
|
1894
1972
|
}
|
|
1895
1973
|
let tableName = '';
|
|
1896
1974
|
if (node.catalogname) {
|
|
1897
|
-
tableName =
|
|
1975
|
+
tableName = quotes_1.QuoteUtils.quoteIdentifier(node.catalogname);
|
|
1898
1976
|
if (node.schemaname) {
|
|
1899
|
-
tableName += '.' +
|
|
1977
|
+
tableName += '.' + quotes_1.QuoteUtils.quoteIdentifierAfterDot(node.schemaname);
|
|
1900
1978
|
}
|
|
1901
|
-
tableName += '.' +
|
|
1979
|
+
tableName += '.' + quotes_1.QuoteUtils.quoteIdentifierAfterDot(node.relname);
|
|
1902
1980
|
}
|
|
1903
1981
|
else if (node.schemaname) {
|
|
1904
|
-
tableName =
|
|
1982
|
+
tableName = quotes_1.QuoteUtils.quoteQualifiedIdentifier(node.schemaname, node.relname);
|
|
1905
1983
|
}
|
|
1906
1984
|
else {
|
|
1907
|
-
tableName =
|
|
1985
|
+
tableName = quotes_1.QuoteUtils.quoteIdentifier(node.relname);
|
|
1908
1986
|
}
|
|
1909
1987
|
output.push(tableName);
|
|
1910
1988
|
if (node.alias) {
|
|
@@ -2058,7 +2136,7 @@ class Deparser {
|
|
|
2058
2136
|
if (size != null) {
|
|
2059
2137
|
return 'char';
|
|
2060
2138
|
}
|
|
2061
|
-
return '
|
|
2139
|
+
return 'bpchar';
|
|
2062
2140
|
case 'varchar':
|
|
2063
2141
|
return 'varchar';
|
|
2064
2142
|
case 'numeric':
|
|
@@ -2072,7 +2150,7 @@ class Deparser {
|
|
|
2072
2150
|
case 'int8':
|
|
2073
2151
|
return 'bigint';
|
|
2074
2152
|
case 'real':
|
|
2075
|
-
return '
|
|
2153
|
+
return 'float4';
|
|
2076
2154
|
case 'time':
|
|
2077
2155
|
return 'time';
|
|
2078
2156
|
case 'timestamp':
|
|
@@ -2082,7 +2160,7 @@ class Deparser {
|
|
|
2082
2160
|
case 'bit':
|
|
2083
2161
|
return 'bit';
|
|
2084
2162
|
default:
|
|
2085
|
-
return
|
|
2163
|
+
return typeName;
|
|
2086
2164
|
}
|
|
2087
2165
|
}
|
|
2088
2166
|
isPgCatalogType(typeName) {
|
|
@@ -2123,14 +2201,16 @@ class Deparser {
|
|
|
2123
2201
|
A_Indirection(node, context) {
|
|
2124
2202
|
let argStr = this.visit(node.arg, context);
|
|
2125
2203
|
const argType = this.getNodeType(node.arg);
|
|
2126
|
-
|
|
2204
|
+
// Grammar: only a parameter takes indirection bare; every other target is
|
|
2205
|
+
// `'(' a_expr ')' opt_indirection` (a plain column subscript is the same node).
|
|
2206
|
+
if (argType !== 'ParamRef') {
|
|
2127
2207
|
argStr = `(${argStr})`;
|
|
2128
2208
|
}
|
|
2129
2209
|
const output = [argStr];
|
|
2130
2210
|
const indirection = list_utils_1.ListUtils.unwrapList(node.indirection);
|
|
2131
2211
|
for (const subnode of indirection) {
|
|
2132
2212
|
if (subnode.String || subnode.A_Star) {
|
|
2133
|
-
const value = subnode.A_Star ? '*' :
|
|
2213
|
+
const value = subnode.A_Star ? '*' : quotes_1.QuoteUtils.quoteIdentifier(subnode.String.sval || subnode.String.str);
|
|
2134
2214
|
output.push(`.${value}`);
|
|
2135
2215
|
}
|
|
2136
2216
|
else {
|
|
@@ -2151,21 +2231,11 @@ class Deparser {
|
|
|
2151
2231
|
if (context.isPretty() && args.length > 0) {
|
|
2152
2232
|
for (const arg of args) {
|
|
2153
2233
|
const whenClause = this.visit(arg, context);
|
|
2154
|
-
|
|
2155
|
-
output.push(context.newline() + whenClause);
|
|
2156
|
-
}
|
|
2157
|
-
else {
|
|
2158
|
-
output.push(context.newline() + context.indent(whenClause));
|
|
2159
|
-
}
|
|
2234
|
+
output.push(context.newline() + context.indent(whenClause));
|
|
2160
2235
|
}
|
|
2161
2236
|
if (node.defresult) {
|
|
2162
2237
|
const elseResult = this.visit(node.defresult, context);
|
|
2163
|
-
|
|
2164
|
-
output.push(context.newline() + 'ELSE ' + elseResult);
|
|
2165
|
-
}
|
|
2166
|
-
else {
|
|
2167
|
-
output.push(context.newline() + context.indent('ELSE ' + elseResult));
|
|
2168
|
-
}
|
|
2238
|
+
output.push(context.newline() + context.indent('ELSE ' + elseResult));
|
|
2169
2239
|
}
|
|
2170
2240
|
output.push(context.newline() + 'END');
|
|
2171
2241
|
return output.join(' ');
|
|
@@ -2275,51 +2345,27 @@ class Deparser {
|
|
|
2275
2345
|
}
|
|
2276
2346
|
return output.join(' ');
|
|
2277
2347
|
}
|
|
2278
|
-
static RESERVED_WORDS = new Set([
|
|
2279
|
-
'all', 'analyse', 'analyze', 'and', 'any', 'array', 'as', 'asc', 'asymmetric', 'both',
|
|
2280
|
-
'case', 'cast', 'check', 'collate', 'column', 'constraint', 'create', 'current_catalog',
|
|
2281
|
-
'current_date', 'current_role', 'current_time', 'current_timestamp', 'current_user',
|
|
2282
|
-
'default', 'deferrable', 'desc', 'distinct', 'do', 'else', 'end', 'except', 'false',
|
|
2283
|
-
'fetch', 'for', 'foreign', 'from', 'grant', 'group', 'having', 'in', 'initially',
|
|
2284
|
-
'intersect', 'into', 'lateral', 'leading', 'limit', 'localtime', 'localtimestamp',
|
|
2285
|
-
'not', 'null', 'offset', 'on', 'only', 'or', 'order', 'placing', 'primary',
|
|
2286
|
-
'references', 'returning', 'select', 'session_user', 'some', 'symmetric', 'table',
|
|
2287
|
-
'then', 'to', 'trailing', 'true', 'union', 'unique', 'user', 'using', 'variadic',
|
|
2288
|
-
'when', 'where', 'window', 'with'
|
|
2289
|
-
]);
|
|
2290
|
-
static needsQuotes(value) {
|
|
2291
|
-
if (!value)
|
|
2292
|
-
return false;
|
|
2293
|
-
const needsQuotesRegex = /[a-z]+[\W\w]*[A-Z]+|[A-Z]+[\W\w]*[a-z]+|\W/;
|
|
2294
|
-
const isAllUppercase = /^[A-Z]+$/.test(value);
|
|
2295
|
-
return needsQuotesRegex.test(value) ||
|
|
2296
|
-
Deparser.RESERVED_WORDS.has(value.toLowerCase()) ||
|
|
2297
|
-
isAllUppercase;
|
|
2298
|
-
}
|
|
2299
2348
|
quoteIfNeeded(value) {
|
|
2300
|
-
|
|
2301
|
-
return `"${value}"`;
|
|
2302
|
-
}
|
|
2303
|
-
return value;
|
|
2349
|
+
return quotes_1.QuoteUtils.quoteIdentifier(value);
|
|
2304
2350
|
}
|
|
2305
2351
|
preserveOperatorDefElemCase(defName) {
|
|
2306
2352
|
const caseMap = {
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2353
|
+
leftarg: 'Leftarg',
|
|
2354
|
+
rightarg: 'Rightarg',
|
|
2355
|
+
procedure: 'Procedure',
|
|
2356
|
+
function: 'Function',
|
|
2357
|
+
commutator: 'Commutator',
|
|
2358
|
+
negator: 'Negator',
|
|
2359
|
+
restrict: 'Restrict',
|
|
2360
|
+
join: 'Join',
|
|
2361
|
+
hashes: 'Hashes',
|
|
2362
|
+
merges: 'Merges'
|
|
2317
2363
|
};
|
|
2318
2364
|
return caseMap[defName.toLowerCase()] || defName;
|
|
2319
2365
|
}
|
|
2320
2366
|
String(node, context) {
|
|
2321
2367
|
if (context.isStringLiteral || context.isEnumValue) {
|
|
2322
|
-
return
|
|
2368
|
+
return quotes_1.QuoteUtils.formatEString(node.sval || '');
|
|
2323
2369
|
}
|
|
2324
2370
|
const value = node.sval || '';
|
|
2325
2371
|
if (context.parentNodeTypes.includes('DefElem') ||
|
|
@@ -2333,27 +2379,19 @@ class Deparser {
|
|
|
2333
2379
|
return value; // Don't quote pure operator symbols like "=" or "-"
|
|
2334
2380
|
}
|
|
2335
2381
|
}
|
|
2336
|
-
return
|
|
2382
|
+
return quotes_1.QuoteUtils.quoteIdentifier(value);
|
|
2337
2383
|
}
|
|
2338
2384
|
Integer(node, context) {
|
|
2339
|
-
return node.ival
|
|
2385
|
+
return node.ival === undefined || node.ival === null ? '0' : formatInteger(node.ival);
|
|
2340
2386
|
}
|
|
2341
2387
|
Float(node, context) {
|
|
2342
|
-
return node.fval
|
|
2388
|
+
return node.fval ? formatNumeric(node.fval) : '0.0';
|
|
2343
2389
|
}
|
|
2344
2390
|
Boolean(node, context) {
|
|
2345
2391
|
return node.boolval ? 'true' : 'false';
|
|
2346
2392
|
}
|
|
2347
2393
|
BitString(node, context) {
|
|
2348
|
-
|
|
2349
|
-
if (node.bsval.startsWith('x')) {
|
|
2350
|
-
return `x'${node.bsval.substring(1)}'`;
|
|
2351
|
-
}
|
|
2352
|
-
if (node.bsval.startsWith('b')) {
|
|
2353
|
-
return `b'${node.bsval.substring(1)}'`;
|
|
2354
|
-
}
|
|
2355
|
-
// Fallback for raw values without prefix
|
|
2356
|
-
return `b'${node.bsval}'`;
|
|
2394
|
+
return formatBitString(node.bsval);
|
|
2357
2395
|
}
|
|
2358
2396
|
Null(node, context) {
|
|
2359
2397
|
return 'NULL';
|
|
@@ -2392,7 +2430,7 @@ class Deparser {
|
|
|
2392
2430
|
output.push(context.parens(elementStrs.join(', ')));
|
|
2393
2431
|
}
|
|
2394
2432
|
}
|
|
2395
|
-
else if (node.tableElts) {
|
|
2433
|
+
else if (node.tableElts && !node.partbound) {
|
|
2396
2434
|
const elements = list_utils_1.ListUtils.unwrapList(node.tableElts);
|
|
2397
2435
|
const elementStrs = elements.map(el => {
|
|
2398
2436
|
return this.deparse(el, context.spawn('CreateStmt'));
|
|
@@ -2420,7 +2458,16 @@ class Deparser {
|
|
|
2420
2458
|
const inherits = list_utils_1.ListUtils.unwrapList(node.inhRelations);
|
|
2421
2459
|
const inheritStrs = inherits.map(rel => this.visit(rel, context));
|
|
2422
2460
|
output.push(inheritStrs[0]);
|
|
2423
|
-
if (node.
|
|
2461
|
+
if (node.tableElts) {
|
|
2462
|
+
const elementStrs = list_utils_1.ListUtils.unwrapList(node.tableElts).map(el => {
|
|
2463
|
+
return this.deparse(el, context.spawn('CreateStmt'));
|
|
2464
|
+
});
|
|
2465
|
+
output.push(context.parens(elementStrs.join(', ')));
|
|
2466
|
+
}
|
|
2467
|
+
if (node.partbound.is_default) {
|
|
2468
|
+
output.push('DEFAULT');
|
|
2469
|
+
}
|
|
2470
|
+
else if (node.partbound.strategy === 'l' && node.partbound.listdatums) {
|
|
2424
2471
|
output.push('FOR VALUES IN');
|
|
2425
2472
|
const listValues = list_utils_1.ListUtils.unwrapList(node.partbound.listdatums)
|
|
2426
2473
|
.map(datum => this.visit(datum, context))
|
|
@@ -2443,13 +2490,9 @@ class Deparser {
|
|
|
2443
2490
|
output.push(`(${upperValues})`);
|
|
2444
2491
|
}
|
|
2445
2492
|
}
|
|
2446
|
-
else if (node.partbound.strategy === 'h'
|
|
2493
|
+
else if (node.partbound.strategy === 'h') {
|
|
2447
2494
|
output.push('FOR VALUES WITH');
|
|
2448
|
-
|
|
2449
|
-
output.push(`(MODULUS ${node.partbound.modulus}, REMAINDER ${remainder})`);
|
|
2450
|
-
}
|
|
2451
|
-
else if (node.partbound.is_default) {
|
|
2452
|
-
output.push('DEFAULT');
|
|
2495
|
+
output.push(`(MODULUS ${node.partbound.modulus ?? 0}, REMAINDER ${node.partbound.remainder ?? 0})`);
|
|
2453
2496
|
}
|
|
2454
2497
|
}
|
|
2455
2498
|
else if (node.inhRelations) {
|
|
@@ -2510,11 +2553,17 @@ class Deparser {
|
|
|
2510
2553
|
ColumnDef(node, context) {
|
|
2511
2554
|
const output = [];
|
|
2512
2555
|
if (node.colname) {
|
|
2513
|
-
output.push(
|
|
2556
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.colname));
|
|
2514
2557
|
}
|
|
2515
2558
|
if (node.typeName) {
|
|
2516
2559
|
output.push(this.TypeName(node.typeName, context));
|
|
2517
2560
|
}
|
|
2561
|
+
if (node.storage_name) {
|
|
2562
|
+
output.push('STORAGE', node.storage_name.toUpperCase());
|
|
2563
|
+
}
|
|
2564
|
+
if (node.compression) {
|
|
2565
|
+
output.push('COMPRESSION', quotes_1.QuoteUtils.quoteIdentifier(node.compression));
|
|
2566
|
+
}
|
|
2518
2567
|
if (node.fdwoptions && node.fdwoptions.length > 0) {
|
|
2519
2568
|
output.push('OPTIONS');
|
|
2520
2569
|
const columnContext = context.spawn('ColumnDef');
|
|
@@ -2549,9 +2598,9 @@ class Deparser {
|
|
|
2549
2598
|
Constraint(node, context) {
|
|
2550
2599
|
const output = [];
|
|
2551
2600
|
// Handle constraint name if present
|
|
2552
|
-
if (node.conname && (node.contype === 'CONSTR_CHECK' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_FOREIGN')) {
|
|
2601
|
+
if (node.conname && (node.contype === 'CONSTR_CHECK' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_FOREIGN' || node.contype === 'CONSTR_NOTNULL' || node.contype === 'CONSTR_EXCLUSION')) {
|
|
2553
2602
|
output.push('CONSTRAINT');
|
|
2554
|
-
output.push(
|
|
2603
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.conname));
|
|
2555
2604
|
}
|
|
2556
2605
|
switch (node.contype) {
|
|
2557
2606
|
case 'CONSTR_NULL':
|
|
@@ -2559,11 +2608,24 @@ class Deparser {
|
|
|
2559
2608
|
break;
|
|
2560
2609
|
case 'CONSTR_NOTNULL':
|
|
2561
2610
|
output.push('NOT NULL');
|
|
2611
|
+
if (node.keys && node.keys.length > 0 && !context.isColumnConstraint) {
|
|
2612
|
+
const keyList = list_utils_1.ListUtils.unwrapList(node.keys)
|
|
2613
|
+
.map(key => this.visit(key, context))
|
|
2614
|
+
.join(', ');
|
|
2615
|
+
output.push(keyList);
|
|
2616
|
+
}
|
|
2617
|
+
if (node.is_no_inherit) {
|
|
2618
|
+
output.push('NO INHERIT');
|
|
2619
|
+
}
|
|
2620
|
+
if (node.skip_validation) {
|
|
2621
|
+
output.push('NOT VALID');
|
|
2622
|
+
}
|
|
2562
2623
|
break;
|
|
2563
2624
|
case 'CONSTR_DEFAULT':
|
|
2564
2625
|
output.push('DEFAULT');
|
|
2565
2626
|
if (node.raw_expr) {
|
|
2566
|
-
|
|
2627
|
+
const defaultExpr = this.visit(node.raw_expr, context);
|
|
2628
|
+
output.push(this.needsBExprParens(node.raw_expr) ? `(${defaultExpr})` : defaultExpr);
|
|
2567
2629
|
}
|
|
2568
2630
|
break;
|
|
2569
2631
|
case 'CONSTR_CHECK':
|
|
@@ -2587,8 +2649,13 @@ class Deparser {
|
|
|
2587
2649
|
output.push(context.parens(this.visit(node.raw_expr, context)));
|
|
2588
2650
|
}
|
|
2589
2651
|
}
|
|
2590
|
-
//
|
|
2591
|
-
|
|
2652
|
+
// PG18: constraints are enforced unless explicitly NOT ENFORCED
|
|
2653
|
+
// (libpg-query omits false booleans, so undefined means not enforced)
|
|
2654
|
+
if (node.is_enforced !== true && !context.isDomainConstraint) {
|
|
2655
|
+
output.push('NOT ENFORCED');
|
|
2656
|
+
}
|
|
2657
|
+
else if (node.skip_validation) {
|
|
2658
|
+
// NOT ENFORCED implies NOT VALID, so only emit NOT VALID when enforced
|
|
2592
2659
|
output.push('NOT VALID');
|
|
2593
2660
|
}
|
|
2594
2661
|
// Handle NO INHERIT for check constraints - only for table constraints, not domain constraints
|
|
@@ -2608,7 +2675,7 @@ class Deparser {
|
|
|
2608
2675
|
if (node.raw_expr) {
|
|
2609
2676
|
output.push(context.parens(this.visit(node.raw_expr, context)));
|
|
2610
2677
|
}
|
|
2611
|
-
output.push('STORED');
|
|
2678
|
+
output.push(node.generated_kind === 'v' ? 'VIRTUAL' : 'STORED');
|
|
2612
2679
|
break;
|
|
2613
2680
|
case 'CONSTR_IDENTITY':
|
|
2614
2681
|
output.push('GENERATED');
|
|
@@ -2684,10 +2751,12 @@ class Deparser {
|
|
|
2684
2751
|
case 'CONSTR_PRIMARY':
|
|
2685
2752
|
output.push('PRIMARY KEY');
|
|
2686
2753
|
if (node.keys && node.keys.length > 0) {
|
|
2687
|
-
const
|
|
2688
|
-
.map(key => this.visit(key, context))
|
|
2689
|
-
|
|
2690
|
-
|
|
2754
|
+
const keyItems = list_utils_1.ListUtils.unwrapList(node.keys)
|
|
2755
|
+
.map(key => this.visit(key, context));
|
|
2756
|
+
if (node.without_overlaps) {
|
|
2757
|
+
keyItems[keyItems.length - 1] += ' WITHOUT OVERLAPS';
|
|
2758
|
+
}
|
|
2759
|
+
output.push(`(${keyItems.join(', ')})`);
|
|
2691
2760
|
}
|
|
2692
2761
|
if (node.indexname) {
|
|
2693
2762
|
output.push('USING INDEX');
|
|
@@ -2705,10 +2774,12 @@ class Deparser {
|
|
|
2705
2774
|
output.push('NULLS NOT DISTINCT');
|
|
2706
2775
|
}
|
|
2707
2776
|
if (node.keys && node.keys.length > 0) {
|
|
2708
|
-
const
|
|
2709
|
-
.map(key => this.visit(key, context))
|
|
2710
|
-
|
|
2711
|
-
|
|
2777
|
+
const keyItems = list_utils_1.ListUtils.unwrapList(node.keys)
|
|
2778
|
+
.map(key => this.visit(key, context));
|
|
2779
|
+
if (node.without_overlaps) {
|
|
2780
|
+
keyItems[keyItems.length - 1] += ' WITHOUT OVERLAPS';
|
|
2781
|
+
}
|
|
2782
|
+
output.push(`(${keyItems.join(', ')})`);
|
|
2712
2783
|
}
|
|
2713
2784
|
if (node.indexname) {
|
|
2714
2785
|
output.push('USING INDEX');
|
|
@@ -2721,20 +2792,14 @@ class Deparser {
|
|
|
2721
2792
|
if (context.isPretty()) {
|
|
2722
2793
|
output.push('\n' + context.indent('FOREIGN KEY'));
|
|
2723
2794
|
if (node.fk_attrs && node.fk_attrs.length > 0) {
|
|
2724
|
-
|
|
2725
|
-
.map(attr => this.visit(attr, context))
|
|
2726
|
-
.join(', ');
|
|
2727
|
-
output.push(`(${fkAttrs})`);
|
|
2795
|
+
output.push(`(${this.deparseKeyAttrs(node.fk_attrs, node.fk_with_period, context)})`);
|
|
2728
2796
|
}
|
|
2729
2797
|
output.push('\n' + context.indent('REFERENCES'));
|
|
2730
2798
|
}
|
|
2731
2799
|
else {
|
|
2732
2800
|
output.push('FOREIGN KEY');
|
|
2733
2801
|
if (node.fk_attrs && node.fk_attrs.length > 0) {
|
|
2734
|
-
|
|
2735
|
-
.map(attr => this.visit(attr, context))
|
|
2736
|
-
.join(', ');
|
|
2737
|
-
output.push(`(${fkAttrs})`);
|
|
2802
|
+
output.push(`(${this.deparseKeyAttrs(node.fk_attrs, node.fk_with_period, context)})`);
|
|
2738
2803
|
}
|
|
2739
2804
|
output.push('REFERENCES');
|
|
2740
2805
|
}
|
|
@@ -2757,9 +2822,7 @@ class Deparser {
|
|
|
2757
2822
|
}
|
|
2758
2823
|
}
|
|
2759
2824
|
if (node.pk_attrs && node.pk_attrs.length > 0) {
|
|
2760
|
-
const pkAttrs =
|
|
2761
|
-
.map(attr => this.visit(attr, context))
|
|
2762
|
-
.join(', ');
|
|
2825
|
+
const pkAttrs = this.deparseKeyAttrs(node.pk_attrs, node.pk_with_period, context);
|
|
2763
2826
|
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2764
2827
|
const lastIndex = output.length - 1;
|
|
2765
2828
|
if (lastIndex >= 0) {
|
|
@@ -2830,6 +2893,15 @@ class Deparser {
|
|
|
2830
2893
|
deleteClause += 'SET DEFAULT';
|
|
2831
2894
|
break;
|
|
2832
2895
|
}
|
|
2896
|
+
if ((node.fk_del_action === 'n' || node.fk_del_action === 'd') && node.fk_del_set_cols && node.fk_del_set_cols.length > 0) {
|
|
2897
|
+
const setColumns = list_utils_1.ListUtils.unwrapList(node.fk_del_set_cols)
|
|
2898
|
+
.map(column => {
|
|
2899
|
+
const stringNode = column.String;
|
|
2900
|
+
return quotes_1.QuoteUtils.quoteIdentifier(stringNode.sval || stringNode.str || '');
|
|
2901
|
+
})
|
|
2902
|
+
.join(', ');
|
|
2903
|
+
deleteClause += ` (${setColumns})`;
|
|
2904
|
+
}
|
|
2833
2905
|
if (context.isPretty()) {
|
|
2834
2906
|
output.push('\n' + context.indent(deleteClause));
|
|
2835
2907
|
}
|
|
@@ -2838,8 +2910,18 @@ class Deparser {
|
|
|
2838
2910
|
output.push(deleteClause.replace('ON DELETE ', ''));
|
|
2839
2911
|
}
|
|
2840
2912
|
}
|
|
2841
|
-
//
|
|
2842
|
-
|
|
2913
|
+
// PG18: constraints are enforced unless explicitly NOT ENFORCED
|
|
2914
|
+
// (libpg-query omits false booleans, so undefined means not enforced)
|
|
2915
|
+
if (node.is_enforced !== true && !context.isDomainConstraint) {
|
|
2916
|
+
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2917
|
+
output.push('\n' + context.indent('NOT ENFORCED'));
|
|
2918
|
+
}
|
|
2919
|
+
else {
|
|
2920
|
+
output.push('NOT ENFORCED');
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
else if (node.skip_validation && !context.isDomainConstraint) {
|
|
2924
|
+
// NOT ENFORCED implies NOT VALID, so only emit NOT VALID when enforced
|
|
2843
2925
|
if (context.isPretty() && !context.isColumnConstraint) {
|
|
2844
2926
|
output.push('\n' + context.indent('NOT VALID'));
|
|
2845
2927
|
}
|
|
@@ -2860,6 +2942,12 @@ class Deparser {
|
|
|
2860
2942
|
case 'CONSTR_ATTR_IMMEDIATE':
|
|
2861
2943
|
output.push('INITIALLY IMMEDIATE');
|
|
2862
2944
|
break;
|
|
2945
|
+
case 'CONSTR_ATTR_ENFORCED':
|
|
2946
|
+
output.push('ENFORCED');
|
|
2947
|
+
break;
|
|
2948
|
+
case 'CONSTR_ATTR_NOT_ENFORCED':
|
|
2949
|
+
output.push('NOT ENFORCED');
|
|
2950
|
+
break;
|
|
2863
2951
|
case 'CONSTR_EXCLUSION':
|
|
2864
2952
|
output.push('EXCLUDE');
|
|
2865
2953
|
if (node.access_method) {
|
|
@@ -2894,10 +2982,14 @@ class Deparser {
|
|
|
2894
2982
|
});
|
|
2895
2983
|
output.push(`(${exclusionElements.join(', ')})`);
|
|
2896
2984
|
}
|
|
2985
|
+
if (node.where_clause) {
|
|
2986
|
+
output.push('WHERE');
|
|
2987
|
+
output.push(context.parens(this.visit(node.where_clause, context)));
|
|
2988
|
+
}
|
|
2897
2989
|
break;
|
|
2898
2990
|
}
|
|
2899
2991
|
// Handle deferrable constraints for all constraint types that support it
|
|
2900
|
-
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN') {
|
|
2992
|
+
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN' || node.contype === 'CONSTR_EXCLUSION') {
|
|
2901
2993
|
if (node.deferrable) {
|
|
2902
2994
|
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2903
2995
|
output.push('\n' + context.indent('DEFERRABLE'));
|
|
@@ -2926,6 +3018,9 @@ class Deparser {
|
|
|
2926
3018
|
output.push('NOT DEFERRABLE');
|
|
2927
3019
|
}
|
|
2928
3020
|
}
|
|
3021
|
+
else if (node.initdeferred) {
|
|
3022
|
+
output.push('INITIALLY DEFERRED');
|
|
3023
|
+
}
|
|
2929
3024
|
}
|
|
2930
3025
|
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2931
3026
|
let result = '';
|
|
@@ -2991,6 +3086,9 @@ class Deparser {
|
|
|
2991
3086
|
output.push(node.name);
|
|
2992
3087
|
}
|
|
2993
3088
|
const windowParts = [];
|
|
3089
|
+
if (node.refname) {
|
|
3090
|
+
windowParts.push(node.refname);
|
|
3091
|
+
}
|
|
2994
3092
|
if (node.partitionClause) {
|
|
2995
3093
|
const partitions = list_utils_1.ListUtils.unwrapList(node.partitionClause);
|
|
2996
3094
|
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
@@ -3001,12 +3099,9 @@ class Deparser {
|
|
|
3001
3099
|
const orderStrs = orders.map(o => this.visit(o, context));
|
|
3002
3100
|
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
3003
3101
|
}
|
|
3004
|
-
|
|
3005
|
-
if (
|
|
3006
|
-
|
|
3007
|
-
if (frameClause) {
|
|
3008
|
-
windowParts.push(frameClause);
|
|
3009
|
-
}
|
|
3102
|
+
const frameClause = this.formatWindowFrame(node, context.spawn('WindowDef'));
|
|
3103
|
+
if (frameClause) {
|
|
3104
|
+
windowParts.push(frameClause);
|
|
3010
3105
|
}
|
|
3011
3106
|
if (windowParts.length > 0) {
|
|
3012
3107
|
if (node.name) {
|
|
@@ -3023,103 +3118,97 @@ class Deparser {
|
|
|
3023
3118
|
}
|
|
3024
3119
|
return output.join(' ');
|
|
3025
3120
|
}
|
|
3121
|
+
formatIdentityColumnOptions(def, context) {
|
|
3122
|
+
const seqContext = context.spawn('AlterSeqStmt');
|
|
3123
|
+
return list_utils_1.ListUtils.unwrapList(def).map(item => {
|
|
3124
|
+
const el = item.DefElem;
|
|
3125
|
+
if (!el)
|
|
3126
|
+
return this.visit(item, context);
|
|
3127
|
+
if (el.defname === 'generated') {
|
|
3128
|
+
const ival = el.arg?.Integer?.ival ?? 0;
|
|
3129
|
+
return ival === 97 ? 'SET GENERATED ALWAYS' : 'SET GENERATED BY DEFAULT';
|
|
3130
|
+
}
|
|
3131
|
+
if (el.defname === 'restart') {
|
|
3132
|
+
return el.arg ? `RESTART WITH ${this.visit(el.arg, context)}` : 'RESTART';
|
|
3133
|
+
}
|
|
3134
|
+
return `SET ${this.visit(item, seqContext)}`;
|
|
3135
|
+
}).join(' ');
|
|
3136
|
+
}
|
|
3137
|
+
// b_expr (used by DEFAULT) excludes IN/LIKE/BETWEEN and boolean operators.
|
|
3138
|
+
needsBExprParens(node) {
|
|
3139
|
+
const nodeType = this.getNodeType(node);
|
|
3140
|
+
if (nodeType === 'BoolExpr')
|
|
3141
|
+
return true;
|
|
3142
|
+
if (nodeType === 'A_Expr') {
|
|
3143
|
+
const kind = this.getNodeData(node).kind;
|
|
3144
|
+
return kind !== 'AEXPR_OP' && kind !== 'AEXPR_DISTINCT' && kind !== 'AEXPR_NOT_DISTINCT';
|
|
3145
|
+
}
|
|
3146
|
+
return false;
|
|
3147
|
+
}
|
|
3026
3148
|
formatWindowFrame(node, context) {
|
|
3027
|
-
if (!node.frameOptions)
|
|
3149
|
+
if (!node.frameOptions || !(node.frameOptions & FRAMEOPTION_NONDEFAULT))
|
|
3028
3150
|
return null;
|
|
3029
3151
|
const frameOptions = node.frameOptions;
|
|
3030
3152
|
const frameParts = [];
|
|
3031
|
-
if (frameOptions &
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
frameParts.push('GROUPS');
|
|
3040
|
-
}
|
|
3153
|
+
if (frameOptions & FRAMEOPTION_RANGE) {
|
|
3154
|
+
frameParts.push('RANGE');
|
|
3155
|
+
}
|
|
3156
|
+
else if (frameOptions & FRAMEOPTION_ROWS) {
|
|
3157
|
+
frameParts.push('ROWS');
|
|
3158
|
+
}
|
|
3159
|
+
else if (frameOptions & FRAMEOPTION_GROUPS) {
|
|
3160
|
+
frameParts.push('GROUPS');
|
|
3041
3161
|
}
|
|
3042
3162
|
if (frameParts.length === 0)
|
|
3043
3163
|
return null;
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
boundsParts.push('CURRENT ROW');
|
|
3048
|
-
boundsParts.push('AND UNBOUNDED FOLLOWING');
|
|
3164
|
+
let start = null;
|
|
3165
|
+
if (frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) {
|
|
3166
|
+
start = 'UNBOUNDED PRECEDING';
|
|
3049
3167
|
}
|
|
3050
|
-
else if (frameOptions
|
|
3051
|
-
|
|
3052
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3168
|
+
else if (frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) {
|
|
3169
|
+
start = 'UNBOUNDED FOLLOWING';
|
|
3053
3170
|
}
|
|
3054
|
-
else if (frameOptions
|
|
3055
|
-
|
|
3056
|
-
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
|
|
3057
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3058
|
-
}
|
|
3171
|
+
else if (frameOptions & FRAMEOPTION_START_CURRENT_ROW) {
|
|
3172
|
+
start = 'CURRENT ROW';
|
|
3059
3173
|
}
|
|
3060
|
-
else if (frameOptions
|
|
3061
|
-
|
|
3062
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3174
|
+
else if (frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING && node.startOffset) {
|
|
3175
|
+
start = `${this.visit(node.startOffset, context)} PRECEDING`;
|
|
3063
3176
|
}
|
|
3064
|
-
else if (frameOptions
|
|
3065
|
-
|
|
3066
|
-
if (node.endOffset) {
|
|
3067
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3068
|
-
}
|
|
3177
|
+
else if (frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING && node.startOffset) {
|
|
3178
|
+
start = `${this.visit(node.startOffset, context)} FOLLOWING`;
|
|
3069
3179
|
}
|
|
3070
|
-
|
|
3071
|
-
|
|
3180
|
+
let end = null;
|
|
3181
|
+
if (frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING) {
|
|
3182
|
+
end = 'UNBOUNDED PRECEDING';
|
|
3072
3183
|
}
|
|
3073
|
-
else {
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
}
|
|
3089
|
-
else if (frameOptions & 0x20) { // FRAMEOPTION_START_CURRENT_ROW
|
|
3090
|
-
boundsParts.push('CURRENT ROW');
|
|
3091
|
-
}
|
|
3092
|
-
// Handle end bound - prioritize explicit offset values over bit flags
|
|
3093
|
-
if (node.endOffset) {
|
|
3094
|
-
if (boundsParts.length > 0) {
|
|
3095
|
-
if (frameOptions & 0x1000) { // FRAMEOPTION_END_VALUE_PRECEDING
|
|
3096
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} PRECEDING`);
|
|
3097
|
-
}
|
|
3098
|
-
else if (frameOptions & 0x2000) { // FRAMEOPTION_END_VALUE_FOLLOWING
|
|
3099
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3100
|
-
}
|
|
3101
|
-
else {
|
|
3102
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3103
|
-
}
|
|
3104
|
-
}
|
|
3105
|
-
}
|
|
3106
|
-
else if (frameOptions & 0x80) { // FRAMEOPTION_END_UNBOUNDED_FOLLOWING
|
|
3107
|
-
if (boundsParts.length > 0) {
|
|
3108
|
-
boundsParts.push('AND UNBOUNDED FOLLOWING');
|
|
3109
|
-
}
|
|
3110
|
-
}
|
|
3111
|
-
else if (frameOptions & 0x100) { // FRAMEOPTION_END_CURRENT_ROW
|
|
3112
|
-
if (boundsParts.length > 0) {
|
|
3113
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3114
|
-
}
|
|
3184
|
+
else if (frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING) {
|
|
3185
|
+
end = 'UNBOUNDED FOLLOWING';
|
|
3186
|
+
}
|
|
3187
|
+
else if (frameOptions & FRAMEOPTION_END_CURRENT_ROW) {
|
|
3188
|
+
end = 'CURRENT ROW';
|
|
3189
|
+
}
|
|
3190
|
+
else if (frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING && node.endOffset) {
|
|
3191
|
+
end = `${this.visit(node.endOffset, context)} PRECEDING`;
|
|
3192
|
+
}
|
|
3193
|
+
else if (frameOptions & FRAMEOPTION_END_OFFSET_FOLLOWING && node.endOffset) {
|
|
3194
|
+
end = `${this.visit(node.endOffset, context)} FOLLOWING`;
|
|
3195
|
+
}
|
|
3196
|
+
if (start) {
|
|
3197
|
+
if (frameOptions & FRAMEOPTION_BETWEEN) {
|
|
3198
|
+
frameParts.push(`BETWEEN ${start} AND ${end ?? 'CURRENT ROW'}`);
|
|
3115
3199
|
}
|
|
3116
|
-
else
|
|
3117
|
-
|
|
3200
|
+
else {
|
|
3201
|
+
frameParts.push(start);
|
|
3118
3202
|
}
|
|
3119
3203
|
}
|
|
3120
|
-
if (
|
|
3121
|
-
frameParts.push('
|
|
3122
|
-
|
|
3204
|
+
if (frameOptions & FRAMEOPTION_EXCLUDE_CURRENT_ROW) {
|
|
3205
|
+
frameParts.push('EXCLUDE CURRENT ROW');
|
|
3206
|
+
}
|
|
3207
|
+
else if (frameOptions & FRAMEOPTION_EXCLUDE_GROUP) {
|
|
3208
|
+
frameParts.push('EXCLUDE GROUP');
|
|
3209
|
+
}
|
|
3210
|
+
else if (frameOptions & FRAMEOPTION_EXCLUDE_TIES) {
|
|
3211
|
+
frameParts.push('EXCLUDE TIES');
|
|
3123
3212
|
}
|
|
3124
3213
|
return frameParts.join(' ');
|
|
3125
3214
|
}
|
|
@@ -3197,8 +3286,35 @@ class Deparser {
|
|
|
3197
3286
|
if (node.ctequery) {
|
|
3198
3287
|
output.push(context.parens(this.visit(node.ctequery, context)));
|
|
3199
3288
|
}
|
|
3289
|
+
if (node.search_clause) {
|
|
3290
|
+
const sc = node.search_clause;
|
|
3291
|
+
const cols = list_utils_1.ListUtils.unwrapList(sc.search_col_list).map(c => this.visit(c, context));
|
|
3292
|
+
output.push('SEARCH', sc.search_breadth_first ? 'BREADTH' : 'DEPTH', 'FIRST BY');
|
|
3293
|
+
output.push(cols.join(', '));
|
|
3294
|
+
output.push('SET', quotes_1.QuoteUtils.quoteIdentifier(sc.search_seq_column));
|
|
3295
|
+
}
|
|
3296
|
+
if (node.cycle_clause) {
|
|
3297
|
+
const cc = node.cycle_clause;
|
|
3298
|
+
const cols = list_utils_1.ListUtils.unwrapList(cc.cycle_col_list).map(c => this.visit(c, context));
|
|
3299
|
+
output.push('CYCLE', cols.join(', '));
|
|
3300
|
+
output.push('SET', quotes_1.QuoteUtils.quoteIdentifier(cc.cycle_mark_column));
|
|
3301
|
+
if (cc.cycle_mark_value && cc.cycle_mark_default) {
|
|
3302
|
+
output.push('TO', this.formatAexprConst(cc.cycle_mark_value, context));
|
|
3303
|
+
output.push('DEFAULT', this.formatAexprConst(cc.cycle_mark_default, context));
|
|
3304
|
+
}
|
|
3305
|
+
output.push('USING', quotes_1.QuoteUtils.quoteIdentifier(cc.cycle_path_column));
|
|
3306
|
+
}
|
|
3200
3307
|
return output.join(' ');
|
|
3201
3308
|
}
|
|
3309
|
+
// Renders a constant in the restricted AexprConst grammar (e.g. `point '(1,1)'`
|
|
3310
|
+
// rather than `CAST('(1,1)' AS point)`).
|
|
3311
|
+
formatAexprConst(node, context) {
|
|
3312
|
+
const cast = node.TypeCast;
|
|
3313
|
+
if (cast?.arg?.A_Const?.sval && cast.typeName) {
|
|
3314
|
+
return `${this.TypeName(cast.typeName, context)} ${this.visit(cast.arg, context)}`;
|
|
3315
|
+
}
|
|
3316
|
+
return this.visit(node, context);
|
|
3317
|
+
}
|
|
3202
3318
|
ParamRef(node, context) {
|
|
3203
3319
|
return `$${node.number}`;
|
|
3204
3320
|
}
|
|
@@ -3448,7 +3564,7 @@ class Deparser {
|
|
|
3448
3564
|
output.push('IF NOT EXISTS');
|
|
3449
3565
|
}
|
|
3450
3566
|
if (node.idxname) {
|
|
3451
|
-
output.push(
|
|
3567
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.idxname));
|
|
3452
3568
|
}
|
|
3453
3569
|
output.push('ON');
|
|
3454
3570
|
if (node.relation) {
|
|
@@ -3467,9 +3583,8 @@ class Deparser {
|
|
|
3467
3583
|
output.push('INCLUDE');
|
|
3468
3584
|
output.push(context.parens(includeStrs.join(', ')));
|
|
3469
3585
|
}
|
|
3470
|
-
if (node.
|
|
3471
|
-
output.push('
|
|
3472
|
-
output.push(this.visit(node.whereClause, context));
|
|
3586
|
+
if (node.nulls_not_distinct) {
|
|
3587
|
+
output.push('NULLS NOT DISTINCT');
|
|
3473
3588
|
}
|
|
3474
3589
|
if (node.options && node.options.length > 0) {
|
|
3475
3590
|
const indexContext = context.spawn('IndexStmt');
|
|
@@ -3477,19 +3592,20 @@ class Deparser {
|
|
|
3477
3592
|
output.push('WITH');
|
|
3478
3593
|
output.push(context.parens(optionStrs.join(', ')));
|
|
3479
3594
|
}
|
|
3480
|
-
if (node.nulls_not_distinct) {
|
|
3481
|
-
output.push('NULLS NOT DISTINCT');
|
|
3482
|
-
}
|
|
3483
3595
|
if (node.tableSpace) {
|
|
3484
3596
|
output.push('TABLESPACE');
|
|
3485
|
-
output.push(
|
|
3597
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.tableSpace));
|
|
3598
|
+
}
|
|
3599
|
+
if (node.whereClause) {
|
|
3600
|
+
output.push('WHERE');
|
|
3601
|
+
output.push(this.visit(node.whereClause, context));
|
|
3486
3602
|
}
|
|
3487
3603
|
return output.join(' ');
|
|
3488
3604
|
}
|
|
3489
3605
|
IndexElem(node, context) {
|
|
3490
3606
|
const output = [];
|
|
3491
3607
|
if (node.name) {
|
|
3492
|
-
output.push(
|
|
3608
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
3493
3609
|
}
|
|
3494
3610
|
else if (node.expr) {
|
|
3495
3611
|
output.push(context.parens(this.visit(node.expr, context)));
|
|
@@ -3507,7 +3623,7 @@ class Deparser {
|
|
|
3507
3623
|
const opclassOpts = list_utils_1.ListUtils.unwrapList(node.opclassopts).map(opt => {
|
|
3508
3624
|
if (opt.DefElem && opt.DefElem.arg && this.getNodeType(opt.DefElem.arg) === 'String') {
|
|
3509
3625
|
const stringData = this.getNodeData(opt.DefElem.arg);
|
|
3510
|
-
return `${opt.DefElem.defname}
|
|
3626
|
+
return `${quotes_1.QuoteUtils.quoteIdentifierAfterDot(opt.DefElem.defname)}=${quotes_1.QuoteUtils.escape(stringData.sval)}`;
|
|
3511
3627
|
}
|
|
3512
3628
|
return this.visit(opt, context.spawn('IndexElem'));
|
|
3513
3629
|
});
|
|
@@ -3540,7 +3656,7 @@ class Deparser {
|
|
|
3540
3656
|
PartitionElem(node, context) {
|
|
3541
3657
|
const output = [];
|
|
3542
3658
|
if (node.name) {
|
|
3543
|
-
output.push(
|
|
3659
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
3544
3660
|
}
|
|
3545
3661
|
else if (node.expr) {
|
|
3546
3662
|
output.push(context.parens(this.visit(node.expr, context)));
|
|
@@ -3558,12 +3674,12 @@ class Deparser {
|
|
|
3558
3674
|
}
|
|
3559
3675
|
PartitionCmd(node, context) {
|
|
3560
3676
|
const output = [];
|
|
3677
|
+
if (node.name) {
|
|
3678
|
+
output.push(this.RangeVar(node.name, context));
|
|
3679
|
+
}
|
|
3561
3680
|
if (node.concurrent) {
|
|
3562
3681
|
output.push('CONCURRENTLY');
|
|
3563
3682
|
}
|
|
3564
|
-
if (node.name) {
|
|
3565
|
-
output.push(this.visit(node.name, context));
|
|
3566
|
-
}
|
|
3567
3683
|
if (node.bound) {
|
|
3568
3684
|
if (node.bound.strategy === 'l' && node.bound.listdatums) {
|
|
3569
3685
|
output.push('FOR VALUES IN');
|
|
@@ -3588,9 +3704,9 @@ class Deparser {
|
|
|
3588
3704
|
output.push(`(${upperValues})`);
|
|
3589
3705
|
}
|
|
3590
3706
|
}
|
|
3591
|
-
else if (node.bound.strategy === 'h'
|
|
3707
|
+
else if (node.bound.strategy === 'h') {
|
|
3592
3708
|
output.push('FOR VALUES WITH');
|
|
3593
|
-
output.push(`(
|
|
3709
|
+
output.push(`(MODULUS ${node.bound.modulus ?? 0}, REMAINDER ${node.bound.remainder ?? 0})`);
|
|
3594
3710
|
}
|
|
3595
3711
|
else if (node.bound.is_default) {
|
|
3596
3712
|
output.push('DEFAULT');
|
|
@@ -3721,12 +3837,7 @@ class Deparser {
|
|
|
3721
3837
|
if (context.isPretty()) {
|
|
3722
3838
|
// For complex JOIN conditions, format with proper indentation
|
|
3723
3839
|
if (qualsStr.includes('AND') || qualsStr.includes('OR') || qualsStr.length > 50) {
|
|
3724
|
-
|
|
3725
|
-
output.push(` ON ${qualsStr}`);
|
|
3726
|
-
}
|
|
3727
|
-
else {
|
|
3728
|
-
output.push(` ON${context.newline()}${context.indent(qualsStr)}`);
|
|
3729
|
-
}
|
|
3840
|
+
output.push(` ON${context.newline()}${context.indent(qualsStr)}`);
|
|
3730
3841
|
}
|
|
3731
3842
|
else {
|
|
3732
3843
|
output.push(` ON ${qualsStr}`);
|
|
@@ -3790,37 +3901,37 @@ class Deparser {
|
|
|
3790
3901
|
case 'TRANS_STMT_SAVEPOINT':
|
|
3791
3902
|
output.push('SAVEPOINT');
|
|
3792
3903
|
if (node.savepoint_name) {
|
|
3793
|
-
output.push(
|
|
3904
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.savepoint_name));
|
|
3794
3905
|
}
|
|
3795
3906
|
break;
|
|
3796
3907
|
case 'TRANS_STMT_RELEASE':
|
|
3797
3908
|
output.push('RELEASE SAVEPOINT');
|
|
3798
3909
|
if (node.savepoint_name) {
|
|
3799
|
-
output.push(
|
|
3910
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.savepoint_name));
|
|
3800
3911
|
}
|
|
3801
3912
|
break;
|
|
3802
3913
|
case 'TRANS_STMT_ROLLBACK_TO':
|
|
3803
3914
|
output.push('ROLLBACK TO');
|
|
3804
3915
|
if (node.savepoint_name) {
|
|
3805
|
-
output.push(
|
|
3916
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.savepoint_name));
|
|
3806
3917
|
}
|
|
3807
3918
|
break;
|
|
3808
3919
|
case 'TRANS_STMT_PREPARE':
|
|
3809
3920
|
output.push('PREPARE TRANSACTION');
|
|
3810
3921
|
if (node.gid) {
|
|
3811
|
-
output.push(
|
|
3922
|
+
output.push(quotes_1.QuoteUtils.escape(node.gid));
|
|
3812
3923
|
}
|
|
3813
3924
|
break;
|
|
3814
3925
|
case 'TRANS_STMT_COMMIT_PREPARED':
|
|
3815
3926
|
output.push('COMMIT PREPARED');
|
|
3816
3927
|
if (node.gid) {
|
|
3817
|
-
output.push(
|
|
3928
|
+
output.push(quotes_1.QuoteUtils.escape(node.gid));
|
|
3818
3929
|
}
|
|
3819
3930
|
break;
|
|
3820
3931
|
case 'TRANS_STMT_ROLLBACK_PREPARED':
|
|
3821
3932
|
output.push('ROLLBACK PREPARED');
|
|
3822
3933
|
if (node.gid) {
|
|
3823
|
-
output.push(
|
|
3934
|
+
output.push(quotes_1.QuoteUtils.escape(node.gid));
|
|
3824
3935
|
}
|
|
3825
3936
|
break;
|
|
3826
3937
|
default:
|
|
@@ -3887,28 +3998,39 @@ class Deparser {
|
|
|
3887
3998
|
switch (node.kind) {
|
|
3888
3999
|
case 'VAR_SET_VALUE':
|
|
3889
4000
|
const localPrefix = node.is_local ? 'LOCAL ' : '';
|
|
4001
|
+
if (node.jumble_args && node.name === 'xmloption' && node.args) {
|
|
4002
|
+
const xmlValue = this.getNodeData(list_utils_1.ListUtils.unwrapList(node.args)[0]);
|
|
4003
|
+
const xmlOption = (typeof xmlValue.sval === 'object' ? xmlValue.sval.sval : xmlValue.sval) || '';
|
|
4004
|
+
return `SET ${localPrefix}XML OPTION ${xmlOption.toUpperCase()}`;
|
|
4005
|
+
}
|
|
3890
4006
|
const args = node.args ? list_utils_1.ListUtils.unwrapList(node.args).map(arg => {
|
|
3891
4007
|
const nodeData = this.getNodeData(arg);
|
|
3892
4008
|
if (nodeData.sval !== undefined) {
|
|
3893
4009
|
const svalValue = typeof nodeData.sval === 'object' ? nodeData.sval.sval : nodeData.sval;
|
|
3894
|
-
if (svalValue
|
|
3895
|
-
return
|
|
4010
|
+
if (!/^[a-z_][a-z0-9_]*$/.test(svalValue) || svalValue.includes(' ') || svalValue.includes('-') || /[A-Z]/.test(svalValue) || /^\d/.test(svalValue) || svalValue.includes('.') || svalValue.includes('$') || svalValue.toLowerCase() === 'all' || /^[+-]\d/.test(svalValue)) {
|
|
4011
|
+
return quotes_1.QuoteUtils.escape(svalValue);
|
|
3896
4012
|
}
|
|
3897
4013
|
return svalValue;
|
|
3898
4014
|
}
|
|
3899
4015
|
return this.visit(arg, context);
|
|
3900
4016
|
}).join(', ') : '';
|
|
4017
|
+
if (node.jumble_args && node.name === 'timezone') {
|
|
4018
|
+
return `SET ${localPrefix}TIME ZONE ${args}`;
|
|
4019
|
+
}
|
|
3901
4020
|
// Handle args - always include TO clause if args exist (even if empty string)
|
|
3902
|
-
const paramName =
|
|
4021
|
+
const paramName = quotes_1.QuoteUtils.quoteIdentifier(node.name);
|
|
3903
4022
|
if (!node.args || node.args.length === 0) {
|
|
3904
4023
|
return `SET ${localPrefix}${paramName}`;
|
|
3905
4024
|
}
|
|
3906
4025
|
return `SET ${localPrefix}${paramName} TO ${args}`;
|
|
3907
4026
|
case 'VAR_SET_DEFAULT':
|
|
3908
|
-
|
|
4027
|
+
if (node.jumble_args && node.name === 'timezone') {
|
|
4028
|
+
return `SET ${node.is_local ? 'LOCAL ' : ''}TIME ZONE DEFAULT`;
|
|
4029
|
+
}
|
|
4030
|
+
const defaultParamName = quotes_1.QuoteUtils.quoteIdentifier(node.name);
|
|
3909
4031
|
return `SET ${defaultParamName} TO DEFAULT`;
|
|
3910
4032
|
case 'VAR_SET_CURRENT':
|
|
3911
|
-
const currentParamName =
|
|
4033
|
+
const currentParamName = quotes_1.QuoteUtils.quoteIdentifier(node.name);
|
|
3912
4034
|
return `SET ${currentParamName} FROM CURRENT`;
|
|
3913
4035
|
case 'VAR_SET_MULTI':
|
|
3914
4036
|
if (node.name === 'TRANSACTION' || node.name === 'SESSION CHARACTERISTICS') {
|
|
@@ -3982,7 +4104,7 @@ class Deparser {
|
|
|
3982
4104
|
return `SET ${assignments}`;
|
|
3983
4105
|
}
|
|
3984
4106
|
case 'VAR_RESET':
|
|
3985
|
-
const resetParamName =
|
|
4107
|
+
const resetParamName = quotes_1.QuoteUtils.quoteIdentifier(node.name);
|
|
3986
4108
|
return `RESET ${resetParamName}`;
|
|
3987
4109
|
case 'VAR_RESET_ALL':
|
|
3988
4110
|
return 'RESET ALL';
|
|
@@ -4002,7 +4124,7 @@ class Deparser {
|
|
|
4002
4124
|
output.push('IF NOT EXISTS');
|
|
4003
4125
|
}
|
|
4004
4126
|
if (node.schemaname) {
|
|
4005
|
-
output.push(node.schemaname);
|
|
4127
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.schemaname));
|
|
4006
4128
|
}
|
|
4007
4129
|
if (node.authrole) {
|
|
4008
4130
|
output.push('AUTHORIZATION');
|
|
@@ -4209,7 +4331,7 @@ class Deparser {
|
|
|
4209
4331
|
if (objList && objList.List && objList.List.items) {
|
|
4210
4332
|
const items = objList.List.items.map((item) => {
|
|
4211
4333
|
if (item.String && item.String.sval) {
|
|
4212
|
-
return item.String.sval;
|
|
4334
|
+
return quotes_1.QuoteUtils.quoteIdentifier(item.String.sval);
|
|
4213
4335
|
}
|
|
4214
4336
|
return this.visit(item, context);
|
|
4215
4337
|
});
|
|
@@ -4251,7 +4373,7 @@ class Deparser {
|
|
|
4251
4373
|
if (objList && objList.List && objList.List.items) {
|
|
4252
4374
|
const items = objList.List.items.map((item) => {
|
|
4253
4375
|
if (item.String && item.String.sval) {
|
|
4254
|
-
return
|
|
4376
|
+
return quotes_1.QuoteUtils.quoteIdentifier(item.String.sval);
|
|
4255
4377
|
}
|
|
4256
4378
|
return this.visit(item, context);
|
|
4257
4379
|
}).filter((name) => name && name.trim());
|
|
@@ -4285,13 +4407,13 @@ class Deparser {
|
|
|
4285
4407
|
if (items.length === 2) {
|
|
4286
4408
|
const accessMethod = items[0];
|
|
4287
4409
|
const objectName = items[1];
|
|
4288
|
-
return `${
|
|
4410
|
+
return `${quotes_1.QuoteUtils.quoteIdentifier(objectName)} USING ${accessMethod}`;
|
|
4289
4411
|
}
|
|
4290
4412
|
else if (items.length === 3) {
|
|
4291
4413
|
const accessMethod = items[0];
|
|
4292
4414
|
const schemaName = items[1];
|
|
4293
4415
|
const objectName = items[2];
|
|
4294
|
-
return `${
|
|
4416
|
+
return `${quotes_1.QuoteUtils.quoteQualifiedIdentifier(schemaName, objectName)} USING ${accessMethod}`;
|
|
4295
4417
|
}
|
|
4296
4418
|
return items.join('.');
|
|
4297
4419
|
}
|
|
@@ -4334,7 +4456,7 @@ class Deparser {
|
|
|
4334
4456
|
if (objList && objList.List && objList.List.items) {
|
|
4335
4457
|
const items = objList.List.items.map((item) => {
|
|
4336
4458
|
if (item.String && item.String.sval) {
|
|
4337
|
-
return
|
|
4459
|
+
return quotes_1.QuoteUtils.quoteIdentifier(item.String.sval);
|
|
4338
4460
|
}
|
|
4339
4461
|
return this.visit(item, context);
|
|
4340
4462
|
}).filter((name) => name && name.trim());
|
|
@@ -4382,7 +4504,7 @@ class Deparser {
|
|
|
4382
4504
|
PLAssignStmt(node, context) {
|
|
4383
4505
|
const output = [];
|
|
4384
4506
|
if (node.name) {
|
|
4385
|
-
let nameWithIndirection =
|
|
4507
|
+
let nameWithIndirection = quotes_1.QuoteUtils.quoteIdentifier(node.name);
|
|
4386
4508
|
if (node.indirection && node.indirection.length > 0) {
|
|
4387
4509
|
const indirectionStr = node.indirection
|
|
4388
4510
|
.map((ind) => this.visit(ind, context))
|
|
@@ -4432,10 +4554,10 @@ class Deparser {
|
|
|
4432
4554
|
output.push('PROGRAM');
|
|
4433
4555
|
}
|
|
4434
4556
|
if (node.filename) {
|
|
4435
|
-
output.push(
|
|
4557
|
+
output.push(quotes_1.QuoteUtils.escape(node.filename));
|
|
4436
4558
|
}
|
|
4437
4559
|
else {
|
|
4438
|
-
output.push('STDIN');
|
|
4560
|
+
output.push(node.is_from ? 'STDIN' : 'STDOUT');
|
|
4439
4561
|
}
|
|
4440
4562
|
if (node.options && node.options.length > 0) {
|
|
4441
4563
|
output.push('WITH');
|
|
@@ -4531,7 +4653,7 @@ class Deparser {
|
|
|
4531
4653
|
const parts = [];
|
|
4532
4654
|
const indentedParts = [];
|
|
4533
4655
|
if (colDefData.colname) {
|
|
4534
|
-
parts.push(
|
|
4656
|
+
parts.push(quotes_1.QuoteUtils.quoteIdentifier(colDefData.colname));
|
|
4535
4657
|
}
|
|
4536
4658
|
if (colDefData.typeName) {
|
|
4537
4659
|
parts.push(this.TypeName(colDefData.typeName, context));
|
|
@@ -4589,7 +4711,7 @@ class Deparser {
|
|
|
4589
4711
|
else {
|
|
4590
4712
|
const parts = [];
|
|
4591
4713
|
if (colDefData.colname) {
|
|
4592
|
-
parts.push(
|
|
4714
|
+
parts.push(quotes_1.QuoteUtils.quoteIdentifier(colDefData.colname));
|
|
4593
4715
|
}
|
|
4594
4716
|
if (colDefData.typeName) {
|
|
4595
4717
|
parts.push(this.TypeName(colDefData.typeName, context));
|
|
@@ -4643,7 +4765,7 @@ class Deparser {
|
|
|
4643
4765
|
}
|
|
4644
4766
|
}
|
|
4645
4767
|
if (node.name) {
|
|
4646
|
-
output.push(
|
|
4768
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4647
4769
|
}
|
|
4648
4770
|
if (node.behavior === 'DROP_CASCADE') {
|
|
4649
4771
|
output.push('CASCADE');
|
|
@@ -4660,13 +4782,16 @@ class Deparser {
|
|
|
4660
4782
|
output.push('ALTER COLUMN');
|
|
4661
4783
|
}
|
|
4662
4784
|
if (node.name) {
|
|
4663
|
-
output.push(
|
|
4785
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4664
4786
|
}
|
|
4665
4787
|
output.push('TYPE');
|
|
4666
4788
|
if (node.def) {
|
|
4667
4789
|
const nodeData = this.getNodeData(node.def);
|
|
4668
4790
|
if (nodeData && nodeData.typeName) {
|
|
4669
4791
|
output.push(this.TypeName(nodeData.typeName, context));
|
|
4792
|
+
if (nodeData.collClause) {
|
|
4793
|
+
output.push(this.CollateClause(nodeData.collClause, context));
|
|
4794
|
+
}
|
|
4670
4795
|
// Handle USING clause (stored in raw_default for ALTER COLUMN TYPE)
|
|
4671
4796
|
if (nodeData.raw_default) {
|
|
4672
4797
|
output.push('USING');
|
|
@@ -4687,7 +4812,7 @@ class Deparser {
|
|
|
4687
4812
|
case 'AT_SetTableSpace':
|
|
4688
4813
|
output.push('SET TABLESPACE');
|
|
4689
4814
|
if (node.name) {
|
|
4690
|
-
output.push(
|
|
4815
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4691
4816
|
}
|
|
4692
4817
|
break;
|
|
4693
4818
|
case 'AT_AddConstraint':
|
|
@@ -4705,7 +4830,7 @@ class Deparser {
|
|
|
4705
4830
|
output.push('DROP CONSTRAINT');
|
|
4706
4831
|
}
|
|
4707
4832
|
if (node.name) {
|
|
4708
|
-
output.push(
|
|
4833
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4709
4834
|
}
|
|
4710
4835
|
if (node.behavior === 'DROP_CASCADE') {
|
|
4711
4836
|
output.push('CASCADE');
|
|
@@ -4743,7 +4868,7 @@ class Deparser {
|
|
|
4743
4868
|
case 'AT_ColumnDefault':
|
|
4744
4869
|
output.push('ALTER COLUMN');
|
|
4745
4870
|
if (node.name) {
|
|
4746
|
-
output.push(
|
|
4871
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4747
4872
|
}
|
|
4748
4873
|
if (node.def) {
|
|
4749
4874
|
output.push('SET DEFAULT');
|
|
@@ -4756,7 +4881,7 @@ class Deparser {
|
|
|
4756
4881
|
case 'AT_SetStorage':
|
|
4757
4882
|
output.push('ALTER COLUMN');
|
|
4758
4883
|
if (node.name) {
|
|
4759
|
-
output.push(
|
|
4884
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4760
4885
|
}
|
|
4761
4886
|
output.push('SET STORAGE');
|
|
4762
4887
|
if (node.def) {
|
|
@@ -4767,7 +4892,7 @@ class Deparser {
|
|
|
4767
4892
|
case 'AT_ClusterOn':
|
|
4768
4893
|
output.push('CLUSTER ON');
|
|
4769
4894
|
if (node.name) {
|
|
4770
|
-
output.push(
|
|
4895
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4771
4896
|
}
|
|
4772
4897
|
break;
|
|
4773
4898
|
case 'AT_DropCluster':
|
|
@@ -4794,21 +4919,21 @@ class Deparser {
|
|
|
4794
4919
|
case 'AT_SetNotNull':
|
|
4795
4920
|
output.push('ALTER COLUMN');
|
|
4796
4921
|
if (node.name) {
|
|
4797
|
-
output.push(
|
|
4922
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4798
4923
|
}
|
|
4799
4924
|
output.push('SET NOT NULL');
|
|
4800
4925
|
break;
|
|
4801
4926
|
case 'AT_DropNotNull':
|
|
4802
4927
|
output.push('ALTER COLUMN');
|
|
4803
4928
|
if (node.name) {
|
|
4804
|
-
output.push(
|
|
4929
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4805
4930
|
}
|
|
4806
4931
|
output.push('DROP NOT NULL');
|
|
4807
4932
|
break;
|
|
4808
4933
|
case 'AT_SetStatistics':
|
|
4809
4934
|
output.push('ALTER COLUMN');
|
|
4810
4935
|
if (node.name) {
|
|
4811
|
-
output.push(
|
|
4936
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4812
4937
|
}
|
|
4813
4938
|
else if (node.num !== undefined && node.num !== null) {
|
|
4814
4939
|
output.push(node.num.toString());
|
|
@@ -4821,7 +4946,7 @@ class Deparser {
|
|
|
4821
4946
|
case 'AT_SetOptions':
|
|
4822
4947
|
output.push('ALTER COLUMN');
|
|
4823
4948
|
if (node.name) {
|
|
4824
|
-
output.push(
|
|
4949
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4825
4950
|
}
|
|
4826
4951
|
output.push('SET');
|
|
4827
4952
|
if (node.def) {
|
|
@@ -4838,7 +4963,7 @@ class Deparser {
|
|
|
4838
4963
|
case 'AT_ResetOptions':
|
|
4839
4964
|
output.push('ALTER COLUMN');
|
|
4840
4965
|
if (node.name) {
|
|
4841
|
-
output.push(
|
|
4966
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4842
4967
|
}
|
|
4843
4968
|
output.push('RESET');
|
|
4844
4969
|
if (node.def) {
|
|
@@ -4855,7 +4980,7 @@ class Deparser {
|
|
|
4855
4980
|
case 'AT_SetCompression':
|
|
4856
4981
|
output.push('ALTER COLUMN');
|
|
4857
4982
|
if (node.name) {
|
|
4858
|
-
output.push(
|
|
4983
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4859
4984
|
}
|
|
4860
4985
|
output.push('SET COMPRESSION');
|
|
4861
4986
|
if (node.def) {
|
|
@@ -4865,31 +4990,31 @@ class Deparser {
|
|
|
4865
4990
|
case 'AT_ValidateConstraint':
|
|
4866
4991
|
output.push('VALIDATE CONSTRAINT');
|
|
4867
4992
|
if (node.name) {
|
|
4868
|
-
output.push(
|
|
4993
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4869
4994
|
}
|
|
4870
4995
|
break;
|
|
4871
4996
|
case 'AT_EnableTrig':
|
|
4872
4997
|
output.push('ENABLE TRIGGER');
|
|
4873
4998
|
if (node.name) {
|
|
4874
|
-
output.push(
|
|
4999
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4875
5000
|
}
|
|
4876
5001
|
break;
|
|
4877
5002
|
case 'AT_EnableAlwaysTrig':
|
|
4878
5003
|
output.push('ENABLE ALWAYS TRIGGER');
|
|
4879
5004
|
if (node.name) {
|
|
4880
|
-
output.push(
|
|
5005
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4881
5006
|
}
|
|
4882
5007
|
break;
|
|
4883
5008
|
case 'AT_EnableReplicaTrig':
|
|
4884
5009
|
output.push('ENABLE REPLICA TRIGGER');
|
|
4885
5010
|
if (node.name) {
|
|
4886
|
-
output.push(
|
|
5011
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4887
5012
|
}
|
|
4888
5013
|
break;
|
|
4889
5014
|
case 'AT_DisableTrig':
|
|
4890
5015
|
output.push('DISABLE TRIGGER');
|
|
4891
5016
|
if (node.name) {
|
|
4892
|
-
output.push(
|
|
5017
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4893
5018
|
}
|
|
4894
5019
|
break;
|
|
4895
5020
|
case 'AT_EnableTrigAll':
|
|
@@ -4907,31 +5032,31 @@ class Deparser {
|
|
|
4907
5032
|
case 'AT_EnableRule':
|
|
4908
5033
|
output.push('ENABLE RULE');
|
|
4909
5034
|
if (node.name) {
|
|
4910
|
-
output.push(
|
|
5035
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4911
5036
|
}
|
|
4912
5037
|
break;
|
|
4913
5038
|
case 'AT_EnableAlwaysRule':
|
|
4914
5039
|
output.push('ENABLE ALWAYS RULE');
|
|
4915
5040
|
if (node.name) {
|
|
4916
|
-
output.push(
|
|
5041
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4917
5042
|
}
|
|
4918
5043
|
break;
|
|
4919
5044
|
case 'AT_EnableReplicaRule':
|
|
4920
5045
|
output.push('ENABLE REPLICA RULE');
|
|
4921
5046
|
if (node.name) {
|
|
4922
|
-
output.push(
|
|
5047
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4923
5048
|
}
|
|
4924
5049
|
break;
|
|
4925
5050
|
case 'AT_DisableRule':
|
|
4926
5051
|
output.push('DISABLE RULE');
|
|
4927
5052
|
if (node.name) {
|
|
4928
|
-
output.push(
|
|
5053
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4929
5054
|
}
|
|
4930
5055
|
break;
|
|
4931
5056
|
case 'AT_SetAccessMethod':
|
|
4932
5057
|
output.push('SET ACCESS METHOD');
|
|
4933
5058
|
if (node.name) {
|
|
4934
|
-
output.push(
|
|
5059
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4935
5060
|
}
|
|
4936
5061
|
else {
|
|
4937
5062
|
// Handle DEFAULT access method case
|
|
@@ -4985,7 +5110,7 @@ class Deparser {
|
|
|
4985
5110
|
case 'AT_CookedColumnDefault':
|
|
4986
5111
|
output.push('ALTER COLUMN');
|
|
4987
5112
|
if (node.name) {
|
|
4988
|
-
output.push(
|
|
5113
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
4989
5114
|
}
|
|
4990
5115
|
if (node.def) {
|
|
4991
5116
|
output.push('SET DEFAULT');
|
|
@@ -4998,26 +5123,23 @@ class Deparser {
|
|
|
4998
5123
|
case 'AT_SetExpression':
|
|
4999
5124
|
output.push('ALTER COLUMN');
|
|
5000
5125
|
if (node.name) {
|
|
5001
|
-
output.push(
|
|
5126
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5002
5127
|
}
|
|
5003
5128
|
output.push('SET EXPRESSION');
|
|
5004
5129
|
if (node.def) {
|
|
5005
|
-
output.push(
|
|
5130
|
+
output.push('AS');
|
|
5131
|
+
output.push(context.parens(this.visit(node.def, context)));
|
|
5006
5132
|
}
|
|
5007
5133
|
break;
|
|
5008
5134
|
case 'AT_DropExpression':
|
|
5009
5135
|
output.push('ALTER COLUMN');
|
|
5010
5136
|
if (node.name) {
|
|
5011
|
-
output.push(
|
|
5137
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5012
5138
|
}
|
|
5013
5139
|
output.push('DROP EXPRESSION');
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
output.push('ALTER COLUMN');
|
|
5017
|
-
if (node.name) {
|
|
5018
|
-
output.push(quote_utils_1.QuoteUtils.quote(node.name));
|
|
5140
|
+
if (node.missing_ok) {
|
|
5141
|
+
output.push('IF EXISTS');
|
|
5019
5142
|
}
|
|
5020
|
-
output.push('SET NOT NULL');
|
|
5021
5143
|
break;
|
|
5022
5144
|
case 'AT_AddIndex':
|
|
5023
5145
|
output.push('ADD');
|
|
@@ -5044,23 +5166,28 @@ class Deparser {
|
|
|
5044
5166
|
}
|
|
5045
5167
|
break;
|
|
5046
5168
|
case 'AT_AlterConstraint':
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5169
|
+
if (node.def && this.getNodeType(node.def) === 'ATAlterConstraint') {
|
|
5170
|
+
output.push(this.ATAlterConstraint(this.getNodeData(node.def), context));
|
|
5171
|
+
}
|
|
5172
|
+
else {
|
|
5173
|
+
output.push('ALTER CONSTRAINT');
|
|
5174
|
+
if (node.def && this.getNodeType(node.def) === 'Constraint') {
|
|
5175
|
+
const constraintData = this.getNodeData(node.def);
|
|
5176
|
+
if (constraintData.conname) {
|
|
5177
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(constraintData.conname));
|
|
5178
|
+
if (constraintData.deferrable !== undefined) {
|
|
5179
|
+
output.push(constraintData.deferrable ? 'DEFERRABLE' : 'NOT DEFERRABLE');
|
|
5180
|
+
}
|
|
5181
|
+
if (constraintData.initdeferred !== undefined) {
|
|
5182
|
+
output.push(constraintData.initdeferred ? 'INITIALLY DEFERRED' : 'INITIALLY IMMEDIATE');
|
|
5183
|
+
}
|
|
5057
5184
|
}
|
|
5058
5185
|
}
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5186
|
+
else if (node.name) {
|
|
5187
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5188
|
+
if (node.def) {
|
|
5189
|
+
output.push(this.visit(node.def, context));
|
|
5190
|
+
}
|
|
5064
5191
|
}
|
|
5065
5192
|
}
|
|
5066
5193
|
break;
|
|
@@ -5079,7 +5206,7 @@ class Deparser {
|
|
|
5079
5206
|
case 'AT_AlterColumnGenericOptions':
|
|
5080
5207
|
output.push('ALTER COLUMN');
|
|
5081
5208
|
if (node.name) {
|
|
5082
|
-
output.push(
|
|
5209
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5083
5210
|
}
|
|
5084
5211
|
output.push('OPTIONS');
|
|
5085
5212
|
if (node.def) {
|
|
@@ -5133,7 +5260,7 @@ class Deparser {
|
|
|
5133
5260
|
case 'AT_AddIdentity':
|
|
5134
5261
|
output.push('ALTER COLUMN');
|
|
5135
5262
|
if (node.name) {
|
|
5136
|
-
output.push(
|
|
5263
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5137
5264
|
}
|
|
5138
5265
|
output.push('ADD');
|
|
5139
5266
|
if (node.def) {
|
|
@@ -5143,24 +5270,20 @@ class Deparser {
|
|
|
5143
5270
|
case 'AT_SetIdentity':
|
|
5144
5271
|
output.push('ALTER COLUMN');
|
|
5145
5272
|
if (node.name) {
|
|
5146
|
-
output.push(
|
|
5273
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5147
5274
|
}
|
|
5148
|
-
output.push('SET');
|
|
5149
5275
|
if (node.def) {
|
|
5150
|
-
output.push(this.
|
|
5276
|
+
output.push(this.formatIdentityColumnOptions(node.def, context));
|
|
5151
5277
|
}
|
|
5152
5278
|
break;
|
|
5153
5279
|
case 'AT_DropIdentity':
|
|
5154
5280
|
output.push('ALTER COLUMN');
|
|
5155
5281
|
if (node.name) {
|
|
5156
|
-
output.push(
|
|
5282
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5157
5283
|
}
|
|
5158
5284
|
output.push('DROP IDENTITY');
|
|
5159
|
-
if (node.
|
|
5160
|
-
output.push('
|
|
5161
|
-
}
|
|
5162
|
-
else if (node.behavior === 'DROP_RESTRICT') {
|
|
5163
|
-
output.push('RESTRICT');
|
|
5285
|
+
if (node.missing_ok) {
|
|
5286
|
+
output.push('IF EXISTS');
|
|
5164
5287
|
}
|
|
5165
5288
|
break;
|
|
5166
5289
|
case 'AT_ReAddStatistics':
|
|
@@ -5187,7 +5310,8 @@ class Deparser {
|
|
|
5187
5310
|
output.push('FUNCTION');
|
|
5188
5311
|
}
|
|
5189
5312
|
if (node.funcname && node.funcname.length > 0) {
|
|
5190
|
-
const
|
|
5313
|
+
const funcnameParts = node.funcname.map((name) => name.String?.sval || name.String?.str || '').filter((s) => s);
|
|
5314
|
+
const funcName = quotes_1.QuoteUtils.quoteDottedName(funcnameParts);
|
|
5191
5315
|
if (node.parameters && node.parameters.length > 0) {
|
|
5192
5316
|
const params = node.parameters
|
|
5193
5317
|
.filter((param) => {
|
|
@@ -5196,7 +5320,13 @@ class Deparser {
|
|
|
5196
5320
|
})
|
|
5197
5321
|
.map((param) => this.visit(param, context));
|
|
5198
5322
|
if (params.length > 0) {
|
|
5199
|
-
|
|
5323
|
+
if (context.isPretty()) {
|
|
5324
|
+
const formattedParams = params.map(p => context.indent(p)).join(',' + context.newline());
|
|
5325
|
+
output.push(funcName + '(' + context.newline() + formattedParams + context.newline() + ')');
|
|
5326
|
+
}
|
|
5327
|
+
else {
|
|
5328
|
+
output.push(funcName + '(' + params.join(', ') + ')');
|
|
5329
|
+
}
|
|
5200
5330
|
}
|
|
5201
5331
|
else {
|
|
5202
5332
|
output.push(funcName + '()');
|
|
@@ -5211,15 +5341,21 @@ class Deparser {
|
|
|
5211
5341
|
return paramData.mode === 'FUNC_PARAM_TABLE';
|
|
5212
5342
|
});
|
|
5213
5343
|
if (hasTableParams) {
|
|
5214
|
-
output.push('RETURNS TABLE (');
|
|
5215
5344
|
const tableParams = node.parameters
|
|
5216
5345
|
.filter((param) => {
|
|
5217
5346
|
const paramData = this.getNodeData(param);
|
|
5218
5347
|
return paramData.mode === 'FUNC_PARAM_TABLE';
|
|
5219
5348
|
})
|
|
5220
5349
|
.map((param) => this.visit(param, context));
|
|
5221
|
-
|
|
5222
|
-
|
|
5350
|
+
if (context.isPretty()) {
|
|
5351
|
+
const formattedTableParams = tableParams.map(p => context.indent(p)).join(',' + context.newline());
|
|
5352
|
+
output.push('RETURNS TABLE (' + context.newline() + formattedTableParams + context.newline() + ')');
|
|
5353
|
+
}
|
|
5354
|
+
else {
|
|
5355
|
+
output.push('RETURNS TABLE (');
|
|
5356
|
+
output.push(tableParams.join(', '));
|
|
5357
|
+
output.push(')');
|
|
5358
|
+
}
|
|
5223
5359
|
}
|
|
5224
5360
|
else if (node.returnType) {
|
|
5225
5361
|
output.push('RETURNS');
|
|
@@ -5241,6 +5377,7 @@ class Deparser {
|
|
|
5241
5377
|
if (bodyType === 'List') {
|
|
5242
5378
|
const statements = list_utils_1.ListUtils.unwrapList(node.sql_body);
|
|
5243
5379
|
if (statements.length === 0 || (statements.length === 1 && Object.keys(statements[0]).length === 0)) {
|
|
5380
|
+
// empty body: nothing to emit
|
|
5244
5381
|
}
|
|
5245
5382
|
else {
|
|
5246
5383
|
// Handle nested List structure in BEGIN ATOMIC blocks
|
|
@@ -5292,7 +5429,7 @@ class Deparser {
|
|
|
5292
5429
|
}
|
|
5293
5430
|
}
|
|
5294
5431
|
if (node.name) {
|
|
5295
|
-
output.push(
|
|
5432
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5296
5433
|
}
|
|
5297
5434
|
if (node.argType) {
|
|
5298
5435
|
output.push(this.TypeName(node.argType, context));
|
|
@@ -5364,7 +5501,7 @@ class Deparser {
|
|
|
5364
5501
|
output.push('ROLE');
|
|
5365
5502
|
}
|
|
5366
5503
|
if (node.role) {
|
|
5367
|
-
const roleName =
|
|
5504
|
+
const roleName = quotes_1.QuoteUtils.quoteIdentifier(node.role);
|
|
5368
5505
|
output.push(roleName);
|
|
5369
5506
|
}
|
|
5370
5507
|
if (node.options) {
|
|
@@ -5388,25 +5525,28 @@ class Deparser {
|
|
|
5388
5525
|
if (node.arg && this.getNodeType(node.arg) === 'List') {
|
|
5389
5526
|
const listData = this.getNodeData(node.arg);
|
|
5390
5527
|
const listItems = list_utils_1.ListUtils.unwrapList(listData.items);
|
|
5528
|
+
const preservedName = this.preserveOperatorDefElemCase(node.defname);
|
|
5391
5529
|
if (listItems.length === 1 && listItems[0].String) {
|
|
5392
|
-
const preservedName = this.preserveOperatorDefElemCase(node.defname);
|
|
5393
5530
|
return `${preservedName} = ${listItems[0].String.sval}`;
|
|
5394
5531
|
}
|
|
5532
|
+
if (listItems.length > 1 && listItems.every((item) => item.String)) {
|
|
5533
|
+
return `${preservedName} = OPERATOR(${this.qualifiedOperatorName(listItems)})`;
|
|
5534
|
+
}
|
|
5395
5535
|
}
|
|
5396
5536
|
}
|
|
5397
5537
|
// Handle IndexElem opclassopts - MUST be first to preserve string types
|
|
5398
5538
|
if (context.parentNodeTypes.includes('IndexElem')) {
|
|
5399
5539
|
if (node.arg && this.getNodeType(node.arg) === 'String') {
|
|
5400
5540
|
const stringData = this.getNodeData(node.arg);
|
|
5401
|
-
return `${node.defname}
|
|
5541
|
+
return `${quotes_1.QuoteUtils.quoteIdentifierAfterDot(node.defname)}=${quotes_1.QuoteUtils.escape(stringData.sval)}`;
|
|
5402
5542
|
}
|
|
5403
|
-
return `${node.defname}=${this.visit(node.arg, context.spawn('DefElem'))}`;
|
|
5543
|
+
return `${quotes_1.QuoteUtils.quoteIdentifierAfterDot(node.defname)}=${this.formatOptionValue(node.arg, this.visit(node.arg, context.spawn('DefElem')))}`;
|
|
5404
5544
|
}
|
|
5405
5545
|
// Handle CREATE OPERATOR boolean flags - MUST be first to preserve case
|
|
5406
5546
|
if (context.parentNodeTypes.includes('DefineStmt') &&
|
|
5407
5547
|
['hashes', 'merges'].includes(node.defname.toLowerCase()) && !node.arg) {
|
|
5408
5548
|
if (node.defname !== node.defname.toLowerCase() && node.defname !== node.defname.toUpperCase()) {
|
|
5409
|
-
return
|
|
5549
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.defname);
|
|
5410
5550
|
}
|
|
5411
5551
|
return node.defname.charAt(0).toUpperCase() + node.defname.slice(1).toLowerCase();
|
|
5412
5552
|
}
|
|
@@ -5425,12 +5565,8 @@ class Deparser {
|
|
|
5425
5565
|
const defElemContext = context.spawn('DefElem');
|
|
5426
5566
|
const argValue = this.visit(node.arg, defElemContext);
|
|
5427
5567
|
if (context.parentNodeTypes.includes('CreateFdwStmt') || context.parentNodeTypes.includes('AlterFdwStmt')) {
|
|
5428
|
-
const finalValue =
|
|
5429
|
-
|
|
5430
|
-
: argValue;
|
|
5431
|
-
const quotedDefname = node.defname.includes(' ') || node.defname.includes('-') || Deparser.needsQuotes(node.defname)
|
|
5432
|
-
? `"${node.defname}"`
|
|
5433
|
-
: node.defname;
|
|
5568
|
+
const finalValue = this.quoteDefElemArg(node.arg, argValue);
|
|
5569
|
+
const quotedDefname = quotes_1.QuoteUtils.quoteIdentifier(node.defname);
|
|
5434
5570
|
if (node.defaction === 'DEFELEM_ADD') {
|
|
5435
5571
|
return `ADD ${quotedDefname} ${finalValue}`;
|
|
5436
5572
|
}
|
|
@@ -5442,9 +5578,7 @@ class Deparser {
|
|
|
5442
5578
|
}
|
|
5443
5579
|
return `${quotedDefname} ${finalValue}`;
|
|
5444
5580
|
}
|
|
5445
|
-
const quotedValue =
|
|
5446
|
-
? `'${argValue}'`
|
|
5447
|
-
: argValue;
|
|
5581
|
+
const quotedValue = this.quoteDefElemArg(node.arg, argValue);
|
|
5448
5582
|
if (node.defaction === 'DEFELEM_ADD') {
|
|
5449
5583
|
return `ADD ${node.defname} ${quotedValue}`;
|
|
5450
5584
|
}
|
|
@@ -5454,9 +5588,7 @@ class Deparser {
|
|
|
5454
5588
|
else if (node.defaction === 'DEFELEM_SET') {
|
|
5455
5589
|
return `SET ${node.defname} ${quotedValue}`;
|
|
5456
5590
|
}
|
|
5457
|
-
const quotedDefname =
|
|
5458
|
-
? `"${node.defname}"`
|
|
5459
|
-
: node.defname;
|
|
5591
|
+
const quotedDefname = quotes_1.QuoteUtils.quoteIdentifier(node.defname);
|
|
5460
5592
|
return `${quotedDefname} ${quotedValue}`;
|
|
5461
5593
|
}
|
|
5462
5594
|
else if (node.defaction === 'DEFELEM_DROP') {
|
|
@@ -5478,9 +5610,7 @@ class Deparser {
|
|
|
5478
5610
|
}
|
|
5479
5611
|
const defElemContext = context.spawn('DefElem');
|
|
5480
5612
|
const argValue = this.visit(node.arg, defElemContext);
|
|
5481
|
-
const quotedValue =
|
|
5482
|
-
? `'${argValue}'`
|
|
5483
|
-
: argValue;
|
|
5613
|
+
const quotedValue = this.quoteDefElemArg(node.arg, argValue);
|
|
5484
5614
|
return `PASSWORD ${quotedValue}`;
|
|
5485
5615
|
}
|
|
5486
5616
|
}
|
|
@@ -5503,22 +5633,23 @@ class Deparser {
|
|
|
5503
5633
|
if (listItems.length === 1 && listItems[0].String) {
|
|
5504
5634
|
return `${node.defname} = ${listItems[0].String.sval}`;
|
|
5505
5635
|
}
|
|
5636
|
+
if (listItems.length > 1 && listItems.every((item) => item.String)) {
|
|
5637
|
+
return `${node.defname} = OPERATOR(${this.qualifiedOperatorName(listItems)})`;
|
|
5638
|
+
}
|
|
5506
5639
|
}
|
|
5507
5640
|
}
|
|
5508
5641
|
if (context.parentNodeTypes.includes('CreatedbStmt') || context.parentNodeTypes.includes('DropdbStmt')) {
|
|
5509
5642
|
const quotedValue = typeof argValue === 'string'
|
|
5510
|
-
?
|
|
5643
|
+
? quotes_1.QuoteUtils.escape(argValue)
|
|
5511
5644
|
: argValue;
|
|
5512
5645
|
return `${node.defname} = ${quotedValue}`;
|
|
5513
5646
|
}
|
|
5514
5647
|
// CreateForeignServerStmt and AlterForeignServerStmt use space format like CreateFdwStmt
|
|
5515
5648
|
if (context.parentNodeTypes.includes('CreateForeignServerStmt') || context.parentNodeTypes.includes('AlterForeignServerStmt')) {
|
|
5516
5649
|
const quotedValue = typeof argValue === 'string'
|
|
5517
|
-
?
|
|
5650
|
+
? quotes_1.QuoteUtils.escape(argValue)
|
|
5518
5651
|
: argValue;
|
|
5519
|
-
const quotedDefname =
|
|
5520
|
-
? `"${node.defname}"`
|
|
5521
|
-
: node.defname;
|
|
5652
|
+
const quotedDefname = quotes_1.QuoteUtils.quoteIdentifier(node.defname);
|
|
5522
5653
|
return `${quotedDefname} ${quotedValue}`;
|
|
5523
5654
|
}
|
|
5524
5655
|
if (context.parentNodeTypes.includes('CreateRoleStmt') || context.parentNodeTypes.includes('AlterRoleStmt')) {
|
|
@@ -5547,9 +5678,7 @@ class Deparser {
|
|
|
5547
5678
|
}
|
|
5548
5679
|
}
|
|
5549
5680
|
if (node.defname === 'validUntil') {
|
|
5550
|
-
const quotedValue =
|
|
5551
|
-
? `'${argValue}'`
|
|
5552
|
-
: argValue;
|
|
5681
|
+
const quotedValue = this.quoteDefElemArg(node.arg, argValue);
|
|
5553
5682
|
return `VALID UNTIL ${quotedValue}`;
|
|
5554
5683
|
}
|
|
5555
5684
|
if (node.defname === 'adminmembers') {
|
|
@@ -5588,15 +5717,15 @@ class Deparser {
|
|
|
5588
5717
|
if (node.arg && this.getNodeType(node.arg) === 'List') {
|
|
5589
5718
|
const listData = this.getNodeData(node.arg);
|
|
5590
5719
|
const listItems = list_utils_1.ListUtils.unwrapList(listData.items);
|
|
5720
|
+
if (listItems.length === 1 && listItems[0].String?.sval === 'none') {
|
|
5721
|
+
return 'OWNED BY NONE';
|
|
5722
|
+
}
|
|
5591
5723
|
const parts = listItems.map(item => {
|
|
5592
5724
|
const itemData = this.getNodeData(item);
|
|
5593
5725
|
if (this.getNodeType(item) === 'String') {
|
|
5594
5726
|
// Check if this identifier needs quotes to preserve case
|
|
5595
5727
|
const value = itemData.sval;
|
|
5596
|
-
|
|
5597
|
-
return `"${value}"`;
|
|
5598
|
-
}
|
|
5599
|
-
return value;
|
|
5728
|
+
return quotes_1.QuoteUtils.quoteIdentifier(value);
|
|
5600
5729
|
}
|
|
5601
5730
|
return this.visit(item, context);
|
|
5602
5731
|
});
|
|
@@ -5729,10 +5858,8 @@ class Deparser {
|
|
|
5729
5858
|
if (context.parentNodeTypes.includes('AlterExtensionStmt')) {
|
|
5730
5859
|
if (node.defname === 'new_version') {
|
|
5731
5860
|
// argValue is unquoted due to DefElem context, so we need to quote it
|
|
5732
|
-
const quotedValue =
|
|
5733
|
-
|
|
5734
|
-
: argValue;
|
|
5735
|
-
return `UPDATE TO ${quotedValue}`;
|
|
5861
|
+
const quotedValue = this.quoteDefElemArg(node.arg, argValue);
|
|
5862
|
+
return `TO ${quotedValue}`;
|
|
5736
5863
|
}
|
|
5737
5864
|
if (node.defname === 'schema') {
|
|
5738
5865
|
return `SET SCHEMA ${argValue}`;
|
|
@@ -5744,7 +5871,7 @@ class Deparser {
|
|
|
5744
5871
|
return `${node.defname.toUpperCase()} ${argValue}`;
|
|
5745
5872
|
}
|
|
5746
5873
|
const quotedValue = typeof argValue === 'string'
|
|
5747
|
-
?
|
|
5874
|
+
? quotes_1.QuoteUtils.escape(argValue)
|
|
5748
5875
|
: argValue;
|
|
5749
5876
|
return `${node.defname} ${quotedValue}`;
|
|
5750
5877
|
}
|
|
@@ -5752,28 +5879,37 @@ class Deparser {
|
|
|
5752
5879
|
if (node.defname === 'cascade') {
|
|
5753
5880
|
return argValue === 'true' ? 'CASCADE' : '';
|
|
5754
5881
|
}
|
|
5882
|
+
if (node.defname === 'new_version') {
|
|
5883
|
+
return `VERSION ${this.quoteDefElemArg(node.arg, argValue)}`;
|
|
5884
|
+
}
|
|
5885
|
+
if (node.defname === 'schema' && node.arg && this.getNodeType(node.arg) === 'String') {
|
|
5886
|
+
return `SCHEMA ${quotes_1.QuoteUtils.quoteIdentifier(this.getNodeData(node.arg).sval)}`;
|
|
5887
|
+
}
|
|
5755
5888
|
return `${node.defname.toUpperCase()} ${argValue}`;
|
|
5756
5889
|
}
|
|
5757
5890
|
// Handle IndexStmt WITH clause options - no quotes, compact formatting
|
|
5758
5891
|
if (context.parentNodeTypes.includes('IndexStmt')) {
|
|
5759
|
-
return `${node.defname}=${argValue}`;
|
|
5892
|
+
return `${quotes_1.QuoteUtils.quoteIdentifierAfterDot(node.defname)}=${this.formatOptionValue(node.arg, argValue)}`;
|
|
5760
5893
|
}
|
|
5761
5894
|
// Handle IndexElem opclassopts - preserve string values as strings
|
|
5762
5895
|
if (context.parentNodeTypes.includes('IndexElem')) {
|
|
5763
5896
|
if (node.arg && this.getNodeType(node.arg) === 'String') {
|
|
5764
5897
|
const stringData = this.getNodeData(node.arg);
|
|
5765
|
-
return `${node.defname}
|
|
5898
|
+
return `${quotes_1.QuoteUtils.quoteIdentifierAfterDot(node.defname)}=${quotes_1.QuoteUtils.escape(stringData.sval)}`;
|
|
5766
5899
|
}
|
|
5767
|
-
return `${node.defname}=${argValue}`;
|
|
5900
|
+
return `${quotes_1.QuoteUtils.quoteIdentifierAfterDot(node.defname)}=${this.formatOptionValue(node.arg, argValue)}`;
|
|
5768
5901
|
}
|
|
5769
5902
|
// Handle CreateStmt table options - no quotes, compact formatting
|
|
5770
5903
|
if (context.parentNodeTypes.includes('CreateStmt')) {
|
|
5904
|
+
const relOptName = node.defnamespace
|
|
5905
|
+
? `${quotes_1.QuoteUtils.quoteIdentifier(node.defnamespace)}.${quotes_1.QuoteUtils.quoteIdentifier(node.defname)}`
|
|
5906
|
+
: quotes_1.QuoteUtils.quoteIdentifier(node.defname);
|
|
5771
5907
|
// For numeric values, use the raw value without quotes
|
|
5772
5908
|
if (node.arg && this.getNodeType(node.arg) === 'Integer') {
|
|
5773
5909
|
const integerData = this.getNodeData(node.arg);
|
|
5774
|
-
return `${
|
|
5910
|
+
return `${relOptName}=${formatInteger(integerData.ival)}`;
|
|
5775
5911
|
}
|
|
5776
|
-
return `${
|
|
5912
|
+
return `${relOptName}=${this.formatOptionValue(node.arg, argValue)}`;
|
|
5777
5913
|
}
|
|
5778
5914
|
// Handle CreateEventTrigStmt WHEN clause - use IN syntax for List arguments
|
|
5779
5915
|
if (context.parentNodeTypes.includes('CreateEventTrigStmt')) {
|
|
@@ -5783,7 +5919,7 @@ class Deparser {
|
|
|
5783
5919
|
const values = listItems.map(item => {
|
|
5784
5920
|
if (this.getNodeType(item) === 'String') {
|
|
5785
5921
|
const stringData = this.getNodeData(item);
|
|
5786
|
-
return
|
|
5922
|
+
return quotes_1.QuoteUtils.escape(stringData.sval || '');
|
|
5787
5923
|
}
|
|
5788
5924
|
return this.visit(item, context);
|
|
5789
5925
|
});
|
|
@@ -5798,7 +5934,7 @@ class Deparser {
|
|
|
5798
5934
|
if (node.arg && this.getNodeType(node.arg) === 'TypeName') {
|
|
5799
5935
|
return `${optionName} = ${argValue}`;
|
|
5800
5936
|
}
|
|
5801
|
-
return `${optionName} = ${argValue}`;
|
|
5937
|
+
return `${optionName} = ${this.formatOptionValue(node.arg, argValue)}`;
|
|
5802
5938
|
}
|
|
5803
5939
|
// Handle ViewStmt WITH options - don't quote numeric values
|
|
5804
5940
|
if (context.parentNodeTypes.includes('ViewStmt')) {
|
|
@@ -5806,21 +5942,33 @@ class Deparser {
|
|
|
5806
5942
|
return `${node.defname}=${argValue}`;
|
|
5807
5943
|
}
|
|
5808
5944
|
const quotedValue = typeof argValue === 'string'
|
|
5809
|
-
?
|
|
5945
|
+
? quotes_1.QuoteUtils.escape(argValue)
|
|
5810
5946
|
: argValue;
|
|
5811
5947
|
return `${node.defname} = ${quotedValue}`;
|
|
5812
5948
|
}
|
|
5813
5949
|
// Handle CopyStmt WITH clause options - uppercase format without quotes
|
|
5814
5950
|
if (context.parentNodeTypes.includes('CopyStmt')) {
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
return
|
|
5951
|
+
const optName = node.defname.toUpperCase();
|
|
5952
|
+
if (!node.arg) {
|
|
5953
|
+
return optName;
|
|
5818
5954
|
}
|
|
5819
|
-
|
|
5820
|
-
if (node.arg) {
|
|
5821
|
-
return
|
|
5955
|
+
const copyArgType = this.getNodeType(node.arg);
|
|
5956
|
+
if (copyArgType === 'Boolean' && this.getNodeData(node.arg).boolval !== false) {
|
|
5957
|
+
return optName;
|
|
5822
5958
|
}
|
|
5823
|
-
|
|
5959
|
+
if (copyArgType === 'List') {
|
|
5960
|
+
const items = list_utils_1.ListUtils.unwrapList(this.getNodeData(node.arg).items)
|
|
5961
|
+
.map(item => this.visit(item, context));
|
|
5962
|
+
return `${optName} (${items.join(', ')})`;
|
|
5963
|
+
}
|
|
5964
|
+
if (copyArgType === 'String') {
|
|
5965
|
+
const sval = this.getNodeData(node.arg).sval;
|
|
5966
|
+
if (node.defname === 'format') {
|
|
5967
|
+
return `${optName} ${sval}`;
|
|
5968
|
+
}
|
|
5969
|
+
return `${optName} ${quotes_1.QuoteUtils.escape(sval)}`;
|
|
5970
|
+
}
|
|
5971
|
+
return `${optName} ${argValue}`;
|
|
5824
5972
|
}
|
|
5825
5973
|
// Handle CREATE OPERATOR and CREATE TYPE context
|
|
5826
5974
|
if (context.parentNodeTypes.includes('DefineStmt')) {
|
|
@@ -5844,13 +5992,13 @@ class Deparser {
|
|
|
5844
5992
|
// Handle boolean flags (no arguments) - preserve quoted case
|
|
5845
5993
|
if (['hashes', 'merges'].includes(node.defname.toLowerCase())) {
|
|
5846
5994
|
if (node.defname !== node.defname.toLowerCase() && node.defname !== node.defname.toUpperCase()) {
|
|
5847
|
-
return
|
|
5995
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.defname);
|
|
5848
5996
|
}
|
|
5849
5997
|
return preservedName.toUpperCase();
|
|
5850
5998
|
}
|
|
5851
5999
|
// Handle CREATE AGGREGATE quoted identifiers - preserve quotes when needed
|
|
5852
|
-
|
|
5853
|
-
|
|
6000
|
+
const quotedDefname = quotes_1.QuoteUtils.quoteIdentifier(node.defname);
|
|
6001
|
+
if (quotedDefname !== node.defname) {
|
|
5854
6002
|
if (node.arg) {
|
|
5855
6003
|
if (this.getNodeType(node.arg) === 'String') {
|
|
5856
6004
|
const stringData = this.getNodeData(node.arg);
|
|
@@ -5859,7 +6007,7 @@ class Deparser {
|
|
|
5859
6007
|
return `${quotedDefname} = ${stringData.sval}`;
|
|
5860
6008
|
}
|
|
5861
6009
|
// Regular string literals get single quotes
|
|
5862
|
-
return `${quotedDefname} =
|
|
6010
|
+
return `${quotedDefname} = ${quotes_1.QuoteUtils.escape(stringData.sval)}`;
|
|
5863
6011
|
}
|
|
5864
6012
|
return `${quotedDefname} = ${argValue}`;
|
|
5865
6013
|
}
|
|
@@ -5880,7 +6028,7 @@ class Deparser {
|
|
|
5880
6028
|
return `${node.defname} = ${stringData.sval}`;
|
|
5881
6029
|
}
|
|
5882
6030
|
// Regular string literals get single quotes
|
|
5883
|
-
return `${node.defname} =
|
|
6031
|
+
return `${node.defname} = ${quotes_1.QuoteUtils.escape(stringData.sval)}`;
|
|
5884
6032
|
}
|
|
5885
6033
|
if (node.arg && this.getNodeType(node.arg) === 'Boolean') {
|
|
5886
6034
|
const boolData = this.getNodeData(node.arg);
|
|
@@ -5901,8 +6049,12 @@ class Deparser {
|
|
|
5901
6049
|
return `${node.defname} = ${argValue}`;
|
|
5902
6050
|
}
|
|
5903
6051
|
}
|
|
6052
|
+
const argType = this.getNodeType(node.arg);
|
|
6053
|
+
if (argType === 'TypeName' || argType === 'Integer' || argType === 'Float' || argType === 'Boolean') {
|
|
6054
|
+
return `${node.defname} = ${argValue}`;
|
|
6055
|
+
}
|
|
5904
6056
|
const quotedValue = typeof argValue === 'string'
|
|
5905
|
-
?
|
|
6057
|
+
? quotes_1.QuoteUtils.escape(argValue)
|
|
5906
6058
|
: argValue;
|
|
5907
6059
|
return `${node.defname} = ${quotedValue}`;
|
|
5908
6060
|
}
|
|
@@ -5910,7 +6062,7 @@ class Deparser {
|
|
|
5910
6062
|
if (context.parentNodeTypes.includes('DefineStmt') && !node.arg) {
|
|
5911
6063
|
// Check if the original defname appears to be quoted (mixed case that's not all upper/lower)
|
|
5912
6064
|
if (node.defname !== node.defname.toLowerCase() && node.defname !== node.defname.toUpperCase()) {
|
|
5913
|
-
return
|
|
6065
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.defname);
|
|
5914
6066
|
}
|
|
5915
6067
|
}
|
|
5916
6068
|
return node.defname.toUpperCase();
|
|
@@ -5926,7 +6078,7 @@ class Deparser {
|
|
|
5926
6078
|
}
|
|
5927
6079
|
if (node.location) {
|
|
5928
6080
|
output.push('LOCATION');
|
|
5929
|
-
output.push(
|
|
6081
|
+
output.push(quotes_1.QuoteUtils.escape(node.location));
|
|
5930
6082
|
}
|
|
5931
6083
|
if (node.options && node.options.length > 0) {
|
|
5932
6084
|
output.push('WITH');
|
|
@@ -5990,6 +6142,7 @@ class Deparser {
|
|
|
5990
6142
|
if (node.extname) {
|
|
5991
6143
|
output.push(this.quoteIfNeeded(node.extname));
|
|
5992
6144
|
}
|
|
6145
|
+
output.push('UPDATE');
|
|
5993
6146
|
if (node.options && node.options.length > 0) {
|
|
5994
6147
|
const extContext = context.spawn('AlterExtensionStmt');
|
|
5995
6148
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
@@ -6094,7 +6247,7 @@ class Deparser {
|
|
|
6094
6247
|
case 'REPLICA_IDENTITY_INDEX':
|
|
6095
6248
|
output.push('USING', 'INDEX');
|
|
6096
6249
|
if (node.name) {
|
|
6097
|
-
output.push(
|
|
6250
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
6098
6251
|
}
|
|
6099
6252
|
break;
|
|
6100
6253
|
default:
|
|
@@ -6153,7 +6306,7 @@ class Deparser {
|
|
|
6153
6306
|
output.push('IF', 'EXISTS');
|
|
6154
6307
|
}
|
|
6155
6308
|
if (node.name) {
|
|
6156
|
-
output.push(
|
|
6309
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
6157
6310
|
}
|
|
6158
6311
|
if (node.behavior === 'DROP_CASCADE') {
|
|
6159
6312
|
output.push('CASCADE');
|
|
@@ -6162,7 +6315,7 @@ class Deparser {
|
|
|
6162
6315
|
case 'AT_ValidateConstraint':
|
|
6163
6316
|
output.push('VALIDATE', 'CONSTRAINT');
|
|
6164
6317
|
if (node.name) {
|
|
6165
|
-
output.push(
|
|
6318
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
6166
6319
|
}
|
|
6167
6320
|
break;
|
|
6168
6321
|
case 'C':
|
|
@@ -6179,7 +6332,7 @@ class Deparser {
|
|
|
6179
6332
|
output.push('IF', 'EXISTS');
|
|
6180
6333
|
}
|
|
6181
6334
|
if (node.name) {
|
|
6182
|
-
output.push(
|
|
6335
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
6183
6336
|
}
|
|
6184
6337
|
if (node.behavior === 'DROP_CASCADE') {
|
|
6185
6338
|
output.push('CASCADE');
|
|
@@ -6188,7 +6341,7 @@ class Deparser {
|
|
|
6188
6341
|
case 'V':
|
|
6189
6342
|
output.push('VALIDATE', 'CONSTRAINT');
|
|
6190
6343
|
if (node.name) {
|
|
6191
|
-
output.push(
|
|
6344
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
6192
6345
|
}
|
|
6193
6346
|
break;
|
|
6194
6347
|
case 'O':
|
|
@@ -6259,7 +6412,7 @@ class Deparser {
|
|
|
6259
6412
|
}
|
|
6260
6413
|
if (node.payload !== null && node.payload !== undefined) {
|
|
6261
6414
|
output.push(',');
|
|
6262
|
-
output.push(
|
|
6415
|
+
output.push(quotes_1.QuoteUtils.escape(node.payload));
|
|
6263
6416
|
}
|
|
6264
6417
|
return output.join(' ');
|
|
6265
6418
|
}
|
|
@@ -6287,7 +6440,7 @@ class Deparser {
|
|
|
6287
6440
|
if (!node.filename) {
|
|
6288
6441
|
throw new Error('LoadStmt requires filename');
|
|
6289
6442
|
}
|
|
6290
|
-
return `LOAD
|
|
6443
|
+
return `LOAD ${quotes_1.QuoteUtils.escape(node.filename)}`;
|
|
6291
6444
|
}
|
|
6292
6445
|
DiscardStmt(node, context) {
|
|
6293
6446
|
switch (node.target) {
|
|
@@ -6303,6 +6456,13 @@ class Deparser {
|
|
|
6303
6456
|
throw new Error(`Unsupported DiscardStmt target: ${node.target}`);
|
|
6304
6457
|
}
|
|
6305
6458
|
}
|
|
6459
|
+
/** `schema.op` for an operator name list: schema parts quoted, the operator symbol as is. */
|
|
6460
|
+
qualifiedOperatorName(objname) {
|
|
6461
|
+
const names = list_utils_1.ListUtils.unwrapList(objname ?? []).map((n) => (n.String ? n.String.sval : 'unknown'));
|
|
6462
|
+
if (names.length === 0)
|
|
6463
|
+
return 'unknown';
|
|
6464
|
+
return [...names.slice(0, -1).map((n) => quotes_1.QuoteUtils.quoteIdentifier(n)), names[names.length - 1]].join('.');
|
|
6465
|
+
}
|
|
6306
6466
|
CommentStmt(node, context) {
|
|
6307
6467
|
const output = ['COMMENT ON'];
|
|
6308
6468
|
if (node.objtype) {
|
|
@@ -6334,6 +6494,9 @@ class Deparser {
|
|
|
6334
6494
|
case 'OBJECT_TABCONSTRAINT':
|
|
6335
6495
|
output.push('CONSTRAINT');
|
|
6336
6496
|
break;
|
|
6497
|
+
case 'OBJECT_DOMCONSTRAINT':
|
|
6498
|
+
output.push('CONSTRAINT');
|
|
6499
|
+
break;
|
|
6337
6500
|
case 'OBJECT_TRIGGER':
|
|
6338
6501
|
output.push('TRIGGER');
|
|
6339
6502
|
break;
|
|
@@ -6410,23 +6573,30 @@ class Deparser {
|
|
|
6410
6573
|
output.push(objectParts.join('.'));
|
|
6411
6574
|
}
|
|
6412
6575
|
}
|
|
6413
|
-
else if (node.objtype === '
|
|
6576
|
+
else if (node.objtype === 'OBJECT_DOMCONSTRAINT') {
|
|
6414
6577
|
if (objectParts.length === 2) {
|
|
6415
|
-
const [
|
|
6416
|
-
output.push(
|
|
6578
|
+
const [domain, constraint] = objectParts;
|
|
6579
|
+
output.push(constraint, 'ON DOMAIN', domain);
|
|
6580
|
+
}
|
|
6581
|
+
else {
|
|
6582
|
+
output.push(objectParts.join('.'));
|
|
6583
|
+
}
|
|
6584
|
+
}
|
|
6585
|
+
else if (node.objtype === 'OBJECT_TRIGGER') {
|
|
6586
|
+
if (objectParts.length >= 2) {
|
|
6587
|
+
output.push(objectParts[objectParts.length - 1]);
|
|
6417
6588
|
output.push('ON');
|
|
6418
|
-
output.push(
|
|
6589
|
+
output.push(objectParts.slice(0, -1).join('.'));
|
|
6419
6590
|
}
|
|
6420
6591
|
else {
|
|
6421
6592
|
output.push(objectParts.join('.'));
|
|
6422
6593
|
}
|
|
6423
6594
|
}
|
|
6424
6595
|
else if (node.objtype === 'OBJECT_RULE') {
|
|
6425
|
-
if (objectParts.length
|
|
6426
|
-
|
|
6427
|
-
output.push(rule);
|
|
6596
|
+
if (objectParts.length >= 2) {
|
|
6597
|
+
output.push(objectParts[objectParts.length - 1]);
|
|
6428
6598
|
output.push('ON');
|
|
6429
|
-
output.push(
|
|
6599
|
+
output.push(objectParts.slice(0, -1).join('.'));
|
|
6430
6600
|
}
|
|
6431
6601
|
else {
|
|
6432
6602
|
output.push(objectParts.join('.'));
|
|
@@ -6437,8 +6607,7 @@ class Deparser {
|
|
|
6437
6607
|
// For operators, we need to handle ObjectWithArgs structure
|
|
6438
6608
|
if (node.object && node.object.ObjectWithArgs) {
|
|
6439
6609
|
const objWithArgs = node.object.ObjectWithArgs;
|
|
6440
|
-
let operatorName =
|
|
6441
|
-
? objWithArgs.objname[0].String.sval : 'unknown';
|
|
6610
|
+
let operatorName = this.qualifiedOperatorName(objWithArgs.objname);
|
|
6442
6611
|
if (operatorName.startsWith('"') && operatorName.endsWith('"')) {
|
|
6443
6612
|
operatorName = operatorName.slice(1, -1);
|
|
6444
6613
|
}
|
|
@@ -6476,7 +6645,13 @@ class Deparser {
|
|
|
6476
6645
|
}
|
|
6477
6646
|
else if (node.objtype === 'OBJECT_POLICY') {
|
|
6478
6647
|
// Handle POLICY syntax: COMMENT ON POLICY policy_name ON table_name IS 'comment'
|
|
6479
|
-
if (objectParts.length ===
|
|
6648
|
+
if (objectParts.length === 3) {
|
|
6649
|
+
const [schema, table, policy] = objectParts;
|
|
6650
|
+
output.push(policy);
|
|
6651
|
+
output.push('ON');
|
|
6652
|
+
output.push(`${schema}.${table}`);
|
|
6653
|
+
}
|
|
6654
|
+
else if (objectParts.length === 2) {
|
|
6480
6655
|
const [table, policy] = objectParts;
|
|
6481
6656
|
output.push(policy);
|
|
6482
6657
|
output.push('ON');
|
|
@@ -6499,6 +6674,9 @@ class Deparser {
|
|
|
6499
6674
|
output.push(objectParts.join('.'));
|
|
6500
6675
|
}
|
|
6501
6676
|
}
|
|
6677
|
+
else if (node.objtype === 'OBJECT_CAST' && objectParts.length === 2) {
|
|
6678
|
+
output.push(`(${objectParts[0]} AS ${objectParts[1]})`);
|
|
6679
|
+
}
|
|
6502
6680
|
else {
|
|
6503
6681
|
output.push(objectParts.join('.'));
|
|
6504
6682
|
}
|
|
@@ -6507,8 +6685,7 @@ class Deparser {
|
|
|
6507
6685
|
else if (node.objtype === 'OBJECT_OPERATOR' && node.object && node.object.ObjectWithArgs) {
|
|
6508
6686
|
// Handle direct ObjectWithArgs for OPERATOR syntax: COMMENT ON OPERATOR -(NONE, integer) IS 'comment'
|
|
6509
6687
|
const objWithArgs = node.object.ObjectWithArgs;
|
|
6510
|
-
let operatorName =
|
|
6511
|
-
? objWithArgs.objname[0].String.sval : 'unknown';
|
|
6688
|
+
let operatorName = this.qualifiedOperatorName(objWithArgs.objname);
|
|
6512
6689
|
// Remove quotes from operator name if present
|
|
6513
6690
|
if (operatorName.startsWith('"') && operatorName.endsWith('"')) {
|
|
6514
6691
|
operatorName = operatorName.slice(1, -1);
|
|
@@ -6540,7 +6717,7 @@ class Deparser {
|
|
|
6540
6717
|
output.push('NULL');
|
|
6541
6718
|
}
|
|
6542
6719
|
else if (node.comment) {
|
|
6543
|
-
output.push(
|
|
6720
|
+
output.push(quotes_1.QuoteUtils.formatEString(node.comment));
|
|
6544
6721
|
}
|
|
6545
6722
|
return output.join(' ');
|
|
6546
6723
|
}
|
|
@@ -6577,7 +6754,7 @@ class Deparser {
|
|
|
6577
6754
|
const output = [];
|
|
6578
6755
|
const initialParts = ['CREATE', 'POLICY'];
|
|
6579
6756
|
if (node.policy_name) {
|
|
6580
|
-
initialParts.push(
|
|
6757
|
+
initialParts.push(quotes_1.QuoteUtils.quoteIdentifier(node.policy_name));
|
|
6581
6758
|
}
|
|
6582
6759
|
output.push(initialParts.join(' '));
|
|
6583
6760
|
// Add ON clause on new line in pretty mode
|
|
@@ -6654,7 +6831,7 @@ class Deparser {
|
|
|
6654
6831
|
AlterPolicyStmt(node, context) {
|
|
6655
6832
|
const output = ['ALTER', 'POLICY'];
|
|
6656
6833
|
if (node.policy_name) {
|
|
6657
|
-
output.push(
|
|
6834
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.policy_name));
|
|
6658
6835
|
}
|
|
6659
6836
|
if (node.table) {
|
|
6660
6837
|
output.push('ON');
|
|
@@ -6690,7 +6867,7 @@ class Deparser {
|
|
|
6690
6867
|
}
|
|
6691
6868
|
output.push('SERVER');
|
|
6692
6869
|
if (node.servername) {
|
|
6693
|
-
output.push(
|
|
6870
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.servername));
|
|
6694
6871
|
}
|
|
6695
6872
|
if (node.options && node.options.length > 0) {
|
|
6696
6873
|
output.push('OPTIONS');
|
|
@@ -6738,10 +6915,10 @@ class Deparser {
|
|
|
6738
6915
|
CreatePublicationStmt(node, context) {
|
|
6739
6916
|
const output = ['CREATE', 'PUBLICATION'];
|
|
6740
6917
|
if (node.pubname) {
|
|
6741
|
-
output.push(
|
|
6918
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.pubname));
|
|
6742
6919
|
}
|
|
6743
6920
|
if (node.pubobjects && node.pubobjects.length > 0) {
|
|
6744
|
-
output.push('FOR'
|
|
6921
|
+
output.push('FOR');
|
|
6745
6922
|
const tables = list_utils_1.ListUtils.unwrapList(node.pubobjects).map(table => this.visit(table, context));
|
|
6746
6923
|
output.push(tables.join(', '));
|
|
6747
6924
|
}
|
|
@@ -6758,11 +6935,11 @@ class Deparser {
|
|
|
6758
6935
|
CreateSubscriptionStmt(node, context) {
|
|
6759
6936
|
const output = ['CREATE', 'SUBSCRIPTION'];
|
|
6760
6937
|
if (node.subname) {
|
|
6761
|
-
output.push(
|
|
6938
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.subname));
|
|
6762
6939
|
}
|
|
6763
6940
|
output.push('CONNECTION');
|
|
6764
6941
|
if (node.conninfo) {
|
|
6765
|
-
output.push(
|
|
6942
|
+
output.push(quotes_1.QuoteUtils.escape(node.conninfo));
|
|
6766
6943
|
}
|
|
6767
6944
|
output.push('PUBLICATION');
|
|
6768
6945
|
if (node.publication && node.publication.length > 0) {
|
|
@@ -6779,10 +6956,11 @@ class Deparser {
|
|
|
6779
6956
|
AlterPublicationStmt(node, context) {
|
|
6780
6957
|
const output = ['ALTER', 'PUBLICATION'];
|
|
6781
6958
|
if (node.pubname) {
|
|
6782
|
-
output.push(
|
|
6959
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.pubname));
|
|
6783
6960
|
}
|
|
6784
|
-
|
|
6785
|
-
|
|
6961
|
+
const hasObjects = node.pubobjects && node.pubobjects.length > 0;
|
|
6962
|
+
if (hasObjects) {
|
|
6963
|
+
switch (node.action || 'AP_AddObjects') {
|
|
6786
6964
|
case 'AP_AddObjects':
|
|
6787
6965
|
output.push('ADD');
|
|
6788
6966
|
break;
|
|
@@ -6795,17 +6973,11 @@ class Deparser {
|
|
|
6795
6973
|
default:
|
|
6796
6974
|
throw new Error(`Unsupported AlterPublicationStmt action: ${node.action}`);
|
|
6797
6975
|
}
|
|
6798
|
-
}
|
|
6799
|
-
if (node.for_all_tables) {
|
|
6800
|
-
output.push('FOR ALL TABLES');
|
|
6801
|
-
}
|
|
6802
|
-
else if (node.pubobjects && node.pubobjects.length > 0) {
|
|
6803
|
-
output.push('FOR TABLE');
|
|
6804
6976
|
const objects = list_utils_1.ListUtils.unwrapList(node.pubobjects).map(obj => this.visit(obj, context));
|
|
6805
6977
|
output.push(objects.join(', '));
|
|
6806
6978
|
}
|
|
6807
|
-
if (node.options && node.options.length > 0) {
|
|
6808
|
-
output.push('
|
|
6979
|
+
else if (node.options && node.options.length > 0) {
|
|
6980
|
+
output.push('SET');
|
|
6809
6981
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context));
|
|
6810
6982
|
output.push(`(${options.join(', ')})`);
|
|
6811
6983
|
}
|
|
@@ -6814,44 +6986,69 @@ class Deparser {
|
|
|
6814
6986
|
AlterSubscriptionStmt(node, context) {
|
|
6815
6987
|
const output = ['ALTER', 'SUBSCRIPTION'];
|
|
6816
6988
|
if (node.subname) {
|
|
6817
|
-
output.push(
|
|
6818
|
-
}
|
|
6819
|
-
|
|
6820
|
-
|
|
6989
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.subname));
|
|
6990
|
+
}
|
|
6991
|
+
const options = node.options && node.options.length > 0
|
|
6992
|
+
? `(${list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context)).join(', ')})`
|
|
6993
|
+
: null;
|
|
6994
|
+
const publications = node.publication && node.publication.length > 0
|
|
6995
|
+
? list_utils_1.ListUtils.unwrapList(node.publication).map(pub => this.visit(pub, context)).join(', ')
|
|
6996
|
+
: null;
|
|
6997
|
+
{
|
|
6998
|
+
switch (node.kind || 'ALTER_SUBSCRIPTION_OPTIONS') {
|
|
6821
6999
|
case 'ALTER_SUBSCRIPTION_OPTIONS':
|
|
6822
7000
|
output.push('SET');
|
|
7001
|
+
if (options)
|
|
7002
|
+
output.push(options);
|
|
6823
7003
|
break;
|
|
6824
7004
|
case 'ALTER_SUBSCRIPTION_CONNECTION':
|
|
6825
7005
|
output.push('CONNECTION');
|
|
6826
7006
|
if (node.conninfo) {
|
|
6827
|
-
output.push(
|
|
7007
|
+
output.push(quotes_1.QuoteUtils.escape(node.conninfo));
|
|
6828
7008
|
}
|
|
6829
7009
|
break;
|
|
6830
7010
|
case 'ALTER_SUBSCRIPTION_SET_PUBLICATION':
|
|
6831
7011
|
output.push('SET PUBLICATION');
|
|
6832
|
-
if (
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
7012
|
+
if (publications)
|
|
7013
|
+
output.push(publications);
|
|
7014
|
+
if (options)
|
|
7015
|
+
output.push('WITH', options);
|
|
7016
|
+
break;
|
|
7017
|
+
case 'ALTER_SUBSCRIPTION_ADD_PUBLICATION':
|
|
7018
|
+
output.push('ADD PUBLICATION');
|
|
7019
|
+
if (publications)
|
|
7020
|
+
output.push(publications);
|
|
7021
|
+
if (options)
|
|
7022
|
+
output.push('WITH', options);
|
|
7023
|
+
break;
|
|
7024
|
+
case 'ALTER_SUBSCRIPTION_DROP_PUBLICATION':
|
|
7025
|
+
output.push('DROP PUBLICATION');
|
|
7026
|
+
if (publications)
|
|
7027
|
+
output.push(publications);
|
|
7028
|
+
if (options)
|
|
7029
|
+
output.push('WITH', options);
|
|
6836
7030
|
break;
|
|
6837
7031
|
case 'ALTER_SUBSCRIPTION_REFRESH':
|
|
6838
7032
|
output.push('REFRESH PUBLICATION');
|
|
7033
|
+
if (options)
|
|
7034
|
+
output.push('WITH', options);
|
|
6839
7035
|
break;
|
|
6840
|
-
case 'ALTER_SUBSCRIPTION_ENABLED':
|
|
6841
|
-
|
|
7036
|
+
case 'ALTER_SUBSCRIPTION_ENABLED': {
|
|
7037
|
+
const enabled = list_utils_1.ListUtils.unwrapList(node.options).find(opt => opt.DefElem?.defname === 'enabled');
|
|
7038
|
+
const arg = enabled?.DefElem?.arg;
|
|
7039
|
+
const isEnabled = arg?.Boolean ? arg.Boolean.boolval !== false : true;
|
|
7040
|
+
output.push(isEnabled ? 'ENABLE' : 'DISABLE');
|
|
6842
7041
|
break;
|
|
7042
|
+
}
|
|
6843
7043
|
case 'ALTER_SUBSCRIPTION_SKIP':
|
|
6844
7044
|
output.push('SKIP');
|
|
7045
|
+
if (options)
|
|
7046
|
+
output.push(options);
|
|
6845
7047
|
break;
|
|
6846
7048
|
default:
|
|
6847
7049
|
throw new Error(`Unsupported AlterSubscriptionStmt kind: ${node.kind}`);
|
|
6848
7050
|
}
|
|
6849
7051
|
}
|
|
6850
|
-
if (node.options && node.options.length > 0) {
|
|
6851
|
-
output.push('WITH');
|
|
6852
|
-
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context));
|
|
6853
|
-
output.push(`(${options.join(', ')})`);
|
|
6854
|
-
}
|
|
6855
7052
|
return output.join(' ');
|
|
6856
7053
|
}
|
|
6857
7054
|
DropSubscriptionStmt(node, context) {
|
|
@@ -6860,7 +7057,7 @@ class Deparser {
|
|
|
6860
7057
|
output.push('IF EXISTS');
|
|
6861
7058
|
}
|
|
6862
7059
|
if (node.subname) {
|
|
6863
|
-
output.push(
|
|
7060
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.subname));
|
|
6864
7061
|
}
|
|
6865
7062
|
if (node.behavior) {
|
|
6866
7063
|
switch (node.behavior) {
|
|
@@ -7105,7 +7302,7 @@ class Deparser {
|
|
|
7105
7302
|
ClosePortalStmt(node, context) {
|
|
7106
7303
|
const output = ['CLOSE'];
|
|
7107
7304
|
if (node.portalname) {
|
|
7108
|
-
output.push(
|
|
7305
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.portalname));
|
|
7109
7306
|
}
|
|
7110
7307
|
else {
|
|
7111
7308
|
output.push('ALL');
|
|
@@ -7163,7 +7360,7 @@ class Deparser {
|
|
|
7163
7360
|
output.push('ALL');
|
|
7164
7361
|
}
|
|
7165
7362
|
if (node.portalname) {
|
|
7166
|
-
output.push(
|
|
7363
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.portalname));
|
|
7167
7364
|
}
|
|
7168
7365
|
return output.join(' ');
|
|
7169
7366
|
}
|
|
@@ -7233,7 +7430,7 @@ class Deparser {
|
|
|
7233
7430
|
AlterFdwStmt(node, context) {
|
|
7234
7431
|
const output = ['ALTER', 'FOREIGN', 'DATA', 'WRAPPER'];
|
|
7235
7432
|
if (node.fdwname) {
|
|
7236
|
-
output.push(
|
|
7433
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.fdwname));
|
|
7237
7434
|
}
|
|
7238
7435
|
if (node.func_options && node.func_options.length > 0) {
|
|
7239
7436
|
const fdwContext = context.spawn('AlterFdwStmt');
|
|
@@ -7254,16 +7451,16 @@ class Deparser {
|
|
|
7254
7451
|
output.push('IF', 'NOT', 'EXISTS');
|
|
7255
7452
|
}
|
|
7256
7453
|
if (node.servername) {
|
|
7257
|
-
output.push(
|
|
7454
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.servername));
|
|
7258
7455
|
}
|
|
7259
7456
|
if (node.servertype) {
|
|
7260
|
-
output.push('TYPE',
|
|
7457
|
+
output.push('TYPE', quotes_1.QuoteUtils.escape(node.servertype));
|
|
7261
7458
|
}
|
|
7262
7459
|
if (node.version) {
|
|
7263
|
-
output.push('VERSION',
|
|
7460
|
+
output.push('VERSION', quotes_1.QuoteUtils.escape(node.version));
|
|
7264
7461
|
}
|
|
7265
7462
|
if (node.fdwname) {
|
|
7266
|
-
output.push('FOREIGN', 'DATA', 'WRAPPER',
|
|
7463
|
+
output.push('FOREIGN', 'DATA', 'WRAPPER', quotes_1.QuoteUtils.quoteIdentifier(node.fdwname));
|
|
7267
7464
|
}
|
|
7268
7465
|
if (node.options && node.options.length > 0) {
|
|
7269
7466
|
output.push('OPTIONS');
|
|
@@ -7278,10 +7475,10 @@ class Deparser {
|
|
|
7278
7475
|
AlterForeignServerStmt(node, context) {
|
|
7279
7476
|
const output = ['ALTER', 'SERVER'];
|
|
7280
7477
|
if (node.servername) {
|
|
7281
|
-
output.push(
|
|
7478
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.servername));
|
|
7282
7479
|
}
|
|
7283
7480
|
if (node.version) {
|
|
7284
|
-
output.push('VERSION',
|
|
7481
|
+
output.push('VERSION', quotes_1.QuoteUtils.escape(node.version));
|
|
7285
7482
|
}
|
|
7286
7483
|
if (node.options && node.options.length > 0) {
|
|
7287
7484
|
output.push('OPTIONS');
|
|
@@ -7303,7 +7500,7 @@ class Deparser {
|
|
|
7303
7500
|
}
|
|
7304
7501
|
output.push('SERVER');
|
|
7305
7502
|
if (node.servername) {
|
|
7306
|
-
output.push(
|
|
7503
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.servername));
|
|
7307
7504
|
}
|
|
7308
7505
|
if (node.options && node.options.length > 0) {
|
|
7309
7506
|
output.push('OPTIONS');
|
|
@@ -7327,14 +7524,14 @@ class Deparser {
|
|
|
7327
7524
|
}
|
|
7328
7525
|
output.push('SERVER');
|
|
7329
7526
|
if (node.servername) {
|
|
7330
|
-
output.push(
|
|
7527
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.servername));
|
|
7331
7528
|
}
|
|
7332
7529
|
return output.join(' ');
|
|
7333
7530
|
}
|
|
7334
7531
|
ImportForeignSchemaStmt(node, context) {
|
|
7335
7532
|
const output = ['IMPORT', 'FOREIGN', 'SCHEMA'];
|
|
7336
7533
|
if (node.remote_schema) {
|
|
7337
|
-
output.push(
|
|
7534
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.remote_schema));
|
|
7338
7535
|
}
|
|
7339
7536
|
if (node.list_type) {
|
|
7340
7537
|
switch (node.list_type) {
|
|
@@ -7360,11 +7557,11 @@ class Deparser {
|
|
|
7360
7557
|
}
|
|
7361
7558
|
output.push('FROM', 'SERVER');
|
|
7362
7559
|
if (node.server_name) {
|
|
7363
|
-
output.push(
|
|
7560
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.server_name));
|
|
7364
7561
|
}
|
|
7365
7562
|
output.push('INTO');
|
|
7366
7563
|
if (node.local_schema) {
|
|
7367
|
-
output.push(
|
|
7564
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.local_schema));
|
|
7368
7565
|
}
|
|
7369
7566
|
if (node.options && node.options.length > 0) {
|
|
7370
7567
|
const importSchemaContext = context.spawn('ImportForeignSchemaStmt');
|
|
@@ -7378,7 +7575,7 @@ class Deparser {
|
|
|
7378
7575
|
if (node.relation) {
|
|
7379
7576
|
output.push(this.RangeVar(node.relation, context));
|
|
7380
7577
|
if (node.indexname) {
|
|
7381
|
-
output.push('USING',
|
|
7578
|
+
output.push('USING', quotes_1.QuoteUtils.quoteIdentifier(node.indexname));
|
|
7382
7579
|
}
|
|
7383
7580
|
}
|
|
7384
7581
|
if (node.params && node.params.length > 0) {
|
|
@@ -7442,7 +7639,7 @@ class Deparser {
|
|
|
7442
7639
|
output.push(this.RangeVar(node.relation, context));
|
|
7443
7640
|
}
|
|
7444
7641
|
if (node.name) {
|
|
7445
|
-
output.push(
|
|
7642
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
7446
7643
|
}
|
|
7447
7644
|
return output.join(' ');
|
|
7448
7645
|
}
|
|
@@ -7482,7 +7679,7 @@ class Deparser {
|
|
|
7482
7679
|
if (!node.dbname) {
|
|
7483
7680
|
throw new Error('CreatedbStmt requires dbname');
|
|
7484
7681
|
}
|
|
7485
|
-
output.push(
|
|
7682
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.dbname));
|
|
7486
7683
|
if (node.options && node.options.length > 0) {
|
|
7487
7684
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
7488
7685
|
.map(option => this.visit(option, context))
|
|
@@ -7499,7 +7696,7 @@ class Deparser {
|
|
|
7499
7696
|
if (!node.dbname) {
|
|
7500
7697
|
throw new Error('DropdbStmt requires dbname');
|
|
7501
7698
|
}
|
|
7502
|
-
output.push(
|
|
7699
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.dbname));
|
|
7503
7700
|
if (node.options && node.options.length > 0) {
|
|
7504
7701
|
const options = list_utils_1.ListUtils.unwrapList(node.options)
|
|
7505
7702
|
.map(option => this.visit(option, context))
|
|
@@ -7597,7 +7794,7 @@ class Deparser {
|
|
|
7597
7794
|
case 'OBJECT_POLICY':
|
|
7598
7795
|
output.push('POLICY');
|
|
7599
7796
|
if (node.subname) {
|
|
7600
|
-
output.push(
|
|
7797
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.subname));
|
|
7601
7798
|
}
|
|
7602
7799
|
break;
|
|
7603
7800
|
case 'OBJECT_PUBLICATION':
|
|
@@ -7655,7 +7852,7 @@ class Deparser {
|
|
|
7655
7852
|
}
|
|
7656
7853
|
// Handle OBJECT_RULE special case: rule_name ON table_name format
|
|
7657
7854
|
if (node.renameType === 'OBJECT_RULE' && node.subname && node.relation) {
|
|
7658
|
-
output.push(
|
|
7855
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.subname));
|
|
7659
7856
|
output.push('ON');
|
|
7660
7857
|
output.push(this.RangeVar(node.relation, context));
|
|
7661
7858
|
}
|
|
@@ -7674,12 +7871,21 @@ class Deparser {
|
|
|
7674
7871
|
if (items.length === 2) {
|
|
7675
7872
|
const accessMethod = items[0].String?.sval || '';
|
|
7676
7873
|
const objectName = items[1].String?.sval || '';
|
|
7677
|
-
output.push(`${
|
|
7874
|
+
output.push(`${quotes_1.QuoteUtils.quoteIdentifier(objectName)} USING ${accessMethod}`);
|
|
7678
7875
|
}
|
|
7679
7876
|
else {
|
|
7680
7877
|
output.push(this.visit(node.object, context));
|
|
7681
7878
|
}
|
|
7682
7879
|
}
|
|
7880
|
+
else if ((node.renameType === 'OBJECT_TYPE' || node.renameType === 'OBJECT_DOMAIN') && node.object.List) {
|
|
7881
|
+
// Qualified type names - join List parts with dots
|
|
7882
|
+
const items = list_utils_1.ListUtils.unwrapList(node.object);
|
|
7883
|
+
const parts = items
|
|
7884
|
+
.map((item) => item.String?.sval)
|
|
7885
|
+
.filter((s) => typeof s === 'string')
|
|
7886
|
+
.map((s) => this.quoteIfNeeded(s));
|
|
7887
|
+
output.push(parts.join('.'));
|
|
7888
|
+
}
|
|
7683
7889
|
else if (node.renameType === 'OBJECT_SCHEMA' && node.object.List) {
|
|
7684
7890
|
// Handle schema names - extract from List structure
|
|
7685
7891
|
const items = list_utils_1.ListUtils.unwrapList(node.object);
|
|
@@ -7695,19 +7901,19 @@ class Deparser {
|
|
|
7695
7901
|
}
|
|
7696
7902
|
}
|
|
7697
7903
|
if (node.renameType === 'OBJECT_COLUMN' && node.subname) {
|
|
7698
|
-
output.push('RENAME COLUMN',
|
|
7904
|
+
output.push('RENAME COLUMN', quotes_1.QuoteUtils.quoteIdentifier(node.subname), 'TO');
|
|
7699
7905
|
}
|
|
7700
7906
|
else if (node.renameType === 'OBJECT_DOMCONSTRAINT' && node.subname) {
|
|
7701
|
-
output.push('RENAME CONSTRAINT',
|
|
7907
|
+
output.push('RENAME CONSTRAINT', quotes_1.QuoteUtils.quoteIdentifier(node.subname), 'TO');
|
|
7702
7908
|
}
|
|
7703
7909
|
else if (node.renameType === 'OBJECT_TABCONSTRAINT' && node.subname) {
|
|
7704
|
-
output.push('RENAME CONSTRAINT',
|
|
7910
|
+
output.push('RENAME CONSTRAINT', quotes_1.QuoteUtils.quoteIdentifier(node.subname), 'TO');
|
|
7705
7911
|
}
|
|
7706
7912
|
else if (node.renameType === 'OBJECT_ATTRIBUTE' && node.subname) {
|
|
7707
|
-
output.push('RENAME ATTRIBUTE',
|
|
7913
|
+
output.push('RENAME ATTRIBUTE', quotes_1.QuoteUtils.quoteIdentifier(node.subname), 'TO');
|
|
7708
7914
|
}
|
|
7709
7915
|
else if (node.renameType === 'OBJECT_ROLE' && node.subname) {
|
|
7710
|
-
output.push(
|
|
7916
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.subname), 'RENAME TO');
|
|
7711
7917
|
}
|
|
7712
7918
|
else if (node.renameType === 'OBJECT_SCHEMA' && node.subname) {
|
|
7713
7919
|
output.push(this.quoteIfNeeded(node.subname), 'RENAME TO');
|
|
@@ -7721,7 +7927,7 @@ class Deparser {
|
|
|
7721
7927
|
if (!node.newname) {
|
|
7722
7928
|
throw new Error('RenameStmt requires newname');
|
|
7723
7929
|
}
|
|
7724
|
-
output.push(
|
|
7930
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.newname));
|
|
7725
7931
|
// Handle CASCADE/RESTRICT behavior for RENAME operations
|
|
7726
7932
|
if (node.behavior === 'DROP_CASCADE') {
|
|
7727
7933
|
output.push('CASCADE');
|
|
@@ -7744,7 +7950,7 @@ class Deparser {
|
|
|
7744
7950
|
if (items.length === 2) {
|
|
7745
7951
|
const accessMethod = items[0].String?.sval || '';
|
|
7746
7952
|
const objectName = items[1].String?.sval || '';
|
|
7747
|
-
output.push(`${
|
|
7953
|
+
output.push(`${quotes_1.QuoteUtils.quoteIdentifier(objectName)} USING ${accessMethod}`);
|
|
7748
7954
|
}
|
|
7749
7955
|
else {
|
|
7750
7956
|
output.push(this.visit(node.object, context));
|
|
@@ -7819,6 +8025,9 @@ class Deparser {
|
|
|
7819
8025
|
else if (node.objtype === 'OBJECT_LANGUAGE') {
|
|
7820
8026
|
output.push('LANGUAGE');
|
|
7821
8027
|
}
|
|
8028
|
+
else if (node.objtype === 'OBJECT_SEQUENCE') {
|
|
8029
|
+
output.push('SEQUENCE');
|
|
8030
|
+
}
|
|
7822
8031
|
else if (node.objtype === 'OBJECT_FUNCTION') {
|
|
7823
8032
|
output.push('FUNCTION');
|
|
7824
8033
|
}
|
|
@@ -7844,8 +8053,11 @@ class Deparser {
|
|
|
7844
8053
|
output.push('DATABASE');
|
|
7845
8054
|
}
|
|
7846
8055
|
if (node.objects && node.objects.length > 0) {
|
|
8056
|
+
const qualifiedKinds = ['OBJECT_TYPE', 'OBJECT_DOMAIN'];
|
|
7847
8057
|
const objects = list_utils_1.ListUtils.unwrapList(node.objects)
|
|
7848
|
-
.map(obj =>
|
|
8058
|
+
.map(obj => qualifiedKinds.includes(node.objtype) && obj.List
|
|
8059
|
+
? list_utils_1.ListUtils.unwrapList(obj.List.items).map((item) => this.visit(item, context)).join('.')
|
|
8060
|
+
: this.visit(obj, context))
|
|
7849
8061
|
.join(', ');
|
|
7850
8062
|
output.push(objects);
|
|
7851
8063
|
}
|
|
@@ -7884,8 +8096,11 @@ class Deparser {
|
|
|
7884
8096
|
break;
|
|
7885
8097
|
default:
|
|
7886
8098
|
if (node.objects && node.objects.length > 0) {
|
|
8099
|
+
const qualifiedKinds = ['OBJECT_TYPE', 'OBJECT_DOMAIN'];
|
|
7887
8100
|
const objects = list_utils_1.ListUtils.unwrapList(node.objects)
|
|
7888
|
-
.map(obj =>
|
|
8101
|
+
.map(obj => qualifiedKinds.includes(node.objtype) && obj.List
|
|
8102
|
+
? list_utils_1.ListUtils.unwrapList(obj.List.items).map((item) => this.visit(item, context)).join('.')
|
|
8103
|
+
: this.visit(obj, context))
|
|
7889
8104
|
.join(', ');
|
|
7890
8105
|
output.push(objects);
|
|
7891
8106
|
}
|
|
@@ -7905,6 +8120,9 @@ class Deparser {
|
|
|
7905
8120
|
if (node.grant_option && node.is_grant) {
|
|
7906
8121
|
output.push('WITH GRANT OPTION');
|
|
7907
8122
|
}
|
|
8123
|
+
if (node.grantor) {
|
|
8124
|
+
output.push('GRANTED BY', this.RoleSpec(node.grantor, context));
|
|
8125
|
+
}
|
|
7908
8126
|
// Only add behavior clauses for REVOKE statements, not for GRANT statements in ALTER DEFAULT PRIVILEGES
|
|
7909
8127
|
if (!node.is_grant) {
|
|
7910
8128
|
if (node.behavior === 'DROP_CASCADE') {
|
|
@@ -7918,57 +8136,34 @@ class Deparser {
|
|
|
7918
8136
|
}
|
|
7919
8137
|
GrantRoleStmt(node, context) {
|
|
7920
8138
|
const output = [];
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
if (adminOption.DefElem && adminOption.DefElem.arg) {
|
|
7941
|
-
adminValue = adminOption.DefElem.arg.Boolean?.boolval;
|
|
7942
|
-
}
|
|
7943
|
-
}
|
|
7944
|
-
if (setOption && setOption.DefElem) {
|
|
7945
|
-
hasSetOption = true;
|
|
7946
|
-
setValue = setOption.DefElem.arg?.Boolean?.boolval;
|
|
7947
|
-
}
|
|
7948
|
-
}
|
|
8139
|
+
const options = list_utils_1.ListUtils.unwrapList(node.opt)
|
|
8140
|
+
.map(opt => opt.DefElem)
|
|
8141
|
+
.filter((opt) => !!opt && !!opt.defname);
|
|
8142
|
+
const optionValue = (opt) => {
|
|
8143
|
+
if (!opt.arg)
|
|
8144
|
+
return true;
|
|
8145
|
+
const argType = this.getNodeType(opt.arg);
|
|
8146
|
+
const argData = this.getNodeData(opt.arg);
|
|
8147
|
+
if (argType === 'Boolean')
|
|
8148
|
+
return argData.boolval !== false;
|
|
8149
|
+
if (argType === 'String')
|
|
8150
|
+
return argData.sval !== 'false';
|
|
8151
|
+
return true;
|
|
8152
|
+
};
|
|
8153
|
+
const roles = list_utils_1.ListUtils.unwrapList(node.granted_roles)
|
|
8154
|
+
.map(role => role.AccessPriv?.priv_name
|
|
8155
|
+
? quotes_1.QuoteUtils.quoteIdentifier(role.AccessPriv.priv_name)
|
|
8156
|
+
: this.visit(role, context))
|
|
8157
|
+
.join(', ');
|
|
7949
8158
|
if (node.is_grant) {
|
|
7950
|
-
output.push('GRANT');
|
|
8159
|
+
output.push('GRANT', roles, 'TO');
|
|
7951
8160
|
}
|
|
7952
8161
|
else {
|
|
7953
8162
|
output.push('REVOKE');
|
|
7954
|
-
if (
|
|
7955
|
-
output.push(
|
|
7956
|
-
}
|
|
7957
|
-
else if (hasAdminOption) {
|
|
7958
|
-
output.push('ADMIN OPTION FOR');
|
|
8163
|
+
if (options.length > 0) {
|
|
8164
|
+
output.push(`${options[0].defname.toUpperCase()} OPTION FOR`);
|
|
7959
8165
|
}
|
|
7960
|
-
|
|
7961
|
-
if (node.granted_roles && node.granted_roles.length > 0) {
|
|
7962
|
-
const roles = list_utils_1.ListUtils.unwrapList(node.granted_roles)
|
|
7963
|
-
.map(role => this.visit(role, context))
|
|
7964
|
-
.join(', ');
|
|
7965
|
-
output.push(roles);
|
|
7966
|
-
}
|
|
7967
|
-
if (node.is_grant) {
|
|
7968
|
-
output.push('TO');
|
|
7969
|
-
}
|
|
7970
|
-
else {
|
|
7971
|
-
output.push('FROM');
|
|
8166
|
+
output.push(roles, 'FROM');
|
|
7972
8167
|
}
|
|
7973
8168
|
if (node.grantee_roles && node.grantee_roles.length > 0) {
|
|
7974
8169
|
const grantees = list_utils_1.ListUtils.unwrapList(node.grantee_roles)
|
|
@@ -7976,45 +8171,22 @@ class Deparser {
|
|
|
7976
8171
|
.join(', ');
|
|
7977
8172
|
output.push(grantees);
|
|
7978
8173
|
}
|
|
7979
|
-
if (node.is_grant) {
|
|
7980
|
-
const withOptions =
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7986
|
-
|
|
7987
|
-
|
|
7988
|
-
else {
|
|
7989
|
-
withOptions.push('ADMIN OPTION');
|
|
7990
|
-
}
|
|
7991
|
-
}
|
|
7992
|
-
if (hasInheritOption) {
|
|
7993
|
-
if (inheritValue === true) {
|
|
7994
|
-
withOptions.push('INHERIT OPTION');
|
|
7995
|
-
}
|
|
7996
|
-
else if (inheritValue === false) {
|
|
7997
|
-
withOptions.push('INHERIT FALSE');
|
|
7998
|
-
}
|
|
7999
|
-
}
|
|
8000
|
-
if (hasSetOption) {
|
|
8001
|
-
if (setValue === true) {
|
|
8002
|
-
withOptions.push('SET TRUE');
|
|
8003
|
-
}
|
|
8004
|
-
else if (setValue === false) {
|
|
8005
|
-
withOptions.push('SET FALSE');
|
|
8006
|
-
}
|
|
8007
|
-
}
|
|
8008
|
-
if (withOptions.length > 0) {
|
|
8009
|
-
output.push('WITH', withOptions.join(', '));
|
|
8010
|
-
}
|
|
8174
|
+
if (node.is_grant && options.length > 0) {
|
|
8175
|
+
const withOptions = options.map(opt => `${opt.defname.toUpperCase()} ${optionValue(opt) ? 'TRUE' : 'FALSE'}`);
|
|
8176
|
+
output.push('WITH', withOptions.join(', '));
|
|
8177
|
+
}
|
|
8178
|
+
if (node.grantor) {
|
|
8179
|
+
output.push('GRANTED BY', this.RoleSpec(node.grantor, context));
|
|
8180
|
+
}
|
|
8181
|
+
if (!node.is_grant && node.behavior === 'DROP_CASCADE') {
|
|
8182
|
+
output.push('CASCADE');
|
|
8011
8183
|
}
|
|
8012
8184
|
return output.join(' ');
|
|
8013
8185
|
}
|
|
8014
8186
|
SecLabelStmt(node, context) {
|
|
8015
8187
|
const output = ['SECURITY LABEL'];
|
|
8016
8188
|
if (node.provider) {
|
|
8017
|
-
output.push('FOR',
|
|
8189
|
+
output.push('FOR', quotes_1.QuoteUtils.quoteIdentifier(node.provider));
|
|
8018
8190
|
}
|
|
8019
8191
|
output.push('ON');
|
|
8020
8192
|
if (node.objtype) {
|
|
@@ -8042,11 +8214,21 @@ class Deparser {
|
|
|
8042
8214
|
}
|
|
8043
8215
|
}
|
|
8044
8216
|
if (node.object) {
|
|
8045
|
-
|
|
8217
|
+
// Qualified names arrive as a List of String nodes and must be
|
|
8218
|
+
// dot-joined (visiting the List directly would comma-join them).
|
|
8219
|
+
if (typeof node.object === 'object' && 'List' in node.object) {
|
|
8220
|
+
const list = node.object.List;
|
|
8221
|
+
const objectParts = list_utils_1.ListUtils.unwrapList(list.items)
|
|
8222
|
+
.map(item => this.visit(item, context));
|
|
8223
|
+
output.push(objectParts.join('.'));
|
|
8224
|
+
}
|
|
8225
|
+
else {
|
|
8226
|
+
output.push(this.visit(node.object, context));
|
|
8227
|
+
}
|
|
8046
8228
|
}
|
|
8047
8229
|
output.push('IS');
|
|
8048
8230
|
if (node.label) {
|
|
8049
|
-
output.push(
|
|
8231
|
+
output.push(quotes_1.QuoteUtils.escape(node.label));
|
|
8050
8232
|
}
|
|
8051
8233
|
else {
|
|
8052
8234
|
output.push('NULL');
|
|
@@ -8103,10 +8285,10 @@ class Deparser {
|
|
|
8103
8285
|
output.push(conversionName);
|
|
8104
8286
|
}
|
|
8105
8287
|
if (node.for_encoding_name) {
|
|
8106
|
-
output.push('FOR',
|
|
8288
|
+
output.push('FOR', quotes_1.QuoteUtils.escape(node.for_encoding_name));
|
|
8107
8289
|
}
|
|
8108
8290
|
if (node.to_encoding_name) {
|
|
8109
|
-
output.push('TO',
|
|
8291
|
+
output.push('TO', quotes_1.QuoteUtils.escape(node.to_encoding_name));
|
|
8110
8292
|
}
|
|
8111
8293
|
if (node.func_name && node.func_name.length > 0) {
|
|
8112
8294
|
output.push('FROM');
|
|
@@ -8167,7 +8349,7 @@ class Deparser {
|
|
|
8167
8349
|
}
|
|
8168
8350
|
output.push('LANGUAGE');
|
|
8169
8351
|
if (node.plname) {
|
|
8170
|
-
output.push(
|
|
8352
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.plname));
|
|
8171
8353
|
}
|
|
8172
8354
|
if (node.plhandler && node.plhandler.length > 0) {
|
|
8173
8355
|
output.push('HANDLER');
|
|
@@ -8203,7 +8385,7 @@ class Deparser {
|
|
|
8203
8385
|
}
|
|
8204
8386
|
output.push('LANGUAGE');
|
|
8205
8387
|
if (node.lang) {
|
|
8206
|
-
output.push(
|
|
8388
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.lang));
|
|
8207
8389
|
}
|
|
8208
8390
|
output.push('(');
|
|
8209
8391
|
const transforms = [];
|
|
@@ -8231,7 +8413,7 @@ class Deparser {
|
|
|
8231
8413
|
}
|
|
8232
8414
|
output.push('TRIGGER');
|
|
8233
8415
|
if (node.trigname) {
|
|
8234
|
-
output.push(
|
|
8416
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.trigname));
|
|
8235
8417
|
}
|
|
8236
8418
|
if (context.isPretty()) {
|
|
8237
8419
|
const components = [];
|
|
@@ -8269,6 +8451,9 @@ class Deparser {
|
|
|
8269
8451
|
.join(' ');
|
|
8270
8452
|
components.push(context.indent('REFERENCING ' + transitionClauses));
|
|
8271
8453
|
}
|
|
8454
|
+
if (node.constrrel) {
|
|
8455
|
+
components.push(context.indent('FROM ' + this.RangeVar(node.constrrel, context)));
|
|
8456
|
+
}
|
|
8272
8457
|
if (node.deferrable) {
|
|
8273
8458
|
components.push(context.indent('DEFERRABLE'));
|
|
8274
8459
|
}
|
|
@@ -8290,7 +8475,7 @@ class Deparser {
|
|
|
8290
8475
|
const funcName = list_utils_1.ListUtils.unwrapList(node.funcname)
|
|
8291
8476
|
.map(name => this.visit(name, context))
|
|
8292
8477
|
.join('.');
|
|
8293
|
-
executeStr += '
|
|
8478
|
+
executeStr += ' FUNCTION ' + funcName;
|
|
8294
8479
|
}
|
|
8295
8480
|
if (node.args && node.args.length > 0) {
|
|
8296
8481
|
const argContext = context.spawn('CreateTrigStmt', { isStringLiteral: true });
|
|
@@ -8395,14 +8580,14 @@ class Deparser {
|
|
|
8395
8580
|
output.push('OLD TABLE AS');
|
|
8396
8581
|
}
|
|
8397
8582
|
if (node.name) {
|
|
8398
|
-
output.push(
|
|
8583
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
8399
8584
|
}
|
|
8400
8585
|
return output.join(' ');
|
|
8401
8586
|
}
|
|
8402
8587
|
CreateEventTrigStmt(node, context) {
|
|
8403
8588
|
const output = ['CREATE EVENT TRIGGER'];
|
|
8404
8589
|
if (node.trigname) {
|
|
8405
|
-
output.push(
|
|
8590
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.trigname));
|
|
8406
8591
|
}
|
|
8407
8592
|
output.push('ON');
|
|
8408
8593
|
if (node.eventname) {
|
|
@@ -8428,7 +8613,7 @@ class Deparser {
|
|
|
8428
8613
|
AlterEventTrigStmt(node, context) {
|
|
8429
8614
|
const output = ['ALTER EVENT TRIGGER'];
|
|
8430
8615
|
if (node.trigname) {
|
|
8431
|
-
output.push(
|
|
8616
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.trigname));
|
|
8432
8617
|
}
|
|
8433
8618
|
if (node.tgenabled) {
|
|
8434
8619
|
switch (node.tgenabled) {
|
|
@@ -8548,6 +8733,74 @@ class Deparser {
|
|
|
8548
8733
|
.join(' ');
|
|
8549
8734
|
output.push(whenClauses);
|
|
8550
8735
|
}
|
|
8736
|
+
if (node.returningClause) {
|
|
8737
|
+
output.push(this.ReturningClause(node.returningClause, context));
|
|
8738
|
+
}
|
|
8739
|
+
return output.join(' ');
|
|
8740
|
+
}
|
|
8741
|
+
MergeSupportFunc(node, context) {
|
|
8742
|
+
return 'merge_action()';
|
|
8743
|
+
}
|
|
8744
|
+
MergeWhenClause(node, context) {
|
|
8745
|
+
const output = ['WHEN'];
|
|
8746
|
+
switch (node.matchKind) {
|
|
8747
|
+
case 'MERGE_WHEN_MATCHED':
|
|
8748
|
+
output.push('MATCHED');
|
|
8749
|
+
break;
|
|
8750
|
+
case 'MERGE_WHEN_NOT_MATCHED_BY_SOURCE':
|
|
8751
|
+
output.push('NOT MATCHED BY SOURCE');
|
|
8752
|
+
break;
|
|
8753
|
+
case 'MERGE_WHEN_NOT_MATCHED_BY_TARGET':
|
|
8754
|
+
output.push('NOT MATCHED');
|
|
8755
|
+
break;
|
|
8756
|
+
}
|
|
8757
|
+
if (node.condition) {
|
|
8758
|
+
output.push('AND');
|
|
8759
|
+
output.push(this.visit(node.condition, context));
|
|
8760
|
+
}
|
|
8761
|
+
output.push('THEN');
|
|
8762
|
+
switch (node.commandType) {
|
|
8763
|
+
case 'CMD_UPDATE': {
|
|
8764
|
+
output.push('UPDATE SET');
|
|
8765
|
+
if (node.targetList && node.targetList.length > 0) {
|
|
8766
|
+
output.push(this.formatUpdateAssignments(node.targetList, context));
|
|
8767
|
+
}
|
|
8768
|
+
break;
|
|
8769
|
+
}
|
|
8770
|
+
case 'CMD_INSERT': {
|
|
8771
|
+
output.push('INSERT');
|
|
8772
|
+
const targetList = list_utils_1.ListUtils.unwrapList(node.targetList);
|
|
8773
|
+
if (targetList.length > 0) {
|
|
8774
|
+
const columns = targetList
|
|
8775
|
+
.map(target => quotes_1.QuoteUtils.quoteIdentifier(target.ResTarget?.name))
|
|
8776
|
+
.join(', ');
|
|
8777
|
+
output.push(`(${columns})`);
|
|
8778
|
+
}
|
|
8779
|
+
if (node.override === 'OVERRIDING_USER_VALUE') {
|
|
8780
|
+
output.push('OVERRIDING USER VALUE');
|
|
8781
|
+
}
|
|
8782
|
+
else if (node.override === 'OVERRIDING_SYSTEM_VALUE') {
|
|
8783
|
+
output.push('OVERRIDING SYSTEM VALUE');
|
|
8784
|
+
}
|
|
8785
|
+
const values = list_utils_1.ListUtils.unwrapList(node.values);
|
|
8786
|
+
if (values.length > 0) {
|
|
8787
|
+
const valueItems = values
|
|
8788
|
+
.map(value => this.visit(value, context))
|
|
8789
|
+
.join(', ');
|
|
8790
|
+
output.push(`VALUES (${valueItems})`);
|
|
8791
|
+
}
|
|
8792
|
+
else {
|
|
8793
|
+
output.push('DEFAULT VALUES');
|
|
8794
|
+
}
|
|
8795
|
+
break;
|
|
8796
|
+
}
|
|
8797
|
+
case 'CMD_DELETE':
|
|
8798
|
+
output.push('DELETE');
|
|
8799
|
+
break;
|
|
8800
|
+
case 'CMD_NOTHING':
|
|
8801
|
+
output.push('DO NOTHING');
|
|
8802
|
+
break;
|
|
8803
|
+
}
|
|
8551
8804
|
return output.join(' ');
|
|
8552
8805
|
}
|
|
8553
8806
|
AlterTableMoveAllStmt(node, context) {
|
|
@@ -8563,11 +8816,11 @@ class Deparser {
|
|
|
8563
8816
|
}
|
|
8564
8817
|
output.push('ALL', 'IN', 'TABLESPACE');
|
|
8565
8818
|
if (node.orig_tablespacename) {
|
|
8566
|
-
output.push(
|
|
8819
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.orig_tablespacename));
|
|
8567
8820
|
}
|
|
8568
8821
|
output.push('SET', 'TABLESPACE');
|
|
8569
8822
|
if (node.new_tablespacename) {
|
|
8570
|
-
output.push(
|
|
8823
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.new_tablespacename));
|
|
8571
8824
|
}
|
|
8572
8825
|
if (node.nowait) {
|
|
8573
8826
|
output.push('NOWAIT');
|
|
@@ -8591,10 +8844,10 @@ class Deparser {
|
|
|
8591
8844
|
const sequenceName = [];
|
|
8592
8845
|
const seq = node.sequence;
|
|
8593
8846
|
if (seq.schemaname) {
|
|
8594
|
-
sequenceName.push(
|
|
8847
|
+
sequenceName.push(quotes_1.QuoteUtils.quoteIdentifier(seq.schemaname));
|
|
8595
8848
|
}
|
|
8596
8849
|
if (seq.relname) {
|
|
8597
|
-
sequenceName.push(
|
|
8850
|
+
sequenceName.push(quotes_1.QuoteUtils.quoteIdentifier(seq.relname));
|
|
8598
8851
|
}
|
|
8599
8852
|
output.push(sequenceName.join('.'));
|
|
8600
8853
|
}
|
|
@@ -8628,10 +8881,10 @@ class Deparser {
|
|
|
8628
8881
|
const sequenceName = [];
|
|
8629
8882
|
const seq = node.sequence;
|
|
8630
8883
|
if (seq.schemaname) {
|
|
8631
|
-
sequenceName.push(
|
|
8884
|
+
sequenceName.push(quotes_1.QuoteUtils.quoteIdentifier(seq.schemaname));
|
|
8632
8885
|
}
|
|
8633
8886
|
if (seq.relname) {
|
|
8634
|
-
sequenceName.push(
|
|
8887
|
+
sequenceName.push(quotes_1.QuoteUtils.quoteIdentifier(seq.relname));
|
|
8635
8888
|
}
|
|
8636
8889
|
output.push(sequenceName.join('.'));
|
|
8637
8890
|
}
|
|
@@ -8916,6 +9169,13 @@ class Deparser {
|
|
|
8916
9169
|
output.push('USING');
|
|
8917
9170
|
output.push(node.into.accessMethod);
|
|
8918
9171
|
}
|
|
9172
|
+
if (node.into && node.into.options && node.into.options.length > 0) {
|
|
9173
|
+
output.push('WITH');
|
|
9174
|
+
const options = list_utils_1.ListUtils.unwrapList(node.into.options)
|
|
9175
|
+
.map(option => this.visit(option, context.spawn('CreateStmt')))
|
|
9176
|
+
.join(', ');
|
|
9177
|
+
output.push(`(${options})`);
|
|
9178
|
+
}
|
|
8919
9179
|
if (node.into && node.into.onCommit && node.into.onCommit !== 'ONCOMMIT_NOOP') {
|
|
8920
9180
|
output.push('ON COMMIT');
|
|
8921
9181
|
switch (node.into.onCommit) {
|
|
@@ -8930,17 +9190,13 @@ class Deparser {
|
|
|
8930
9190
|
break;
|
|
8931
9191
|
}
|
|
8932
9192
|
}
|
|
9193
|
+
if (node.into && node.into.tableSpaceName) {
|
|
9194
|
+
output.push('TABLESPACE', quotes_1.QuoteUtils.quoteIdentifier(node.into.tableSpaceName));
|
|
9195
|
+
}
|
|
8933
9196
|
output.push('AS');
|
|
8934
9197
|
if (node.query) {
|
|
8935
9198
|
output.push(this.visit(node.query, context));
|
|
8936
9199
|
}
|
|
8937
|
-
if (node.into && node.into.options && node.into.options.length > 0) {
|
|
8938
|
-
output.push('WITH');
|
|
8939
|
-
const options = list_utils_1.ListUtils.unwrapList(node.into.options)
|
|
8940
|
-
.map(option => this.visit(option, context))
|
|
8941
|
-
.join(', ');
|
|
8942
|
-
output.push(`(${options})`);
|
|
8943
|
-
}
|
|
8944
9200
|
if (node.into && node.into.skipData) {
|
|
8945
9201
|
output.push('WITH NO DATA');
|
|
8946
9202
|
}
|
|
@@ -8978,7 +9234,7 @@ class Deparser {
|
|
|
8978
9234
|
}
|
|
8979
9235
|
aliasname(node, context) {
|
|
8980
9236
|
if (typeof node === 'string') {
|
|
8981
|
-
return
|
|
9237
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node);
|
|
8982
9238
|
}
|
|
8983
9239
|
return this.visit(node, context);
|
|
8984
9240
|
}
|
|
@@ -9010,18 +9266,16 @@ class Deparser {
|
|
|
9010
9266
|
const defName = defElem.defname;
|
|
9011
9267
|
const defValue = defElem.arg;
|
|
9012
9268
|
if (defName && defValue) {
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
preservedDefName = `"${defName}"`;
|
|
9016
|
-
}
|
|
9017
|
-
else {
|
|
9018
|
-
preservedDefName = this.preserveOperatorDefElemCase(defName);
|
|
9019
|
-
}
|
|
9269
|
+
const quotedDefName = quotes_1.QuoteUtils.quoteIdentifier(defName);
|
|
9270
|
+
const preservedDefName = quotedDefName !== defName ? quotedDefName : this.preserveOperatorDefElemCase(defName);
|
|
9020
9271
|
if ((defName.toLowerCase() === 'commutator' || defName.toLowerCase() === 'negator') && defValue.List) {
|
|
9021
9272
|
const listItems = list_utils_1.ListUtils.unwrapList(defValue.List.items);
|
|
9022
9273
|
if (listItems.length === 1 && listItems[0].String) {
|
|
9023
9274
|
return `${preservedDefName} = ${listItems[0].String.sval}`;
|
|
9024
9275
|
}
|
|
9276
|
+
if (listItems.length > 1 && listItems.every(item => item.String)) {
|
|
9277
|
+
return `${preservedDefName} = OPERATOR(${this.qualifiedOperatorName(listItems)})`;
|
|
9278
|
+
}
|
|
9025
9279
|
}
|
|
9026
9280
|
// For commutator/negator, we already handled them above
|
|
9027
9281
|
if ((defName.toLowerCase() === 'commutator' || defName.toLowerCase() === 'negator')) {
|
|
@@ -9032,7 +9286,7 @@ class Deparser {
|
|
|
9032
9286
|
else if (defName && !defValue) {
|
|
9033
9287
|
// Handle boolean flags like HASHES, MERGES - preserve original case
|
|
9034
9288
|
if (defName === 'Hashes' || defName === 'Merges') {
|
|
9035
|
-
return
|
|
9289
|
+
return quotes_1.QuoteUtils.quoteIdentifier(defName);
|
|
9036
9290
|
}
|
|
9037
9291
|
return this.preserveOperatorDefElemCase(defName).toUpperCase();
|
|
9038
9292
|
}
|
|
@@ -9171,16 +9425,11 @@ class Deparser {
|
|
|
9171
9425
|
const defName = defElem.defname;
|
|
9172
9426
|
const defValue = defElem.arg;
|
|
9173
9427
|
if (defName && defValue) {
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
preservedDefName = `"${defName}"`;
|
|
9177
|
-
}
|
|
9178
|
-
else {
|
|
9179
|
-
preservedDefName = defName;
|
|
9180
|
-
}
|
|
9428
|
+
const quotedDefName = quotes_1.QuoteUtils.quoteIdentifier(defName);
|
|
9429
|
+
const preservedDefName = quotedDefName !== defName ? quotedDefName : defName;
|
|
9181
9430
|
// Handle String arguments with single quotes for string literals
|
|
9182
9431
|
if (defValue.String) {
|
|
9183
|
-
return `${preservedDefName} =
|
|
9432
|
+
return `${preservedDefName} = ${quotes_1.QuoteUtils.escape(defValue.String.sval)}`;
|
|
9184
9433
|
}
|
|
9185
9434
|
return `${preservedDefName} = ${this.visit(defValue, context)}`;
|
|
9186
9435
|
}
|
|
@@ -9303,7 +9552,7 @@ class Deparser {
|
|
|
9303
9552
|
// For CREATE COLLATION, ensure String nodes are quoted as string literals
|
|
9304
9553
|
let valueStr;
|
|
9305
9554
|
if (defValue.String) {
|
|
9306
|
-
valueStr =
|
|
9555
|
+
valueStr = quotes_1.QuoteUtils.escape(defValue.String.sval);
|
|
9307
9556
|
}
|
|
9308
9557
|
else {
|
|
9309
9558
|
valueStr = this.visit(defValue, context);
|
|
@@ -9332,7 +9581,7 @@ class Deparser {
|
|
|
9332
9581
|
AlterDatabaseStmt(node, context) {
|
|
9333
9582
|
const output = ['ALTER', 'DATABASE'];
|
|
9334
9583
|
if (node.dbname) {
|
|
9335
|
-
output.push(
|
|
9584
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.dbname));
|
|
9336
9585
|
}
|
|
9337
9586
|
if (node.options && node.options.length > 0) {
|
|
9338
9587
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context));
|
|
@@ -9343,7 +9592,7 @@ class Deparser {
|
|
|
9343
9592
|
AlterDatabaseRefreshCollStmt(node, context) {
|
|
9344
9593
|
const output = ['ALTER', 'DATABASE'];
|
|
9345
9594
|
if (node.dbname) {
|
|
9346
|
-
output.push(
|
|
9595
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.dbname));
|
|
9347
9596
|
}
|
|
9348
9597
|
output.push('REFRESH', 'COLLATION', 'VERSION');
|
|
9349
9598
|
return output.join(' ');
|
|
@@ -9351,7 +9600,7 @@ class Deparser {
|
|
|
9351
9600
|
AlterDatabaseSetStmt(node, context) {
|
|
9352
9601
|
const output = ['ALTER', 'DATABASE'];
|
|
9353
9602
|
if (node.dbname) {
|
|
9354
|
-
output.push(
|
|
9603
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.dbname));
|
|
9355
9604
|
}
|
|
9356
9605
|
if (node.setstmt) {
|
|
9357
9606
|
const setClause = this.VariableSetStmt(node.setstmt, context);
|
|
@@ -9362,7 +9611,7 @@ class Deparser {
|
|
|
9362
9611
|
DeclareCursorStmt(node, context) {
|
|
9363
9612
|
const output = ['DECLARE'];
|
|
9364
9613
|
if (node.portalname) {
|
|
9365
|
-
output.push(
|
|
9614
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.portalname));
|
|
9366
9615
|
}
|
|
9367
9616
|
// Handle cursor options before CURSOR keyword
|
|
9368
9617
|
const cursorOptions = [];
|
|
@@ -9404,7 +9653,7 @@ class Deparser {
|
|
|
9404
9653
|
else if (node.pubobjtype === 'PUBLICATIONOBJ_TABLES_IN_SCHEMA') {
|
|
9405
9654
|
output.push('TABLES IN SCHEMA');
|
|
9406
9655
|
if (node.name) {
|
|
9407
|
-
output.push(
|
|
9656
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
9408
9657
|
}
|
|
9409
9658
|
}
|
|
9410
9659
|
else if (node.pubobjtype === 'PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA') {
|
|
@@ -9423,14 +9672,14 @@ class Deparser {
|
|
|
9423
9672
|
}
|
|
9424
9673
|
if (node.whereClause) {
|
|
9425
9674
|
output.push('WHERE');
|
|
9426
|
-
output.push(this.visit(node.whereClause, context));
|
|
9675
|
+
output.push(`(${this.visit(node.whereClause, context)})`);
|
|
9427
9676
|
}
|
|
9428
9677
|
return output.join(' ');
|
|
9429
9678
|
}
|
|
9430
9679
|
CreateAmStmt(node, context) {
|
|
9431
9680
|
const output = ['CREATE', 'ACCESS', 'METHOD'];
|
|
9432
9681
|
if (node.amname) {
|
|
9433
|
-
output.push(
|
|
9682
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.amname));
|
|
9434
9683
|
}
|
|
9435
9684
|
output.push('TYPE');
|
|
9436
9685
|
switch (node.amtype) {
|
|
@@ -9490,7 +9739,7 @@ class Deparser {
|
|
|
9490
9739
|
}
|
|
9491
9740
|
}
|
|
9492
9741
|
if (node.tableSpaceName) {
|
|
9493
|
-
output.push('TABLESPACE',
|
|
9742
|
+
output.push('TABLESPACE', quotes_1.QuoteUtils.quoteIdentifier(node.tableSpaceName));
|
|
9494
9743
|
}
|
|
9495
9744
|
return output.join(' ');
|
|
9496
9745
|
}
|
|
@@ -9570,6 +9819,23 @@ class Deparser {
|
|
|
9570
9819
|
}
|
|
9571
9820
|
return output.join(' ');
|
|
9572
9821
|
}
|
|
9822
|
+
quoteDefElemArg(arg, argValue) {
|
|
9823
|
+
if (arg && this.getNodeType(arg) === 'String') {
|
|
9824
|
+
return quotes_1.QuoteUtils.escape(this.getNodeData(arg).sval || '');
|
|
9825
|
+
}
|
|
9826
|
+
return typeof argValue === 'string' && !argValue.startsWith("'")
|
|
9827
|
+
? quotes_1.QuoteUtils.escape(argValue)
|
|
9828
|
+
: argValue;
|
|
9829
|
+
}
|
|
9830
|
+
formatOptionValue(arg, argValue) {
|
|
9831
|
+
if (arg && this.getNodeType(arg) === 'String') {
|
|
9832
|
+
const sval = this.getNodeData(arg).sval || '';
|
|
9833
|
+
return /^[a-z_][a-z0-9_]*$/.test(sval) && (0, quotes_1.keywordKindOf)(sval) === 'NO_KEYWORD'
|
|
9834
|
+
? sval
|
|
9835
|
+
: quotes_1.QuoteUtils.escape(sval);
|
|
9836
|
+
}
|
|
9837
|
+
return argValue;
|
|
9838
|
+
}
|
|
9573
9839
|
Var(node, context) {
|
|
9574
9840
|
if (node.varno && node.varattno) {
|
|
9575
9841
|
return `$${node.varno}.${node.varattno}`;
|
|
@@ -9609,7 +9875,7 @@ class Deparser {
|
|
|
9609
9875
|
}
|
|
9610
9876
|
if (node.rowexpr) {
|
|
9611
9877
|
output.push(',');
|
|
9612
|
-
output.push(
|
|
9878
|
+
output.push(this.visit(node.rowexpr, context));
|
|
9613
9879
|
}
|
|
9614
9880
|
if (node.colexprs && node.colexprs.length > 0) {
|
|
9615
9881
|
output.push('COLUMNS');
|
|
@@ -9626,29 +9892,44 @@ class Deparser {
|
|
|
9626
9892
|
if (node.lateral) {
|
|
9627
9893
|
output.push('LATERAL');
|
|
9628
9894
|
}
|
|
9629
|
-
|
|
9630
|
-
|
|
9895
|
+
const args = [];
|
|
9896
|
+
if (node.namespaces && node.namespaces.length > 0) {
|
|
9897
|
+
const namespaces = list_utils_1.ListUtils.unwrapList(node.namespaces).map(ns => {
|
|
9898
|
+
const target = this.getNodeData(ns);
|
|
9899
|
+
const uri = this.visit(target.val, context);
|
|
9900
|
+
return target.name ? `${uri} AS ${quotes_1.QuoteUtils.quoteIdentifier(target.name)}` : `DEFAULT ${uri}`;
|
|
9901
|
+
});
|
|
9902
|
+
args.push(`XMLNAMESPACES(${namespaces.join(', ')}),`);
|
|
9631
9903
|
}
|
|
9632
9904
|
if (node.rowexpr) {
|
|
9633
|
-
|
|
9634
|
-
|
|
9905
|
+
args.push(this.formatXmlTableExpr(node.rowexpr, context));
|
|
9906
|
+
}
|
|
9907
|
+
if (node.docexpr) {
|
|
9908
|
+
args.push('PASSING');
|
|
9909
|
+
args.push(this.formatXmlTableExpr(node.docexpr, context));
|
|
9635
9910
|
}
|
|
9636
9911
|
if (node.columns && node.columns.length > 0) {
|
|
9637
|
-
|
|
9638
|
-
|
|
9912
|
+
args.push('COLUMNS');
|
|
9913
|
+
args.push(list_utils_1.ListUtils.unwrapList(node.columns)
|
|
9639
9914
|
.map(col => this.visit(col, context))
|
|
9640
|
-
.join(', ');
|
|
9641
|
-
output.push(`(${columns})`);
|
|
9915
|
+
.join(', '));
|
|
9642
9916
|
}
|
|
9917
|
+
output.push(`XMLTABLE(${args.join(' ')})`);
|
|
9643
9918
|
if (node.alias) {
|
|
9644
9919
|
output.push(this.Alias(node.alias, context));
|
|
9645
9920
|
}
|
|
9646
9921
|
return output.join(' ');
|
|
9647
9922
|
}
|
|
9923
|
+
formatXmlTableExpr(expr, context) {
|
|
9924
|
+
const value = this.visit(expr, context);
|
|
9925
|
+
return ['A_Const', 'ColumnRef', 'ParamRef', 'FuncCall'].includes(this.getNodeType(expr))
|
|
9926
|
+
? value
|
|
9927
|
+
: `(${value})`;
|
|
9928
|
+
}
|
|
9648
9929
|
RangeTableFuncCol(node, context) {
|
|
9649
9930
|
const output = [];
|
|
9650
9931
|
if (node.colname) {
|
|
9651
|
-
output.push(
|
|
9932
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.colname));
|
|
9652
9933
|
}
|
|
9653
9934
|
if (node.for_ordinality) {
|
|
9654
9935
|
output.push('FOR ORDINALITY');
|
|
@@ -9658,32 +9939,193 @@ class Deparser {
|
|
|
9658
9939
|
}
|
|
9659
9940
|
if (node.colexpr) {
|
|
9660
9941
|
output.push('PATH');
|
|
9661
|
-
output.push(
|
|
9942
|
+
output.push(this.visit(node.colexpr, context));
|
|
9662
9943
|
}
|
|
9663
9944
|
if (node.coldefexpr) {
|
|
9664
9945
|
output.push('DEFAULT');
|
|
9665
9946
|
output.push(this.visit(node.coldefexpr, context));
|
|
9666
9947
|
}
|
|
9948
|
+
if (node.is_not_null) {
|
|
9949
|
+
output.push('NOT NULL');
|
|
9950
|
+
}
|
|
9667
9951
|
return output.join(' ');
|
|
9668
9952
|
}
|
|
9953
|
+
formatJsonFormat(format) {
|
|
9954
|
+
if (!format || !format.format_type || format.format_type === 'JS_FORMAT_DEFAULT') {
|
|
9955
|
+
return null;
|
|
9956
|
+
}
|
|
9957
|
+
const parts = ['FORMAT JSON'];
|
|
9958
|
+
switch (format.encoding) {
|
|
9959
|
+
case 'JS_ENC_UTF8':
|
|
9960
|
+
parts.push('ENCODING UTF8');
|
|
9961
|
+
break;
|
|
9962
|
+
case 'JS_ENC_UTF16':
|
|
9963
|
+
parts.push('ENCODING UTF16');
|
|
9964
|
+
break;
|
|
9965
|
+
case 'JS_ENC_UTF32':
|
|
9966
|
+
parts.push('ENCODING UTF32');
|
|
9967
|
+
break;
|
|
9968
|
+
}
|
|
9969
|
+
return parts.join(' ');
|
|
9970
|
+
}
|
|
9971
|
+
formatJsonOutput(output, context) {
|
|
9972
|
+
if (!output || !output.typeName)
|
|
9973
|
+
return null;
|
|
9974
|
+
const parts = ['RETURNING', this.TypeName(output.typeName, context)];
|
|
9975
|
+
const format = this.formatJsonFormat(output.returning?.format);
|
|
9976
|
+
if (format)
|
|
9977
|
+
parts.push(format);
|
|
9978
|
+
return parts.join(' ');
|
|
9979
|
+
}
|
|
9980
|
+
formatJsonNullClause(absentOnNull) {
|
|
9981
|
+
return absentOnNull ? 'ABSENT ON NULL' : 'NULL ON NULL';
|
|
9982
|
+
}
|
|
9983
|
+
formatJsonUniqueClause(unique) {
|
|
9984
|
+
return unique ? 'WITH UNIQUE KEYS' : null;
|
|
9985
|
+
}
|
|
9986
|
+
JsonValueExpr(node, context) {
|
|
9987
|
+
const parts = [];
|
|
9988
|
+
if (node.raw_expr) {
|
|
9989
|
+
parts.push(this.visit(node.raw_expr, context));
|
|
9990
|
+
}
|
|
9991
|
+
const format = this.formatJsonFormat(node.format);
|
|
9992
|
+
if (format)
|
|
9993
|
+
parts.push(format);
|
|
9994
|
+
return parts.join(' ');
|
|
9995
|
+
}
|
|
9996
|
+
JsonKeyValue(node, context) {
|
|
9997
|
+
const key = node.key ? this.visit(node.key, context) : '';
|
|
9998
|
+
const value = node.value ? this.JsonValueExpr(node.value, context) : '';
|
|
9999
|
+
return `${key} : ${value}`;
|
|
10000
|
+
}
|
|
10001
|
+
JsonObjectConstructor(node, context) {
|
|
10002
|
+
const args = [];
|
|
10003
|
+
if (node.exprs && node.exprs.length > 0) {
|
|
10004
|
+
args.push(list_utils_1.ListUtils.unwrapList(node.exprs).map(e => this.visit(e, context)).join(', '));
|
|
10005
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
10006
|
+
const unique = this.formatJsonUniqueClause(node.unique);
|
|
10007
|
+
if (unique)
|
|
10008
|
+
args.push(unique);
|
|
10009
|
+
}
|
|
10010
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
10011
|
+
if (output)
|
|
10012
|
+
args.push(output);
|
|
10013
|
+
return `JSON_OBJECT(${args.join(' ')})`;
|
|
10014
|
+
}
|
|
10015
|
+
JsonArrayConstructor(node, context) {
|
|
10016
|
+
const args = [];
|
|
10017
|
+
if (node.exprs && node.exprs.length > 0) {
|
|
10018
|
+
args.push(list_utils_1.ListUtils.unwrapList(node.exprs).map(e => this.visit(e, context)).join(', '));
|
|
10019
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
10020
|
+
}
|
|
10021
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
10022
|
+
if (output)
|
|
10023
|
+
args.push(output);
|
|
10024
|
+
return `JSON_ARRAY(${args.join(' ')})`;
|
|
10025
|
+
}
|
|
9669
10026
|
JsonArrayQueryConstructor(node, context) {
|
|
9670
|
-
const
|
|
10027
|
+
const args = [];
|
|
9671
10028
|
if (node.query) {
|
|
9672
|
-
|
|
10029
|
+
args.push(this.visit(node.query, context));
|
|
10030
|
+
}
|
|
10031
|
+
const format = this.formatJsonFormat(node.format);
|
|
10032
|
+
if (format)
|
|
10033
|
+
args.push(format);
|
|
10034
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
10035
|
+
if (output)
|
|
10036
|
+
args.push(output);
|
|
10037
|
+
return `JSON_ARRAY(${args.join(' ')})`;
|
|
10038
|
+
}
|
|
10039
|
+
formatJsonAggSuffix(ctor, context) {
|
|
10040
|
+
if (!ctor)
|
|
10041
|
+
return '';
|
|
10042
|
+
let result = '';
|
|
10043
|
+
if (ctor.agg_filter) {
|
|
10044
|
+
result += ` FILTER (WHERE ${this.visit(ctor.agg_filter, context)})`;
|
|
9673
10045
|
}
|
|
9674
|
-
if (
|
|
9675
|
-
|
|
10046
|
+
if (ctor.over) {
|
|
10047
|
+
result += this.formatOverClause(ctor.over, context);
|
|
9676
10048
|
}
|
|
9677
|
-
|
|
9678
|
-
|
|
10049
|
+
return result;
|
|
10050
|
+
}
|
|
10051
|
+
JsonObjectAgg(node, context) {
|
|
10052
|
+
const args = [];
|
|
10053
|
+
if (node.arg) {
|
|
10054
|
+
args.push(this.JsonKeyValue(node.arg, context));
|
|
10055
|
+
}
|
|
10056
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
10057
|
+
const unique = this.formatJsonUniqueClause(node.unique);
|
|
10058
|
+
if (unique)
|
|
10059
|
+
args.push(unique);
|
|
10060
|
+
const output = this.formatJsonOutput(node.constructor?.output, context);
|
|
10061
|
+
if (output)
|
|
10062
|
+
args.push(output);
|
|
10063
|
+
return `JSON_OBJECTAGG(${args.join(' ')})${this.formatJsonAggSuffix(node.constructor, context)}`;
|
|
10064
|
+
}
|
|
10065
|
+
JsonArrayAgg(node, context) {
|
|
10066
|
+
const args = [];
|
|
10067
|
+
if (node.arg) {
|
|
10068
|
+
args.push(this.JsonValueExpr(node.arg, context));
|
|
9679
10069
|
}
|
|
9680
|
-
|
|
9681
|
-
|
|
10070
|
+
const aggOrder = node.constructor?.agg_order;
|
|
10071
|
+
if (aggOrder && aggOrder.length > 0) {
|
|
10072
|
+
const orderItems = list_utils_1.ListUtils.unwrapList(aggOrder).map(item => this.visit(item, context));
|
|
10073
|
+
args.push(`ORDER BY ${orderItems.join(', ')}`);
|
|
9682
10074
|
}
|
|
9683
|
-
|
|
9684
|
-
|
|
10075
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
10076
|
+
const output = this.formatJsonOutput(node.constructor?.output, context);
|
|
10077
|
+
if (output)
|
|
10078
|
+
args.push(output);
|
|
10079
|
+
return `JSON_ARRAYAGG(${args.join(' ')})${this.formatJsonAggSuffix(node.constructor, context)}`;
|
|
10080
|
+
}
|
|
10081
|
+
JsonParseExpr(node, context) {
|
|
10082
|
+
const args = [];
|
|
10083
|
+
if (node.expr) {
|
|
10084
|
+
args.push(this.JsonValueExpr(node.expr, context));
|
|
9685
10085
|
}
|
|
9686
|
-
|
|
10086
|
+
const unique = this.formatJsonUniqueClause(node.unique_keys);
|
|
10087
|
+
if (unique)
|
|
10088
|
+
args.push(unique);
|
|
10089
|
+
return `JSON(${args.join(' ')})`;
|
|
10090
|
+
}
|
|
10091
|
+
JsonScalarExpr(node, context) {
|
|
10092
|
+
const expr = node.expr ? this.visit(node.expr, context) : '';
|
|
10093
|
+
return `JSON_SCALAR(${expr})`;
|
|
10094
|
+
}
|
|
10095
|
+
JsonSerializeExpr(node, context) {
|
|
10096
|
+
const args = [];
|
|
10097
|
+
if (node.expr) {
|
|
10098
|
+
args.push(this.JsonValueExpr(node.expr, context));
|
|
10099
|
+
}
|
|
10100
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
10101
|
+
if (output)
|
|
10102
|
+
args.push(output);
|
|
10103
|
+
return `JSON_SERIALIZE(${args.join(' ')})`;
|
|
10104
|
+
}
|
|
10105
|
+
JsonIsPredicate(node, context) {
|
|
10106
|
+
const parts = [];
|
|
10107
|
+
if (node.expr) {
|
|
10108
|
+
parts.push(this.visit(node.expr, context));
|
|
10109
|
+
}
|
|
10110
|
+
const format = this.formatJsonFormat(node.format);
|
|
10111
|
+
if (format)
|
|
10112
|
+
parts.push(format);
|
|
10113
|
+
parts.push('IS JSON');
|
|
10114
|
+
switch (node.item_type) {
|
|
10115
|
+
case 'JS_TYPE_OBJECT':
|
|
10116
|
+
parts.push('OBJECT');
|
|
10117
|
+
break;
|
|
10118
|
+
case 'JS_TYPE_ARRAY':
|
|
10119
|
+
parts.push('ARRAY');
|
|
10120
|
+
break;
|
|
10121
|
+
case 'JS_TYPE_SCALAR':
|
|
10122
|
+
parts.push('SCALAR');
|
|
10123
|
+
break;
|
|
10124
|
+
}
|
|
10125
|
+
if (node.unique_keys) {
|
|
10126
|
+
parts.push('WITH UNIQUE KEYS');
|
|
10127
|
+
}
|
|
10128
|
+
return parts.join(' ');
|
|
9687
10129
|
}
|
|
9688
10130
|
RangeFunction(node, context) {
|
|
9689
10131
|
const output = [];
|
|
@@ -9794,10 +10236,10 @@ class Deparser {
|
|
|
9794
10236
|
if (node.op === 'IS_XMLPI') {
|
|
9795
10237
|
if (node.name && node.args && node.args.length > 0) {
|
|
9796
10238
|
const argStrs = list_utils_1.ListUtils.unwrapList(node.args).map(arg => this.visit(arg, context));
|
|
9797
|
-
return `xmlpi(name ${
|
|
10239
|
+
return `xmlpi(name ${quotes_1.QuoteUtils.quoteIdentifier(node.name)}, ${argStrs.join(', ')})`;
|
|
9798
10240
|
}
|
|
9799
10241
|
else if (node.name) {
|
|
9800
|
-
return `xmlpi(name ${
|
|
10242
|
+
return `xmlpi(name ${quotes_1.QuoteUtils.quoteIdentifier(node.name)})`;
|
|
9801
10243
|
}
|
|
9802
10244
|
else {
|
|
9803
10245
|
return 'XMLPI()';
|
|
@@ -9812,7 +10254,7 @@ class Deparser {
|
|
|
9812
10254
|
output.push('XMLELEMENT');
|
|
9813
10255
|
const elementParts = [];
|
|
9814
10256
|
if (node.name) {
|
|
9815
|
-
elementParts.push(`NAME ${
|
|
10257
|
+
elementParts.push(`NAME ${quotes_1.QuoteUtils.quoteIdentifier(node.name)}`);
|
|
9816
10258
|
}
|
|
9817
10259
|
if (node.named_args && node.named_args.length > 0) {
|
|
9818
10260
|
const namedArgStrs = list_utils_1.ListUtils.unwrapList(node.named_args).map(arg => this.visit(arg, context));
|
|
@@ -9877,6 +10319,7 @@ class Deparser {
|
|
|
9877
10319
|
rootParts.push('STANDALONE NO VALUE');
|
|
9878
10320
|
}
|
|
9879
10321
|
else if (standaloneArg.A_Const.ival.ival === 3) {
|
|
10322
|
+
// STANDALONE omitted
|
|
9880
10323
|
}
|
|
9881
10324
|
else if (Object.keys(standaloneArg.A_Const.ival).length === 0) {
|
|
9882
10325
|
rootParts.push('STANDALONE YES');
|
|
@@ -9912,7 +10355,7 @@ class Deparser {
|
|
|
9912
10355
|
// Handle name and args for operations that don't have special handling
|
|
9913
10356
|
if (node.op !== 'IS_XMLELEMENT' && node.op !== 'IS_XMLPARSE' && node.op !== 'IS_XMLROOT' && node.op !== 'IS_DOCUMENT') {
|
|
9914
10357
|
if (node.name) {
|
|
9915
|
-
const quotedName =
|
|
10358
|
+
const quotedName = quotes_1.QuoteUtils.quoteIdentifier(node.name);
|
|
9916
10359
|
output.push(`NAME ${quotedName}`);
|
|
9917
10360
|
}
|
|
9918
10361
|
if (node.args && node.args.length > 0) {
|
|
@@ -9933,26 +10376,26 @@ class Deparser {
|
|
|
9933
10376
|
}
|
|
9934
10377
|
schemaname(node, context) {
|
|
9935
10378
|
if (typeof node === 'string') {
|
|
9936
|
-
return
|
|
10379
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node);
|
|
9937
10380
|
}
|
|
9938
10381
|
if (node && node.String && node.String.sval) {
|
|
9939
|
-
return
|
|
10382
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.String.sval);
|
|
9940
10383
|
}
|
|
9941
10384
|
// Handle other node types without recursion
|
|
9942
10385
|
if (node && typeof node === 'object') {
|
|
9943
10386
|
if (node.sval !== undefined) {
|
|
9944
|
-
return
|
|
10387
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.sval);
|
|
9945
10388
|
}
|
|
9946
10389
|
// Handle List nodes that might contain schema names
|
|
9947
10390
|
if (node.List && Array.isArray(node.List.items)) {
|
|
9948
10391
|
const items = node.List.items;
|
|
9949
10392
|
if (items.length > 0 && items[0].String && items[0].String.sval) {
|
|
9950
|
-
return
|
|
10393
|
+
return quotes_1.QuoteUtils.quoteIdentifier(items[0].String.sval);
|
|
9951
10394
|
}
|
|
9952
10395
|
}
|
|
9953
10396
|
// For other complex nodes, try to extract string value without recursion
|
|
9954
10397
|
if (node.val !== undefined) {
|
|
9955
|
-
return
|
|
10398
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.val);
|
|
9956
10399
|
}
|
|
9957
10400
|
return '';
|
|
9958
10401
|
}
|
|
@@ -10015,7 +10458,7 @@ class Deparser {
|
|
|
10015
10458
|
}
|
|
10016
10459
|
output.push('RULE');
|
|
10017
10460
|
if (node.rulename) {
|
|
10018
|
-
output.push(
|
|
10461
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.rulename));
|
|
10019
10462
|
}
|
|
10020
10463
|
output.push('AS ON');
|
|
10021
10464
|
if (node.event) {
|
|
@@ -10082,42 +10525,42 @@ class Deparser {
|
|
|
10082
10525
|
}
|
|
10083
10526
|
relname(node, context) {
|
|
10084
10527
|
if (typeof node === 'string') {
|
|
10085
|
-
return
|
|
10528
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node);
|
|
10086
10529
|
}
|
|
10087
10530
|
if (node && node.String && node.String.sval) {
|
|
10088
|
-
return
|
|
10531
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.String.sval);
|
|
10089
10532
|
}
|
|
10090
10533
|
if (node && typeof node === 'object' && node.relname) {
|
|
10091
|
-
return
|
|
10534
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.relname);
|
|
10092
10535
|
}
|
|
10093
10536
|
return this.visit(node, context);
|
|
10094
10537
|
}
|
|
10095
10538
|
rel(node, context) {
|
|
10096
10539
|
if (typeof node === 'string') {
|
|
10097
|
-
return
|
|
10540
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node);
|
|
10098
10541
|
}
|
|
10099
10542
|
if (node && node.String && node.String.sval) {
|
|
10100
|
-
return
|
|
10543
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.String.sval);
|
|
10101
10544
|
}
|
|
10102
10545
|
if (node && node.RangeVar) {
|
|
10103
10546
|
return this.RangeVar(node.RangeVar, context);
|
|
10104
10547
|
}
|
|
10105
10548
|
if (node && typeof node === 'object' && node.relname) {
|
|
10106
|
-
return
|
|
10549
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.relname);
|
|
10107
10550
|
}
|
|
10108
10551
|
return this.visit(node, context);
|
|
10109
10552
|
}
|
|
10110
10553
|
objname(node, context) {
|
|
10111
10554
|
if (typeof node === 'string') {
|
|
10112
|
-
return
|
|
10555
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node);
|
|
10113
10556
|
}
|
|
10114
10557
|
if (node && node.String && node.String.sval) {
|
|
10115
|
-
return
|
|
10558
|
+
return quotes_1.QuoteUtils.quoteIdentifier(node.String.sval);
|
|
10116
10559
|
}
|
|
10117
10560
|
if (Array.isArray(node)) {
|
|
10118
10561
|
const parts = node.map(part => {
|
|
10119
10562
|
if (part && part.String && part.String.sval) {
|
|
10120
|
-
return
|
|
10563
|
+
return quotes_1.QuoteUtils.quoteIdentifier(part.String.sval);
|
|
10121
10564
|
}
|
|
10122
10565
|
return this.visit(part, context);
|
|
10123
10566
|
});
|
|
@@ -10188,7 +10631,7 @@ class Deparser {
|
|
|
10188
10631
|
CurrentOfExpr(node, context) {
|
|
10189
10632
|
const output = ['CURRENT OF'];
|
|
10190
10633
|
if (node.cursor_name) {
|
|
10191
|
-
output.push(
|
|
10634
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.cursor_name));
|
|
10192
10635
|
}
|
|
10193
10636
|
if (node.cursor_param > 0) {
|
|
10194
10637
|
output.push(`$${node.cursor_param}`);
|
|
@@ -10271,7 +10714,7 @@ class Deparser {
|
|
|
10271
10714
|
if (items.length === 2) {
|
|
10272
10715
|
const schemaName = items[0].String?.sval || '';
|
|
10273
10716
|
const domainName = items[1].String?.sval || '';
|
|
10274
|
-
output.push(
|
|
10717
|
+
output.push(quotes_1.QuoteUtils.quoteQualifiedIdentifier(schemaName, domainName));
|
|
10275
10718
|
}
|
|
10276
10719
|
else {
|
|
10277
10720
|
output.push(this.visit(node.object, context));
|
|
@@ -10283,7 +10726,7 @@ class Deparser {
|
|
|
10283
10726
|
if (items.length === 2) {
|
|
10284
10727
|
const schemaName = items[0].String?.sval || '';
|
|
10285
10728
|
const typeName = items[1].String?.sval || '';
|
|
10286
|
-
output.push(
|
|
10729
|
+
output.push(quotes_1.QuoteUtils.quoteQualifiedIdentifier(schemaName, typeName));
|
|
10287
10730
|
}
|
|
10288
10731
|
else {
|
|
10289
10732
|
output.push(this.visit(node.object, context));
|
|
@@ -10295,7 +10738,7 @@ class Deparser {
|
|
|
10295
10738
|
if (items.length === 2) {
|
|
10296
10739
|
const schemaName = items[0].String?.sval || '';
|
|
10297
10740
|
const conversionName = items[1].String?.sval || '';
|
|
10298
|
-
output.push(
|
|
10741
|
+
output.push(quotes_1.QuoteUtils.quoteQualifiedIdentifier(schemaName, conversionName));
|
|
10299
10742
|
}
|
|
10300
10743
|
else {
|
|
10301
10744
|
output.push(this.visit(node.object, context));
|
|
@@ -10307,7 +10750,7 @@ class Deparser {
|
|
|
10307
10750
|
if (items.length === 2) {
|
|
10308
10751
|
const schemaName = items[0].String?.sval || '';
|
|
10309
10752
|
const parserName = items[1].String?.sval || '';
|
|
10310
|
-
output.push(
|
|
10753
|
+
output.push(quotes_1.QuoteUtils.quoteQualifiedIdentifier(schemaName, parserName));
|
|
10311
10754
|
}
|
|
10312
10755
|
else {
|
|
10313
10756
|
output.push(this.visit(node.object, context));
|
|
@@ -10319,7 +10762,7 @@ class Deparser {
|
|
|
10319
10762
|
if (items.length === 2) {
|
|
10320
10763
|
const schemaName = items[0].String?.sval || '';
|
|
10321
10764
|
const configName = items[1].String?.sval || '';
|
|
10322
|
-
output.push(
|
|
10765
|
+
output.push(quotes_1.QuoteUtils.quoteQualifiedIdentifier(schemaName, configName));
|
|
10323
10766
|
}
|
|
10324
10767
|
else {
|
|
10325
10768
|
output.push(this.visit(node.object, context));
|
|
@@ -10331,7 +10774,7 @@ class Deparser {
|
|
|
10331
10774
|
if (items.length === 2) {
|
|
10332
10775
|
const schemaName = items[0].String?.sval || '';
|
|
10333
10776
|
const templateName = items[1].String?.sval || '';
|
|
10334
|
-
output.push(
|
|
10777
|
+
output.push(quotes_1.QuoteUtils.quoteQualifiedIdentifier(schemaName, templateName));
|
|
10335
10778
|
}
|
|
10336
10779
|
else {
|
|
10337
10780
|
output.push(this.visit(node.object, context));
|
|
@@ -10343,7 +10786,7 @@ class Deparser {
|
|
|
10343
10786
|
if (items.length === 2) {
|
|
10344
10787
|
const schemaName = items[0].String?.sval || '';
|
|
10345
10788
|
const dictionaryName = items[1].String?.sval || '';
|
|
10346
|
-
output.push(
|
|
10789
|
+
output.push(quotes_1.QuoteUtils.quoteQualifiedIdentifier(schemaName, dictionaryName));
|
|
10347
10790
|
}
|
|
10348
10791
|
else {
|
|
10349
10792
|
output.push(this.visit(node.object, context));
|
|
@@ -10355,13 +10798,13 @@ class Deparser {
|
|
|
10355
10798
|
if (items.length === 2) {
|
|
10356
10799
|
const accessMethod = items[0].String?.sval || '';
|
|
10357
10800
|
const opClassName = items[1].String?.sval || '';
|
|
10358
|
-
output.push(`${
|
|
10801
|
+
output.push(`${quotes_1.QuoteUtils.quoteIdentifier(opClassName)} USING ${accessMethod}`);
|
|
10359
10802
|
}
|
|
10360
10803
|
else if (items.length === 3) {
|
|
10361
10804
|
const accessMethod = items[0].String?.sval || '';
|
|
10362
10805
|
const schemaName = items[1].String?.sval || '';
|
|
10363
10806
|
const opClassName = items[2].String?.sval || '';
|
|
10364
|
-
output.push(`${
|
|
10807
|
+
output.push(`${quotes_1.QuoteUtils.quoteQualifiedIdentifier(schemaName, opClassName)} USING ${accessMethod}`);
|
|
10365
10808
|
}
|
|
10366
10809
|
else {
|
|
10367
10810
|
output.push(this.visit(node.object, context));
|
|
@@ -10373,13 +10816,13 @@ class Deparser {
|
|
|
10373
10816
|
if (items.length === 2) {
|
|
10374
10817
|
const accessMethod = items[0].String?.sval || '';
|
|
10375
10818
|
const opFamilyName = items[1].String?.sval || '';
|
|
10376
|
-
output.push(`${
|
|
10819
|
+
output.push(`${quotes_1.QuoteUtils.quoteIdentifier(opFamilyName)} USING ${accessMethod}`);
|
|
10377
10820
|
}
|
|
10378
10821
|
else if (items.length === 3) {
|
|
10379
10822
|
const accessMethod = items[0].String?.sval || '';
|
|
10380
10823
|
const schemaName = items[1].String?.sval || '';
|
|
10381
10824
|
const opFamilyName = items[2].String?.sval || '';
|
|
10382
|
-
output.push(`${
|
|
10825
|
+
output.push(`${quotes_1.QuoteUtils.quoteQualifiedIdentifier(schemaName, opFamilyName)} USING ${accessMethod}`);
|
|
10383
10826
|
}
|
|
10384
10827
|
else {
|
|
10385
10828
|
output.push(this.visit(node.object, context));
|
|
@@ -10391,7 +10834,7 @@ class Deparser {
|
|
|
10391
10834
|
}
|
|
10392
10835
|
output.push('SET SCHEMA');
|
|
10393
10836
|
if (node.newschema) {
|
|
10394
|
-
output.push(
|
|
10837
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.newschema));
|
|
10395
10838
|
}
|
|
10396
10839
|
return output.join(' ');
|
|
10397
10840
|
}
|
|
@@ -10460,7 +10903,7 @@ class Deparser {
|
|
|
10460
10903
|
}
|
|
10461
10904
|
if (node.servername) {
|
|
10462
10905
|
output.push('SERVER');
|
|
10463
|
-
output.push(
|
|
10906
|
+
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.servername));
|
|
10464
10907
|
}
|
|
10465
10908
|
if (node.options && node.options.length > 0) {
|
|
10466
10909
|
const foreignTableContext = context.spawn('CreateForeignTableStmt');
|
|
@@ -10469,9 +10912,5 @@ class Deparser {
|
|
|
10469
10912
|
}
|
|
10470
10913
|
return output.join(' ');
|
|
10471
10914
|
}
|
|
10472
|
-
containsMultilineStringLiteral(content) {
|
|
10473
|
-
const stringLiteralRegex = /'[^']*\n[^']*'/g;
|
|
10474
|
-
return stringLiteralRegex.test(content);
|
|
10475
|
-
}
|
|
10476
10915
|
}
|
|
10477
10916
|
exports.Deparser = Deparser;
|