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.
- package/README.md +23 -16
- package/deparser/deparser.d.ts +37 -28
- package/deparser/deparser.js +1413 -948
- package/deparser/index.d.ts +3 -1
- package/deparser/index.js +5 -1
- package/deparser/utils/sql-formatter.d.ts +8 -0
- package/deparser/utils/sql-formatter.js +104 -1
- package/esm/deparser/deparser.js +1396 -931
- package/esm/deparser/index.js +3 -1
- package/esm/deparser/utils/sql-formatter.js +103 -1
- package/esm/index.js +101 -7
- package/esm/v13-to-v14.js +76 -29
- package/esm/v13-to-v18-direct.js +88 -0
- package/esm/v14-to-v15.js +34 -0
- package/esm/v15-to-v16.js +16 -5
- package/esm/v16-to-v17.js +50 -1
- package/esm/v17-to-v18.js +209 -0
- package/index.d.ts +18 -4
- package/index.js +104 -6
- package/package.json +7 -6
- package/v13-to-v14.d.ts +6 -0
- package/v13-to-v14.js +76 -29
- package/v13-to-v18-direct.d.ts +25 -0
- package/v13-to-v18-direct.js +92 -0
- package/v14-to-v15.d.ts +1 -0
- package/v14-to-v15.js +34 -0
- package/v15-to-v16.js +16 -5
- package/v16-to-v17.d.ts +3 -0
- package/v16-to-v17.js +50 -1
- package/v17-to-v18.d.ts +55 -0
- package/v17-to-v18.js +213 -0
package/esm/deparser/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Auto-generated file with types stripped for better tree-shaking
|
|
3
3
|
* DO NOT EDIT - Generated by strip-deparser-types.ts
|
|
4
4
|
*/
|
|
5
|
-
import { Deparser } from
|
|
5
|
+
import { Deparser } from './deparser';
|
|
6
6
|
const deparseMethod = Deparser.deparse;
|
|
7
7
|
// Export the original sync version as deparseSync
|
|
8
8
|
export const deparseSync = deparseMethod;
|
|
@@ -11,3 +11,5 @@ export const deparse = async (...args) => {
|
|
|
11
11
|
return deparseMethod(...args);
|
|
12
12
|
};
|
|
13
13
|
export { Deparser };
|
|
14
|
+
export { splitSqlLines } from './utils/sql-formatter';
|
|
15
|
+
export { QuoteUtils } from '@pgsql/quotes';
|
|
@@ -2,6 +2,108 @@
|
|
|
2
2
|
* Auto-generated file with types stripped for better tree-shaking
|
|
3
3
|
* DO NOT EDIT - Generated by strip-deparser-types.ts
|
|
4
4
|
*/
|
|
5
|
+
const isIdentChar = (ch) => ch !== undefined && (/[A-Za-z0-9_$]/.test(ch) || ch.charCodeAt(0) >= 0x80);
|
|
6
|
+
const DOLLAR_TAG = /\$(?:[A-Za-z_\u0080-\uffff][A-Za-z0-9_\u0080-\uffff]*)?\$/y;
|
|
7
|
+
/**
|
|
8
|
+
* Splits SQL text into lines, breaking only at newlines that sit between
|
|
9
|
+
* tokens. A newline inside a string literal ('...', E'...', $tag$...$tag$),
|
|
10
|
+
* a quoted identifier or a block comment is part of that token's value and
|
|
11
|
+
* stays inside its line, so callers can re-indent the lines without changing
|
|
12
|
+
* what the SQL means.
|
|
13
|
+
*/
|
|
14
|
+
export function splitSqlLines(text, newlineChar = '\n') {
|
|
15
|
+
if (!newlineChar || !text.includes(newlineChar)) {
|
|
16
|
+
return [text];
|
|
17
|
+
}
|
|
18
|
+
const lines = [];
|
|
19
|
+
const length = text.length;
|
|
20
|
+
let lineStart = 0;
|
|
21
|
+
let i = 0;
|
|
22
|
+
while (i < length) {
|
|
23
|
+
const ch = text[i];
|
|
24
|
+
if (ch === "'") {
|
|
25
|
+
const prev = text[i - 1];
|
|
26
|
+
const backslashEscapes = (prev === 'E' || prev === 'e') && !isIdentChar(text[i - 2]);
|
|
27
|
+
i++;
|
|
28
|
+
while (i < length) {
|
|
29
|
+
if (backslashEscapes && text[i] === '\\') {
|
|
30
|
+
i += 2;
|
|
31
|
+
}
|
|
32
|
+
else if (text[i] === "'") {
|
|
33
|
+
if (text[i + 1] === "'") {
|
|
34
|
+
i += 2;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
i++;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
i++;
|
|
45
|
+
}
|
|
46
|
+
else if (ch === '"') {
|
|
47
|
+
i++;
|
|
48
|
+
while (i < length) {
|
|
49
|
+
if (text[i] === '"') {
|
|
50
|
+
if (text[i + 1] === '"') {
|
|
51
|
+
i += 2;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
i++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
i++;
|
|
62
|
+
}
|
|
63
|
+
else if (ch === '$' && !isIdentChar(text[i - 1])) {
|
|
64
|
+
DOLLAR_TAG.lastIndex = i;
|
|
65
|
+
const tag = DOLLAR_TAG.exec(text);
|
|
66
|
+
if (tag) {
|
|
67
|
+
const close = text.indexOf(tag[0], i + tag[0].length);
|
|
68
|
+
i = close === -1 ? length : close + tag[0].length;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
i++;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (ch === '-' && text[i + 1] === '-') {
|
|
75
|
+
const end = text.indexOf('\n', i);
|
|
76
|
+
i = end === -1 ? length : end;
|
|
77
|
+
}
|
|
78
|
+
else if (ch === '/' && text[i + 1] === '*') {
|
|
79
|
+
let depth = 1;
|
|
80
|
+
i += 2;
|
|
81
|
+
while (i < length && depth > 0) {
|
|
82
|
+
if (text[i] === '/' && text[i + 1] === '*') {
|
|
83
|
+
depth++;
|
|
84
|
+
i += 2;
|
|
85
|
+
}
|
|
86
|
+
else if (text[i] === '*' && text[i + 1] === '/') {
|
|
87
|
+
depth--;
|
|
88
|
+
i += 2;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
i++;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else if (text.startsWith(newlineChar, i)) {
|
|
96
|
+
lines.push(text.slice(lineStart, i));
|
|
97
|
+
i += newlineChar.length;
|
|
98
|
+
lineStart = i;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
i++;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
lines.push(text.slice(lineStart));
|
|
105
|
+
return lines;
|
|
106
|
+
}
|
|
5
107
|
export class SqlFormatter {
|
|
6
108
|
newlineChar;
|
|
7
109
|
tabChar;
|
|
@@ -19,7 +121,7 @@ export class SqlFormatter {
|
|
|
19
121
|
return text;
|
|
20
122
|
}
|
|
21
123
|
const indentation = this.tabChar.repeat(count);
|
|
22
|
-
return text
|
|
124
|
+
return splitSqlLines(text, this.newlineChar).map(line => line.trim() ? indentation + line : line).join(this.newlineChar);
|
|
23
125
|
}
|
|
24
126
|
parens(content) {
|
|
25
127
|
return `(${content})`;
|
package/esm/index.js
CHANGED
|
@@ -2,14 +2,108 @@
|
|
|
2
2
|
* Deparser for PostgreSQL version 13
|
|
3
3
|
* Auto-generated by generate-version-deparsers.ts
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
const tx = new
|
|
5
|
+
import { Deparser as Deparser18 } from './deparser';
|
|
6
|
+
import { PG13ToPG18Transformer } from './v13-to-v18-direct';
|
|
7
|
+
const tx = new PG13ToPG18Transformer();
|
|
8
|
+
const bare = (names, name) => Array.isArray(names) && names.length === 1 && (names[0]?.String?.sval ?? names[0]?.String?.str) === name;
|
|
9
|
+
const v16to17 = tx.v16to17;
|
|
10
|
+
const upgradeTypeName = v16to17.TypeName.bind(v16to17);
|
|
11
|
+
v16to17.TypeName = (node, context) => {
|
|
12
|
+
const out = upgradeTypeName(node, context);
|
|
13
|
+
if (bare(node.names, 'json'))
|
|
14
|
+
out.TypeName.names = [{ String: { sval: 'json' } }];
|
|
15
|
+
return out;
|
|
16
|
+
};
|
|
17
|
+
const upgradeTypeCast = v16to17.TypeCast.bind(v16to17);
|
|
18
|
+
v16to17.TypeCast = (node, context) => {
|
|
19
|
+
const out = upgradeTypeCast(node, context);
|
|
20
|
+
const typeName = out.TypeCast.typeName?.TypeName ?? out.TypeCast.typeName;
|
|
21
|
+
if (typeName && bare((node.typeName?.TypeName ?? node.typeName)?.names, 'json')) {
|
|
22
|
+
typeName.names = [{ String: { sval: 'json' } }];
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
};
|
|
26
|
+
const v15to16 = tx.v15to16;
|
|
27
|
+
const upgradeFuncCall = v15to16.FuncCall.bind(v15to16);
|
|
28
|
+
v15to16.FuncCall = (node, context) => {
|
|
29
|
+
const out = upgradeFuncCall(node, context);
|
|
30
|
+
if (out.FuncCall && bare(node.funcname, 'json_object')) {
|
|
31
|
+
out.FuncCall.funcname = [{ String: { sval: 'json_object' } }];
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
};
|
|
35
|
+
const v13to14 = tx.v13to14;
|
|
36
|
+
const upgradeSubstring = v13to14.FuncCall.bind(v13to14);
|
|
37
|
+
v13to14.FuncCall = (node, context) => {
|
|
38
|
+
const out = upgradeSubstring(node, context);
|
|
39
|
+
const [schema, name] = (node.funcname ?? []).map((part) => part?.String?.str ?? part?.String?.sval);
|
|
40
|
+
const argCount = node.args?.length;
|
|
41
|
+
if (out.FuncCall && node.funcname?.length === 2 && schema === 'pg_catalog' && name === 'substring' && (argCount === 2 || argCount === 3)) {
|
|
42
|
+
out.FuncCall.funcname = [{ String: { sval: 'pg_catalog' } }, { String: { sval: 'substring' } }];
|
|
43
|
+
out.FuncCall.funcformat = 'COERCE_SQL_SYNTAX';
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
};
|
|
47
|
+
const toAst18 = (query) => Array.isArray(query) ? query.map(node => tx.transform(node)) : tx.transform(query);
|
|
48
|
+
export class Deparser extends Deparser18 {
|
|
49
|
+
constructor(tree, opts = {}) {
|
|
50
|
+
super(toAst18(tree), opts);
|
|
51
|
+
}
|
|
52
|
+
static deparse(query, opts = {}) {
|
|
53
|
+
return new Deparser(query, opts).deparseQuery();
|
|
54
|
+
}
|
|
55
|
+
DefElem(node, context) {
|
|
56
|
+
if (!node.arg && node.defaction !== 'DEFELEM_DROP' && context.parentNodeTypes.includes('AlterOperatorStmt')) {
|
|
57
|
+
return `${node.defname} = NONE`;
|
|
58
|
+
}
|
|
59
|
+
return super.DefElem(node, context);
|
|
60
|
+
}
|
|
61
|
+
GrantRoleStmt(node, context) {
|
|
62
|
+
const sql = super.GrantRoleStmt(node, context);
|
|
63
|
+
const opts = (Array.isArray(node.opt) ? node.opt : []).map((opt) => opt.DefElem);
|
|
64
|
+
const arg = opts[0]?.arg;
|
|
65
|
+
const off = arg?.Boolean ? arg.Boolean.boolval !== true : arg?.String?.sval === 'false';
|
|
66
|
+
if (!node.is_grant || opts.length !== 1 || opts[0]?.defname !== 'admin' || off)
|
|
67
|
+
return sql;
|
|
68
|
+
// locate the option by what the statement prints without GRANTED BY, so a role name can never match
|
|
69
|
+
const head = node.grantor ? super.GrantRoleStmt({ ...node, grantor: undefined }, context) : sql;
|
|
70
|
+
const option = ' WITH ADMIN TRUE';
|
|
71
|
+
if (!head.endsWith(option) || !sql.startsWith(head))
|
|
72
|
+
return sql;
|
|
73
|
+
return head.slice(0, -option.length) + ' WITH ADMIN OPTION' + sql.slice(head.length);
|
|
74
|
+
}
|
|
75
|
+
publicationTableListed = false;
|
|
76
|
+
CreatePublicationStmt(node, context) {
|
|
77
|
+
this.publicationTableListed = false;
|
|
78
|
+
return super.CreatePublicationStmt(node, context);
|
|
79
|
+
}
|
|
80
|
+
AlterPublicationStmt(node, context) {
|
|
81
|
+
this.publicationTableListed = false;
|
|
82
|
+
return super.AlterPublicationStmt(node, context);
|
|
83
|
+
}
|
|
84
|
+
PublicationObjSpec(node, context) {
|
|
85
|
+
const sql = super.PublicationObjSpec(node, context);
|
|
86
|
+
if (node.pubobjtype !== 'PUBLICATIONOBJ_TABLE')
|
|
87
|
+
return sql;
|
|
88
|
+
const first = !this.publicationTableListed;
|
|
89
|
+
this.publicationTableListed = true;
|
|
90
|
+
return first ? sql : sql.replace(/^TABLE /, '');
|
|
91
|
+
}
|
|
92
|
+
ReindexStmt(node, context) {
|
|
93
|
+
const params = Array.isArray(node.params) ? node.params : [];
|
|
94
|
+
const others = params.filter((param) => param?.DefElem?.defname !== 'concurrently');
|
|
95
|
+
if (others.length === params.length)
|
|
96
|
+
return super.ReindexStmt(node, context);
|
|
97
|
+
return super
|
|
98
|
+
.ReindexStmt({ ...node, params: others }, context)
|
|
99
|
+
.replace(/^REINDEX( \([^)]*\))? (INDEX|TABLE|SCHEMA|SYSTEM|DATABASE)/, match => `${match} CONCURRENTLY`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
8
102
|
export async function deparse(query, opts) {
|
|
9
|
-
|
|
10
|
-
return await deparse17(ast17, opts);
|
|
103
|
+
return Deparser.deparse(query, opts);
|
|
11
104
|
}
|
|
12
105
|
export function deparseSync(query, opts) {
|
|
13
|
-
|
|
14
|
-
return deparseSync17(ast17, opts);
|
|
106
|
+
return Deparser.deparse(query, opts);
|
|
15
107
|
}
|
|
108
|
+
export { splitSqlLines } from './deparser/utils/sql-formatter';
|
|
109
|
+
export { QuoteUtils } from '@pgsql/quotes';
|
package/esm/v13-to-v14.js
CHANGED
|
@@ -1016,10 +1016,13 @@ export class V13ToV14Transformer {
|
|
|
1016
1016
|
}
|
|
1017
1017
|
if (node.func !== undefined) {
|
|
1018
1018
|
// Handle plain object func (not wrapped in ObjectWithArgs)
|
|
1019
|
-
if (typeof node.func === 'object' && !('ObjectWithArgs' in node.func) && 'objargs' in node.func) {
|
|
1019
|
+
if (typeof node.func === 'object' && !('ObjectWithArgs' in node.func) && ('objargs' in node.func || 'objname' in node.func)) {
|
|
1020
1020
|
const funcResult = {};
|
|
1021
|
-
|
|
1022
|
-
|
|
1021
|
+
const objname = node.func.objname;
|
|
1022
|
+
if (objname !== undefined) {
|
|
1023
|
+
funcResult.objname = Array.isArray(objname)
|
|
1024
|
+
? objname.map((item) => this.transform(item, childContext))
|
|
1025
|
+
: this.transform(objname, childContext);
|
|
1023
1026
|
}
|
|
1024
1027
|
if (node.func.objargs !== undefined) {
|
|
1025
1028
|
funcResult.objargs = this.transform(node.func.objargs, childContext);
|
|
@@ -1027,6 +1030,9 @@ export class V13ToV14Transformer {
|
|
|
1027
1030
|
? node.func.objargs.map((arg, index) => this.createFunctionParameterFromTypeName(arg, childContext, index))
|
|
1028
1031
|
: [this.createFunctionParameterFromTypeName(node.func.objargs, childContext, 0)];
|
|
1029
1032
|
}
|
|
1033
|
+
if (node.func.args_unspecified !== undefined) {
|
|
1034
|
+
funcResult.args_unspecified = node.func.args_unspecified;
|
|
1035
|
+
}
|
|
1030
1036
|
result.func = funcResult;
|
|
1031
1037
|
}
|
|
1032
1038
|
else {
|
|
@@ -1637,6 +1643,25 @@ export class V13ToV14Transformer {
|
|
|
1637
1643
|
// Functions like testfunc1(int), testfunc2(int), testfunc4(boolean) should NOT have parameter names
|
|
1638
1644
|
return undefined;
|
|
1639
1645
|
}
|
|
1646
|
+
AlterExtensionContentsStmt(node, context) {
|
|
1647
|
+
const result = {};
|
|
1648
|
+
const childContext = {
|
|
1649
|
+
...context,
|
|
1650
|
+
alterExtensionObjtype: node.objtype
|
|
1651
|
+
};
|
|
1652
|
+
for (const [key, value] of Object.entries(node)) {
|
|
1653
|
+
if (Array.isArray(value)) {
|
|
1654
|
+
result[key] = value.map(item => this.transform(item, childContext));
|
|
1655
|
+
}
|
|
1656
|
+
else if (typeof value === 'object' && value !== null) {
|
|
1657
|
+
result[key] = this.transform(value, childContext);
|
|
1658
|
+
}
|
|
1659
|
+
else {
|
|
1660
|
+
result[key] = value;
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
return { AlterExtensionContentsStmt: result };
|
|
1664
|
+
}
|
|
1640
1665
|
ObjectWithArgs(node, context) {
|
|
1641
1666
|
const result = { ...node };
|
|
1642
1667
|
if (result.objname !== undefined) {
|
|
@@ -1838,6 +1863,9 @@ export class V13ToV14Transformer {
|
|
|
1838
1863
|
if (!context.parentNodeTypes || context.parentNodeTypes.length === 0) {
|
|
1839
1864
|
return false;
|
|
1840
1865
|
}
|
|
1866
|
+
if (context.alterExtensionObjtype === 'OBJECT_OPERATOR') {
|
|
1867
|
+
return false;
|
|
1868
|
+
}
|
|
1841
1869
|
if (context.commentObjtype === 'OBJECT_OPERATOR' &&
|
|
1842
1870
|
context.parentNodeTypes.includes('CommentStmt')) {
|
|
1843
1871
|
return false;
|
|
@@ -1894,7 +1922,7 @@ export class V13ToV14Transformer {
|
|
|
1894
1922
|
}
|
|
1895
1923
|
}
|
|
1896
1924
|
const allowedNodeTypes = [
|
|
1897
|
-
'CommentStmt', 'AlterFunctionStmt', 'RenameStmt', 'AlterOwnerStmt', 'AlterObjectSchemaStmt', 'CreateCastStmt', 'CreateTransformStmt', 'AlterOpFamilyStmt', 'CreateOpClassItem', 'GrantStmt', 'RevokeStmt'
|
|
1925
|
+
'CommentStmt', 'AlterFunctionStmt', 'RenameStmt', 'AlterOwnerStmt', 'AlterObjectSchemaStmt', 'CreateCastStmt', 'CreateTransformStmt', 'AlterOpFamilyStmt', 'CreateOpClassItem', 'GrantStmt', 'RevokeStmt', 'AlterExtensionContentsStmt'
|
|
1898
1926
|
];
|
|
1899
1927
|
for (const node of path) {
|
|
1900
1928
|
if (node && typeof node === 'object') {
|
|
@@ -1969,7 +1997,7 @@ export class V13ToV14Transformer {
|
|
|
1969
1997
|
const argType = transformedTypeName.TypeName ? transformedTypeName.TypeName : transformedTypeName;
|
|
1970
1998
|
// Check if this should be a variadic parameter
|
|
1971
1999
|
const isVariadic = this.isVariadicParameterType(typeNameNode, index, undefined, context);
|
|
1972
|
-
let mode = isVariadic ?
|
|
2000
|
+
let mode = isVariadic ? 'FUNC_PARAM_VARIADIC' : 'FUNC_PARAM_DEFAULT';
|
|
1973
2001
|
const functionParam = {
|
|
1974
2002
|
argType: argType,
|
|
1975
2003
|
mode: mode
|
|
@@ -2004,31 +2032,31 @@ export class V13ToV14Transformer {
|
|
|
2004
2032
|
}
|
|
2005
2033
|
transformA_Expr_Kind(kind) {
|
|
2006
2034
|
const pg13ToP14Map = {
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2035
|
+
AEXPR_OP: 'AEXPR_OP',
|
|
2036
|
+
AEXPR_OP_ANY: 'AEXPR_OP_ANY',
|
|
2037
|
+
AEXPR_OP_ALL: 'AEXPR_OP_ALL',
|
|
2038
|
+
AEXPR_DISTINCT: 'AEXPR_DISTINCT',
|
|
2039
|
+
AEXPR_NOT_DISTINCT: 'AEXPR_NOT_DISTINCT',
|
|
2040
|
+
AEXPR_NULLIF: 'AEXPR_NULLIF',
|
|
2041
|
+
AEXPR_OF: 'AEXPR_IN', // AEXPR_OF removed, map to AEXPR_IN
|
|
2042
|
+
AEXPR_IN: 'AEXPR_IN',
|
|
2043
|
+
AEXPR_LIKE: 'AEXPR_LIKE',
|
|
2044
|
+
AEXPR_ILIKE: 'AEXPR_ILIKE',
|
|
2045
|
+
AEXPR_SIMILAR: 'AEXPR_SIMILAR',
|
|
2046
|
+
AEXPR_BETWEEN: 'AEXPR_BETWEEN',
|
|
2047
|
+
AEXPR_NOT_BETWEEN: 'AEXPR_NOT_BETWEEN',
|
|
2048
|
+
AEXPR_BETWEEN_SYM: 'AEXPR_BETWEEN_SYM',
|
|
2049
|
+
AEXPR_NOT_BETWEEN_SYM: 'AEXPR_NOT_BETWEEN_SYM',
|
|
2050
|
+
AEXPR_PAREN: 'AEXPR_OP' // AEXPR_PAREN removed, map to AEXPR_OP
|
|
2023
2051
|
};
|
|
2024
2052
|
return pg13ToP14Map[kind] || kind;
|
|
2025
2053
|
}
|
|
2026
2054
|
transformRoleSpecType(type) {
|
|
2027
2055
|
const pg13ToP14Map = {
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2056
|
+
ROLESPEC_CSTRING: 'ROLESPEC_CSTRING',
|
|
2057
|
+
ROLESPEC_CURRENT_USER: 'ROLESPEC_CURRENT_USER',
|
|
2058
|
+
ROLESPEC_SESSION_USER: 'ROLESPEC_SESSION_USER',
|
|
2059
|
+
ROLESPEC_PUBLIC: 'ROLESPEC_PUBLIC'
|
|
2032
2060
|
};
|
|
2033
2061
|
return pg13ToP14Map[type] || type;
|
|
2034
2062
|
}
|
|
@@ -2087,11 +2115,11 @@ export class V13ToV14Transformer {
|
|
|
2087
2115
|
A_Expr(node, context) {
|
|
2088
2116
|
const result = {};
|
|
2089
2117
|
if (node.kind !== undefined) {
|
|
2090
|
-
if (node.kind ===
|
|
2091
|
-
result.kind =
|
|
2118
|
+
if (node.kind === 'AEXPR_OF') {
|
|
2119
|
+
result.kind = 'AEXPR_IN';
|
|
2092
2120
|
}
|
|
2093
|
-
else if (node.kind ===
|
|
2094
|
-
result.kind =
|
|
2121
|
+
else if (node.kind === 'AEXPR_PAREN') {
|
|
2122
|
+
result.kind = 'AEXPR_OP';
|
|
2095
2123
|
}
|
|
2096
2124
|
else {
|
|
2097
2125
|
result.kind = node.kind;
|
|
@@ -2330,6 +2358,14 @@ export class V13ToV14Transformer {
|
|
|
2330
2358
|
shouldConvertCTEsToArray(context) {
|
|
2331
2359
|
return true;
|
|
2332
2360
|
}
|
|
2361
|
+
AlterSubscriptionStmt(node, context) {
|
|
2362
|
+
const result = this.transformGenericNode(node, context);
|
|
2363
|
+
// PG14 added ADD / DROP PUBLICATION and renamed the existing SET PUBLICATION kind
|
|
2364
|
+
if (result.kind === 'ALTER_SUBSCRIPTION_PUBLICATION') {
|
|
2365
|
+
result.kind = 'ALTER_SUBSCRIPTION_SET_PUBLICATION';
|
|
2366
|
+
}
|
|
2367
|
+
return { AlterSubscriptionStmt: result };
|
|
2368
|
+
}
|
|
2333
2369
|
AlterSeqStmt(node, context) {
|
|
2334
2370
|
const result = {};
|
|
2335
2371
|
if (node.sequence !== undefined) {
|
|
@@ -2745,6 +2781,17 @@ export class V13ToV14Transformer {
|
|
|
2745
2781
|
else if (nodeAny.params !== undefined) {
|
|
2746
2782
|
result.params = this.transform(nodeAny.params, context);
|
|
2747
2783
|
}
|
|
2784
|
+
if (nodeAny.concurrent === true) {
|
|
2785
|
+
result.params = [
|
|
2786
|
+
...(result.params || []),
|
|
2787
|
+
{
|
|
2788
|
+
DefElem: {
|
|
2789
|
+
defname: 'concurrently',
|
|
2790
|
+
defaction: 'DEFELEM_UNSPEC'
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
];
|
|
2794
|
+
}
|
|
2748
2795
|
return { ReindexStmt: result };
|
|
2749
2796
|
}
|
|
2750
2797
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
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
|
+
import { V13ToV14Transformer } from "./v13-to-v14";
|
|
6
|
+
import { V14ToV15Transformer } from "./v14-to-v15";
|
|
7
|
+
import { V15ToV16Transformer } from "./v15-to-v16";
|
|
8
|
+
import { V16ToV17Transformer } from "./v16-to-v17";
|
|
9
|
+
import { V17ToV18Transformer } from "./v17-to-v18";
|
|
10
|
+
/**
|
|
11
|
+
* Direct transformer from PG13 to PG18
|
|
12
|
+
* This transformer chains v13->...->v18 transformations
|
|
13
|
+
*/
|
|
14
|
+
export class PG13ToPG18Transformer {
|
|
15
|
+
v13to14 = new V13ToV14Transformer();
|
|
16
|
+
v14to15 = new V14ToV15Transformer();
|
|
17
|
+
v15to16 = new V15ToV16Transformer();
|
|
18
|
+
v16to17 = new V16ToV17Transformer();
|
|
19
|
+
v17to18 = new V17ToV18Transformer();
|
|
20
|
+
transform(node) {
|
|
21
|
+
if (this.isParseResult(node)) {
|
|
22
|
+
// Transform through the chain: v13->v14->v15->v16->v17->v18
|
|
23
|
+
const v14Stmts = node.stmts.map((stmtWrapper) => {
|
|
24
|
+
if (stmtWrapper.stmt) {
|
|
25
|
+
const stmt = this.v13to14.transform(stmtWrapper.stmt, { parentNodeTypes: [] });
|
|
26
|
+
return { ...stmtWrapper, stmt };
|
|
27
|
+
}
|
|
28
|
+
return stmtWrapper;
|
|
29
|
+
});
|
|
30
|
+
const v15Stmts = v14Stmts.map((stmtWrapper) => {
|
|
31
|
+
if (stmtWrapper.stmt) {
|
|
32
|
+
const stmt = this.v14to15.transform(stmtWrapper.stmt, { parentNodeTypes: [] });
|
|
33
|
+
return { ...stmtWrapper, stmt };
|
|
34
|
+
}
|
|
35
|
+
return stmtWrapper;
|
|
36
|
+
});
|
|
37
|
+
const v16Stmts = v15Stmts.map((stmtWrapper) => {
|
|
38
|
+
if (stmtWrapper.stmt) {
|
|
39
|
+
const stmt = this.v15to16.transform(stmtWrapper.stmt, { parentNodeTypes: [] });
|
|
40
|
+
return { ...stmtWrapper, stmt };
|
|
41
|
+
}
|
|
42
|
+
return stmtWrapper;
|
|
43
|
+
});
|
|
44
|
+
const v17Stmts = v16Stmts.map((stmtWrapper) => {
|
|
45
|
+
if (stmtWrapper.stmt) {
|
|
46
|
+
const stmt = this.v16to17.transform(stmtWrapper.stmt, { parentNodeTypes: [] });
|
|
47
|
+
return { ...stmtWrapper, stmt };
|
|
48
|
+
}
|
|
49
|
+
return stmtWrapper;
|
|
50
|
+
});
|
|
51
|
+
const v18Stmts = v17Stmts.map((stmtWrapper) => {
|
|
52
|
+
if (stmtWrapper.stmt) {
|
|
53
|
+
const stmt = this.v17to18.transform(stmtWrapper.stmt, { parentNodeTypes: [] });
|
|
54
|
+
return { ...stmtWrapper, stmt };
|
|
55
|
+
}
|
|
56
|
+
return stmtWrapper;
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
...node,
|
|
60
|
+
version: 180004, // PG18 version
|
|
61
|
+
stmts: v18Stmts
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Otherwise, transform as a regular node through the chain
|
|
65
|
+
const v14Node = this.v13to14.transform(node, { parentNodeTypes: [] });
|
|
66
|
+
const v15Node = this.v14to15.transform(v14Node, { parentNodeTypes: [] });
|
|
67
|
+
const v16Node = this.v15to16.transform(v15Node, { parentNodeTypes: [] });
|
|
68
|
+
const v17Node = this.v16to17.transform(v16Node, { parentNodeTypes: [] });
|
|
69
|
+
return this.v17to18.transform(v17Node, { parentNodeTypes: [] });
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Transform a single statement from PG13 to PG18
|
|
73
|
+
* @deprecated Use transform() instead, which handles all node types
|
|
74
|
+
*/
|
|
75
|
+
transformStatement(stmt) {
|
|
76
|
+
const v14Stmt = this.v13to14.transform(stmt, { parentNodeTypes: [] });
|
|
77
|
+
const v15Stmt = this.v14to15.transform(v14Stmt, { parentNodeTypes: [] });
|
|
78
|
+
const v16Stmt = this.v15to16.transform(v15Stmt, { parentNodeTypes: [] });
|
|
79
|
+
const v17Stmt = this.v16to17.transform(v16Stmt, { parentNodeTypes: [] });
|
|
80
|
+
return this.v17to18.transform(v17Stmt, { parentNodeTypes: [] });
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Type guard to check if a node is a ParseResult
|
|
84
|
+
*/
|
|
85
|
+
isParseResult(node) {
|
|
86
|
+
return node && typeof node === 'object' && 'version' in node && 'stmts' in node;
|
|
87
|
+
}
|
|
88
|
+
}
|
package/esm/v14-to-v15.js
CHANGED
|
@@ -828,8 +828,21 @@ export class V14ToV15Transformer {
|
|
|
828
828
|
const result = this.transformGenericNode(node, context);
|
|
829
829
|
return { StatsElem: result };
|
|
830
830
|
}
|
|
831
|
+
// PG15 replaced the publication's list of tables with a list of PublicationObjSpec
|
|
832
|
+
publicationTablesToObjects(result) {
|
|
833
|
+
if (result.tables === undefined)
|
|
834
|
+
return;
|
|
835
|
+
result.pubobjects = (Array.isArray(result.tables) ? result.tables : [result.tables]).map((table) => ({
|
|
836
|
+
PublicationObjSpec: {
|
|
837
|
+
pubobjtype: 'PUBLICATIONOBJ_TABLE',
|
|
838
|
+
pubtable: { relation: table.RangeVar ?? table }
|
|
839
|
+
}
|
|
840
|
+
}));
|
|
841
|
+
delete result.tables;
|
|
842
|
+
}
|
|
831
843
|
CreatePublicationStmt(node, context) {
|
|
832
844
|
const result = this.transformGenericNode(node, context);
|
|
845
|
+
this.publicationTablesToObjects(result);
|
|
833
846
|
return { CreatePublicationStmt: result };
|
|
834
847
|
}
|
|
835
848
|
CreateSubscriptionStmt(node, context) {
|
|
@@ -838,10 +851,31 @@ export class V14ToV15Transformer {
|
|
|
838
851
|
}
|
|
839
852
|
AlterPublicationStmt(node, context) {
|
|
840
853
|
const result = this.transformGenericNode(node, context);
|
|
854
|
+
this.publicationTablesToObjects(result);
|
|
855
|
+
if (result.tableAction !== undefined) {
|
|
856
|
+
const actions = {
|
|
857
|
+
DEFELEM_ADD: 'AP_AddObjects',
|
|
858
|
+
DEFELEM_DROP: 'AP_DropObjects',
|
|
859
|
+
DEFELEM_SET: 'AP_SetObjects'
|
|
860
|
+
};
|
|
861
|
+
if (actions[result.tableAction]) {
|
|
862
|
+
result.action = actions[result.tableAction];
|
|
863
|
+
}
|
|
864
|
+
delete result.tableAction;
|
|
865
|
+
}
|
|
841
866
|
return { AlterPublicationStmt: result };
|
|
842
867
|
}
|
|
843
868
|
AlterSubscriptionStmt(node, context) {
|
|
844
869
|
const result = this.transformGenericNode(node, context);
|
|
870
|
+
// ENABLE / DISABLE carried an Integer before PG15 introduced the Boolean node
|
|
871
|
+
if (result.kind === 'ALTER_SUBSCRIPTION_ENABLED' && Array.isArray(result.options)) {
|
|
872
|
+
result.options = result.options.map((option) => {
|
|
873
|
+
const ival = option?.DefElem?.arg?.Integer;
|
|
874
|
+
if (option?.DefElem?.defname !== 'enabled' || !ival)
|
|
875
|
+
return option;
|
|
876
|
+
return { DefElem: { ...option.DefElem, arg: { Boolean: { boolval: ival.ival === 1 } } } };
|
|
877
|
+
});
|
|
878
|
+
}
|
|
845
879
|
return { AlterSubscriptionStmt: result };
|
|
846
880
|
}
|
|
847
881
|
DropSubscriptionStmt(node, context) {
|
package/esm/v15-to-v16.js
CHANGED
|
@@ -790,9 +790,9 @@ export class V15ToV16Transformer {
|
|
|
790
790
|
const partspec = { ...node.partspec };
|
|
791
791
|
if (partspec.strategy !== undefined) {
|
|
792
792
|
const strategyMap = {
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
793
|
+
range: 'PARTITION_STRATEGY_RANGE',
|
|
794
|
+
list: 'PARTITION_STRATEGY_LIST',
|
|
795
|
+
hash: 'PARTITION_STRATEGY_HASH'
|
|
796
796
|
};
|
|
797
797
|
partspec.strategy = strategyMap[partspec.strategy] || partspec.strategy;
|
|
798
798
|
}
|
|
@@ -854,6 +854,9 @@ export class V15ToV16Transformer {
|
|
|
854
854
|
if (node.storage !== undefined) {
|
|
855
855
|
result.storage = node.storage;
|
|
856
856
|
}
|
|
857
|
+
if (node.compression !== undefined) {
|
|
858
|
+
result.compression = node.compression;
|
|
859
|
+
}
|
|
857
860
|
if (node.raw_default !== undefined) {
|
|
858
861
|
result.raw_default = this.transform(node.raw_default, context);
|
|
859
862
|
}
|
|
@@ -976,6 +979,11 @@ export class V15ToV16Transformer {
|
|
|
976
979
|
if (node.fk_del_action !== undefined) {
|
|
977
980
|
result.fk_del_action = node.fk_del_action;
|
|
978
981
|
}
|
|
982
|
+
if (node.fk_del_set_cols !== undefined) {
|
|
983
|
+
result.fk_del_set_cols = Array.isArray(node.fk_del_set_cols)
|
|
984
|
+
? node.fk_del_set_cols.map((item) => this.transform(item, context))
|
|
985
|
+
: this.transform(node.fk_del_set_cols, context);
|
|
986
|
+
}
|
|
979
987
|
if (node.old_conpfeqop !== undefined) {
|
|
980
988
|
result.old_conpfeqop = Array.isArray(node.old_conpfeqop)
|
|
981
989
|
? node.old_conpfeqop.map((item) => this.transform(item, context))
|
|
@@ -2551,13 +2559,13 @@ export class V15ToV16Transformer {
|
|
|
2551
2559
|
result.opt = [
|
|
2552
2560
|
{
|
|
2553
2561
|
DefElem: {
|
|
2554
|
-
defname:
|
|
2562
|
+
defname: 'admin',
|
|
2555
2563
|
arg: {
|
|
2556
2564
|
Boolean: {
|
|
2557
2565
|
boolval: true
|
|
2558
2566
|
}
|
|
2559
2567
|
},
|
|
2560
|
-
defaction:
|
|
2568
|
+
defaction: 'DEFELEM_UNSPEC'
|
|
2561
2569
|
}
|
|
2562
2570
|
}
|
|
2563
2571
|
];
|
|
@@ -2568,6 +2576,9 @@ export class V15ToV16Transformer {
|
|
|
2568
2576
|
? nodeAny.opt.map((item) => this.transform(item, context))
|
|
2569
2577
|
: this.transform(nodeAny.opt, context);
|
|
2570
2578
|
}
|
|
2579
|
+
if (node.grantor !== undefined) {
|
|
2580
|
+
result.grantor = node.grantor;
|
|
2581
|
+
}
|
|
2571
2582
|
return { GrantRoleStmt: result };
|
|
2572
2583
|
}
|
|
2573
2584
|
SecLabelStmt(node, context) {
|