pgsql-deparser 18.3.7 → 18.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deparser.d.ts +20 -25
- package/deparser.js +547 -344
- package/esm/deparser.js +547 -344
- package/package.json +2 -2
package/deparser.js
CHANGED
|
@@ -5,6 +5,25 @@ const quotes_1 = require("@pgsql/quotes");
|
|
|
5
5
|
const list_utils_1 = require("./utils/list-utils");
|
|
6
6
|
const sql_formatter_1 = require("./utils/sql-formatter");
|
|
7
7
|
const base_1 = require("./visitors/base");
|
|
8
|
+
// WindowDef.frameOptions bit flags (src/include/nodes/parsenodes.h)
|
|
9
|
+
const FRAMEOPTION_NONDEFAULT = 0x00001;
|
|
10
|
+
const FRAMEOPTION_RANGE = 0x00002;
|
|
11
|
+
const FRAMEOPTION_ROWS = 0x00004;
|
|
12
|
+
const FRAMEOPTION_GROUPS = 0x00008;
|
|
13
|
+
const FRAMEOPTION_BETWEEN = 0x00010;
|
|
14
|
+
const FRAMEOPTION_START_UNBOUNDED_PRECEDING = 0x00020;
|
|
15
|
+
const FRAMEOPTION_END_UNBOUNDED_PRECEDING = 0x00040;
|
|
16
|
+
const FRAMEOPTION_START_UNBOUNDED_FOLLOWING = 0x00080;
|
|
17
|
+
const FRAMEOPTION_END_UNBOUNDED_FOLLOWING = 0x00100;
|
|
18
|
+
const FRAMEOPTION_START_CURRENT_ROW = 0x00200;
|
|
19
|
+
const FRAMEOPTION_END_CURRENT_ROW = 0x00400;
|
|
20
|
+
const FRAMEOPTION_START_OFFSET_PRECEDING = 0x00800;
|
|
21
|
+
const FRAMEOPTION_END_OFFSET_PRECEDING = 0x01000;
|
|
22
|
+
const FRAMEOPTION_START_OFFSET_FOLLOWING = 0x02000;
|
|
23
|
+
const FRAMEOPTION_END_OFFSET_FOLLOWING = 0x04000;
|
|
24
|
+
const FRAMEOPTION_EXCLUDE_CURRENT_ROW = 0x08000;
|
|
25
|
+
const FRAMEOPTION_EXCLUDE_GROUP = 0x10000;
|
|
26
|
+
const FRAMEOPTION_EXCLUDE_TIES = 0x20000;
|
|
8
27
|
/**
|
|
9
28
|
* List of real PostgreSQL built-in types as they appear in pg_catalog.pg_type.typname.
|
|
10
29
|
* These are stored in lowercase in PostgreSQL system catalogs.
|
|
@@ -103,6 +122,16 @@ function isWrappedParseResult(obj) {
|
|
|
103
122
|
* The deparser automatically detects bare ParseResult objects for backward
|
|
104
123
|
* compatibility and wraps them internally for consistent processing.
|
|
105
124
|
*/
|
|
125
|
+
function formatBitString(bsval) {
|
|
126
|
+
const quote = (value) => value.replace(/'/g, "''");
|
|
127
|
+
if (/^x[0-9A-Fa-f]+$/.test(bsval)) {
|
|
128
|
+
return `x'${bsval.substring(1)}'`;
|
|
129
|
+
}
|
|
130
|
+
if (bsval.startsWith('b')) {
|
|
131
|
+
return `b'${quote(bsval.substring(1))}'`;
|
|
132
|
+
}
|
|
133
|
+
return `b'${quote(bsval)}'`;
|
|
134
|
+
}
|
|
106
135
|
class Deparser {
|
|
107
136
|
tree;
|
|
108
137
|
options;
|
|
@@ -984,6 +1013,12 @@ class Deparser {
|
|
|
984
1013
|
output.push(context.parens(columnNames.join(', ')));
|
|
985
1014
|
}
|
|
986
1015
|
}
|
|
1016
|
+
if (node.override === 'OVERRIDING_USER_VALUE') {
|
|
1017
|
+
output.push('OVERRIDING USER VALUE');
|
|
1018
|
+
}
|
|
1019
|
+
else if (node.override === 'OVERRIDING_SYSTEM_VALUE') {
|
|
1020
|
+
output.push('OVERRIDING SYSTEM VALUE');
|
|
1021
|
+
}
|
|
987
1022
|
if (node.selectStmt) {
|
|
988
1023
|
output.push(this.visit(node.selectStmt, context));
|
|
989
1024
|
}
|
|
@@ -1060,38 +1095,8 @@ class Deparser {
|
|
|
1060
1095
|
output.push(this.RangeVar(node.relation, context));
|
|
1061
1096
|
}
|
|
1062
1097
|
output.push('SET');
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
const firstTarget = targetList[0];
|
|
1066
|
-
const processedTargets = new Set();
|
|
1067
|
-
const assignmentParts = [];
|
|
1068
|
-
for (let i = 0; i < targetList.length; i++) {
|
|
1069
|
-
if (processedTargets.has(i))
|
|
1070
|
-
continue;
|
|
1071
|
-
const target = targetList[i];
|
|
1072
|
-
const multiAssignRef = target.ResTarget?.val?.MultiAssignRef;
|
|
1073
|
-
if (multiAssignRef) {
|
|
1074
|
-
const relatedTargets = [];
|
|
1075
|
-
for (let j = i; j < targetList.length; j++) {
|
|
1076
|
-
const otherTarget = targetList[j];
|
|
1077
|
-
const otherMultiAssignRef = otherTarget.ResTarget?.val?.MultiAssignRef;
|
|
1078
|
-
if (otherMultiAssignRef &&
|
|
1079
|
-
JSON.stringify(otherMultiAssignRef.source) === JSON.stringify(multiAssignRef.source)) {
|
|
1080
|
-
relatedTargets.push(otherTarget);
|
|
1081
|
-
processedTargets.add(j);
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
const names = relatedTargets.map(t => t.ResTarget.name);
|
|
1085
|
-
const multiAssignment = `${context.parens(names.join(', '))} = ${this.visit(multiAssignRef.source, context)}`;
|
|
1086
|
-
assignmentParts.push(multiAssignment);
|
|
1087
|
-
}
|
|
1088
|
-
else {
|
|
1089
|
-
// Handle regular single-column assignment
|
|
1090
|
-
assignmentParts.push(this.visit(target, context.spawn('UpdateStmt', { update: true })));
|
|
1091
|
-
processedTargets.add(i);
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
1094
|
-
output.push(assignmentParts.join(','));
|
|
1098
|
+
if (node.targetList && node.targetList.length > 0) {
|
|
1099
|
+
output.push(this.formatUpdateAssignments(node.targetList, context));
|
|
1095
1100
|
}
|
|
1096
1101
|
if (node.fromClause) {
|
|
1097
1102
|
output.push('FROM');
|
|
@@ -1108,6 +1113,36 @@ class Deparser {
|
|
|
1108
1113
|
}
|
|
1109
1114
|
return output.join(' ');
|
|
1110
1115
|
}
|
|
1116
|
+
formatUpdateAssignments(targets, context) {
|
|
1117
|
+
const targetList = list_utils_1.ListUtils.unwrapList(targets);
|
|
1118
|
+
const processedTargets = new Set();
|
|
1119
|
+
const assignmentParts = [];
|
|
1120
|
+
for (let i = 0; i < targetList.length; i++) {
|
|
1121
|
+
if (processedTargets.has(i))
|
|
1122
|
+
continue;
|
|
1123
|
+
const target = targetList[i];
|
|
1124
|
+
const multiAssignRef = target.ResTarget?.val?.MultiAssignRef;
|
|
1125
|
+
if (multiAssignRef) {
|
|
1126
|
+
const relatedTargets = [];
|
|
1127
|
+
for (let j = i; j < targetList.length; j++) {
|
|
1128
|
+
const otherTarget = targetList[j];
|
|
1129
|
+
const otherMultiAssignRef = otherTarget.ResTarget?.val?.MultiAssignRef;
|
|
1130
|
+
if (otherMultiAssignRef &&
|
|
1131
|
+
JSON.stringify(otherMultiAssignRef.source) === JSON.stringify(multiAssignRef.source)) {
|
|
1132
|
+
relatedTargets.push(otherTarget);
|
|
1133
|
+
processedTargets.add(j);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
const names = relatedTargets.map(t => quotes_1.QuoteUtils.quoteIdentifier(t.ResTarget.name));
|
|
1137
|
+
assignmentParts.push(`${context.parens(names.join(', '))} = ${this.visit(multiAssignRef.source, context)}`);
|
|
1138
|
+
}
|
|
1139
|
+
else {
|
|
1140
|
+
assignmentParts.push(this.visit(target, context.spawn('UpdateStmt', { update: true })));
|
|
1141
|
+
processedTargets.add(i);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
return assignmentParts.join(', ');
|
|
1145
|
+
}
|
|
1111
1146
|
DeleteStmt(node, context) {
|
|
1112
1147
|
try {
|
|
1113
1148
|
const output = [];
|
|
@@ -1520,43 +1555,41 @@ class Deparser {
|
|
|
1520
1555
|
result += ` FILTER (WHERE ${this.visit(node.agg_filter, context)})`;
|
|
1521
1556
|
}
|
|
1522
1557
|
if (node.over) {
|
|
1523
|
-
|
|
1524
|
-
if (node.over.name) {
|
|
1525
|
-
result += ` OVER ${node.over.name}`;
|
|
1526
|
-
}
|
|
1527
|
-
else {
|
|
1528
|
-
const windowParts = [];
|
|
1529
|
-
if (node.over.partitionClause) {
|
|
1530
|
-
const partitions = list_utils_1.ListUtils.unwrapList(node.over.partitionClause);
|
|
1531
|
-
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
1532
|
-
windowParts.push(`PARTITION BY ${partitionStrs.join(', ')}`);
|
|
1533
|
-
}
|
|
1534
|
-
if (node.over.orderClause) {
|
|
1535
|
-
const orders = list_utils_1.ListUtils.unwrapList(node.over.orderClause);
|
|
1536
|
-
const orderStrs = orders.map(o => this.visit(o, context));
|
|
1537
|
-
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
1538
|
-
}
|
|
1539
|
-
// Handle window frame specifications using the dedicated formatWindowFrame method
|
|
1540
|
-
const frameClause = this.formatWindowFrame(node.over, context.spawn('FuncCall'));
|
|
1541
|
-
if (frameClause) {
|
|
1542
|
-
windowParts.push(frameClause);
|
|
1543
|
-
}
|
|
1544
|
-
if (windowParts.length > 0) {
|
|
1545
|
-
if (context.isPretty() && windowParts.length > 1) {
|
|
1546
|
-
const formattedParts = windowParts.map(part => context.indent(part));
|
|
1547
|
-
result += ` OVER (${context.newline()}${formattedParts.join(context.newline())}${context.newline()})`;
|
|
1548
|
-
}
|
|
1549
|
-
else {
|
|
1550
|
-
result += ` OVER (${windowParts.join(' ')})`;
|
|
1551
|
-
}
|
|
1552
|
-
}
|
|
1553
|
-
else {
|
|
1554
|
-
result += ` OVER ()`;
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1558
|
+
result += this.formatOverClause(node.over, context);
|
|
1557
1559
|
}
|
|
1558
1560
|
return result;
|
|
1559
1561
|
}
|
|
1562
|
+
formatOverClause(over, context) {
|
|
1563
|
+
if (over.name) {
|
|
1564
|
+
return ` OVER ${over.name}`;
|
|
1565
|
+
}
|
|
1566
|
+
const windowParts = [];
|
|
1567
|
+
if (over.refname) {
|
|
1568
|
+
windowParts.push(over.refname);
|
|
1569
|
+
}
|
|
1570
|
+
if (over.partitionClause) {
|
|
1571
|
+
const partitions = list_utils_1.ListUtils.unwrapList(over.partitionClause);
|
|
1572
|
+
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
1573
|
+
windowParts.push(`PARTITION BY ${partitionStrs.join(', ')}`);
|
|
1574
|
+
}
|
|
1575
|
+
if (over.orderClause) {
|
|
1576
|
+
const orders = list_utils_1.ListUtils.unwrapList(over.orderClause);
|
|
1577
|
+
const orderStrs = orders.map(o => this.visit(o, context));
|
|
1578
|
+
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
1579
|
+
}
|
|
1580
|
+
const frameClause = this.formatWindowFrame(over, context.spawn('FuncCall'));
|
|
1581
|
+
if (frameClause) {
|
|
1582
|
+
windowParts.push(frameClause);
|
|
1583
|
+
}
|
|
1584
|
+
if (windowParts.length === 0) {
|
|
1585
|
+
return ' OVER ()';
|
|
1586
|
+
}
|
|
1587
|
+
if (context.isPretty() && windowParts.length > 1) {
|
|
1588
|
+
const formattedParts = windowParts.map(part => context.indent(part));
|
|
1589
|
+
return ` OVER (${context.newline()}${formattedParts.join(context.newline())}${context.newline()})`;
|
|
1590
|
+
}
|
|
1591
|
+
return ` OVER (${windowParts.join(' ')})`;
|
|
1592
|
+
}
|
|
1560
1593
|
FuncExpr(node, context) {
|
|
1561
1594
|
const funcName = `func_${node.funcid}`;
|
|
1562
1595
|
const args = node.args ? list_utils_1.ListUtils.unwrapList(node.args).map(arg => this.visit(arg, context)).join(', ') : '';
|
|
@@ -1646,15 +1679,7 @@ class Deparser {
|
|
|
1646
1679
|
else if (nodeAny.bsval !== undefined) {
|
|
1647
1680
|
if (typeof nodeAny.bsval === 'object' && nodeAny.bsval !== null) {
|
|
1648
1681
|
if (nodeAny.bsval.bsval !== undefined) {
|
|
1649
|
-
|
|
1650
|
-
// Check if this is a hexadecimal bit string (starts with x and contains only hex digits)
|
|
1651
|
-
if (bsval.startsWith('x') && /^x[0-9A-Fa-f]+$/.test(bsval)) {
|
|
1652
|
-
return `x'${bsval.substring(1)}'`;
|
|
1653
|
-
}
|
|
1654
|
-
if (bsval.startsWith('b')) {
|
|
1655
|
-
return `b'${bsval.substring(1)}'`;
|
|
1656
|
-
}
|
|
1657
|
-
return `b'${bsval}'`;
|
|
1682
|
+
return formatBitString(nodeAny.bsval.bsval);
|
|
1658
1683
|
}
|
|
1659
1684
|
else if (Object.keys(nodeAny.bsval).length === 0) {
|
|
1660
1685
|
return "''";
|
|
@@ -1667,15 +1692,7 @@ class Deparser {
|
|
|
1667
1692
|
return 'NULL';
|
|
1668
1693
|
}
|
|
1669
1694
|
else {
|
|
1670
|
-
|
|
1671
|
-
// Check if this is a hexadecimal bit string (starts with x and contains only hex digits)
|
|
1672
|
-
if (bsval.startsWith('x') && /^x[0-9A-Fa-f]+$/.test(bsval)) {
|
|
1673
|
-
return `x'${bsval.substring(1)}'`;
|
|
1674
|
-
}
|
|
1675
|
-
if (bsval.startsWith('b')) {
|
|
1676
|
-
return `b'${bsval.substring(1)}'`;
|
|
1677
|
-
}
|
|
1678
|
-
return `b'${bsval}'`;
|
|
1695
|
+
return formatBitString(nodeAny.bsval);
|
|
1679
1696
|
}
|
|
1680
1697
|
}
|
|
1681
1698
|
if (nodeAny.val) {
|
|
@@ -1692,7 +1709,7 @@ class Deparser {
|
|
|
1692
1709
|
return nodeAny.val.Boolean.boolval ? 'true' : 'false';
|
|
1693
1710
|
}
|
|
1694
1711
|
else if (nodeAny.val.BitString?.bsval !== undefined) {
|
|
1695
|
-
return nodeAny.val.BitString.bsval;
|
|
1712
|
+
return formatBitString(nodeAny.val.BitString.bsval);
|
|
1696
1713
|
}
|
|
1697
1714
|
}
|
|
1698
1715
|
if (nodeAny.isnull === true) {
|
|
@@ -2372,15 +2389,7 @@ class Deparser {
|
|
|
2372
2389
|
return node.boolval ? 'true' : 'false';
|
|
2373
2390
|
}
|
|
2374
2391
|
BitString(node, context) {
|
|
2375
|
-
|
|
2376
|
-
if (node.bsval.startsWith('x')) {
|
|
2377
|
-
return `x'${node.bsval.substring(1)}'`;
|
|
2378
|
-
}
|
|
2379
|
-
if (node.bsval.startsWith('b')) {
|
|
2380
|
-
return `b'${node.bsval.substring(1)}'`;
|
|
2381
|
-
}
|
|
2382
|
-
// Fallback for raw values without prefix
|
|
2383
|
-
return `b'${node.bsval}'`;
|
|
2392
|
+
return formatBitString(node.bsval);
|
|
2384
2393
|
}
|
|
2385
2394
|
Null(node, context) {
|
|
2386
2395
|
return 'NULL';
|
|
@@ -2419,7 +2428,7 @@ class Deparser {
|
|
|
2419
2428
|
output.push(context.parens(elementStrs.join(', ')));
|
|
2420
2429
|
}
|
|
2421
2430
|
}
|
|
2422
|
-
else if (node.tableElts) {
|
|
2431
|
+
else if (node.tableElts && !node.partbound) {
|
|
2423
2432
|
const elements = list_utils_1.ListUtils.unwrapList(node.tableElts);
|
|
2424
2433
|
const elementStrs = elements.map(el => {
|
|
2425
2434
|
return this.deparse(el, context.spawn('CreateStmt'));
|
|
@@ -2447,7 +2456,16 @@ class Deparser {
|
|
|
2447
2456
|
const inherits = list_utils_1.ListUtils.unwrapList(node.inhRelations);
|
|
2448
2457
|
const inheritStrs = inherits.map(rel => this.visit(rel, context));
|
|
2449
2458
|
output.push(inheritStrs[0]);
|
|
2450
|
-
if (node.
|
|
2459
|
+
if (node.tableElts) {
|
|
2460
|
+
const elementStrs = list_utils_1.ListUtils.unwrapList(node.tableElts).map(el => {
|
|
2461
|
+
return this.deparse(el, context.spawn('CreateStmt'));
|
|
2462
|
+
});
|
|
2463
|
+
output.push(context.parens(elementStrs.join(', ')));
|
|
2464
|
+
}
|
|
2465
|
+
if (node.partbound.is_default) {
|
|
2466
|
+
output.push('DEFAULT');
|
|
2467
|
+
}
|
|
2468
|
+
else if (node.partbound.strategy === 'l' && node.partbound.listdatums) {
|
|
2451
2469
|
output.push('FOR VALUES IN');
|
|
2452
2470
|
const listValues = list_utils_1.ListUtils.unwrapList(node.partbound.listdatums)
|
|
2453
2471
|
.map(datum => this.visit(datum, context))
|
|
@@ -2470,13 +2488,9 @@ class Deparser {
|
|
|
2470
2488
|
output.push(`(${upperValues})`);
|
|
2471
2489
|
}
|
|
2472
2490
|
}
|
|
2473
|
-
else if (node.partbound.strategy === 'h'
|
|
2491
|
+
else if (node.partbound.strategy === 'h') {
|
|
2474
2492
|
output.push('FOR VALUES WITH');
|
|
2475
|
-
|
|
2476
|
-
output.push(`(MODULUS ${node.partbound.modulus}, REMAINDER ${remainder})`);
|
|
2477
|
-
}
|
|
2478
|
-
else if (node.partbound.is_default) {
|
|
2479
|
-
output.push('DEFAULT');
|
|
2493
|
+
output.push(`(MODULUS ${node.partbound.modulus ?? 0}, REMAINDER ${node.partbound.remainder ?? 0})`);
|
|
2480
2494
|
}
|
|
2481
2495
|
}
|
|
2482
2496
|
else if (node.inhRelations) {
|
|
@@ -2542,6 +2556,12 @@ class Deparser {
|
|
|
2542
2556
|
if (node.typeName) {
|
|
2543
2557
|
output.push(this.TypeName(node.typeName, context));
|
|
2544
2558
|
}
|
|
2559
|
+
if (node.storage_name) {
|
|
2560
|
+
output.push('STORAGE', node.storage_name.toUpperCase());
|
|
2561
|
+
}
|
|
2562
|
+
if (node.compression) {
|
|
2563
|
+
output.push('COMPRESSION', quotes_1.QuoteUtils.quoteIdentifier(node.compression));
|
|
2564
|
+
}
|
|
2545
2565
|
if (node.fdwoptions && node.fdwoptions.length > 0) {
|
|
2546
2566
|
output.push('OPTIONS');
|
|
2547
2567
|
const columnContext = context.spawn('ColumnDef');
|
|
@@ -2602,7 +2622,8 @@ class Deparser {
|
|
|
2602
2622
|
case 'CONSTR_DEFAULT':
|
|
2603
2623
|
output.push('DEFAULT');
|
|
2604
2624
|
if (node.raw_expr) {
|
|
2605
|
-
|
|
2625
|
+
const defaultExpr = this.visit(node.raw_expr, context);
|
|
2626
|
+
output.push(this.needsBExprParens(node.raw_expr) ? `(${defaultExpr})` : defaultExpr);
|
|
2606
2627
|
}
|
|
2607
2628
|
break;
|
|
2608
2629
|
case 'CONSTR_CHECK':
|
|
@@ -2966,7 +2987,7 @@ class Deparser {
|
|
|
2966
2987
|
break;
|
|
2967
2988
|
}
|
|
2968
2989
|
// Handle deferrable constraints for all constraint types that support it
|
|
2969
|
-
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN') {
|
|
2990
|
+
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN' || node.contype === 'CONSTR_EXCLUSION') {
|
|
2970
2991
|
if (node.deferrable) {
|
|
2971
2992
|
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2972
2993
|
output.push('\n' + context.indent('DEFERRABLE'));
|
|
@@ -2995,6 +3016,9 @@ class Deparser {
|
|
|
2995
3016
|
output.push('NOT DEFERRABLE');
|
|
2996
3017
|
}
|
|
2997
3018
|
}
|
|
3019
|
+
else if (node.initdeferred) {
|
|
3020
|
+
output.push('INITIALLY DEFERRED');
|
|
3021
|
+
}
|
|
2998
3022
|
}
|
|
2999
3023
|
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
3000
3024
|
let result = '';
|
|
@@ -3060,6 +3084,9 @@ class Deparser {
|
|
|
3060
3084
|
output.push(node.name);
|
|
3061
3085
|
}
|
|
3062
3086
|
const windowParts = [];
|
|
3087
|
+
if (node.refname) {
|
|
3088
|
+
windowParts.push(node.refname);
|
|
3089
|
+
}
|
|
3063
3090
|
if (node.partitionClause) {
|
|
3064
3091
|
const partitions = list_utils_1.ListUtils.unwrapList(node.partitionClause);
|
|
3065
3092
|
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
@@ -3070,12 +3097,9 @@ class Deparser {
|
|
|
3070
3097
|
const orderStrs = orders.map(o => this.visit(o, context));
|
|
3071
3098
|
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
3072
3099
|
}
|
|
3073
|
-
|
|
3074
|
-
if (
|
|
3075
|
-
|
|
3076
|
-
if (frameClause) {
|
|
3077
|
-
windowParts.push(frameClause);
|
|
3078
|
-
}
|
|
3100
|
+
const frameClause = this.formatWindowFrame(node, context.spawn('WindowDef'));
|
|
3101
|
+
if (frameClause) {
|
|
3102
|
+
windowParts.push(frameClause);
|
|
3079
3103
|
}
|
|
3080
3104
|
if (windowParts.length > 0) {
|
|
3081
3105
|
if (node.name) {
|
|
@@ -3092,114 +3116,96 @@ class Deparser {
|
|
|
3092
3116
|
}
|
|
3093
3117
|
return output.join(' ');
|
|
3094
3118
|
}
|
|
3119
|
+
formatIdentityColumnOptions(def, context) {
|
|
3120
|
+
const seqContext = context.spawn('AlterSeqStmt');
|
|
3121
|
+
return list_utils_1.ListUtils.unwrapList(def).map(item => {
|
|
3122
|
+
const el = item.DefElem;
|
|
3123
|
+
if (!el)
|
|
3124
|
+
return this.visit(item, context);
|
|
3125
|
+
if (el.defname === 'generated') {
|
|
3126
|
+
const ival = el.arg?.Integer?.ival ?? 0;
|
|
3127
|
+
return ival === 97 ? 'SET GENERATED ALWAYS' : 'SET GENERATED BY DEFAULT';
|
|
3128
|
+
}
|
|
3129
|
+
if (el.defname === 'restart') {
|
|
3130
|
+
return el.arg ? `RESTART WITH ${this.visit(el.arg, context)}` : 'RESTART';
|
|
3131
|
+
}
|
|
3132
|
+
return `SET ${this.visit(item, seqContext)}`;
|
|
3133
|
+
}).join(' ');
|
|
3134
|
+
}
|
|
3135
|
+
// b_expr (used by DEFAULT) excludes IN/LIKE/BETWEEN and boolean operators.
|
|
3136
|
+
needsBExprParens(node) {
|
|
3137
|
+
const nodeType = this.getNodeType(node);
|
|
3138
|
+
if (nodeType === 'BoolExpr')
|
|
3139
|
+
return true;
|
|
3140
|
+
if (nodeType === 'A_Expr') {
|
|
3141
|
+
const kind = this.getNodeData(node).kind;
|
|
3142
|
+
return kind !== 'AEXPR_OP' && kind !== 'AEXPR_DISTINCT' && kind !== 'AEXPR_NOT_DISTINCT';
|
|
3143
|
+
}
|
|
3144
|
+
return false;
|
|
3145
|
+
}
|
|
3095
3146
|
formatWindowFrame(node, context) {
|
|
3096
|
-
if (!node.frameOptions)
|
|
3147
|
+
if (!node.frameOptions || !(node.frameOptions & FRAMEOPTION_NONDEFAULT))
|
|
3097
3148
|
return null;
|
|
3098
3149
|
const frameOptions = node.frameOptions;
|
|
3099
|
-
const EXCLUDE_MASK = 0x8000 | 0x10000 | 0x20000;
|
|
3100
|
-
const baseFrameOptions = frameOptions & ~EXCLUDE_MASK;
|
|
3101
3150
|
const frameParts = [];
|
|
3102
|
-
if (frameOptions &
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
frameParts.push('GROUPS');
|
|
3111
|
-
}
|
|
3151
|
+
if (frameOptions & FRAMEOPTION_RANGE) {
|
|
3152
|
+
frameParts.push('RANGE');
|
|
3153
|
+
}
|
|
3154
|
+
else if (frameOptions & FRAMEOPTION_ROWS) {
|
|
3155
|
+
frameParts.push('ROWS');
|
|
3156
|
+
}
|
|
3157
|
+
else if (frameOptions & FRAMEOPTION_GROUPS) {
|
|
3158
|
+
frameParts.push('GROUPS');
|
|
3112
3159
|
}
|
|
3113
3160
|
if (frameParts.length === 0)
|
|
3114
3161
|
return null;
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
boundsParts.push('CURRENT ROW');
|
|
3119
|
-
boundsParts.push('AND UNBOUNDED FOLLOWING');
|
|
3162
|
+
let start = null;
|
|
3163
|
+
if (frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) {
|
|
3164
|
+
start = 'UNBOUNDED PRECEDING';
|
|
3120
3165
|
}
|
|
3121
|
-
else if (
|
|
3122
|
-
|
|
3123
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3166
|
+
else if (frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) {
|
|
3167
|
+
start = 'UNBOUNDED FOLLOWING';
|
|
3124
3168
|
}
|
|
3125
|
-
else if (
|
|
3126
|
-
|
|
3127
|
-
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
|
|
3128
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3129
|
-
}
|
|
3169
|
+
else if (frameOptions & FRAMEOPTION_START_CURRENT_ROW) {
|
|
3170
|
+
start = 'CURRENT ROW';
|
|
3130
3171
|
}
|
|
3131
|
-
else if (
|
|
3132
|
-
|
|
3133
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3172
|
+
else if (frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING && node.startOffset) {
|
|
3173
|
+
start = `${this.visit(node.startOffset, context)} PRECEDING`;
|
|
3134
3174
|
}
|
|
3135
|
-
else if (
|
|
3136
|
-
|
|
3137
|
-
if (node.endOffset) {
|
|
3138
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3139
|
-
}
|
|
3175
|
+
else if (frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING && node.startOffset) {
|
|
3176
|
+
start = `${this.visit(node.startOffset, context)} FOLLOWING`;
|
|
3140
3177
|
}
|
|
3141
|
-
|
|
3142
|
-
|
|
3178
|
+
let end = null;
|
|
3179
|
+
if (frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING) {
|
|
3180
|
+
end = 'UNBOUNDED PRECEDING';
|
|
3143
3181
|
}
|
|
3144
|
-
else {
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
}
|
|
3160
|
-
else if (frameOptions & 0x20) { // FRAMEOPTION_START_CURRENT_ROW
|
|
3161
|
-
boundsParts.push('CURRENT ROW');
|
|
3162
|
-
}
|
|
3163
|
-
// Handle end bound - prioritize explicit offset values over bit flags
|
|
3164
|
-
if (node.endOffset) {
|
|
3165
|
-
if (boundsParts.length > 0) {
|
|
3166
|
-
if (frameOptions & 0x1000) { // FRAMEOPTION_END_VALUE_PRECEDING
|
|
3167
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} PRECEDING`);
|
|
3168
|
-
}
|
|
3169
|
-
else if (frameOptions & 0x2000) { // FRAMEOPTION_END_VALUE_FOLLOWING
|
|
3170
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3171
|
-
}
|
|
3172
|
-
else {
|
|
3173
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3174
|
-
}
|
|
3175
|
-
}
|
|
3176
|
-
}
|
|
3177
|
-
else if (frameOptions & 0x80) { // FRAMEOPTION_END_UNBOUNDED_FOLLOWING
|
|
3178
|
-
if (boundsParts.length > 0) {
|
|
3179
|
-
boundsParts.push('AND UNBOUNDED FOLLOWING');
|
|
3180
|
-
}
|
|
3181
|
-
}
|
|
3182
|
-
else if (frameOptions & 0x100) { // FRAMEOPTION_END_CURRENT_ROW
|
|
3183
|
-
if (boundsParts.length > 0) {
|
|
3184
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3185
|
-
}
|
|
3182
|
+
else if (frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING) {
|
|
3183
|
+
end = 'UNBOUNDED FOLLOWING';
|
|
3184
|
+
}
|
|
3185
|
+
else if (frameOptions & FRAMEOPTION_END_CURRENT_ROW) {
|
|
3186
|
+
end = 'CURRENT ROW';
|
|
3187
|
+
}
|
|
3188
|
+
else if (frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING && node.endOffset) {
|
|
3189
|
+
end = `${this.visit(node.endOffset, context)} PRECEDING`;
|
|
3190
|
+
}
|
|
3191
|
+
else if (frameOptions & FRAMEOPTION_END_OFFSET_FOLLOWING && node.endOffset) {
|
|
3192
|
+
end = `${this.visit(node.endOffset, context)} FOLLOWING`;
|
|
3193
|
+
}
|
|
3194
|
+
if (start) {
|
|
3195
|
+
if (frameOptions & FRAMEOPTION_BETWEEN) {
|
|
3196
|
+
frameParts.push(`BETWEEN ${start} AND ${end ?? 'CURRENT ROW'}`);
|
|
3186
3197
|
}
|
|
3187
|
-
else
|
|
3188
|
-
|
|
3198
|
+
else {
|
|
3199
|
+
frameParts.push(start);
|
|
3189
3200
|
}
|
|
3190
3201
|
}
|
|
3191
|
-
if (
|
|
3192
|
-
frameParts.push('BETWEEN');
|
|
3193
|
-
frameParts.push(boundsParts.join(' '));
|
|
3194
|
-
}
|
|
3195
|
-
// EXCLUDE clause
|
|
3196
|
-
if (frameOptions & 0x8000) { // FRAMEOPTION_EXCLUDE_CURRENT_ROW
|
|
3202
|
+
if (frameOptions & FRAMEOPTION_EXCLUDE_CURRENT_ROW) {
|
|
3197
3203
|
frameParts.push('EXCLUDE CURRENT ROW');
|
|
3198
3204
|
}
|
|
3199
|
-
else if (frameOptions &
|
|
3205
|
+
else if (frameOptions & FRAMEOPTION_EXCLUDE_GROUP) {
|
|
3200
3206
|
frameParts.push('EXCLUDE GROUP');
|
|
3201
3207
|
}
|
|
3202
|
-
else if (frameOptions &
|
|
3208
|
+
else if (frameOptions & FRAMEOPTION_EXCLUDE_TIES) {
|
|
3203
3209
|
frameParts.push('EXCLUDE TIES');
|
|
3204
3210
|
}
|
|
3205
3211
|
return frameParts.join(' ');
|
|
@@ -3278,8 +3284,35 @@ class Deparser {
|
|
|
3278
3284
|
if (node.ctequery) {
|
|
3279
3285
|
output.push(context.parens(this.visit(node.ctequery, context)));
|
|
3280
3286
|
}
|
|
3287
|
+
if (node.search_clause) {
|
|
3288
|
+
const sc = node.search_clause;
|
|
3289
|
+
const cols = list_utils_1.ListUtils.unwrapList(sc.search_col_list).map(c => this.visit(c, context));
|
|
3290
|
+
output.push('SEARCH', sc.search_breadth_first ? 'BREADTH' : 'DEPTH', 'FIRST BY');
|
|
3291
|
+
output.push(cols.join(', '));
|
|
3292
|
+
output.push('SET', quotes_1.QuoteUtils.quoteIdentifier(sc.search_seq_column));
|
|
3293
|
+
}
|
|
3294
|
+
if (node.cycle_clause) {
|
|
3295
|
+
const cc = node.cycle_clause;
|
|
3296
|
+
const cols = list_utils_1.ListUtils.unwrapList(cc.cycle_col_list).map(c => this.visit(c, context));
|
|
3297
|
+
output.push('CYCLE', cols.join(', '));
|
|
3298
|
+
output.push('SET', quotes_1.QuoteUtils.quoteIdentifier(cc.cycle_mark_column));
|
|
3299
|
+
if (cc.cycle_mark_value && cc.cycle_mark_default) {
|
|
3300
|
+
output.push('TO', this.formatAexprConst(cc.cycle_mark_value, context));
|
|
3301
|
+
output.push('DEFAULT', this.formatAexprConst(cc.cycle_mark_default, context));
|
|
3302
|
+
}
|
|
3303
|
+
output.push('USING', quotes_1.QuoteUtils.quoteIdentifier(cc.cycle_path_column));
|
|
3304
|
+
}
|
|
3281
3305
|
return output.join(' ');
|
|
3282
3306
|
}
|
|
3307
|
+
// Renders a constant in the restricted AexprConst grammar (e.g. `point '(1,1)'`
|
|
3308
|
+
// rather than `CAST('(1,1)' AS point)`).
|
|
3309
|
+
formatAexprConst(node, context) {
|
|
3310
|
+
const cast = node.TypeCast;
|
|
3311
|
+
if (cast?.arg?.A_Const?.sval && cast.typeName) {
|
|
3312
|
+
return `${this.TypeName(cast.typeName, context)} ${this.visit(cast.arg, context)}`;
|
|
3313
|
+
}
|
|
3314
|
+
return this.visit(node, context);
|
|
3315
|
+
}
|
|
3283
3316
|
ParamRef(node, context) {
|
|
3284
3317
|
return `$${node.number}`;
|
|
3285
3318
|
}
|
|
@@ -3669,9 +3702,9 @@ class Deparser {
|
|
|
3669
3702
|
output.push(`(${upperValues})`);
|
|
3670
3703
|
}
|
|
3671
3704
|
}
|
|
3672
|
-
else if (node.bound.strategy === 'h'
|
|
3705
|
+
else if (node.bound.strategy === 'h') {
|
|
3673
3706
|
output.push('FOR VALUES WITH');
|
|
3674
|
-
output.push(`(MODULUS ${node.bound.modulus}, REMAINDER ${node.bound.remainder ?? 0})`);
|
|
3707
|
+
output.push(`(MODULUS ${node.bound.modulus ?? 0}, REMAINDER ${node.bound.remainder ?? 0})`);
|
|
3675
3708
|
}
|
|
3676
3709
|
else if (node.bound.is_default) {
|
|
3677
3710
|
output.push('DEFAULT');
|
|
@@ -4524,10 +4557,10 @@ class Deparser {
|
|
|
4524
4557
|
output.push('PROGRAM');
|
|
4525
4558
|
}
|
|
4526
4559
|
if (node.filename) {
|
|
4527
|
-
output.push(
|
|
4560
|
+
output.push(quotes_1.QuoteUtils.escape(node.filename));
|
|
4528
4561
|
}
|
|
4529
4562
|
else {
|
|
4530
|
-
output.push('STDIN');
|
|
4563
|
+
output.push(node.is_from ? 'STDIN' : 'STDOUT');
|
|
4531
4564
|
}
|
|
4532
4565
|
if (node.options && node.options.length > 0) {
|
|
4533
4566
|
output.push('WITH');
|
|
@@ -4759,6 +4792,9 @@ class Deparser {
|
|
|
4759
4792
|
const nodeData = this.getNodeData(node.def);
|
|
4760
4793
|
if (nodeData && nodeData.typeName) {
|
|
4761
4794
|
output.push(this.TypeName(nodeData.typeName, context));
|
|
4795
|
+
if (nodeData.collClause) {
|
|
4796
|
+
output.push(this.CollateClause(nodeData.collClause, context));
|
|
4797
|
+
}
|
|
4762
4798
|
// Handle USING clause (stored in raw_default for ALTER COLUMN TYPE)
|
|
4763
4799
|
if (nodeData.raw_default) {
|
|
4764
4800
|
output.push('USING');
|
|
@@ -5239,9 +5275,8 @@ class Deparser {
|
|
|
5239
5275
|
if (node.name) {
|
|
5240
5276
|
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5241
5277
|
}
|
|
5242
|
-
output.push('SET');
|
|
5243
5278
|
if (node.def) {
|
|
5244
|
-
output.push(this.
|
|
5279
|
+
output.push(this.formatIdentityColumnOptions(node.def, context));
|
|
5245
5280
|
}
|
|
5246
5281
|
break;
|
|
5247
5282
|
case 'AT_DropIdentity':
|
|
@@ -5250,11 +5285,8 @@ class Deparser {
|
|
|
5250
5285
|
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.name));
|
|
5251
5286
|
}
|
|
5252
5287
|
output.push('DROP IDENTITY');
|
|
5253
|
-
if (node.
|
|
5254
|
-
output.push('
|
|
5255
|
-
}
|
|
5256
|
-
else if (node.behavior === 'DROP_RESTRICT') {
|
|
5257
|
-
output.push('RESTRICT');
|
|
5288
|
+
if (node.missing_ok) {
|
|
5289
|
+
output.push('IF EXISTS');
|
|
5258
5290
|
}
|
|
5259
5291
|
break;
|
|
5260
5292
|
case 'AT_ReAddStatistics':
|
|
@@ -5690,6 +5722,9 @@ class Deparser {
|
|
|
5690
5722
|
if (node.arg && this.getNodeType(node.arg) === 'List') {
|
|
5691
5723
|
const listData = this.getNodeData(node.arg);
|
|
5692
5724
|
const listItems = list_utils_1.ListUtils.unwrapList(listData.items);
|
|
5725
|
+
if (listItems.length === 1 && listItems[0].String?.sval === 'none') {
|
|
5726
|
+
return 'OWNED BY NONE';
|
|
5727
|
+
}
|
|
5693
5728
|
const parts = listItems.map(item => {
|
|
5694
5729
|
const itemData = this.getNodeData(item);
|
|
5695
5730
|
if (this.getNodeType(item) === 'String') {
|
|
@@ -5867,12 +5902,15 @@ class Deparser {
|
|
|
5867
5902
|
}
|
|
5868
5903
|
// Handle CreateStmt table options - no quotes, compact formatting
|
|
5869
5904
|
if (context.parentNodeTypes.includes('CreateStmt')) {
|
|
5905
|
+
const relOptName = node.defnamespace
|
|
5906
|
+
? `${quotes_1.QuoteUtils.quoteIdentifier(node.defnamespace)}.${quotes_1.QuoteUtils.quoteIdentifier(node.defname)}`
|
|
5907
|
+
: quotes_1.QuoteUtils.quoteIdentifier(node.defname);
|
|
5870
5908
|
// For numeric values, use the raw value without quotes
|
|
5871
5909
|
if (node.arg && this.getNodeType(node.arg) === 'Integer') {
|
|
5872
5910
|
const integerData = this.getNodeData(node.arg);
|
|
5873
|
-
return `${
|
|
5911
|
+
return `${relOptName}=${integerData.ival}`;
|
|
5874
5912
|
}
|
|
5875
|
-
return `${
|
|
5913
|
+
return `${relOptName}=${argValue}`;
|
|
5876
5914
|
}
|
|
5877
5915
|
// Handle CreateEventTrigStmt WHEN clause - use IN syntax for List arguments
|
|
5878
5916
|
if (context.parentNodeTypes.includes('CreateEventTrigStmt')) {
|
|
@@ -5911,15 +5949,27 @@ class Deparser {
|
|
|
5911
5949
|
}
|
|
5912
5950
|
// Handle CopyStmt WITH clause options - uppercase format without quotes
|
|
5913
5951
|
if (context.parentNodeTypes.includes('CopyStmt')) {
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
return
|
|
5952
|
+
const optName = node.defname.toUpperCase();
|
|
5953
|
+
if (!node.arg) {
|
|
5954
|
+
return optName;
|
|
5955
|
+
}
|
|
5956
|
+
const copyArgType = this.getNodeType(node.arg);
|
|
5957
|
+
if (copyArgType === 'Boolean' && this.getNodeData(node.arg).boolval !== false) {
|
|
5958
|
+
return optName;
|
|
5959
|
+
}
|
|
5960
|
+
if (copyArgType === 'List') {
|
|
5961
|
+
const items = list_utils_1.ListUtils.unwrapList(this.getNodeData(node.arg).items)
|
|
5962
|
+
.map(item => this.visit(item, context));
|
|
5963
|
+
return `${optName} (${items.join(', ')})`;
|
|
5917
5964
|
}
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5965
|
+
if (copyArgType === 'String') {
|
|
5966
|
+
const sval = this.getNodeData(node.arg).sval;
|
|
5967
|
+
if (node.defname === 'format') {
|
|
5968
|
+
return `${optName} ${sval}`;
|
|
5969
|
+
}
|
|
5970
|
+
return `${optName} ${quotes_1.QuoteUtils.escape(sval)}`;
|
|
5921
5971
|
}
|
|
5922
|
-
return
|
|
5972
|
+
return `${optName} ${argValue}`;
|
|
5923
5973
|
}
|
|
5924
5974
|
// Handle CREATE OPERATOR and CREATE TYPE context
|
|
5925
5975
|
if (context.parentNodeTypes.includes('DefineStmt')) {
|
|
@@ -6000,6 +6050,10 @@ class Deparser {
|
|
|
6000
6050
|
return `${node.defname} = ${argValue}`;
|
|
6001
6051
|
}
|
|
6002
6052
|
}
|
|
6053
|
+
const argType = this.getNodeType(node.arg);
|
|
6054
|
+
if (argType === 'TypeName' || argType === 'Integer' || argType === 'Float' || argType === 'Boolean') {
|
|
6055
|
+
return `${node.defname} = ${argValue}`;
|
|
6056
|
+
}
|
|
6003
6057
|
const quotedValue = typeof argValue === 'string'
|
|
6004
6058
|
? quotes_1.QuoteUtils.escape(argValue)
|
|
6005
6059
|
: argValue;
|
|
@@ -6433,6 +6487,9 @@ class Deparser {
|
|
|
6433
6487
|
case 'OBJECT_TABCONSTRAINT':
|
|
6434
6488
|
output.push('CONSTRAINT');
|
|
6435
6489
|
break;
|
|
6490
|
+
case 'OBJECT_DOMCONSTRAINT':
|
|
6491
|
+
output.push('CONSTRAINT');
|
|
6492
|
+
break;
|
|
6436
6493
|
case 'OBJECT_TRIGGER':
|
|
6437
6494
|
output.push('TRIGGER');
|
|
6438
6495
|
break;
|
|
@@ -6509,6 +6566,15 @@ class Deparser {
|
|
|
6509
6566
|
output.push(objectParts.join('.'));
|
|
6510
6567
|
}
|
|
6511
6568
|
}
|
|
6569
|
+
else if (node.objtype === 'OBJECT_DOMCONSTRAINT') {
|
|
6570
|
+
if (objectParts.length === 2) {
|
|
6571
|
+
const [domain, constraint] = objectParts;
|
|
6572
|
+
output.push(constraint, 'ON DOMAIN', domain);
|
|
6573
|
+
}
|
|
6574
|
+
else {
|
|
6575
|
+
output.push(objectParts.join('.'));
|
|
6576
|
+
}
|
|
6577
|
+
}
|
|
6512
6578
|
else if (node.objtype === 'OBJECT_TRIGGER') {
|
|
6513
6579
|
if (objectParts.length === 2) {
|
|
6514
6580
|
const [table, trigger] = objectParts;
|
|
@@ -6840,7 +6906,7 @@ class Deparser {
|
|
|
6840
6906
|
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.pubname));
|
|
6841
6907
|
}
|
|
6842
6908
|
if (node.pubobjects && node.pubobjects.length > 0) {
|
|
6843
|
-
output.push('FOR'
|
|
6909
|
+
output.push('FOR');
|
|
6844
6910
|
const tables = list_utils_1.ListUtils.unwrapList(node.pubobjects).map(table => this.visit(table, context));
|
|
6845
6911
|
output.push(tables.join(', '));
|
|
6846
6912
|
}
|
|
@@ -6880,8 +6946,9 @@ class Deparser {
|
|
|
6880
6946
|
if (node.pubname) {
|
|
6881
6947
|
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.pubname));
|
|
6882
6948
|
}
|
|
6883
|
-
|
|
6884
|
-
|
|
6949
|
+
const hasObjects = node.pubobjects && node.pubobjects.length > 0;
|
|
6950
|
+
if (hasObjects) {
|
|
6951
|
+
switch (node.action || 'AP_AddObjects') {
|
|
6885
6952
|
case 'AP_AddObjects':
|
|
6886
6953
|
output.push('ADD');
|
|
6887
6954
|
break;
|
|
@@ -6894,17 +6961,11 @@ class Deparser {
|
|
|
6894
6961
|
default:
|
|
6895
6962
|
throw new Error(`Unsupported AlterPublicationStmt action: ${node.action}`);
|
|
6896
6963
|
}
|
|
6897
|
-
}
|
|
6898
|
-
if (node.for_all_tables) {
|
|
6899
|
-
output.push('FOR ALL TABLES');
|
|
6900
|
-
}
|
|
6901
|
-
else if (node.pubobjects && node.pubobjects.length > 0) {
|
|
6902
|
-
output.push('FOR TABLE');
|
|
6903
6964
|
const objects = list_utils_1.ListUtils.unwrapList(node.pubobjects).map(obj => this.visit(obj, context));
|
|
6904
6965
|
output.push(objects.join(', '));
|
|
6905
6966
|
}
|
|
6906
|
-
if (node.options && node.options.length > 0) {
|
|
6907
|
-
output.push('
|
|
6967
|
+
else if (node.options && node.options.length > 0) {
|
|
6968
|
+
output.push('SET');
|
|
6908
6969
|
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context));
|
|
6909
6970
|
output.push(`(${options.join(', ')})`);
|
|
6910
6971
|
}
|
|
@@ -6915,42 +6976,67 @@ class Deparser {
|
|
|
6915
6976
|
if (node.subname) {
|
|
6916
6977
|
output.push(quotes_1.QuoteUtils.quoteIdentifier(node.subname));
|
|
6917
6978
|
}
|
|
6918
|
-
|
|
6919
|
-
|
|
6979
|
+
const options = node.options && node.options.length > 0
|
|
6980
|
+
? `(${list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context)).join(', ')})`
|
|
6981
|
+
: null;
|
|
6982
|
+
const publications = node.publication && node.publication.length > 0
|
|
6983
|
+
? list_utils_1.ListUtils.unwrapList(node.publication).map(pub => this.visit(pub, context)).join(', ')
|
|
6984
|
+
: null;
|
|
6985
|
+
{
|
|
6986
|
+
switch (node.kind || 'ALTER_SUBSCRIPTION_OPTIONS') {
|
|
6920
6987
|
case 'ALTER_SUBSCRIPTION_OPTIONS':
|
|
6921
6988
|
output.push('SET');
|
|
6989
|
+
if (options)
|
|
6990
|
+
output.push(options);
|
|
6922
6991
|
break;
|
|
6923
6992
|
case 'ALTER_SUBSCRIPTION_CONNECTION':
|
|
6924
6993
|
output.push('CONNECTION');
|
|
6925
6994
|
if (node.conninfo) {
|
|
6926
|
-
output.push(
|
|
6995
|
+
output.push(quotes_1.QuoteUtils.escape(node.conninfo));
|
|
6927
6996
|
}
|
|
6928
6997
|
break;
|
|
6929
6998
|
case 'ALTER_SUBSCRIPTION_SET_PUBLICATION':
|
|
6930
6999
|
output.push('SET PUBLICATION');
|
|
6931
|
-
if (
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
7000
|
+
if (publications)
|
|
7001
|
+
output.push(publications);
|
|
7002
|
+
if (options)
|
|
7003
|
+
output.push('WITH', options);
|
|
7004
|
+
break;
|
|
7005
|
+
case 'ALTER_SUBSCRIPTION_ADD_PUBLICATION':
|
|
7006
|
+
output.push('ADD PUBLICATION');
|
|
7007
|
+
if (publications)
|
|
7008
|
+
output.push(publications);
|
|
7009
|
+
if (options)
|
|
7010
|
+
output.push('WITH', options);
|
|
7011
|
+
break;
|
|
7012
|
+
case 'ALTER_SUBSCRIPTION_DROP_PUBLICATION':
|
|
7013
|
+
output.push('DROP PUBLICATION');
|
|
7014
|
+
if (publications)
|
|
7015
|
+
output.push(publications);
|
|
7016
|
+
if (options)
|
|
7017
|
+
output.push('WITH', options);
|
|
6935
7018
|
break;
|
|
6936
7019
|
case 'ALTER_SUBSCRIPTION_REFRESH':
|
|
6937
7020
|
output.push('REFRESH PUBLICATION');
|
|
7021
|
+
if (options)
|
|
7022
|
+
output.push('WITH', options);
|
|
6938
7023
|
break;
|
|
6939
|
-
case 'ALTER_SUBSCRIPTION_ENABLED':
|
|
6940
|
-
|
|
7024
|
+
case 'ALTER_SUBSCRIPTION_ENABLED': {
|
|
7025
|
+
const enabled = list_utils_1.ListUtils.unwrapList(node.options).find(opt => opt.DefElem?.defname === 'enabled');
|
|
7026
|
+
const arg = enabled?.DefElem?.arg;
|
|
7027
|
+
const isEnabled = arg?.Boolean ? arg.Boolean.boolval !== false : true;
|
|
7028
|
+
output.push(isEnabled ? 'ENABLE' : 'DISABLE');
|
|
6941
7029
|
break;
|
|
7030
|
+
}
|
|
6942
7031
|
case 'ALTER_SUBSCRIPTION_SKIP':
|
|
6943
7032
|
output.push('SKIP');
|
|
7033
|
+
if (options)
|
|
7034
|
+
output.push(options);
|
|
6944
7035
|
break;
|
|
6945
7036
|
default:
|
|
6946
7037
|
throw new Error(`Unsupported AlterSubscriptionStmt kind: ${node.kind}`);
|
|
6947
7038
|
}
|
|
6948
7039
|
}
|
|
6949
|
-
if (node.options && node.options.length > 0) {
|
|
6950
|
-
output.push('WITH');
|
|
6951
|
-
const options = list_utils_1.ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context));
|
|
6952
|
-
output.push(`(${options.join(', ')})`);
|
|
6953
|
-
}
|
|
6954
7040
|
return output.join(' ');
|
|
6955
7041
|
}
|
|
6956
7042
|
DropSubscriptionStmt(node, context) {
|
|
@@ -8016,6 +8102,9 @@ class Deparser {
|
|
|
8016
8102
|
if (node.grant_option && node.is_grant) {
|
|
8017
8103
|
output.push('WITH GRANT OPTION');
|
|
8018
8104
|
}
|
|
8105
|
+
if (node.grantor) {
|
|
8106
|
+
output.push('GRANTED BY', this.RoleSpec(node.grantor, context));
|
|
8107
|
+
}
|
|
8019
8108
|
// Only add behavior clauses for REVOKE statements, not for GRANT statements in ALTER DEFAULT PRIVILEGES
|
|
8020
8109
|
if (!node.is_grant) {
|
|
8021
8110
|
if (node.behavior === 'DROP_CASCADE') {
|
|
@@ -8029,57 +8118,34 @@ class Deparser {
|
|
|
8029
8118
|
}
|
|
8030
8119
|
GrantRoleStmt(node, context) {
|
|
8031
8120
|
const output = [];
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
if (adminOption.DefElem && adminOption.DefElem.arg) {
|
|
8052
|
-
adminValue = adminOption.DefElem.arg.Boolean?.boolval;
|
|
8053
|
-
}
|
|
8054
|
-
}
|
|
8055
|
-
if (setOption && setOption.DefElem) {
|
|
8056
|
-
hasSetOption = true;
|
|
8057
|
-
setValue = setOption.DefElem.arg?.Boolean?.boolval;
|
|
8058
|
-
}
|
|
8059
|
-
}
|
|
8121
|
+
const options = list_utils_1.ListUtils.unwrapList(node.opt)
|
|
8122
|
+
.map(opt => opt.DefElem)
|
|
8123
|
+
.filter((opt) => !!opt && !!opt.defname);
|
|
8124
|
+
const optionValue = (opt) => {
|
|
8125
|
+
if (!opt.arg)
|
|
8126
|
+
return true;
|
|
8127
|
+
const argType = this.getNodeType(opt.arg);
|
|
8128
|
+
const argData = this.getNodeData(opt.arg);
|
|
8129
|
+
if (argType === 'Boolean')
|
|
8130
|
+
return argData.boolval !== false;
|
|
8131
|
+
if (argType === 'String')
|
|
8132
|
+
return argData.sval !== 'false';
|
|
8133
|
+
return true;
|
|
8134
|
+
};
|
|
8135
|
+
const roles = list_utils_1.ListUtils.unwrapList(node.granted_roles)
|
|
8136
|
+
.map(role => role.AccessPriv?.priv_name
|
|
8137
|
+
? quotes_1.QuoteUtils.quoteIdentifier(role.AccessPriv.priv_name)
|
|
8138
|
+
: this.visit(role, context))
|
|
8139
|
+
.join(', ');
|
|
8060
8140
|
if (node.is_grant) {
|
|
8061
|
-
output.push('GRANT');
|
|
8141
|
+
output.push('GRANT', roles, 'TO');
|
|
8062
8142
|
}
|
|
8063
8143
|
else {
|
|
8064
8144
|
output.push('REVOKE');
|
|
8065
|
-
if (
|
|
8066
|
-
output.push(
|
|
8067
|
-
}
|
|
8068
|
-
else if (hasAdminOption) {
|
|
8069
|
-
output.push('ADMIN OPTION FOR');
|
|
8145
|
+
if (options.length > 0) {
|
|
8146
|
+
output.push(`${options[0].defname.toUpperCase()} OPTION FOR`);
|
|
8070
8147
|
}
|
|
8071
|
-
|
|
8072
|
-
if (node.granted_roles && node.granted_roles.length > 0) {
|
|
8073
|
-
const roles = list_utils_1.ListUtils.unwrapList(node.granted_roles)
|
|
8074
|
-
.map(role => this.visit(role, context))
|
|
8075
|
-
.join(', ');
|
|
8076
|
-
output.push(roles);
|
|
8077
|
-
}
|
|
8078
|
-
if (node.is_grant) {
|
|
8079
|
-
output.push('TO');
|
|
8080
|
-
}
|
|
8081
|
-
else {
|
|
8082
|
-
output.push('FROM');
|
|
8148
|
+
output.push(roles, 'FROM');
|
|
8083
8149
|
}
|
|
8084
8150
|
if (node.grantee_roles && node.grantee_roles.length > 0) {
|
|
8085
8151
|
const grantees = list_utils_1.ListUtils.unwrapList(node.grantee_roles)
|
|
@@ -8087,38 +8153,15 @@ class Deparser {
|
|
|
8087
8153
|
.join(', ');
|
|
8088
8154
|
output.push(grantees);
|
|
8089
8155
|
}
|
|
8090
|
-
if (node.is_grant) {
|
|
8091
|
-
const withOptions =
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
else {
|
|
8100
|
-
withOptions.push('ADMIN OPTION');
|
|
8101
|
-
}
|
|
8102
|
-
}
|
|
8103
|
-
if (hasInheritOption) {
|
|
8104
|
-
if (inheritValue === true) {
|
|
8105
|
-
withOptions.push('INHERIT OPTION');
|
|
8106
|
-
}
|
|
8107
|
-
else if (inheritValue === false) {
|
|
8108
|
-
withOptions.push('INHERIT FALSE');
|
|
8109
|
-
}
|
|
8110
|
-
}
|
|
8111
|
-
if (hasSetOption) {
|
|
8112
|
-
if (setValue === true) {
|
|
8113
|
-
withOptions.push('SET TRUE');
|
|
8114
|
-
}
|
|
8115
|
-
else if (setValue === false) {
|
|
8116
|
-
withOptions.push('SET FALSE');
|
|
8117
|
-
}
|
|
8118
|
-
}
|
|
8119
|
-
if (withOptions.length > 0) {
|
|
8120
|
-
output.push('WITH', withOptions.join(', '));
|
|
8121
|
-
}
|
|
8156
|
+
if (node.is_grant && options.length > 0) {
|
|
8157
|
+
const withOptions = options.map(opt => `${opt.defname.toUpperCase()} ${optionValue(opt) ? 'TRUE' : 'FALSE'}`);
|
|
8158
|
+
output.push('WITH', withOptions.join(', '));
|
|
8159
|
+
}
|
|
8160
|
+
if (node.grantor) {
|
|
8161
|
+
output.push('GRANTED BY', this.RoleSpec(node.grantor, context));
|
|
8162
|
+
}
|
|
8163
|
+
if (!node.is_grant && node.behavior === 'DROP_CASCADE') {
|
|
8164
|
+
output.push('CASCADE');
|
|
8122
8165
|
}
|
|
8123
8166
|
return output.join(' ');
|
|
8124
8167
|
}
|
|
@@ -8698,10 +8741,9 @@ class Deparser {
|
|
|
8698
8741
|
switch (node.commandType) {
|
|
8699
8742
|
case 'CMD_UPDATE': {
|
|
8700
8743
|
output.push('UPDATE SET');
|
|
8701
|
-
|
|
8702
|
-
.
|
|
8703
|
-
|
|
8704
|
-
output.push(assignments);
|
|
8744
|
+
if (node.targetList && node.targetList.length > 0) {
|
|
8745
|
+
output.push(this.formatUpdateAssignments(node.targetList, context));
|
|
8746
|
+
}
|
|
8705
8747
|
break;
|
|
8706
8748
|
}
|
|
8707
8749
|
case 'CMD_INSERT': {
|
|
@@ -9106,6 +9148,13 @@ class Deparser {
|
|
|
9106
9148
|
output.push('USING');
|
|
9107
9149
|
output.push(node.into.accessMethod);
|
|
9108
9150
|
}
|
|
9151
|
+
if (node.into && node.into.options && node.into.options.length > 0) {
|
|
9152
|
+
output.push('WITH');
|
|
9153
|
+
const options = list_utils_1.ListUtils.unwrapList(node.into.options)
|
|
9154
|
+
.map(option => this.visit(option, context.spawn('CreateStmt')))
|
|
9155
|
+
.join(', ');
|
|
9156
|
+
output.push(`(${options})`);
|
|
9157
|
+
}
|
|
9109
9158
|
if (node.into && node.into.onCommit && node.into.onCommit !== 'ONCOMMIT_NOOP') {
|
|
9110
9159
|
output.push('ON COMMIT');
|
|
9111
9160
|
switch (node.into.onCommit) {
|
|
@@ -9120,17 +9169,13 @@ class Deparser {
|
|
|
9120
9169
|
break;
|
|
9121
9170
|
}
|
|
9122
9171
|
}
|
|
9172
|
+
if (node.into && node.into.tableSpaceName) {
|
|
9173
|
+
output.push('TABLESPACE', quotes_1.QuoteUtils.quoteIdentifier(node.into.tableSpaceName));
|
|
9174
|
+
}
|
|
9123
9175
|
output.push('AS');
|
|
9124
9176
|
if (node.query) {
|
|
9125
9177
|
output.push(this.visit(node.query, context));
|
|
9126
9178
|
}
|
|
9127
|
-
if (node.into && node.into.options && node.into.options.length > 0) {
|
|
9128
|
-
output.push('WITH');
|
|
9129
|
-
const options = list_utils_1.ListUtils.unwrapList(node.into.options)
|
|
9130
|
-
.map(option => this.visit(option, context))
|
|
9131
|
-
.join(', ');
|
|
9132
|
-
output.push(`(${options})`);
|
|
9133
|
-
}
|
|
9134
9179
|
if (node.into && node.into.skipData) {
|
|
9135
9180
|
output.push('WITH NO DATA');
|
|
9136
9181
|
}
|
|
@@ -9603,7 +9648,7 @@ class Deparser {
|
|
|
9603
9648
|
}
|
|
9604
9649
|
if (node.whereClause) {
|
|
9605
9650
|
output.push('WHERE');
|
|
9606
|
-
output.push(this.visit(node.whereClause, context));
|
|
9651
|
+
output.push(`(${this.visit(node.whereClause, context)})`);
|
|
9607
9652
|
}
|
|
9608
9653
|
return output.join(' ');
|
|
9609
9654
|
}
|
|
@@ -9846,24 +9891,182 @@ class Deparser {
|
|
|
9846
9891
|
}
|
|
9847
9892
|
return output.join(' ');
|
|
9848
9893
|
}
|
|
9894
|
+
formatJsonFormat(format) {
|
|
9895
|
+
if (!format || !format.format_type || format.format_type === 'JS_FORMAT_DEFAULT') {
|
|
9896
|
+
return null;
|
|
9897
|
+
}
|
|
9898
|
+
const parts = ['FORMAT JSON'];
|
|
9899
|
+
switch (format.encoding) {
|
|
9900
|
+
case 'JS_ENC_UTF8':
|
|
9901
|
+
parts.push('ENCODING UTF8');
|
|
9902
|
+
break;
|
|
9903
|
+
case 'JS_ENC_UTF16':
|
|
9904
|
+
parts.push('ENCODING UTF16');
|
|
9905
|
+
break;
|
|
9906
|
+
case 'JS_ENC_UTF32':
|
|
9907
|
+
parts.push('ENCODING UTF32');
|
|
9908
|
+
break;
|
|
9909
|
+
}
|
|
9910
|
+
return parts.join(' ');
|
|
9911
|
+
}
|
|
9912
|
+
formatJsonOutput(output, context) {
|
|
9913
|
+
if (!output || !output.typeName)
|
|
9914
|
+
return null;
|
|
9915
|
+
const parts = ['RETURNING', this.TypeName(output.typeName, context)];
|
|
9916
|
+
const format = this.formatJsonFormat(output.returning?.format);
|
|
9917
|
+
if (format)
|
|
9918
|
+
parts.push(format);
|
|
9919
|
+
return parts.join(' ');
|
|
9920
|
+
}
|
|
9921
|
+
formatJsonNullClause(absentOnNull) {
|
|
9922
|
+
return absentOnNull ? 'ABSENT ON NULL' : 'NULL ON NULL';
|
|
9923
|
+
}
|
|
9924
|
+
formatJsonUniqueClause(unique) {
|
|
9925
|
+
return unique ? 'WITH UNIQUE KEYS' : null;
|
|
9926
|
+
}
|
|
9927
|
+
JsonValueExpr(node, context) {
|
|
9928
|
+
const parts = [];
|
|
9929
|
+
if (node.raw_expr) {
|
|
9930
|
+
parts.push(this.visit(node.raw_expr, context));
|
|
9931
|
+
}
|
|
9932
|
+
const format = this.formatJsonFormat(node.format);
|
|
9933
|
+
if (format)
|
|
9934
|
+
parts.push(format);
|
|
9935
|
+
return parts.join(' ');
|
|
9936
|
+
}
|
|
9937
|
+
JsonKeyValue(node, context) {
|
|
9938
|
+
const key = node.key ? this.visit(node.key, context) : '';
|
|
9939
|
+
const value = node.value ? this.JsonValueExpr(node.value, context) : '';
|
|
9940
|
+
return `${key} : ${value}`;
|
|
9941
|
+
}
|
|
9942
|
+
JsonObjectConstructor(node, context) {
|
|
9943
|
+
const args = [];
|
|
9944
|
+
if (node.exprs && node.exprs.length > 0) {
|
|
9945
|
+
args.push(list_utils_1.ListUtils.unwrapList(node.exprs).map(e => this.visit(e, context)).join(', '));
|
|
9946
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
9947
|
+
const unique = this.formatJsonUniqueClause(node.unique);
|
|
9948
|
+
if (unique)
|
|
9949
|
+
args.push(unique);
|
|
9950
|
+
}
|
|
9951
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
9952
|
+
if (output)
|
|
9953
|
+
args.push(output);
|
|
9954
|
+
return `JSON_OBJECT(${args.join(' ')})`;
|
|
9955
|
+
}
|
|
9956
|
+
JsonArrayConstructor(node, context) {
|
|
9957
|
+
const args = [];
|
|
9958
|
+
if (node.exprs && node.exprs.length > 0) {
|
|
9959
|
+
args.push(list_utils_1.ListUtils.unwrapList(node.exprs).map(e => this.visit(e, context)).join(', '));
|
|
9960
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
9961
|
+
}
|
|
9962
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
9963
|
+
if (output)
|
|
9964
|
+
args.push(output);
|
|
9965
|
+
return `JSON_ARRAY(${args.join(' ')})`;
|
|
9966
|
+
}
|
|
9849
9967
|
JsonArrayQueryConstructor(node, context) {
|
|
9850
|
-
const
|
|
9968
|
+
const args = [];
|
|
9851
9969
|
if (node.query) {
|
|
9852
|
-
|
|
9970
|
+
args.push(this.visit(node.query, context));
|
|
9971
|
+
}
|
|
9972
|
+
const format = this.formatJsonFormat(node.format);
|
|
9973
|
+
if (format)
|
|
9974
|
+
args.push(format);
|
|
9975
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
9976
|
+
if (output)
|
|
9977
|
+
args.push(output);
|
|
9978
|
+
return `JSON_ARRAY(${args.join(' ')})`;
|
|
9979
|
+
}
|
|
9980
|
+
formatJsonAggSuffix(ctor, context) {
|
|
9981
|
+
if (!ctor)
|
|
9982
|
+
return '';
|
|
9983
|
+
let result = '';
|
|
9984
|
+
if (ctor.agg_filter) {
|
|
9985
|
+
result += ` FILTER (WHERE ${this.visit(ctor.agg_filter, context)})`;
|
|
9853
9986
|
}
|
|
9854
|
-
if (
|
|
9855
|
-
|
|
9987
|
+
if (ctor.over) {
|
|
9988
|
+
result += this.formatOverClause(ctor.over, context);
|
|
9856
9989
|
}
|
|
9857
|
-
|
|
9858
|
-
|
|
9990
|
+
return result;
|
|
9991
|
+
}
|
|
9992
|
+
JsonObjectAgg(node, context) {
|
|
9993
|
+
const args = [];
|
|
9994
|
+
if (node.arg) {
|
|
9995
|
+
args.push(this.JsonKeyValue(node.arg, context));
|
|
9996
|
+
}
|
|
9997
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
9998
|
+
const unique = this.formatJsonUniqueClause(node.unique);
|
|
9999
|
+
if (unique)
|
|
10000
|
+
args.push(unique);
|
|
10001
|
+
const output = this.formatJsonOutput(node.constructor?.output, context);
|
|
10002
|
+
if (output)
|
|
10003
|
+
args.push(output);
|
|
10004
|
+
return `JSON_OBJECTAGG(${args.join(' ')})${this.formatJsonAggSuffix(node.constructor, context)}`;
|
|
10005
|
+
}
|
|
10006
|
+
JsonArrayAgg(node, context) {
|
|
10007
|
+
const args = [];
|
|
10008
|
+
if (node.arg) {
|
|
10009
|
+
args.push(this.JsonValueExpr(node.arg, context));
|
|
9859
10010
|
}
|
|
9860
|
-
|
|
9861
|
-
|
|
10011
|
+
const aggOrder = node.constructor?.agg_order;
|
|
10012
|
+
if (aggOrder && aggOrder.length > 0) {
|
|
10013
|
+
const orderItems = list_utils_1.ListUtils.unwrapList(aggOrder).map(item => this.visit(item, context));
|
|
10014
|
+
args.push(`ORDER BY ${orderItems.join(', ')}`);
|
|
9862
10015
|
}
|
|
9863
|
-
|
|
9864
|
-
|
|
10016
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
10017
|
+
const output = this.formatJsonOutput(node.constructor?.output, context);
|
|
10018
|
+
if (output)
|
|
10019
|
+
args.push(output);
|
|
10020
|
+
return `JSON_ARRAYAGG(${args.join(' ')})${this.formatJsonAggSuffix(node.constructor, context)}`;
|
|
10021
|
+
}
|
|
10022
|
+
JsonParseExpr(node, context) {
|
|
10023
|
+
const args = [];
|
|
10024
|
+
if (node.expr) {
|
|
10025
|
+
args.push(this.JsonValueExpr(node.expr, context));
|
|
9865
10026
|
}
|
|
9866
|
-
|
|
10027
|
+
const unique = this.formatJsonUniqueClause(node.unique_keys);
|
|
10028
|
+
if (unique)
|
|
10029
|
+
args.push(unique);
|
|
10030
|
+
return `JSON(${args.join(' ')})`;
|
|
10031
|
+
}
|
|
10032
|
+
JsonScalarExpr(node, context) {
|
|
10033
|
+
const expr = node.expr ? this.visit(node.expr, context) : '';
|
|
10034
|
+
return `JSON_SCALAR(${expr})`;
|
|
10035
|
+
}
|
|
10036
|
+
JsonSerializeExpr(node, context) {
|
|
10037
|
+
const args = [];
|
|
10038
|
+
if (node.expr) {
|
|
10039
|
+
args.push(this.JsonValueExpr(node.expr, context));
|
|
10040
|
+
}
|
|
10041
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
10042
|
+
if (output)
|
|
10043
|
+
args.push(output);
|
|
10044
|
+
return `JSON_SERIALIZE(${args.join(' ')})`;
|
|
10045
|
+
}
|
|
10046
|
+
JsonIsPredicate(node, context) {
|
|
10047
|
+
const parts = [];
|
|
10048
|
+
if (node.expr) {
|
|
10049
|
+
parts.push(this.visit(node.expr, context));
|
|
10050
|
+
}
|
|
10051
|
+
const format = this.formatJsonFormat(node.format);
|
|
10052
|
+
if (format)
|
|
10053
|
+
parts.push(format);
|
|
10054
|
+
parts.push('IS JSON');
|
|
10055
|
+
switch (node.item_type) {
|
|
10056
|
+
case 'JS_TYPE_OBJECT':
|
|
10057
|
+
parts.push('OBJECT');
|
|
10058
|
+
break;
|
|
10059
|
+
case 'JS_TYPE_ARRAY':
|
|
10060
|
+
parts.push('ARRAY');
|
|
10061
|
+
break;
|
|
10062
|
+
case 'JS_TYPE_SCALAR':
|
|
10063
|
+
parts.push('SCALAR');
|
|
10064
|
+
break;
|
|
10065
|
+
}
|
|
10066
|
+
if (node.unique_keys) {
|
|
10067
|
+
parts.push('WITH UNIQUE KEYS');
|
|
10068
|
+
}
|
|
10069
|
+
return parts.join(' ');
|
|
9867
10070
|
}
|
|
9868
10071
|
RangeFunction(node, context) {
|
|
9869
10072
|
const output = [];
|