neon 8.4.5 → 8.6.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.
Files changed (79) hide show
  1. package/README.md +18 -9
  2. package/dist/_chunks/{env-4WGRW2nw.js → env-BNm69Qh8.js} +2 -5
  3. package/dist/commands/config.js +11 -28
  4. package/dist/commands/dev.js +93 -27
  5. package/dist/commands/env.js +2 -3
  6. package/dist/commands/init.js +1 -2
  7. package/dist/commands/link.js +1 -1
  8. package/dist/commands/manifest.js +1 -3
  9. package/dist/commands/subscribe.js +16 -16
  10. package/dist/credential_io.js +1 -2
  11. package/dist/dev/env.js +1 -2
  12. package/dist/dev/runtime.js +8 -0
  13. package/dist/env_file.js +9 -1
  14. package/dist/index.js +1 -1
  15. package/dist/init/auth.js +1 -4
  16. package/dist/init/choices.js +21 -7
  17. package/dist/init/copy.js +21 -7
  18. package/dist/init/run.js +25 -16
  19. package/dist/plugins/run.js +2 -1
  20. package/dist/psql/command/cmd_io.js +1 -2
  21. package/dist/psql/command/cmd_pipeline.js +1 -2
  22. package/dist/psql/core/common.js +1 -2
  23. package/dist/psql/core/startup.js +1 -2
  24. package/dist/psql/index.js +1 -2
  25. package/dist/psql/types/index.js +1 -2
  26. package/dist/skills/catalog.js +5 -0
  27. package/dist/utils/hooks.js +0 -2
  28. package/dist/utils/staging.js +1 -14
  29. package/{LICENSE → dist/vendor/postgres-meta/LICENSE} +0 -1
  30. package/dist/vendor/postgres-meta/constants.js +14 -0
  31. package/dist/vendor/postgres-meta/lib/PostgresMeta.js +49 -0
  32. package/dist/vendor/postgres-meta/lib/PostgresMetaColumnPrivileges.js +85 -0
  33. package/dist/vendor/postgres-meta/lib/PostgresMetaColumns.js +235 -0
  34. package/dist/vendor/postgres-meta/lib/PostgresMetaConfig.js +16 -0
  35. package/dist/vendor/postgres-meta/lib/PostgresMetaExtensions.js +79 -0
  36. package/dist/vendor/postgres-meta/lib/PostgresMetaForeignTables.js +81 -0
  37. package/dist/vendor/postgres-meta/lib/PostgresMetaFunctions.js +173 -0
  38. package/dist/vendor/postgres-meta/lib/PostgresMetaIndexes.js +42 -0
  39. package/dist/vendor/postgres-meta/lib/PostgresMetaMaterializedViews.js +84 -0
  40. package/dist/vendor/postgres-meta/lib/PostgresMetaPolicies.js +120 -0
  41. package/dist/vendor/postgres-meta/lib/PostgresMetaPublications.js +193 -0
  42. package/dist/vendor/postgres-meta/lib/PostgresMetaRelationships.js +87 -0
  43. package/dist/vendor/postgres-meta/lib/PostgresMetaRoles.js +203 -0
  44. package/dist/vendor/postgres-meta/lib/PostgresMetaSchemas.js +105 -0
  45. package/dist/vendor/postgres-meta/lib/PostgresMetaTablePrivileges.js +91 -0
  46. package/dist/vendor/postgres-meta/lib/PostgresMetaTables.js +183 -0
  47. package/dist/vendor/postgres-meta/lib/PostgresMetaTriggers.js +156 -0
  48. package/dist/vendor/postgres-meta/lib/PostgresMetaTypes.js +22 -0
  49. package/dist/vendor/postgres-meta/lib/PostgresMetaVersion.js +20 -0
  50. package/dist/vendor/postgres-meta/lib/PostgresMetaViews.js +83 -0
  51. package/dist/vendor/postgres-meta/lib/constants.js +8 -0
  52. package/dist/vendor/postgres-meta/lib/db.js +147 -0
  53. package/dist/vendor/postgres-meta/lib/generators.js +106 -0
  54. package/dist/vendor/postgres-meta/lib/helpers.js +26 -0
  55. package/dist/vendor/postgres-meta/lib/index.js +1 -0
  56. package/dist/vendor/postgres-meta/lib/sql/column_privileges.sql.js +154 -0
  57. package/dist/vendor/postgres-meta/lib/sql/columns.sql.js +123 -0
  58. package/dist/vendor/postgres-meta/lib/sql/common.js +1 -0
  59. package/dist/vendor/postgres-meta/lib/sql/config.sql.js +32 -0
  60. package/dist/vendor/postgres-meta/lib/sql/extensions.sql.js +20 -0
  61. package/dist/vendor/postgres-meta/lib/sql/foreign_tables.sql.js +20 -0
  62. package/dist/vendor/postgres-meta/lib/sql/functions.sql.js +141 -0
  63. package/dist/vendor/postgres-meta/lib/sql/indexes.sql.js +51 -0
  64. package/dist/vendor/postgres-meta/lib/sql/materialized_views.sql.js +21 -0
  65. package/dist/vendor/postgres-meta/lib/sql/policies.sql.js +53 -0
  66. package/dist/vendor/postgres-meta/lib/sql/publications.sql.js +46 -0
  67. package/dist/vendor/postgres-meta/lib/sql/roles.sql.js +40 -0
  68. package/dist/vendor/postgres-meta/lib/sql/schemas.sql.js +26 -0
  69. package/dist/vendor/postgres-meta/lib/sql/table.sql.js +109 -0
  70. package/dist/vendor/postgres-meta/lib/sql/table_privileges.sql.js +85 -0
  71. package/dist/vendor/postgres-meta/lib/sql/table_relationships.sql.js +52 -0
  72. package/dist/vendor/postgres-meta/lib/sql/triggers.sql.js +64 -0
  73. package/dist/vendor/postgres-meta/lib/sql/types.sql.js +65 -0
  74. package/dist/vendor/postgres-meta/lib/sql/version.sql.js +15 -0
  75. package/dist/vendor/postgres-meta/lib/sql/views.sql.js +22 -0
  76. package/dist/vendor/postgres-meta/lib/sql/views_key_dependencies.sql.js +198 -0
  77. package/dist/vendor/postgres-meta/lib/types.js +1 -0
  78. package/dist/vendor/postgres-meta/templates/typescript.js +608 -0
  79. package/package.json +12 -5
