pgsql-deparser 18.3.6 → 18.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deparser.d.ts +20 -0
- package/deparser.js +545 -319
- package/esm/deparser.js +545 -319
- package/package.json +3 -3
package/esm/deparser.js
CHANGED
|
@@ -2,6 +2,25 @@ import { QuoteUtils } from '@pgsql/quotes';
|
|
|
2
2
|
import { ListUtils } from './utils/list-utils';
|
|
3
3
|
import { SqlFormatter } from './utils/sql-formatter';
|
|
4
4
|
import { DeparserContext } from './visitors/base';
|
|
5
|
+
// WindowDef.frameOptions bit flags (src/include/nodes/parsenodes.h)
|
|
6
|
+
const FRAMEOPTION_NONDEFAULT = 0x00001;
|
|
7
|
+
const FRAMEOPTION_RANGE = 0x00002;
|
|
8
|
+
const FRAMEOPTION_ROWS = 0x00004;
|
|
9
|
+
const FRAMEOPTION_GROUPS = 0x00008;
|
|
10
|
+
const FRAMEOPTION_BETWEEN = 0x00010;
|
|
11
|
+
const FRAMEOPTION_START_UNBOUNDED_PRECEDING = 0x00020;
|
|
12
|
+
const FRAMEOPTION_END_UNBOUNDED_PRECEDING = 0x00040;
|
|
13
|
+
const FRAMEOPTION_START_UNBOUNDED_FOLLOWING = 0x00080;
|
|
14
|
+
const FRAMEOPTION_END_UNBOUNDED_FOLLOWING = 0x00100;
|
|
15
|
+
const FRAMEOPTION_START_CURRENT_ROW = 0x00200;
|
|
16
|
+
const FRAMEOPTION_END_CURRENT_ROW = 0x00400;
|
|
17
|
+
const FRAMEOPTION_START_OFFSET_PRECEDING = 0x00800;
|
|
18
|
+
const FRAMEOPTION_END_OFFSET_PRECEDING = 0x01000;
|
|
19
|
+
const FRAMEOPTION_START_OFFSET_FOLLOWING = 0x02000;
|
|
20
|
+
const FRAMEOPTION_END_OFFSET_FOLLOWING = 0x04000;
|
|
21
|
+
const FRAMEOPTION_EXCLUDE_CURRENT_ROW = 0x08000;
|
|
22
|
+
const FRAMEOPTION_EXCLUDE_GROUP = 0x10000;
|
|
23
|
+
const FRAMEOPTION_EXCLUDE_TIES = 0x20000;
|
|
5
24
|
/**
|
|
6
25
|
* List of real PostgreSQL built-in types as they appear in pg_catalog.pg_type.typname.
|
|
7
26
|
* These are stored in lowercase in PostgreSQL system catalogs.
|
|
@@ -981,6 +1000,12 @@ export class Deparser {
|
|
|
981
1000
|
output.push(context.parens(columnNames.join(', ')));
|
|
982
1001
|
}
|
|
983
1002
|
}
|
|
1003
|
+
if (node.override === 'OVERRIDING_USER_VALUE') {
|
|
1004
|
+
output.push('OVERRIDING USER VALUE');
|
|
1005
|
+
}
|
|
1006
|
+
else if (node.override === 'OVERRIDING_SYSTEM_VALUE') {
|
|
1007
|
+
output.push('OVERRIDING SYSTEM VALUE');
|
|
1008
|
+
}
|
|
984
1009
|
if (node.selectStmt) {
|
|
985
1010
|
output.push(this.visit(node.selectStmt, context));
|
|
986
1011
|
}
|
|
@@ -1057,38 +1082,8 @@ export class Deparser {
|
|
|
1057
1082
|
output.push(this.RangeVar(node.relation, context));
|
|
1058
1083
|
}
|
|
1059
1084
|
output.push('SET');
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
const firstTarget = targetList[0];
|
|
1063
|
-
const processedTargets = new Set();
|
|
1064
|
-
const assignmentParts = [];
|
|
1065
|
-
for (let i = 0; i < targetList.length; i++) {
|
|
1066
|
-
if (processedTargets.has(i))
|
|
1067
|
-
continue;
|
|
1068
|
-
const target = targetList[i];
|
|
1069
|
-
const multiAssignRef = target.ResTarget?.val?.MultiAssignRef;
|
|
1070
|
-
if (multiAssignRef) {
|
|
1071
|
-
const relatedTargets = [];
|
|
1072
|
-
for (let j = i; j < targetList.length; j++) {
|
|
1073
|
-
const otherTarget = targetList[j];
|
|
1074
|
-
const otherMultiAssignRef = otherTarget.ResTarget?.val?.MultiAssignRef;
|
|
1075
|
-
if (otherMultiAssignRef &&
|
|
1076
|
-
JSON.stringify(otherMultiAssignRef.source) === JSON.stringify(multiAssignRef.source)) {
|
|
1077
|
-
relatedTargets.push(otherTarget);
|
|
1078
|
-
processedTargets.add(j);
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
const names = relatedTargets.map(t => t.ResTarget.name);
|
|
1082
|
-
const multiAssignment = `${context.parens(names.join(', '))} = ${this.visit(multiAssignRef.source, context)}`;
|
|
1083
|
-
assignmentParts.push(multiAssignment);
|
|
1084
|
-
}
|
|
1085
|
-
else {
|
|
1086
|
-
// Handle regular single-column assignment
|
|
1087
|
-
assignmentParts.push(this.visit(target, context.spawn('UpdateStmt', { update: true })));
|
|
1088
|
-
processedTargets.add(i);
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
output.push(assignmentParts.join(','));
|
|
1085
|
+
if (node.targetList && node.targetList.length > 0) {
|
|
1086
|
+
output.push(this.formatUpdateAssignments(node.targetList, context));
|
|
1092
1087
|
}
|
|
1093
1088
|
if (node.fromClause) {
|
|
1094
1089
|
output.push('FROM');
|
|
@@ -1105,6 +1100,36 @@ export class Deparser {
|
|
|
1105
1100
|
}
|
|
1106
1101
|
return output.join(' ');
|
|
1107
1102
|
}
|
|
1103
|
+
formatUpdateAssignments(targets, context) {
|
|
1104
|
+
const targetList = ListUtils.unwrapList(targets);
|
|
1105
|
+
const processedTargets = new Set();
|
|
1106
|
+
const assignmentParts = [];
|
|
1107
|
+
for (let i = 0; i < targetList.length; i++) {
|
|
1108
|
+
if (processedTargets.has(i))
|
|
1109
|
+
continue;
|
|
1110
|
+
const target = targetList[i];
|
|
1111
|
+
const multiAssignRef = target.ResTarget?.val?.MultiAssignRef;
|
|
1112
|
+
if (multiAssignRef) {
|
|
1113
|
+
const relatedTargets = [];
|
|
1114
|
+
for (let j = i; j < targetList.length; j++) {
|
|
1115
|
+
const otherTarget = targetList[j];
|
|
1116
|
+
const otherMultiAssignRef = otherTarget.ResTarget?.val?.MultiAssignRef;
|
|
1117
|
+
if (otherMultiAssignRef &&
|
|
1118
|
+
JSON.stringify(otherMultiAssignRef.source) === JSON.stringify(multiAssignRef.source)) {
|
|
1119
|
+
relatedTargets.push(otherTarget);
|
|
1120
|
+
processedTargets.add(j);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
const names = relatedTargets.map(t => QuoteUtils.quoteIdentifier(t.ResTarget.name));
|
|
1124
|
+
assignmentParts.push(`${context.parens(names.join(', '))} = ${this.visit(multiAssignRef.source, context)}`);
|
|
1125
|
+
}
|
|
1126
|
+
else {
|
|
1127
|
+
assignmentParts.push(this.visit(target, context.spawn('UpdateStmt', { update: true })));
|
|
1128
|
+
processedTargets.add(i);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
return assignmentParts.join(', ');
|
|
1132
|
+
}
|
|
1108
1133
|
DeleteStmt(node, context) {
|
|
1109
1134
|
try {
|
|
1110
1135
|
const output = [];
|
|
@@ -1517,43 +1542,41 @@ export class Deparser {
|
|
|
1517
1542
|
result += ` FILTER (WHERE ${this.visit(node.agg_filter, context)})`;
|
|
1518
1543
|
}
|
|
1519
1544
|
if (node.over) {
|
|
1520
|
-
|
|
1521
|
-
if (node.over.name) {
|
|
1522
|
-
result += ` OVER ${node.over.name}`;
|
|
1523
|
-
}
|
|
1524
|
-
else {
|
|
1525
|
-
const windowParts = [];
|
|
1526
|
-
if (node.over.partitionClause) {
|
|
1527
|
-
const partitions = ListUtils.unwrapList(node.over.partitionClause);
|
|
1528
|
-
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
1529
|
-
windowParts.push(`PARTITION BY ${partitionStrs.join(', ')}`);
|
|
1530
|
-
}
|
|
1531
|
-
if (node.over.orderClause) {
|
|
1532
|
-
const orders = ListUtils.unwrapList(node.over.orderClause);
|
|
1533
|
-
const orderStrs = orders.map(o => this.visit(o, context));
|
|
1534
|
-
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
1535
|
-
}
|
|
1536
|
-
// Handle window frame specifications using the dedicated formatWindowFrame method
|
|
1537
|
-
const frameClause = this.formatWindowFrame(node.over, context.spawn('FuncCall'));
|
|
1538
|
-
if (frameClause) {
|
|
1539
|
-
windowParts.push(frameClause);
|
|
1540
|
-
}
|
|
1541
|
-
if (windowParts.length > 0) {
|
|
1542
|
-
if (context.isPretty() && windowParts.length > 1) {
|
|
1543
|
-
const formattedParts = windowParts.map(part => context.indent(part));
|
|
1544
|
-
result += ` OVER (${context.newline()}${formattedParts.join(context.newline())}${context.newline()})`;
|
|
1545
|
-
}
|
|
1546
|
-
else {
|
|
1547
|
-
result += ` OVER (${windowParts.join(' ')})`;
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
else {
|
|
1551
|
-
result += ` OVER ()`;
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1545
|
+
result += this.formatOverClause(node.over, context);
|
|
1554
1546
|
}
|
|
1555
1547
|
return result;
|
|
1556
1548
|
}
|
|
1549
|
+
formatOverClause(over, context) {
|
|
1550
|
+
if (over.name) {
|
|
1551
|
+
return ` OVER ${over.name}`;
|
|
1552
|
+
}
|
|
1553
|
+
const windowParts = [];
|
|
1554
|
+
if (over.refname) {
|
|
1555
|
+
windowParts.push(over.refname);
|
|
1556
|
+
}
|
|
1557
|
+
if (over.partitionClause) {
|
|
1558
|
+
const partitions = ListUtils.unwrapList(over.partitionClause);
|
|
1559
|
+
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
1560
|
+
windowParts.push(`PARTITION BY ${partitionStrs.join(', ')}`);
|
|
1561
|
+
}
|
|
1562
|
+
if (over.orderClause) {
|
|
1563
|
+
const orders = ListUtils.unwrapList(over.orderClause);
|
|
1564
|
+
const orderStrs = orders.map(o => this.visit(o, context));
|
|
1565
|
+
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
1566
|
+
}
|
|
1567
|
+
const frameClause = this.formatWindowFrame(over, context.spawn('FuncCall'));
|
|
1568
|
+
if (frameClause) {
|
|
1569
|
+
windowParts.push(frameClause);
|
|
1570
|
+
}
|
|
1571
|
+
if (windowParts.length === 0) {
|
|
1572
|
+
return ' OVER ()';
|
|
1573
|
+
}
|
|
1574
|
+
if (context.isPretty() && windowParts.length > 1) {
|
|
1575
|
+
const formattedParts = windowParts.map(part => context.indent(part));
|
|
1576
|
+
return ` OVER (${context.newline()}${formattedParts.join(context.newline())}${context.newline()})`;
|
|
1577
|
+
}
|
|
1578
|
+
return ` OVER (${windowParts.join(' ')})`;
|
|
1579
|
+
}
|
|
1557
1580
|
FuncExpr(node, context) {
|
|
1558
1581
|
const funcName = `func_${node.funcid}`;
|
|
1559
1582
|
const args = node.args ? ListUtils.unwrapList(node.args).map(arg => this.visit(arg, context)).join(', ') : '';
|
|
@@ -2416,7 +2439,7 @@ export class Deparser {
|
|
|
2416
2439
|
output.push(context.parens(elementStrs.join(', ')));
|
|
2417
2440
|
}
|
|
2418
2441
|
}
|
|
2419
|
-
else if (node.tableElts) {
|
|
2442
|
+
else if (node.tableElts && !node.partbound) {
|
|
2420
2443
|
const elements = ListUtils.unwrapList(node.tableElts);
|
|
2421
2444
|
const elementStrs = elements.map(el => {
|
|
2422
2445
|
return this.deparse(el, context.spawn('CreateStmt'));
|
|
@@ -2444,7 +2467,16 @@ export class Deparser {
|
|
|
2444
2467
|
const inherits = ListUtils.unwrapList(node.inhRelations);
|
|
2445
2468
|
const inheritStrs = inherits.map(rel => this.visit(rel, context));
|
|
2446
2469
|
output.push(inheritStrs[0]);
|
|
2447
|
-
if (node.
|
|
2470
|
+
if (node.tableElts) {
|
|
2471
|
+
const elementStrs = ListUtils.unwrapList(node.tableElts).map(el => {
|
|
2472
|
+
return this.deparse(el, context.spawn('CreateStmt'));
|
|
2473
|
+
});
|
|
2474
|
+
output.push(context.parens(elementStrs.join(', ')));
|
|
2475
|
+
}
|
|
2476
|
+
if (node.partbound.is_default) {
|
|
2477
|
+
output.push('DEFAULT');
|
|
2478
|
+
}
|
|
2479
|
+
else if (node.partbound.strategy === 'l' && node.partbound.listdatums) {
|
|
2448
2480
|
output.push('FOR VALUES IN');
|
|
2449
2481
|
const listValues = ListUtils.unwrapList(node.partbound.listdatums)
|
|
2450
2482
|
.map(datum => this.visit(datum, context))
|
|
@@ -2467,13 +2499,9 @@ export class Deparser {
|
|
|
2467
2499
|
output.push(`(${upperValues})`);
|
|
2468
2500
|
}
|
|
2469
2501
|
}
|
|
2470
|
-
else if (node.partbound.strategy === 'h'
|
|
2502
|
+
else if (node.partbound.strategy === 'h') {
|
|
2471
2503
|
output.push('FOR VALUES WITH');
|
|
2472
|
-
|
|
2473
|
-
output.push(`(MODULUS ${node.partbound.modulus}, REMAINDER ${remainder})`);
|
|
2474
|
-
}
|
|
2475
|
-
else if (node.partbound.is_default) {
|
|
2476
|
-
output.push('DEFAULT');
|
|
2504
|
+
output.push(`(MODULUS ${node.partbound.modulus ?? 0}, REMAINDER ${node.partbound.remainder ?? 0})`);
|
|
2477
2505
|
}
|
|
2478
2506
|
}
|
|
2479
2507
|
else if (node.inhRelations) {
|
|
@@ -2539,6 +2567,12 @@ export class Deparser {
|
|
|
2539
2567
|
if (node.typeName) {
|
|
2540
2568
|
output.push(this.TypeName(node.typeName, context));
|
|
2541
2569
|
}
|
|
2570
|
+
if (node.storage_name) {
|
|
2571
|
+
output.push('STORAGE', node.storage_name.toUpperCase());
|
|
2572
|
+
}
|
|
2573
|
+
if (node.compression) {
|
|
2574
|
+
output.push('COMPRESSION', QuoteUtils.quoteIdentifier(node.compression));
|
|
2575
|
+
}
|
|
2542
2576
|
if (node.fdwoptions && node.fdwoptions.length > 0) {
|
|
2543
2577
|
output.push('OPTIONS');
|
|
2544
2578
|
const columnContext = context.spawn('ColumnDef');
|
|
@@ -2599,7 +2633,8 @@ export class Deparser {
|
|
|
2599
2633
|
case 'CONSTR_DEFAULT':
|
|
2600
2634
|
output.push('DEFAULT');
|
|
2601
2635
|
if (node.raw_expr) {
|
|
2602
|
-
|
|
2636
|
+
const defaultExpr = this.visit(node.raw_expr, context);
|
|
2637
|
+
output.push(this.needsBExprParens(node.raw_expr) ? `(${defaultExpr})` : defaultExpr);
|
|
2603
2638
|
}
|
|
2604
2639
|
break;
|
|
2605
2640
|
case 'CONSTR_CHECK':
|
|
@@ -2867,6 +2902,15 @@ export class Deparser {
|
|
|
2867
2902
|
deleteClause += 'SET DEFAULT';
|
|
2868
2903
|
break;
|
|
2869
2904
|
}
|
|
2905
|
+
if ((node.fk_del_action === 'n' || node.fk_del_action === 'd') && node.fk_del_set_cols && node.fk_del_set_cols.length > 0) {
|
|
2906
|
+
const setColumns = ListUtils.unwrapList(node.fk_del_set_cols)
|
|
2907
|
+
.map(column => {
|
|
2908
|
+
const stringNode = column.String;
|
|
2909
|
+
return QuoteUtils.quoteIdentifier(stringNode.sval || stringNode.str || '');
|
|
2910
|
+
})
|
|
2911
|
+
.join(', ');
|
|
2912
|
+
deleteClause += ` (${setColumns})`;
|
|
2913
|
+
}
|
|
2870
2914
|
if (context.isPretty()) {
|
|
2871
2915
|
output.push('\n' + context.indent(deleteClause));
|
|
2872
2916
|
}
|
|
@@ -2954,7 +2998,7 @@ export class Deparser {
|
|
|
2954
2998
|
break;
|
|
2955
2999
|
}
|
|
2956
3000
|
// Handle deferrable constraints for all constraint types that support it
|
|
2957
|
-
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN') {
|
|
3001
|
+
if (node.contype === 'CONSTR_PRIMARY' || node.contype === 'CONSTR_UNIQUE' || node.contype === 'CONSTR_FOREIGN' || node.contype === 'CONSTR_EXCLUSION') {
|
|
2958
3002
|
if (node.deferrable) {
|
|
2959
3003
|
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2960
3004
|
output.push('\n' + context.indent('DEFERRABLE'));
|
|
@@ -2983,6 +3027,9 @@ export class Deparser {
|
|
|
2983
3027
|
output.push('NOT DEFERRABLE');
|
|
2984
3028
|
}
|
|
2985
3029
|
}
|
|
3030
|
+
else if (node.initdeferred) {
|
|
3031
|
+
output.push('INITIALLY DEFERRED');
|
|
3032
|
+
}
|
|
2986
3033
|
}
|
|
2987
3034
|
if (context.isPretty() && node.contype === 'CONSTR_FOREIGN') {
|
|
2988
3035
|
let result = '';
|
|
@@ -3048,6 +3095,9 @@ export class Deparser {
|
|
|
3048
3095
|
output.push(node.name);
|
|
3049
3096
|
}
|
|
3050
3097
|
const windowParts = [];
|
|
3098
|
+
if (node.refname) {
|
|
3099
|
+
windowParts.push(node.refname);
|
|
3100
|
+
}
|
|
3051
3101
|
if (node.partitionClause) {
|
|
3052
3102
|
const partitions = ListUtils.unwrapList(node.partitionClause);
|
|
3053
3103
|
const partitionStrs = partitions.map(p => this.visit(p, context));
|
|
@@ -3058,12 +3108,9 @@ export class Deparser {
|
|
|
3058
3108
|
const orderStrs = orders.map(o => this.visit(o, context));
|
|
3059
3109
|
windowParts.push(`ORDER BY ${orderStrs.join(', ')}`);
|
|
3060
3110
|
}
|
|
3061
|
-
|
|
3062
|
-
if (
|
|
3063
|
-
|
|
3064
|
-
if (frameClause) {
|
|
3065
|
-
windowParts.push(frameClause);
|
|
3066
|
-
}
|
|
3111
|
+
const frameClause = this.formatWindowFrame(node, context.spawn('WindowDef'));
|
|
3112
|
+
if (frameClause) {
|
|
3113
|
+
windowParts.push(frameClause);
|
|
3067
3114
|
}
|
|
3068
3115
|
if (windowParts.length > 0) {
|
|
3069
3116
|
if (node.name) {
|
|
@@ -3080,114 +3127,96 @@ export class Deparser {
|
|
|
3080
3127
|
}
|
|
3081
3128
|
return output.join(' ');
|
|
3082
3129
|
}
|
|
3130
|
+
formatIdentityColumnOptions(def, context) {
|
|
3131
|
+
const seqContext = context.spawn('AlterSeqStmt');
|
|
3132
|
+
return ListUtils.unwrapList(def).map(item => {
|
|
3133
|
+
const el = item.DefElem;
|
|
3134
|
+
if (!el)
|
|
3135
|
+
return this.visit(item, context);
|
|
3136
|
+
if (el.defname === 'generated') {
|
|
3137
|
+
const ival = el.arg?.Integer?.ival ?? 0;
|
|
3138
|
+
return ival === 97 ? 'SET GENERATED ALWAYS' : 'SET GENERATED BY DEFAULT';
|
|
3139
|
+
}
|
|
3140
|
+
if (el.defname === 'restart') {
|
|
3141
|
+
return el.arg ? `RESTART WITH ${this.visit(el.arg, context)}` : 'RESTART';
|
|
3142
|
+
}
|
|
3143
|
+
return `SET ${this.visit(item, seqContext)}`;
|
|
3144
|
+
}).join(' ');
|
|
3145
|
+
}
|
|
3146
|
+
// b_expr (used by DEFAULT) excludes IN/LIKE/BETWEEN and boolean operators.
|
|
3147
|
+
needsBExprParens(node) {
|
|
3148
|
+
const nodeType = this.getNodeType(node);
|
|
3149
|
+
if (nodeType === 'BoolExpr')
|
|
3150
|
+
return true;
|
|
3151
|
+
if (nodeType === 'A_Expr') {
|
|
3152
|
+
const kind = this.getNodeData(node).kind;
|
|
3153
|
+
return kind !== 'AEXPR_OP' && kind !== 'AEXPR_DISTINCT' && kind !== 'AEXPR_NOT_DISTINCT';
|
|
3154
|
+
}
|
|
3155
|
+
return false;
|
|
3156
|
+
}
|
|
3083
3157
|
formatWindowFrame(node, context) {
|
|
3084
|
-
if (!node.frameOptions)
|
|
3158
|
+
if (!node.frameOptions || !(node.frameOptions & FRAMEOPTION_NONDEFAULT))
|
|
3085
3159
|
return null;
|
|
3086
3160
|
const frameOptions = node.frameOptions;
|
|
3087
|
-
const EXCLUDE_MASK = 0x8000 | 0x10000 | 0x20000;
|
|
3088
|
-
const baseFrameOptions = frameOptions & ~EXCLUDE_MASK;
|
|
3089
3161
|
const frameParts = [];
|
|
3090
|
-
if (frameOptions &
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
frameParts.push('GROUPS');
|
|
3099
|
-
}
|
|
3162
|
+
if (frameOptions & FRAMEOPTION_RANGE) {
|
|
3163
|
+
frameParts.push('RANGE');
|
|
3164
|
+
}
|
|
3165
|
+
else if (frameOptions & FRAMEOPTION_ROWS) {
|
|
3166
|
+
frameParts.push('ROWS');
|
|
3167
|
+
}
|
|
3168
|
+
else if (frameOptions & FRAMEOPTION_GROUPS) {
|
|
3169
|
+
frameParts.push('GROUPS');
|
|
3100
3170
|
}
|
|
3101
3171
|
if (frameParts.length === 0)
|
|
3102
3172
|
return null;
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
boundsParts.push('CURRENT ROW');
|
|
3107
|
-
boundsParts.push('AND UNBOUNDED FOLLOWING');
|
|
3173
|
+
let start = null;
|
|
3174
|
+
if (frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) {
|
|
3175
|
+
start = 'UNBOUNDED PRECEDING';
|
|
3108
3176
|
}
|
|
3109
|
-
else if (
|
|
3110
|
-
|
|
3111
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3177
|
+
else if (frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) {
|
|
3178
|
+
start = 'UNBOUNDED FOLLOWING';
|
|
3112
3179
|
}
|
|
3113
|
-
else if (
|
|
3114
|
-
|
|
3115
|
-
boundsParts.push(`${this.visit(node.startOffset, context)} PRECEDING`);
|
|
3116
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3117
|
-
}
|
|
3180
|
+
else if (frameOptions & FRAMEOPTION_START_CURRENT_ROW) {
|
|
3181
|
+
start = 'CURRENT ROW';
|
|
3118
3182
|
}
|
|
3119
|
-
else if (
|
|
3120
|
-
|
|
3121
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3183
|
+
else if (frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING && node.startOffset) {
|
|
3184
|
+
start = `${this.visit(node.startOffset, context)} PRECEDING`;
|
|
3122
3185
|
}
|
|
3123
|
-
else if (
|
|
3124
|
-
|
|
3125
|
-
if (node.endOffset) {
|
|
3126
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3127
|
-
}
|
|
3186
|
+
else if (frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING && node.startOffset) {
|
|
3187
|
+
start = `${this.visit(node.startOffset, context)} FOLLOWING`;
|
|
3128
3188
|
}
|
|
3129
|
-
|
|
3130
|
-
|
|
3189
|
+
let end = null;
|
|
3190
|
+
if (frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING) {
|
|
3191
|
+
end = 'UNBOUNDED PRECEDING';
|
|
3131
3192
|
}
|
|
3132
|
-
else {
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
}
|
|
3148
|
-
else if (frameOptions & 0x20) { // FRAMEOPTION_START_CURRENT_ROW
|
|
3149
|
-
boundsParts.push('CURRENT ROW');
|
|
3150
|
-
}
|
|
3151
|
-
// Handle end bound - prioritize explicit offset values over bit flags
|
|
3152
|
-
if (node.endOffset) {
|
|
3153
|
-
if (boundsParts.length > 0) {
|
|
3154
|
-
if (frameOptions & 0x1000) { // FRAMEOPTION_END_VALUE_PRECEDING
|
|
3155
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} PRECEDING`);
|
|
3156
|
-
}
|
|
3157
|
-
else if (frameOptions & 0x2000) { // FRAMEOPTION_END_VALUE_FOLLOWING
|
|
3158
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3159
|
-
}
|
|
3160
|
-
else {
|
|
3161
|
-
boundsParts.push(`AND ${this.visit(node.endOffset, context)} FOLLOWING`);
|
|
3162
|
-
}
|
|
3163
|
-
}
|
|
3164
|
-
}
|
|
3165
|
-
else if (frameOptions & 0x80) { // FRAMEOPTION_END_UNBOUNDED_FOLLOWING
|
|
3166
|
-
if (boundsParts.length > 0) {
|
|
3167
|
-
boundsParts.push('AND UNBOUNDED FOLLOWING');
|
|
3168
|
-
}
|
|
3169
|
-
}
|
|
3170
|
-
else if (frameOptions & 0x100) { // FRAMEOPTION_END_CURRENT_ROW
|
|
3171
|
-
if (boundsParts.length > 0) {
|
|
3172
|
-
boundsParts.push('AND CURRENT ROW');
|
|
3173
|
-
}
|
|
3193
|
+
else if (frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING) {
|
|
3194
|
+
end = 'UNBOUNDED FOLLOWING';
|
|
3195
|
+
}
|
|
3196
|
+
else if (frameOptions & FRAMEOPTION_END_CURRENT_ROW) {
|
|
3197
|
+
end = 'CURRENT ROW';
|
|
3198
|
+
}
|
|
3199
|
+
else if (frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING && node.endOffset) {
|
|
3200
|
+
end = `${this.visit(node.endOffset, context)} PRECEDING`;
|
|
3201
|
+
}
|
|
3202
|
+
else if (frameOptions & FRAMEOPTION_END_OFFSET_FOLLOWING && node.endOffset) {
|
|
3203
|
+
end = `${this.visit(node.endOffset, context)} FOLLOWING`;
|
|
3204
|
+
}
|
|
3205
|
+
if (start) {
|
|
3206
|
+
if (frameOptions & FRAMEOPTION_BETWEEN) {
|
|
3207
|
+
frameParts.push(`BETWEEN ${start} AND ${end ?? 'CURRENT ROW'}`);
|
|
3174
3208
|
}
|
|
3175
|
-
else
|
|
3176
|
-
|
|
3209
|
+
else {
|
|
3210
|
+
frameParts.push(start);
|
|
3177
3211
|
}
|
|
3178
3212
|
}
|
|
3179
|
-
if (
|
|
3180
|
-
frameParts.push('BETWEEN');
|
|
3181
|
-
frameParts.push(boundsParts.join(' '));
|
|
3182
|
-
}
|
|
3183
|
-
// EXCLUDE clause
|
|
3184
|
-
if (frameOptions & 0x8000) { // FRAMEOPTION_EXCLUDE_CURRENT_ROW
|
|
3213
|
+
if (frameOptions & FRAMEOPTION_EXCLUDE_CURRENT_ROW) {
|
|
3185
3214
|
frameParts.push('EXCLUDE CURRENT ROW');
|
|
3186
3215
|
}
|
|
3187
|
-
else if (frameOptions &
|
|
3216
|
+
else if (frameOptions & FRAMEOPTION_EXCLUDE_GROUP) {
|
|
3188
3217
|
frameParts.push('EXCLUDE GROUP');
|
|
3189
3218
|
}
|
|
3190
|
-
else if (frameOptions &
|
|
3219
|
+
else if (frameOptions & FRAMEOPTION_EXCLUDE_TIES) {
|
|
3191
3220
|
frameParts.push('EXCLUDE TIES');
|
|
3192
3221
|
}
|
|
3193
3222
|
return frameParts.join(' ');
|
|
@@ -3266,8 +3295,35 @@ export class Deparser {
|
|
|
3266
3295
|
if (node.ctequery) {
|
|
3267
3296
|
output.push(context.parens(this.visit(node.ctequery, context)));
|
|
3268
3297
|
}
|
|
3298
|
+
if (node.search_clause) {
|
|
3299
|
+
const sc = node.search_clause;
|
|
3300
|
+
const cols = ListUtils.unwrapList(sc.search_col_list).map(c => this.visit(c, context));
|
|
3301
|
+
output.push('SEARCH', sc.search_breadth_first ? 'BREADTH' : 'DEPTH', 'FIRST BY');
|
|
3302
|
+
output.push(cols.join(', '));
|
|
3303
|
+
output.push('SET', QuoteUtils.quoteIdentifier(sc.search_seq_column));
|
|
3304
|
+
}
|
|
3305
|
+
if (node.cycle_clause) {
|
|
3306
|
+
const cc = node.cycle_clause;
|
|
3307
|
+
const cols = ListUtils.unwrapList(cc.cycle_col_list).map(c => this.visit(c, context));
|
|
3308
|
+
output.push('CYCLE', cols.join(', '));
|
|
3309
|
+
output.push('SET', QuoteUtils.quoteIdentifier(cc.cycle_mark_column));
|
|
3310
|
+
if (cc.cycle_mark_value && cc.cycle_mark_default) {
|
|
3311
|
+
output.push('TO', this.formatAexprConst(cc.cycle_mark_value, context));
|
|
3312
|
+
output.push('DEFAULT', this.formatAexprConst(cc.cycle_mark_default, context));
|
|
3313
|
+
}
|
|
3314
|
+
output.push('USING', QuoteUtils.quoteIdentifier(cc.cycle_path_column));
|
|
3315
|
+
}
|
|
3269
3316
|
return output.join(' ');
|
|
3270
3317
|
}
|
|
3318
|
+
// Renders a constant in the restricted AexprConst grammar (e.g. `point '(1,1)'`
|
|
3319
|
+
// rather than `CAST('(1,1)' AS point)`).
|
|
3320
|
+
formatAexprConst(node, context) {
|
|
3321
|
+
const cast = node.TypeCast;
|
|
3322
|
+
if (cast?.arg?.A_Const?.sval && cast.typeName) {
|
|
3323
|
+
return `${this.TypeName(cast.typeName, context)} ${this.visit(cast.arg, context)}`;
|
|
3324
|
+
}
|
|
3325
|
+
return this.visit(node, context);
|
|
3326
|
+
}
|
|
3271
3327
|
ParamRef(node, context) {
|
|
3272
3328
|
return `$${node.number}`;
|
|
3273
3329
|
}
|
|
@@ -3627,12 +3683,12 @@ export class Deparser {
|
|
|
3627
3683
|
}
|
|
3628
3684
|
PartitionCmd(node, context) {
|
|
3629
3685
|
const output = [];
|
|
3686
|
+
if (node.name) {
|
|
3687
|
+
output.push(this.RangeVar(node.name, context));
|
|
3688
|
+
}
|
|
3630
3689
|
if (node.concurrent) {
|
|
3631
3690
|
output.push('CONCURRENTLY');
|
|
3632
3691
|
}
|
|
3633
|
-
if (node.name) {
|
|
3634
|
-
output.push(this.visit(node.name, context));
|
|
3635
|
-
}
|
|
3636
3692
|
if (node.bound) {
|
|
3637
3693
|
if (node.bound.strategy === 'l' && node.bound.listdatums) {
|
|
3638
3694
|
output.push('FOR VALUES IN');
|
|
@@ -3657,9 +3713,9 @@ export class Deparser {
|
|
|
3657
3713
|
output.push(`(${upperValues})`);
|
|
3658
3714
|
}
|
|
3659
3715
|
}
|
|
3660
|
-
else if (node.bound.strategy === 'h'
|
|
3716
|
+
else if (node.bound.strategy === 'h') {
|
|
3661
3717
|
output.push('FOR VALUES WITH');
|
|
3662
|
-
output.push(`(
|
|
3718
|
+
output.push(`(MODULUS ${node.bound.modulus ?? 0}, REMAINDER ${node.bound.remainder ?? 0})`);
|
|
3663
3719
|
}
|
|
3664
3720
|
else if (node.bound.is_default) {
|
|
3665
3721
|
output.push('DEFAULT');
|
|
@@ -4512,10 +4568,10 @@ export class Deparser {
|
|
|
4512
4568
|
output.push('PROGRAM');
|
|
4513
4569
|
}
|
|
4514
4570
|
if (node.filename) {
|
|
4515
|
-
output.push(
|
|
4571
|
+
output.push(QuoteUtils.escape(node.filename));
|
|
4516
4572
|
}
|
|
4517
4573
|
else {
|
|
4518
|
-
output.push('STDIN');
|
|
4574
|
+
output.push(node.is_from ? 'STDIN' : 'STDOUT');
|
|
4519
4575
|
}
|
|
4520
4576
|
if (node.options && node.options.length > 0) {
|
|
4521
4577
|
output.push('WITH');
|
|
@@ -4747,6 +4803,9 @@ export class Deparser {
|
|
|
4747
4803
|
const nodeData = this.getNodeData(node.def);
|
|
4748
4804
|
if (nodeData && nodeData.typeName) {
|
|
4749
4805
|
output.push(this.TypeName(nodeData.typeName, context));
|
|
4806
|
+
if (nodeData.collClause) {
|
|
4807
|
+
output.push(this.CollateClause(nodeData.collClause, context));
|
|
4808
|
+
}
|
|
4750
4809
|
// Handle USING clause (stored in raw_default for ALTER COLUMN TYPE)
|
|
4751
4810
|
if (nodeData.raw_default) {
|
|
4752
4811
|
output.push('USING');
|
|
@@ -5227,9 +5286,8 @@ export class Deparser {
|
|
|
5227
5286
|
if (node.name) {
|
|
5228
5287
|
output.push(QuoteUtils.quoteIdentifier(node.name));
|
|
5229
5288
|
}
|
|
5230
|
-
output.push('SET');
|
|
5231
5289
|
if (node.def) {
|
|
5232
|
-
output.push(this.
|
|
5290
|
+
output.push(this.formatIdentityColumnOptions(node.def, context));
|
|
5233
5291
|
}
|
|
5234
5292
|
break;
|
|
5235
5293
|
case 'AT_DropIdentity':
|
|
@@ -5238,11 +5296,8 @@ export class Deparser {
|
|
|
5238
5296
|
output.push(QuoteUtils.quoteIdentifier(node.name));
|
|
5239
5297
|
}
|
|
5240
5298
|
output.push('DROP IDENTITY');
|
|
5241
|
-
if (node.
|
|
5242
|
-
output.push('
|
|
5243
|
-
}
|
|
5244
|
-
else if (node.behavior === 'DROP_RESTRICT') {
|
|
5245
|
-
output.push('RESTRICT');
|
|
5299
|
+
if (node.missing_ok) {
|
|
5300
|
+
output.push('IF EXISTS');
|
|
5246
5301
|
}
|
|
5247
5302
|
break;
|
|
5248
5303
|
case 'AT_ReAddStatistics':
|
|
@@ -5678,6 +5733,9 @@ export class Deparser {
|
|
|
5678
5733
|
if (node.arg && this.getNodeType(node.arg) === 'List') {
|
|
5679
5734
|
const listData = this.getNodeData(node.arg);
|
|
5680
5735
|
const listItems = ListUtils.unwrapList(listData.items);
|
|
5736
|
+
if (listItems.length === 1 && listItems[0].String?.sval === 'none') {
|
|
5737
|
+
return 'OWNED BY NONE';
|
|
5738
|
+
}
|
|
5681
5739
|
const parts = listItems.map(item => {
|
|
5682
5740
|
const itemData = this.getNodeData(item);
|
|
5683
5741
|
if (this.getNodeType(item) === 'String') {
|
|
@@ -5855,12 +5913,15 @@ export class Deparser {
|
|
|
5855
5913
|
}
|
|
5856
5914
|
// Handle CreateStmt table options - no quotes, compact formatting
|
|
5857
5915
|
if (context.parentNodeTypes.includes('CreateStmt')) {
|
|
5916
|
+
const relOptName = node.defnamespace
|
|
5917
|
+
? `${QuoteUtils.quoteIdentifier(node.defnamespace)}.${QuoteUtils.quoteIdentifier(node.defname)}`
|
|
5918
|
+
: QuoteUtils.quoteIdentifier(node.defname);
|
|
5858
5919
|
// For numeric values, use the raw value without quotes
|
|
5859
5920
|
if (node.arg && this.getNodeType(node.arg) === 'Integer') {
|
|
5860
5921
|
const integerData = this.getNodeData(node.arg);
|
|
5861
|
-
return `${
|
|
5922
|
+
return `${relOptName}=${integerData.ival}`;
|
|
5862
5923
|
}
|
|
5863
|
-
return `${
|
|
5924
|
+
return `${relOptName}=${argValue}`;
|
|
5864
5925
|
}
|
|
5865
5926
|
// Handle CreateEventTrigStmt WHEN clause - use IN syntax for List arguments
|
|
5866
5927
|
if (context.parentNodeTypes.includes('CreateEventTrigStmt')) {
|
|
@@ -5899,15 +5960,27 @@ export class Deparser {
|
|
|
5899
5960
|
}
|
|
5900
5961
|
// Handle CopyStmt WITH clause options - uppercase format without quotes
|
|
5901
5962
|
if (context.parentNodeTypes.includes('CopyStmt')) {
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
return
|
|
5963
|
+
const optName = node.defname.toUpperCase();
|
|
5964
|
+
if (!node.arg) {
|
|
5965
|
+
return optName;
|
|
5905
5966
|
}
|
|
5906
|
-
|
|
5907
|
-
if (node.arg) {
|
|
5908
|
-
return
|
|
5967
|
+
const copyArgType = this.getNodeType(node.arg);
|
|
5968
|
+
if (copyArgType === 'Boolean' && this.getNodeData(node.arg).boolval !== false) {
|
|
5969
|
+
return optName;
|
|
5909
5970
|
}
|
|
5910
|
-
|
|
5971
|
+
if (copyArgType === 'List') {
|
|
5972
|
+
const items = ListUtils.unwrapList(this.getNodeData(node.arg).items)
|
|
5973
|
+
.map(item => this.visit(item, context));
|
|
5974
|
+
return `${optName} (${items.join(', ')})`;
|
|
5975
|
+
}
|
|
5976
|
+
if (copyArgType === 'String') {
|
|
5977
|
+
const sval = this.getNodeData(node.arg).sval;
|
|
5978
|
+
if (node.defname === 'format') {
|
|
5979
|
+
return `${optName} ${sval}`;
|
|
5980
|
+
}
|
|
5981
|
+
return `${optName} ${QuoteUtils.escape(sval)}`;
|
|
5982
|
+
}
|
|
5983
|
+
return `${optName} ${argValue}`;
|
|
5911
5984
|
}
|
|
5912
5985
|
// Handle CREATE OPERATOR and CREATE TYPE context
|
|
5913
5986
|
if (context.parentNodeTypes.includes('DefineStmt')) {
|
|
@@ -5988,6 +6061,10 @@ export class Deparser {
|
|
|
5988
6061
|
return `${node.defname} = ${argValue}`;
|
|
5989
6062
|
}
|
|
5990
6063
|
}
|
|
6064
|
+
const argType = this.getNodeType(node.arg);
|
|
6065
|
+
if (argType === 'TypeName' || argType === 'Integer' || argType === 'Float' || argType === 'Boolean') {
|
|
6066
|
+
return `${node.defname} = ${argValue}`;
|
|
6067
|
+
}
|
|
5991
6068
|
const quotedValue = typeof argValue === 'string'
|
|
5992
6069
|
? QuoteUtils.escape(argValue)
|
|
5993
6070
|
: argValue;
|
|
@@ -6421,6 +6498,9 @@ export class Deparser {
|
|
|
6421
6498
|
case 'OBJECT_TABCONSTRAINT':
|
|
6422
6499
|
output.push('CONSTRAINT');
|
|
6423
6500
|
break;
|
|
6501
|
+
case 'OBJECT_DOMCONSTRAINT':
|
|
6502
|
+
output.push('CONSTRAINT');
|
|
6503
|
+
break;
|
|
6424
6504
|
case 'OBJECT_TRIGGER':
|
|
6425
6505
|
output.push('TRIGGER');
|
|
6426
6506
|
break;
|
|
@@ -6497,6 +6577,15 @@ export class Deparser {
|
|
|
6497
6577
|
output.push(objectParts.join('.'));
|
|
6498
6578
|
}
|
|
6499
6579
|
}
|
|
6580
|
+
else if (node.objtype === 'OBJECT_DOMCONSTRAINT') {
|
|
6581
|
+
if (objectParts.length === 2) {
|
|
6582
|
+
const [domain, constraint] = objectParts;
|
|
6583
|
+
output.push(constraint, 'ON DOMAIN', domain);
|
|
6584
|
+
}
|
|
6585
|
+
else {
|
|
6586
|
+
output.push(objectParts.join('.'));
|
|
6587
|
+
}
|
|
6588
|
+
}
|
|
6500
6589
|
else if (node.objtype === 'OBJECT_TRIGGER') {
|
|
6501
6590
|
if (objectParts.length === 2) {
|
|
6502
6591
|
const [table, trigger] = objectParts;
|
|
@@ -6828,7 +6917,7 @@ export class Deparser {
|
|
|
6828
6917
|
output.push(QuoteUtils.quoteIdentifier(node.pubname));
|
|
6829
6918
|
}
|
|
6830
6919
|
if (node.pubobjects && node.pubobjects.length > 0) {
|
|
6831
|
-
output.push('FOR'
|
|
6920
|
+
output.push('FOR');
|
|
6832
6921
|
const tables = ListUtils.unwrapList(node.pubobjects).map(table => this.visit(table, context));
|
|
6833
6922
|
output.push(tables.join(', '));
|
|
6834
6923
|
}
|
|
@@ -6868,8 +6957,9 @@ export class Deparser {
|
|
|
6868
6957
|
if (node.pubname) {
|
|
6869
6958
|
output.push(QuoteUtils.quoteIdentifier(node.pubname));
|
|
6870
6959
|
}
|
|
6871
|
-
|
|
6872
|
-
|
|
6960
|
+
const hasObjects = node.pubobjects && node.pubobjects.length > 0;
|
|
6961
|
+
if (hasObjects) {
|
|
6962
|
+
switch (node.action || 'AP_AddObjects') {
|
|
6873
6963
|
case 'AP_AddObjects':
|
|
6874
6964
|
output.push('ADD');
|
|
6875
6965
|
break;
|
|
@@ -6882,17 +6972,11 @@ export class Deparser {
|
|
|
6882
6972
|
default:
|
|
6883
6973
|
throw new Error(`Unsupported AlterPublicationStmt action: ${node.action}`);
|
|
6884
6974
|
}
|
|
6885
|
-
}
|
|
6886
|
-
if (node.for_all_tables) {
|
|
6887
|
-
output.push('FOR ALL TABLES');
|
|
6888
|
-
}
|
|
6889
|
-
else if (node.pubobjects && node.pubobjects.length > 0) {
|
|
6890
|
-
output.push('FOR TABLE');
|
|
6891
6975
|
const objects = ListUtils.unwrapList(node.pubobjects).map(obj => this.visit(obj, context));
|
|
6892
6976
|
output.push(objects.join(', '));
|
|
6893
6977
|
}
|
|
6894
|
-
if (node.options && node.options.length > 0) {
|
|
6895
|
-
output.push('
|
|
6978
|
+
else if (node.options && node.options.length > 0) {
|
|
6979
|
+
output.push('SET');
|
|
6896
6980
|
const options = ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context));
|
|
6897
6981
|
output.push(`(${options.join(', ')})`);
|
|
6898
6982
|
}
|
|
@@ -6903,42 +6987,67 @@ export class Deparser {
|
|
|
6903
6987
|
if (node.subname) {
|
|
6904
6988
|
output.push(QuoteUtils.quoteIdentifier(node.subname));
|
|
6905
6989
|
}
|
|
6906
|
-
|
|
6907
|
-
|
|
6990
|
+
const options = node.options && node.options.length > 0
|
|
6991
|
+
? `(${ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context)).join(', ')})`
|
|
6992
|
+
: null;
|
|
6993
|
+
const publications = node.publication && node.publication.length > 0
|
|
6994
|
+
? ListUtils.unwrapList(node.publication).map(pub => this.visit(pub, context)).join(', ')
|
|
6995
|
+
: null;
|
|
6996
|
+
{
|
|
6997
|
+
switch (node.kind || 'ALTER_SUBSCRIPTION_OPTIONS') {
|
|
6908
6998
|
case 'ALTER_SUBSCRIPTION_OPTIONS':
|
|
6909
6999
|
output.push('SET');
|
|
7000
|
+
if (options)
|
|
7001
|
+
output.push(options);
|
|
6910
7002
|
break;
|
|
6911
7003
|
case 'ALTER_SUBSCRIPTION_CONNECTION':
|
|
6912
7004
|
output.push('CONNECTION');
|
|
6913
7005
|
if (node.conninfo) {
|
|
6914
|
-
output.push(
|
|
7006
|
+
output.push(QuoteUtils.escape(node.conninfo));
|
|
6915
7007
|
}
|
|
6916
7008
|
break;
|
|
6917
7009
|
case 'ALTER_SUBSCRIPTION_SET_PUBLICATION':
|
|
6918
7010
|
output.push('SET PUBLICATION');
|
|
6919
|
-
if (
|
|
6920
|
-
|
|
6921
|
-
|
|
6922
|
-
|
|
7011
|
+
if (publications)
|
|
7012
|
+
output.push(publications);
|
|
7013
|
+
if (options)
|
|
7014
|
+
output.push('WITH', options);
|
|
7015
|
+
break;
|
|
7016
|
+
case 'ALTER_SUBSCRIPTION_ADD_PUBLICATION':
|
|
7017
|
+
output.push('ADD PUBLICATION');
|
|
7018
|
+
if (publications)
|
|
7019
|
+
output.push(publications);
|
|
7020
|
+
if (options)
|
|
7021
|
+
output.push('WITH', options);
|
|
7022
|
+
break;
|
|
7023
|
+
case 'ALTER_SUBSCRIPTION_DROP_PUBLICATION':
|
|
7024
|
+
output.push('DROP PUBLICATION');
|
|
7025
|
+
if (publications)
|
|
7026
|
+
output.push(publications);
|
|
7027
|
+
if (options)
|
|
7028
|
+
output.push('WITH', options);
|
|
6923
7029
|
break;
|
|
6924
7030
|
case 'ALTER_SUBSCRIPTION_REFRESH':
|
|
6925
7031
|
output.push('REFRESH PUBLICATION');
|
|
7032
|
+
if (options)
|
|
7033
|
+
output.push('WITH', options);
|
|
6926
7034
|
break;
|
|
6927
|
-
case 'ALTER_SUBSCRIPTION_ENABLED':
|
|
6928
|
-
|
|
7035
|
+
case 'ALTER_SUBSCRIPTION_ENABLED': {
|
|
7036
|
+
const enabled = ListUtils.unwrapList(node.options).find(opt => opt.DefElem?.defname === 'enabled');
|
|
7037
|
+
const arg = enabled?.DefElem?.arg;
|
|
7038
|
+
const isEnabled = arg?.Boolean ? arg.Boolean.boolval !== false : true;
|
|
7039
|
+
output.push(isEnabled ? 'ENABLE' : 'DISABLE');
|
|
6929
7040
|
break;
|
|
7041
|
+
}
|
|
6930
7042
|
case 'ALTER_SUBSCRIPTION_SKIP':
|
|
6931
7043
|
output.push('SKIP');
|
|
7044
|
+
if (options)
|
|
7045
|
+
output.push(options);
|
|
6932
7046
|
break;
|
|
6933
7047
|
default:
|
|
6934
7048
|
throw new Error(`Unsupported AlterSubscriptionStmt kind: ${node.kind}`);
|
|
6935
7049
|
}
|
|
6936
7050
|
}
|
|
6937
|
-
if (node.options && node.options.length > 0) {
|
|
6938
|
-
output.push('WITH');
|
|
6939
|
-
const options = ListUtils.unwrapList(node.options).map(opt => this.visit(opt, context));
|
|
6940
|
-
output.push(`(${options.join(', ')})`);
|
|
6941
|
-
}
|
|
6942
7051
|
return output.join(' ');
|
|
6943
7052
|
}
|
|
6944
7053
|
DropSubscriptionStmt(node, context) {
|
|
@@ -8004,6 +8113,9 @@ export class Deparser {
|
|
|
8004
8113
|
if (node.grant_option && node.is_grant) {
|
|
8005
8114
|
output.push('WITH GRANT OPTION');
|
|
8006
8115
|
}
|
|
8116
|
+
if (node.grantor) {
|
|
8117
|
+
output.push('GRANTED BY', this.RoleSpec(node.grantor, context));
|
|
8118
|
+
}
|
|
8007
8119
|
// Only add behavior clauses for REVOKE statements, not for GRANT statements in ALTER DEFAULT PRIVILEGES
|
|
8008
8120
|
if (!node.is_grant) {
|
|
8009
8121
|
if (node.behavior === 'DROP_CASCADE') {
|
|
@@ -8017,57 +8129,34 @@ export class Deparser {
|
|
|
8017
8129
|
}
|
|
8018
8130
|
GrantRoleStmt(node, context) {
|
|
8019
8131
|
const output = [];
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
8024
|
-
|
|
8025
|
-
|
|
8026
|
-
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
|
|
8031
|
-
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
if (adminOption.DefElem && adminOption.DefElem.arg) {
|
|
8040
|
-
adminValue = adminOption.DefElem.arg.Boolean?.boolval;
|
|
8041
|
-
}
|
|
8042
|
-
}
|
|
8043
|
-
if (setOption && setOption.DefElem) {
|
|
8044
|
-
hasSetOption = true;
|
|
8045
|
-
setValue = setOption.DefElem.arg?.Boolean?.boolval;
|
|
8046
|
-
}
|
|
8047
|
-
}
|
|
8132
|
+
const options = ListUtils.unwrapList(node.opt)
|
|
8133
|
+
.map(opt => opt.DefElem)
|
|
8134
|
+
.filter((opt) => !!opt && !!opt.defname);
|
|
8135
|
+
const optionValue = (opt) => {
|
|
8136
|
+
if (!opt.arg)
|
|
8137
|
+
return true;
|
|
8138
|
+
const argType = this.getNodeType(opt.arg);
|
|
8139
|
+
const argData = this.getNodeData(opt.arg);
|
|
8140
|
+
if (argType === 'Boolean')
|
|
8141
|
+
return argData.boolval !== false;
|
|
8142
|
+
if (argType === 'String')
|
|
8143
|
+
return argData.sval !== 'false';
|
|
8144
|
+
return true;
|
|
8145
|
+
};
|
|
8146
|
+
const roles = ListUtils.unwrapList(node.granted_roles)
|
|
8147
|
+
.map(role => role.AccessPriv?.priv_name
|
|
8148
|
+
? QuoteUtils.quoteIdentifier(role.AccessPriv.priv_name)
|
|
8149
|
+
: this.visit(role, context))
|
|
8150
|
+
.join(', ');
|
|
8048
8151
|
if (node.is_grant) {
|
|
8049
|
-
output.push('GRANT');
|
|
8152
|
+
output.push('GRANT', roles, 'TO');
|
|
8050
8153
|
}
|
|
8051
8154
|
else {
|
|
8052
8155
|
output.push('REVOKE');
|
|
8053
|
-
if (
|
|
8054
|
-
output.push(
|
|
8055
|
-
}
|
|
8056
|
-
else if (hasAdminOption) {
|
|
8057
|
-
output.push('ADMIN OPTION FOR');
|
|
8156
|
+
if (options.length > 0) {
|
|
8157
|
+
output.push(`${options[0].defname.toUpperCase()} OPTION FOR`);
|
|
8058
8158
|
}
|
|
8059
|
-
|
|
8060
|
-
if (node.granted_roles && node.granted_roles.length > 0) {
|
|
8061
|
-
const roles = ListUtils.unwrapList(node.granted_roles)
|
|
8062
|
-
.map(role => this.visit(role, context))
|
|
8063
|
-
.join(', ');
|
|
8064
|
-
output.push(roles);
|
|
8065
|
-
}
|
|
8066
|
-
if (node.is_grant) {
|
|
8067
|
-
output.push('TO');
|
|
8068
|
-
}
|
|
8069
|
-
else {
|
|
8070
|
-
output.push('FROM');
|
|
8159
|
+
output.push(roles, 'FROM');
|
|
8071
8160
|
}
|
|
8072
8161
|
if (node.grantee_roles && node.grantee_roles.length > 0) {
|
|
8073
8162
|
const grantees = ListUtils.unwrapList(node.grantee_roles)
|
|
@@ -8075,38 +8164,15 @@ export class Deparser {
|
|
|
8075
8164
|
.join(', ');
|
|
8076
8165
|
output.push(grantees);
|
|
8077
8166
|
}
|
|
8078
|
-
if (node.is_grant) {
|
|
8079
|
-
const withOptions =
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
else {
|
|
8088
|
-
withOptions.push('ADMIN OPTION');
|
|
8089
|
-
}
|
|
8090
|
-
}
|
|
8091
|
-
if (hasInheritOption) {
|
|
8092
|
-
if (inheritValue === true) {
|
|
8093
|
-
withOptions.push('INHERIT OPTION');
|
|
8094
|
-
}
|
|
8095
|
-
else if (inheritValue === false) {
|
|
8096
|
-
withOptions.push('INHERIT FALSE');
|
|
8097
|
-
}
|
|
8098
|
-
}
|
|
8099
|
-
if (hasSetOption) {
|
|
8100
|
-
if (setValue === true) {
|
|
8101
|
-
withOptions.push('SET TRUE');
|
|
8102
|
-
}
|
|
8103
|
-
else if (setValue === false) {
|
|
8104
|
-
withOptions.push('SET FALSE');
|
|
8105
|
-
}
|
|
8106
|
-
}
|
|
8107
|
-
if (withOptions.length > 0) {
|
|
8108
|
-
output.push('WITH', withOptions.join(', '));
|
|
8109
|
-
}
|
|
8167
|
+
if (node.is_grant && options.length > 0) {
|
|
8168
|
+
const withOptions = options.map(opt => `${opt.defname.toUpperCase()} ${optionValue(opt) ? 'TRUE' : 'FALSE'}`);
|
|
8169
|
+
output.push('WITH', withOptions.join(', '));
|
|
8170
|
+
}
|
|
8171
|
+
if (node.grantor) {
|
|
8172
|
+
output.push('GRANTED BY', this.RoleSpec(node.grantor, context));
|
|
8173
|
+
}
|
|
8174
|
+
if (!node.is_grant && node.behavior === 'DROP_CASCADE') {
|
|
8175
|
+
output.push('CASCADE');
|
|
8110
8176
|
}
|
|
8111
8177
|
return output.join(' ');
|
|
8112
8178
|
}
|
|
@@ -8686,10 +8752,9 @@ export class Deparser {
|
|
|
8686
8752
|
switch (node.commandType) {
|
|
8687
8753
|
case 'CMD_UPDATE': {
|
|
8688
8754
|
output.push('UPDATE SET');
|
|
8689
|
-
|
|
8690
|
-
.
|
|
8691
|
-
|
|
8692
|
-
output.push(assignments);
|
|
8755
|
+
if (node.targetList && node.targetList.length > 0) {
|
|
8756
|
+
output.push(this.formatUpdateAssignments(node.targetList, context));
|
|
8757
|
+
}
|
|
8693
8758
|
break;
|
|
8694
8759
|
}
|
|
8695
8760
|
case 'CMD_INSERT': {
|
|
@@ -9094,6 +9159,13 @@ export class Deparser {
|
|
|
9094
9159
|
output.push('USING');
|
|
9095
9160
|
output.push(node.into.accessMethod);
|
|
9096
9161
|
}
|
|
9162
|
+
if (node.into && node.into.options && node.into.options.length > 0) {
|
|
9163
|
+
output.push('WITH');
|
|
9164
|
+
const options = ListUtils.unwrapList(node.into.options)
|
|
9165
|
+
.map(option => this.visit(option, context.spawn('CreateStmt')))
|
|
9166
|
+
.join(', ');
|
|
9167
|
+
output.push(`(${options})`);
|
|
9168
|
+
}
|
|
9097
9169
|
if (node.into && node.into.onCommit && node.into.onCommit !== 'ONCOMMIT_NOOP') {
|
|
9098
9170
|
output.push('ON COMMIT');
|
|
9099
9171
|
switch (node.into.onCommit) {
|
|
@@ -9108,17 +9180,13 @@ export class Deparser {
|
|
|
9108
9180
|
break;
|
|
9109
9181
|
}
|
|
9110
9182
|
}
|
|
9183
|
+
if (node.into && node.into.tableSpaceName) {
|
|
9184
|
+
output.push('TABLESPACE', QuoteUtils.quoteIdentifier(node.into.tableSpaceName));
|
|
9185
|
+
}
|
|
9111
9186
|
output.push('AS');
|
|
9112
9187
|
if (node.query) {
|
|
9113
9188
|
output.push(this.visit(node.query, context));
|
|
9114
9189
|
}
|
|
9115
|
-
if (node.into && node.into.options && node.into.options.length > 0) {
|
|
9116
|
-
output.push('WITH');
|
|
9117
|
-
const options = ListUtils.unwrapList(node.into.options)
|
|
9118
|
-
.map(option => this.visit(option, context))
|
|
9119
|
-
.join(', ');
|
|
9120
|
-
output.push(`(${options})`);
|
|
9121
|
-
}
|
|
9122
9190
|
if (node.into && node.into.skipData) {
|
|
9123
9191
|
output.push('WITH NO DATA');
|
|
9124
9192
|
}
|
|
@@ -9591,7 +9659,7 @@ export class Deparser {
|
|
|
9591
9659
|
}
|
|
9592
9660
|
if (node.whereClause) {
|
|
9593
9661
|
output.push('WHERE');
|
|
9594
|
-
output.push(this.visit(node.whereClause, context));
|
|
9662
|
+
output.push(`(${this.visit(node.whereClause, context)})`);
|
|
9595
9663
|
}
|
|
9596
9664
|
return output.join(' ');
|
|
9597
9665
|
}
|
|
@@ -9834,24 +9902,182 @@ export class Deparser {
|
|
|
9834
9902
|
}
|
|
9835
9903
|
return output.join(' ');
|
|
9836
9904
|
}
|
|
9905
|
+
formatJsonFormat(format) {
|
|
9906
|
+
if (!format || !format.format_type || format.format_type === 'JS_FORMAT_DEFAULT') {
|
|
9907
|
+
return null;
|
|
9908
|
+
}
|
|
9909
|
+
const parts = ['FORMAT JSON'];
|
|
9910
|
+
switch (format.encoding) {
|
|
9911
|
+
case 'JS_ENC_UTF8':
|
|
9912
|
+
parts.push('ENCODING UTF8');
|
|
9913
|
+
break;
|
|
9914
|
+
case 'JS_ENC_UTF16':
|
|
9915
|
+
parts.push('ENCODING UTF16');
|
|
9916
|
+
break;
|
|
9917
|
+
case 'JS_ENC_UTF32':
|
|
9918
|
+
parts.push('ENCODING UTF32');
|
|
9919
|
+
break;
|
|
9920
|
+
}
|
|
9921
|
+
return parts.join(' ');
|
|
9922
|
+
}
|
|
9923
|
+
formatJsonOutput(output, context) {
|
|
9924
|
+
if (!output || !output.typeName)
|
|
9925
|
+
return null;
|
|
9926
|
+
const parts = ['RETURNING', this.TypeName(output.typeName, context)];
|
|
9927
|
+
const format = this.formatJsonFormat(output.returning?.format);
|
|
9928
|
+
if (format)
|
|
9929
|
+
parts.push(format);
|
|
9930
|
+
return parts.join(' ');
|
|
9931
|
+
}
|
|
9932
|
+
formatJsonNullClause(absentOnNull) {
|
|
9933
|
+
return absentOnNull ? 'ABSENT ON NULL' : 'NULL ON NULL';
|
|
9934
|
+
}
|
|
9935
|
+
formatJsonUniqueClause(unique) {
|
|
9936
|
+
return unique ? 'WITH UNIQUE KEYS' : null;
|
|
9937
|
+
}
|
|
9938
|
+
JsonValueExpr(node, context) {
|
|
9939
|
+
const parts = [];
|
|
9940
|
+
if (node.raw_expr) {
|
|
9941
|
+
parts.push(this.visit(node.raw_expr, context));
|
|
9942
|
+
}
|
|
9943
|
+
const format = this.formatJsonFormat(node.format);
|
|
9944
|
+
if (format)
|
|
9945
|
+
parts.push(format);
|
|
9946
|
+
return parts.join(' ');
|
|
9947
|
+
}
|
|
9948
|
+
JsonKeyValue(node, context) {
|
|
9949
|
+
const key = node.key ? this.visit(node.key, context) : '';
|
|
9950
|
+
const value = node.value ? this.JsonValueExpr(node.value, context) : '';
|
|
9951
|
+
return `${key} : ${value}`;
|
|
9952
|
+
}
|
|
9953
|
+
JsonObjectConstructor(node, context) {
|
|
9954
|
+
const args = [];
|
|
9955
|
+
if (node.exprs && node.exprs.length > 0) {
|
|
9956
|
+
args.push(ListUtils.unwrapList(node.exprs).map(e => this.visit(e, context)).join(', '));
|
|
9957
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
9958
|
+
const unique = this.formatJsonUniqueClause(node.unique);
|
|
9959
|
+
if (unique)
|
|
9960
|
+
args.push(unique);
|
|
9961
|
+
}
|
|
9962
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
9963
|
+
if (output)
|
|
9964
|
+
args.push(output);
|
|
9965
|
+
return `JSON_OBJECT(${args.join(' ')})`;
|
|
9966
|
+
}
|
|
9967
|
+
JsonArrayConstructor(node, context) {
|
|
9968
|
+
const args = [];
|
|
9969
|
+
if (node.exprs && node.exprs.length > 0) {
|
|
9970
|
+
args.push(ListUtils.unwrapList(node.exprs).map(e => this.visit(e, context)).join(', '));
|
|
9971
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
9972
|
+
}
|
|
9973
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
9974
|
+
if (output)
|
|
9975
|
+
args.push(output);
|
|
9976
|
+
return `JSON_ARRAY(${args.join(' ')})`;
|
|
9977
|
+
}
|
|
9837
9978
|
JsonArrayQueryConstructor(node, context) {
|
|
9838
|
-
const
|
|
9979
|
+
const args = [];
|
|
9839
9980
|
if (node.query) {
|
|
9840
|
-
|
|
9981
|
+
args.push(this.visit(node.query, context));
|
|
9982
|
+
}
|
|
9983
|
+
const format = this.formatJsonFormat(node.format);
|
|
9984
|
+
if (format)
|
|
9985
|
+
args.push(format);
|
|
9986
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
9987
|
+
if (output)
|
|
9988
|
+
args.push(output);
|
|
9989
|
+
return `JSON_ARRAY(${args.join(' ')})`;
|
|
9990
|
+
}
|
|
9991
|
+
formatJsonAggSuffix(ctor, context) {
|
|
9992
|
+
if (!ctor)
|
|
9993
|
+
return '';
|
|
9994
|
+
let result = '';
|
|
9995
|
+
if (ctor.agg_filter) {
|
|
9996
|
+
result += ` FILTER (WHERE ${this.visit(ctor.agg_filter, context)})`;
|
|
9841
9997
|
}
|
|
9842
|
-
if (
|
|
9843
|
-
|
|
9998
|
+
if (ctor.over) {
|
|
9999
|
+
result += this.formatOverClause(ctor.over, context);
|
|
9844
10000
|
}
|
|
9845
|
-
|
|
9846
|
-
|
|
10001
|
+
return result;
|
|
10002
|
+
}
|
|
10003
|
+
JsonObjectAgg(node, context) {
|
|
10004
|
+
const args = [];
|
|
10005
|
+
if (node.arg) {
|
|
10006
|
+
args.push(this.JsonKeyValue(node.arg, context));
|
|
10007
|
+
}
|
|
10008
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
10009
|
+
const unique = this.formatJsonUniqueClause(node.unique);
|
|
10010
|
+
if (unique)
|
|
10011
|
+
args.push(unique);
|
|
10012
|
+
const output = this.formatJsonOutput(node.constructor?.output, context);
|
|
10013
|
+
if (output)
|
|
10014
|
+
args.push(output);
|
|
10015
|
+
return `JSON_OBJECTAGG(${args.join(' ')})${this.formatJsonAggSuffix(node.constructor, context)}`;
|
|
10016
|
+
}
|
|
10017
|
+
JsonArrayAgg(node, context) {
|
|
10018
|
+
const args = [];
|
|
10019
|
+
if (node.arg) {
|
|
10020
|
+
args.push(this.JsonValueExpr(node.arg, context));
|
|
9847
10021
|
}
|
|
9848
|
-
|
|
9849
|
-
|
|
10022
|
+
const aggOrder = node.constructor?.agg_order;
|
|
10023
|
+
if (aggOrder && aggOrder.length > 0) {
|
|
10024
|
+
const orderItems = ListUtils.unwrapList(aggOrder).map(item => this.visit(item, context));
|
|
10025
|
+
args.push(`ORDER BY ${orderItems.join(', ')}`);
|
|
9850
10026
|
}
|
|
9851
|
-
|
|
9852
|
-
|
|
10027
|
+
args.push(this.formatJsonNullClause(node.absent_on_null));
|
|
10028
|
+
const output = this.formatJsonOutput(node.constructor?.output, context);
|
|
10029
|
+
if (output)
|
|
10030
|
+
args.push(output);
|
|
10031
|
+
return `JSON_ARRAYAGG(${args.join(' ')})${this.formatJsonAggSuffix(node.constructor, context)}`;
|
|
10032
|
+
}
|
|
10033
|
+
JsonParseExpr(node, context) {
|
|
10034
|
+
const args = [];
|
|
10035
|
+
if (node.expr) {
|
|
10036
|
+
args.push(this.JsonValueExpr(node.expr, context));
|
|
9853
10037
|
}
|
|
9854
|
-
|
|
10038
|
+
const unique = this.formatJsonUniqueClause(node.unique_keys);
|
|
10039
|
+
if (unique)
|
|
10040
|
+
args.push(unique);
|
|
10041
|
+
return `JSON(${args.join(' ')})`;
|
|
10042
|
+
}
|
|
10043
|
+
JsonScalarExpr(node, context) {
|
|
10044
|
+
const expr = node.expr ? this.visit(node.expr, context) : '';
|
|
10045
|
+
return `JSON_SCALAR(${expr})`;
|
|
10046
|
+
}
|
|
10047
|
+
JsonSerializeExpr(node, context) {
|
|
10048
|
+
const args = [];
|
|
10049
|
+
if (node.expr) {
|
|
10050
|
+
args.push(this.JsonValueExpr(node.expr, context));
|
|
10051
|
+
}
|
|
10052
|
+
const output = this.formatJsonOutput(node.output, context);
|
|
10053
|
+
if (output)
|
|
10054
|
+
args.push(output);
|
|
10055
|
+
return `JSON_SERIALIZE(${args.join(' ')})`;
|
|
10056
|
+
}
|
|
10057
|
+
JsonIsPredicate(node, context) {
|
|
10058
|
+
const parts = [];
|
|
10059
|
+
if (node.expr) {
|
|
10060
|
+
parts.push(this.visit(node.expr, context));
|
|
10061
|
+
}
|
|
10062
|
+
const format = this.formatJsonFormat(node.format);
|
|
10063
|
+
if (format)
|
|
10064
|
+
parts.push(format);
|
|
10065
|
+
parts.push('IS JSON');
|
|
10066
|
+
switch (node.item_type) {
|
|
10067
|
+
case 'JS_TYPE_OBJECT':
|
|
10068
|
+
parts.push('OBJECT');
|
|
10069
|
+
break;
|
|
10070
|
+
case 'JS_TYPE_ARRAY':
|
|
10071
|
+
parts.push('ARRAY');
|
|
10072
|
+
break;
|
|
10073
|
+
case 'JS_TYPE_SCALAR':
|
|
10074
|
+
parts.push('SCALAR');
|
|
10075
|
+
break;
|
|
10076
|
+
}
|
|
10077
|
+
if (node.unique_keys) {
|
|
10078
|
+
parts.push('WITH UNIQUE KEYS');
|
|
10079
|
+
}
|
|
10080
|
+
return parts.join(' ');
|
|
9855
10081
|
}
|
|
9856
10082
|
RangeFunction(node, context) {
|
|
9857
10083
|
const output = [];
|