@intentius/chant-lexicon-sql 0.124.30 → 0.124.32
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/dist/change-set.js +250 -0
- package/dist/clickhouse/access.js +722 -0
- package/dist/clickhouse/apply/apply.js +243 -0
- package/dist/clickhouse/apply/mutations.js +66 -0
- package/dist/clickhouse/apply/statements.js +545 -0
- package/dist/clickhouse/catalog-types.js +7 -0
- package/dist/clickhouse/container.js +152 -0
- package/dist/clickhouse/engine-syntax.js +159 -0
- package/dist/clickhouse/entities.js +593 -0
- package/dist/clickhouse/expressions.js +107 -0
- package/dist/clickhouse/http.js +55 -0
- package/dist/clickhouse/import/generator.js +192 -0
- package/dist/clickhouse/import/inlined.js +207 -0
- package/dist/clickhouse/import/ir.js +160 -0
- package/dist/clickhouse/import/live-export.js +131 -0
- package/dist/clickhouse/import/parser.js +17 -0
- package/dist/clickhouse/live/bind.js +116 -0
- package/dist/clickhouse/live/catalog.js +223 -0
- package/dist/clickhouse/live/describe-resources.js +91 -0
- package/dist/clickhouse/live/undeclarable.js +59 -0
- package/dist/clickhouse/overlays/codecs.js +57 -0
- package/dist/clickhouse/overlays/engines.js +101 -0
- package/dist/clickhouse/overlays/kinds.js +1 -0
- package/dist/clickhouse/overlays/projections.js +26 -0
- package/dist/clickhouse/overlays/skip-indexes.js +40 -0
- package/dist/clickhouse/overlays/ttl.js +34 -0
- package/dist/clickhouse/overlays/types.js +59 -0
- package/dist/clickhouse/ownership.js +83 -0
- package/dist/clickhouse/parser.js +674 -0
- package/dist/clickhouse/plan/commands.js +159 -0
- package/dist/clickhouse/plan/deep.js +345 -0
- package/dist/clickhouse/plan/diff.js +312 -0
- package/dist/clickhouse/plan/disruption.js +73 -0
- package/dist/clickhouse/plan/normalize.js +545 -0
- package/dist/clickhouse/plan/rebuild-handoff.js +57 -0
- package/dist/clickhouse/plan/report.js +26 -0
- package/dist/clickhouse/plan/rules.js +72 -0
- package/dist/clickhouse/plan/schema.js +67 -0
- package/dist/clickhouse/plan/server-format.js +35 -0
- package/dist/clickhouse/rebuild/backfill.js +265 -0
- package/dist/clickhouse/rebuild/engines.js +146 -0
- package/dist/clickhouse/rebuild/observe.js +260 -0
- package/dist/clickhouse/rebuild/op.js +152 -0
- package/dist/clickhouse/rebuild/partitions.js +65 -0
- package/dist/clickhouse/rebuild/receipts.js +120 -0
- package/dist/clickhouse/rebuild/replicas.js +121 -0
- package/dist/clickhouse/rebuild/shards.js +76 -0
- package/dist/clickhouse/rebuild/steps.js +383 -0
- package/dist/clickhouse/rebuild/verify.js +279 -0
- package/dist/clickhouse/row-types.js +151 -0
- package/dist/clickhouse/testing/fake-server.js +47 -0
- package/dist/clickhouse/testing/roundtrip-schema.js +25 -0
- package/dist/clickhouse/testing/writable-server.js +123 -0
- package/dist/clickhouse/tokens.js +23 -0
- package/dist/clickhouse/topology.js +463 -0
- package/dist/clickhouse/type-syntax.js +73 -0
- package/dist/clickhouse.js +25 -0
- package/dist/codegen/classifier-page.js +93 -0
- package/dist/codegen/clickhouse-module.js +249 -0
- package/dist/codegen/coverage-page.js +70 -0
- package/dist/codegen/docs-cli.js +3 -0
- package/dist/codegen/docs.js +222 -0
- package/dist/codegen/generate-cli.js +13 -0
- package/dist/codegen/generate.js +97 -0
- package/dist/codegen/package.js +28 -0
- package/dist/codegen/postgres-classifier-page.js +95 -0
- package/dist/codegen/postgres-module.js +418 -0
- package/dist/codegen/registry.js +52 -0
- package/dist/composites/audit-log-table.js +35 -0
- package/dist/composites/catalog.js +524 -0
- package/dist/composites/cdc-mirror.js +32 -0
- package/dist/composites/clickhouse.js +6 -0
- package/dist/composites/events-table.js +26 -0
- package/dist/composites/index.js +8 -0
- package/dist/composites/join-table.js +25 -0
- package/dist/composites/postgres.js +6 -0
- package/dist/composites/refreshed-view.js +24 -0
- package/dist/composites/replacing-table.js +28 -0
- package/dist/composites/rollup-view.js +29 -0
- package/dist/composites/sharded-table.js +27 -0
- package/dist/composites/soft-delete-table.js +34 -0
- package/dist/composites/tenant-table.js +26 -0
- package/dist/composites/typed.js +8 -0
- package/dist/config.js +206 -0
- package/dist/core/apply.js +93 -0
- package/dist/core/classifier.js +115 -0
- package/dist/core/container.js +69 -0
- package/dist/core/cursor.js +261 -0
- package/dist/core/diff.js +48 -0
- package/dist/core/entity.js +58 -0
- package/dist/core/find-templates.js +118 -0
- package/dist/core/foreign-tables.js +27 -0
- package/dist/core/handoff.js +32 -0
- package/dist/core/index.js +64 -0
- package/dist/core/interpolation.js +191 -0
- package/dist/core/normalize.js +43 -0
- package/dist/core/ownership.js +119 -0
- package/dist/core/receipts.js +22 -0
- package/dist/core/references.js +61 -0
- package/dist/core/statements.js +42 -0
- package/dist/core/template.js +79 -0
- package/dist/core/testing/http-stub.js +21 -0
- package/dist/core/tokens.js +202 -0
- package/dist/core/typed.js +40 -0
- package/dist/core/undeclarable.js +46 -0
- package/dist/coverage.js +161 -0
- package/dist/detect.js +32 -0
- package/dist/dialects.js +18 -0
- package/dist/files/build-root.js +72 -0
- package/dist/files/clickhouse.js +138 -0
- package/dist/files/common.js +58 -0
- package/dist/files/postgres.js +389 -0
- package/dist/generated/clickhouse-types.js +5 -0
- package/dist/generated/clickhouse.js +4361 -0
- package/dist/generated/postgres-types.js +227 -0
- package/dist/generated/postgres.js +3667 -0
- package/dist/import-generator.js +14 -0
- package/dist/import-parser.js +71 -0
- package/dist/index.js +24 -0
- package/dist/init-templates.js +290 -0
- package/dist/integrity.json +2 -2
- package/dist/lint/audit-catalog.js +31 -0
- package/dist/lint/audit-lineage.js +22 -0
- package/dist/lint/post-synth/audit-entries.js +34 -0
- package/dist/lint/post-synth/clickhouse-helpers.js +79 -0
- package/dist/lint/post-synth/clickhouse-type-check.js +162 -0
- package/dist/lint/post-synth/index.js +112 -0
- package/dist/lint/post-synth/postgres-audit-entries.js +35 -0
- package/dist/lint/post-synth/postgres-helpers.js +65 -0
- package/dist/lint/post-synth/postgres-names.js +507 -0
- package/dist/lint/post-synth/sql-helpers.js +23 -0
- package/dist/lint/post-synth/sql101.js +59 -0
- package/dist/lint/post-synth/sql102.js +34 -0
- package/dist/lint/post-synth/sqlch101.js +34 -0
- package/dist/lint/post-synth/sqlch102.js +23 -0
- package/dist/lint/post-synth/sqlch103.js +45 -0
- package/dist/lint/post-synth/sqlch104.js +41 -0
- package/dist/lint/post-synth/sqlch105.js +36 -0
- package/dist/lint/post-synth/sqlch106.js +27 -0
- package/dist/lint/post-synth/sqlch107.js +39 -0
- package/dist/lint/post-synth/sqlch108.js +28 -0
- package/dist/lint/post-synth/sqlch109.js +21 -0
- package/dist/lint/post-synth/sqlch110.js +31 -0
- package/dist/lint/post-synth/sqlch111.js +41 -0
- package/dist/lint/post-synth/sqlch112.js +28 -0
- package/dist/lint/post-synth/sqlch113.js +19 -0
- package/dist/lint/post-synth/sqlch114.js +26 -0
- package/dist/lint/post-synth/sqlch115.js +30 -0
- package/dist/lint/post-synth/sqlch116.js +22 -0
- package/dist/lint/post-synth/sqlch117.js +26 -0
- package/dist/lint/post-synth/sqlch118.js +27 -0
- package/dist/lint/post-synth/sqlch119.js +32 -0
- package/dist/lint/post-synth/sqlch120.js +20 -0
- package/dist/lint/post-synth/sqlch121.js +11 -0
- package/dist/lint/post-synth/sqlch122.js +11 -0
- package/dist/lint/post-synth/sqlch123.js +10 -0
- package/dist/lint/post-synth/sqlch124.js +21 -0
- package/dist/lint/post-synth/sqlch125.js +55 -0
- package/dist/lint/post-synth/sqlch126.js +62 -0
- package/dist/lint/post-synth/sqlch127.js +132 -0
- package/dist/lint/post-synth/sqlpg101.js +25 -0
- package/dist/lint/post-synth/sqlpg102.js +35 -0
- package/dist/lint/post-synth/sqlpg103.js +23 -0
- package/dist/lint/post-synth/sqlpg104.js +23 -0
- package/dist/lint/post-synth/sqlpg105.js +22 -0
- package/dist/lint/post-synth/sqlpg106.js +22 -0
- package/dist/lint/post-synth/sqlpg107.js +22 -0
- package/dist/lint/post-synth/sqlpg108.js +28 -0
- package/dist/lint/post-synth/sqlpg109.js +39 -0
- package/dist/lint/post-synth/sqlpg110.js +38 -0
- package/dist/lint/post-synth/sqlpg111.js +23 -0
- package/dist/lint/post-synth/sqlpg112.js +25 -0
- package/dist/lint/post-synth/sqlpg113.js +29 -0
- package/dist/lint/post-synth/sqlpg114.js +39 -0
- package/dist/lint/post-synth/sqlpg115.js +48 -0
- package/dist/lint/post-synth/sqlpg116.js +26 -0
- package/dist/lint/post-synth/sqlpg117.js +24 -0
- package/dist/lint/post-synth/sqlpg118.js +22 -0
- package/dist/lint/post-synth/sqlpg119.js +41 -0
- package/dist/lint/post-synth/sqlpg120.js +83 -0
- package/dist/lint/post-synth/sqlpg121.js +33 -0
- package/dist/lint/post-synth/sqlpg122.js +27 -0
- package/dist/lint/post-synth/sqlpg123.js +69 -0
- package/dist/lint/post-synth/sqlpg124.js +50 -0
- package/dist/lint/post-synth/sqlpg125.js +41 -0
- package/dist/lint/post-synth/sqlpg126.js +38 -0
- package/dist/lint/rules/index.js +12 -0
- package/dist/lint/rules/postgres-templates.js +27 -0
- package/dist/lint/rules/sqlch001.js +79 -0
- package/dist/lint/rules/sqlch002.js +124 -0
- package/dist/lint/rules/sqlch003.js +69 -0
- package/dist/lint/rules/sqlch004.js +83 -0
- package/dist/lint/rules/sqlpg001.js +68 -0
- package/dist/lint/rules/sqlpg002.js +69 -0
- package/dist/lint/rules/sqlpg003.js +58 -0
- package/dist/lint/rules/sqlpg004.js +77 -0
- package/dist/lint/rules/sqlpg005.js +86 -0
- package/dist/lint/rules/templates.js +25 -0
- package/dist/lint/rules/typed-names.js +132 -0
- package/dist/live-dialect.js +32 -0
- package/dist/lsp/catalog.js +44 -0
- package/dist/lsp/completions.js +136 -0
- package/dist/lsp/hover.js +115 -0
- package/dist/lsp/postgres-catalog.js +176 -0
- package/dist/lsp/postgres-template.js +171 -0
- package/dist/lsp/postgres.js +266 -0
- package/dist/lsp/refs.js +60 -0
- package/dist/lsp/registry.d.ts.map +1 -1
- package/dist/lsp/registry.js +19 -0
- package/dist/lsp/template.js +143 -0
- package/dist/manifest.json +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +293 -0
- package/dist/mcp/postgres.js +117 -0
- package/dist/migration-statements.js +243 -0
- package/dist/op/activities/clickhouse-apply.js +83 -0
- package/dist/op/activities/clickhouse-emulator.js +53 -0
- package/dist/op/activities/clickhouse-rebuild.js +119 -0
- package/dist/op/activities/index.js +26 -0
- package/dist/op/activities/postgres-apply.js +126 -0
- package/dist/op/activities/postgres-emulator.js +70 -0
- package/dist/op/activities/postgres-migration.js +156 -0
- package/dist/op/activities/sql-exec.js +57 -0
- package/dist/op/activity-contracts.js +103 -0
- package/dist/package-cli.js +14 -0
- package/dist/plugin.js +259 -0
- package/dist/postgres/access/acl.js +344 -0
- package/dist/postgres/access/changes.js +30 -0
- package/dist/postgres/access/import.js +61 -0
- package/dist/postgres/access/live.js +96 -0
- package/dist/postgres/apply/apply.js +557 -0
- package/dist/postgres/apply/statements.js +882 -0
- package/dist/postgres/catalog-types.js +18 -0
- package/dist/postgres/container.js +58 -0
- package/dist/postgres/entities.js +1390 -0
- package/dist/postgres/entity-types.js +28 -0
- package/dist/postgres/import/generator.js +283 -0
- package/dist/postgres/import/ir.js +53 -0
- package/dist/postgres/import/live-export.js +83 -0
- package/dist/postgres/keywords.js +32 -0
- package/dist/postgres/live/bind.js +130 -0
- package/dist/postgres/live/catalog-kinds.js +301 -0
- package/dist/postgres/live/catalog.js +644 -0
- package/dist/postgres/live/client.js +151 -0
- package/dist/postgres/live/describe-resources.js +135 -0
- package/dist/postgres/live/undeclarable.js +111 -0
- package/dist/postgres/migrate/backfill.js +170 -0
- package/dist/postgres/migrate/batches.js +122 -0
- package/dist/postgres/migrate/carry.js +518 -0
- package/dist/postgres/migrate/handoff.js +59 -0
- package/dist/postgres/migrate/names.js +61 -0
- package/dist/postgres/migrate/observe.js +360 -0
- package/dist/postgres/migrate/op.js +178 -0
- package/dist/postgres/migrate/receipts.js +117 -0
- package/dist/postgres/migrate/replication.js +106 -0
- package/dist/postgres/migrate/steps.js +514 -0
- package/dist/postgres/overlays/columns.js +31 -0
- package/dist/postgres/overlays/constraints.js +52 -0
- package/dist/postgres/overlays/extension-objects.js +88 -0
- package/dist/postgres/overlays/indexes.js +25 -0
- package/dist/postgres/overlays/kinds.js +2 -0
- package/dist/postgres/overlays/partitioning.js +23 -0
- package/dist/postgres/overlays/relations.js +25 -0
- package/dist/postgres/overlays/storage.js +65 -0
- package/dist/postgres/overlays/type-ddl.js +36 -0
- package/dist/postgres/overlays/types.js +74 -0
- package/dist/postgres/parser.js +1824 -0
- package/dist/postgres/plan/commands.js +137 -0
- package/dist/postgres/plan/deep.js +324 -0
- package/dist/postgres/plan/diff.js +499 -0
- package/dist/postgres/plan/disruption.js +64 -0
- package/dist/postgres/plan/normalize.js +889 -0
- package/dist/postgres/plan/report.js +21 -0
- package/dist/postgres/plan/rules.js +115 -0
- package/dist/postgres/plan/schema.js +105 -0
- package/dist/postgres/plan/server-normalize.js +166 -0
- package/dist/postgres/providers/aurora.js +44 -0
- package/dist/postgres/providers/azure.js +53 -0
- package/dist/postgres/providers/cloud-sql.js +41 -0
- package/dist/postgres/providers/index.js +73 -0
- package/dist/postgres/providers/neon.js +44 -0
- package/dist/postgres/providers/rds.js +47 -0
- package/dist/postgres/providers/supabase.js +45 -0
- package/dist/postgres/providers/types.js +21 -0
- package/dist/postgres/row-types.js +107 -0
- package/dist/postgres/testing/fake-client.js +34 -0
- package/dist/postgres/testing/migration.js +48 -0
- package/dist/postgres/testing/roundtrip-schema.js +64 -0
- package/dist/postgres/testing/server.js +47 -0
- package/dist/postgres/testing/writable-server.js +160 -0
- package/dist/postgres/tokens.js +41 -0
- package/dist/postgres.js +15 -0
- package/dist/read/clickhouse.js +82 -0
- package/dist/read/objects.js +44 -0
- package/dist/read/postgres.js +104 -0
- package/dist/read.js +52 -0
- package/dist/receipts.js +207 -0
- package/dist/serializer.js +172 -0
- package/dist/skill-defs.js +93 -0
- package/dist/spec/catalog.js +191 -0
- package/dist/spec/fetch.d.ts.map +1 -1
- package/dist/spec/fetch.js +90 -0
- package/dist/spec/pin.js +42 -0
- package/dist/spec/postgres-catalog.js +171 -0
- package/dist/spec/postgres-fetch.js +91 -0
- package/dist/spec/postgres-pin.js +82 -0
- package/dist/sql-files.js +206 -0
- package/dist/sql-types-command.js +97 -0
- package/dist/sql-types.js +323 -0
- package/dist/token-source.js +156 -0
- package/dist/validate-cli.js +5 -0
- package/dist/validate.js +151 -0
- package/dist/workspace-outputs.js +191 -0
- package/package.json +7 -7
- package/src/codegen/package.ts +2 -2
- package/src/lint/rules/typescript-7.test.ts +2 -1
- package/src/lsp/catalog.ts +2 -2
- package/src/lsp/postgres-catalog.ts +2 -2
- package/src/lsp/registry.ts +2 -1
- package/src/mcp/index.ts +4 -2
- package/src/spec/fetch.ts +2 -2
- package/src/spec/postgres-fetch.ts +2 -2
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The catalog read of the kinds #3911 adds: composite and range types,
|
|
3
|
+
* collations, aggregates, casts and event triggers. Postgres has no printer
|
|
4
|
+
* for any of them (`pg_dump` assembles each from its catalog row), so the
|
|
5
|
+
* statement is assembled here the same way: `format_type()` for every type,
|
|
6
|
+
* `regproc` for every function (bare in `pg_catalog`, qualified elsewhere,
|
|
7
|
+
* since the session's search_path is empty), and an option only where it is
|
|
8
|
+
* not what Postgres would choose by itself, so the printed form is the
|
|
9
|
+
* canonical one a declaration is compared with (`../plan/normalize.ts`).
|
|
10
|
+
*
|
|
11
|
+
* Left out, each for its reason: a table's row type (the table is its
|
|
12
|
+
* declaration), a multirange type (its range type creates it), an object an
|
|
13
|
+
* extension owns, and a cast the server defines (`oid` below 16384, the first
|
|
14
|
+
* normal object id).
|
|
15
|
+
*
|
|
16
|
+
* Each object carries what depends on it (`pg_depend`, a normal dependency),
|
|
17
|
+
* which a DROP refuses over, so a change the plan would make by dropping and
|
|
18
|
+
* creating it is refused instead (SQLPG301).
|
|
19
|
+
*/
|
|
20
|
+
import { notExtensionOwned, scopeSql } from "./catalog.js";
|
|
21
|
+
import { POSTGRES_ENTITY_TYPES } from "../entity-types.js";
|
|
22
|
+
import { quoteIdent } from "../keywords.js";
|
|
23
|
+
import { stripMarker } from "../../core/ownership.js";
|
|
24
|
+
const C = 'COLLATE "C"';
|
|
25
|
+
const str = (v) => (v === null || v === undefined ? undefined : String(v));
|
|
26
|
+
const literal = (s) => `'${s.replace(/'/g, "''")}'`;
|
|
27
|
+
const qname = (schema, name) => `${quoteIdent(schema)}.${quoteIdent(name)}`;
|
|
28
|
+
function commentOn(what, comment) {
|
|
29
|
+
const c = str(comment);
|
|
30
|
+
if (c === undefined)
|
|
31
|
+
return [];
|
|
32
|
+
const own = stripMarker(c);
|
|
33
|
+
return own === "" ? [] : [`COMMENT ON ${what} IS ${literal(own)}`];
|
|
34
|
+
}
|
|
35
|
+
const notInternal = (catalog, oid) => `NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = 'pg_catalog.${catalog}'::pg_catalog.regclass AND d.objid = ${oid} AND d.deptype = 'i')`;
|
|
36
|
+
/** What depends on an object of catalog `catalog` (a normal dependency), as the server describes each. */
|
|
37
|
+
const dependentsOf = (catalog, oid) => `ARRAY(SELECT pg_catalog.pg_describe_object(d.classid, d.objid, d.objsubid) FROM pg_catalog.pg_depend d
|
|
38
|
+
WHERE d.refclassid = 'pg_catalog.${catalog}'::pg_catalog.regclass AND d.refobjid = ${oid} AND d.deptype = 'n' ORDER BY 1)`;
|
|
39
|
+
/** A collation's name as a clause: a `pg_catalog` one bare. */
|
|
40
|
+
const collationName = (oid) => `(SELECT CASE WHEN cn.nspname = 'pg_catalog' THEN pg_catalog.quote_ident(co.collname) ELSE pg_catalog.quote_ident(cn.nspname) || '.' || pg_catalog.quote_ident(co.collname) END ` +
|
|
41
|
+
`FROM pg_catalog.pg_collation co JOIN pg_catalog.pg_namespace cn ON cn.oid = co.collnamespace WHERE co.oid = ${oid})`;
|
|
42
|
+
/** A function named by a `regproc` column, or nothing for 0 (which `regproc` prints as `-`). */
|
|
43
|
+
const proc = (column) => `NULLIF(${column}::text, '-')`;
|
|
44
|
+
const dependents = (r) => {
|
|
45
|
+
const d = r.dependents ?? [];
|
|
46
|
+
return d.length > 0 ? { dependents: d } : {};
|
|
47
|
+
};
|
|
48
|
+
const withComment = (r) => (str(r.comment) ? { comment: str(r.comment) } : {});
|
|
49
|
+
/** Composite and range types: read where the enums are, before the domains and tables that may use them. */
|
|
50
|
+
export async function readTypeKinds(client, scope) {
|
|
51
|
+
const out = [];
|
|
52
|
+
const s = scopeSql("n.nspname", scope);
|
|
53
|
+
// Composite types: the standalone ones, not a table's or a view's row type.
|
|
54
|
+
const composites = await client.query(`SELECT t.oid::text AS oid, n.nspname AS schema, t.typname AS name, pg_catalog.obj_description(t.oid, 'pg_type') AS comment,
|
|
55
|
+
ARRAY(SELECT pg_catalog.quote_ident(a.attname) || ' ' || pg_catalog.format_type(a.atttypid, a.atttypmod) ||
|
|
56
|
+
CASE WHEN a.attcollation <> 0 AND a.attcollation <> at.typcollation THEN ' COLLATE ' || ${collationName("a.attcollation")} ELSE '' END
|
|
57
|
+
FROM pg_catalog.pg_attribute AS a JOIN pg_catalog.pg_type at ON at.oid = a.atttypid
|
|
58
|
+
WHERE a.attrelid = t.typrelid AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum) AS attributes,
|
|
59
|
+
${dependentsOf("pg_type", "t.oid")} AS dependents
|
|
60
|
+
FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace JOIN pg_catalog.pg_class c ON c.oid = t.typrelid
|
|
61
|
+
WHERE t.typtype = 'c' AND c.relkind = 'c' AND ${s.sql} AND ${notExtensionOwned("pg_type", "t.oid")}
|
|
62
|
+
ORDER BY n.nspname ${C}, t.typname ${C}`, s.params);
|
|
63
|
+
for (const r of composites) {
|
|
64
|
+
const q = qname(String(r.schema), String(r.name));
|
|
65
|
+
const attributes = r.attributes ?? [];
|
|
66
|
+
out.push({
|
|
67
|
+
type: POSTGRES_ENTITY_TYPES.composite,
|
|
68
|
+
schema: String(r.schema),
|
|
69
|
+
name: String(r.name),
|
|
70
|
+
oid: String(r.oid),
|
|
71
|
+
...withComment(r),
|
|
72
|
+
...dependents(r),
|
|
73
|
+
statement: [`CREATE TYPE ${q} AS (${attributes.length > 0 ? `\n ${attributes.join(",\n ")}\n` : ""})`, ...commentOn(`TYPE ${q}`, r.comment)].join(";\n"),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Range types, each with the options that differ from what CREATE TYPE ... AS RANGE would choose.
|
|
77
|
+
const ranges = await client.query(`SELECT t.oid::text AS oid, n.nspname AS schema, t.typname AS name, pg_catalog.obj_description(t.oid, 'pg_type') AS comment,
|
|
78
|
+
pg_catalog.format_type(r.rngsubtype, NULL) AS subtype,
|
|
79
|
+
CASE WHEN r.rngsubopc <> (SELECT o.oid FROM pg_catalog.pg_opclass o JOIN pg_catalog.pg_am am ON am.oid = o.opcmethod
|
|
80
|
+
WHERE am.amname = 'btree' AND o.opcintype = r.rngsubtype AND o.opcdefault LIMIT 1)
|
|
81
|
+
THEN (SELECT CASE WHEN on2.nspname = 'pg_catalog' THEN pg_catalog.quote_ident(o.opcname) ELSE pg_catalog.quote_ident(on2.nspname) || '.' || pg_catalog.quote_ident(o.opcname) END
|
|
82
|
+
FROM pg_catalog.pg_opclass o JOIN pg_catalog.pg_namespace on2 ON on2.oid = o.opcnamespace WHERE o.oid = r.rngsubopc) END AS opclass,
|
|
83
|
+
CASE WHEN r.rngcollation <> 0 AND r.rngcollation <> st.typcollation THEN ${collationName("r.rngcollation")} END AS collation,
|
|
84
|
+
${proc("r.rngcanonical")} AS canonical, ${proc("r.rngsubdiff")} AS subdiff,
|
|
85
|
+
mn.nspname AS multi_schema, mt.typname AS multi_name,
|
|
86
|
+
${dependentsOf("pg_type", "t.oid")} AS dependents
|
|
87
|
+
FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace JOIN pg_catalog.pg_range r ON r.rngtypid = t.oid
|
|
88
|
+
JOIN pg_catalog.pg_type st ON st.oid = r.rngsubtype
|
|
89
|
+
JOIN pg_catalog.pg_type mt ON mt.oid = r.rngmultitypid JOIN pg_catalog.pg_namespace mn ON mn.oid = mt.typnamespace
|
|
90
|
+
WHERE t.typtype = 'r' AND ${s.sql} AND ${notExtensionOwned("pg_type", "t.oid")}
|
|
91
|
+
ORDER BY n.nspname ${C}, t.typname ${C}`, s.params);
|
|
92
|
+
for (const r of ranges) {
|
|
93
|
+
const schema = String(r.schema);
|
|
94
|
+
const name = String(r.name);
|
|
95
|
+
const q = qname(schema, name);
|
|
96
|
+
const opts = [`SUBTYPE = ${r.subtype}`];
|
|
97
|
+
if (str(r.opclass))
|
|
98
|
+
opts.push(`SUBTYPE_OPCLASS = ${r.opclass}`);
|
|
99
|
+
if (str(r.collation))
|
|
100
|
+
opts.push(`COLLATION = ${r.collation}`);
|
|
101
|
+
if (str(r.canonical))
|
|
102
|
+
opts.push(`CANONICAL = ${r.canonical}`);
|
|
103
|
+
if (str(r.subdiff))
|
|
104
|
+
opts.push(`SUBTYPE_DIFF = ${r.subdiff}`);
|
|
105
|
+
// The multirange type's name, when it is not the one Postgres derives in the range's schema.
|
|
106
|
+
const at = name.indexOf("range");
|
|
107
|
+
const derived = at >= 0 ? `${name.slice(0, at)}multi${name.slice(at)}` : `${name}_multirange`;
|
|
108
|
+
if (String(r.multi_schema) !== schema || String(r.multi_name) !== derived)
|
|
109
|
+
opts.push(`MULTIRANGE_TYPE_NAME = ${qname(String(r.multi_schema), String(r.multi_name))}`);
|
|
110
|
+
out.push({
|
|
111
|
+
type: POSTGRES_ENTITY_TYPES.range,
|
|
112
|
+
schema,
|
|
113
|
+
name,
|
|
114
|
+
oid: String(r.oid),
|
|
115
|
+
...withComment(r),
|
|
116
|
+
...dependents(r),
|
|
117
|
+
statement: [`CREATE TYPE ${q} AS RANGE (${opts.join(", ")})`, ...commentOn(`TYPE ${q}`, r.comment)].join(";\n"),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
/** Collations: read first, before the types and tables whose columns use them. */
|
|
123
|
+
export async function readCollations(client, scope) {
|
|
124
|
+
const s = scopeSql("n.nspname", scope);
|
|
125
|
+
const rows = await client.query(`SELECT c.oid::text AS oid, n.nspname AS schema, c.collname AS name, pg_catalog.to_jsonb(c) AS def,
|
|
126
|
+
pg_catalog.obj_description(c.oid, 'pg_collation') AS comment, ${dependentsOf("pg_collation", "c.oid")} AS dependents
|
|
127
|
+
FROM pg_catalog.pg_collation c JOIN pg_catalog.pg_namespace n ON n.oid = c.collnamespace
|
|
128
|
+
WHERE ${s.sql} AND ${notExtensionOwned("pg_collation", "c.oid")}
|
|
129
|
+
ORDER BY n.nspname ${C}, c.collname ${C}`, s.params);
|
|
130
|
+
const out = [];
|
|
131
|
+
for (const r of rows) {
|
|
132
|
+
// The row as JSON: its columns differ across the majors (`colliculocale` in 15 and 16, `colllocale` from 17, `collicurules` from 16).
|
|
133
|
+
const d = (typeof r.def === "string" ? JSON.parse(r.def) : r.def);
|
|
134
|
+
const provider = { c: "libc", i: "icu", b: "builtin", d: "default" }[String(d.collprovider)] ?? "libc";
|
|
135
|
+
const locale = str(d.colllocale) ?? str(d.colliculocale);
|
|
136
|
+
const opts = [];
|
|
137
|
+
if (provider !== "libc")
|
|
138
|
+
opts.push(`PROVIDER = ${provider}`);
|
|
139
|
+
if (provider === "libc" || locale === undefined) {
|
|
140
|
+
const collate = str(d.collcollate) ?? "";
|
|
141
|
+
const ctype = str(d.collctype) ?? "";
|
|
142
|
+
if (provider !== "libc")
|
|
143
|
+
opts.push(`LOCALE = ${literal(collate)}`);
|
|
144
|
+
else if (collate === ctype)
|
|
145
|
+
opts.push(`LOCALE = ${literal(collate)}`);
|
|
146
|
+
else
|
|
147
|
+
opts.push(`LC_COLLATE = ${literal(collate)}`, `LC_CTYPE = ${literal(ctype)}`);
|
|
148
|
+
}
|
|
149
|
+
else
|
|
150
|
+
opts.push(`LOCALE = ${literal(locale)}`);
|
|
151
|
+
if (d.collisdeterministic === false)
|
|
152
|
+
opts.push("DETERMINISTIC = false");
|
|
153
|
+
if (str(d.collicurules))
|
|
154
|
+
opts.push(`RULES = ${literal(String(d.collicurules))}`);
|
|
155
|
+
const q = qname(String(r.schema), String(r.name));
|
|
156
|
+
out.push({
|
|
157
|
+
type: POSTGRES_ENTITY_TYPES.collation,
|
|
158
|
+
schema: String(r.schema),
|
|
159
|
+
name: String(r.name),
|
|
160
|
+
oid: String(r.oid),
|
|
161
|
+
...withComment(r),
|
|
162
|
+
...dependents(r),
|
|
163
|
+
statement: [`CREATE COLLATION ${q} (${opts.join(", ")})`, ...commentOn(`COLLATION ${q}`, r.comment)].join(";\n"),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return out;
|
|
167
|
+
}
|
|
168
|
+
const MODIFY = { r: "READ_ONLY", s: "SHAREABLE", w: "READ_WRITE" };
|
|
169
|
+
/** Aggregates, casts and event triggers: read after the functions they call. */
|
|
170
|
+
export async function readRoutineKinds(client, scope) {
|
|
171
|
+
const out = [];
|
|
172
|
+
const s = scopeSql("n.nspname", scope);
|
|
173
|
+
const aggregates = await client.query(`SELECT p.oid::text AS oid, n.nspname AS schema, p.proname AS name, pg_catalog.pg_get_function_arguments(p.oid) AS args,
|
|
174
|
+
ARRAY(SELECT pg_catalog.format_type(u.x, NULL) FROM pg_catalog.unnest(p.proargtypes::pg_catalog.oid[]) WITH ORDINALITY AS u(x, i) ORDER BY u.i) AS argtypes,
|
|
175
|
+
a.aggkind AS kind, a.aggnumdirectargs AS ndirect,
|
|
176
|
+
${proc("a.aggtransfn")} AS sfunc, pg_catalog.format_type(a.aggtranstype, NULL) AS stype, a.aggtransspace AS sspace,
|
|
177
|
+
${proc("a.aggfinalfn")} AS finalfunc, a.aggfinalextra AS finalextra, a.aggfinalmodify::text AS finalmodify,
|
|
178
|
+
${proc("a.aggcombinefn")} AS combinefunc, ${proc("a.aggserialfn")} AS serialfunc, ${proc("a.aggdeserialfn")} AS deserialfunc,
|
|
179
|
+
a.agginitval AS initcond,
|
|
180
|
+
${proc("a.aggmtransfn")} AS msfunc, ${proc("a.aggminvtransfn")} AS minvfunc,
|
|
181
|
+
CASE WHEN a.aggmtranstype <> 0 THEN pg_catalog.format_type(a.aggmtranstype, NULL) END AS mstype, a.aggmtransspace AS msspace,
|
|
182
|
+
${proc("a.aggmfinalfn")} AS mfinalfunc, a.aggmfinalextra AS mfinalextra, a.aggmfinalmodify::text AS mfinalmodify, a.aggminitval AS minitcond,
|
|
183
|
+
CASE WHEN a.aggsortop <> 0 THEN (SELECT CASE WHEN opn.nspname = 'pg_catalog' THEN o.oprname ELSE 'OPERATOR(' || pg_catalog.quote_ident(opn.nspname) || '.' || o.oprname || ')' END
|
|
184
|
+
FROM pg_catalog.pg_operator o JOIN pg_catalog.pg_namespace opn ON opn.oid = o.oprnamespace WHERE o.oid = a.aggsortop) END AS sortop,
|
|
185
|
+
p.proparallel AS parallel, pg_catalog.obj_description(p.oid, 'pg_proc') AS comment,
|
|
186
|
+
${dependentsOf("pg_proc", "p.oid")} AS dependents
|
|
187
|
+
FROM pg_catalog.pg_proc p JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace JOIN pg_catalog.pg_aggregate a ON a.aggfnoid = p.oid
|
|
188
|
+
WHERE p.prokind = 'a' AND ${s.sql} AND ${notExtensionOwned("pg_proc", "p.oid")}
|
|
189
|
+
ORDER BY n.nspname ${C}, p.proname ${C}, pg_catalog.oidvectortypes(p.proargtypes) ${C}`, s.params);
|
|
190
|
+
for (const r of aggregates) {
|
|
191
|
+
const kind = String(r.kind);
|
|
192
|
+
const types = r.argtypes ?? [];
|
|
193
|
+
const ndirect = Number(r.ndirect ?? 0);
|
|
194
|
+
const signature = kind === "n"
|
|
195
|
+
? `(${types.length === 0 ? "*" : types.join(",")})`
|
|
196
|
+
: `(${ndirect > 0 ? `${types.slice(0, ndirect).join(",")} ` : ""}ORDER BY ${types.slice(ndirect).join(",")})`;
|
|
197
|
+
const args = str(r.args) || "*";
|
|
198
|
+
const modifyDefault = kind === "n" ? "r" : "w";
|
|
199
|
+
const opts = [`SFUNC = ${r.sfunc}`, `STYPE = ${r.stype}`];
|
|
200
|
+
if (Number(r.sspace) !== 0)
|
|
201
|
+
opts.push(`SSPACE = ${Number(r.sspace)}`);
|
|
202
|
+
if (str(r.finalfunc))
|
|
203
|
+
opts.push(`FINALFUNC = ${r.finalfunc}`);
|
|
204
|
+
if (r.finalextra === true)
|
|
205
|
+
opts.push("FINALFUNC_EXTRA");
|
|
206
|
+
if (str(r.finalmodify) && r.finalmodify !== modifyDefault)
|
|
207
|
+
opts.push(`FINALFUNC_MODIFY = ${MODIFY[String(r.finalmodify)]}`);
|
|
208
|
+
if (str(r.combinefunc))
|
|
209
|
+
opts.push(`COMBINEFUNC = ${r.combinefunc}`);
|
|
210
|
+
if (str(r.serialfunc))
|
|
211
|
+
opts.push(`SERIALFUNC = ${r.serialfunc}`);
|
|
212
|
+
if (str(r.deserialfunc))
|
|
213
|
+
opts.push(`DESERIALFUNC = ${r.deserialfunc}`);
|
|
214
|
+
if (str(r.initcond) !== undefined)
|
|
215
|
+
opts.push(`INITCOND = ${literal(String(r.initcond))}`);
|
|
216
|
+
if (str(r.msfunc)) {
|
|
217
|
+
opts.push(`MSFUNC = ${r.msfunc}`);
|
|
218
|
+
if (str(r.minvfunc))
|
|
219
|
+
opts.push(`MINVFUNC = ${r.minvfunc}`);
|
|
220
|
+
if (str(r.mstype))
|
|
221
|
+
opts.push(`MSTYPE = ${r.mstype}`);
|
|
222
|
+
if (Number(r.msspace) !== 0)
|
|
223
|
+
opts.push(`MSSPACE = ${Number(r.msspace)}`);
|
|
224
|
+
if (str(r.mfinalfunc))
|
|
225
|
+
opts.push(`MFINALFUNC = ${r.mfinalfunc}`);
|
|
226
|
+
if (r.mfinalextra === true)
|
|
227
|
+
opts.push("MFINALFUNC_EXTRA");
|
|
228
|
+
if (str(r.mfinalmodify) && r.mfinalmodify !== modifyDefault)
|
|
229
|
+
opts.push(`MFINALFUNC_MODIFY = ${MODIFY[String(r.mfinalmodify)]}`);
|
|
230
|
+
if (str(r.minitcond) !== undefined)
|
|
231
|
+
opts.push(`MINITCOND = ${literal(String(r.minitcond))}`);
|
|
232
|
+
}
|
|
233
|
+
if (str(r.sortop))
|
|
234
|
+
opts.push(`SORTOP = ${r.sortop}`);
|
|
235
|
+
if (r.parallel === "s")
|
|
236
|
+
opts.push("PARALLEL = SAFE");
|
|
237
|
+
else if (r.parallel === "r")
|
|
238
|
+
opts.push("PARALLEL = RESTRICTED");
|
|
239
|
+
if (kind === "h")
|
|
240
|
+
opts.push("HYPOTHETICAL");
|
|
241
|
+
const q = qname(String(r.schema), String(r.name));
|
|
242
|
+
out.push({
|
|
243
|
+
type: POSTGRES_ENTITY_TYPES.aggregate,
|
|
244
|
+
schema: String(r.schema),
|
|
245
|
+
name: String(r.name),
|
|
246
|
+
oid: String(r.oid),
|
|
247
|
+
signature,
|
|
248
|
+
...withComment(r),
|
|
249
|
+
...dependents(r),
|
|
250
|
+
statement: [`CREATE AGGREGATE ${q}(${args}) (${opts.join(", ")})`, ...commentOn(`AGGREGATE ${q}(${args})`, r.comment)].join(";\n"),
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
// Casts the database defines: the server's own have oids below the first normal object id. In scope when a type or the function is.
|
|
254
|
+
const scoped = (column) => scope.schemas
|
|
255
|
+
? `(SELECT xn.nspname FROM pg_catalog.pg_type x JOIN pg_catalog.pg_namespace xn ON xn.oid = x.typnamespace WHERE x.oid = ${column}) = ANY($1::text[])`
|
|
256
|
+
: "true";
|
|
257
|
+
const casts = await client.query(`SELECT c.oid::text AS oid, pg_catalog.format_type(c.castsource, NULL) AS source, pg_catalog.format_type(c.casttarget, NULL) AS target,
|
|
258
|
+
c.castmethod::text AS method, c.castcontext::text AS context,
|
|
259
|
+
CASE WHEN c.castfunc <> 0 THEN c.castfunc::pg_catalog.regprocedure::text END AS func,
|
|
260
|
+
pg_catalog.obj_description(c.oid, 'pg_cast') AS comment, ${dependentsOf("pg_cast", "c.oid")} AS dependents
|
|
261
|
+
FROM pg_catalog.pg_cast c
|
|
262
|
+
WHERE c.oid >= 16384 AND ${notExtensionOwned("pg_cast", "c.oid")} AND ${notInternal("pg_cast", "c.oid")}
|
|
263
|
+
AND (${scoped("c.castsource")} OR ${scoped("c.casttarget")}
|
|
264
|
+
OR ${scope.schemas ? `(SELECT pn.nspname FROM pg_catalog.pg_proc pp JOIN pg_catalog.pg_namespace pn ON pn.oid = pp.pronamespace WHERE pp.oid = c.castfunc) = ANY($1::text[])` : "true"})
|
|
265
|
+
ORDER BY pg_catalog.format_type(c.castsource, NULL) ${C}, pg_catalog.format_type(c.casttarget, NULL) ${C}`, scope.schemas ? [[...scope.schemas]] : []);
|
|
266
|
+
for (const r of casts) {
|
|
267
|
+
const name = `(${r.source} AS ${r.target})`;
|
|
268
|
+
const how = r.method === "b" ? "WITHOUT FUNCTION" : r.method === "i" ? "WITH INOUT" : `WITH FUNCTION ${r.func}`;
|
|
269
|
+
const context = r.context === "a" ? " AS ASSIGNMENT" : r.context === "i" ? " AS IMPLICIT" : "";
|
|
270
|
+
out.push({
|
|
271
|
+
type: POSTGRES_ENTITY_TYPES.cast,
|
|
272
|
+
name,
|
|
273
|
+
oid: String(r.oid),
|
|
274
|
+
...withComment(r),
|
|
275
|
+
...dependents(r),
|
|
276
|
+
statement: [`CREATE CAST ${name} ${how}${context}`, ...commentOn(`CAST ${name}`, r.comment)].join(";\n"),
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
// Event triggers: the database's, in scope when their function is.
|
|
280
|
+
const fs = scopeSql("fn.nspname", scope);
|
|
281
|
+
const events = await client.query(`SELECT e.oid::text AS oid, e.evtname AS name, e.evtevent AS event, ${proc("e.evtfoid::pg_catalog.regproc")} AS func, e.evttags AS tags,
|
|
282
|
+
pg_catalog.obj_description(e.oid, 'pg_event_trigger') AS comment
|
|
283
|
+
FROM pg_catalog.pg_event_trigger e JOIN pg_catalog.pg_proc f ON f.oid = e.evtfoid JOIN pg_catalog.pg_namespace fn ON fn.oid = f.pronamespace
|
|
284
|
+
WHERE ${fs.sql} AND ${notExtensionOwned("pg_event_trigger", "e.oid")}
|
|
285
|
+
ORDER BY e.evtname ${C}`, fs.params);
|
|
286
|
+
for (const r of events) {
|
|
287
|
+
const name = quoteIdent(String(r.name));
|
|
288
|
+
const tags = r.tags ?? [];
|
|
289
|
+
out.push({
|
|
290
|
+
type: POSTGRES_ENTITY_TYPES.eventTrigger,
|
|
291
|
+
name: String(r.name),
|
|
292
|
+
oid: String(r.oid),
|
|
293
|
+
...withComment(r),
|
|
294
|
+
statement: [
|
|
295
|
+
`CREATE EVENT TRIGGER ${name} ON ${quoteIdent(String(r.event))}${tags.length > 0 ? ` WHEN TAG IN (${tags.map(literal).join(", ")})` : ""} EXECUTE FUNCTION ${r.func}()`,
|
|
296
|
+
...commentOn(`EVENT TRIGGER ${name}`, r.comment),
|
|
297
|
+
].join(";\n"),
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
return out;
|
|
301
|
+
}
|