@intentius/chant-lexicon-sql 0.0.0-stage → 0.112.1
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 +39 -2
- package/dist/clickhouse/apply/apply.d.ts +82 -0
- package/dist/clickhouse/apply/apply.d.ts.map +1 -0
- package/dist/clickhouse/apply/mutations.d.ts +46 -0
- package/dist/clickhouse/apply/mutations.d.ts.map +1 -0
- package/dist/clickhouse/apply/statements.d.ts +99 -0
- package/dist/clickhouse/apply/statements.d.ts.map +1 -0
- package/dist/clickhouse/catalog-types.d.ts +76 -0
- package/dist/clickhouse/catalog-types.d.ts.map +1 -0
- package/dist/clickhouse/container.d.ts +63 -0
- package/dist/clickhouse/container.d.ts.map +1 -0
- package/dist/clickhouse/engine-syntax.d.ts +43 -0
- package/dist/clickhouse/engine-syntax.d.ts.map +1 -0
- package/dist/clickhouse/entities.d.ts +183 -0
- package/dist/clickhouse/entities.d.ts.map +1 -0
- package/dist/clickhouse/http.d.ts +40 -0
- package/dist/clickhouse/http.d.ts.map +1 -0
- package/dist/clickhouse/import/generator.d.ts +16 -0
- package/dist/clickhouse/import/generator.d.ts.map +1 -0
- package/dist/clickhouse/import/ir.d.ts +52 -0
- package/dist/clickhouse/import/ir.d.ts.map +1 -0
- package/dist/clickhouse/import/live-export.d.ts +28 -0
- package/dist/clickhouse/import/live-export.d.ts.map +1 -0
- package/dist/clickhouse/import/parser.d.ts +10 -0
- package/dist/clickhouse/import/parser.d.ts.map +1 -0
- package/dist/clickhouse/live/bind.d.ts +56 -0
- package/dist/clickhouse/live/bind.d.ts.map +1 -0
- package/dist/clickhouse/live/catalog.d.ts +39 -0
- package/dist/clickhouse/live/catalog.d.ts.map +1 -0
- package/dist/clickhouse/live/describe-resources.d.ts +34 -0
- package/dist/clickhouse/live/describe-resources.d.ts.map +1 -0
- package/dist/clickhouse/overlays/codecs.d.ts +28 -0
- package/dist/clickhouse/overlays/codecs.d.ts.map +1 -0
- package/dist/clickhouse/overlays/engines.d.ts +20 -0
- package/dist/clickhouse/overlays/engines.d.ts.map +1 -0
- package/dist/clickhouse/overlays/kinds.d.ts +38 -0
- package/dist/clickhouse/overlays/kinds.d.ts.map +1 -0
- package/dist/clickhouse/overlays/projections.d.ts +27 -0
- package/dist/clickhouse/overlays/projections.d.ts.map +1 -0
- package/dist/clickhouse/overlays/skip-indexes.d.ts +10 -0
- package/dist/clickhouse/overlays/skip-indexes.d.ts.map +1 -0
- package/dist/clickhouse/overlays/ttl.d.ts +35 -0
- package/dist/clickhouse/overlays/ttl.d.ts.map +1 -0
- package/dist/clickhouse/overlays/types.d.ts +21 -0
- package/dist/clickhouse/overlays/types.d.ts.map +1 -0
- package/dist/clickhouse/ownership.d.ts +71 -0
- package/dist/clickhouse/ownership.d.ts.map +1 -0
- package/dist/clickhouse/parser.d.ts +130 -0
- package/dist/clickhouse/parser.d.ts.map +1 -0
- package/dist/clickhouse/plan/commands.d.ts +26 -0
- package/dist/clickhouse/plan/commands.d.ts.map +1 -0
- package/dist/clickhouse/plan/deep.d.ts +32 -0
- package/dist/clickhouse/plan/deep.d.ts.map +1 -0
- package/dist/clickhouse/plan/diff.d.ts +37 -0
- package/dist/clickhouse/plan/diff.d.ts.map +1 -0
- package/dist/clickhouse/plan/disruption.d.ts +17 -0
- package/dist/clickhouse/plan/disruption.d.ts.map +1 -0
- package/dist/clickhouse/plan/normalize.d.ts +97 -0
- package/dist/clickhouse/plan/normalize.d.ts.map +1 -0
- package/dist/clickhouse/plan/rebuild-handoff.d.ts +38 -0
- package/dist/clickhouse/plan/rebuild-handoff.d.ts.map +1 -0
- package/dist/clickhouse/plan/report.d.ts +6 -0
- package/dist/clickhouse/plan/report.d.ts.map +1 -0
- package/dist/clickhouse/plan/rules.d.ts +60 -0
- package/dist/clickhouse/plan/rules.d.ts.map +1 -0
- package/dist/clickhouse/plan/schema.d.ts +23 -0
- package/dist/clickhouse/plan/schema.d.ts.map +1 -0
- package/dist/clickhouse/plan/server-format.d.ts +12 -0
- package/dist/clickhouse/plan/server-format.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/backfill.d.ts +70 -0
- package/dist/clickhouse/rebuild/backfill.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/observe.d.ts +157 -0
- package/dist/clickhouse/rebuild/observe.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/op.d.ts +108 -0
- package/dist/clickhouse/rebuild/op.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/partitions.d.ts +24 -0
- package/dist/clickhouse/rebuild/partitions.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/receipts.d.ts +76 -0
- package/dist/clickhouse/rebuild/receipts.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/replicas.d.ts +78 -0
- package/dist/clickhouse/rebuild/replicas.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/steps.d.ts +151 -0
- package/dist/clickhouse/rebuild/steps.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/verify.d.ts +51 -0
- package/dist/clickhouse/rebuild/verify.d.ts.map +1 -0
- package/dist/clickhouse/testing/fake-server.d.ts +27 -0
- package/dist/clickhouse/testing/fake-server.d.ts.map +1 -0
- package/dist/clickhouse/testing/roundtrip-schema.d.ts +3 -0
- package/dist/clickhouse/testing/roundtrip-schema.d.ts.map +1 -0
- package/dist/clickhouse/testing/writable-server.d.ts +35 -0
- package/dist/clickhouse/testing/writable-server.d.ts.map +1 -0
- package/dist/clickhouse/tokens.d.ts +15 -0
- package/dist/clickhouse/tokens.d.ts.map +1 -0
- package/dist/clickhouse.d.ts +24 -0
- package/dist/clickhouse.d.ts.map +1 -0
- package/dist/codegen/classifier-page.d.ts +6 -0
- package/dist/codegen/classifier-page.d.ts.map +1 -0
- package/dist/codegen/clickhouse-module.d.ts +23 -0
- package/dist/codegen/clickhouse-module.d.ts.map +1 -0
- package/dist/codegen/docs-cli.d.ts +3 -0
- package/dist/codegen/docs-cli.d.ts.map +1 -0
- package/dist/codegen/docs.d.ts +8 -0
- package/dist/codegen/docs.d.ts.map +1 -0
- package/dist/codegen/generate-cli.d.ts +3 -0
- package/dist/codegen/generate-cli.d.ts.map +1 -0
- package/dist/codegen/generate.d.ts +40 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/codegen/package.d.ts +7 -0
- package/dist/codegen/package.d.ts.map +1 -0
- package/dist/codegen/postgres-classifier-page.d.ts +7 -0
- package/dist/codegen/postgres-classifier-page.d.ts.map +1 -0
- package/dist/codegen/postgres-module.d.ts +30 -0
- package/dist/codegen/postgres-module.d.ts.map +1 -0
- package/dist/codegen/registry.d.ts +12 -0
- package/dist/codegen/registry.d.ts.map +1 -0
- package/dist/composites/audit-log-table.d.ts +31 -0
- package/dist/composites/audit-log-table.d.ts.map +1 -0
- package/dist/composites/catalog.d.ts +3 -0
- package/dist/composites/catalog.d.ts.map +1 -0
- package/dist/composites/cdc-mirror.d.ts +32 -0
- package/dist/composites/cdc-mirror.d.ts.map +1 -0
- package/dist/composites/clickhouse.d.ts +7 -0
- package/dist/composites/clickhouse.d.ts.map +1 -0
- package/dist/composites/events-table.d.ts +32 -0
- package/dist/composites/events-table.d.ts.map +1 -0
- package/dist/composites/index.d.ts +9 -0
- package/dist/composites/index.d.ts.map +1 -0
- package/dist/composites/join-table.d.ts +41 -0
- package/dist/composites/join-table.d.ts.map +1 -0
- package/dist/composites/postgres.d.ts +7 -0
- package/dist/composites/postgres.d.ts.map +1 -0
- package/dist/composites/refreshed-view.d.ts +32 -0
- package/dist/composites/refreshed-view.d.ts.map +1 -0
- package/dist/composites/replacing-table.d.ts +34 -0
- package/dist/composites/replacing-table.d.ts.map +1 -0
- package/dist/composites/rollup-view.d.ts +39 -0
- package/dist/composites/rollup-view.d.ts.map +1 -0
- package/dist/composites/sharded-table.d.ts +35 -0
- package/dist/composites/sharded-table.d.ts.map +1 -0
- package/dist/composites/soft-delete-table.d.ts +40 -0
- package/dist/composites/soft-delete-table.d.ts.map +1 -0
- package/dist/composites/tenant-table.d.ts +34 -0
- package/dist/composites/tenant-table.d.ts.map +1 -0
- package/dist/config.d.ts +213 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/core/apply.d.ts +89 -0
- package/dist/core/apply.d.ts.map +1 -0
- package/dist/core/classifier.d.ts +88 -0
- package/dist/core/classifier.d.ts.map +1 -0
- package/dist/core/container.d.ts +45 -0
- package/dist/core/container.d.ts.map +1 -0
- package/dist/core/cursor.d.ts +67 -0
- package/dist/core/cursor.d.ts.map +1 -0
- package/dist/core/diff.d.ts +49 -0
- package/dist/core/diff.d.ts.map +1 -0
- package/dist/core/entity.d.ts +41 -0
- package/dist/core/entity.d.ts.map +1 -0
- package/dist/core/find-templates.d.ts +69 -0
- package/dist/core/find-templates.d.ts.map +1 -0
- package/dist/core/handoff.d.ts +36 -0
- package/dist/core/handoff.d.ts.map +1 -0
- package/dist/core/index.d.ts +61 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/interpolation.d.ts +88 -0
- package/dist/core/interpolation.d.ts.map +1 -0
- package/dist/core/normalize.d.ts +18 -0
- package/dist/core/normalize.d.ts.map +1 -0
- package/dist/core/ownership.d.ts +60 -0
- package/dist/core/ownership.d.ts.map +1 -0
- package/dist/core/receipts.d.ts +28 -0
- package/dist/core/receipts.d.ts.map +1 -0
- package/dist/core/references.d.ts +37 -0
- package/dist/core/references.d.ts.map +1 -0
- package/dist/core/template.d.ts +41 -0
- package/dist/core/template.d.ts.map +1 -0
- package/dist/core/testing/http-stub.d.ts +17 -0
- package/dist/core/testing/http-stub.d.ts.map +1 -0
- package/dist/core/tokens.d.ts +102 -0
- package/dist/core/tokens.d.ts.map +1 -0
- package/dist/coverage.d.ts +25 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/detect.d.ts +15 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/dialects.d.ts +20 -0
- package/dist/dialects.d.ts.map +1 -0
- package/dist/generated/clickhouse-types.d.ts +4380 -0
- package/dist/generated/clickhouse-types.d.ts.map +1 -0
- package/dist/generated/clickhouse.d.ts +11 -0
- package/dist/generated/clickhouse.d.ts.map +1 -0
- package/dist/generated/postgres-types.d.ts +1579 -0
- package/dist/generated/postgres-types.d.ts.map +1 -0
- package/dist/generated/postgres.d.ts +9 -0
- package/dist/generated/postgres.d.ts.map +1 -0
- package/dist/import-generator.d.ts +8 -0
- package/dist/import-generator.d.ts.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/init-templates.d.ts +20 -0
- package/dist/init-templates.d.ts.map +1 -0
- package/dist/integrity.json +61 -0
- package/dist/lint/audit-catalog.d.ts +10 -0
- package/dist/lint/audit-catalog.d.ts.map +1 -0
- package/dist/lint/audit-lineage.d.ts +25 -0
- package/dist/lint/audit-lineage.d.ts.map +1 -0
- package/dist/lint/post-synth/audit-entries.d.ts +8 -0
- package/dist/lint/post-synth/audit-entries.d.ts.map +1 -0
- package/dist/lint/post-synth/clickhouse-helpers.d.ts +85 -0
- package/dist/lint/post-synth/clickhouse-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/index.d.ts +3 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -0
- package/dist/lint/post-synth/postgres-audit-entries.d.ts +9 -0
- package/dist/lint/post-synth/postgres-audit-entries.d.ts.map +1 -0
- package/dist/lint/post-synth/postgres-helpers.d.ts +89 -0
- package/dist/lint/post-synth/postgres-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/sql-helpers.d.ts +27 -0
- package/dist/lint/post-synth/sql-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch101.d.ts +12 -0
- package/dist/lint/post-synth/sqlch101.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch102.d.ts +9 -0
- package/dist/lint/post-synth/sqlch102.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch103.d.ts +10 -0
- package/dist/lint/post-synth/sqlch103.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch104.d.ts +9 -0
- package/dist/lint/post-synth/sqlch104.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch105.d.ts +10 -0
- package/dist/lint/post-synth/sqlch105.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch106.d.ts +11 -0
- package/dist/lint/post-synth/sqlch106.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch107.d.ts +10 -0
- package/dist/lint/post-synth/sqlch107.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch108.d.ts +11 -0
- package/dist/lint/post-synth/sqlch108.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch109.d.ts +10 -0
- package/dist/lint/post-synth/sqlch109.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch110.d.ts +12 -0
- package/dist/lint/post-synth/sqlch110.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch111.d.ts +11 -0
- package/dist/lint/post-synth/sqlch111.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch112.d.ts +12 -0
- package/dist/lint/post-synth/sqlch112.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch113.d.ts +9 -0
- package/dist/lint/post-synth/sqlch113.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch114.d.ts +8 -0
- package/dist/lint/post-synth/sqlch114.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch115.d.ts +13 -0
- package/dist/lint/post-synth/sqlch115.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch116.d.ts +10 -0
- package/dist/lint/post-synth/sqlch116.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch117.d.ts +9 -0
- package/dist/lint/post-synth/sqlch117.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch118.d.ts +10 -0
- package/dist/lint/post-synth/sqlch118.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch119.d.ts +11 -0
- package/dist/lint/post-synth/sqlch119.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch120.d.ts +10 -0
- package/dist/lint/post-synth/sqlch120.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg101.d.ts +12 -0
- package/dist/lint/post-synth/sqlpg101.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg102.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg102.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg103.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg103.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg104.d.ts +10 -0
- package/dist/lint/post-synth/sqlpg104.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg105.d.ts +10 -0
- package/dist/lint/post-synth/sqlpg105.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg106.d.ts +9 -0
- package/dist/lint/post-synth/sqlpg106.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg107.d.ts +10 -0
- package/dist/lint/post-synth/sqlpg107.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg108.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg108.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg109.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg109.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg110.d.ts +12 -0
- package/dist/lint/post-synth/sqlpg110.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg111.d.ts +10 -0
- package/dist/lint/post-synth/sqlpg111.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg112.d.ts +10 -0
- package/dist/lint/post-synth/sqlpg112.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg113.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg113.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg114.d.ts +13 -0
- package/dist/lint/post-synth/sqlpg114.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg115.d.ts +13 -0
- package/dist/lint/post-synth/sqlpg115.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg116.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg116.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg117.d.ts +12 -0
- package/dist/lint/post-synth/sqlpg117.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg118.d.ts +12 -0
- package/dist/lint/post-synth/sqlpg118.d.ts.map +1 -0
- package/dist/lint/rules/index.d.ts +12 -0
- package/dist/lint/rules/index.d.ts.map +1 -0
- package/dist/lint/rules/postgres-templates.d.ts +18 -0
- package/dist/lint/rules/postgres-templates.d.ts.map +1 -0
- package/dist/lint/rules/sqlch001.d.ts +12 -0
- package/dist/lint/rules/sqlch001.d.ts.map +1 -0
- package/dist/lint/rules/sqlch002.d.ts +11 -0
- package/dist/lint/rules/sqlch002.d.ts.map +1 -0
- package/dist/lint/rules/sqlch003.d.ts +12 -0
- package/dist/lint/rules/sqlch003.d.ts.map +1 -0
- package/dist/lint/rules/sqlpg001.d.ts +16 -0
- package/dist/lint/rules/sqlpg001.d.ts.map +1 -0
- package/dist/lint/rules/sqlpg002.d.ts +12 -0
- package/dist/lint/rules/sqlpg002.d.ts.map +1 -0
- package/dist/lint/rules/sqlpg003.d.ts +16 -0
- package/dist/lint/rules/sqlpg003.d.ts.map +1 -0
- package/dist/lint/rules/sqlpg004.d.ts +21 -0
- package/dist/lint/rules/sqlpg004.d.ts.map +1 -0
- package/dist/lint/rules/templates.d.ts +23 -0
- package/dist/lint/rules/templates.d.ts.map +1 -0
- package/dist/live-dialect.d.ts +25 -0
- package/dist/live-dialect.d.ts.map +1 -0
- package/dist/lsp/catalog.d.ts +22 -0
- package/dist/lsp/catalog.d.ts.map +1 -0
- package/dist/lsp/completions.d.ts +13 -0
- package/dist/lsp/completions.d.ts.map +1 -0
- package/dist/lsp/hover.d.ts +12 -0
- package/dist/lsp/hover.d.ts.map +1 -0
- package/dist/lsp/postgres-catalog.d.ts +85 -0
- package/dist/lsp/postgres-catalog.d.ts.map +1 -0
- package/dist/lsp/postgres-template.d.ts +35 -0
- package/dist/lsp/postgres-template.d.ts.map +1 -0
- package/dist/lsp/postgres.d.ts +20 -0
- package/dist/lsp/postgres.d.ts.map +1 -0
- package/dist/lsp/refs.d.ts +8 -0
- package/dist/lsp/refs.d.ts.map +1 -0
- package/dist/lsp/registry.d.ts +4 -0
- package/dist/lsp/registry.d.ts.map +1 -0
- package/dist/lsp/template.d.ts +34 -0
- package/dist/lsp/template.d.ts.map +1 -0
- package/dist/manifest.json +8 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/postgres.d.ts +32 -0
- package/dist/mcp/postgres.d.ts.map +1 -0
- package/dist/meta.json +67 -0
- package/dist/okf/index.md +67 -0
- package/dist/okf/rules/SQLCH001.md +11 -0
- package/dist/okf/rules/SQLCH002.md +11 -0
- package/dist/okf/rules/SQLCH003.md +11 -0
- package/dist/okf/rules/SQLCH101.md +15 -0
- package/dist/okf/rules/SQLCH102.md +11 -0
- package/dist/okf/rules/SQLCH103.md +11 -0
- package/dist/okf/rules/SQLCH104.md +11 -0
- package/dist/okf/rules/SQLCH105.md +11 -0
- package/dist/okf/rules/SQLCH106.md +11 -0
- package/dist/okf/rules/SQLCH107.md +11 -0
- package/dist/okf/rules/SQLCH108.md +15 -0
- package/dist/okf/rules/SQLCH109.md +11 -0
- package/dist/okf/rules/SQLCH110.md +11 -0
- package/dist/okf/rules/SQLCH111.md +11 -0
- package/dist/okf/rules/SQLCH112.md +11 -0
- package/dist/okf/rules/SQLCH113.md +11 -0
- package/dist/okf/rules/SQLCH114.md +11 -0
- package/dist/okf/rules/SQLCH115.md +11 -0
- package/dist/okf/rules/SQLCH116.md +11 -0
- package/dist/okf/rules/SQLCH117.md +15 -0
- package/dist/okf/rules/SQLCH118.md +15 -0
- package/dist/okf/rules/SQLCH119.md +15 -0
- package/dist/okf/rules/SQLCH120.md +15 -0
- package/dist/okf/rules/SQLPG001.md +11 -0
- package/dist/okf/rules/SQLPG002.md +11 -0
- package/dist/okf/rules/SQLPG003.md +11 -0
- package/dist/okf/rules/SQLPG004.md +11 -0
- package/dist/okf/rules/SQLPG101.md +11 -0
- package/dist/okf/rules/SQLPG102.md +11 -0
- package/dist/okf/rules/SQLPG103.md +11 -0
- package/dist/okf/rules/SQLPG104.md +11 -0
- package/dist/okf/rules/SQLPG105.md +11 -0
- package/dist/okf/rules/SQLPG106.md +11 -0
- package/dist/okf/rules/SQLPG107.md +11 -0
- package/dist/okf/rules/SQLPG108.md +11 -0
- package/dist/okf/rules/SQLPG109.md +11 -0
- package/dist/okf/rules/SQLPG110.md +11 -0
- package/dist/okf/rules/SQLPG111.md +11 -0
- package/dist/okf/rules/SQLPG112.md +11 -0
- package/dist/okf/rules/SQLPG113.md +24 -0
- package/dist/okf/rules/SQLPG114.md +11 -0
- package/dist/okf/rules/SQLPG115.md +11 -0
- package/dist/okf/rules/SQLPG116.md +15 -0
- package/dist/okf/rules/SQLPG117.md +11 -0
- package/dist/okf/rules/SQLPG118.md +11 -0
- package/dist/okf/types/Database.md +15 -0
- package/dist/okf/types/MaterializedView.md +14 -0
- package/dist/okf/types/PostgresDomain.md +13 -0
- package/dist/okf/types/PostgresEnum.md +13 -0
- package/dist/okf/types/PostgresExtension.md +13 -0
- package/dist/okf/types/PostgresIndex.md +9 -0
- package/dist/okf/types/PostgresMaterializedView.md +13 -0
- package/dist/okf/types/PostgresSchema.md +13 -0
- package/dist/okf/types/PostgresSequence.md +13 -0
- package/dist/okf/types/PostgresTable.md +13 -0
- package/dist/okf/types/PostgresView.md +13 -0
- package/dist/okf/types/Table.md +15 -0
- package/dist/okf/types/View.md +13 -0
- package/dist/op/activities/clickhouse-apply.d.ts +56 -0
- package/dist/op/activities/clickhouse-apply.d.ts.map +1 -0
- package/dist/op/activities/clickhouse-emulator.d.ts +26 -0
- package/dist/op/activities/clickhouse-emulator.d.ts.map +1 -0
- package/dist/op/activities/clickhouse-rebuild.d.ts +43 -0
- package/dist/op/activities/clickhouse-rebuild.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +19 -0
- package/dist/op/activities/index.d.ts.map +1 -0
- package/dist/op/activities/postgres-apply.d.ts +69 -0
- package/dist/op/activities/postgres-apply.d.ts.map +1 -0
- package/dist/op/activities/postgres-emulator.d.ts +33 -0
- package/dist/op/activities/postgres-emulator.d.ts.map +1 -0
- package/dist/op/activities/postgres-migration.d.ts +48 -0
- package/dist/op/activities/postgres-migration.d.ts.map +1 -0
- package/dist/op/activity-contracts.d.ts +464 -0
- package/dist/op/activity-contracts.d.ts.map +1 -0
- package/dist/package-cli.d.ts +3 -0
- package/dist/package-cli.d.ts.map +1 -0
- package/dist/plugin.d.ts +12 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/postgres/apply/apply.d.ts +163 -0
- package/dist/postgres/apply/apply.d.ts.map +1 -0
- package/dist/postgres/apply/statements.d.ts +138 -0
- package/dist/postgres/apply/statements.d.ts.map +1 -0
- package/dist/postgres/catalog-types.d.ts +50 -0
- package/dist/postgres/catalog-types.d.ts.map +1 -0
- package/dist/postgres/container.d.ts +23 -0
- package/dist/postgres/container.d.ts.map +1 -0
- package/dist/postgres/entities.d.ts +322 -0
- package/dist/postgres/entities.d.ts.map +1 -0
- package/dist/postgres/entity-types.d.ts +17 -0
- package/dist/postgres/entity-types.d.ts.map +1 -0
- package/dist/postgres/import/generator.d.ts +28 -0
- package/dist/postgres/import/generator.d.ts.map +1 -0
- package/dist/postgres/import/ir.d.ts +24 -0
- package/dist/postgres/import/ir.d.ts.map +1 -0
- package/dist/postgres/import/live-export.d.ts +26 -0
- package/dist/postgres/import/live-export.d.ts.map +1 -0
- package/dist/postgres/keywords.d.ts +22 -0
- package/dist/postgres/keywords.d.ts.map +1 -0
- package/dist/postgres/live/bind.d.ts +76 -0
- package/dist/postgres/live/bind.d.ts.map +1 -0
- package/dist/postgres/live/catalog.d.ts +98 -0
- package/dist/postgres/live/catalog.d.ts.map +1 -0
- package/dist/postgres/live/client.d.ts +32 -0
- package/dist/postgres/live/client.d.ts.map +1 -0
- package/dist/postgres/live/describe-resources.d.ts +41 -0
- package/dist/postgres/live/describe-resources.d.ts.map +1 -0
- package/dist/postgres/migrate/backfill.d.ts +103 -0
- package/dist/postgres/migrate/backfill.d.ts.map +1 -0
- package/dist/postgres/migrate/batches.d.ts +90 -0
- package/dist/postgres/migrate/batches.d.ts.map +1 -0
- package/dist/postgres/migrate/carry.d.ts +196 -0
- package/dist/postgres/migrate/carry.d.ts.map +1 -0
- package/dist/postgres/migrate/handoff.d.ts +46 -0
- package/dist/postgres/migrate/handoff.d.ts.map +1 -0
- package/dist/postgres/migrate/names.d.ts +55 -0
- package/dist/postgres/migrate/names.d.ts.map +1 -0
- package/dist/postgres/migrate/observe.d.ts +139 -0
- package/dist/postgres/migrate/observe.d.ts.map +1 -0
- package/dist/postgres/migrate/op.d.ts +128 -0
- package/dist/postgres/migrate/op.d.ts.map +1 -0
- package/dist/postgres/migrate/receipts.d.ts +63 -0
- package/dist/postgres/migrate/receipts.d.ts.map +1 -0
- package/dist/postgres/migrate/replication.d.ts +80 -0
- package/dist/postgres/migrate/replication.d.ts.map +1 -0
- package/dist/postgres/migrate/steps.d.ts +225 -0
- package/dist/postgres/migrate/steps.d.ts.map +1 -0
- package/dist/postgres/overlays/columns.d.ts +6 -0
- package/dist/postgres/overlays/columns.d.ts.map +1 -0
- package/dist/postgres/overlays/constraints.d.ts +8 -0
- package/dist/postgres/overlays/constraints.d.ts.map +1 -0
- package/dist/postgres/overlays/indexes.d.ts +8 -0
- package/dist/postgres/overlays/indexes.d.ts.map +1 -0
- package/dist/postgres/overlays/kinds.d.ts +48 -0
- package/dist/postgres/overlays/kinds.d.ts.map +1 -0
- package/dist/postgres/overlays/partitioning.d.ts +5 -0
- package/dist/postgres/overlays/partitioning.d.ts.map +1 -0
- package/dist/postgres/overlays/relations.d.ts +6 -0
- package/dist/postgres/overlays/relations.d.ts.map +1 -0
- package/dist/postgres/overlays/storage.d.ts +28 -0
- package/dist/postgres/overlays/storage.d.ts.map +1 -0
- package/dist/postgres/overlays/type-ddl.d.ts +7 -0
- package/dist/postgres/overlays/type-ddl.d.ts.map +1 -0
- package/dist/postgres/overlays/types.d.ts +24 -0
- package/dist/postgres/overlays/types.d.ts.map +1 -0
- package/dist/postgres/parser.d.ts +216 -0
- package/dist/postgres/parser.d.ts.map +1 -0
- package/dist/postgres/plan/commands.d.ts +61 -0
- package/dist/postgres/plan/commands.d.ts.map +1 -0
- package/dist/postgres/plan/deep.d.ts +33 -0
- package/dist/postgres/plan/deep.d.ts.map +1 -0
- package/dist/postgres/plan/diff.d.ts +45 -0
- package/dist/postgres/plan/diff.d.ts.map +1 -0
- package/dist/postgres/plan/disruption.d.ts +14 -0
- package/dist/postgres/plan/disruption.d.ts.map +1 -0
- package/dist/postgres/plan/normalize.d.ts +108 -0
- package/dist/postgres/plan/normalize.d.ts.map +1 -0
- package/dist/postgres/plan/report.d.ts +6 -0
- package/dist/postgres/plan/report.d.ts.map +1 -0
- package/dist/postgres/plan/rules.d.ts +84 -0
- package/dist/postgres/plan/rules.d.ts.map +1 -0
- package/dist/postgres/plan/schema.d.ts +50 -0
- package/dist/postgres/plan/schema.d.ts.map +1 -0
- package/dist/postgres/plan/server-normalize.d.ts +26 -0
- package/dist/postgres/plan/server-normalize.d.ts.map +1 -0
- package/dist/postgres/providers/aurora.d.ts +12 -0
- package/dist/postgres/providers/aurora.d.ts.map +1 -0
- package/dist/postgres/providers/azure.d.ts +14 -0
- package/dist/postgres/providers/azure.d.ts.map +1 -0
- package/dist/postgres/providers/cloud-sql.d.ts +11 -0
- package/dist/postgres/providers/cloud-sql.d.ts.map +1 -0
- package/dist/postgres/providers/index.d.ts +35 -0
- package/dist/postgres/providers/index.d.ts.map +1 -0
- package/dist/postgres/providers/neon.d.ts +13 -0
- package/dist/postgres/providers/neon.d.ts.map +1 -0
- package/dist/postgres/providers/rds.d.ts +10 -0
- package/dist/postgres/providers/rds.d.ts.map +1 -0
- package/dist/postgres/providers/supabase.d.ts +12 -0
- package/dist/postgres/providers/supabase.d.ts.map +1 -0
- package/dist/postgres/providers/types.d.ts +59 -0
- package/dist/postgres/providers/types.d.ts.map +1 -0
- package/dist/postgres/testing/fake-client.d.ts +38 -0
- package/dist/postgres/testing/fake-client.d.ts.map +1 -0
- package/dist/postgres/testing/migration.d.ts +25 -0
- package/dist/postgres/testing/migration.d.ts.map +1 -0
- package/dist/postgres/testing/roundtrip-schema.d.ts +11 -0
- package/dist/postgres/testing/roundtrip-schema.d.ts.map +1 -0
- package/dist/postgres/testing/server.d.ts +17 -0
- package/dist/postgres/testing/server.d.ts.map +1 -0
- package/dist/postgres/testing/writable-server.d.ts +45 -0
- package/dist/postgres/testing/writable-server.d.ts.map +1 -0
- package/dist/postgres/tokens.d.ts +26 -0
- package/dist/postgres/tokens.d.ts.map +1 -0
- package/dist/postgres.d.ts +13 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/rules/audit-entries.ts +29 -0
- package/dist/rules/clickhouse-helpers.ts +206 -0
- package/dist/rules/postgres-audit-entries.ts +29 -0
- package/dist/rules/postgres-helpers.ts +126 -0
- package/dist/rules/postgres-templates.ts +36 -0
- package/dist/rules/sql-helpers.ts +53 -0
- package/dist/rules/sqlch001.ts +53 -0
- package/dist/rules/sqlch002.ts +115 -0
- package/dist/rules/sqlch003.ts +68 -0
- package/dist/rules/sqlch101.ts +35 -0
- package/dist/rules/sqlch102.ts +23 -0
- package/dist/rules/sqlch103.ts +45 -0
- package/dist/rules/sqlch104.ts +42 -0
- package/dist/rules/sqlch105.ts +35 -0
- package/dist/rules/sqlch106.ts +27 -0
- package/dist/rules/sqlch107.ts +35 -0
- package/dist/rules/sqlch108.ts +27 -0
- package/dist/rules/sqlch109.ts +21 -0
- package/dist/rules/sqlch110.ts +29 -0
- package/dist/rules/sqlch111.ts +40 -0
- package/dist/rules/sqlch112.ts +30 -0
- package/dist/rules/sqlch113.ts +20 -0
- package/dist/rules/sqlch114.ts +26 -0
- package/dist/rules/sqlch115.ts +31 -0
- package/dist/rules/sqlch116.ts +22 -0
- package/dist/rules/sqlch117.ts +25 -0
- package/dist/rules/sqlch118.ts +26 -0
- package/dist/rules/sqlch119.ts +31 -0
- package/dist/rules/sqlch120.ts +21 -0
- package/dist/rules/sqlpg001.ts +88 -0
- package/dist/rules/sqlpg002.ts +68 -0
- package/dist/rules/sqlpg003.ts +59 -0
- package/dist/rules/sqlpg004.ts +73 -0
- package/dist/rules/sqlpg101.ts +24 -0
- package/dist/rules/sqlpg102.ts +30 -0
- package/dist/rules/sqlpg103.ts +23 -0
- package/dist/rules/sqlpg104.ts +23 -0
- package/dist/rules/sqlpg105.ts +22 -0
- package/dist/rules/sqlpg106.ts +22 -0
- package/dist/rules/sqlpg107.ts +22 -0
- package/dist/rules/sqlpg108.ts +27 -0
- package/dist/rules/sqlpg109.ts +37 -0
- package/dist/rules/sqlpg110.ts +33 -0
- package/dist/rules/sqlpg111.ts +23 -0
- package/dist/rules/sqlpg112.ts +25 -0
- package/dist/rules/sqlpg113.ts +28 -0
- package/dist/rules/sqlpg114.ts +37 -0
- package/dist/rules/sqlpg115.ts +38 -0
- package/dist/rules/sqlpg116.ts +25 -0
- package/dist/rules/sqlpg117.ts +24 -0
- package/dist/rules/sqlpg118.ts +22 -0
- package/dist/rules/templates.ts +35 -0
- package/dist/serializer.d.ts +37 -0
- package/dist/serializer.d.ts.map +1 -0
- package/dist/skill-defs.d.ts +3 -0
- package/dist/skill-defs.d.ts.map +1 -0
- package/dist/spec/catalog.d.ts +125 -0
- package/dist/spec/catalog.d.ts.map +1 -0
- package/dist/spec/fetch.d.ts +43 -0
- package/dist/spec/fetch.d.ts.map +1 -0
- package/dist/spec/pin.d.ts +39 -0
- package/dist/spec/pin.d.ts.map +1 -0
- package/dist/spec/postgres-catalog.d.ts +108 -0
- package/dist/spec/postgres-catalog.d.ts.map +1 -0
- package/dist/spec/postgres-fetch.d.ts +46 -0
- package/dist/spec/postgres-fetch.d.ts.map +1 -0
- package/dist/spec/postgres-pin.d.ts +67 -0
- package/dist/spec/postgres-pin.d.ts.map +1 -0
- package/dist/types/index.d.ts +4386 -0
- package/dist/validate-cli.d.ts +3 -0
- package/dist/validate-cli.d.ts.map +1 -0
- package/dist/validate.d.ts +15 -0
- package/dist/validate.d.ts.map +1 -0
- package/package.json +74 -4
- package/src/clickhouse/apply/apply.ts +288 -0
- package/src/clickhouse/apply/mutations.ts +90 -0
- package/src/clickhouse/apply/statements.ts +393 -0
- package/src/clickhouse/catalog-types.ts +84 -0
- package/src/clickhouse/container.ts +176 -0
- package/src/clickhouse/engine-syntax.test.ts +53 -0
- package/src/clickhouse/engine-syntax.ts +173 -0
- package/src/clickhouse/entities.test.ts +188 -0
- package/src/clickhouse/entities.ts +425 -0
- package/src/clickhouse/http.ts +76 -0
- package/src/clickhouse/import/generator.ts +153 -0
- package/src/clickhouse/import/import.test.ts +157 -0
- package/src/clickhouse/import/ir.ts +171 -0
- package/src/clickhouse/import/live-export.ts +53 -0
- package/src/clickhouse/import/parser.ts +27 -0
- package/src/clickhouse/import/roundtrip.test.ts +90 -0
- package/src/clickhouse/live/bind.ts +126 -0
- package/src/clickhouse/live/catalog.ts +96 -0
- package/src/clickhouse/live/describe-resources.ts +98 -0
- package/src/clickhouse/live/live.test.ts +143 -0
- package/src/clickhouse/live/roundtrip.e2e.test.ts +93 -0
- package/src/clickhouse/overlays/codecs.ts +68 -0
- package/src/clickhouse/overlays/engines.ts +108 -0
- package/src/clickhouse/overlays/kinds.ts +38 -0
- package/src/clickhouse/overlays/projections.ts +36 -0
- package/src/clickhouse/overlays/skip-indexes.ts +44 -0
- package/src/clickhouse/overlays/ttl.ts +55 -0
- package/src/clickhouse/overlays/types.ts +58 -0
- package/src/clickhouse/ownership.test.ts +20 -0
- package/src/clickhouse/ownership.ts +103 -0
- package/src/clickhouse/parser.test.ts +166 -0
- package/src/clickhouse/parser.ts +459 -0
- package/src/clickhouse/plan/commands.ts +101 -0
- package/src/clickhouse/plan/deep.ts +124 -0
- package/src/clickhouse/plan/diff.ts +203 -0
- package/src/clickhouse/plan/disruption.ts +61 -0
- package/src/clickhouse/plan/normalize.ts +352 -0
- package/src/clickhouse/plan/plan-wiring.test.ts +77 -0
- package/src/clickhouse/plan/plan.e2e.test.ts +77 -0
- package/src/clickhouse/plan/plan.test.ts +201 -0
- package/src/clickhouse/plan/rebuild-handoff.ts +59 -0
- package/src/clickhouse/plan/report.ts +19 -0
- package/src/clickhouse/plan/rules.ts +241 -0
- package/src/clickhouse/plan/schema.ts +56 -0
- package/src/clickhouse/plan/server-format.ts +39 -0
- package/src/clickhouse/rebuild/backfill.ts +186 -0
- package/src/clickhouse/rebuild/observe.ts +380 -0
- package/src/clickhouse/rebuild/op.ts +206 -0
- package/src/clickhouse/rebuild/partitions.ts +62 -0
- package/src/clickhouse/rebuild/rebuild-replicated.e2e.test.ts +513 -0
- package/src/clickhouse/rebuild/rebuild.e2e.test.ts +351 -0
- package/src/clickhouse/rebuild/rebuild.test.ts +190 -0
- package/src/clickhouse/rebuild/receipts.ts +143 -0
- package/src/clickhouse/rebuild/replicas.test.ts +70 -0
- package/src/clickhouse/rebuild/replicas.ts +148 -0
- package/src/clickhouse/rebuild/steps.ts +382 -0
- package/src/clickhouse/rebuild/verify.ts +124 -0
- package/src/clickhouse/testdata/NOTICE +5 -0
- package/src/clickhouse/testdata/clickhouse-tests-corpus.json +302 -0
- package/src/clickhouse/testing/fake-server.ts +65 -0
- package/src/clickhouse/testing/roundtrip-schema.ts +25 -0
- package/src/clickhouse/testing/writable-server.ts +141 -0
- package/src/clickhouse/tokens.ts +28 -0
- package/src/clickhouse.ts +63 -0
- package/src/codegen/classifier-page.test.ts +16 -0
- package/src/codegen/classifier-page.ts +76 -0
- package/src/codegen/clickhouse-module.test.ts +63 -0
- package/src/codegen/clickhouse-module.ts +269 -0
- package/src/codegen/docs-cli.ts +4 -0
- package/src/codegen/docs.ts +225 -0
- package/src/codegen/generate-cli.ts +13 -0
- package/src/codegen/generate.ts +126 -0
- package/src/codegen/package.ts +36 -0
- package/src/codegen/postgres-classifier-page.ts +81 -0
- package/src/codegen/postgres-module.test.ts +77 -0
- package/src/codegen/postgres-module.ts +434 -0
- package/src/codegen/registry.ts +36 -0
- package/src/composites/audit-log-table.ts +54 -0
- package/src/composites/catalog.test.ts +61 -0
- package/src/composites/catalog.ts +529 -0
- package/src/composites/cdc-mirror.ts +54 -0
- package/src/composites/clickhouse.ts +7 -0
- package/src/composites/composites.test.ts +758 -0
- package/src/composites/events-table.ts +49 -0
- package/src/composites/index.ts +9 -0
- package/src/composites/join-table.ts +57 -0
- package/src/composites/postgres.ts +7 -0
- package/src/composites/refreshed-view.ts +46 -0
- package/src/composites/replacing-table.ts +49 -0
- package/src/composites/rollup-view.ts +55 -0
- package/src/composites/sharded-table.ts +49 -0
- package/src/composites/soft-delete-table.ts +61 -0
- package/src/composites/tenant-table.ts +50 -0
- package/src/config.ts +157 -0
- package/src/core/apply.ts +153 -0
- package/src/core/classifier.ts +186 -0
- package/src/core/container.ts +93 -0
- package/src/core/core.test.ts +254 -0
- package/src/core/cursor.ts +189 -0
- package/src/core/diff.ts +72 -0
- package/src/core/entity.ts +85 -0
- package/src/core/find-templates.ts +158 -0
- package/src/core/handoff.ts +44 -0
- package/src/core/index.ts +61 -0
- package/src/core/interpolation.ts +225 -0
- package/src/core/normalize.ts +39 -0
- package/src/core/ownership.test.ts +36 -0
- package/src/core/ownership.ts +133 -0
- package/src/core/receipts.ts +29 -0
- package/src/core/references.ts +74 -0
- package/src/core/template.ts +83 -0
- package/src/core/testing/http-stub.ts +33 -0
- package/src/core/tokens.ts +252 -0
- package/src/coverage.ts +64 -0
- package/src/detect.ts +32 -0
- package/src/dialects.ts +21 -0
- package/src/generated/clickhouse-types.ts +4386 -0
- package/src/generated/clickhouse.ts +2476 -0
- package/src/generated/index.d.ts +4386 -0
- package/src/generated/lexicon-sql.json +67 -0
- package/src/generated/postgres-types.ts +1190 -0
- package/src/generated/postgres.ts +1039 -0
- package/src/import-generator.ts +18 -0
- package/src/index.ts +21 -0
- package/src/init-templates.test.ts +108 -0
- package/src/init-templates.ts +327 -0
- package/src/lint/audit-catalog.ts +73 -0
- package/src/lint/audit-lineage.ts +47 -0
- package/src/lint/post-synth/audit-entries.ts +29 -0
- package/src/lint/post-synth/clickhouse-checks.test.ts +278 -0
- package/src/lint/post-synth/clickhouse-helpers.ts +206 -0
- package/src/lint/post-synth/index.ts +81 -0
- package/src/lint/post-synth/post-synth.test.ts +33 -0
- package/src/lint/post-synth/postgres-audit-entries.ts +29 -0
- package/src/lint/post-synth/postgres-checks.test.ts +257 -0
- package/src/lint/post-synth/postgres-helpers.ts +126 -0
- package/src/lint/post-synth/sql-helpers.ts +53 -0
- package/src/lint/post-synth/sqlch101.ts +35 -0
- package/src/lint/post-synth/sqlch102.ts +23 -0
- package/src/lint/post-synth/sqlch103.ts +45 -0
- package/src/lint/post-synth/sqlch104.ts +42 -0
- package/src/lint/post-synth/sqlch105.ts +35 -0
- package/src/lint/post-synth/sqlch106.ts +27 -0
- package/src/lint/post-synth/sqlch107.ts +35 -0
- package/src/lint/post-synth/sqlch108.ts +27 -0
- package/src/lint/post-synth/sqlch109.ts +21 -0
- package/src/lint/post-synth/sqlch110.ts +29 -0
- package/src/lint/post-synth/sqlch111.ts +40 -0
- package/src/lint/post-synth/sqlch112.ts +30 -0
- package/src/lint/post-synth/sqlch113.ts +20 -0
- package/src/lint/post-synth/sqlch114.ts +26 -0
- package/src/lint/post-synth/sqlch115.ts +31 -0
- package/src/lint/post-synth/sqlch116.ts +22 -0
- package/src/lint/post-synth/sqlch117.ts +25 -0
- package/src/lint/post-synth/sqlch118.ts +26 -0
- package/src/lint/post-synth/sqlch119.ts +31 -0
- package/src/lint/post-synth/sqlch120.ts +21 -0
- package/src/lint/post-synth/sqlpg101.ts +24 -0
- package/src/lint/post-synth/sqlpg102.ts +30 -0
- package/src/lint/post-synth/sqlpg103.ts +23 -0
- package/src/lint/post-synth/sqlpg104.ts +23 -0
- package/src/lint/post-synth/sqlpg105.ts +22 -0
- package/src/lint/post-synth/sqlpg106.ts +22 -0
- package/src/lint/post-synth/sqlpg107.ts +22 -0
- package/src/lint/post-synth/sqlpg108.ts +27 -0
- package/src/lint/post-synth/sqlpg109.ts +37 -0
- package/src/lint/post-synth/sqlpg110.ts +33 -0
- package/src/lint/post-synth/sqlpg111.ts +23 -0
- package/src/lint/post-synth/sqlpg112.ts +25 -0
- package/src/lint/post-synth/sqlpg113.ts +28 -0
- package/src/lint/post-synth/sqlpg114.ts +37 -0
- package/src/lint/post-synth/sqlpg115.ts +38 -0
- package/src/lint/post-synth/sqlpg116.ts +25 -0
- package/src/lint/post-synth/sqlpg117.ts +24 -0
- package/src/lint/post-synth/sqlpg118.ts +22 -0
- package/src/lint/rules/index.ts +13 -0
- package/src/lint/rules/postgres-templates.ts +36 -0
- package/src/lint/rules/rules.test.ts +228 -0
- package/src/lint/rules/sqlch001.ts +53 -0
- package/src/lint/rules/sqlch002.ts +115 -0
- package/src/lint/rules/sqlch003.ts +68 -0
- package/src/lint/rules/sqlpg001.ts +88 -0
- package/src/lint/rules/sqlpg002.ts +68 -0
- package/src/lint/rules/sqlpg003.ts +59 -0
- package/src/lint/rules/sqlpg004.ts +73 -0
- package/src/lint/rules/templates.ts +35 -0
- package/src/live-dialect.ts +37 -0
- package/src/lsp/catalog.ts +60 -0
- package/src/lsp/completions.test.ts +111 -0
- package/src/lsp/completions.ts +128 -0
- package/src/lsp/diagnostics.test.ts +26 -0
- package/src/lsp/hover.test.ts +90 -0
- package/src/lsp/hover.ts +113 -0
- package/src/lsp/postgres-catalog.ts +234 -0
- package/src/lsp/postgres-template.ts +161 -0
- package/src/lsp/postgres.test.ts +150 -0
- package/src/lsp/postgres.ts +270 -0
- package/src/lsp/refs.ts +53 -0
- package/src/lsp/registry.ts +19 -0
- package/src/lsp/template.ts +166 -0
- package/src/mcp/index.ts +304 -0
- package/src/mcp/mcp.test.ts +184 -0
- package/src/mcp/postgres.ts +125 -0
- package/src/op/activities/clickhouse-apply.e2e.test.ts +150 -0
- package/src/op/activities/clickhouse-apply.test.ts +265 -0
- package/src/op/activities/clickhouse-apply.ts +113 -0
- package/src/op/activities/clickhouse-emulator.test.ts +23 -0
- package/src/op/activities/clickhouse-emulator.ts +37 -0
- package/src/op/activities/clickhouse-rebuild.ts +136 -0
- package/src/op/activities/index.ts +50 -0
- package/src/op/activities/postgres-apply.e2e.test.ts +184 -0
- package/src/op/activities/postgres-apply.test.ts +304 -0
- package/src/op/activities/postgres-apply.ts +170 -0
- package/src/op/activities/postgres-emulator.test.ts +26 -0
- package/src/op/activities/postgres-emulator.ts +44 -0
- package/src/op/activities/postgres-migration.ts +182 -0
- package/src/op/activity-contracts.ts +210 -0
- package/src/package-cli.ts +17 -0
- package/src/plugin.test.ts +74 -0
- package/src/plugin.ts +242 -0
- package/src/postgres/apply/apply.ts +582 -0
- package/src/postgres/apply/statements.test.ts +155 -0
- package/src/postgres/apply/statements.ts +603 -0
- package/src/postgres/catalog-types.ts +59 -0
- package/src/postgres/container.ts +72 -0
- package/src/postgres/entities.test.ts +170 -0
- package/src/postgres/entities.ts +1016 -0
- package/src/postgres/entity-types.ts +18 -0
- package/src/postgres/import/generator.ts +176 -0
- package/src/postgres/import/import.test.ts +71 -0
- package/src/postgres/import/ir.ts +67 -0
- package/src/postgres/import/live-export.ts +53 -0
- package/src/postgres/import/live-warnings.test.ts +45 -0
- package/src/postgres/keywords.ts +40 -0
- package/src/postgres/live/bind.ts +146 -0
- package/src/postgres/live/catalog.ts +581 -0
- package/src/postgres/live/client.ts +84 -0
- package/src/postgres/live/describe-resources.ts +111 -0
- package/src/postgres/live/live.test.ts +198 -0
- package/src/postgres/live/roundtrip.e2e.test.ts +111 -0
- package/src/postgres/migrate/backfill.ts +233 -0
- package/src/postgres/migrate/batches.e2e.test.ts +163 -0
- package/src/postgres/migrate/batches.test.ts +36 -0
- package/src/postgres/migrate/batches.ts +159 -0
- package/src/postgres/migrate/carry.e2e.test.ts +335 -0
- package/src/postgres/migrate/carry.test.ts +103 -0
- package/src/postgres/migrate/carry.ts +653 -0
- package/src/postgres/migrate/handoff.ts +73 -0
- package/src/postgres/migrate/kinds.e2e.test.ts +204 -0
- package/src/postgres/migrate/migrate.e2e.test.ts +362 -0
- package/src/postgres/migrate/migrate.test.ts +322 -0
- package/src/postgres/migrate/names.ts +93 -0
- package/src/postgres/migrate/observe.ts +521 -0
- package/src/postgres/migrate/op.ts +242 -0
- package/src/postgres/migrate/receipts.ts +135 -0
- package/src/postgres/migrate/replication.ts +151 -0
- package/src/postgres/migrate/steps.ts +657 -0
- package/src/postgres/overlays/columns.ts +34 -0
- package/src/postgres/overlays/constraints.ts +56 -0
- package/src/postgres/overlays/indexes.ts +27 -0
- package/src/postgres/overlays/kinds.ts +53 -0
- package/src/postgres/overlays/partitioning.ts +26 -0
- package/src/postgres/overlays/relations.ts +29 -0
- package/src/postgres/overlays/storage.ts +75 -0
- package/src/postgres/overlays/type-ddl.ts +38 -0
- package/src/postgres/overlays/types.ts +56 -0
- package/src/postgres/parser.test.ts +214 -0
- package/src/postgres/parser.ts +1062 -0
- package/src/postgres/plan/commands.ts +124 -0
- package/src/postgres/plan/deep.ts +177 -0
- package/src/postgres/plan/diff.ts +323 -0
- package/src/postgres/plan/disruption.ts +52 -0
- package/src/postgres/plan/normalize.test.ts +148 -0
- package/src/postgres/plan/normalize.ts +542 -0
- package/src/postgres/plan/plan.e2e.test.ts +117 -0
- package/src/postgres/plan/plan.test.ts +244 -0
- package/src/postgres/plan/report.ts +24 -0
- package/src/postgres/plan/rules.ts +276 -0
- package/src/postgres/plan/schema.ts +114 -0
- package/src/postgres/plan/server-normalize.ts +123 -0
- package/src/postgres/providers/aurora.ts +45 -0
- package/src/postgres/providers/azure.ts +54 -0
- package/src/postgres/providers/cloud-sql.ts +42 -0
- package/src/postgres/providers/index.ts +90 -0
- package/src/postgres/providers/neon.ts +45 -0
- package/src/postgres/providers/providers.test.ts +136 -0
- package/src/postgres/providers/rds.ts +48 -0
- package/src/postgres/providers/supabase.ts +46 -0
- package/src/postgres/providers/types.ts +70 -0
- package/src/postgres/testdata/NOTICE +31 -0
- package/src/postgres/testdata/postgres-regress-corpus.json +460 -0
- package/src/postgres/testing/fake-client.ts +42 -0
- package/src/postgres/testing/migration.ts +52 -0
- package/src/postgres/testing/roundtrip-schema.ts +46 -0
- package/src/postgres/testing/server.ts +58 -0
- package/src/postgres/testing/writable-server.ts +188 -0
- package/src/postgres/tokens.ts +46 -0
- package/src/postgres.ts +75 -0
- package/src/serializer.test.ts +128 -0
- package/src/serializer.ts +148 -0
- package/src/skill-defs.test.ts +81 -0
- package/src/skill-defs.ts +102 -0
- package/src/skills/chant-sql-plan.md +123 -0
- package/src/skills/chant-sql-postgres-migration.md +126 -0
- package/src/skills/chant-sql-postgres-plan.md +194 -0
- package/src/skills/chant-sql-postgres.md +165 -0
- package/src/skills/chant-sql-rebuild.md +68 -0
- package/src/skills/chant-sql.md +123 -0
- package/src/spec/catalog.e2e.test.ts +29 -0
- package/src/spec/catalog.test.ts +56 -0
- package/src/spec/catalog.ts +311 -0
- package/src/spec/clickhouse-catalog.snapshot.json +5246 -0
- package/src/spec/fetch.test.ts +77 -0
- package/src/spec/fetch.ts +112 -0
- package/src/spec/pin.ts +47 -0
- package/src/spec/postgres-catalog-14.snapshot.json +3494 -0
- package/src/spec/postgres-catalog-15.snapshot.json +3529 -0
- package/src/spec/postgres-catalog-16.snapshot.json +3597 -0
- package/src/spec/postgres-catalog-17.snapshot.json +3656 -0
- package/src/spec/postgres-catalog-18.snapshot.json +3747 -0
- package/src/spec/postgres-catalog.test.ts +43 -0
- package/src/spec/postgres-catalog.ts +301 -0
- package/src/spec/postgres-fetch.test.ts +75 -0
- package/src/spec/postgres-fetch.ts +112 -0
- package/src/spec/postgres-pin.test.ts +64 -0
- package/src/spec/postgres-pin.ts +101 -0
- package/src/typecheck.test.ts +104 -0
- package/src/validate-cli.ts +6 -0
- package/src/validate.ts +149 -0
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading a live Postgres server's schema from its catalog, and printing each
|
|
3
|
+
* object as the statement that creates it.
|
|
4
|
+
*
|
|
5
|
+
* Postgres has no `SHOW CREATE TABLE`, so the statement is assembled from the
|
|
6
|
+
* server's own printers, the way `pg_dump` assembles it: `format_type()` for
|
|
7
|
+
* every type, `pg_get_expr()` for defaults, generated columns and partition
|
|
8
|
+
* bounds, `pg_get_constraintdef()` for every constraint, `pg_get_indexdef()`,
|
|
9
|
+
* `pg_get_viewdef()` and `pg_get_partkeydef()`. The session reads with an
|
|
10
|
+
* empty `search_path` (`./client.ts`), so every name outside `pg_catalog` is
|
|
11
|
+
* schema-qualified in what they print. That printed form is the canonical
|
|
12
|
+
* one: import writes it, and normalization compares against it.
|
|
13
|
+
*
|
|
14
|
+
* Left out, each for its reason:
|
|
15
|
+
*
|
|
16
|
+
* - the server's own schemas (`pg_catalog`, `information_schema`, `pg_toast`,
|
|
17
|
+
* the temp schemas) and `public`, which every database has;
|
|
18
|
+
* - objects an extension owns (`pg_depend.deptype = 'e'`): the extension
|
|
19
|
+
* declares them, so the extension is what is imported;
|
|
20
|
+
* - `plpgsql`, installed in every database;
|
|
21
|
+
* - a sequence an identity column owns (it is the column's), and a `serial`
|
|
22
|
+
* column's sequence, since the column prints as `serial`;
|
|
23
|
+
* - an index that backs a constraint (the constraint creates it), and an
|
|
24
|
+
* index partition (the partitioned index creates it);
|
|
25
|
+
* - chant's own receipts tables (`../../core/ownership.ts`), and the working
|
|
26
|
+
* columns, constraints and indexes of an expand-and-contract migration in
|
|
27
|
+
* progress (`../migrate/names.ts`, `../migrate/carry.ts`), so a table reads
|
|
28
|
+
* as it was before the migration until its switch, and as declared after it.
|
|
29
|
+
*
|
|
30
|
+
* Objects another tool owns, an ORM's or a migration runner's revision table
|
|
31
|
+
* ({@link FOREIGN_TABLES}), are read and marked with the tool, so import
|
|
32
|
+
* leaves them out with a warning and observation reports them foreign, never
|
|
33
|
+
* as orphans (#3047 question 10).
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import type { PostgresClient } from "./client";
|
|
37
|
+
import { POSTGRES_ENTITY_TYPES, type PostgresEntityType } from "../entity-types";
|
|
38
|
+
import { quoteIdent } from "../keywords";
|
|
39
|
+
import { hasChantTrailerKey, RECEIPTS_TRAILER_KEY, stripMarker } from "../../core/ownership";
|
|
40
|
+
import { MIGRATION_TRAILER_KEY } from "../migrate/names";
|
|
41
|
+
import { isProviderOwned, providerData } from "../providers";
|
|
42
|
+
import type { PostgresProvider } from "../providers/types";
|
|
43
|
+
|
|
44
|
+
/** The server's own schemas, never part of a declared schema. */
|
|
45
|
+
export const SYSTEM_SCHEMAS = ["pg_catalog", "information_schema", "pg_toast"];
|
|
46
|
+
|
|
47
|
+
/** Tables another tool keeps its migration history in, by name, with the tool. */
|
|
48
|
+
export const FOREIGN_TABLES: Readonly<Record<string, string>> = {
|
|
49
|
+
_prisma_migrations: "Prisma Migrate",
|
|
50
|
+
schema_migrations: "a migration runner (Rails, golang-migrate, dbmate)",
|
|
51
|
+
ar_internal_metadata: "Rails",
|
|
52
|
+
django_migrations: "Django",
|
|
53
|
+
alembic_version: "Alembic",
|
|
54
|
+
__drizzle_migrations: "drizzle-kit",
|
|
55
|
+
flyway_schema_history: "Flyway",
|
|
56
|
+
goose_db_version: "goose",
|
|
57
|
+
knex_migrations: "Knex",
|
|
58
|
+
knex_migrations_lock: "Knex",
|
|
59
|
+
SequelizeMeta: "Sequelize",
|
|
60
|
+
pgmigrations: "node-pg-migrate",
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export interface LivePgObject {
|
|
64
|
+
type: PostgresEntityType;
|
|
65
|
+
/** The schema it is in; absent for a schema and an extension. */
|
|
66
|
+
schema?: string;
|
|
67
|
+
name: string;
|
|
68
|
+
/** The catalog oid, the object's physical id. */
|
|
69
|
+
oid: string;
|
|
70
|
+
/** The object's comment as the server holds it, chant's ownership trailer included. */
|
|
71
|
+
comment?: string;
|
|
72
|
+
/**
|
|
73
|
+
* The statements that create it as the server prints them, chant's trailer
|
|
74
|
+
* taken out of every comment: the CREATE, then a `COMMENT ON` per comment.
|
|
75
|
+
*/
|
|
76
|
+
statement: string;
|
|
77
|
+
/** The tool whose bookkeeping this is, when it is another tool's (an ORM's revision table). */
|
|
78
|
+
foreign?: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** What {@link readLiveSchema} reads. */
|
|
82
|
+
export interface SchemaScope {
|
|
83
|
+
/** The schemas in scope; undefined is every schema but the server's own and `public`'s own objects included. */
|
|
84
|
+
schemas?: readonly string[];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
type Row = Record<string, unknown>;
|
|
88
|
+
|
|
89
|
+
const str = (v: unknown): string | undefined => (v === null || v === undefined ? undefined : String(v));
|
|
90
|
+
const literal = (s: string): string => `'${s.replace(/'/g, "''")}'`;
|
|
91
|
+
const qname = (schema: string | undefined, name: string): string => (schema ? `${quoteIdent(schema)}.${quoteIdent(name)}` : quoteIdent(name));
|
|
92
|
+
|
|
93
|
+
/** A comment with chant's trailer taken off, or undefined when nothing is left. */
|
|
94
|
+
function ownComment(comment: unknown): string | undefined {
|
|
95
|
+
const c = str(comment);
|
|
96
|
+
if (c === undefined) return undefined;
|
|
97
|
+
const own = stripMarker(c);
|
|
98
|
+
return own === "" ? undefined : own;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const commentOn = (what: string, comment: unknown): string[] => {
|
|
102
|
+
const own = ownComment(comment);
|
|
103
|
+
return own === undefined ? [] : [`COMMENT ON ${what} IS ${literal(own)}`];
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/** The scope as a predicate on a schema name column, with its parameter. */
|
|
107
|
+
function scopeSql(column: string, scope: SchemaScope): { sql: string; params: unknown[] } {
|
|
108
|
+
if (scope.schemas) return { sql: `${column} = ANY($1::text[])`, params: [[...scope.schemas]] };
|
|
109
|
+
return {
|
|
110
|
+
sql: `${column} NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND ${column} NOT LIKE 'pg\\_temp\\_%' AND ${column} NOT LIKE 'pg\\_toast\\_temp\\_%'`,
|
|
111
|
+
params: [],
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** `NOT <object is owned by an extension>`, for an object of catalog `catalog` with oid column `oid`. */
|
|
116
|
+
const notExtensionOwned = (catalog: string, oid: string): string =>
|
|
117
|
+
`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 = 'e')`;
|
|
118
|
+
|
|
119
|
+
/** A collation name as a clause, `pg_catalog` names unqualified. */
|
|
120
|
+
const COLLATION_NAME = (oid: string) =>
|
|
121
|
+
`(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 ` +
|
|
122
|
+
`FROM pg_catalog.pg_collation co JOIN pg_catalog.pg_namespace cn ON cn.oid = co.collnamespace WHERE co.oid = ${oid})`;
|
|
123
|
+
|
|
124
|
+
// ── Sequences ──────────────────────────────────────────────────────────
|
|
125
|
+
|
|
126
|
+
interface SequenceParams {
|
|
127
|
+
type: string;
|
|
128
|
+
start: string;
|
|
129
|
+
increment: string;
|
|
130
|
+
min: string;
|
|
131
|
+
max: string;
|
|
132
|
+
cache: string;
|
|
133
|
+
cycle: boolean;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const TYPE_RANGE: Record<string, [bigint, bigint]> = {
|
|
137
|
+
smallint: [-32768n, 32767n],
|
|
138
|
+
integer: [-2147483648n, 2147483647n],
|
|
139
|
+
bigint: [-9223372036854775808n, 9223372036854775807n],
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/** The defaults `CREATE SEQUENCE` gives a sequence of `type` counting by `increment`. */
|
|
143
|
+
export function sequenceDefaults(type: string, increment: bigint): Omit<SequenceParams, "type" | "increment" | "cycle"> {
|
|
144
|
+
const [lo, hi] = TYPE_RANGE[type] ?? TYPE_RANGE.bigint!;
|
|
145
|
+
const min = increment > 0n ? 1n : lo;
|
|
146
|
+
const max = increment > 0n ? hi : -1n;
|
|
147
|
+
return { min: String(min), max: String(max), start: String(increment > 0n ? min : max), cache: "1" };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* The sequence options that differ from what `CREATE SEQUENCE` would choose,
|
|
152
|
+
* in the order the reference page lists them. `withType` writes `AS type`
|
|
153
|
+
* when it is not `bigint`; an identity sequence takes its column's type.
|
|
154
|
+
*/
|
|
155
|
+
export function sequenceOptions(p: SequenceParams, withType: boolean): string[] {
|
|
156
|
+
const inc = BigInt(p.increment);
|
|
157
|
+
const d = sequenceDefaults(p.type, inc);
|
|
158
|
+
const out: string[] = [];
|
|
159
|
+
if (withType && p.type !== "bigint") out.push(`AS ${p.type}`);
|
|
160
|
+
if (inc !== 1n) out.push(`INCREMENT BY ${p.increment}`);
|
|
161
|
+
if (p.min !== d.min) out.push(`MINVALUE ${p.min}`);
|
|
162
|
+
if (p.max !== d.max) out.push(`MAXVALUE ${p.max}`);
|
|
163
|
+
// A sequence starts at its minimum (counting up) or its maximum (counting down) unless told otherwise.
|
|
164
|
+
if (p.start !== (inc > 0n ? p.min : p.max)) out.push(`START WITH ${p.start}`);
|
|
165
|
+
if (p.cache !== d.cache) out.push(`CACHE ${p.cache}`);
|
|
166
|
+
if (p.cycle) out.push("CYCLE");
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const seqParams = (r: Row): SequenceParams => ({
|
|
171
|
+
type: String(r.type),
|
|
172
|
+
start: String(r.start),
|
|
173
|
+
increment: String(r.increment),
|
|
174
|
+
min: String(r.min),
|
|
175
|
+
max: String(r.max),
|
|
176
|
+
cache: String(r.cache),
|
|
177
|
+
cycle: r.cycle === true,
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// ── Reading ────────────────────────────────────────────────────────────
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Every object in scope, in a stable order: schemas, extensions, enums,
|
|
184
|
+
* domains, sequences, tables, views and materialized views, indexes; each
|
|
185
|
+
* kind by schema then name, in byte order.
|
|
186
|
+
*/
|
|
187
|
+
export async function readLiveSchema(client: PostgresClient, scope: SchemaScope = {}): Promise<LivePgObject[]> {
|
|
188
|
+
const out: LivePgObject[] = [];
|
|
189
|
+
const C = 'COLLATE "C"';
|
|
190
|
+
|
|
191
|
+
// Schemas.
|
|
192
|
+
{
|
|
193
|
+
const s = scopeSql("n.nspname", scope);
|
|
194
|
+
const rows = await client.query<Row>(
|
|
195
|
+
`SELECT n.oid::text AS oid, n.nspname AS name, pg_catalog.obj_description(n.oid, 'pg_namespace') AS comment
|
|
196
|
+
FROM pg_catalog.pg_namespace n WHERE ${s.sql} AND n.nspname <> 'public' AND ${notExtensionOwned("pg_namespace", "n.oid")}
|
|
197
|
+
ORDER BY n.nspname ${C}`,
|
|
198
|
+
s.params,
|
|
199
|
+
);
|
|
200
|
+
for (const r of rows) {
|
|
201
|
+
const name = String(r.name);
|
|
202
|
+
out.push({
|
|
203
|
+
type: POSTGRES_ENTITY_TYPES.schema,
|
|
204
|
+
name,
|
|
205
|
+
oid: String(r.oid),
|
|
206
|
+
...(str(r.comment) ? { comment: str(r.comment) } : {}),
|
|
207
|
+
statement: [`CREATE SCHEMA ${quoteIdent(name)}`, ...commentOn(`SCHEMA ${quoteIdent(name)}`, r.comment)].join(";\n"),
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Extensions, in a schema in scope.
|
|
213
|
+
{
|
|
214
|
+
const s = scopeSql("n.nspname", scope);
|
|
215
|
+
const rows = await client.query<Row>(
|
|
216
|
+
`SELECT e.oid::text AS oid, e.extname AS name, n.nspname AS schema, e.extversion AS version, x.default_version,
|
|
217
|
+
pg_catalog.obj_description(e.oid, 'pg_extension') AS comment, x.comment AS default_comment
|
|
218
|
+
FROM pg_catalog.pg_extension e JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
|
|
219
|
+
LEFT JOIN pg_catalog.pg_available_extensions x ON x.name = e.extname
|
|
220
|
+
WHERE e.extname <> 'plpgsql' AND (${s.sql} OR n.nspname = 'public')
|
|
221
|
+
ORDER BY e.extname ${C}`,
|
|
222
|
+
s.params,
|
|
223
|
+
);
|
|
224
|
+
for (const r of rows) {
|
|
225
|
+
const name = String(r.name);
|
|
226
|
+
const version = str(r.version);
|
|
227
|
+
const create = `CREATE EXTENSION ${quoteIdent(name)} WITH SCHEMA ${quoteIdent(String(r.schema))}${version && version !== str(r.default_version) ? ` VERSION ${literal(version)}` : ""}`;
|
|
228
|
+
// The comment the extension's control file sets is the extension's, not a
|
|
229
|
+
// declared one, also when chant's trailer follows it (`../apply/statements.ts`).
|
|
230
|
+
const own = str(r.comment) !== undefined && ownComment(r.comment) === str(r.default_comment) ? null : r.comment;
|
|
231
|
+
out.push({
|
|
232
|
+
type: POSTGRES_ENTITY_TYPES.extension,
|
|
233
|
+
name,
|
|
234
|
+
oid: String(r.oid),
|
|
235
|
+
...(str(r.comment) && str(r.comment) !== str(r.default_comment) ? { comment: str(r.comment) } : {}),
|
|
236
|
+
statement: [create, ...commentOn(`EXTENSION ${quoteIdent(name)}`, own)].join(";\n"),
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Enums.
|
|
242
|
+
{
|
|
243
|
+
const s = scopeSql("n.nspname", scope);
|
|
244
|
+
const rows = await client.query<Row>(
|
|
245
|
+
`SELECT t.oid::text AS oid, n.nspname AS schema, t.typname AS name, pg_catalog.obj_description(t.oid, 'pg_type') AS comment,
|
|
246
|
+
ARRAY(SELECT pg_catalog.quote_literal(e.enumlabel) FROM pg_catalog.pg_enum e WHERE e.enumtypid = t.oid ORDER BY e.enumsortorder) AS labels
|
|
247
|
+
FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
|
|
248
|
+
WHERE t.typtype = 'e' AND ${s.sql} AND ${notExtensionOwned("pg_type", "t.oid")}
|
|
249
|
+
ORDER BY n.nspname ${C}, t.typname ${C}`,
|
|
250
|
+
s.params,
|
|
251
|
+
);
|
|
252
|
+
for (const r of rows) {
|
|
253
|
+
const q = qname(String(r.schema), String(r.name));
|
|
254
|
+
out.push({
|
|
255
|
+
type: POSTGRES_ENTITY_TYPES.enum,
|
|
256
|
+
schema: String(r.schema),
|
|
257
|
+
name: String(r.name),
|
|
258
|
+
oid: String(r.oid),
|
|
259
|
+
...(str(r.comment) ? { comment: str(r.comment) } : {}),
|
|
260
|
+
statement: [`CREATE TYPE ${q} AS ENUM (${(r.labels as string[]).join(", ")})`, ...commentOn(`TYPE ${q}`, r.comment)].join(";\n"),
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Domains.
|
|
266
|
+
{
|
|
267
|
+
const s = scopeSql("n.nspname", scope);
|
|
268
|
+
const rows = await client.query<Row>(
|
|
269
|
+
`SELECT t.oid::text AS oid, n.nspname AS schema, t.typname AS name, pg_catalog.format_type(t.typbasetype, t.typtypmod) AS base,
|
|
270
|
+
t.typnotnull AS notnull, t.typdefault AS dflt, pg_catalog.obj_description(t.oid, 'pg_type') AS comment,
|
|
271
|
+
CASE WHEN t.typcollation <> 0 AND t.typcollation <> bt.typcollation THEN ${COLLATION_NAME("t.typcollation")} END AS collation,
|
|
272
|
+
ARRAY(SELECT 'CONSTRAINT ' || pg_catalog.quote_ident(c.conname) || ' ' || pg_catalog.pg_get_constraintdef(c.oid, true)
|
|
273
|
+
FROM pg_catalog.pg_constraint c WHERE c.contypid = t.oid AND c.contype = 'c' ORDER BY c.conname ${C}) AS checks,
|
|
274
|
+
ARRAY(SELECT pg_catalog.quote_ident(c.conname) || E'\\t' || pg_catalog.obj_description(c.oid, 'pg_constraint')
|
|
275
|
+
FROM pg_catalog.pg_constraint c WHERE c.contypid = t.oid AND c.contype = 'c' AND pg_catalog.obj_description(c.oid, 'pg_constraint') IS NOT NULL
|
|
276
|
+
ORDER BY c.conname ${C}) AS check_comments
|
|
277
|
+
FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace JOIN pg_catalog.pg_type bt ON bt.oid = t.typbasetype
|
|
278
|
+
WHERE t.typtype = 'd' AND ${s.sql} AND ${notExtensionOwned("pg_type", "t.oid")}
|
|
279
|
+
ORDER BY n.nspname ${C}, t.typname ${C}`,
|
|
280
|
+
s.params,
|
|
281
|
+
);
|
|
282
|
+
for (const r of rows) {
|
|
283
|
+
const q = qname(String(r.schema), String(r.name));
|
|
284
|
+
const parts = [`CREATE DOMAIN ${q} AS ${r.base}`];
|
|
285
|
+
if (str(r.collation)) parts.push(`COLLATE ${r.collation}`);
|
|
286
|
+
if (str(r.dflt)) parts.push(`DEFAULT ${r.dflt}`);
|
|
287
|
+
if (r.notnull === true) parts.push("NOT NULL");
|
|
288
|
+
parts.push(...(r.checks as string[]));
|
|
289
|
+
const constraintComments = (r.check_comments as string[]).flatMap((line) => {
|
|
290
|
+
const [con, text] = line.split("\t") as [string, string];
|
|
291
|
+
return commentOn(`CONSTRAINT ${con} ON DOMAIN ${q}`, text);
|
|
292
|
+
});
|
|
293
|
+
out.push({
|
|
294
|
+
type: POSTGRES_ENTITY_TYPES.domain,
|
|
295
|
+
schema: String(r.schema),
|
|
296
|
+
name: String(r.name),
|
|
297
|
+
oid: String(r.oid),
|
|
298
|
+
...(str(r.comment) ? { comment: str(r.comment) } : {}),
|
|
299
|
+
statement: [parts.join(" "), ...commentOn(`DOMAIN ${q}`, r.comment), ...constraintComments].join(";\n"),
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Tables, read first so sequences can tell a serial column's sequence.
|
|
305
|
+
const s = scopeSql("n.nspname", scope);
|
|
306
|
+
const tables = await client.query<Row>(
|
|
307
|
+
`SELECT c.oid::text AS oid, n.nspname AS schema, c.relname AS name, c.relkind AS kind, c.relpersistence AS persistence,
|
|
308
|
+
c.relispartition AS ispartition, c.reloftype <> 0 AS typed,
|
|
309
|
+
CASE WHEN c.relkind = 'p' THEN pg_catalog.pg_get_partkeydef(c.oid) END AS partkey,
|
|
310
|
+
CASE WHEN c.relispartition THEN pg_catalog.pg_get_expr(c.relpartbound, c.oid, true) END AS bound,
|
|
311
|
+
ARRAY(SELECT pg_catalog.quote_ident(pn.nspname) || '.' || pg_catalog.quote_ident(pc.relname)
|
|
312
|
+
FROM pg_catalog.pg_inherits i JOIN pg_catalog.pg_class pc ON pc.oid = i.inhparent JOIN pg_catalog.pg_namespace pn ON pn.oid = pc.relnamespace
|
|
313
|
+
WHERE i.inhrelid = c.oid ORDER BY i.inhseqno) AS parents,
|
|
314
|
+
c.reloptions AS reloptions, (SELECT a.amname FROM pg_catalog.pg_am a WHERE a.oid = c.relam) AS am,
|
|
315
|
+
(SELECT ts.spcname FROM pg_catalog.pg_tablespace ts WHERE ts.oid = c.reltablespace) AS tablespace,
|
|
316
|
+
pg_catalog.obj_description(c.oid, 'pg_class') AS comment
|
|
317
|
+
FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
318
|
+
WHERE c.relkind IN ('r', 'p') AND ${s.sql} AND ${notExtensionOwned("pg_class", "c.oid")}
|
|
319
|
+
ORDER BY n.nspname ${C}, c.relname ${C}`,
|
|
320
|
+
s.params,
|
|
321
|
+
);
|
|
322
|
+
const tableOids = tables.map((t) => String(t.oid));
|
|
323
|
+
const columns = tableOids.length === 0 ? [] : await client.query<Row>(
|
|
324
|
+
`SELECT a.attrelid::text AS rel, a.attnum AS num, a.attname AS name, pg_catalog.format_type(a.atttypid, a.atttypmod) AS type,
|
|
325
|
+
a.attnotnull AS notnull, a.attidentity AS identity, a.attgenerated AS generated, a.attislocal AS islocal,
|
|
326
|
+
pg_catalog.pg_get_expr(d.adbin, d.adrelid, true) AS dflt,
|
|
327
|
+
CASE WHEN a.attcollation <> 0 AND a.attcollation <> t.typcollation THEN ${COLLATION_NAME("a.attcollation")} END AS collation,
|
|
328
|
+
pg_catalog.col_description(a.attrelid, a.attnum) AS comment, a.attcompression::text AS compression, a.attstorage::text AS storage, t.typstorage::text AS typstorage
|
|
329
|
+
FROM pg_catalog.pg_attribute a JOIN pg_catalog.pg_type t ON t.oid = a.atttypid
|
|
330
|
+
LEFT JOIN pg_catalog.pg_attrdef d ON d.adrelid = a.attrelid AND d.adnum = a.attnum
|
|
331
|
+
WHERE a.attrelid = ANY($1::oid[]) AND a.attnum > 0 AND NOT a.attisdropped
|
|
332
|
+
ORDER BY a.attrelid, a.attnum`,
|
|
333
|
+
[tableOids],
|
|
334
|
+
);
|
|
335
|
+
const constraints = tableOids.length === 0 ? [] : await client.query<Row>(
|
|
336
|
+
`SELECT c.conrelid::text AS rel, c.conname AS name, c.contype AS type, pg_catalog.pg_get_constraintdef(c.oid, true) AS def,
|
|
337
|
+
c.conkey AS keys, pg_catalog.obj_description(c.oid, 'pg_constraint') AS comment
|
|
338
|
+
FROM pg_catalog.pg_constraint c
|
|
339
|
+
WHERE c.conrelid = ANY($1::oid[]) AND c.contype IN ('p', 'u', 'c', 'f', 'x') AND c.conislocal AND c.conparentid = 0
|
|
340
|
+
ORDER BY c.conrelid, CASE c.contype WHEN 'p' THEN 1 WHEN 'u' THEN 2 WHEN 'c' THEN 3 WHEN 'f' THEN 4 ELSE 5 END, c.conname ${C}`,
|
|
341
|
+
[tableOids],
|
|
342
|
+
);
|
|
343
|
+
const identities = tableOids.length === 0 ? [] : await client.query<Row>(
|
|
344
|
+
`SELECT d.refobjid::text AS rel, d.refobjsubid AS num, pg_catalog.format_type(s.seqtypid, NULL) AS type, s.seqstart::text AS start,
|
|
345
|
+
s.seqincrement::text AS increment, s.seqmin::text AS min, s.seqmax::text AS max, s.seqcache::text AS cache, s.seqcycle AS cycle
|
|
346
|
+
FROM pg_catalog.pg_depend d JOIN pg_catalog.pg_sequence s ON s.seqrelid = d.objid
|
|
347
|
+
WHERE d.classid = 'pg_catalog.pg_class'::pg_catalog.regclass AND d.refclassid = 'pg_catalog.pg_class'::pg_catalog.regclass
|
|
348
|
+
AND d.deptype = 'i' AND d.refobjid = ANY($1::oid[])`,
|
|
349
|
+
[tableOids],
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
// Sequences: every one in scope that an identity column does not own.
|
|
353
|
+
const sequences = await client.query<Row>(
|
|
354
|
+
`SELECT c.oid::text AS oid, n.nspname AS schema, c.relname AS name, pg_catalog.format_type(s.seqtypid, NULL) AS type,
|
|
355
|
+
s.seqstart::text AS start, s.seqincrement::text AS increment, s.seqmin::text AS min, s.seqmax::text AS max,
|
|
356
|
+
s.seqcache::text AS cache, s.seqcycle AS cycle, c.relpersistence AS persistence,
|
|
357
|
+
pg_catalog.obj_description(c.oid, 'pg_class') AS comment,
|
|
358
|
+
(SELECT d.refobjid::text || ':' || d.refobjsubid FROM pg_catalog.pg_depend d
|
|
359
|
+
WHERE d.classid = 'pg_catalog.pg_class'::pg_catalog.regclass AND d.objid = c.oid AND d.refclassid = 'pg_catalog.pg_class'::pg_catalog.regclass
|
|
360
|
+
AND d.deptype = 'a' AND d.refobjsubid > 0 LIMIT 1) AS owner
|
|
361
|
+
FROM pg_catalog.pg_class c JOIN pg_catalog.pg_sequence s ON s.seqrelid = c.oid JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
362
|
+
WHERE c.relkind = 'S' AND ${s.sql} AND ${notExtensionOwned("pg_class", "c.oid")}
|
|
363
|
+
AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_depend d WHERE d.classid = 'pg_catalog.pg_class'::pg_catalog.regclass AND d.objid = c.oid AND d.deptype = 'i')
|
|
364
|
+
ORDER BY n.nspname ${C}, c.relname ${C}`,
|
|
365
|
+
s.params,
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
// A serial column: an integer column whose default is nextval of a sequence it owns, named as Postgres names it, with default options.
|
|
369
|
+
const tableByOid = new Map(tables.map((t) => [String(t.oid), t]));
|
|
370
|
+
const serialSequences = new Set<string>();
|
|
371
|
+
const serialColumns = new Map<string, string>(); // rel:num -> serial type
|
|
372
|
+
for (const q of sequences) {
|
|
373
|
+
const owner = str(q.owner);
|
|
374
|
+
if (!owner) continue;
|
|
375
|
+
const [rel, num] = owner.split(":") as [string, string];
|
|
376
|
+
const t = tableByOid.get(rel);
|
|
377
|
+
const col = columns.find((c) => String(c.rel) === rel && String(c.num) === num);
|
|
378
|
+
if (!t || !col) continue;
|
|
379
|
+
const seqName = qname(String(q.schema), String(q.name));
|
|
380
|
+
const serial = { integer: "serial", bigint: "bigserial", smallint: "smallserial" }[String(col.type)];
|
|
381
|
+
const expected = `${String(t.name)}_${String(col.name)}_seq`;
|
|
382
|
+
const p = seqParams(q);
|
|
383
|
+
if (
|
|
384
|
+
serial &&
|
|
385
|
+
String(q.schema) === String(t.schema) &&
|
|
386
|
+
String(q.name) === expected &&
|
|
387
|
+
str(col.dflt) === `nextval(${literal(seqName)}::regclass)` &&
|
|
388
|
+
p.type === String(col.type) &&
|
|
389
|
+
sequenceOptions(p, false).length === 0 &&
|
|
390
|
+
ownComment(q.comment) === undefined
|
|
391
|
+
) {
|
|
392
|
+
serialSequences.add(String(q.oid));
|
|
393
|
+
serialColumns.set(owner, serial);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
for (const q of sequences) {
|
|
398
|
+
if (serialSequences.has(String(q.oid))) continue;
|
|
399
|
+
const qn = qname(String(q.schema), String(q.name));
|
|
400
|
+
const opts = sequenceOptions(seqParams(q), true);
|
|
401
|
+
const owner = str(q.owner);
|
|
402
|
+
const ownerTable = owner ? tableByOid.get(owner.split(":")[0]!) : undefined;
|
|
403
|
+
out.push({
|
|
404
|
+
type: POSTGRES_ENTITY_TYPES.sequence,
|
|
405
|
+
schema: String(q.schema),
|
|
406
|
+
name: String(q.name),
|
|
407
|
+
oid: String(q.oid),
|
|
408
|
+
...(str(q.comment) ? { comment: str(q.comment) } : {}),
|
|
409
|
+
...(ownerTable && FOREIGN_TABLES[String(ownerTable.name)] ? { foreign: FOREIGN_TABLES[String(ownerTable.name)] } : {}),
|
|
410
|
+
statement: [
|
|
411
|
+
`CREATE ${q.persistence === "u" ? "UNLOGGED " : ""}SEQUENCE ${qn}${opts.length ? ` ${opts.join(" ")}` : ""}`,
|
|
412
|
+
...commentOn(`SEQUENCE ${qn}`, q.comment),
|
|
413
|
+
].join(";\n"),
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
for (const t of tables) {
|
|
418
|
+
const rel = String(t.oid);
|
|
419
|
+
const q = qname(String(t.schema), String(t.name));
|
|
420
|
+
if (hasChantTrailerKey(str(t.comment), [RECEIPTS_TRAILER_KEY])) continue;
|
|
421
|
+
const working = (comment: unknown) => hasChantTrailerKey(str(comment), [MIGRATION_TRAILER_KEY]);
|
|
422
|
+
const cols = columns.filter((c) => String(c.rel) === rel && !working(c.comment));
|
|
423
|
+
const cons = constraints.filter((c) => String(c.rel) === rel && !working(c.comment));
|
|
424
|
+
const pkColumns = new Set(
|
|
425
|
+
cons.filter((c) => c.type === "p").flatMap((c) => (c.keys as number[] | null) ?? []).map((n) => String(n)),
|
|
426
|
+
);
|
|
427
|
+
const lines: string[] = [];
|
|
428
|
+
const commentLines: string[] = [];
|
|
429
|
+
for (const c of cols) {
|
|
430
|
+
if (t.ispartition === true || (Array.isArray(t.parents) && (t.parents as string[]).length > 0 && c.islocal !== true)) {
|
|
431
|
+
// A partition's columns, and an inheriting table's inherited ones, are its parent's.
|
|
432
|
+
commentLines.push(...commentOn(`COLUMN ${q}.${quoteIdent(String(c.name))}`, c.comment));
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
const serial = serialColumns.get(`${rel}:${String(c.num)}`);
|
|
436
|
+
const parts = [quoteIdent(String(c.name)), serial ?? String(c.type)];
|
|
437
|
+
const compression = str(c.compression);
|
|
438
|
+
if (compression === "p") parts.push("COMPRESSION pglz");
|
|
439
|
+
else if (compression === "l") parts.push("COMPRESSION lz4");
|
|
440
|
+
if (str(c.storage) !== str(c.typstorage)) {
|
|
441
|
+
parts.push(`STORAGE ${{ p: "PLAIN", e: "EXTERNAL", m: "MAIN", x: "EXTENDED" }[String(c.storage)] ?? "DEFAULT"}`);
|
|
442
|
+
}
|
|
443
|
+
if (str(c.collation)) parts.push(`COLLATE ${c.collation}`);
|
|
444
|
+
const identity = str(c.identity);
|
|
445
|
+
if (identity === "a" || identity === "d") {
|
|
446
|
+
const seq = identities.find((x) => String(x.rel) === rel && String(x.num) === String(c.num));
|
|
447
|
+
const opts = seq ? sequenceOptions(seqParams(seq), false) : [];
|
|
448
|
+
parts.push(`GENERATED ${identity === "a" ? "ALWAYS" : "BY DEFAULT"} AS IDENTITY${opts.length ? ` (${opts.join(" ")})` : ""}`);
|
|
449
|
+
} else if (str(c.generated) === "s" || str(c.generated) === "v") {
|
|
450
|
+
parts.push(`GENERATED ALWAYS AS (${c.dflt}) ${c.generated === "s" ? "STORED" : "VIRTUAL"}`);
|
|
451
|
+
} else if (str(c.dflt) && !serial) parts.push(`DEFAULT ${c.dflt}`);
|
|
452
|
+
// A primary key and an identity column are NOT NULL by themselves.
|
|
453
|
+
if (c.notnull === true && !pkColumns.has(String(c.num)) && identity !== "a" && identity !== "d" && !serial) parts.push("NOT NULL");
|
|
454
|
+
lines.push(parts.join(" "));
|
|
455
|
+
commentLines.push(...commentOn(`COLUMN ${q}.${quoteIdent(String(c.name))}`, c.comment));
|
|
456
|
+
}
|
|
457
|
+
for (const c of cons) {
|
|
458
|
+
lines.push(`CONSTRAINT ${quoteIdent(String(c.name))} ${c.def}`);
|
|
459
|
+
commentLines.push(...commentOn(`CONSTRAINT ${quoteIdent(String(c.name))} ON ${q}`, c.comment));
|
|
460
|
+
}
|
|
461
|
+
const head = `CREATE ${t.persistence === "u" ? "UNLOGGED " : ""}TABLE ${q}`;
|
|
462
|
+
const parents = (t.parents as string[] | null) ?? [];
|
|
463
|
+
let create: string;
|
|
464
|
+
if (t.ispartition === true) {
|
|
465
|
+
create = `${head} PARTITION OF ${parents[0]}${lines.length ? ` (\n ${lines.join(",\n ")}\n)` : ""} ${t.bound}`;
|
|
466
|
+
} else {
|
|
467
|
+
create = `${head} (\n ${lines.join(",\n ")}\n)${parents.length ? ` INHERITS (${parents.join(", ")})` : ""}`;
|
|
468
|
+
}
|
|
469
|
+
if (str(t.partkey)) create += ` PARTITION BY ${t.partkey}`;
|
|
470
|
+
if (str(t.am) && t.am !== "heap") create += ` USING ${quoteIdent(String(t.am))}`;
|
|
471
|
+
const opts = (t.reloptions as string[] | null) ?? [];
|
|
472
|
+
if (opts.length) create += ` WITH (${opts.join(", ")})`;
|
|
473
|
+
if (str(t.tablespace)) create += ` TABLESPACE ${quoteIdent(String(t.tablespace))}`;
|
|
474
|
+
out.push({
|
|
475
|
+
type: POSTGRES_ENTITY_TYPES.table,
|
|
476
|
+
schema: String(t.schema),
|
|
477
|
+
name: String(t.name),
|
|
478
|
+
oid: rel,
|
|
479
|
+
...(str(t.comment) ? { comment: str(t.comment) } : {}),
|
|
480
|
+
...(FOREIGN_TABLES[String(t.name)] ? { foreign: FOREIGN_TABLES[String(t.name)] } : {}),
|
|
481
|
+
statement: [create, ...commentOn(`TABLE ${q}`, t.comment), ...commentLines].join(";\n"),
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Views and materialized views.
|
|
486
|
+
{
|
|
487
|
+
const rows = await client.query<Row>(
|
|
488
|
+
`SELECT c.oid::text AS oid, n.nspname AS schema, c.relname AS name, c.relkind AS kind, pg_catalog.pg_get_viewdef(c.oid, true) AS def,
|
|
489
|
+
c.reloptions AS reloptions, c.relispopulated AS populated, (SELECT a.amname FROM pg_catalog.pg_am a WHERE a.oid = c.relam) AS am,
|
|
490
|
+
(SELECT ts.spcname FROM pg_catalog.pg_tablespace ts WHERE ts.oid = c.reltablespace) AS tablespace,
|
|
491
|
+
pg_catalog.obj_description(c.oid, 'pg_class') AS comment,
|
|
492
|
+
ARRAY(SELECT pg_catalog.quote_ident(a.attname) || E'\\t' || pg_catalog.col_description(c.oid, a.attnum) FROM pg_catalog.pg_attribute a
|
|
493
|
+
WHERE a.attrelid = c.oid AND a.attnum > 0 AND NOT a.attisdropped AND pg_catalog.col_description(c.oid, a.attnum) IS NOT NULL ORDER BY a.attnum) AS column_comments
|
|
494
|
+
FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
495
|
+
WHERE c.relkind IN ('v', 'm') AND ${s.sql} AND ${notExtensionOwned("pg_class", "c.oid")}
|
|
496
|
+
ORDER BY n.nspname ${C}, c.relname ${C}`,
|
|
497
|
+
s.params,
|
|
498
|
+
);
|
|
499
|
+
for (const r of rows) {
|
|
500
|
+
const q = qname(String(r.schema), String(r.name));
|
|
501
|
+
const materialized = r.kind === "m";
|
|
502
|
+
const query = String(r.def).trim().replace(/;$/, "");
|
|
503
|
+
let opts = (r.reloptions as string[] | null) ?? [];
|
|
504
|
+
const check = opts.find((o) => o.startsWith("check_option="));
|
|
505
|
+
opts = opts.filter((o) => !o.startsWith("check_option="));
|
|
506
|
+
let create = `CREATE ${materialized ? "MATERIALIZED " : ""}VIEW ${q}`;
|
|
507
|
+
if (materialized && str(r.am) && r.am !== "heap") create += ` USING ${quoteIdent(String(r.am))}`;
|
|
508
|
+
if (opts.length) create += ` WITH (${opts.join(", ")})`;
|
|
509
|
+
if (materialized && str(r.tablespace)) create += ` TABLESPACE ${quoteIdent(String(r.tablespace))}`;
|
|
510
|
+
create += ` AS\n${query}`;
|
|
511
|
+
if (check) create += `\nWITH ${check.endsWith("local") ? "LOCAL" : "CASCADED"} CHECK OPTION`;
|
|
512
|
+
if (materialized && r.populated === false) create += "\nWITH NO DATA";
|
|
513
|
+
const what = materialized ? "MATERIALIZED VIEW" : "VIEW";
|
|
514
|
+
const columnComments = (r.column_comments as string[]).flatMap((line) => {
|
|
515
|
+
const [col, text] = line.split("\t") as [string, string];
|
|
516
|
+
return commentOn(`COLUMN ${q}.${col}`, text);
|
|
517
|
+
});
|
|
518
|
+
out.push({
|
|
519
|
+
type: materialized ? POSTGRES_ENTITY_TYPES.materializedView : POSTGRES_ENTITY_TYPES.view,
|
|
520
|
+
schema: String(r.schema),
|
|
521
|
+
name: String(r.name),
|
|
522
|
+
oid: String(r.oid),
|
|
523
|
+
...(str(r.comment) ? { comment: str(r.comment) } : {}),
|
|
524
|
+
statement: [create, ...commentOn(`${what} ${q}`, r.comment), ...columnComments].join(";\n"),
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Indexes a constraint does not create, and not index partitions.
|
|
530
|
+
{
|
|
531
|
+
const rows = await client.query<Row>(
|
|
532
|
+
`SELECT ic.oid::text AS oid, n.nspname AS schema, ic.relname AS name, tc.relname AS table_name,
|
|
533
|
+
pg_catalog.pg_get_indexdef(i.indexrelid, 0, true) AS def, pg_catalog.obj_description(ic.oid, 'pg_class') AS comment
|
|
534
|
+
FROM pg_catalog.pg_index i JOIN pg_catalog.pg_class ic ON ic.oid = i.indexrelid JOIN pg_catalog.pg_class tc ON tc.oid = i.indrelid
|
|
535
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = ic.relnamespace
|
|
536
|
+
WHERE tc.relkind IN ('r', 'p', 'm') AND NOT ic.relispartition AND ${s.sql} AND ${notExtensionOwned("pg_class", "tc.oid")}
|
|
537
|
+
AND NOT EXISTS (SELECT 1 FROM pg_catalog.pg_constraint c WHERE c.conindid = i.indexrelid AND c.contype IN ('p', 'u', 'x'))
|
|
538
|
+
ORDER BY n.nspname ${C}, ic.relname ${C}`,
|
|
539
|
+
s.params,
|
|
540
|
+
);
|
|
541
|
+
for (const r of rows) {
|
|
542
|
+
// An index a migration builds on its new column, or keeps on the old one until its contract.
|
|
543
|
+
if (hasChantTrailerKey(str(r.comment), [MIGRATION_TRAILER_KEY])) continue;
|
|
544
|
+
const q = qname(String(r.schema), String(r.name));
|
|
545
|
+
out.push({
|
|
546
|
+
type: POSTGRES_ENTITY_TYPES.index,
|
|
547
|
+
schema: String(r.schema),
|
|
548
|
+
name: String(r.name),
|
|
549
|
+
oid: String(r.oid),
|
|
550
|
+
...(str(r.comment) ? { comment: str(r.comment) } : {}),
|
|
551
|
+
...(FOREIGN_TABLES[String(r.table_name)] ? { foreign: FOREIGN_TABLES[String(r.table_name)] } : {}),
|
|
552
|
+
statement: [String(r.def), ...commentOn(`INDEX ${q}`, r.comment)].join(";\n"),
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return out;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/** The key an object is found by: its type and schema-qualified name. */
|
|
561
|
+
export const liveKey = (type: string, schema: string | undefined, name: string): string => `${type} ${schema ?? ""}.${name}`;
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Mark what the managed service owns (#3282) as foreign: its reserved
|
|
565
|
+
* schemas and everything in them, and the extensions it installs itself
|
|
566
|
+
* (`rdsadmin`, Supabase's `auth` and `storage`, ...). They are the
|
|
567
|
+
* provider's, so import leaves them out and observation never reports them
|
|
568
|
+
* as chant's.
|
|
569
|
+
*/
|
|
570
|
+
export function markProviderOwned(objects: readonly LivePgObject[], provider: PostgresProvider | undefined): LivePgObject[] {
|
|
571
|
+
if (!provider) return [...objects];
|
|
572
|
+
const label = providerData(provider).label;
|
|
573
|
+
return objects.map((o) => {
|
|
574
|
+
if (o.foreign) return o;
|
|
575
|
+
const owned =
|
|
576
|
+
(o.type === POSTGRES_ENTITY_TYPES.schema && isProviderOwned(provider, { kind: "schema", name: o.name })) ||
|
|
577
|
+
(o.type === POSTGRES_ENTITY_TYPES.extension && isProviderOwned(provider, { kind: "extension", name: o.name })) ||
|
|
578
|
+
(o.schema !== undefined && isProviderOwned(provider, { kind: "schema", name: o.schema }));
|
|
579
|
+
return owned ? { ...o, foreign: label } : o;
|
|
580
|
+
});
|
|
581
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Postgres wire client: node-postgres (`pg`), loaded the first time a
|
|
3
|
+
* Postgres server is read, so a ClickHouse-only project never loads it.
|
|
4
|
+
*
|
|
5
|
+
* Every session reads the catalog with an empty `search_path`, as `pg_dump`
|
|
6
|
+
* does: `pg_get_*def()` and `format_type()` then qualify every name outside
|
|
7
|
+
* `pg_catalog`, so what a server prints does not depend on the role's own
|
|
8
|
+
* search path.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface PostgresEndpoint {
|
|
12
|
+
/** A `postgres://` connection URL, without a password. */
|
|
13
|
+
url: string;
|
|
14
|
+
user?: string;
|
|
15
|
+
password?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** What chant reads and writes through: one connection. */
|
|
19
|
+
export interface PostgresClient {
|
|
20
|
+
query<T = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<T[]>;
|
|
21
|
+
/** Close the connection. Safe to call twice. */
|
|
22
|
+
end(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** A failed statement, with the server's SQLSTATE when it sent one. */
|
|
26
|
+
export class PostgresQueryError extends Error {
|
|
27
|
+
constructor(
|
|
28
|
+
message: string,
|
|
29
|
+
readonly code?: string,
|
|
30
|
+
readonly position?: number,
|
|
31
|
+
) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "PostgresQueryError";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type PgModule = typeof import("pg");
|
|
38
|
+
|
|
39
|
+
let loaded: Promise<PgModule> | undefined;
|
|
40
|
+
|
|
41
|
+
async function pgModule(): Promise<PgModule> {
|
|
42
|
+
loaded ??= import("pg").then((m) => ((m as unknown as { default?: PgModule }).default ?? m) as PgModule);
|
|
43
|
+
return loaded;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const wrap = (err: unknown): PostgresQueryError => {
|
|
47
|
+
const e = err as { message?: string; code?: string; position?: string };
|
|
48
|
+
return new PostgresQueryError(e.message ?? String(err), e.code, e.position !== undefined ? Number(e.position) : undefined);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** Connect to `endpoint` and set the catalog-reading session up. */
|
|
52
|
+
export async function connectPostgres(endpoint: PostgresEndpoint, options: { applicationName?: string } = {}): Promise<PostgresClient> {
|
|
53
|
+
const pg = await pgModule();
|
|
54
|
+
// node-postgres lets the connection string's fields win over the config's, so the credentials go into the URL.
|
|
55
|
+
const url = new URL(endpoint.url);
|
|
56
|
+
if (endpoint.user !== undefined) url.username = encodeURIComponent(endpoint.user);
|
|
57
|
+
if (endpoint.password !== undefined) url.password = encodeURIComponent(endpoint.password);
|
|
58
|
+
const client = new pg.Client({ connectionString: url.toString(), application_name: options.applicationName ?? "chant" });
|
|
59
|
+
// A server that goes away emits an error event; the next query fails with it instead of the process crashing.
|
|
60
|
+
client.on("error", () => undefined);
|
|
61
|
+
try {
|
|
62
|
+
await client.connect();
|
|
63
|
+
await client.query("SELECT pg_catalog.set_config('search_path', '', false)");
|
|
64
|
+
} catch (err) {
|
|
65
|
+
await client.end().catch(() => undefined);
|
|
66
|
+
throw wrap(err);
|
|
67
|
+
}
|
|
68
|
+
let ended = false;
|
|
69
|
+
return {
|
|
70
|
+
async query<T>(sql: string, params?: readonly unknown[]): Promise<T[]> {
|
|
71
|
+
try {
|
|
72
|
+
const r = await client.query(sql, params as unknown[] | undefined);
|
|
73
|
+
return r.rows as T[];
|
|
74
|
+
} catch (err) {
|
|
75
|
+
throw wrap(err);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
async end() {
|
|
79
|
+
if (ended) return;
|
|
80
|
+
ended = true;
|
|
81
|
+
await client.end().catch(() => undefined);
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|