@intentius/chant-lexicon-sql 0.0.0-stage → 0.112.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,459 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A hand-written recursive-descent parser for the ClickHouse statements the
|
|
3
|
+
* dialect declares: `CREATE DATABASE`, `CREATE TABLE`, `CREATE VIEW` and
|
|
4
|
+
* `CREATE MATERIALIZED VIEW` (chant #3196).
|
|
5
|
+
*
|
|
6
|
+
* Statement structure is parsed; expressions are not. An expression (a
|
|
7
|
+
* default, a codec, a sort key, a TTL, a view's SELECT) is kept as a span of
|
|
8
|
+
* tokens: its source text, verbatim, and the interpolations inside it. That is
|
|
9
|
+
* what entities, references, dependency order and lineage need. Comparing
|
|
10
|
+
* `INTERVAL 1 DAY` with the server's `toIntervalDay(1)` is normalization's job,
|
|
11
|
+
* which asks the server.
|
|
12
|
+
*
|
|
13
|
+
* An interpolation (`ref` token) is accepted wherever a name, a type or an
|
|
14
|
+
* expression goes. At build time the tag has already spliced plain strings into
|
|
15
|
+
* the token list as SQL text, so a `ref` left here is an entity or a column
|
|
16
|
+
* reference. Lint parses the source with every interpolation still a `ref`,
|
|
17
|
+
* because it cannot know the values; accepting them keeps it from reporting an
|
|
18
|
+
* error the build would not have.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import type { Token } from "./tokens";
|
|
22
|
+
import { kw, SqlCursor, unquoteWith, type Span } from "../core/cursor";
|
|
23
|
+
|
|
24
|
+
export type { Span } from "../core/cursor";
|
|
25
|
+
|
|
26
|
+
export interface ColumnNode {
|
|
27
|
+
/** The name as written, unquoted. Empty when the name is an interpolation. */
|
|
28
|
+
name: string;
|
|
29
|
+
nameSpan: Span;
|
|
30
|
+
type?: Span;
|
|
31
|
+
/** `NULL` / `NOT NULL` after the type. */
|
|
32
|
+
nullable?: boolean;
|
|
33
|
+
default?: { kind: "DEFAULT" | "MATERIALIZED" | "ALIAS" | "EPHEMERAL"; expr?: Span };
|
|
34
|
+
comment?: Span;
|
|
35
|
+
codec?: Span;
|
|
36
|
+
ttl?: Span;
|
|
37
|
+
statistics?: Span;
|
|
38
|
+
settings?: Span;
|
|
39
|
+
/** `PRIMARY KEY` written on the column. */
|
|
40
|
+
primaryKey?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface IndexNode {
|
|
44
|
+
name: string;
|
|
45
|
+
expr: Span;
|
|
46
|
+
type: Span;
|
|
47
|
+
granularity?: Span;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ProjectionNode {
|
|
51
|
+
name: string;
|
|
52
|
+
body: Span;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface ConstraintNode {
|
|
56
|
+
name: string;
|
|
57
|
+
kind: "CHECK" | "ASSUME";
|
|
58
|
+
expr: Span;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface StorageNode {
|
|
62
|
+
engine?: { name: string; nameSpan: Span; args?: Span[]; span: Span };
|
|
63
|
+
orderBy?: Span;
|
|
64
|
+
primaryKey?: Span;
|
|
65
|
+
partitionBy?: Span;
|
|
66
|
+
sampleBy?: Span;
|
|
67
|
+
ttl?: Span;
|
|
68
|
+
settings?: Array<{ key: string; value: Span }>;
|
|
69
|
+
/** The whole `SETTINGS ...` clause, keyword included. */
|
|
70
|
+
settingsClause?: Span;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface DatabaseNode {
|
|
74
|
+
statement: "database";
|
|
75
|
+
ifNotExists: boolean;
|
|
76
|
+
name: Span;
|
|
77
|
+
onCluster?: Span;
|
|
78
|
+
engine?: { name: string; nameSpan: Span; args?: Span[]; span: Span };
|
|
79
|
+
settings?: Array<{ key: string; value: Span }>;
|
|
80
|
+
comment?: Span;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface TableNode extends StorageNode {
|
|
84
|
+
statement: "table";
|
|
85
|
+
orReplace: boolean;
|
|
86
|
+
ifNotExists: boolean;
|
|
87
|
+
name: Span;
|
|
88
|
+
onCluster?: Span;
|
|
89
|
+
columns: ColumnNode[];
|
|
90
|
+
indexes: IndexNode[];
|
|
91
|
+
projections: ProjectionNode[];
|
|
92
|
+
constraints: ConstraintNode[];
|
|
93
|
+
comment?: Span;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface ViewNode extends StorageNode {
|
|
97
|
+
statement: "view";
|
|
98
|
+
materialized: boolean;
|
|
99
|
+
orReplace: boolean;
|
|
100
|
+
ifNotExists: boolean;
|
|
101
|
+
name: Span;
|
|
102
|
+
onCluster?: Span;
|
|
103
|
+
refresh?: Span;
|
|
104
|
+
append: boolean;
|
|
105
|
+
to?: Span;
|
|
106
|
+
columns: ColumnNode[];
|
|
107
|
+
/** The parenthesised column list, parentheses included, when there is one. */
|
|
108
|
+
columnsSpan?: Span;
|
|
109
|
+
populate: boolean;
|
|
110
|
+
empty: boolean;
|
|
111
|
+
/** `DEFINER = ...` and `SQL SECURITY ...`, as written. */
|
|
112
|
+
security?: Span;
|
|
113
|
+
select: Span;
|
|
114
|
+
comment?: Span;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export type CreateNode = DatabaseNode | TableNode | ViewNode;
|
|
118
|
+
|
|
119
|
+
/** A token that can stand where a name goes. */
|
|
120
|
+
const isNameToken = (t: Token | undefined): boolean =>
|
|
121
|
+
t !== undefined &&
|
|
122
|
+
(t.kind === "ident" || t.kind === "qident" || t.kind === "ref" || (t.kind === "number" && /[A-Za-z_]/.test(t.text)));
|
|
123
|
+
|
|
124
|
+
/** A name with its `` ` `` or `"` quotes taken off. */
|
|
125
|
+
export const unquote = (text: string): string => unquoteWith(text, '`"');
|
|
126
|
+
|
|
127
|
+
const countOf = (text: string, c: string): number => text.split(c).length - 1;
|
|
128
|
+
|
|
129
|
+
const STORAGE_KEYWORDS = ["ENGINE", "ORDER", "PRIMARY", "PARTITION", "SAMPLE", "TTL", "SETTINGS", "COMMENT"];
|
|
130
|
+
|
|
131
|
+
class Parser extends SqlCursor {
|
|
132
|
+
/** `ORDER`, `PARTITION`, `SAMPLE` and `GROUP` stop only before `BY`, `PRIMARY` only before `KEY`. */
|
|
133
|
+
protected override stopsAt(stop: readonly string[]): boolean {
|
|
134
|
+
if (!super.stopsAt(stop)) return false;
|
|
135
|
+
const word = this.peek()!.text.toUpperCase();
|
|
136
|
+
const two = ["ORDER", "PARTITION", "SAMPLE", "GROUP"].includes(word) ? kw(this.peek(1), "BY") : true;
|
|
137
|
+
const key = word === "PRIMARY" ? kw(this.peek(1), "KEY") : true;
|
|
138
|
+
return two && key;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Array and map literals: `[` and `]` arrive inside operator runs. */
|
|
142
|
+
protected override depthChange(t: Token): number {
|
|
143
|
+
if (t.kind === "op") return countOf(t.text, "[") + countOf(t.text, "{") - countOf(t.text, "]") - countOf(t.text, "}");
|
|
144
|
+
return super.depthChange(t);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** One name token. */
|
|
148
|
+
private name(what = "a name"): { text: string; span: Span } {
|
|
149
|
+
const t = this.next();
|
|
150
|
+
if (!isNameToken(t)) this.fail(`expected ${what}`, t);
|
|
151
|
+
const i = this.idx(-1);
|
|
152
|
+
return { text: t.kind === "ref" ? "" : unquote(t.text), span: { from: i, to: i + 1, refs: t.kind === "ref" ? [t.part] : [] } };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** A name, optionally `db.`-qualified. */
|
|
156
|
+
private qualifiedName(): Span {
|
|
157
|
+
const from = this.idx();
|
|
158
|
+
const refs: number[] = [];
|
|
159
|
+
const one = () => {
|
|
160
|
+
const t = this.next();
|
|
161
|
+
if (!isNameToken(t)) this.fail("expected a name", t);
|
|
162
|
+
if (t.kind === "ref") refs.push(t.part);
|
|
163
|
+
};
|
|
164
|
+
one();
|
|
165
|
+
while (this.isPunct(".")) {
|
|
166
|
+
this.p++;
|
|
167
|
+
one();
|
|
168
|
+
}
|
|
169
|
+
return this.span(from, refs);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** `UInt64`, `Nullable(String)`, `DateTime64(3, 'UTC')`, `Tuple(a UInt8, b String)`. */
|
|
173
|
+
private typeSpan(): Span {
|
|
174
|
+
const from = this.idx();
|
|
175
|
+
const t = this.next();
|
|
176
|
+
if (t.kind !== "ident" && t.kind !== "ref") this.fail("expected a type", t);
|
|
177
|
+
// `DOUBLE PRECISION`, `CHAR VARYING`, `CHAR LARGE OBJECT`: the SQL-compatible multi-word aliases.
|
|
178
|
+
while (kw(this.peek(), "PRECISION", "VARYING", "UNSIGNED", "SIGNED", "LARGE", "OBJECT")) this.p++;
|
|
179
|
+
if (this.isPunct("(")) this.parenthesized();
|
|
180
|
+
// MySQL-compatible modifiers the server accepts and ignores, kept with the type as written.
|
|
181
|
+
for (;;) {
|
|
182
|
+
if (kw(this.peek(), "COLLATE") && isNameToken(this.peek(1))) this.p += 2;
|
|
183
|
+
else if (kw(this.peek(), "AUTO_INCREMENT", "UNSIGNED", "SIGNED")) this.p++;
|
|
184
|
+
else break;
|
|
185
|
+
}
|
|
186
|
+
return this.span(from, t.kind === "ref" ? [t.part] : []);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private column(typed: boolean): ColumnNode {
|
|
190
|
+
const { text, span } = this.name("a column name");
|
|
191
|
+
const col: ColumnNode = { name: text, nameSpan: span };
|
|
192
|
+
const STOP = ["COMMENT", "CODEC", "TTL", "STATISTICS", "SETTINGS", "PRIMARY"];
|
|
193
|
+
const at = this.peek();
|
|
194
|
+
const bare = at === undefined || (at.kind === "punct" && (at.text === "," || at.text === ")"));
|
|
195
|
+
if (!bare && !kw(at, "DEFAULT", "MATERIALIZED", "ALIAS", "EPHEMERAL", "NULL", "NOT", ...STOP)) {
|
|
196
|
+
col.type = this.typeSpan();
|
|
197
|
+
} else if (typed && bare) {
|
|
198
|
+
this.fail("expected a column type");
|
|
199
|
+
}
|
|
200
|
+
for (;;) {
|
|
201
|
+
if (this.accept("NULL")) col.nullable = true;
|
|
202
|
+
else if (kw(this.peek(), "NOT") && kw(this.peek(1), "NULL")) {
|
|
203
|
+
this.p += 2;
|
|
204
|
+
col.nullable = false;
|
|
205
|
+
} else if (kw(this.peek(), "DEFAULT", "MATERIALIZED", "ALIAS")) {
|
|
206
|
+
const kind = this.next().text.toUpperCase() as "DEFAULT" | "MATERIALIZED" | "ALIAS";
|
|
207
|
+
col.default = { kind, expr: this.expr(STOP) };
|
|
208
|
+
} else if (this.accept("EPHEMERAL")) {
|
|
209
|
+
const t = this.peek();
|
|
210
|
+
const hasExpr = t && !(t.kind === "punct" && (t.text === "," || t.text === ")")) && !kw(t, ...STOP);
|
|
211
|
+
col.default = { kind: "EPHEMERAL", expr: hasExpr ? this.expr(STOP) : undefined };
|
|
212
|
+
} else if (this.accept("COMMENT")) col.comment = this.expr(STOP);
|
|
213
|
+
else if (this.accept("CODEC")) col.codec = this.parenthesized();
|
|
214
|
+
else if (this.accept("STATISTICS")) col.statistics = this.parenthesized();
|
|
215
|
+
else if (this.accept("TTL")) col.ttl = this.expr(STOP);
|
|
216
|
+
else if (this.accept("SETTINGS")) col.settings = this.parenthesized();
|
|
217
|
+
else if (kw(this.peek(), "PRIMARY") && kw(this.peek(1), "KEY")) {
|
|
218
|
+
this.p += 2;
|
|
219
|
+
col.primaryKey = true;
|
|
220
|
+
} else break;
|
|
221
|
+
}
|
|
222
|
+
return col;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** True when the element starting here is `INDEX name ... TYPE ...`, not a column named `index`. */
|
|
226
|
+
private looksLikeIndex(): boolean {
|
|
227
|
+
if (!kw(this.peek(), "INDEX") || !isNameToken(this.peek(1))) return false;
|
|
228
|
+
let depth = 0;
|
|
229
|
+
for (let n = 2; ; n++) {
|
|
230
|
+
const t = this.peek(n);
|
|
231
|
+
if (t === undefined) return false;
|
|
232
|
+
if (t.kind === "punct" && t.text === "(") depth++;
|
|
233
|
+
else if (t.kind === "punct" && t.text === ")") {
|
|
234
|
+
if (depth === 0) return false;
|
|
235
|
+
depth--;
|
|
236
|
+
} else if (depth === 0 && t.kind === "punct" && t.text === ",") return false;
|
|
237
|
+
else if (depth === 0 && kw(t, "TYPE")) return true;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private tableElements(node: Pick<TableNode, "columns" | "indexes" | "projections" | "constraints">, typed: boolean): void {
|
|
242
|
+
this.expectPunct("(");
|
|
243
|
+
for (;;) {
|
|
244
|
+
if (this.looksLikeIndex()) {
|
|
245
|
+
this.p++;
|
|
246
|
+
const name = this.name("an index name").text;
|
|
247
|
+
const expr = this.expr(["TYPE"]);
|
|
248
|
+
this.expect("TYPE");
|
|
249
|
+
const type = this.expr(["GRANULARITY"]);
|
|
250
|
+
const granularity = this.accept("GRANULARITY") ? this.expr() : undefined;
|
|
251
|
+
node.indexes.push({ name, expr, type, granularity });
|
|
252
|
+
} else if (kw(this.peek(), "PROJECTION") && isNameToken(this.peek(1)) && this.isPunct("(", 2)) {
|
|
253
|
+
this.p++;
|
|
254
|
+
const name = this.name("a projection name").text;
|
|
255
|
+
node.projections.push({ name, body: this.parenthesized() });
|
|
256
|
+
} else if (kw(this.peek(), "PROJECTION") && isNameToken(this.peek(1)) && kw(this.peek(2), "INDEX")) {
|
|
257
|
+
// `PROJECTION p INDEX expr TYPE basic`: a projection kept as an index.
|
|
258
|
+
this.p++;
|
|
259
|
+
const name = this.name("a projection name").text;
|
|
260
|
+
const from = this.idx();
|
|
261
|
+
this.p++;
|
|
262
|
+
const expr = this.expr(["TYPE"]);
|
|
263
|
+
this.expect("TYPE");
|
|
264
|
+
const type = this.expr();
|
|
265
|
+
node.projections.push({ name, body: { from, to: type.to, refs: [...expr.refs, ...type.refs] } });
|
|
266
|
+
} else if (kw(this.peek(), "CONSTRAINT") && isNameToken(this.peek(1)) && kw(this.peek(2), "CHECK", "ASSUME")) {
|
|
267
|
+
this.p++;
|
|
268
|
+
const name = this.name("a constraint name").text;
|
|
269
|
+
const kind = this.next().text.toUpperCase() as "CHECK" | "ASSUME";
|
|
270
|
+
node.constraints.push({ name, kind, expr: this.expr() });
|
|
271
|
+
} else if (kw(this.peek(), "PRIMARY") && kw(this.peek(1), "KEY")) {
|
|
272
|
+
// `PRIMARY KEY (a, b)` inside the column list.
|
|
273
|
+
this.p += 2;
|
|
274
|
+
(node as TableNode).primaryKey = this.expr();
|
|
275
|
+
} else {
|
|
276
|
+
node.columns.push(this.column(typed));
|
|
277
|
+
}
|
|
278
|
+
// A trailing comma before the closing parenthesis is accepted, as the server accepts it.
|
|
279
|
+
if (this.acceptPunct(",")) {
|
|
280
|
+
if (this.acceptPunct(")")) return;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
this.expectPunct(")");
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private engine(): NonNullable<StorageNode["engine"]> {
|
|
289
|
+
const from = this.idx(-1);
|
|
290
|
+
this.acceptPunct("=");
|
|
291
|
+
const { text, span } = this.name("an engine name");
|
|
292
|
+
let args: Span[] | undefined;
|
|
293
|
+
if (this.acceptPunct("(")) {
|
|
294
|
+
args = [];
|
|
295
|
+
if (!this.acceptPunct(")")) {
|
|
296
|
+
for (;;) {
|
|
297
|
+
args.push(this.expr());
|
|
298
|
+
if (this.acceptPunct(",")) continue;
|
|
299
|
+
this.expectPunct(")");
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return { name: text, nameSpan: span, args, span: this.span(from, [...span.refs, ...(args?.flatMap((a) => a.refs) ?? [])]) };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
private settingsList(stop: readonly string[]): Array<{ key: string; value: Span }> {
|
|
308
|
+
const out: Array<{ key: string; value: Span }> = [];
|
|
309
|
+
for (;;) {
|
|
310
|
+
const key = this.name("a setting name").text;
|
|
311
|
+
this.expectPunct("=");
|
|
312
|
+
out.push({ key, value: this.expr(stop) });
|
|
313
|
+
if (!this.acceptPunct(",")) return out;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** ENGINE and the storage clauses, in any order, as ClickHouse accepts them. */
|
|
318
|
+
private storage(into: StorageNode, terminators: readonly string[]): void {
|
|
319
|
+
const STOP = [...STORAGE_KEYWORDS, ...terminators];
|
|
320
|
+
for (;;) {
|
|
321
|
+
if (this.accept("ENGINE")) into.engine = this.engine();
|
|
322
|
+
else if (kw(this.peek(), "ORDER") && kw(this.peek(1), "BY")) {
|
|
323
|
+
this.p += 2;
|
|
324
|
+
into.orderBy = this.expr(STOP, false);
|
|
325
|
+
} else if (kw(this.peek(), "PRIMARY") && kw(this.peek(1), "KEY")) {
|
|
326
|
+
this.p += 2;
|
|
327
|
+
into.primaryKey = this.expr(STOP, false);
|
|
328
|
+
} else if (kw(this.peek(), "PARTITION") && kw(this.peek(1), "BY")) {
|
|
329
|
+
this.p += 2;
|
|
330
|
+
into.partitionBy = this.expr(STOP, false);
|
|
331
|
+
} else if (kw(this.peek(), "SAMPLE") && kw(this.peek(1), "BY")) {
|
|
332
|
+
this.p += 2;
|
|
333
|
+
into.sampleBy = this.expr(STOP, false);
|
|
334
|
+
} else if (this.accept("TTL")) into.ttl = this.expr(STOP, false);
|
|
335
|
+
else if (kw(this.peek(), "SETTINGS")) {
|
|
336
|
+
const from = this.idx();
|
|
337
|
+
this.p++;
|
|
338
|
+
into.settings = this.settingsList(STOP);
|
|
339
|
+
into.settingsClause = this.span(from, into.settings.flatMap((s) => s.value.refs));
|
|
340
|
+
} else return;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
parse(): CreateNode {
|
|
345
|
+
this.expect("CREATE");
|
|
346
|
+
let orReplace = false;
|
|
347
|
+
if (this.accept("OR")) {
|
|
348
|
+
this.expect("REPLACE");
|
|
349
|
+
orReplace = true;
|
|
350
|
+
}
|
|
351
|
+
if (this.accept("DATABASE")) return this.database();
|
|
352
|
+
if (this.accept("TABLE")) return this.table(orReplace);
|
|
353
|
+
const materialized = this.accept("MATERIALIZED");
|
|
354
|
+
if (this.accept("VIEW")) return this.view(orReplace, materialized);
|
|
355
|
+
return this.fail(materialized ? "expected VIEW" : "expected DATABASE, TABLE, VIEW or MATERIALIZED VIEW");
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
private ifNotExists(): boolean {
|
|
359
|
+
if (kw(this.peek(), "IF") && kw(this.peek(1), "NOT") && kw(this.peek(2), "EXISTS")) {
|
|
360
|
+
this.p += 3;
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
private onCluster(): Span | undefined {
|
|
367
|
+
if (kw(this.peek(), "ON") && kw(this.peek(1), "CLUSTER")) {
|
|
368
|
+
this.p += 2;
|
|
369
|
+
return this.qualifiedName();
|
|
370
|
+
}
|
|
371
|
+
return undefined;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/** A `UUID '...'` clause after the name, as `SHOW CREATE` can print it. Skipped. */
|
|
375
|
+
private uuid(): void {
|
|
376
|
+
if (kw(this.peek(), "UUID") && this.peek(1)?.kind === "string") this.p += 2;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
private finish(what: string): void {
|
|
380
|
+
this.acceptPunct(";");
|
|
381
|
+
if (this.peek() !== undefined) this.fail(`unexpected token after the ${what}`);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
private database(): DatabaseNode {
|
|
385
|
+
const node: DatabaseNode = { statement: "database", ifNotExists: this.ifNotExists(), name: this.qualifiedName() };
|
|
386
|
+
this.uuid();
|
|
387
|
+
node.onCluster = this.onCluster();
|
|
388
|
+
if (this.accept("ENGINE")) node.engine = this.engine();
|
|
389
|
+
if (this.accept("SETTINGS")) node.settings = this.settingsList(["COMMENT"]);
|
|
390
|
+
if (this.accept("COMMENT")) node.comment = this.expr();
|
|
391
|
+
this.finish("database definition");
|
|
392
|
+
return node;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
private table(orReplace: boolean): TableNode {
|
|
396
|
+
const ifNotExists = this.ifNotExists();
|
|
397
|
+
const name = this.qualifiedName();
|
|
398
|
+
this.uuid();
|
|
399
|
+
const node: TableNode = {
|
|
400
|
+
statement: "table",
|
|
401
|
+
orReplace,
|
|
402
|
+
ifNotExists,
|
|
403
|
+
name,
|
|
404
|
+
onCluster: this.onCluster(),
|
|
405
|
+
columns: [],
|
|
406
|
+
indexes: [],
|
|
407
|
+
projections: [],
|
|
408
|
+
constraints: [],
|
|
409
|
+
};
|
|
410
|
+
if (!this.isPunct("(")) this.fail("expected the column list (CREATE TABLE ... AS is not declared here)");
|
|
411
|
+
this.tableElements(node, true);
|
|
412
|
+
this.storage(node, []);
|
|
413
|
+
if (this.accept("COMMENT")) node.comment = this.expr();
|
|
414
|
+
this.finish("table definition");
|
|
415
|
+
return node;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
private view(orReplace: boolean, materialized: boolean): ViewNode {
|
|
419
|
+
const ifNotExists = this.ifNotExists();
|
|
420
|
+
const name = this.qualifiedName();
|
|
421
|
+
this.uuid();
|
|
422
|
+
const node: ViewNode = {
|
|
423
|
+
statement: "view",
|
|
424
|
+
materialized,
|
|
425
|
+
orReplace,
|
|
426
|
+
ifNotExists,
|
|
427
|
+
name,
|
|
428
|
+
onCluster: this.onCluster(),
|
|
429
|
+
append: false,
|
|
430
|
+
columns: [],
|
|
431
|
+
populate: false,
|
|
432
|
+
empty: false,
|
|
433
|
+
select: { from: 0, to: 0, refs: [] },
|
|
434
|
+
};
|
|
435
|
+
if (this.accept("REFRESH")) node.refresh = this.expr(["TO", "ENGINE", "AS", "EMPTY", "APPEND", "DEPENDS", "SETTINGS"]);
|
|
436
|
+
if (this.accept("APPEND")) node.append = true;
|
|
437
|
+
if (this.accept("TO")) node.to = this.qualifiedName();
|
|
438
|
+
if (this.isPunct("(")) {
|
|
439
|
+
const from = this.idx();
|
|
440
|
+
const holder = { columns: node.columns, indexes: [], projections: [], constraints: [] };
|
|
441
|
+
this.tableElements(holder, false);
|
|
442
|
+
node.columnsSpan = this.span(from, []);
|
|
443
|
+
}
|
|
444
|
+
this.storage(node, ["AS", "POPULATE", "EMPTY", "DEFINER", "SQL"]);
|
|
445
|
+
if (this.accept("POPULATE")) node.populate = true;
|
|
446
|
+
if (this.accept("EMPTY")) node.empty = true;
|
|
447
|
+
if (kw(this.peek(), "DEFINER", "SQL")) node.security = this.expr(["AS"], false);
|
|
448
|
+
this.expect("AS");
|
|
449
|
+
node.select = this.expr(["COMMENT"], false);
|
|
450
|
+
if (this.accept("COMMENT")) node.comment = this.expr();
|
|
451
|
+
this.finish("view's SELECT");
|
|
452
|
+
return node;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/** Parse one CREATE statement. Throws {@link SqlSyntaxError} located in the template. */
|
|
457
|
+
export function parseCreate(tokens: Token[]): CreateNode {
|
|
458
|
+
return new Parser(tokens).parse();
|
|
459
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant sql diff` and `chant sql plan`: the classified change between two
|
|
3
|
+
* builds, or between a build and a live server. A Postgres build (its output
|
|
4
|
+
* says `"dialect": "postgres"`) or a Postgres binding goes to
|
|
5
|
+
* `../../postgres/plan/commands.ts`.
|
|
6
|
+
*
|
|
7
|
+
* chant sql diff <before.json> <after.json> [--json]
|
|
8
|
+
* chant sql plan <env> <build.json> [--json]
|
|
9
|
+
*
|
|
10
|
+
* `diff` is offline: it compares two `chant build` outputs, say a pull
|
|
11
|
+
* request's base and head, and needs no server. `plan` compares a build with
|
|
12
|
+
* the server `sql.profiles.<env>` binds and asks that server's formatter about
|
|
13
|
+
* expressions the rules leave different. Both exit 2 when a change needs a
|
|
14
|
+
* rebuild, which a plan refuses to make in place, and 0 otherwise; for each
|
|
15
|
+
* refused table they name the `ClickHouseRebuildOp` to run instead
|
|
16
|
+
* (`rebuildOps` in `--json`, `./rebuild-handoff.ts`).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type { CommandGroup, CommandGroupContext } from "@intentius/chant/cli/command-group";
|
|
20
|
+
import { diffSchemas, type SchemaDiff } from "./diff";
|
|
21
|
+
import { renderDiff } from "./report";
|
|
22
|
+
import { keyedByQualifiedName, schemaFromBuildFile, schemaFromServer } from "./schema";
|
|
23
|
+
import { dropFormattingOnly } from "./server-format";
|
|
24
|
+
import { bindClickHouse } from "../live/bind";
|
|
25
|
+
import { rebuildOpSuggestions } from "./rebuild-handoff";
|
|
26
|
+
import { readFileSync } from "node:fs";
|
|
27
|
+
|
|
28
|
+
/** The dialect a build output names. */
|
|
29
|
+
function outputDialect(path: string): string | undefined {
|
|
30
|
+
try {
|
|
31
|
+
return (JSON.parse(readFileSync(path, "utf-8")) as { dialect?: string }).dialect;
|
|
32
|
+
} catch {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function split(args: string[]): { positional: string[]; json: boolean } {
|
|
38
|
+
return { positional: args.filter((a) => !a.startsWith("--")), json: args.includes("--json") };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function emit(diff: SchemaDiff, json: boolean, title: string): number {
|
|
42
|
+
console.log(json ? JSON.stringify(diff, null, 2) : renderDiff(diff, { title }));
|
|
43
|
+
return diff.rebuilds.length > 0 ? 2 : 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function runDiff(ctx: CommandGroupContext): Promise<number> {
|
|
47
|
+
const { positional, json } = split(ctx.rawArgs);
|
|
48
|
+
if (positional.length !== 2) {
|
|
49
|
+
console.error("usage: chant sql diff <before.json> <after.json> [--json]");
|
|
50
|
+
return 1;
|
|
51
|
+
}
|
|
52
|
+
if (outputDialect(positional[1]!) === "postgres") {
|
|
53
|
+
const { diffPgBuildFiles, emitPg, projectMajor } = await import("../../postgres/plan/commands");
|
|
54
|
+
return emitPg(diffPgBuildFiles(positional[0]!, positional[1]!, await projectMajor()), json, `${positional[0]} -> ${positional[1]}`);
|
|
55
|
+
}
|
|
56
|
+
const after = schemaFromBuildFile(positional[1]!);
|
|
57
|
+
const diff = diffSchemas(schemaFromBuildFile(positional[0]!), after);
|
|
58
|
+
const rebuildOps = rebuildOpSuggestions(diff, new Map(after.map((o) => [o.key, o.canonical])), "<env>");
|
|
59
|
+
return emit(rebuildOps.length > 0 ? { ...diff, rebuildOps } : diff, json, `${positional[0]} -> ${positional[1]}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The declared objects against the server, keys and labels by `database.name`. */
|
|
63
|
+
export async function planAgainstServer(environment: string, buildFile: string, options: Parameters<typeof bindClickHouse>[0] = {}): Promise<SchemaDiff> {
|
|
64
|
+
const target = await bindClickHouse({ ...options, environment });
|
|
65
|
+
const declared = keyedByQualifiedName(schemaFromBuildFile(buildFile, target.defaultDatabase));
|
|
66
|
+
const databases = new Set(declared.map((o) => o.canonical.database ?? o.canonical.name));
|
|
67
|
+
const live = await schemaFromServer(target, databases);
|
|
68
|
+
const diff = diffSchemas(live, declared);
|
|
69
|
+
const changes = await dropFormattingOnly(target.endpoint, diff.changes);
|
|
70
|
+
const rebuildOps = rebuildOpSuggestions(
|
|
71
|
+
{ ...diff, changes, rebuilds: changes.filter((c) => c.class === "rebuild") },
|
|
72
|
+
new Map(declared.map((o) => [o.key, o.canonical])),
|
|
73
|
+
environment,
|
|
74
|
+
);
|
|
75
|
+
const label = new Map(declared.map((o) => [o.key, `${o.exportName} (${o.key})`]));
|
|
76
|
+
const relabel = changes.map((c) => ({ ...c, object: label.get(c.object) ?? c.object }));
|
|
77
|
+
return { changes: relabel, rebuilds: relabel.filter((c) => c.class === "rebuild"), hints: diff.hints, ...(rebuildOps.length > 0 ? { rebuildOps } : {}) };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function runPlan(ctx: CommandGroupContext): Promise<number> {
|
|
81
|
+
const { positional, json } = split(ctx.rawArgs);
|
|
82
|
+
if (positional.length !== 2) {
|
|
83
|
+
console.error("usage: chant sql plan <env> <build.json> [--json]");
|
|
84
|
+
return 1;
|
|
85
|
+
}
|
|
86
|
+
if (outputDialect(positional[1]!) === "postgres") {
|
|
87
|
+
const { planPgAgainstServer, emitPg } = await import("../../postgres/plan/commands");
|
|
88
|
+
return emitPg(await planPgAgainstServer(positional[0]!, positional[1]!), json, `${positional[1]} against ${positional[0]}`);
|
|
89
|
+
}
|
|
90
|
+
const diff = await planAgainstServer(positional[0]!, positional[1]!);
|
|
91
|
+
return emit(diff, json, `${positional[1]} against ${positional[0]}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const sqlCommands: CommandGroup = {
|
|
95
|
+
name: "sql",
|
|
96
|
+
description: "Schema changes, classified: between two builds, or a build and a live server",
|
|
97
|
+
commands: [
|
|
98
|
+
{ name: "diff", description: "Classify the change between two chant build outputs (offline)", handler: runDiff },
|
|
99
|
+
{ name: "plan", description: "Classify the change from an environment's server to a chant build output", handler: runPlan },
|
|
100
|
+
],
|
|
101
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `observeResourcesDeep()` for the ClickHouse dialect: each declared object's
|
|
3
|
+
* live definition as a property tree in the declaration's own shape, so
|
|
4
|
+
* `chant lifecycle diff --live` and `plan` report property drift with no false
|
|
5
|
+
* drift.
|
|
6
|
+
*
|
|
7
|
+
* The reader parses the server's `SHOW CREATE` with the same tag the
|
|
8
|
+
* declaration used, which gives the same props shape. A field whose canonical
|
|
9
|
+
* form (`./normalize.ts`) equals the declaration's is written with the
|
|
10
|
+
* declaration's own value, so `INTERVAL 180 DAY` and `toIntervalDay(180)` do
|
|
11
|
+
* not read as drift; a field that differs keeps the server's value.
|
|
12
|
+
* `deepNormalizationHooks` prunes what is not a property of the object (the
|
|
13
|
+
* DDL text, the template source, lineage, a view's reads and `TO` target).
|
|
14
|
+
* `chant sql plan` covers the target, and classifies every change.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { deepObservation, type DeepObservationResult, type DeepResourceObservation, type DeepNormalizationHooks } from "@intentius/chant/deep-observation";
|
|
18
|
+
import type { UnobservedEntity } from "@intentius/chant/lexicon";
|
|
19
|
+
import { bindClickHouse, classifyClickHouseFailure, type BindOptions } from "../live/bind";
|
|
20
|
+
import { readLiveSchema, type LiveObject } from "../live/catalog";
|
|
21
|
+
import { database, table, view, CLICKHOUSE_ENTITY_TYPES, type ColumnDef } from "../entities";
|
|
22
|
+
import { canonicalObject, type CanonicalColumn, type CanonicalObject } from "./normalize";
|
|
23
|
+
|
|
24
|
+
type Props = Record<string, unknown>;
|
|
25
|
+
|
|
26
|
+
// `concurrently` is how a Postgres index is created, not a property of it.
|
|
27
|
+
const PRUNED = new Set(["ddl", "source", "lineage", "reads", "to", "orReplace", "ifNotExists", "concurrently"]);
|
|
28
|
+
|
|
29
|
+
export const sqlDeepNormalizationHooks: DeepNormalizationHooks = {
|
|
30
|
+
prune: (node) => PRUNED.has(node.pattern.split(/[.[]/)[0]!),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function liveProps(o: LiveObject): Props {
|
|
34
|
+
const tag = o.type === CLICKHOUSE_ENTITY_TYPES.database ? database : o.type === CLICKHOUSE_ENTITY_TYPES.table ? table : view;
|
|
35
|
+
const strings = Object.assign([o.statement], { raw: [o.statement] }) as unknown as TemplateStringsArray;
|
|
36
|
+
return { ...(tag(strings).props as unknown as Props) };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const sameColumn = (a: CanonicalColumn, b: CanonicalColumn) => {
|
|
40
|
+
const strip = ({ text: _t, position: _p, previously: _v, ...rest }: CanonicalColumn) => rest;
|
|
41
|
+
return JSON.stringify(strip(a)) === JSON.stringify(strip(b));
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/** The live props, with each field the declaration means the same as written the declaration's way. */
|
|
45
|
+
export function inDeclaredVocabulary(declared: Props, live: Props, d: CanonicalObject, l: CanonicalObject): Props {
|
|
46
|
+
const out: Props = { ...live };
|
|
47
|
+
const same = (k: keyof CanonicalObject) => JSON.stringify(d[k]) === JSON.stringify(l[k]);
|
|
48
|
+
const adopt = (key: string, equal: boolean) => {
|
|
49
|
+
if (!equal) return;
|
|
50
|
+
if (declared[key] === undefined) delete out[key];
|
|
51
|
+
else out[key] = declared[key];
|
|
52
|
+
};
|
|
53
|
+
adopt("name", d.name === l.name);
|
|
54
|
+
adopt("database", d.database === l.database);
|
|
55
|
+
adopt("engine", same("engine"));
|
|
56
|
+
for (const k of ["orderBy", "primaryKey", "partitionBy", "sampleBy", "ttl", "comment", "select", "refresh"] as const) adopt(k, same(k));
|
|
57
|
+
adopt("settings", same("settings"));
|
|
58
|
+
adopt("indexes", same("indexes"));
|
|
59
|
+
adopt("projections", same("projections"));
|
|
60
|
+
adopt("constraints", same("constraints"));
|
|
61
|
+
|
|
62
|
+
const declaredColumns = (declared.columns as ColumnDef[] | undefined) ?? [];
|
|
63
|
+
if (d.kind === "view" || d.kind === "materializedView") {
|
|
64
|
+
// The server infers a view's columns; a declaration that lists none is not drift.
|
|
65
|
+
if (declaredColumns.length === 0) out.columns = [];
|
|
66
|
+
} else if (d.kind === "table") {
|
|
67
|
+
const liveColumns = (live.columns as ColumnDef[] | undefined) ?? [];
|
|
68
|
+
out.columns = liveColumns.map((c, i) => {
|
|
69
|
+
const lc = l.columns[i];
|
|
70
|
+
const dc = d.columns.find((x) => x.name === c.name);
|
|
71
|
+
const di = dc ? declaredColumns[dc.position] : undefined;
|
|
72
|
+
return lc && dc && di && sameColumn(lc, dc) ? di : c;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function observeResourcesDeep(
|
|
79
|
+
options: {
|
|
80
|
+
environment: string;
|
|
81
|
+
entityNames: string[];
|
|
82
|
+
entities: Map<string, { entityType: string; props: Record<string, unknown> }>;
|
|
83
|
+
} & Omit<BindOptions, "environment">,
|
|
84
|
+
): Promise<DeepObservationResult> {
|
|
85
|
+
const resources: Record<string, DeepResourceObservation> = {};
|
|
86
|
+
const unobserved: Record<string, UnobservedEntity> = {};
|
|
87
|
+
let target;
|
|
88
|
+
let live: LiveObject[];
|
|
89
|
+
try {
|
|
90
|
+
target = await bindClickHouse(options);
|
|
91
|
+
live = await readLiveSchema(target);
|
|
92
|
+
} catch (err) {
|
|
93
|
+
const why = classifyClickHouseFailure(err);
|
|
94
|
+
for (const name of options.entityNames) {
|
|
95
|
+
unobserved[name] = { type: options.entities.get(name)?.entityType ?? "", reason: why.reason, detail: why.detail };
|
|
96
|
+
}
|
|
97
|
+
return deepObservation({}, unobserved);
|
|
98
|
+
}
|
|
99
|
+
const byKey = new Map(live.map((o) => [`${o.database ?? ""}.${o.name}`, o]));
|
|
100
|
+
for (const name of options.entityNames) {
|
|
101
|
+
const entity = options.entities.get(name);
|
|
102
|
+
if (!entity || !entity.entityType.startsWith("ClickHouse::")) {
|
|
103
|
+
unobserved[name] = { type: entity?.entityType ?? "", reason: "unsupported-kind" };
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const props = entity.props;
|
|
107
|
+
const isDb = entity.entityType === CLICKHOUSE_ENTITY_TYPES.database;
|
|
108
|
+
const db = isDb ? undefined : typeof props.database === "string" ? props.database : target.defaultDatabase;
|
|
109
|
+
const o = byKey.get(`${db ?? ""}.${String(props.name)}`);
|
|
110
|
+
if (!o) continue;
|
|
111
|
+
try {
|
|
112
|
+
const d = canonicalObject(String(props.ddl), target.defaultDatabase);
|
|
113
|
+
const l = canonicalObject(o.statement, target.defaultDatabase);
|
|
114
|
+
resources[name] = {
|
|
115
|
+
type: o.type,
|
|
116
|
+
physicalId: o.uuid ?? `${db ? `${db}.` : ""}${o.name}`,
|
|
117
|
+
properties: inDeclaredVocabulary(props, liveProps(o), d, l),
|
|
118
|
+
};
|
|
119
|
+
} catch (err) {
|
|
120
|
+
unobserved[name] = { type: entity.entityType, reason: "read-failed", detail: `the server's definition does not parse: ${(err as Error).message}` };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return deepObservation(resources, unobserved);
|
|
124
|
+
}
|