@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,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two sides a Postgres diff compares: a build's output (the
|
|
3
|
+
* declarations), or what a live server's catalog prints. Both are parsed with
|
|
4
|
+
* the tag each object was declared with and brought to canonical form
|
|
5
|
+
* (`./normalize.ts`), so the diff compares like with like.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import type { Keyed } from "../../core/diff";
|
|
10
|
+
import { previouslyIn } from "../../core/normalize";
|
|
11
|
+
import type { LivePgObject } from "../live/catalog";
|
|
12
|
+
import { liveProps } from "./deep";
|
|
13
|
+
import { canonicalPgObject, type CanonicalPgObject } from "./normalize";
|
|
14
|
+
import { identValue } from "../parser";
|
|
15
|
+
|
|
16
|
+
/** A canonical object with what the diff needs besides: rename hints, how an index is created, a view's outputs. */
|
|
17
|
+
export interface PgDiffObject extends CanonicalPgObject {
|
|
18
|
+
type: string;
|
|
19
|
+
/** `-- previously: <old name>` before the CREATE. */
|
|
20
|
+
previously?: string;
|
|
21
|
+
/** Per column, `-- previously: <old name>` on its line. */
|
|
22
|
+
columnPreviously: Record<string, string>;
|
|
23
|
+
/** The index is declared CONCURRENTLY. */
|
|
24
|
+
concurrently?: boolean;
|
|
25
|
+
/** A view's output columns, in order. */
|
|
26
|
+
outputs?: string[];
|
|
27
|
+
/** The tool another object belongs to (an ORM's revision table), when it is not chant's to change. */
|
|
28
|
+
foreign?: string;
|
|
29
|
+
/** The export name, against a server. */
|
|
30
|
+
exportName?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type PgSchemaObject = Keyed<PgDiffObject>;
|
|
34
|
+
|
|
35
|
+
/** The rename hints in a statement: the object's (a comment before the CREATE) and each column's (a comment on its line). */
|
|
36
|
+
export function renameHints(ddl: string): { previously?: string; columns: Record<string, string> } {
|
|
37
|
+
const lines = ddl.split("\n");
|
|
38
|
+
const createAt = lines.findIndex((l) => /\bCREATE\b/i.test(l.replace(/--.*$/, "")));
|
|
39
|
+
const before = lines.slice(0, Math.max(createAt, 0)).map((l) => l.trim()).filter((l) => l.startsWith("--"));
|
|
40
|
+
const columns: Record<string, string> = {};
|
|
41
|
+
for (const line of lines.slice(createAt + 1)) {
|
|
42
|
+
const m = /^\s*("(?:[^"]|"")+"|[A-Za-z_][A-Za-z0-9_$]*)\b.*?(--.*)$/.exec(line);
|
|
43
|
+
if (!m) continue;
|
|
44
|
+
const prev = previouslyIn([m[2]!]);
|
|
45
|
+
if (prev) columns[identValue(m[1]!)] = identValue(prev);
|
|
46
|
+
}
|
|
47
|
+
const prev = previouslyIn(before);
|
|
48
|
+
return { ...(prev ? { previously: prev } : {}), columns };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** One object, from its type and statements, in the diff's form. */
|
|
52
|
+
export function diffObject(type: string, ddl: string, defaultSchema: string): PgDiffObject {
|
|
53
|
+
const props = liveProps({ type, statement: ddl } as LivePgObject);
|
|
54
|
+
const canonical = canonicalPgObject(type, props, defaultSchema);
|
|
55
|
+
const hints = renameHints(ddl);
|
|
56
|
+
const lineage = props.lineage as Array<{ output: string }> | undefined;
|
|
57
|
+
const declaredColumns = props.columns as unknown[] | undefined;
|
|
58
|
+
return {
|
|
59
|
+
...canonical,
|
|
60
|
+
type,
|
|
61
|
+
...(hints.previously ? { previously: identValue(hints.previously) } : {}),
|
|
62
|
+
columnPreviously: hints.columns,
|
|
63
|
+
...(props.concurrently === true ? { concurrently: true } : {}),
|
|
64
|
+
...(canonical.kind === "view" || canonical.kind === "materializedView"
|
|
65
|
+
? { outputs: Array.isArray(declaredColumns) && declaredColumns.length > 0 ? (declaredColumns as string[]) : (lineage ?? []).map((e) => e.output) }
|
|
66
|
+
: {}),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface OutputDoc {
|
|
71
|
+
dialect?: string;
|
|
72
|
+
postgresMajor?: number;
|
|
73
|
+
objects?: Array<{ export: string; type: string; ddl: string }>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** The objects a Postgres `chant build` output holds, keyed by export name. */
|
|
77
|
+
export function pgSchemaFromBuildOutput(json: string, defaultSchema = "public"): PgSchemaObject[] {
|
|
78
|
+
const doc = JSON.parse(json) as OutputDoc;
|
|
79
|
+
if (doc.dialect !== "postgres" || !Array.isArray(doc.objects)) throw new Error('not a Postgres build output: expected { dialect: "postgres", objects: [...] }');
|
|
80
|
+
return doc.objects.map((o) => ({ key: o.export, canonical: { ...diffObject(o.type, o.ddl, defaultSchema), exportName: o.export } }));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** The major a Postgres build recorded (`postgresMajor`), or undefined for output that predates the field. */
|
|
84
|
+
export function pgBuildMajor(json: string): number | undefined {
|
|
85
|
+
const m = (JSON.parse(json) as OutputDoc).postgresMajor;
|
|
86
|
+
return typeof m === "number" ? m : undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function pgBuildFileMajor(path: string): number | undefined {
|
|
90
|
+
return pgBuildMajor(readFileSync(path, "utf-8"));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function pgSchemaFromBuildFile(path: string, defaultSchema = "public"): PgSchemaObject[] {
|
|
94
|
+
return pgSchemaFromBuildOutput(readFileSync(path, "utf-8"), defaultSchema);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** The identity an object has on a server: its kind's namespace and its qualified name. */
|
|
98
|
+
export function qualifiedKey(o: { kind: string; schema?: string; name: string }): string {
|
|
99
|
+
const space = o.kind === "schema" ? "schema" : o.kind === "extension" ? "extension" : o.kind === "enum" || o.kind === "domain" ? "type" : "relation";
|
|
100
|
+
return `${space} ${o.schema ? `${o.schema}.` : ""}${o.name}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The declared objects re-keyed by qualified name, the only identity a server has. */
|
|
104
|
+
export function keyedByQualifiedName(objects: readonly PgSchemaObject[]): PgSchemaObject[] {
|
|
105
|
+
return objects.map((o) => ({ key: qualifiedKey(o.canonical), canonical: { ...o.canonical, exportName: o.canonical.exportName ?? o.key } }));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** What a server holds, in the diff's form, keyed by qualified name. */
|
|
109
|
+
export function pgSchemaFromLive(live: readonly LivePgObject[], defaultSchema: string): PgSchemaObject[] {
|
|
110
|
+
return live.map((o) => {
|
|
111
|
+
const canonical = { ...diffObject(o.type, o.statement, defaultSchema), ...(o.foreign ? { foreign: o.foreign } : {}) };
|
|
112
|
+
return { key: qualifiedKey(canonical), canonical };
|
|
113
|
+
});
|
|
114
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The backstop for normalization against a live server: what the rules in
|
|
3
|
+
* `./normalize.ts` cannot see (a view's `SELECT *`, which the server expands;
|
|
4
|
+
* the parentheses it adds inside a check) is asked of the server itself.
|
|
5
|
+
*
|
|
6
|
+
* For each declared table or view whose expressions still differ from the
|
|
7
|
+
* server's, the declaration's expressions are created as a temporary object
|
|
8
|
+
* (`CREATE TEMP VIEW`, or a `CREATE TEMP TABLE` holding the columns' types,
|
|
9
|
+
* defaults and generated expressions and the checks) inside a transaction
|
|
10
|
+
* that is always rolled back, with a short `lock_timeout`, and read back with
|
|
11
|
+
* the same printers the catalog read uses. Nothing is left behind: Postgres
|
|
12
|
+
* DDL is transactional and a temporary object lives in the session's own
|
|
13
|
+
* schema. A server that refuses (no TEMP privilege, a lock not granted in
|
|
14
|
+
* time, an expression it rejects) leaves the rules' answer standing.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { PostgresClient } from "../live/client";
|
|
18
|
+
import { quoteIdent } from "../keywords";
|
|
19
|
+
import { canonicalExpr, type CanonicalPgObject } from "./normalize";
|
|
20
|
+
|
|
21
|
+
type Row = Record<string, unknown>;
|
|
22
|
+
|
|
23
|
+
async function rolledBack<T>(client: PostgresClient, defaultSchema: string, body: () => Promise<T>): Promise<T | undefined> {
|
|
24
|
+
await client.query("BEGIN");
|
|
25
|
+
try {
|
|
26
|
+
await client.query("SET LOCAL lock_timeout = '1s'");
|
|
27
|
+
await client.query("SET LOCAL statement_timeout = '10s'");
|
|
28
|
+
await client.query(`SELECT pg_catalog.set_config('search_path', $1, true)`, [quoteIdent(defaultSchema)]);
|
|
29
|
+
return await body();
|
|
30
|
+
} catch {
|
|
31
|
+
return undefined;
|
|
32
|
+
} finally {
|
|
33
|
+
await client.query("ROLLBACK").catch(() => undefined);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const emptyPath = (client: PostgresClient) => client.query(`SELECT pg_catalog.set_config('search_path', '', true)`);
|
|
38
|
+
|
|
39
|
+
/** A view's query as the server prints it, canonical, and its output columns. */
|
|
40
|
+
async function viewQuery(client: PostgresClient, query: string, defaultSchema: string): Promise<{ query: string; outputs: string[] } | undefined> {
|
|
41
|
+
return rolledBack(client, defaultSchema, async () => {
|
|
42
|
+
await client.query(`CREATE TEMP VIEW chant_normalize AS ${query}`);
|
|
43
|
+
await emptyPath(client);
|
|
44
|
+
const [row] = await client.query<Row>(`SELECT pg_catalog.pg_get_viewdef('pg_temp.chant_normalize'::pg_catalog.regclass, true) AS def`);
|
|
45
|
+
const cols = await client.query<Row>(
|
|
46
|
+
`SELECT a.attname AS name FROM pg_catalog.pg_attribute a WHERE a.attrelid = 'pg_temp.chant_normalize'::pg_catalog.regclass AND a.attnum > 0 ORDER BY a.attnum`,
|
|
47
|
+
);
|
|
48
|
+
return { query: canonicalExpr(String(row?.def ?? "").trim().replace(/;$/, ""))!, outputs: cols.map((c) => String(c.name)) };
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** A table's defaults, generated expressions and checks as the server prints them, canonical. */
|
|
53
|
+
async function tableExpressions(client: PostgresClient, o: CanonicalPgObject, defaultSchema: string): Promise<{ defaults: Map<string, string>; generated: Map<string, string>; checks: string[] } | undefined> {
|
|
54
|
+
const columns = o.columns.filter((c) => c.type !== undefined);
|
|
55
|
+
if (columns.length === 0) return undefined;
|
|
56
|
+
const defs = columns.map((c) => {
|
|
57
|
+
const type = /^(small|big)?serial$/.test(c.type!) ? c.type!.replace("serial", "int").replace("smallint", "smallint").replace(/^int$/, "integer") : c.type!;
|
|
58
|
+
const parts = [quoteIdent(c.name), type];
|
|
59
|
+
if (c.collate) parts.push(`COLLATE ${c.collate}`);
|
|
60
|
+
if (c.generated) {
|
|
61
|
+
const [kind, ...expr] = c.generated.split(" ");
|
|
62
|
+
parts.push(`GENERATED ALWAYS AS (${expr.join(" ")}) ${kind === "virtual" ? "VIRTUAL" : "STORED"}`);
|
|
63
|
+
} else if (c.default !== undefined) parts.push(`DEFAULT ${c.default}`);
|
|
64
|
+
return parts.join(" ");
|
|
65
|
+
});
|
|
66
|
+
const checks = o.constraints.filter((c) => c.kind === "CHECK").map((c, i) => `CONSTRAINT chant_check_${String(i).padStart(4, "0")} ${c.body.replace(/^check /, "CHECK (").replace(/( no inherit| not enforced)*$/, ")$&")}`);
|
|
67
|
+
return rolledBack(client, defaultSchema, async () => {
|
|
68
|
+
await client.query(`CREATE TEMP TABLE chant_normalize (${[...defs, ...checks].join(", ")})`);
|
|
69
|
+
await emptyPath(client);
|
|
70
|
+
const cols = await client.query<Row>(
|
|
71
|
+
`SELECT a.attname AS name, a.attgenerated AS generated, pg_catalog.pg_get_expr(d.adbin, d.adrelid, true) AS expr
|
|
72
|
+
FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef d ON d.adrelid = a.attrelid AND d.adnum = a.attnum
|
|
73
|
+
WHERE a.attrelid = 'pg_temp.chant_normalize'::pg_catalog.regclass AND a.attnum > 0 AND NOT a.attisdropped`,
|
|
74
|
+
);
|
|
75
|
+
const cons = await client.query<Row>(
|
|
76
|
+
`SELECT c.conname AS name, pg_catalog.pg_get_constraintdef(c.oid, true) AS def FROM pg_catalog.pg_constraint c
|
|
77
|
+
WHERE c.conrelid = 'pg_temp.chant_normalize'::pg_catalog.regclass AND c.contype = 'c' ORDER BY c.conname`,
|
|
78
|
+
);
|
|
79
|
+
const defaults = new Map<string, string>();
|
|
80
|
+
const generated = new Map<string, string>();
|
|
81
|
+
for (const r of cols) {
|
|
82
|
+
if (r.expr === null || r.expr === undefined) continue;
|
|
83
|
+
if (r.generated === "s" || r.generated === "v") generated.set(String(r.name), `${r.generated === "s" ? "stored" : "virtual"} ${canonicalExpr(String(r.expr))}`);
|
|
84
|
+
else defaults.set(String(r.name), canonicalExpr(String(r.expr))!);
|
|
85
|
+
}
|
|
86
|
+
const printed = cons.map((r) => String(r.def).replace(/^CHECK /, "")).map((d) => canonicalExpr(d)!);
|
|
87
|
+
return { defaults, generated, checks: printed };
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The declared object with its expressions in the server's own printing,
|
|
93
|
+
* when the server answers; the object unchanged otherwise. Only the
|
|
94
|
+
* expressions are touched: everything else stays the rules'.
|
|
95
|
+
*/
|
|
96
|
+
export async function serverNormalized<T extends CanonicalPgObject & { outputs?: string[] }>(client: PostgresClient, o: T, defaultSchema: string): Promise<T> {
|
|
97
|
+
if ((o.kind === "view" || o.kind === "materializedView") && typeof o.fields.query === "string") {
|
|
98
|
+
const q = await viewQuery(client, o.fields.query, defaultSchema);
|
|
99
|
+
// A declared column list names the outputs; otherwise the server's names do (`SELECT *` expanded).
|
|
100
|
+
return q === undefined ? o : { ...o, fields: { ...o.fields, query: q.query }, ...(o.fields.columns === undefined ? { outputs: q.outputs } : {}) };
|
|
101
|
+
}
|
|
102
|
+
if (o.kind === "table") {
|
|
103
|
+
const e = await tableExpressions(client, o, defaultSchema);
|
|
104
|
+
if (!e) return o;
|
|
105
|
+
let i = 0;
|
|
106
|
+
return {
|
|
107
|
+
...o,
|
|
108
|
+
columns: o.columns.map((c) => ({
|
|
109
|
+
...c,
|
|
110
|
+
...(c.default !== undefined && e.defaults.has(c.name) && !/^(small|big)?serial$/.test(c.type ?? "") ? { default: e.defaults.get(c.name) } : {}),
|
|
111
|
+
...(c.generated !== undefined && e.generated.has(c.name) ? { generated: e.generated.get(c.name) } : {}),
|
|
112
|
+
})),
|
|
113
|
+
constraints: o.constraints.map((c) => {
|
|
114
|
+
if (c.kind !== "CHECK") return c;
|
|
115
|
+
const printed = e.checks[i++];
|
|
116
|
+
if (printed === undefined) return c;
|
|
117
|
+
const tail = /( no inherit| not enforced)*$/.exec(c.body)?.[0] ?? "";
|
|
118
|
+
return { ...c, body: `check ${printed}${tail}` };
|
|
119
|
+
}),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return o;
|
|
123
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { rds } from "./rds";
|
|
2
|
+
import { words, type ProviderData } from "./types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Amazon Aurora PostgreSQL. Roles and refused statements are RDS's (Aurora
|
|
6
|
+
* uses the same master-user model). The extension list is the table
|
|
7
|
+
* "Extensions supported for Aurora PostgreSQL 18" on the Aurora release-notes
|
|
8
|
+
* page, read 2026-10-03; package names were mapped to extension names as in
|
|
9
|
+
* rds.ts (h3-pg is `h3`, pgvector is `vector`, pg_roaringbitmap is
|
|
10
|
+
* `roaringbitmap`). Aurora adds apg_plan_mgmt, aurora_stat_utils, aws_ml,
|
|
11
|
+
* pg_ad_mapping and pg_columnmask.
|
|
12
|
+
*/
|
|
13
|
+
export const aurora: ProviderData = {
|
|
14
|
+
...rds,
|
|
15
|
+
provider: "aurora",
|
|
16
|
+
label: "Amazon Aurora PostgreSQL",
|
|
17
|
+
sources: [
|
|
18
|
+
{
|
|
19
|
+
url: "https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraPostgreSQL.Extensions.html",
|
|
20
|
+
readOn: "2026-10-03",
|
|
21
|
+
covers: "allowedExtensions (Aurora PostgreSQL 18 table)",
|
|
22
|
+
},
|
|
23
|
+
...rds.sources.filter((s) => s.covers !== "allowedExtensions (major 18 table)"),
|
|
24
|
+
],
|
|
25
|
+
allowedExtensions: words(`
|
|
26
|
+
address_standardizer address_standardizer_data_us amcheck apg_plan_mgmt aurora_stat_utils auto_explain autoinc
|
|
27
|
+
aws_commons aws_lambda aws_ml aws_s3 bloom bool_plperl btree_gin btree_gist citext cube dblink dict_int dict_xsyn
|
|
28
|
+
earthdistance fuzzystrmatch h3 h3_postgis hll hstore hstore_plperl hypopg insert_username intagg intarray ip4r isn
|
|
29
|
+
jsonb_plperl lo log_fdw ltree moddatetime mysql_fdw oracle_fdw orafce pg_ad_mapping pg_bigm pg_buffercache
|
|
30
|
+
pg_columnmask pg_cron pg_freespacemap pg_hint_plan pg_partman pg_prewarm pg_proctab pg_repack pg_similarity
|
|
31
|
+
pg_stat_statements pg_tle pg_trgm pg_visibility pgaudit pgcrypto pgdam pglogical pgrouting pgrowlocks pgstattuple
|
|
32
|
+
pgtap plcoffee plls plperl plpgsql plprofiler pltcl plv8 postgis postgis_raster postgis_tiger_geocoder
|
|
33
|
+
postgis_topology postgres_fdw prefix rdkit rds_activity_stream rds_tools refint roaringbitmap seg sslinfo
|
|
34
|
+
tablefunc tcn tds_fdw tsm_system_rows tsm_system_time unaccent uuid-ossp vector wal2json
|
|
35
|
+
`),
|
|
36
|
+
providerExtensions: [
|
|
37
|
+
"apg_plan_mgmt", "aurora_stat_utils", "aws_commons", "aws_lambda", "aws_ml", "aws_s3", "log_fdw",
|
|
38
|
+
"pg_ad_mapping", "pg_columnmask", "pgdam", "rds_activity_stream", "rds_tools",
|
|
39
|
+
],
|
|
40
|
+
toCheck: [
|
|
41
|
+
"per-release differences inside major 18, and the other majors' tables",
|
|
42
|
+
"pgdam and pg_columnmask were listed by the page with no description read",
|
|
43
|
+
...rds.toCheck.filter((t) => !t.startsWith("per-major")),
|
|
44
|
+
],
|
|
45
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { words, COMMON_REFUSED, type ProviderData } from "./types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Azure Database for PostgreSQL flexible server. The extension list is "List
|
|
5
|
+
* of extensions and modules by name", the entries available on major 18,
|
|
6
|
+
* read 2026-10-03. Besides being on that list, an extension must be allow-
|
|
7
|
+
* listed in the server's `azure.extensions` parameter before CREATE EXTENSION
|
|
8
|
+
* succeeds, and some also need `shared_preload_libraries`; that is server
|
|
9
|
+
* configuration, not something the list says, so it is not modelled.
|
|
10
|
+
* Roles are the three the access-control page names: azure_pg_admin (the
|
|
11
|
+
* pseudo-superuser the administrator belongs to), azuresu (Microsoft's
|
|
12
|
+
* control-plane superuser) and the administrator role the customer names.
|
|
13
|
+
*/
|
|
14
|
+
export const azure: ProviderData = {
|
|
15
|
+
provider: "azure",
|
|
16
|
+
label: "Azure Database for PostgreSQL flexible server",
|
|
17
|
+
sources: [
|
|
18
|
+
{
|
|
19
|
+
url: "https://learn.microsoft.com/en-us/azure/postgresql/extensions/concepts-extensions-versions",
|
|
20
|
+
readOn: "2026-10-03",
|
|
21
|
+
covers: "allowedExtensions (entries with a major 18 version)",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
url: "https://learn.microsoft.com/en-us/azure/postgresql/security/security-access-control",
|
|
25
|
+
readOn: "2026-10-03",
|
|
26
|
+
covers: "reservedRoles (azure_pg_admin, azuresu); the public schema is owned by azure_pg_admin",
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
reservedRoles: ["azure_pg_admin", "azuresu"],
|
|
30
|
+
reservedSchemas: [],
|
|
31
|
+
allowedExtensions: words(`
|
|
32
|
+
address_standardizer address_standardizer_data_us age amcheck anon auto_explain azure_ai azure_storage bloom
|
|
33
|
+
btree_gin btree_gist citext credcheck cube dblink dict_int dict_xsyn earthdistance fuzzystrmatch hll hstore hypopg
|
|
34
|
+
intagg intarray ip4r isn lo login_hook ltree oracle_fdw orafce pageinspect pgaudit pg_buffercache pg_cron pgcrypto
|
|
35
|
+
pg_diskann pg_failover_slots pg_freespacemap pg_hint_plan pg_ivm pglogical pg_partman pg_partman_bgw pg_prewarm
|
|
36
|
+
pg_repack pgrouting pgrowlocks pg_squeeze pg_stat_statements pgstattuple pg_trgm pg_visibility plpgsql
|
|
37
|
+
plpgsql_check plv8 pointcloud postgis postgis_raster postgis_sfcgal postgis_tiger_geocoder postgis_topology
|
|
38
|
+
postgres_fdw postgres_protobuf rdkit semver session_variable sslinfo tablefunc tdigest tds_fdw temporal_tables
|
|
39
|
+
timescaledb topn tsm_system_rows tsm_system_time unaccent uuid-ossp vector wal2json
|
|
40
|
+
`),
|
|
41
|
+
extensionListComplete: true,
|
|
42
|
+
providerExtensions: ["azure_ai", "azure_storage", "pg_diskann"],
|
|
43
|
+
refusedStatements: [
|
|
44
|
+
...COMMON_REFUSED,
|
|
45
|
+
{ id: "alter-azure-pg-admin", pattern: /^(ALTER|DROP) (ROLE|USER) "?AZURE_PG_ADMIN"?\b/, reason: "azure_pg_admin is a system-managed restricted role and cannot be modified" },
|
|
46
|
+
{ id: "grant-to-azure-pg-admin", pattern: /^GRANT\b.*\bTO "?AZURE_PG_ADMIN"?\b/, reason: "azure_pg_admin is a system-managed restricted role; granting membership in it is refused" },
|
|
47
|
+
],
|
|
48
|
+
toCheck: [
|
|
49
|
+
"the azure.extensions allowlist parameter and shared_preload_libraries needs: https://learn.microsoft.com/en-us/azure/postgresql/extensions/how-to-allow-extensions (the page rendered no body)",
|
|
50
|
+
"reservedSchemas: none read from a page: https://learn.microsoft.com/en-us/azure/postgresql/security/security-access-control",
|
|
51
|
+
"wal2json and pg_partman_bgw are logical-decoding or background-worker modules that may not take CREATE EXTENSION: https://learn.microsoft.com/en-us/azure/postgresql/extensions/concepts-extensions-versions",
|
|
52
|
+
"older majors' lists",
|
|
53
|
+
],
|
|
54
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { words, COMMON_REFUSED, type ProviderData } from "./types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Google Cloud SQL for PostgreSQL. The extension list is the tables on
|
|
5
|
+
* "Configure PostgreSQL extensions" (PostGIS, data type, language and
|
|
6
|
+
* miscellaneous groups), read 2026-10-03. Names are the `CREATE EXTENSION`
|
|
7
|
+
* names: the page's pgAudit is `pgaudit`, pgTAP is `pgtap`, pgvector is
|
|
8
|
+
* `vector`. The page says a customer cannot create their own extensions.
|
|
9
|
+
* Roles are the `cloudsql*` names the Cloud SQL users page lists.
|
|
10
|
+
*/
|
|
11
|
+
export const cloudSql: ProviderData = {
|
|
12
|
+
provider: "cloud-sql",
|
|
13
|
+
label: "Google Cloud SQL for PostgreSQL",
|
|
14
|
+
sources: [
|
|
15
|
+
{ url: "https://cloud.google.com/sql/docs/postgres/extensions", readOn: "2026-10-03", covers: "allowedExtensions, superuser requirement" },
|
|
16
|
+
{ url: "https://cloud.google.com/sql/docs/postgres/users", readOn: "2026-10-03", covers: "reservedRoles (the cloudsql* roles)" },
|
|
17
|
+
],
|
|
18
|
+
reservedRoles: [
|
|
19
|
+
"cloudsqlsuperuser", "cloudsqladmin", "cloudsqlagent", "cloudsqlconnpooladmin", "cloudsqliamgroup",
|
|
20
|
+
"cloudsqliamgroupserviceaccount", "cloudsqliamgroupuser", "cloudsqliamserviceaccount", "cloudsqliamuser",
|
|
21
|
+
"cloudsqlimportexport", "cloudsqlinactiveuser", "cloudsqllogical", "cloudsqlobservability", "cloudsqlreplica",
|
|
22
|
+
],
|
|
23
|
+
reservedSchemas: [],
|
|
24
|
+
allowedExtensions: words(`
|
|
25
|
+
address_standardizer address_standardizer_data_us amcheck auto_explain autoinc bloom btree_gin btree_gist chkpass
|
|
26
|
+
citext cube dblink dict_int earthdistance fuzzystrmatch google_ml_integration google_read_only_session hll hstore
|
|
27
|
+
insert_username intagg intarray ip4r isn lo ltree moddatetime oracle_fdw orafce pageinspect pg_background pg_bigm
|
|
28
|
+
pg_buffercache pg_cron pg_freespacemap pg_hint_plan pg_ivm pg_partman pg_prewarm pg_proctab pg_qualstats pg_repack
|
|
29
|
+
pg_similarity pg_squeeze pg_stat_statements pg_textsearch pg_trgm pg_visibility pg_wait_sampling pgaudit pgcrypto
|
|
30
|
+
pgfincore pglogical pgrowlocks pgstattuple pgtap pgtt plpgsql plpgsql_check plv8 postgis postgis_raster
|
|
31
|
+
postgis_sfcgal postgis_tiger_geocoder postgis_topology postgres_fdw prefix rdkit roaringbitmap sslinfo tablefunc
|
|
32
|
+
tcn tds_fdw temporal_tables tsm_system_rows tsm_system_time unaccent uuid-ossp vector
|
|
33
|
+
`),
|
|
34
|
+
extensionListComplete: true,
|
|
35
|
+
providerExtensions: ["google_ml_integration", "google_read_only_session"],
|
|
36
|
+
refusedStatements: COMMON_REFUSED,
|
|
37
|
+
toCheck: [
|
|
38
|
+
"anon (the page lists postgresql_anonymizer; the CREATE EXTENSION name was not read): https://cloud.google.com/sql/docs/postgres/extensions",
|
|
39
|
+
"the list is for the newest major; older majors drop some entries",
|
|
40
|
+
"reservedSchemas: no page read names a schema Cloud SQL owns: https://cloud.google.com/sql/docs/postgres/users",
|
|
41
|
+
],
|
|
42
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Managed-provider knowledge for the Postgres dialect (#3282): which roles
|
|
3
|
+
* and schemas a provider owns, which extensions it lets a customer create,
|
|
4
|
+
* and which statements it refuses. See ./types.ts for what a list means and
|
|
5
|
+
* how stale one can be.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { aurora } from "./aurora";
|
|
9
|
+
import { azure } from "./azure";
|
|
10
|
+
import { cloudSql } from "./cloud-sql";
|
|
11
|
+
import { neon } from "./neon";
|
|
12
|
+
import { rds } from "./rds";
|
|
13
|
+
import { supabase } from "./supabase";
|
|
14
|
+
import { POSTGRES_PROVIDERS, type PostgresProvider, type ProviderData, type RefusedStatement } from "./types";
|
|
15
|
+
|
|
16
|
+
export { POSTGRES_PROVIDERS, COMMON_REFUSED } from "./types";
|
|
17
|
+
export type { PostgresProvider, ProviderData, ProviderSource, RefusedStatement, ProviderSetting } from "./types";
|
|
18
|
+
|
|
19
|
+
const DATA: Record<PostgresProvider, ProviderData> = {
|
|
20
|
+
rds,
|
|
21
|
+
aurora,
|
|
22
|
+
"cloud-sql": cloudSql,
|
|
23
|
+
azure,
|
|
24
|
+
neon,
|
|
25
|
+
supabase,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** The data for one provider. */
|
|
29
|
+
export function providerData(provider: PostgresProvider): ProviderData {
|
|
30
|
+
return DATA[provider];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const isPostgresProvider = (v: unknown): v is PostgresProvider =>
|
|
34
|
+
typeof v === "string" && (POSTGRES_PROVIDERS as readonly string[]).includes(v);
|
|
35
|
+
|
|
36
|
+
/** Role and schema names fold to lower case unless quoted; the lists are lower case. */
|
|
37
|
+
const fold = (name: string) => name.toLowerCase();
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Whether the provider lets a customer create the extension. `undefined` when
|
|
41
|
+
* the provider's list is partial and does not name it: the answer is unknown,
|
|
42
|
+
* not no.
|
|
43
|
+
*/
|
|
44
|
+
export function providerAllowsExtension(provider: PostgresProvider, name: string): boolean | undefined {
|
|
45
|
+
const data = DATA[provider];
|
|
46
|
+
if (data.allowedExtensions.includes(fold(name))) return true;
|
|
47
|
+
return data.extensionListComplete ? false : undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** A live object as import or describe sees it: its kind and name, schema-less for roles, schemas and extensions. */
|
|
51
|
+
export interface LiveObjectRef {
|
|
52
|
+
kind: "role" | "schema" | "extension";
|
|
53
|
+
name: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Whether the provider owns a live object, so import and describe can read it
|
|
58
|
+
* as foreign (not the project's to declare or change). A role or schema the
|
|
59
|
+
* provider created, an extension the provider installs, or a `pg_` built-in
|
|
60
|
+
* role. Names are compared case-folded.
|
|
61
|
+
*/
|
|
62
|
+
export function isProviderOwned(provider: PostgresProvider, object: LiveObjectRef): boolean {
|
|
63
|
+
const data = DATA[provider];
|
|
64
|
+
const name = fold(object.name);
|
|
65
|
+
switch (object.kind) {
|
|
66
|
+
case "role":
|
|
67
|
+
return data.reservedRoles.includes(name) || name.startsWith("pg_");
|
|
68
|
+
case "schema":
|
|
69
|
+
return data.reservedSchemas.includes(name);
|
|
70
|
+
case "extension":
|
|
71
|
+
return data.providerExtensions.includes(name);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Reduce a statement to what the refused-statement patterns match: comments and strings removed, upper case, whitespace collapsed. */
|
|
76
|
+
export function normalizeStatement(sql: string): string {
|
|
77
|
+
return sql
|
|
78
|
+
.replace(/\/\*[\s\S]*?\*\//g, " ")
|
|
79
|
+
.replace(/--[^\n]*/g, " ")
|
|
80
|
+
.replace(/'(?:[^']|'')*'/g, "''")
|
|
81
|
+
.replace(/\s+/g, " ")
|
|
82
|
+
.trim()
|
|
83
|
+
.toUpperCase();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The refused-statement entry a statement matches on the provider, if any. */
|
|
87
|
+
export function refusedStatement(provider: PostgresProvider, sql: string): RefusedStatement | undefined {
|
|
88
|
+
const text = normalizeStatement(sql);
|
|
89
|
+
return DATA[provider].refusedStatements.find((r) => r.pattern.test(text));
|
|
90
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { words, COMMON_REFUSED, type ProviderData } from "./types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Neon. The extension list is the "Postgres extensions" table, the entries
|
|
5
|
+
* with a PG18 version (entries marked `-` for PG18, such as plv8, rum and
|
|
6
|
+
* pg_search, are left out), read 2026-10-03. Table names were mapped to
|
|
7
|
+
* `CREATE EXTENSION` names where the page says so: pgvector is `vector`,
|
|
8
|
+
* pg_roaringbitmap is `roaringbitmap`. wal2json is a decoder plugin the page
|
|
9
|
+
* says needs no CREATE EXTENSION, so it is not listed. Reserved roles are
|
|
10
|
+
* the "Reserved role names" list plus neon_service, which the roles page
|
|
11
|
+
* describes as internal.
|
|
12
|
+
*/
|
|
13
|
+
export const neon: ProviderData = {
|
|
14
|
+
provider: "neon",
|
|
15
|
+
label: "Neon",
|
|
16
|
+
sources: [
|
|
17
|
+
{ url: "https://neon.com/docs/extensions/pg-extensions", readOn: "2026-10-03", covers: "allowedExtensions (PG18 column)" },
|
|
18
|
+
{ url: "https://neon.com/docs/manage/roles", readOn: "2026-10-03", covers: "reservedRoles, neon_superuser, internal roles" },
|
|
19
|
+
{ url: "https://neon.com/docs/reference/compatibility", readOn: "2026-10-03", covers: "no superuser, no tablespaces" },
|
|
20
|
+
],
|
|
21
|
+
reservedRoles: ["neon_superuser", "cloud_admin", "zenith_admin", "neon_service"],
|
|
22
|
+
reservedSchemas: [],
|
|
23
|
+
allowedExtensions: words(`
|
|
24
|
+
address_standardizer address_standardizer_data_us anon autoinc bloom btree_gin btree_gist citext cube dblink
|
|
25
|
+
dict_int earthdistance fuzzystrmatch h3 h3_postgis hll hstore hypopg insert_username intagg intarray ip4r isn
|
|
26
|
+
lakebase_text lakebase_tokenizer lakebase_vector lo ltree moddatetime neon neon_utils pg_cron pg_graphql
|
|
27
|
+
pg_hashids pg_hint_plan pg_ivm pg_jsonschema pg_partman pg_prewarm pg_repack pg_session_jwt pg_stat_statements
|
|
28
|
+
pg_tiktoken pg_trgm pg_uuidv7 pgcrypto pgjwt pgrag pgrouting pgrowlocks pgstattuple pgtap pgx_ulid plpgsql
|
|
29
|
+
plpgsql_check postgis postgis_raster postgis_sfcgal postgis_tiger_geocoder postgis_topology postgres_fdw prefix
|
|
30
|
+
rdkit refint roaringbitmap seg semver tablefunc tcn timescaledb tsm_system_rows tsm_system_time unaccent
|
|
31
|
+
uuid-ossp vector xml2
|
|
32
|
+
`),
|
|
33
|
+
extensionListComplete: true,
|
|
34
|
+
providerExtensions: ["neon", "neon_utils", "pg_session_jwt", "lakebase_text", "lakebase_tokenizer", "lakebase_vector"],
|
|
35
|
+
refusedStatements: [
|
|
36
|
+
...COMMON_REFUSED,
|
|
37
|
+
{ id: "create-tablespace", pattern: /^CREATE TABLESPACE\b/, reason: "Neon does not support tablespaces" },
|
|
38
|
+
{ id: "alter-neon-superuser", pattern: /^(ALTER|DROP) (ROLE|USER) "?NEON_SUPERUSER"?\b/, reason: "neon_superuser is not intended to be modified" },
|
|
39
|
+
],
|
|
40
|
+
toCheck: [
|
|
41
|
+
"reservedSchemas: none read from a page: https://neon.com/docs/manage/roles",
|
|
42
|
+
"pg_repack needs a paid plan and Neon Support to enable, pg_ivm is not available for new installs: https://neon.com/docs/extensions/pg-extensions",
|
|
43
|
+
"older majors' columns",
|
|
44
|
+
],
|
|
45
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
POSTGRES_PROVIDERS,
|
|
4
|
+
isProviderOwned,
|
|
5
|
+
providerAllowsExtension,
|
|
6
|
+
providerData,
|
|
7
|
+
refusedStatement,
|
|
8
|
+
normalizeStatement,
|
|
9
|
+
type PostgresProvider,
|
|
10
|
+
} from "./index";
|
|
11
|
+
|
|
12
|
+
describe("every provider's data", () => {
|
|
13
|
+
test.each(POSTGRES_PROVIDERS)("%s cites a page and the date it was read, and its lists are lower case and unique", (p) => {
|
|
14
|
+
const d = providerData(p);
|
|
15
|
+
expect(d.provider).toBe(p);
|
|
16
|
+
expect(d.sources.length).toBeGreaterThan(0);
|
|
17
|
+
for (const s of d.sources) {
|
|
18
|
+
expect(s.url).toMatch(/^https:\/\//);
|
|
19
|
+
expect(s.readOn).toMatch(/^2026-10-03$/);
|
|
20
|
+
}
|
|
21
|
+
for (const list of [d.reservedRoles, d.reservedSchemas, d.allowedExtensions, d.providerExtensions]) {
|
|
22
|
+
expect(list.every((n) => n === n.toLowerCase())).toBe(true);
|
|
23
|
+
expect(new Set(list).size).toBe(list.length);
|
|
24
|
+
}
|
|
25
|
+
expect(d.allowedExtensions.length).toBeGreaterThan(10);
|
|
26
|
+
for (const t of d.toCheck) expect(t.length).toBeGreaterThan(0);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("every provider refuses what needs a superuser", () => {
|
|
30
|
+
for (const p of POSTGRES_PROVIDERS) {
|
|
31
|
+
expect(refusedStatement(p, "CREATE ROLE admin SUPERUSER")?.id).toBe("superuser-role");
|
|
32
|
+
expect(refusedStatement(p, "copy t from program 'curl x'")?.id).toBe("copy-program");
|
|
33
|
+
expect(refusedStatement(p, "CREATE TABLE t (a int)")).toBeUndefined();
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
interface Fixture {
|
|
39
|
+
provider: PostgresProvider;
|
|
40
|
+
allowed: string[];
|
|
41
|
+
refused: string[];
|
|
42
|
+
ownedRole: string;
|
|
43
|
+
ownedExtension: string;
|
|
44
|
+
ownedSchema?: string;
|
|
45
|
+
refusedStatement?: [string, string];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const FIXTURES: Fixture[] = [
|
|
49
|
+
{
|
|
50
|
+
provider: "rds",
|
|
51
|
+
allowed: ["pg_stat_statements", "pgcrypto", "vector", "postgis", "aws_s3"],
|
|
52
|
+
refused: ["pg_squeeze", "pg_ivm", "timescaledb"],
|
|
53
|
+
ownedRole: "rds_superuser",
|
|
54
|
+
ownedExtension: "aws_s3",
|
|
55
|
+
refusedStatement: ["CREATE TABLESPACE fast LOCATION '/ssd'", "create-tablespace-location"],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
provider: "aurora",
|
|
59
|
+
allowed: ["pg_stat_statements", "apg_plan_mgmt", "aws_ml", "vector", "pgaudit"],
|
|
60
|
+
refused: ["pg_squeeze", "timescaledb"],
|
|
61
|
+
ownedRole: "rdsadmin",
|
|
62
|
+
ownedExtension: "apg_plan_mgmt",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
provider: "cloud-sql",
|
|
66
|
+
allowed: ["pg_trgm", "vector", "uuid-ossp", "pgaudit", "postgis"],
|
|
67
|
+
refused: ["aws_s3", "timescaledb"],
|
|
68
|
+
ownedRole: "cloudsqlsuperuser",
|
|
69
|
+
ownedExtension: "google_ml_integration",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
provider: "azure",
|
|
73
|
+
allowed: ["pg_trgm", "vector", "azure_ai", "timescaledb", "uuid-ossp"],
|
|
74
|
+
refused: ["aws_s3", "pg_stat_monitor"],
|
|
75
|
+
ownedRole: "azure_pg_admin",
|
|
76
|
+
ownedExtension: "azure_storage",
|
|
77
|
+
refusedStatement: ["GRANT dba TO azure_pg_admin", "grant-to-azure-pg-admin"],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
provider: "neon",
|
|
81
|
+
allowed: ["pg_trgm", "vector", "neon", "pg_graphql", "timescaledb"],
|
|
82
|
+
refused: ["pg_squeeze", "plv8", "wal2json"],
|
|
83
|
+
ownedRole: "neon_superuser",
|
|
84
|
+
ownedExtension: "neon_utils",
|
|
85
|
+
refusedStatement: ["create tablespace t location '/x'", "create-tablespace"],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
provider: "supabase",
|
|
89
|
+
allowed: ["pg_graphql", "vector", "pgtap", "uuid-ossp"],
|
|
90
|
+
refused: [],
|
|
91
|
+
ownedRole: "supabase_admin",
|
|
92
|
+
ownedExtension: "pg_net",
|
|
93
|
+
ownedSchema: "auth",
|
|
94
|
+
},
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
describe.each(FIXTURES)("$provider", (f) => {
|
|
98
|
+
test("allows the extensions its page lists", () => {
|
|
99
|
+
for (const e of f.allowed) expect(providerAllowsExtension(f.provider, e), e).toBe(true);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("an extension its page does not list is refused, or unknown when the list is partial", () => {
|
|
103
|
+
for (const e of f.refused) expect(providerAllowsExtension(f.provider, e), e).toBe(false);
|
|
104
|
+
const partial = !providerData(f.provider).extensionListComplete;
|
|
105
|
+
expect(providerAllowsExtension(f.provider, "not_an_extension")).toBe(partial ? undefined : false);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test("reads its own roles, schemas and extensions as provider-owned, and a customer's as not", () => {
|
|
109
|
+
expect(isProviderOwned(f.provider, { kind: "role", name: f.ownedRole })).toBe(true);
|
|
110
|
+
expect(isProviderOwned(f.provider, { kind: "role", name: f.ownedRole.toUpperCase() })).toBe(true);
|
|
111
|
+
expect(isProviderOwned(f.provider, { kind: "role", name: "pg_monitor" })).toBe(true);
|
|
112
|
+
expect(isProviderOwned(f.provider, { kind: "role", name: "app_owner" })).toBe(false);
|
|
113
|
+
expect(isProviderOwned(f.provider, { kind: "extension", name: f.ownedExtension })).toBe(true);
|
|
114
|
+
expect(isProviderOwned(f.provider, { kind: "extension", name: "pgcrypto" })).toBe(false);
|
|
115
|
+
expect(isProviderOwned(f.provider, { kind: "schema", name: "app" })).toBe(false);
|
|
116
|
+
if (f.ownedSchema) expect(isProviderOwned(f.provider, { kind: "schema", name: f.ownedSchema })).toBe(true);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
if (f.refusedStatement) {
|
|
120
|
+
test("refuses its own statements", () => {
|
|
121
|
+
expect(refusedStatement(f.provider, f.refusedStatement![0])?.id).toBe(f.refusedStatement![1]);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe("normalizeStatement", () => {
|
|
127
|
+
test("drops comments and string contents, collapses whitespace and upper-cases", () => {
|
|
128
|
+
expect(normalizeStatement("/* x */ alter system -- c\n set a = 'ALTER SYSTEM'")).toBe("ALTER SYSTEM SET A = ''");
|
|
129
|
+
});
|
|
130
|
+
test("a string that names a refused statement does not match", () => {
|
|
131
|
+
expect(refusedStatement("rds", "COMMENT ON TABLE t IS 'ALTER SYSTEM is refused'")).toBeUndefined();
|
|
132
|
+
});
|
|
133
|
+
test("ALTER SYSTEM is refused", () => {
|
|
134
|
+
expect(refusedStatement("neon", "ALTER SYSTEM SET work_mem = '1GB'")?.id).toBe("alter-system");
|
|
135
|
+
});
|
|
136
|
+
});
|