@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,81 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { sqlPlugin } from "./plugin";
|
|
4
|
+
|
|
5
|
+
describe("skills", () => {
|
|
6
|
+
const skills = sqlPlugin.skills!();
|
|
7
|
+
|
|
8
|
+
test("six skills, each with its file's content and a matching frontmatter name", () => {
|
|
9
|
+
expect(skills.map((s) => s.name)).toEqual(["chant-sql", "chant-sql-plan", "chant-sql-rebuild", "chant-sql-postgres", "chant-sql-postgres-plan", "chant-sql-postgres-migration"]);
|
|
10
|
+
for (const s of skills) {
|
|
11
|
+
expect(s.content.length, s.name).toBeGreaterThan(500);
|
|
12
|
+
expect(s.content).toContain(`skill: ${s.name}\n`);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("the rebuild skill declares the shipped Op", () => {
|
|
17
|
+
const rebuild = skills.find((s) => s.name === "chant-sql-rebuild")!;
|
|
18
|
+
expect(rebuild.content).toContain('import { ClickHouseRebuildOp } from "@intentius/chant-lexicon-sql/clickhouse"');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("the Postgres skill cites only SQLPG ids that exist, and the ClickHouse skills none", async () => {
|
|
22
|
+
const { rules } = await import("./lint/rules");
|
|
23
|
+
const known = new Set<string>(rules.map((r) => r.id));
|
|
24
|
+
const pg = skills.find((s) => s.name === "chant-sql-postgres")!;
|
|
25
|
+
const ids = pg.content.match(/SQLPG\d{3}/g) ?? [];
|
|
26
|
+
expect(ids.length).toBeGreaterThan(0);
|
|
27
|
+
for (const id of ids) expect(known.has(id), id).toBe(true);
|
|
28
|
+
expect(pg.content).not.toMatch(/SQLCH\d{3}/);
|
|
29
|
+
for (const s of skills.filter((s) => !s.name.startsWith("chant-sql-postgres"))) {
|
|
30
|
+
if (["chant-sql", "chant-sql-plan", "chant-sql-rebuild"].includes(s.name)) expect(s.content, s.name).not.toMatch(/Postgres|SQLPG/);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("the Postgres plan skill cites only classifier rules that exist, names no ClickHouse rule, and stays Postgres-only", async () => {
|
|
35
|
+
const { PG_CLASSIFIER_RULES } = await import("./postgres/plan/rules");
|
|
36
|
+
const plan = skills.find((s) => s.name === "chant-sql-postgres-plan")!;
|
|
37
|
+
const ids = [...new Set(plan.content.match(/SQLPG2\d\d/g) ?? [])];
|
|
38
|
+
expect(ids.length).toBeGreaterThan(20);
|
|
39
|
+
for (const id of ids) expect(id in PG_CLASSIFIER_RULES, id).toBe(true);
|
|
40
|
+
expect(plan.content).not.toMatch(/SQLCH|ClickHouse|MergeTree/);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("every SQLPG0xx and SQLPG1xx id the Postgres skills cite is a lint rule or a post-synth check", async () => {
|
|
44
|
+
const { rules } = await import("./lint/rules");
|
|
45
|
+
const { postSynthChecks } = await import("./lint/post-synth");
|
|
46
|
+
const known = new Set<string>([...rules.map((r) => r.id), ...postSynthChecks.map((c) => c.id)]);
|
|
47
|
+
for (const s of skills.filter((s) => s.name.startsWith("chant-sql-postgres"))) {
|
|
48
|
+
for (const id of s.content.match(/SQLPG[01]\d\d/g) ?? []) expect(known.has(id), `${s.name}: ${id}`).toBe(true);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("every SQLCH id a skill cites exists in the lexicon", async () => {
|
|
53
|
+
const { rules } = await import("./lint/rules");
|
|
54
|
+
const { postSynthChecks } = await import("./lint/post-synth");
|
|
55
|
+
const known = new Set<string>([...rules.map((r) => r.id), ...postSynthChecks.map((c) => c.id)]);
|
|
56
|
+
for (const s of skills) {
|
|
57
|
+
// The SQLCH2xx ids are the classifier's, which come from the plan rules, not from a lint rule.
|
|
58
|
+
for (const id of s.content.match(/SQLCH0\d\d|SQLCH1\d\d/g) ?? []) expect(known.has(id), `${s.name}: ${id}`).toBe(true);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("the Postgres migration skill declares the shipped Op with options it has, and cites only rules that exist", async () => {
|
|
63
|
+
const { PG_CLASSIFIER_RULES } = await import("./postgres/plan/rules");
|
|
64
|
+
const src = readFileSync(new URL("./postgres/migrate/op.ts", import.meta.url), "utf8");
|
|
65
|
+
const iface = /export interface PostgresMigrationOpConfig \{([\s\S]*?)\n\}/.exec(src)![1]!;
|
|
66
|
+
const options = new Set([...iface.matchAll(/^ (\w+)\??:/gm)].map((m) => m[1]!));
|
|
67
|
+
const mig = skills.find((s) => s.name === "chant-sql-postgres-migration")!;
|
|
68
|
+
expect(mig.content).toContain('import { PostgresMigrationOp } from "@intentius/chant-lexicon-sql/postgres"');
|
|
69
|
+
// Every option named in the options list, and every key of a declaration, is on the Op's config.
|
|
70
|
+
const listed = [...mig.content.matchAll(/^- `(\w+)`(?: \(| and `(\w+)`|:)/gm)].flatMap((m) => [m[1], m[2]]).filter((x): x is string => !!x);
|
|
71
|
+
const declared = [...mig.content.matchAll(/PostgresMigrationOp\(\{([^}]*)\}\)/g), ...mig.content.matchAll(/PostgresMigrationOp\(\{([\s\S]*?)\n\}\)/g)]
|
|
72
|
+
.flatMap((m) => [...m[1]!.replace(/\/\/.*$/gm, "").matchAll(/(?:^|[\s,{])(\w+):/g)].map((k) => k[1]!));
|
|
73
|
+
expect(listed.length).toBeGreaterThan(5);
|
|
74
|
+
for (const o of [...listed, ...declared]) expect(options.has(o), o).toBe(true);
|
|
75
|
+
for (const o of ["env", "table", "column", "using", "batchSize", "retain", "replicationLag", "gate", "contractGate"]) expect(mig.content, o).toContain(`\`${o}\``);
|
|
76
|
+
const ids = [...new Set(mig.content.match(/SQLPG\d{3}/g) ?? [])];
|
|
77
|
+
expect(ids.length).toBeGreaterThan(1);
|
|
78
|
+
for (const id of ids) expect(id in PG_CLASSIFIER_RULES, id).toBe(true);
|
|
79
|
+
expect(mig.content).not.toMatch(/SQLCH|ClickHouse|MergeTree/);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { createSkillsLoader } from "@intentius/chant/lexicon-plugin-helpers";
|
|
2
|
+
|
|
3
|
+
/** The sql lexicon's AI skills, read from src/skills/. */
|
|
4
|
+
export const sqlSkills = createSkillsLoader(import.meta.url, [
|
|
5
|
+
{
|
|
6
|
+
file: "chant-sql.md",
|
|
7
|
+
name: "chant-sql",
|
|
8
|
+
description:
|
|
9
|
+
"Declare ClickHouse databases, tables, views and materialized views as SQL-shaped tagged templates, with references, lineage and the checks that run on them",
|
|
10
|
+
triggers: [
|
|
11
|
+
{ type: "context" as const, value: "clickhouse" },
|
|
12
|
+
{ type: "context" as const, value: "clickhouse schema" },
|
|
13
|
+
{ type: "context" as const, value: "materialized view" },
|
|
14
|
+
],
|
|
15
|
+
examples: [
|
|
16
|
+
{
|
|
17
|
+
title: "A table and a view that reads it",
|
|
18
|
+
output:
|
|
19
|
+
'export const analytics = database`CREATE DATABASE analytics ENGINE = Atomic`;\n' +
|
|
20
|
+
"export const events = table`CREATE TABLE ${analytics}.events (user_id UUID, ts DateTime) ENGINE = MergeTree ORDER BY (user_id, ts)`;\n" +
|
|
21
|
+
"export const recent = view`CREATE VIEW ${analytics}.recent AS SELECT ${events.columns.user_id} AS user_id FROM ${events}`;",
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
file: "chant-sql-plan.md",
|
|
27
|
+
name: "chant-sql-plan",
|
|
28
|
+
description:
|
|
29
|
+
"Plan ClickHouse schema changes with chant sql diff and chant sql plan, and read the three change classes (metadata only, background rewrite, rebuild) with the ALTER restriction behind each",
|
|
30
|
+
triggers: [
|
|
31
|
+
{ type: "context" as const, value: "clickhouse schema change" },
|
|
32
|
+
{ type: "context" as const, value: "sql plan" },
|
|
33
|
+
{ type: "context" as const, value: "alter table" },
|
|
34
|
+
],
|
|
35
|
+
examples: [
|
|
36
|
+
{
|
|
37
|
+
title: "Classify a pull request's schema change offline",
|
|
38
|
+
output: "chant sql diff base.json head.json",
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
file: "chant-sql-rebuild.md",
|
|
44
|
+
name: "chant-sql-rebuild",
|
|
45
|
+
description:
|
|
46
|
+
"Run a ClickHouse table rebuild (a sorting key, primary key, partition key, engine or key column type change) with ClickHouseRebuildOp, a gated Op with backfill receipts, verification, an exchange swap and onFailure cleanup",
|
|
47
|
+
triggers: [
|
|
48
|
+
{ type: "context" as const, value: "clickhouse rebuild" },
|
|
49
|
+
{ type: "context" as const, value: "change sorting key" },
|
|
50
|
+
{ type: "context" as const, value: "clickhouse migration" },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
file: "chant-sql-postgres.md",
|
|
55
|
+
name: "chant-sql-postgres",
|
|
56
|
+
description:
|
|
57
|
+
"Declare Postgres schemas, tables, constraints, indexes, views, sequences, enum and domain types and extensions as SQL-shaped tagged templates, with references, lineage and the SQLPG lint rules",
|
|
58
|
+
triggers: [
|
|
59
|
+
{ type: "context" as const, value: "postgres" },
|
|
60
|
+
{ type: "context" as const, value: "postgres schema" },
|
|
61
|
+
{ type: "context" as const, value: "postgresql" },
|
|
62
|
+
],
|
|
63
|
+
examples: [
|
|
64
|
+
{
|
|
65
|
+
title: "A table with a foreign key and an index",
|
|
66
|
+
output:
|
|
67
|
+
'export const app = schema`CREATE SCHEMA app`;\n' +
|
|
68
|
+
"export const users = table`CREATE TABLE ${app}.users (id bigint PRIMARY KEY)`;\n" +
|
|
69
|
+
"export const orders = table`CREATE TABLE ${app}.orders (id bigint PRIMARY KEY, user_id bigint NOT NULL REFERENCES ${users} (${users.columns.id}))`;\n" +
|
|
70
|
+
"export const ordersUser = index`CREATE INDEX orders_user_id_idx ON ${orders} (${orders.columns.user_id})`;",
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
file: "chant-sql-postgres-plan.md",
|
|
76
|
+
name: "chant-sql-postgres-plan",
|
|
77
|
+
description:
|
|
78
|
+
"Plan Postgres schema changes with chant sql diff and chant sql plan, and read the change classes (metadata only, validates, needs CONCURRENTLY, ACCESS EXCLUSIVE rewrite, expand and contract) as the lock each takes in production",
|
|
79
|
+
triggers: [
|
|
80
|
+
{ type: "context" as const, value: "postgres schema change" },
|
|
81
|
+
{ type: "context" as const, value: "postgres lock" },
|
|
82
|
+
{ type: "context" as const, value: "postgres migration" },
|
|
83
|
+
],
|
|
84
|
+
examples: [
|
|
85
|
+
{
|
|
86
|
+
title: "Classify a pull request's Postgres schema change offline",
|
|
87
|
+
output: "chant sql diff base.json head.json",
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
file: "chant-sql-postgres-migration.md",
|
|
93
|
+
name: "chant-sql-postgres-migration",
|
|
94
|
+
description:
|
|
95
|
+
"Run a Postgres column rename or type change with PostgresMigrationOp, a gated expand-and-contract Op with a dual-write trigger, a batched backfill with receipts, verification, a switch, replication lag handling and onFailure cleanup",
|
|
96
|
+
triggers: [
|
|
97
|
+
{ type: "context" as const, value: "postgres column rename" },
|
|
98
|
+
{ type: "context" as const, value: "postgres expand and contract" },
|
|
99
|
+
{ type: "context" as const, value: "postgres backfill" },
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
]);
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: chant-sql-plan
|
|
3
|
+
description: Plan ClickHouse schema changes with chant sql diff and chant sql plan, and read the three change classes (metadata only, background rewrite, rebuild) with the ALTER restriction behind each
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
# Planning and applying ClickHouse schema changes
|
|
7
|
+
|
|
8
|
+
Use this skill when a declared ClickHouse schema changes and you need to know what the change does to the server before anything runs. This skill covers what exists today: the offline diff, the plan against a live server, and the change classifier. The applier and the rebuild are described at the end with their current state.
|
|
9
|
+
|
|
10
|
+
## Two commands
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
chant sql diff base.json head.json # two chant build outputs, offline
|
|
14
|
+
chant sql plan prod dist/schema.json # a build output against the prod server
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`chant sql diff` compares a pull request's base and head builds and needs no server. `chant sql plan <env>` reads the server that `sql.profiles.<env>` binds in `chant.config.ts`, and compares the build with it. Add `--json` to either for a machine-readable report.
|
|
18
|
+
|
|
19
|
+
Both exit 2 when any change needs a rebuild, and 0 otherwise, so either can gate a pipeline.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// chant.config.ts
|
|
23
|
+
import type { ChantConfig } from "@intentius/chant/config";
|
|
24
|
+
import "@intentius/chant-lexicon-sql";
|
|
25
|
+
|
|
26
|
+
export default {
|
|
27
|
+
lexicons: ["sql"],
|
|
28
|
+
sql: {
|
|
29
|
+
profiles: {
|
|
30
|
+
prod: {
|
|
31
|
+
url: "https://clickhouse.example.com:8443",
|
|
32
|
+
user: { env: "CH_USER" },
|
|
33
|
+
password: { env: "CH_PROD_PASSWORD" },
|
|
34
|
+
databases: ["analytics"],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
} satisfies ChantConfig;
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Credentials are named by environment variable and never written into the config.
|
|
42
|
+
|
|
43
|
+
## The three change classes
|
|
44
|
+
|
|
45
|
+
| Class | Means | Examples |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| metadata only | the server records the change and touches no existing data | add a column (SQLCH201), change a default (SQLCH207), add a skip index (SQLCH204), rename a column outside the keys (SQLCH212), change a materialized view's query (SQLCH241) |
|
|
48
|
+
| background rewrite | a mutation rewrites existing parts in the background, with no rollback | change a TTL (SQLCH205), change the type of a column outside the primary key (SQLCH210) |
|
|
49
|
+
| rebuild | ClickHouse cannot make the change to the existing table; the data has to be copied into a new one | change the sorting key beyond appending new columns (SQLCH220), the partition key (SQLCH222), the engine or its arguments (SQLCH223), a materialized view's `TO` target (SQLCH242) |
|
|
50
|
+
|
|
51
|
+
Every rule has an id in the SQLCH2xx range, names its class, and cites the ClickHouse documentation page that states the restriction. The full table is on the "Planning and the Change Classifier" page of the sql docs, written from the rules, so read the page rather than recalling a class from memory.
|
|
52
|
+
|
|
53
|
+
Two classes of change are not what they look like:
|
|
54
|
+
|
|
55
|
+
- A metadata-only drop (SQLCH202) is not reversible: the column's data is removed from every part.
|
|
56
|
+
- A TTL change (SQLCH205) looks like metadata, but with `materialize_ttl_after_modify` on (the default) the server recalculates the TTL over existing data as a mutation.
|
|
57
|
+
|
|
58
|
+
`chant lifecycle plan` reports the same classification as each update's disruption: metadata only is `in-place`, a rewrite is `rolling`, a rebuild is `replace`. For a column type or a sorting key change the lifecycle plan reports `unknown`, since deciding needs the whole definition; `chant sql plan` classifies those.
|
|
59
|
+
|
|
60
|
+
## Identity and renames
|
|
61
|
+
|
|
62
|
+
Between two builds an object is its export name, so a changed SQL name under the same export is a rename (`RENAME TABLE`, metadata only on an Atomic database). Against a server, which has no export names, an object is `database.name`. To rename something the server already has, put a comment before its CREATE:
|
|
63
|
+
|
|
64
|
+
```sql
|
|
65
|
+
-- previously: events_raw
|
|
66
|
+
CREATE TABLE analytics.events (...)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
A column is its name. Declare a rename on the column's own line:
|
|
70
|
+
|
|
71
|
+
```sql
|
|
72
|
+
event_kind LowCardinality(String), -- previously: kind
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Without the hint, a rename plans as a drop and an add, and the report says so when the two have the same type and position. A drop is destructive, so add the hint.
|
|
76
|
+
|
|
77
|
+
## No false drift
|
|
78
|
+
|
|
79
|
+
The server rewrites DDL on `SHOW CREATE` (quoting, `INTERVAL 1 DAY` as `toIntervalDay(1)`, default codec levels, settings at their default). The plan undoes those rewrites with normalization rules, and asks the server's own formatter about any expression the rules leave different, so formatting alone is not reported as a change. `chant lifecycle diff <env> --live` reads property-level drift with the same normalization.
|
|
80
|
+
|
|
81
|
+
## Reading a plan in a pull request
|
|
82
|
+
|
|
83
|
+
1. `chant build src --lexicon sql -o head.json` on the pull request branch, and the same on the base branch into `base.json`.
|
|
84
|
+
2. `chant sql diff base.json head.json`.
|
|
85
|
+
3. A rebuild exits 2. Do not merge it as an ordinary change: the report names the `ClickHouseRebuildOp` declaration to add for each refused table (`rebuildOps` in `--json`), and the rebuild runs as that Op (`chant-sql-rebuild`).
|
|
86
|
+
|
|
87
|
+
## Using plans in Ops
|
|
88
|
+
|
|
89
|
+
The sql lexicon does not yet export step builders for these commands. Until it does, an Op can run them with `shell` and gate on the result:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { Op, phase, build, shell, gate } from "@intentius/chant/op";
|
|
93
|
+
|
|
94
|
+
export default Op({
|
|
95
|
+
name: "schema-plan",
|
|
96
|
+
overview: "Build the schema, plan it against prod, stop for approval",
|
|
97
|
+
phases: [
|
|
98
|
+
phase("Plan", [
|
|
99
|
+
build("src"),
|
|
100
|
+
shell("chant sql plan prod dist/schema.json --json", { json: true }),
|
|
101
|
+
]),
|
|
102
|
+
phase("Approve", [gate("approve-schema-plan")]),
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Resolve the gate with `chant approve approve-schema-plan`. The MCP server's `op-run`, `op-status` and `op-signal` tools start and watch the same Op.
|
|
108
|
+
|
|
109
|
+
## Applying
|
|
110
|
+
|
|
111
|
+
`ApplyOp` with `target: "clickhouse"` applies a build (`dist/schema.json`) to the server `sql.profiles.<env>` binds, through the sql lexicon's `clickhouseApply`. It makes the metadata-only and background-rewrite changes with `ALTER`, waits on `system.mutations` for a rewrite, and stamps chant's ownership marker on each object's comment. It reports a rebuild as not attempted (`unsupported-kind`, with the rule and the ALTER restriction in the detail) and sends nothing for that object, and withholds a column drop unless the Op may delete (`delete: "owned-only"` or `"gated"`). Prune drops only objects whose comment carries the project's marker.
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { ApplyOp } from "@intentius/chant/op";
|
|
115
|
+
|
|
116
|
+
const { op } = ApplyOp({ name: "schema-apply", env: "prod", target: "clickhouse", delete: "gated" });
|
|
117
|
+
|
|
118
|
+
export default op;
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Read the run's not-attempted count before calling a schema converged. A rebuild is never applied in place; it runs as the rebuild migration Op.
|
|
122
|
+
|
|
123
|
+
`chant migrate` is not a schema migration runner. Schema changes go through plan, apply and the rebuild Op.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: chant-sql-postgres-migration
|
|
3
|
+
description: Run a Postgres column rename or type change with PostgresMigrationOp, a gated expand-and-contract Op with a dual-write trigger, a batched backfill with receipts, verification, a switch, replication lag handling and onFailure cleanup
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
# Running a Postgres column migration
|
|
7
|
+
|
|
8
|
+
Use this skill when `chant sql plan` or `chant sql diff` exits 2 because a column's change is a rename (SQLPG205) or a type change across kinds (SQLPG208, text to integer). Postgres has no way to make these in place without breaking readers or failing on existing rows, and the applier refuses them. `PostgresMigrationOp` makes them as expand and contract: a new column is added beside the old, kept written, filled in batches, verified, and swapped in behind an approval.
|
|
9
|
+
|
|
10
|
+
A type change within a kind that rewrites the table under `ACCESS EXCLUSIVE` (SQLPG207, integer to bigint) can run as the same Op: it fills the new column in batches instead of holding the lock for a rewrite. The plan does not hand that one over; write the declaration yourself. The other expand-and-contract rules (a NOT NULL column with no default, partitioning, an object rename, a view's columns, enum labels) have no Op.
|
|
11
|
+
|
|
12
|
+
## Declare the Op
|
|
13
|
+
|
|
14
|
+
The plan prints a declaration for each refused column, and `--json` carries them as `migrationOps`. Copy it into an `*.op.ts` file in the same pull request as the schema change:
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// ops/migrate-app-users-login.op.ts
|
|
18
|
+
import { PostgresMigrationOp } from "@intentius/chant-lexicon-sql/postgres";
|
|
19
|
+
|
|
20
|
+
export const { op } = PostgresMigrationOp({
|
|
21
|
+
name: "migrate-app-users-login",
|
|
22
|
+
env: "prod", // sql.profiles.prod
|
|
23
|
+
table: "app.users", // schema.name as the server knows it
|
|
24
|
+
column: "login", // the column as the build declares it: the new name for a rename
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For a type change, `using` is the expression that computes the new value from the old row, as `ALTER COLUMN ... TYPE ... USING` takes it. It defaults to a cast to the declared type; set it when the cast is not the conversion you want:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
PostgresMigrationOp({ name: "migrate-orders-amount", env: "prod", table: "shop.orders", column: "amount", using: "NULLIF(amount, 'n/a')::numeric(12,2)" });
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Options besides `name`, `env`, `table`, `column`, `using`:
|
|
35
|
+
|
|
36
|
+
- `batchSize` (default 1000): rows per batch, the width of a range of a primary key of one integer column, or how many keys lie between two recorded boundaries of any other key;
|
|
37
|
+
- `retain` (default `7d`): how long the old column is kept after the switch;
|
|
38
|
+
- `replicationLag` (default `{ max: "10s", wait: "30m" }`, or `false`): see below;
|
|
39
|
+
- `lockTimeoutMs` (default the profile's, else 5000) and `statementTimeoutMs` (default the profile's, else 60000, not applied to the scans of validation and verification);
|
|
40
|
+
- `gate` and `contractGate`: the two approvals, each with `gate` (name), `timeout` and `description`; `gate` also takes `approval` for quorum, roles and a policy, and a policy gets `verifiedRows` and `mismatched` as context;
|
|
41
|
+
- `backfillTimeout` (default `6h`), `output` (default `dist/schema.json`), `path`, `build` (default true runs `chant build` first), `stack`, `ownershipEnv`.
|
|
42
|
+
|
|
43
|
+
## What it does
|
|
44
|
+
|
|
45
|
+
| Phase | Step |
|
|
46
|
+
|---|---|
|
|
47
|
+
| Build | `chant build` |
|
|
48
|
+
| Plan | classifies the column's change against the server and refuses what the Op does not make |
|
|
49
|
+
| Expand | adds the new column, nullable, no default (a catalog change) |
|
|
50
|
+
| Dual write | a trigger keeps the new column written: computed from the old one for a type change, both ways for a rename |
|
|
51
|
+
| Backfill | `UPDATE` per primary-key range, each batch in its own transaction with its receipt, under `lock_timeout` |
|
|
52
|
+
| Carry over | builds each index on the old column again on the new one `CONCURRENTLY` (a key's too), and adds each check and foreign key (another table's that references the column too) `NOT VALID`, then validates it |
|
|
53
|
+
| Verify | compares rows, mismatches, NULLs and checksums of the new column against the old |
|
|
54
|
+
| Approve | the switch gate |
|
|
55
|
+
| Switch | proves NOT NULL (declared, or for a primary key or identity) with a `NOT VALID` check then `VALIDATE`; then one short transaction: a type change swaps the columns by name, a rename finishes the new column and keeps both written; the carried indexes and constraints take their names, keys with `ADD CONSTRAINT ... USING INDEX`; the views that read the column are made again from their declarations; an identity or serial sequence moves to the new column |
|
|
56
|
+
| Retain | keeps the old column until `retain` has passed |
|
|
57
|
+
| Approve contract | the contract gate |
|
|
58
|
+
| Contract | drops the old column, and a rename's trigger |
|
|
59
|
+
|
|
60
|
+
## Run it
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
chant run migrate-app-users-login # expand, dual write, backfill, verify; exits 3 at approve-migrate-app-users-login
|
|
64
|
+
chant run status migrate-app-users-login # Filled, Skipped, BackfilledRows, Verification, VerifiedRows
|
|
65
|
+
chant approve migrate-app-users-login approve-migrate-app-users-login --actor <you>
|
|
66
|
+
chant run migrate-app-users-login # switches; exits 3 at approve-migrate-app-users-login-contract
|
|
67
|
+
chant approve migrate-app-users-login approve-migrate-app-users-login-contract --actor <you>
|
|
68
|
+
chant run migrate-app-users-login # drops the old column once retain has passed
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Each run goes as far as the next gate. Every step reads the server again, so a run after a gate, a crash or an approval carries on where the last stopped.
|
|
72
|
+
|
|
73
|
+
The switch gate is bound to a digest of the plan and the verified new column. If the next run verifies different numbers, the gate asks again. For a rename, readers move to the new name at the switch, and the old name keeps working for writers until the contract, so deploy readers before approving. The contract gate is bound to the old column's identity and retention date; approving it early is fine, nothing is dropped before the date.
|
|
74
|
+
|
|
75
|
+
## What it carries over
|
|
76
|
+
|
|
77
|
+
What uses the column moves with it, so `integer` to `bigint` on a primary key that other tables reference, or a rename of a uniquely indexed `email`, needs nothing dropped first:
|
|
78
|
+
|
|
79
|
+
- indexes, primary keys and unique constraints on the column are built on the new column `CONCURRENTLY` while writes go on;
|
|
80
|
+
- checks and foreign keys, this table's and other tables' that reference the column, are added `NOT VALID` and validated;
|
|
81
|
+
- views that read the column (and views on those) are dropped and created again from their declarations in the switch, with their grants and owner, so each such view must be declared in the build;
|
|
82
|
+
- an identity moves to the new column under its sequence's name and carries on from the old sequence's position; a serial column's sequence is handed over and widened with it.
|
|
83
|
+
|
|
84
|
+
A type change keeps every name. A rename takes the name the build declares for a key, foreign key or index on the new column, else turns a name Postgres made from the old column (`users_email_key`) into the one it makes from the new (`users_login_key`), and keeps the old column's unique constraints and indexes, renamed `__chant_old`, for readers of the old name until the contract.
|
|
85
|
+
|
|
86
|
+
A partitioned table is migrated as one; its partitions follow it.
|
|
87
|
+
|
|
88
|
+
## Receipts and resuming
|
|
89
|
+
|
|
90
|
+
Each batch commits its `UPDATE` and its receipt in one transaction, in `<schema>.__chant_receipts` in the migrated table's schema. A primary key of one integer column is batched by ranges of its value; any other key (uuid, text, several columns) by boundaries walked from its index on the first run and recorded beside the receipts, so every run finds the same batches. A run killed during the backfill (Ctrl-C, a lost machine) is not a failure and runs no onFailure. The next run skips the batches that have receipts and fills the rest, so no batch is updated twice. The receipts bind the table's oid and the new column, so receipts from another table or an earlier attempt are not reused.
|
|
91
|
+
|
|
92
|
+
## Replication lag
|
|
93
|
+
|
|
94
|
+
Before each batch the backfill reads `pg_stat_replication` and pauses while a replica's replay lag is above `replicationLag.max`, for up to `wait` at a time. With no replicas it carries on. If `wait` passes with a replica still behind, the backfill stops with a message naming the replica, keeps its receipts, and the next run goes on from there.
|
|
95
|
+
|
|
96
|
+
A role that is neither superuser nor a member of `pg_monitor` cannot read other sessions' lag, and the backfill stops saying so rather than guess. Grant it and run again:
|
|
97
|
+
|
|
98
|
+
```sql
|
|
99
|
+
GRANT pg_monitor TO migration_role;
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
or set `replicationLag: false` to run without the check.
|
|
103
|
+
|
|
104
|
+
## When something goes wrong
|
|
105
|
+
|
|
106
|
+
- A failed step (a value the `using` expression cannot convert, a verification mismatch, a refused declaration, an index that cannot be built) runs onFailure: the trigger, its function, the check, the carried indexes and constraints, the new column and the receipts table are dropped, and the plan shows the original change again. The old column was never touched. Fix the declaration or the data and run again. A failed gate or an aborted run does not run onFailure.
|
|
107
|
+
- A lock timeout means another session holds a lock the step needs (SQLSTATE 55P03). The step retries a few times, then fails. Run again when the blocker has finished.
|
|
108
|
+
- The working objects (new column, trigger, function, check, receipts table) carry chant's comment marker with a `migration=` key, and plans, imports and prunes leave them out, so an `ApplyOp` for the rest of the schema can run beside a migration. An object under one of the working names that is not this migration's stops the run; rename or drop it by hand.
|
|
109
|
+
|
|
110
|
+
## What the Op refuses today
|
|
111
|
+
|
|
112
|
+
The Plan phase refuses, naming each object and what to do, a table or column with:
|
|
113
|
+
|
|
114
|
+
- something on the column it does not carry over: an exclusion constraint, a constraint trigger, a materialized view, a rule, a trigger, a policy, a statistics object, a generated column computed from it, an INVALID index, or a view the build does not declare;
|
|
115
|
+
- on a partitioned table, an index, key or foreign key on the column, or the column in the partition key (chant #3333);
|
|
116
|
+
- a partition (run the Op on its partitioned table) or an inheritance tree (chant #3333);
|
|
117
|
+
- a generated column itself, which the applier changes in place;
|
|
118
|
+
- no primary key;
|
|
119
|
+
- a rename combined with a type change: run the Op twice, the rename first (chant #3331);
|
|
120
|
+
- a rename of a column with a default, an identity or a serial sequence: drop the default, rename, declare it again (chant #3331);
|
|
121
|
+
- a column a logical replication publication sends; a column list that leaves it out does not stop the Op (chant #3332);
|
|
122
|
+
- a column that needs no migration, where the message says to use the applier.
|
|
123
|
+
|
|
124
|
+
## Checking it is done
|
|
125
|
+
|
|
126
|
+
`chant sql plan <env> dist/schema.json` reports no changes for the column, the old column and the receipts table are gone, and a later `chant run` of the Op reports done. Then remove the `*.op.ts` file.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: chant-sql-postgres-plan
|
|
3
|
+
description: Plan Postgres schema changes with chant sql diff and chant sql plan, and read the change classes (metadata only, validates, needs CONCURRENTLY, ACCESS EXCLUSIVE rewrite, expand and contract) as the lock each takes in production
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
# Planning Postgres schema changes
|
|
7
|
+
|
|
8
|
+
Use this skill when a declared Postgres schema changes and you need to know what the change does to a running server before anything runs. It covers the offline diff, the plan against a live server, the classifier behind both, and applying a plan with the Postgres applier. The expand-and-contract migration Op has its own skill, `chant-sql-postgres-migration`.
|
|
9
|
+
|
|
10
|
+
The classes are Postgres's own. A change is classified by the lock it takes and whether it reads or rewrites the table, so the class answers the production question: will this queue behind running queries, block writes, or fail?
|
|
11
|
+
|
|
12
|
+
## Two commands
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
chant sql diff base.json head.json # two chant build outputs, offline
|
|
16
|
+
chant sql plan prod dist/schema.json # a build output against the prod server
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`chant sql diff` compares a pull request's base and head builds and needs no server. `chant sql plan <env>` reads the server that `sql.profiles.<env>` binds, and compares the build with it. Add `--json` to either for a machine-readable report. The build output's `dialect` decides which classifier runs; a Postgres build gets the one described here.
|
|
20
|
+
|
|
21
|
+
Both exit 2 when any change can only be made as expand and contract, and 0 otherwise, so either can gate a pipeline. A plan refuses such a change: it is never one statement.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// chant.config.ts
|
|
25
|
+
import type { ChantConfig } from "@intentius/chant/config";
|
|
26
|
+
import "@intentius/chant-lexicon-sql";
|
|
27
|
+
|
|
28
|
+
export default {
|
|
29
|
+
lexicons: ["sql"],
|
|
30
|
+
sql: {
|
|
31
|
+
dialect: "postgres",
|
|
32
|
+
postgresMajor: 16,
|
|
33
|
+
provider: "rds",
|
|
34
|
+
profiles: {
|
|
35
|
+
prod: {
|
|
36
|
+
url: "postgres://db.internal:5432/shop",
|
|
37
|
+
user: { env: "PGUSER" },
|
|
38
|
+
password: { env: "PG_PROD_PASSWORD" },
|
|
39
|
+
schemas: ["app"],
|
|
40
|
+
defaultSchema: "app",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
} satisfies ChantConfig;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Credentials are named by environment variable and never written into the URL. `schemas` limits what the plan reads to those schemas, and `defaultSchema` is where an unqualified declaration lives (`public` when omitted). Without a profile, `POSTGRES_URL`, `POSTGRES_USER` and `POSTGRES_PASSWORD` bind.
|
|
48
|
+
|
|
49
|
+
## sql.postgresMajor
|
|
50
|
+
|
|
51
|
+
`sql.postgresMajor` is the major the project targets (14 to 18); without it the newest supported major is used. The plan reads it, so set it to the server's major. It changes a classification where the majors differ:
|
|
52
|
+
|
|
53
|
+
- changing a STORED generated column's expression (SQLPG212) is a rewrite from 17 on; on 14 to 16 there is no `SET EXPRESSION`, so the column is dropped and added and the change is expand and contract;
|
|
54
|
+
- changing a table's access method (SQLPG226) is a rewrite from 15 on; on 14 it is expand and contract.
|
|
55
|
+
|
|
56
|
+
The post-synth checks SQLPG114 to SQLPG116 read the same setting.
|
|
57
|
+
|
|
58
|
+
## The change classes
|
|
59
|
+
|
|
60
|
+
| Class | Report label | What it means in production |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| create | create | a new object; nothing existing changes |
|
|
63
|
+
| metadata | metadata only | a catalog change; no row is read or written |
|
|
64
|
+
| validate | validates under a weaker lock | every row is read to check a constraint, but reads and writes go on |
|
|
65
|
+
| concurrently | needs CONCURRENTLY | an index build or drop that blocks writes unless it is done CONCURRENTLY |
|
|
66
|
+
| rewrite | ACCESS EXCLUSIVE rewrite or scan | the table is rewritten or read in full, and its reads and writes block until done |
|
|
67
|
+
| expand | EXPAND AND CONTRACT | no in-place change keeps old readers working; the plan refuses it |
|
|
68
|
+
| drop | drop | the object and, for a table, its data are gone |
|
|
69
|
+
|
|
70
|
+
Metadata only does not mean free. Most `ALTER TABLE` forms take `ACCESS EXCLUSIVE`, which queues behind every running query and then blocks every query behind it, so a short change can stall a busy table if a long transaction is open. The class says no rows move; the lock still has to be won.
|
|
71
|
+
|
|
72
|
+
## What the rules say
|
|
73
|
+
|
|
74
|
+
Every rule has an id in the SQLPG2xx range, names its class and cites the Postgres 18 documentation page behind it, with the differences across majors 14 to 18 where there are any. The full table is on the "Planning and the Change Classifier" page of the sql docs. The common cases:
|
|
75
|
+
|
|
76
|
+
| Change | Rule | Class | Notes |
|
|
77
|
+
|---|---|---|---|
|
|
78
|
+
| add a column, no default or a non-volatile default | SQLPG201 | metadata | the default is stored once, in every supported major |
|
|
79
|
+
| add a column with a volatile default, a STORED generated column or an identity column | SQLPG202 | rewrite | `gen_random_uuid()`, `random()`, `nextval()`, `clock_timestamp()` are volatile; `now()` is not |
|
|
80
|
+
| add a NOT NULL column with no default | SQLPG203 | expand | fails on a table with rows: add it nullable, backfill, then set NOT NULL |
|
|
81
|
+
| drop a column | SQLPG204 | metadata | the data is gone |
|
|
82
|
+
| rename a column | SQLPG205 | expand | old readers fail the moment it runs |
|
|
83
|
+
| column type to a binary-coercible type (longer varchar, text, wider numeric) | SQLPG206 | metadata | indexes on the column may still be rebuilt |
|
|
84
|
+
| column type with a rewrite (integer to bigint, a shorter varchar) | SQLPG207 | rewrite | |
|
|
85
|
+
| column type across kinds (text to integer) | SQLPG208 | expand | needs USING and breaks readers |
|
|
86
|
+
| set NOT NULL | SQLPG210 | rewrite | a valid `CHECK (col IS NOT NULL)` already in place makes it metadata |
|
|
87
|
+
| add a CHECK | SQLPG218 | rewrite | declare it `NOT VALID`, then validate |
|
|
88
|
+
| add a foreign key | SQLPG219 | validate | `SHARE ROW EXCLUSIVE` on both tables for the scan; `NOT VALID` first avoids it |
|
|
89
|
+
| add a constraint `NOT VALID` | SQLPG217 | metadata | checks new rows only |
|
|
90
|
+
| validate a constraint | SQLPG220 | validate | `SHARE UPDATE EXCLUSIVE`, so reads and writes go on |
|
|
91
|
+
| add a primary key or unique constraint | SQLPG221 | concurrently | build the unique index CONCURRENTLY, then `ADD CONSTRAINT ... USING INDEX` |
|
|
92
|
+
| create an index CONCURRENTLY | SQLPG240 | concurrently | cannot run inside a transaction block; a failed build leaves an INVALID index to drop |
|
|
93
|
+
| create an index without CONCURRENTLY on an existing table | SQLPG241 | concurrently | `SHARE` blocks every write until the build ends: declare it CONCURRENTLY |
|
|
94
|
+
| drop or change an index | SQLPG242, SQLPG243 | concurrently | a changed index is dropped and created |
|
|
95
|
+
| change a view's query, keeping its columns | SQLPG250 | metadata | |
|
|
96
|
+
| change a view's columns | SQLPG251 | expand | dropped and created, with every view on top of it |
|
|
97
|
+
| add an enum label | SQLPG260 | metadata | the new label cannot be used in the same transaction |
|
|
98
|
+
| remove or reorder enum labels | SQLPG261 | expand | a new type, columns moved, the old type dropped |
|
|
99
|
+
| change partitioning or inheritance | SQLPG227 | expand | a new table is filled and swapped in |
|
|
100
|
+
| rename an object or move it to another schema | SQLPG228 | expand | |
|
|
101
|
+
| drop an object | SQLPG270 | drop | |
|
|
102
|
+
|
|
103
|
+
A table created in the same plan as its indexes needs no CONCURRENTLY, so those indexes classify as create.
|
|
104
|
+
|
|
105
|
+
Two forms to prefer over the one-step version, because the rule names them:
|
|
106
|
+
|
|
107
|
+
- Adding a constraint that scans the table: declare it `NOT VALID` first (SQLPG217, metadata), then drop `NOT VALID` to validate it (SQLPG220, validate).
|
|
108
|
+
- Adding a unique key to a busy table: a named unique index `CONCURRENTLY` first, then the constraint over it.
|
|
109
|
+
|
|
110
|
+
## Identity and renames
|
|
111
|
+
|
|
112
|
+
Between two builds an object is its export name, so a changed SQL name under the same export is a rename. Against a server, which has no export names, an object is its qualified name (`app.orders`). A rename is expand and contract (SQLPG205, SQLPG228), so plan it deliberately. To tell the plan that a name changed rather than that one object was dropped and another created, put a comment before the CREATE:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
export const orders = table`
|
|
116
|
+
-- previously: purchases
|
|
117
|
+
CREATE TABLE ${app}.orders (...)`;
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
A column is its name. Declare a column rename on its own line:
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
status text NOT NULL, -- previously: state
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Without the hint, a rename plans as a drop and an add, and the report says so when the two have the same type in the same place. A drop is destructive, so add the hint. An index renames in place (SQLPG229, metadata) and nothing reads an index by name.
|
|
127
|
+
|
|
128
|
+
## Objects that are not yours
|
|
129
|
+
|
|
130
|
+
Some objects on a server belong to another tool. The catalog reader marks them foreign, and the plan never proposes to drop them; it reports a hint that the object is kept by that tool and is left alone.
|
|
131
|
+
|
|
132
|
+
- ORM and migration-runner tables, by name: `_prisma_migrations` (Prisma Migrate), `django_migrations`, `alembic_version`, `__drizzle_migrations`, `flyway_schema_history`, `goose_db_version`, `knex_migrations`, `SequelizeMeta`, `pgmigrations`, `schema_migrations`, `ar_internal_metadata`.
|
|
133
|
+
- Provider-owned objects: with `sql.provider` (or a profile's `provider`) set, the provider's own schemas and extensions read as foreign, so a Supabase `auth` schema is not an orphan to drop.
|
|
134
|
+
|
|
135
|
+
A foreign object is not a change to approve. If a plan wants to drop something you did not declare and it is not marked foreign, it is yours to either declare or leave out of `schemas`.
|
|
136
|
+
|
|
137
|
+
## No false drift
|
|
138
|
+
|
|
139
|
+
The server prints DDL its own way (`format_type()`, schema-qualified names, normalized expressions, a constraint name it generated). The plan undoes those rewrites with normalization rules and asks the server about any expression the rules leave different, so formatting alone is not a change. A constraint the declaration leaves unnamed is matched by what it says, so the name Postgres gave it is not a change either. Name a constraint when a later migration must refer to it.
|
|
140
|
+
|
|
141
|
+
`chant lifecycle plan` reports each change's disruption: create and metadata are `in-place`; validate, concurrently and rewrite are `rolling`; expand and contract is `replace`; a drop is `destroy`. For a column, constraint, view or enum change the lifecycle plan reports `unknown`, because the class depends on both definitions; `chant sql plan` classifies those.
|
|
142
|
+
|
|
143
|
+
## Reading a plan in a pull request
|
|
144
|
+
|
|
145
|
+
1. `chant build src --lexicon sql -o head.json` on the pull request branch, and the same on the base branch into `base.json`.
|
|
146
|
+
2. `chant sql diff base.json head.json`.
|
|
147
|
+
3. Read the `Warning` line: it counts the rewrites, each of which blocks the table's reads and writes until done. The rule names the form that does not.
|
|
148
|
+
4. An exit of 2 means a refused change. Do not merge it as an ordinary change: it runs as expand and contract (add the new, write both, backfill, move readers, drop the old). For a column rename (SQLPG205) or a type change across kinds (SQLPG208) the report names the `PostgresMigrationOp` declaration to add (`migrationOps` in `--json`); run it with `chant run <name>` until it is done (see `chant-sql-postgres-migration`). The other expand-and-contract changes have no Op yet.
|
|
149
|
+
|
|
150
|
+
## Applying
|
|
151
|
+
|
|
152
|
+
`ApplyOp` with `target: "postgres"` applies a build (`dist/schema.json`) to the server `sql.profiles.<env>` binds, through `postgresApply`.
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import { ApplyOp } from "@intentius/chant/op";
|
|
156
|
+
|
|
157
|
+
const { op } = ApplyOp({ name: "schema-apply", env: "prod", target: "postgres", delete: "gated" });
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The applier sends the statements for every change the classifier does not refuse, in the build's order, and a refused change is never sent.
|
|
161
|
+
|
|
162
|
+
Transactions follow the class, so a long scan holds locks on one table and what came before has committed:
|
|
163
|
+
|
|
164
|
+
- consecutive catalog-only statements (create, metadata, drop) share one transaction, across objects;
|
|
165
|
+
- a statement that reads or rewrites rows (rewrite and validate classes, an index built without `CONCURRENTLY`) runs in a transaction of its own object;
|
|
166
|
+
- `CREATE INDEX CONCURRENTLY`, `DROP INDEX CONCURRENTLY` and `ALTER TYPE ... ADD VALUE` run alone, outside any transaction. A failed `CONCURRENTLY` build leaves an INVALID index; the applier drops it, and only an invalid one.
|
|
167
|
+
|
|
168
|
+
A primary key or unique constraint added to an existing table goes in two steps, the unique index built `CONCURRENTLY` and then `ADD CONSTRAINT ... USING INDEX` (SQLPG221), so a busy table is never blocked for the build.
|
|
169
|
+
|
|
170
|
+
Timeouts are set on every statement: `lock_timeout` 5000 ms, so a statement that cannot get its lock fails instead of queueing behind a long transaction and blocking everything behind it; `statement_timeout` 60000 ms for catalog-only statements, and 0 (no limit) for scans, rewrites and `CONCURRENTLY` builds. Set them per environment with `lockTimeoutMs`, `statementTimeoutMs` and `scanTimeoutMs` on `sql.profiles.<env>`, or per call.
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
profiles: { prod: { url: "postgres://db.internal:5432/shop", lockTimeoutMs: 2000, scanTimeoutMs: 600000 } }
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Each object gets a verdict:
|
|
177
|
+
|
|
178
|
+
- created, updated or unchanged;
|
|
179
|
+
- not attempted `unsupported-kind` for an expand-and-contract change. The detail names each rule, its restriction and the Postgres 18 page, and for a column rename or a type change across kinds the `PostgresMigrationOp` declaration. Also a change with no in-place statement on the target major;
|
|
180
|
+
- not attempted `filtered` for a column drop when the Op may not delete, and for an object another tool keeps (an ORM revision table, a provider schema);
|
|
181
|
+
- not attempted `dependency-failed` when a referenced object is not on the server, or when the object's statements ran in a transaction that rolled back;
|
|
182
|
+
- not attempted `no-binding` or `no-credentials` when the environment names no server or the credentials are missing.
|
|
183
|
+
|
|
184
|
+
When the server refuses a statement, that object goes to `failed`, the objects that depend on it are `dependency-failed`, and the apply throws `PostgresApplyError` carrying the outcome. The outcome records the timeouts, every statement with the values it ran under and its transaction, and how each transaction ended. A lock timeout reads `lock_timeout 5000ms: another session holds a lock this statement needs; SQLSTATE 55P03`: run again when the blocker has finished. A rolled-back transaction changed nothing, so a re-run starts clean.
|
|
185
|
+
|
|
186
|
+
The target major is the build output's `postgresMajor`, else `sql.postgresMajor`, and picks `SET EXPRESSION` (17 and later) and `SET STORAGE DEFAULT` (16 and later).
|
|
187
|
+
|
|
188
|
+
Ownership is a trailer on the object's comment, set with `COMMENT ON` in the transaction that creates it: `One row per account [chant managed-by=chant stack=shop env=prod]`. It replaces the declared object comment on create; column and constraint comments are sent as written. Prune drops owned objects in the declared schemas only: views, indexes (`CONCURRENTLY`), tables, sequences, types, extensions, and schemas last. It never uses `CASCADE`, and an object something else depends on is reported `not-prunable`. Objects without the trailer, and other stacks', are never touched.
|
|
189
|
+
|
|
190
|
+
To try an apply without a real server, `chant emulator up --lexicon sql` starts the pinned `postgres` image and reports `POSTGRES_URL`, `POSTGRES_USER` and `POSTGRES_PASSWORD`, which the binding reads when no profile names a server.
|
|
191
|
+
|
|
192
|
+
## Not covered
|
|
193
|
+
|
|
194
|
+
Roles, grants, policies, functions and triggers are not modelled, so a plan does not see them. `chant migrate` is not a schema migration runner.
|