@@ -0,0 +1,147 @@
1
+ import pg from "pg";
2
+ import { parse } from "postgres-array";
3
+ //#region src/vendor/postgres-meta/lib/db.ts
4
+ pg.types.setTypeParser(pg.types.builtins.INT8, (x) => {
5
+ const asNumber = Number(x);
6
+ if (Number.isSafeInteger(asNumber)) return asNumber;
7
+ else return x;
8
+ });
9
+ pg.types.setTypeParser(pg.types.builtins.DATE, (x) => x);
10
+ pg.types.setTypeParser(pg.types.builtins.INTERVAL, (x) => x);
11
+ pg.types.setTypeParser(pg.types.builtins.TIMESTAMP, (x) => x);
12
+ pg.types.setTypeParser(pg.types.builtins.TIMESTAMPTZ, (x) => x);
13
+ pg.types.setTypeParser(1115, parse);
14
+ pg.types.setTypeParser(1182, parse);
15
+ pg.types.setTypeParser(1185, parse);
16
+ pg.types.setTypeParser(600, (x) => x);
17
+ pg.types.setTypeParser(1017, (x) => x);
18
+ const poolerQueryHandleError = (pgpool, sql, parameters) => {
19
+ return new Promise((resolve, reject) => {
20
+ let rejected = false;
21
+ const connectionErrorHandler = (err) => {
22
+ if (!rejected) setTimeout(() => {
23
+ rejected = true;
24
+ return reject(err);
25
+ });
26
+ };
27
+ pgpool.once("error", connectionErrorHandler);
28
+ pgpool.query(sql, parameters).then((results) => {
29
+ if (!rejected) return resolve(results);
30
+ }).catch((err) => {
31
+ if (!rejected) {
32
+ rejected = true;
33
+ return reject(err);
34
+ }
35
+ });
36
+ });
37
+ };
38
+ const init = (config) => {
39
+ if (config.connectionString) {
40
+ const u = new URL(config.connectionString);
41
+ const sslmode = u.searchParams.get("sslmode");
42
+ u.searchParams.delete("sslmode");
43
+ u.searchParams.delete("sslca");
44
+ u.searchParams.delete("sslkey");
45
+ u.searchParams.delete("sslcert");
46
+ u.searchParams.delete("sslrootcert");
47
+ config.connectionString = u.toString();
48
+ if (sslmode === null) {} else if (sslmode === "disable") config.ssl = false;
49
+ else {
50
+ if (typeof config.ssl !== "object") config.ssl = {};
51
+ config.ssl.rejectUnauthorized = sslmode === "verify-full";
52
+ }
53
+ }
54
+ let pool = new pg.Pool(config);
55
+ return {
56
+ async query(sql, { statementQueryTimeout, parameters } = {}) {
57
+ const statementTimeoutQueryPrefix = statementQueryTimeout ? `SET statement_timeout='${statementQueryTimeout}s'; SET idle_session_timeout='${statementQueryTimeout}s';` : "";
58
+ const sqlWithStatementTimeout = `${statementTimeoutQueryPrefix}${sql}`;
59
+ try {
60
+ if (!pool) {
61
+ const transientPool = new pg.Pool(config);
62
+ let res = await poolerQueryHandleError(transientPool, sqlWithStatementTimeout, parameters);
63
+ if (Array.isArray(res)) res = res.reverse().find((x) => x.rows.length !== 0) ?? { rows: [] };
64
+ await transientPool.end();
65
+ return {
66
+ data: res.rows,
67
+ error: null
68
+ };
69
+ }
70
+ let res = await poolerQueryHandleError(pool, sqlWithStatementTimeout, parameters);
71
+ if (Array.isArray(res)) res = res.reverse().find((x) => x.rows.length !== 0) ?? { rows: [] };
72
+ return {
73
+ data: res.rows,
74
+ error: null
75
+ };
76
+ } catch (error) {
77
+ if (error.constructor.name === "DatabaseError") {
78
+ let formattedError = "";
79
+ if (error.severity) formattedError += `${error.severity}: `;
80
+ if (error.code) formattedError += `${error.code}: `;
81
+ if (error.message) formattedError += error.message;
82
+ formattedError += "\n";
83
+ if (error.position) {
84
+ const position = Number(error.position) - 1 - statementTimeoutQueryPrefix.length;
85
+ error.position = `${position + 1}`;
86
+ let line = "";
87
+ let lineNumber = 0;
88
+ let lineOffset = 0;
89
+ const lines = sql.split("\n");
90
+ let currentOffset = 0;
91
+ for (let i = 0; i < lines.length; i++) {
92
+ if (currentOffset + lines[i].length > position) {
93
+ line = lines[i];
94
+ lineNumber = i + 1;
95
+ lineOffset = position - currentOffset;
96
+ break;
97
+ }
98
+ currentOffset += lines[i].length + 1;
99
+ }
100
+ formattedError += `LINE ${lineNumber}: ${line}\n${" ".repeat(5 + lineNumber.toString().length + 2 + lineOffset)}^\n`;
101
+ }
102
+ if (error.detail) formattedError += `DETAIL: ${error.detail}\n`;
103
+ if (error.hint) formattedError += `HINT: ${error.hint}\n`;
104
+ if (error.internalQuery) formattedError += `QUERY: ${error.internalQuery}\n`;
105
+ if (error.where) formattedError += `CONTEXT: ${error.where}\n`;
106
+ return {
107
+ data: null,
108
+ error: {
109
+ ...error,
110
+ message: error.message,
111
+ formattedError
112
+ }
113
+ };
114
+ }
115
+ try {
116
+ return {
117
+ data: null,
118
+ error: {
119
+ code: error.code,
120
+ message: error.message
121
+ }
122
+ };
123
+ } finally {
124
+ try {
125
+ await this.end.bind(this);
126
+ } catch (_endError) {
127
+ console.error("Failed to end the connection on error: ", {
128
+ this: this,
129
+ end: this.end
130
+ });
131
+ }
132
+ }
133
+ }
134
+ },
135
+ async end() {
136
+ try {
137
+ const _pool = pool;
138
+ pool = null;
139
+ if (_pool) await _pool.end();
140
+ } catch (endError) {
141
+ console.error("Failed ending connection pool", endError);
142
+ }
143
+ }
144
+ };
145
+ };
146
+ //#endregion
147
+ export { init };
@@ -0,0 +1,106 @@
1
+ //#region src/vendor/postgres-meta/lib/generators.ts
2
+ async function getGeneratorMetadata(pgMeta, filters = {
3
+ includedSchemas: [],
4
+ excludedSchemas: []
5
+ }) {
6
+ const includedSchemas = filters.includedSchemas ?? [];
7
+ const excludedSchemas = filters.excludedSchemas ?? [];
8
+ const { data: schemas, error: schemasError } = await pgMeta.schemas.list({
9
+ includeSystemSchemas: false,
10
+ includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
11
+ excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0
12
+ });
13
+ if (schemasError) return {
14
+ data: null,
15
+ error: schemasError
16
+ };
17
+ const { data: tables, error: tablesError } = await pgMeta.tables.list({
18
+ includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
19
+ excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
20
+ includeColumns: false
21
+ });
22
+ if (tablesError) return {
23
+ data: null,
24
+ error: tablesError
25
+ };
26
+ const { data: foreignTables, error: foreignTablesError } = await pgMeta.foreignTables.list({
27
+ includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
28
+ excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
29
+ includeColumns: false
30
+ });
31
+ if (foreignTablesError) return {
32
+ data: null,
33
+ error: foreignTablesError
34
+ };
35
+ const { data: views, error: viewsError } = await pgMeta.views.list({
36
+ includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
37
+ excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
38
+ includeColumns: false
39
+ });
40
+ if (viewsError) return {
41
+ data: null,
42
+ error: viewsError
43
+ };
44
+ const { data: materializedViews, error: materializedViewsError } = await pgMeta.materializedViews.list({
45
+ includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
46
+ excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
47
+ includeColumns: false
48
+ });
49
+ if (materializedViewsError) return {
50
+ data: null,
51
+ error: materializedViewsError
52
+ };
53
+ const { data: columns, error: columnsError } = await pgMeta.columns.list({
54
+ includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
55
+ excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
56
+ includeSystemSchemas: false
57
+ });
58
+ if (columnsError) return {
59
+ data: null,
60
+ error: columnsError
61
+ };
62
+ const { data: relationships, error: relationshipsError } = await pgMeta.relationships.list({
63
+ includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
64
+ excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
65
+ includeSystemSchemas: false
66
+ });
67
+ if (relationshipsError) return {
68
+ data: null,
69
+ error: relationshipsError
70
+ };
71
+ const { data: functions, error: functionsError } = await pgMeta.functions.list({
72
+ includedSchemas: includedSchemas.length > 0 ? includedSchemas : void 0,
73
+ excludedSchemas: excludedSchemas.length > 0 ? excludedSchemas : void 0,
74
+ includeSystemSchemas: false
75
+ });
76
+ if (functionsError) return {
77
+ data: null,
78
+ error: functionsError
79
+ };
80
+ const { data: types, error: typesError } = await pgMeta.types.list({
81
+ includeTableTypes: true,
82
+ includeArrayTypes: true,
83
+ includeSystemSchemas: true
84
+ });
85
+ if (typesError) return {
86
+ data: null,
87
+ error: typesError
88
+ };
89
+ await pgMeta.end();
90
+ return {
91
+ data: {
92
+ schemas: schemas.filter(({ name }) => !excludedSchemas.includes(name) && (includedSchemas.length === 0 || includedSchemas.includes(name))),
93
+ tables,
94
+ foreignTables,
95
+ views,
96
+ materializedViews,
97
+ columns,
98
+ relationships,
99
+ functions: functions.filter(({ return_type }) => !["trigger", "event_trigger"].includes(return_type)),
100
+ types
101
+ },
102
+ error: null
103
+ };
104
+ }
105
+ //#endregion
106
+ export { getGeneratorMetadata };
@@ -0,0 +1,26 @@
1
+ import { literal } from "pg-format";
2
+ //#region src/vendor/postgres-meta/lib/helpers.ts
3
+ const coalesceRowsToArray = (source, filter) => {
4
+ return `
5
+ COALESCE(
6
+ (
7
+ SELECT
8
+ array_agg(row_to_json(${source})) FILTER (WHERE ${filter})
9
+ FROM
10
+ ${source}
11
+ ),
12
+ '{}'
13
+ ) AS ${source}`;
14
+ };
15
+ const filterByList = (include, exclude, defaultExclude) => {
16
+ if (defaultExclude) exclude = defaultExclude.concat(exclude ?? []);
17
+ if (include?.length) return `IN (${include.map(literal).join(",")})`;
18
+ else if (exclude?.length) return `NOT IN (${exclude.map(literal).join(",")})`;
19
+ return "";
20
+ };
21
+ const filterByValue = (ids) => {
22
+ if (ids?.length) return `IN (${ids.map(literal).join(",")})`;
23
+ return "";
24
+ };
25
+ //#endregion
26
+ export { coalesceRowsToArray, filterByList, filterByValue };
@@ -0,0 +1 @@
1
+ export { default as PostgresMeta } from "./PostgresMeta.js";
@@ -0,0 +1,154 @@
1
+ //#region src/vendor/postgres-meta/lib/sql/column_privileges.sql.ts
2
+ const COLUMN_PRIVILEGES_SQL = (props) => `
3
+ -- Lists each column's privileges in the form of:
4
+ --
5
+ -- [
6
+ -- {
7
+ -- "column_id": "12345.1",
8
+ -- "relation_schema": "public",
9
+ -- "relation_name": "mytable",
10
+ -- "column_name": "mycolumn",
11
+ -- "privileges": [
12
+ -- {
13
+ -- "grantor": "postgres",
14
+ -- "grantee": "myrole",
15
+ -- "privilege_type": "SELECT",
16
+ -- "is_grantable": false
17
+ -- },
18
+ -- ...
19
+ -- ]
20
+ -- },
21
+ -- ...
22
+ -- ]
23
+ --
24
+ -- Modified from information_schema.column_privileges. We try to be as close as
25
+ -- possible to the view definition, obtained from:
26
+ --
27
+ -- select pg_get_viewdef('information_schema.column_privileges');
28
+ --
29
+ -- The main differences are:
30
+ -- - we include column privileges for materialized views
31
+ -- (reason for exclusion in information_schema.column_privileges:
32
+ -- https://www.postgresql.org/message-id/9136.1502740844%40sss.pgh.pa.us)
33
+ -- - we query a.attrelid and a.attnum to generate \`column_id\`
34
+ -- - \`table_catalog\` is omitted
35
+ -- - table_schema -> relation_schema, table_name -> relation_name
36
+ --
37
+ -- Column privileges are intertwined with table privileges in that table
38
+ -- privileges override column privileges. E.g. if we do:
39
+ --
40
+ -- grant all on mytable to myrole;
41
+ --
42
+ -- Then \`myrole\` is granted privileges for ALL columns. Likewise, if we do:
43
+ --
44
+ -- grant all (id) on mytable to myrole;
45
+ -- revoke all on mytable from myrole;
46
+ --
47
+ -- Then the grant on the \`id\` column is revoked.
48
+ --
49
+ -- This is unlike how grants for schemas and tables interact, where you need
50
+ -- privileges for BOTH the schema the table is in AND the table itself in order
51
+ -- to access the table.
52
+
53
+ select (x.attrelid || '.' || x.attnum) as column_id,
54
+ nc.nspname as relation_schema,
55
+ x.relname as relation_name,
56
+ x.attname as column_name,
57
+ coalesce(
58
+ jsonb_agg(
59
+ jsonb_build_object(
60
+ 'grantor', u_grantor.rolname,
61
+ 'grantee', grantee.rolname,
62
+ 'privilege_type', x.prtype,
63
+ 'is_grantable', x.grantable
64
+ )
65
+ ),
66
+ '[]'
67
+ ) as privileges
68
+ from
69
+ (select pr_c.grantor,
70
+ pr_c.grantee,
71
+ a.attrelid,
72
+ a.attnum,
73
+ a.attname,
74
+ pr_c.relname,
75
+ pr_c.relnamespace,
76
+ pr_c.prtype,
77
+ pr_c.grantable,
78
+ pr_c.relowner
79
+ from
80
+ (select pg_class.oid,
81
+ pg_class.relname,
82
+ pg_class.relnamespace,
83
+ pg_class.relowner,
84
+ (aclexplode(coalesce(pg_class.relacl, acldefault('r', pg_class.relowner)))).grantor as grantor,
85
+ (aclexplode(coalesce(pg_class.relacl, acldefault('r', pg_class.relowner)))).grantee as grantee,
86
+ (aclexplode(coalesce(pg_class.relacl, acldefault('r', pg_class.relowner)))).privilege_type as privilege_type,
87
+ (aclexplode(coalesce(pg_class.relacl, acldefault('r', pg_class.relowner)))).is_grantable as is_grantable
88
+ from pg_class
89
+ where (pg_class.relkind = any (array['r',
90
+ 'v',
91
+ 'm',
92
+ 'f',
93
+ 'p'])) ) pr_c(oid, relname, relnamespace, relowner, grantor, grantee, prtype, grantable),
94
+ pg_attribute a
95
+ where ((a.attrelid = pr_c.oid)
96
+ and (a.attnum > 0)
97
+ and (not a.attisdropped))
98
+ union select pr_a.grantor,
99
+ pr_a.grantee,
100
+ pr_a.attrelid,
101
+ pr_a.attnum,
102
+ pr_a.attname,
103
+ c.relname,
104
+ c.relnamespace,
105
+ pr_a.prtype,
106
+ pr_a.grantable,
107
+ c.relowner
108
+ from
109
+ (select a.attrelid,
110
+ a.attnum,
111
+ a.attname,
112
+ (aclexplode(coalesce(a.attacl, acldefault('c', cc.relowner)))).grantor as grantor,
113
+ (aclexplode(coalesce(a.attacl, acldefault('c', cc.relowner)))).grantee as grantee,
114
+ (aclexplode(coalesce(a.attacl, acldefault('c', cc.relowner)))).privilege_type as privilege_type,
115
+ (aclexplode(coalesce(a.attacl, acldefault('c', cc.relowner)))).is_grantable as is_grantable
116
+ from (pg_attribute a
117
+ join pg_class cc on ((a.attrelid = cc.oid)))
118
+ where ((a.attnum > 0)
119
+ and (not a.attisdropped))) pr_a(attrelid, attnum, attname, grantor, grantee, prtype, grantable),
120
+ pg_class c
121
+ where ((pr_a.attrelid = c.oid)
122
+ and (c.relkind = any (ARRAY['r',
123
+ 'v',
124
+ 'm',
125
+ 'f',
126
+ 'p'])))) x,
127
+ pg_namespace nc,
128
+ pg_authid u_grantor,
129
+ (select pg_authid.oid,
130
+ pg_authid.rolname
131
+ from pg_authid
132
+ union all select (0)::oid as oid,
133
+ 'PUBLIC') grantee(oid, rolname)
134
+ where ((x.relnamespace = nc.oid)
135
+ ${props.schemaFilter ? `and nc.nspname ${props.schemaFilter}` : ""}
136
+ ${props.columnIdsFilter ? `and (x.attrelid || '.' || x.attnum) ${props.columnIdsFilter}` : ""}
137
+ and (x.grantee = grantee.oid)
138
+ and (x.grantor = u_grantor.oid)
139
+ and (x.prtype = any (ARRAY['INSERT',
140
+ 'SELECT',
141
+ 'UPDATE',
142
+ 'REFERENCES']))
143
+ and (pg_has_role(u_grantor.oid, 'USAGE')
144
+ or pg_has_role(grantee.oid, 'USAGE')
145
+ or (grantee.rolname = 'PUBLIC')))
146
+ group by column_id,
147
+ nc.nspname,
148
+ x.relname,
149
+ x.attname
150
+ ${props.limit ? `limit ${props.limit}` : ""}
151
+ ${props.offset ? `offset ${props.offset}` : ""}
152
+ `;
153
+ //#endregion
154
+ export { COLUMN_PRIVILEGES_SQL };
@@ -0,0 +1,123 @@
1
+ //#region src/vendor/postgres-meta/lib/sql/columns.sql.ts
2
+ const COLUMNS_SQL = (props) => `
3
+ -- Adapted from information_schema.columns
4
+
5
+ SELECT
6
+ c.oid :: int8 AS table_id,
7
+ nc.nspname AS schema,
8
+ c.relname AS table,
9
+ (c.oid || '.' || a.attnum) AS id,
10
+ a.attnum AS ordinal_position,
11
+ a.attname AS name,
12
+ CASE
13
+ WHEN a.atthasdef THEN pg_get_expr(ad.adbin, ad.adrelid)
14
+ ELSE NULL
15
+ END AS default_value,
16
+ CASE
17
+ WHEN t.typtype = 'd' THEN CASE
18
+ WHEN bt.typelem <> 0 :: oid
19
+ AND bt.typlen = -1 THEN 'ARRAY'
20
+ WHEN nbt.nspname = 'pg_catalog' THEN format_type(t.typbasetype, NULL)
21
+ ELSE 'USER-DEFINED'
22
+ END
23
+ ELSE CASE
24
+ WHEN t.typelem <> 0 :: oid
25
+ AND t.typlen = -1 THEN 'ARRAY'
26
+ WHEN nt.nspname = 'pg_catalog' THEN format_type(a.atttypid, NULL)
27
+ ELSE 'USER-DEFINED'
28
+ END
29
+ END AS data_type,
30
+ COALESCE(bt.typname, t.typname) AS format,
31
+ a.attidentity IN ('a', 'd') AS is_identity,
32
+ CASE
33
+ a.attidentity
34
+ WHEN 'a' THEN 'ALWAYS'
35
+ WHEN 'd' THEN 'BY DEFAULT'
36
+ ELSE NULL
37
+ END AS identity_generation,
38
+ a.attgenerated IN ('s') AS is_generated,
39
+ NOT (
40
+ a.attnotnull
41
+ OR t.typtype = 'd' AND t.typnotnull
42
+ ) AS is_nullable,
43
+ (
44
+ c.relkind IN ('r', 'p')
45
+ OR c.relkind IN ('v', 'f') AND pg_column_is_updatable(c.oid, a.attnum, FALSE)
46
+ ) AS is_updatable,
47
+ uniques.table_id IS NOT NULL AS is_unique,
48
+ check_constraints.definition AS "check",
49
+ array_to_json(
50
+ array(
51
+ SELECT
52
+ enumlabel
53
+ FROM
54
+ pg_catalog.pg_enum enums
55
+ WHERE
56
+ enums.enumtypid = coalesce(bt.oid, t.oid)
57
+ OR enums.enumtypid = coalesce(bt.typelem, t.typelem)
58
+ ORDER BY
59
+ enums.enumsortorder
60
+ )
61
+ ) AS enums,
62
+ col_description(c.oid, a.attnum) AS comment
63
+ FROM
64
+ pg_attribute a
65
+ LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid
66
+ AND a.attnum = ad.adnum
67
+ JOIN (
68
+ pg_class c
69
+ JOIN pg_namespace nc ON c.relnamespace = nc.oid
70
+ ) ON a.attrelid = c.oid
71
+ JOIN (
72
+ pg_type t
73
+ JOIN pg_namespace nt ON t.typnamespace = nt.oid
74
+ ) ON a.atttypid = t.oid
75
+ LEFT JOIN (
76
+ pg_type bt
77
+ JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid
78
+ ) ON t.typtype = 'd'
79
+ AND t.typbasetype = bt.oid
80
+ LEFT JOIN (
81
+ SELECT DISTINCT ON (table_id, ordinal_position)
82
+ conrelid AS table_id,
83
+ conkey[1] AS ordinal_position
84
+ FROM pg_catalog.pg_constraint
85
+ WHERE contype = 'u' AND cardinality(conkey) = 1
86
+ ) AS uniques ON uniques.table_id = c.oid AND uniques.ordinal_position = a.attnum
87
+ LEFT JOIN (
88
+ -- We only select the first column check
89
+ SELECT DISTINCT ON (table_id, ordinal_position)
90
+ conrelid AS table_id,
91
+ conkey[1] AS ordinal_position,
92
+ substring(
93
+ pg_get_constraintdef(pg_constraint.oid, true),
94
+ 8,
95
+ length(pg_get_constraintdef(pg_constraint.oid, true)) - 8
96
+ ) AS "definition"
97
+ FROM pg_constraint
98
+ WHERE contype = 'c' AND cardinality(conkey) = 1
99
+ ORDER BY table_id, ordinal_position, oid asc
100
+ ) AS check_constraints ON check_constraints.table_id = c.oid AND check_constraints.ordinal_position = a.attnum
101
+ WHERE
102
+ ${props.schemaFilter ? `nc.nspname ${props.schemaFilter} AND` : ""}
103
+ ${props.idsFilter ? `(c.oid || '.' || a.attnum) ${props.idsFilter} AND` : ""}
104
+ ${props.columnNameFilter ? `(c.relname || '.' || a.attname) ${props.columnNameFilter} AND` : ""}
105
+ ${props.tableIdFilter ? `c.oid ${props.tableIdFilter} AND` : ""}
106
+ ${props.tableIdentifierFilter ? `nc.nspname || '.' || c.relname ${props.tableIdentifierFilter} AND` : ""}
107
+ NOT pg_is_other_temp_schema(nc.oid)
108
+ AND a.attnum > 0
109
+ AND NOT a.attisdropped
110
+ AND (c.relkind IN ('r', 'v', 'm', 'f', 'p'))
111
+ AND (
112
+ pg_has_role(c.relowner, 'USAGE')
113
+ OR has_column_privilege(
114
+ c.oid,
115
+ a.attnum,
116
+ 'SELECT, INSERT, UPDATE, REFERENCES'
117
+ )
118
+ )
119
+ ${props.limit ? `limit ${props.limit}` : ""}
120
+ ${props.offset ? `offset ${props.offset}` : ""}
121
+ `;
122
+ //#endregion
123
+ export { COLUMNS_SQL };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ //#region src/vendor/postgres-meta/lib/sql/config.sql.ts
2
+ const CONFIG_SQL = (props) => `
3
+ SELECT
4
+ name,
5
+ setting,
6
+ category,
7
+ TRIM(split_part(category, '/', 1)) AS group,
8
+ TRIM(split_part(category, '/', 2)) AS subgroup,
9
+ unit,
10
+ short_desc,
11
+ extra_desc,
12
+ context,
13
+ vartype,
14
+ source,
15
+ min_val,
16
+ max_val,
17
+ enumvals,
18
+ boot_val,
19
+ reset_val,
20
+ sourcefile,
21
+ sourceline,
22
+ pending_restart
23
+ FROM
24
+ pg_settings
25
+ ORDER BY
26
+ category,
27
+ name
28
+ ${props.limit ? `limit ${props.limit}` : ""}
29
+ ${props.offset ? `offset ${props.offset}` : ""}
30
+ `;
31
+ //#endregion
32
+ export { CONFIG_SQL };
@@ -0,0 +1,20 @@
1
+ //#region src/vendor/postgres-meta/lib/sql/extensions.sql.ts
2
+ const EXTENSIONS_SQL = (props) => `
3
+ SELECT
4
+ e.name,
5
+ n.nspname AS schema,
6
+ e.default_version,
7
+ x.extversion AS installed_version,
8
+ e.comment
9
+ FROM
10
+ pg_available_extensions() e(name, default_version, comment)
11
+ LEFT JOIN pg_extension x ON e.name = x.extname
12
+ LEFT JOIN pg_namespace n ON x.extnamespace = n.oid
13
+ WHERE
14
+ true
15
+ ${props.nameFilter ? `AND e.name ${props.nameFilter}` : ""}
16
+ ${props.limit ? `limit ${props.limit}` : ""}
17
+ ${props.offset ? `offset ${props.offset}` : ""}
18
+ `;
19
+ //#endregion
20
+ export { EXTENSIONS_SQL };
@@ -0,0 +1,20 @@
1
+ //#region src/vendor/postgres-meta/lib/sql/foreign_tables.sql.ts
2
+ const FOREIGN_TABLES_SQL = (props) => `
3
+ SELECT
4
+ c.oid :: int8 AS id,
5
+ n.nspname AS schema,
6
+ c.relname AS name,
7
+ obj_description(c.oid) AS comment
8
+ FROM
9
+ pg_class c
10
+ JOIN pg_namespace n ON n.oid = c.relnamespace
11
+ WHERE
12
+ ${props.schemaFilter ? `n.nspname ${props.schemaFilter} AND` : ""}
13
+ ${props.idsFilter ? `c.oid ${props.idsFilter} AND` : ""}
14
+ ${props.tableIdentifierFilter ? `(n.nspname || '.' || c.relname) ${props.tableIdentifierFilter} AND` : ""}
15
+ c.relkind = 'f'
16
+ ${props.limit ? `limit ${props.limit}` : ""}
17
+ ${props.offset ? `offset ${props.offset}` : ""}
18
+ `;
19
+ //#endregion
20
+ export { FOREIGN_TABLES_SQL };