pgsql-deparser 13.19.0 → 13.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Auto-generated file with types stripped for better tree-shaking
3
+ * DO NOT EDIT - Generated by strip-direct-transformer-types.ts
4
+ */
5
+ /**
6
+ * Direct transformer from PG13 to PG18
7
+ * This transformer chains v13->...->v18 transformations
8
+ */
9
+ export declare class PG13ToPG18Transformer {
10
+ private v13to14;
11
+ private v14to15;
12
+ private v15to16;
13
+ private v16to17;
14
+ private v17to18;
15
+ transform(node: any): any;
16
+ /**
17
+ * Transform a single statement from PG13 to PG18
18
+ * @deprecated Use transform() instead, which handles all node types
19
+ */
20
+ transformStatement(stmt: any): any;
21
+ /**
22
+ * Type guard to check if a node is a ParseResult
23
+ */
24
+ private isParseResult;
25
+ }
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ /**
3
+ * Auto-generated file with types stripped for better tree-shaking
4
+ * DO NOT EDIT - Generated by strip-direct-transformer-types.ts
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PG13ToPG18Transformer = void 0;
8
+ const v13_to_v14_1 = require("./v13-to-v14");
9
+ const v14_to_v15_1 = require("./v14-to-v15");
10
+ const v15_to_v16_1 = require("./v15-to-v16");
11
+ const v16_to_v17_1 = require("./v16-to-v17");
12
+ const v17_to_v18_1 = require("./v17-to-v18");
13
+ /**
14
+ * Direct transformer from PG13 to PG18
15
+ * This transformer chains v13->...->v18 transformations
16
+ */
17
+ class PG13ToPG18Transformer {
18
+ v13to14 = new v13_to_v14_1.V13ToV14Transformer();
19
+ v14to15 = new v14_to_v15_1.V14ToV15Transformer();
20
+ v15to16 = new v15_to_v16_1.V15ToV16Transformer();
21
+ v16to17 = new v16_to_v17_1.V16ToV17Transformer();
22
+ v17to18 = new v17_to_v18_1.V17ToV18Transformer();
23
+ transform(node) {
24
+ if (this.isParseResult(node)) {
25
+ // Transform through the chain: v13->v14->v15->v16->v17->v18
26
+ const v14Stmts = node.stmts.map((stmtWrapper) => {
27
+ if (stmtWrapper.stmt) {
28
+ const stmt = this.v13to14.transform(stmtWrapper.stmt, { parentNodeTypes: [] });
29
+ return { ...stmtWrapper, stmt };
30
+ }
31
+ return stmtWrapper;
32
+ });
33
+ const v15Stmts = v14Stmts.map((stmtWrapper) => {
34
+ if (stmtWrapper.stmt) {
35
+ const stmt = this.v14to15.transform(stmtWrapper.stmt, { parentNodeTypes: [] });
36
+ return { ...stmtWrapper, stmt };
37
+ }
38
+ return stmtWrapper;
39
+ });
40
+ const v16Stmts = v15Stmts.map((stmtWrapper) => {
41
+ if (stmtWrapper.stmt) {
42
+ const stmt = this.v15to16.transform(stmtWrapper.stmt, { parentNodeTypes: [] });
43
+ return { ...stmtWrapper, stmt };
44
+ }
45
+ return stmtWrapper;
46
+ });
47
+ const v17Stmts = v16Stmts.map((stmtWrapper) => {
48
+ if (stmtWrapper.stmt) {
49
+ const stmt = this.v16to17.transform(stmtWrapper.stmt, { parentNodeTypes: [] });
50
+ return { ...stmtWrapper, stmt };
51
+ }
52
+ return stmtWrapper;
53
+ });
54
+ const v18Stmts = v17Stmts.map((stmtWrapper) => {
55
+ if (stmtWrapper.stmt) {
56
+ const stmt = this.v17to18.transform(stmtWrapper.stmt, { parentNodeTypes: [] });
57
+ return { ...stmtWrapper, stmt };
58
+ }
59
+ return stmtWrapper;
60
+ });
61
+ return {
62
+ ...node,
63
+ version: 180004, // PG18 version
64
+ stmts: v18Stmts
65
+ };
66
+ }
67
+ // Otherwise, transform as a regular node through the chain
68
+ const v14Node = this.v13to14.transform(node, { parentNodeTypes: [] });
69
+ const v15Node = this.v14to15.transform(v14Node, { parentNodeTypes: [] });
70
+ const v16Node = this.v15to16.transform(v15Node, { parentNodeTypes: [] });
71
+ const v17Node = this.v16to17.transform(v16Node, { parentNodeTypes: [] });
72
+ return this.v17to18.transform(v17Node, { parentNodeTypes: [] });
73
+ }
74
+ /**
75
+ * Transform a single statement from PG13 to PG18
76
+ * @deprecated Use transform() instead, which handles all node types
77
+ */
78
+ transformStatement(stmt) {
79
+ const v14Stmt = this.v13to14.transform(stmt, { parentNodeTypes: [] });
80
+ const v15Stmt = this.v14to15.transform(v14Stmt, { parentNodeTypes: [] });
81
+ const v16Stmt = this.v15to16.transform(v15Stmt, { parentNodeTypes: [] });
82
+ const v17Stmt = this.v16to17.transform(v16Stmt, { parentNodeTypes: [] });
83
+ return this.v17to18.transform(v17Stmt, { parentNodeTypes: [] });
84
+ }
85
+ /**
86
+ * Type guard to check if a node is a ParseResult
87
+ */
88
+ isParseResult(node) {
89
+ return node && typeof node === 'object' && 'version' in node && 'stmts' in node;
90
+ }
91
+ }
92
+ exports.PG13ToPG18Transformer = PG13ToPG18Transformer;
package/v14-to-v15.d.ts CHANGED
@@ -342,6 +342,7 @@ export declare class V14ToV15Transformer {
342
342
  StatsElem(node: any, context: any): {
343
343
  StatsElem: any;
344
344
  };
345
+ private publicationTablesToObjects;
345
346
  CreatePublicationStmt(node: any, context: any): {
346
347
  CreatePublicationStmt: any;
347
348
  };
package/v14-to-v15.js CHANGED
@@ -831,8 +831,21 @@ class V14ToV15Transformer {
831
831
  const result = this.transformGenericNode(node, context);
832
832
  return { StatsElem: result };
833
833
  }
834
+ // PG15 replaced the publication's list of tables with a list of PublicationObjSpec
835
+ publicationTablesToObjects(result) {
836
+ if (result.tables === undefined)
837
+ return;
838
+ result.pubobjects = (Array.isArray(result.tables) ? result.tables : [result.tables]).map((table) => ({
839
+ PublicationObjSpec: {
840
+ pubobjtype: 'PUBLICATIONOBJ_TABLE',
841
+ pubtable: { relation: table.RangeVar ?? table }
842
+ }
843
+ }));
844
+ delete result.tables;
845
+ }
834
846
  CreatePublicationStmt(node, context) {
835
847
  const result = this.transformGenericNode(node, context);
848
+ this.publicationTablesToObjects(result);
836
849
  return { CreatePublicationStmt: result };
837
850
  }
838
851
  CreateSubscriptionStmt(node, context) {
@@ -841,10 +854,31 @@ class V14ToV15Transformer {
841
854
  }
842
855
  AlterPublicationStmt(node, context) {
843
856
  const result = this.transformGenericNode(node, context);
857
+ this.publicationTablesToObjects(result);
858
+ if (result.tableAction !== undefined) {
859
+ const actions = {
860
+ DEFELEM_ADD: 'AP_AddObjects',
861
+ DEFELEM_DROP: 'AP_DropObjects',
862
+ DEFELEM_SET: 'AP_SetObjects'
863
+ };
864
+ if (actions[result.tableAction]) {
865
+ result.action = actions[result.tableAction];
866
+ }
867
+ delete result.tableAction;
868
+ }
844
869
  return { AlterPublicationStmt: result };
845
870
  }
846
871
  AlterSubscriptionStmt(node, context) {
847
872
  const result = this.transformGenericNode(node, context);
873
+ // ENABLE / DISABLE carried an Integer before PG15 introduced the Boolean node
874
+ if (result.kind === 'ALTER_SUBSCRIPTION_ENABLED' && Array.isArray(result.options)) {
875
+ result.options = result.options.map((option) => {
876
+ const ival = option?.DefElem?.arg?.Integer;
877
+ if (option?.DefElem?.defname !== 'enabled' || !ival)
878
+ return option;
879
+ return { DefElem: { ...option.DefElem, arg: { Boolean: { boolval: ival.ival === 1 } } } };
880
+ });
881
+ }
848
882
  return { AlterSubscriptionStmt: result };
849
883
  }
850
884
  DropSubscriptionStmt(node, context) {
package/v15-to-v16.js CHANGED
@@ -793,9 +793,9 @@ class V15ToV16Transformer {
793
793
  const partspec = { ...node.partspec };
794
794
  if (partspec.strategy !== undefined) {
795
795
  const strategyMap = {
796
- 'range': 'PARTITION_STRATEGY_RANGE',
797
- 'list': 'PARTITION_STRATEGY_LIST',
798
- 'hash': 'PARTITION_STRATEGY_HASH'
796
+ range: 'PARTITION_STRATEGY_RANGE',
797
+ list: 'PARTITION_STRATEGY_LIST',
798
+ hash: 'PARTITION_STRATEGY_HASH'
799
799
  };
800
800
  partspec.strategy = strategyMap[partspec.strategy] || partspec.strategy;
801
801
  }
@@ -857,6 +857,9 @@ class V15ToV16Transformer {
857
857
  if (node.storage !== undefined) {
858
858
  result.storage = node.storage;
859
859
  }
860
+ if (node.compression !== undefined) {
861
+ result.compression = node.compression;
862
+ }
860
863
  if (node.raw_default !== undefined) {
861
864
  result.raw_default = this.transform(node.raw_default, context);
862
865
  }
@@ -979,6 +982,11 @@ class V15ToV16Transformer {
979
982
  if (node.fk_del_action !== undefined) {
980
983
  result.fk_del_action = node.fk_del_action;
981
984
  }
985
+ if (node.fk_del_set_cols !== undefined) {
986
+ result.fk_del_set_cols = Array.isArray(node.fk_del_set_cols)
987
+ ? node.fk_del_set_cols.map((item) => this.transform(item, context))
988
+ : this.transform(node.fk_del_set_cols, context);
989
+ }
982
990
  if (node.old_conpfeqop !== undefined) {
983
991
  result.old_conpfeqop = Array.isArray(node.old_conpfeqop)
984
992
  ? node.old_conpfeqop.map((item) => this.transform(item, context))
@@ -2554,13 +2562,13 @@ class V15ToV16Transformer {
2554
2562
  result.opt = [
2555
2563
  {
2556
2564
  DefElem: {
2557
- defname: "admin",
2565
+ defname: 'admin',
2558
2566
  arg: {
2559
2567
  Boolean: {
2560
2568
  boolval: true
2561
2569
  }
2562
2570
  },
2563
- defaction: "DEFELEM_UNSPEC"
2571
+ defaction: 'DEFELEM_UNSPEC'
2564
2572
  }
2565
2573
  }
2566
2574
  ];
@@ -2571,6 +2579,9 @@ class V15ToV16Transformer {
2571
2579
  ? nodeAny.opt.map((item) => this.transform(item, context))
2572
2580
  : this.transform(nodeAny.opt, context);
2573
2581
  }
2582
+ if (node.grantor !== undefined) {
2583
+ result.grantor = node.grantor;
2584
+ }
2574
2585
  return { GrantRoleStmt: result };
2575
2586
  }
2576
2587
  SecLabelStmt(node, context) {
package/v16-to-v17.d.ts CHANGED
@@ -496,6 +496,9 @@ export declare class V16ToV17Transformer {
496
496
  MergeStmt(node: any, context: any): {
497
497
  MergeStmt: any;
498
498
  };
499
+ MergeWhenClause(node: any, context: any): {
500
+ MergeWhenClause: any;
501
+ };
499
502
  AlterTableMoveAllStmt(node: any, context: any): {
500
503
  AlterTableMoveAllStmt: any;
501
504
  };
package/v16-to-v17.js CHANGED
@@ -655,6 +655,12 @@ class V16ToV17Transformer {
655
655
  if (node.storage !== undefined) {
656
656
  result.storage = node.storage;
657
657
  }
658
+ if (node.storage_name !== undefined) {
659
+ result.storage_name = node.storage_name;
660
+ }
661
+ if (node.compression !== undefined) {
662
+ result.compression = node.compression;
663
+ }
658
664
  if (node.raw_default !== undefined) {
659
665
  result.raw_default = this.transform(node.raw_default, context);
660
666
  }
@@ -1113,7 +1119,50 @@ class V16ToV17Transformer {
1113
1119
  return { AlterOpFamilyStmt: node };
1114
1120
  }
1115
1121
  MergeStmt(node, context) {
1116
- return { MergeStmt: node };
1122
+ const result = {};
1123
+ if (node.relation !== undefined) {
1124
+ result.relation = node.relation;
1125
+ }
1126
+ if (node.sourceRelation !== undefined) {
1127
+ result.sourceRelation = this.transform(node.sourceRelation, context);
1128
+ }
1129
+ if (node.joinCondition !== undefined) {
1130
+ result.joinCondition = this.transform(node.joinCondition, context);
1131
+ }
1132
+ if (node.mergeWhenClauses !== undefined) {
1133
+ result.mergeWhenClauses = Array.isArray(node.mergeWhenClauses)
1134
+ ? node.mergeWhenClauses.map(item => this.transform(item, context))
1135
+ : this.transform(node.mergeWhenClauses, context);
1136
+ }
1137
+ if (node.withClause !== undefined) {
1138
+ result.withClause = this.WithClause(node.withClause, context);
1139
+ }
1140
+ return { MergeStmt: result };
1141
+ }
1142
+ MergeWhenClause(node, context) {
1143
+ const result = {};
1144
+ // v17 replaces the boolean matched with matchKind
1145
+ result.matchKind = node.matched ? 'MERGE_WHEN_MATCHED' : 'MERGE_WHEN_NOT_MATCHED_BY_TARGET';
1146
+ if (node.commandType !== undefined) {
1147
+ result.commandType = node.commandType;
1148
+ }
1149
+ if (node.override !== undefined) {
1150
+ result.override = node.override;
1151
+ }
1152
+ if (node.condition !== undefined) {
1153
+ result.condition = this.transform(node.condition, context);
1154
+ }
1155
+ if (node.targetList !== undefined) {
1156
+ result.targetList = Array.isArray(node.targetList)
1157
+ ? node.targetList.map(item => this.transform(item, context))
1158
+ : this.transform(node.targetList, context);
1159
+ }
1160
+ if (node.values !== undefined) {
1161
+ result.values = Array.isArray(node.values)
1162
+ ? node.values.map(item => this.transform(item, context))
1163
+ : this.transform(node.values, context);
1164
+ }
1165
+ return { MergeWhenClause: result };
1117
1166
  }
1118
1167
  AlterTableMoveAllStmt(node, context) {
1119
1168
  return { AlterTableMoveAllStmt: node };
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Auto-generated file with types stripped for better tree-shaking
3
+ * DO NOT EDIT - Generated by strip-transformer-types.ts
4
+ */
5
+ /**
6
+ * V17 to V18 AST Transformer
7
+ * Transforms PostgreSQL v17 AST nodes to v18 format
8
+ *
9
+ * Structural changes in v18:
10
+ * - InsertStmt/UpdateStmt/DeleteStmt/MergeStmt: returningList -> returningClause { exprs }
11
+ * - Constraint: new is_enforced flag (true by default for CHECK/FOREIGN/NOTNULL)
12
+ * - Constraint: CONSTR_GENERATED gains generated_kind ('s' = STORED, 'v' = VIRTUAL)
13
+ * - Column-level NOT NULL constraints gain initially_valid: true
14
+ */
15
+ export declare class V17ToV18Transformer {
16
+ transform(node: any, context?: any): any;
17
+ visit(node: any, context?: any): any;
18
+ /**
19
+ * Generic recursive walk that re-dispatches wrapped nodes with a
20
+ * dedicated transformer method and deep-copies everything else.
21
+ */
22
+ private walkValue;
23
+ getNodeType(node: any): any;
24
+ getNodeData(node: any): any;
25
+ ParseResult(node: any, context: any): any;
26
+ RawStmt(node: any, context: any): {
27
+ RawStmt: any;
28
+ };
29
+ /**
30
+ * Convert a v17 returningList into a v18 ReturningClause
31
+ */
32
+ private transformReturningList;
33
+ private transformDmlStatement;
34
+ InsertStmt(node: any, context: any): {
35
+ InsertStmt: any;
36
+ };
37
+ UpdateStmt(node: any, context: any): {
38
+ UpdateStmt: any;
39
+ };
40
+ DeleteStmt(node: any, context: any): {
41
+ DeleteStmt: any;
42
+ };
43
+ MergeStmt(node: any, context: any): {
44
+ MergeStmt: any;
45
+ };
46
+ AlterTableCmd(node: any, context: any): {
47
+ AlterTableCmd: any;
48
+ };
49
+ VariableSetStmt(node: any, context: any): {
50
+ VariableSetStmt: any;
51
+ };
52
+ Constraint(node: any, context: any): {
53
+ Constraint: any;
54
+ };
55
+ }
package/v17-to-v18.js ADDED
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ /**
3
+ * Auto-generated file with types stripped for better tree-shaking
4
+ * DO NOT EDIT - Generated by strip-transformer-types.ts
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.V17ToV18Transformer = void 0;
8
+ // @ts-nocheck
9
+ /**
10
+ * V17 to V18 AST Transformer
11
+ * Transforms PostgreSQL v17 AST nodes to v18 format
12
+ *
13
+ * Structural changes in v18:
14
+ * - InsertStmt/UpdateStmt/DeleteStmt/MergeStmt: returningList -> returningClause { exprs }
15
+ * - Constraint: new is_enforced flag (true by default for CHECK/FOREIGN/NOTNULL)
16
+ * - Constraint: CONSTR_GENERATED gains generated_kind ('s' = STORED, 'v' = VIRTUAL)
17
+ * - Column-level NOT NULL constraints gain initially_valid: true
18
+ */
19
+ class V17ToV18Transformer {
20
+ transform(node, context = { parentNodeTypes: [] }) {
21
+ if (node == null) {
22
+ return null;
23
+ }
24
+ if (typeof node === 'number' || node instanceof Number) {
25
+ return node;
26
+ }
27
+ if (typeof node === 'string') {
28
+ return node;
29
+ }
30
+ try {
31
+ return this.visit(node, context);
32
+ }
33
+ catch (error) {
34
+ const nodeType = Object.keys(node)[0];
35
+ throw new Error(`Error transforming ${nodeType}: ${error.message}`);
36
+ }
37
+ }
38
+ visit(node, context = { parentNodeTypes: [] }) {
39
+ if (node && typeof node === 'object' && 'version' in node && 'stmts' in node) {
40
+ return this.ParseResult(node, context);
41
+ }
42
+ const nodeType = this.getNodeType(node);
43
+ // Handle empty objects
44
+ if (!nodeType) {
45
+ return {};
46
+ }
47
+ const nodeData = this.getNodeData(node);
48
+ const methodName = nodeType;
49
+ if (typeof this[methodName] === 'function') {
50
+ const childContext = {
51
+ ...context,
52
+ parentNodeTypes: [...context.parentNodeTypes, nodeType]
53
+ };
54
+ const result = this[methodName](nodeData, childContext);
55
+ return result;
56
+ }
57
+ // No specific method: recurse into children so nested statements
58
+ // (e.g. DML inside CTEs) still get transformed
59
+ return this.walkValue(node, context);
60
+ }
61
+ /**
62
+ * Generic recursive walk that re-dispatches wrapped nodes with a
63
+ * dedicated transformer method and deep-copies everything else.
64
+ */
65
+ walkValue(value, context) {
66
+ if (value == null || typeof value !== 'object') {
67
+ return value;
68
+ }
69
+ if (Array.isArray(value)) {
70
+ return value.map(item => this.walkValue(item, context));
71
+ }
72
+ const keys = Object.keys(value);
73
+ if (keys.length === 1 && typeof this[keys[0]] === 'function') {
74
+ // Wrapped node with a dedicated transformer method
75
+ return this.visit(value, context);
76
+ }
77
+ const result = {};
78
+ for (const key of keys) {
79
+ result[key] = this.walkValue(value[key], context);
80
+ }
81
+ return result;
82
+ }
83
+ getNodeType(node) {
84
+ return Object.keys(node)[0];
85
+ }
86
+ getNodeData(node) {
87
+ const keys = Object.keys(node);
88
+ if (keys.length === 1 && typeof node[keys[0]] === 'object') {
89
+ return node[keys[0]];
90
+ }
91
+ return node;
92
+ }
93
+ ParseResult(node, context) {
94
+ if (node && typeof node === 'object' && 'version' in node && 'stmts' in node) {
95
+ return {
96
+ version: 180004, // PG18 version
97
+ stmts: node.stmts.map((stmt) => {
98
+ if (stmt && typeof stmt === 'object' && 'stmt' in stmt) {
99
+ return {
100
+ ...stmt,
101
+ stmt: this.transform(stmt.stmt, context)
102
+ };
103
+ }
104
+ return this.transform(stmt, context);
105
+ })
106
+ };
107
+ }
108
+ return node;
109
+ }
110
+ RawStmt(node, context) {
111
+ const result = {};
112
+ if (node.stmt !== undefined) {
113
+ result.stmt = this.transform(node.stmt, context);
114
+ }
115
+ if (node.stmt_location !== undefined) {
116
+ result.stmt_location = node.stmt_location;
117
+ }
118
+ if (node.stmt_len !== undefined) {
119
+ result.stmt_len = node.stmt_len;
120
+ }
121
+ return { RawStmt: result };
122
+ }
123
+ /**
124
+ * Convert a v17 returningList into a v18 ReturningClause
125
+ */
126
+ transformReturningList(returningList, context) {
127
+ return {
128
+ exprs: returningList.map(item => this.transform(item, context))
129
+ };
130
+ }
131
+ transformDmlStatement(nodeType, node, context) {
132
+ const result = {};
133
+ for (const key of Object.keys(node)) {
134
+ if (key === 'returningList') {
135
+ result.returningClause = this.transformReturningList(node.returningList, context);
136
+ }
137
+ else {
138
+ result[key] = this.walkValue(node[key], context);
139
+ }
140
+ }
141
+ return { [nodeType]: result };
142
+ }
143
+ InsertStmt(node, context) {
144
+ return this.transformDmlStatement('InsertStmt', node, context);
145
+ }
146
+ UpdateStmt(node, context) {
147
+ return this.transformDmlStatement('UpdateStmt', node, context);
148
+ }
149
+ DeleteStmt(node, context) {
150
+ return this.transformDmlStatement('DeleteStmt', node, context);
151
+ }
152
+ MergeStmt(node, context) {
153
+ return this.transformDmlStatement('MergeStmt', node, context);
154
+ }
155
+ AlterTableCmd(node, context) {
156
+ const result = {};
157
+ for (const key of Object.keys(node)) {
158
+ result[key] = this.walkValue(node[key], context);
159
+ }
160
+ // v18 wraps ALTER CONSTRAINT definitions in the new ATAlterConstraint node
161
+ if (node.subtype === 'AT_AlterConstraint' && node.def?.Constraint) {
162
+ const constraint = node.def.Constraint;
163
+ const alterConstraint = {};
164
+ if (constraint.conname !== undefined) {
165
+ alterConstraint.conname = constraint.conname;
166
+ }
167
+ alterConstraint.is_enforced = true;
168
+ // v17 ALTER CONSTRAINT could only change deferrability
169
+ alterConstraint.alterDeferrability = true;
170
+ if (constraint.deferrable !== undefined) {
171
+ alterConstraint.deferrable = constraint.deferrable;
172
+ }
173
+ if (constraint.initdeferred !== undefined) {
174
+ alterConstraint.initdeferred = constraint.initdeferred;
175
+ }
176
+ result.def = { ATAlterConstraint: alterConstraint };
177
+ }
178
+ return { AlterTableCmd: result };
179
+ }
180
+ VariableSetStmt(node, context) {
181
+ const result = {};
182
+ for (const key of Object.keys(node)) {
183
+ result[key] = this.walkValue(node[key], context);
184
+ }
185
+ // v18 marks SET TRANSACTION / SESSION CHARACTERISTICS args as jumbled
186
+ if (node.kind === 'VAR_SET_MULTI' && (node.name === 'TRANSACTION' || node.name === 'SESSION CHARACTERISTICS')) {
187
+ result.jumble_args = true;
188
+ }
189
+ return { VariableSetStmt: result };
190
+ }
191
+ Constraint(node, context) {
192
+ const result = {};
193
+ for (const key of Object.keys(node)) {
194
+ result[key] = this.walkValue(node[key], context);
195
+ }
196
+ // v18 constraints are enforced by default; v17 grammar had no ENFORCED syntax
197
+ if (node.contype === 'CONSTR_CHECK' || node.contype === 'CONSTR_FOREIGN') {
198
+ result.is_enforced = true;
199
+ }
200
+ if (node.contype === 'CONSTR_NOTNULL') {
201
+ // v17 only produces column-level NOT NULL constraints, which in v18
202
+ // carry is_enforced and initially_valid
203
+ result.is_enforced = true;
204
+ result.initially_valid = true;
205
+ }
206
+ if (node.contype === 'CONSTR_GENERATED' && result.generated_kind === undefined) {
207
+ // v17 only supports STORED generated columns
208
+ result.generated_kind = 's';
209
+ }
210
+ return { Constraint: result };
211
+ }
212
+ }
213
+ exports.V17ToV18Transformer = V17ToV18Transformer;