@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,157 @@
|
|
|
1
|
+
import { afterAll, beforeAll, describe, expect, test } from "vitest";
|
|
2
|
+
import { ClickHouseSqlParser } from "./parser";
|
|
3
|
+
import { ClickHouseGenerator } from "./generator";
|
|
4
|
+
import { exportNames, objectsToIR, splitStatements, stripServerDefaults } from "./ir";
|
|
5
|
+
import { exportResources } from "./live-export";
|
|
6
|
+
import { fakeClickHouse, type FakeServer } from "../testing/fake-server";
|
|
7
|
+
|
|
8
|
+
const SCHEMA = `
|
|
9
|
+
CREATE DATABASE analytics ENGINE = Atomic;
|
|
10
|
+
|
|
11
|
+
CREATE TABLE analytics.events
|
|
12
|
+
(
|
|
13
|
+
\`user_id\` UUID,
|
|
14
|
+
\`kind\` LowCardinality(String),
|
|
15
|
+
\`my col\` String DEFAULT 'a\`b'
|
|
16
|
+
)
|
|
17
|
+
ENGINE = MergeTree
|
|
18
|
+
ORDER BY (user_id, kind)
|
|
19
|
+
SETTINGS index_granularity = 8192;
|
|
20
|
+
|
|
21
|
+
CREATE MATERIALIZED VIEW analytics.counts TO analytics.daily
|
|
22
|
+
(
|
|
23
|
+
\`kind\` LowCardinality(String),
|
|
24
|
+
\`n\` UInt64
|
|
25
|
+
)
|
|
26
|
+
AS SELECT kind, count() AS n
|
|
27
|
+
FROM analytics.events
|
|
28
|
+
GROUP BY kind;
|
|
29
|
+
|
|
30
|
+
CREATE TABLE analytics.daily (kind LowCardinality(String), n UInt64) ENGINE = SummingMergeTree ORDER BY kind;
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
describe("reading a file of statements", () => {
|
|
34
|
+
test("splits on top-level semicolons only", () => {
|
|
35
|
+
expect(splitStatements("CREATE TABLE a (s String DEFAULT ';') ENGINE = Log; ; CREATE DATABASE b")).toEqual([
|
|
36
|
+
"CREATE TABLE a (s String DEFAULT ';') ENGINE = Log",
|
|
37
|
+
"CREATE DATABASE b",
|
|
38
|
+
]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("each statement becomes one resource of its type, a bad one a warning", () => {
|
|
42
|
+
const ir = new ClickHouseSqlParser().parse(`${SCHEMA}\nCREATE TABLE broken (a Strin g) ENGINE = Log;\nINSERT INTO t VALUES (1);`);
|
|
43
|
+
expect(ir.resources.map((r) => [r.logicalId, r.type])).toEqual([
|
|
44
|
+
["analyticsDb", "ClickHouse::Database"],
|
|
45
|
+
["events", "ClickHouse::Table"],
|
|
46
|
+
["counts", "ClickHouse::MaterializedView"],
|
|
47
|
+
["daily", "ClickHouse::Table"],
|
|
48
|
+
]);
|
|
49
|
+
expect(ir.warnings).toHaveLength(2);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe("export names", () => {
|
|
54
|
+
test("a database is suffixed Db, a shared table name takes its database, a reserved word is avoided", () => {
|
|
55
|
+
expect(
|
|
56
|
+
exportNames([
|
|
57
|
+
{ type: "ClickHouse::Database", name: "default", ddl: "" },
|
|
58
|
+
{ type: "ClickHouse::Table", database: "a", name: "events", ddl: "" },
|
|
59
|
+
{ type: "ClickHouse::Table", database: "b", name: "events", ddl: "" },
|
|
60
|
+
{ type: "ClickHouse::Table", database: "a", name: "class", ddl: "" },
|
|
61
|
+
{ type: "ClickHouse::Table", database: "a", name: "00_raw", ddl: "" },
|
|
62
|
+
]),
|
|
63
|
+
).toEqual(["defaultDb", "aEvents", "bEvents", "classTable", "t00Raw"]);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe("what the server adds is left out by default", () => {
|
|
68
|
+
test("a setting at its default goes, another stays", () => {
|
|
69
|
+
const out = stripServerDefaults(
|
|
70
|
+
"CREATE TABLE t\n(\n `a` UInt8\n)\nENGINE = MergeTree\nORDER BY a\nSETTINGS index_granularity = 8192, min_bytes_for_wide_part = 0",
|
|
71
|
+
);
|
|
72
|
+
expect(out).toContain("SETTINGS min_bytes_for_wide_part = 0");
|
|
73
|
+
expect(out).not.toContain("index_granularity");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("a view's inferred column list goes", () => {
|
|
77
|
+
const out = stripServerDefaults("CREATE VIEW v\n(\n `id` UInt64\n)\nAS SELECT id\nFROM t");
|
|
78
|
+
expect(out).toBe("CREATE VIEW v\nAS SELECT id\nFROM t");
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe("generating declarations", () => {
|
|
83
|
+
const ir = new ClickHouseSqlParser().parse(SCHEMA);
|
|
84
|
+
const [file] = new ClickHouseGenerator().generate(ir);
|
|
85
|
+
|
|
86
|
+
test("one schema.ts, references interpolated, each declaration after what it references", () => {
|
|
87
|
+
expect(file!.path).toBe("schema.ts");
|
|
88
|
+
const src = file!.content;
|
|
89
|
+
expect(src).toContain('import { database, table, view } from "@intentius/chant-lexicon-sql/clickhouse";');
|
|
90
|
+
expect(src).toContain("CREATE TABLE ${analyticsDb}.events");
|
|
91
|
+
expect(src).toContain("TO ${daily}");
|
|
92
|
+
expect(src).toContain("FROM ${events}");
|
|
93
|
+
const order = [...src.matchAll(/export const (\w+)/g)].map((m) => m[1]);
|
|
94
|
+
expect(order).toEqual(["analyticsDb", "events", "daily", "counts"]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("identifiers lose their backquotes, and one that needs quoting is double-quoted", () => {
|
|
98
|
+
expect(file!.content).toContain("user_id UUID");
|
|
99
|
+
expect(file!.content).toContain('"my col" String');
|
|
100
|
+
expect(file!.content).toContain("DEFAULT 'a\\`b'");
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe("live export", () => {
|
|
105
|
+
let server: FakeServer;
|
|
106
|
+
beforeAll(async () => {
|
|
107
|
+
server = await fakeClickHouse([
|
|
108
|
+
{ name: "default", engine: "Atomic", statement: "CREATE DATABASE default\nENGINE = Atomic" },
|
|
109
|
+
{ name: "analytics", engine: "Atomic", statement: "CREATE DATABASE analytics\nENGINE = Atomic" },
|
|
110
|
+
{
|
|
111
|
+
database: "analytics",
|
|
112
|
+
name: "events",
|
|
113
|
+
engine: "MergeTree",
|
|
114
|
+
statement:
|
|
115
|
+
"CREATE TABLE analytics.events\n(\n `id` UInt64\n)\nENGINE = MergeTree\nORDER BY id\nSETTINGS index_granularity = 8192\nCOMMENT 'Raw events [chant managed-by=chant stack=shop]'",
|
|
116
|
+
comment: "Raw events [chant managed-by=chant stack=shop]",
|
|
117
|
+
},
|
|
118
|
+
]);
|
|
119
|
+
});
|
|
120
|
+
afterAll(() => server.close());
|
|
121
|
+
|
|
122
|
+
const run = (extra: Record<string, unknown> = {}) =>
|
|
123
|
+
exportResources({ environment: "x", config: {}, env: { CLICKHOUSE_URL: server.url }, ...extra });
|
|
124
|
+
|
|
125
|
+
test("exports every object but the default database, defaults stripped", async () => {
|
|
126
|
+
const ir = await run();
|
|
127
|
+
expect(ir.resources.map((r) => r.logicalId)).toEqual(["analyticsDb", "events"]);
|
|
128
|
+
expect(String(ir.resources[1]!.properties.ddl)).not.toContain("index_granularity");
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("verbatim keeps the statement as the server printed it", async () => {
|
|
132
|
+
const ir = await run({ verbatim: true });
|
|
133
|
+
expect(String(ir.resources[1]!.properties.ddl)).toContain("index_granularity = 8192");
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("a selector narrows by type and name", async () => {
|
|
137
|
+
expect((await run({ selector: { name: "analytics.events" } })).resources.map((r) => r.logicalId)).toEqual(["events"]);
|
|
138
|
+
expect((await run({ selector: { type: "ClickHouse::Database" } })).resources.map((r) => r.logicalId)).toEqual(["analyticsDb"]);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("owned keeps the objects carrying chant's marker (#3208)", async () => {
|
|
142
|
+
const ir = await run({ owned: true });
|
|
143
|
+
expect(ir.resources.map((r) => r.logicalId)).toEqual(["events"]);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("the ownership marker is never written into a declaration (#3208)", async () => {
|
|
147
|
+
const ddl = String((await run()).resources[1]!.properties.ddl);
|
|
148
|
+
expect(ddl).toContain("COMMENT 'Raw events'");
|
|
149
|
+
expect(ddl).not.toContain("[chant");
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test("the IR builds back through the generator", async () => {
|
|
153
|
+
const ir = await run();
|
|
154
|
+
expect(objectsToIR([]).resources).toEqual([]);
|
|
155
|
+
expect(new ClickHouseGenerator().generate(ir)[0]!.content).toContain("CREATE TABLE ${analyticsDb}.events");
|
|
156
|
+
});
|
|
157
|
+
});
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClickHouse DDL into the import IR, and back out as `database`, `table` and
|
|
3
|
+
* `view` declarations.
|
|
4
|
+
*
|
|
5
|
+
* `chant import --from <env>` reads each object's `SHOW CREATE` and `chant
|
|
6
|
+
* import schema.sql` reads a file of CREATE statements; both arrive here as
|
|
7
|
+
* statements. The generated declaration is the statement itself, the
|
|
8
|
+
* server's canonical form when it came from a server (#3046 question 5), with
|
|
9
|
+
* two changes:
|
|
10
|
+
*
|
|
11
|
+
* - a qualified name of another imported object becomes a reference to its
|
|
12
|
+
* export (`FROM analytics.events` is `FROM ${events}`), and the database
|
|
13
|
+
* part of an object's own name becomes a reference to the database's export,
|
|
14
|
+
* so dependency order survives the import;
|
|
15
|
+
* - a backquoted identifier that needs no quoting is written bare, and one that
|
|
16
|
+
* does is double-quoted, so the template has no backquotes to escape.
|
|
17
|
+
*
|
|
18
|
+
* Columns written by name inside a view's SELECT stay text: which table a
|
|
19
|
+
* bare name belongs to is the server's to resolve, and a guess would be
|
|
20
|
+
* wrong lineage. An imported view therefore records its reads, not its column
|
|
21
|
+
* lineage, until its column references are written as `${t.columns.c}`.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import type { ResourceIR, TemplateIR } from "@intentius/chant/import/parser";
|
|
25
|
+
import { isTrivia, tokenizeText, untokenize, type Token } from "../tokens";
|
|
26
|
+
import { parseCreate, unquote, type CreateNode, type Span } from "../parser";
|
|
27
|
+
import { CLICKHOUSE_ENTITY_TYPES, type ClickHouseEntityType } from "../entities";
|
|
28
|
+
import { MERGE_TREE_SETTINGS } from "../../generated/clickhouse";
|
|
29
|
+
|
|
30
|
+
export interface ImportedObject {
|
|
31
|
+
type: ClickHouseEntityType;
|
|
32
|
+
database?: string;
|
|
33
|
+
name: string;
|
|
34
|
+
/** The CREATE statement. */
|
|
35
|
+
ddl: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const JS_RESERVED = new Set(
|
|
39
|
+
"break case catch class const continue debugger default delete do else enum export extends false finally for function if import in instanceof new null return super switch this throw true try typeof var void while with yield let static implements interface package private protected public await".split(
|
|
40
|
+
" ",
|
|
41
|
+
),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
function camel(name: string): string {
|
|
45
|
+
const words = name.split(/[^A-Za-z0-9]+/).filter(Boolean);
|
|
46
|
+
if (words.length === 0) return "object";
|
|
47
|
+
const s = words.map((w, i) => (i === 0 ? w[0]!.toLowerCase() + w.slice(1) : w[0]!.toUpperCase() + w.slice(1))).join("");
|
|
48
|
+
return /^[0-9]/.test(s) ? `t${s}` : s;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Export names for a set of objects. A table or view is its name in camel
|
|
53
|
+
* case, prefixed with its database when two databases share a name; a
|
|
54
|
+
* database is its name with `Db` after it, so `analytics` the database and
|
|
55
|
+
* `analytics` a table do not collide.
|
|
56
|
+
*/
|
|
57
|
+
export function exportNames(objects: readonly ImportedObject[]): string[] {
|
|
58
|
+
const relations = objects.filter((o) => o.type !== CLICKHOUSE_ENTITY_TYPES.database);
|
|
59
|
+
const count = new Map<string, number>();
|
|
60
|
+
for (const o of relations) count.set(o.name, (count.get(o.name) ?? 0) + 1);
|
|
61
|
+
const used = new Set<string>();
|
|
62
|
+
return objects.map((o) => {
|
|
63
|
+
let base =
|
|
64
|
+
o.type === CLICKHOUSE_ENTITY_TYPES.database
|
|
65
|
+
? `${camel(o.name)}Db`
|
|
66
|
+
: (count.get(o.name) ?? 0) > 1 && o.database
|
|
67
|
+
? camel(`${o.database}_${o.name}`)
|
|
68
|
+
: camel(o.name);
|
|
69
|
+
if (JS_RESERVED.has(base)) base = `${base}Table`;
|
|
70
|
+
let name = base;
|
|
71
|
+
for (let i = 2; used.has(name); i++) name = `${base}${i}`;
|
|
72
|
+
used.add(name);
|
|
73
|
+
return name;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Split a file of statements on top-level `;`. */
|
|
78
|
+
export function splitStatements(text: string): string[] {
|
|
79
|
+
const out: string[] = [];
|
|
80
|
+
let current: Token[] = [];
|
|
81
|
+
const flush = () => {
|
|
82
|
+
const stmt = current.map((t) => t.text).join("").trim();
|
|
83
|
+
if (current.some((t) => !isTrivia(t))) out.push(stmt);
|
|
84
|
+
current = [];
|
|
85
|
+
};
|
|
86
|
+
for (const t of tokenizeText(text, 0)) {
|
|
87
|
+
if (t.kind === "punct" && t.text === ";") flush();
|
|
88
|
+
else current.push(t);
|
|
89
|
+
}
|
|
90
|
+
flush();
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const statementType = (node: CreateNode): ClickHouseEntityType =>
|
|
95
|
+
node.statement === "database"
|
|
96
|
+
? CLICKHOUSE_ENTITY_TYPES.database
|
|
97
|
+
: node.statement === "table"
|
|
98
|
+
? CLICKHOUSE_ENTITY_TYPES.table
|
|
99
|
+
: node.materialized
|
|
100
|
+
? CLICKHOUSE_ENTITY_TYPES.materializedView
|
|
101
|
+
: CLICKHOUSE_ENTITY_TYPES.view;
|
|
102
|
+
|
|
103
|
+
function nameOf(tokens: Token[], span: Span): { database?: string; name: string } {
|
|
104
|
+
const parts = tokens
|
|
105
|
+
.slice(span.from, span.to)
|
|
106
|
+
.filter((t) => !isTrivia(t) && !(t.kind === "punct" && t.text === "."))
|
|
107
|
+
.map((t) => unquote(t.text));
|
|
108
|
+
return parts.length >= 2 ? { database: parts[parts.length - 2], name: parts[parts.length - 1]! } : { name: parts[0] ?? "" };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Read a statement's kind and name. Throws the parser's error when it does not parse. */
|
|
112
|
+
export function describeStatement(ddl: string): ImportedObject {
|
|
113
|
+
const tokens = tokenizeText(ddl, 0);
|
|
114
|
+
const node = parseCreate(tokens);
|
|
115
|
+
return { type: statementType(node), ...nameOf(tokens, node.name), ddl };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Leave out what the server adds and the declaration would not say: settings
|
|
120
|
+
* at the pinned server's default (`index_granularity = 8192`), and a view's
|
|
121
|
+
* column list, which the server infers from the SELECT. A server re-adds both
|
|
122
|
+
* on create, so the stripped statement creates the same object.
|
|
123
|
+
*/
|
|
124
|
+
export function stripServerDefaults(ddl: string): string {
|
|
125
|
+
const tokens = tokenizeText(ddl, 0);
|
|
126
|
+
let node: CreateNode;
|
|
127
|
+
try {
|
|
128
|
+
node = parseCreate(tokens);
|
|
129
|
+
} catch {
|
|
130
|
+
return ddl;
|
|
131
|
+
}
|
|
132
|
+
const edits: Array<{ span: Span; text: string }> = [];
|
|
133
|
+
if (node.statement !== "database" && node.settings && node.settingsClause) {
|
|
134
|
+
const text = (s: Span) => tokens.slice(s.from, s.to).map((t) => t.text).join("").trim();
|
|
135
|
+
const kept = node.settings.filter((s) => {
|
|
136
|
+
const def = (MERGE_TREE_SETTINGS as Record<string, { default: string } | undefined>)[s.key];
|
|
137
|
+
return !def || text(s.value).replace(/^'|'$/g, "") !== def.default;
|
|
138
|
+
});
|
|
139
|
+
if (kept.length !== node.settings.length) {
|
|
140
|
+
edits.push({
|
|
141
|
+
span: node.settingsClause,
|
|
142
|
+
text: kept.length === 0 ? "" : `SETTINGS ${kept.map((s) => `${s.key} = ${text(s.value)}`).join(", ")}`,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (node.statement === "view" && node.columnsSpan) edits.push({ span: node.columnsSpan, text: "" });
|
|
147
|
+
if (edits.length === 0) return ddl;
|
|
148
|
+
edits.sort((a, b) => b.span.from - a.span.from);
|
|
149
|
+
const out = [...tokens];
|
|
150
|
+
for (const e of edits) {
|
|
151
|
+
out.splice(e.span.from, e.span.to - e.span.from, { kind: "ws", text: e.text, part: 0, start: 0, end: 0 });
|
|
152
|
+
}
|
|
153
|
+
return out
|
|
154
|
+
.map((t) => t.text)
|
|
155
|
+
.join("")
|
|
156
|
+
.split("\n")
|
|
157
|
+
.filter((line) => line.trim().length > 0)
|
|
158
|
+
.join("\n")
|
|
159
|
+
.replace(/[ \t]+$/gm, "");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** The IR for a set of objects. */
|
|
163
|
+
export function objectsToIR(objects: readonly ImportedObject[], warnings: string[] = []): TemplateIR {
|
|
164
|
+
const names = exportNames(objects);
|
|
165
|
+
const resources: ResourceIR[] = objects.map((o, i) => ({
|
|
166
|
+
logicalId: names[i]!,
|
|
167
|
+
type: o.type,
|
|
168
|
+
properties: { ...(o.database ? { database: o.database } : {}), name: o.name, ddl: o.ddl },
|
|
169
|
+
}));
|
|
170
|
+
return { resources, parameters: [], ...(warnings.length ? { warnings } : {}) };
|
|
171
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live export: `chant import --from <env>` writes the server's schema as
|
|
3
|
+
* `database`, `table` and `view` declarations.
|
|
4
|
+
*
|
|
5
|
+
* Every object in the environment's databases is read with `SHOW CREATE`, the
|
|
6
|
+
* server's canonical form, which is the baseline #3046 question 5 asks for.
|
|
7
|
+
* By default what the server adds on its own is left out (settings at their
|
|
8
|
+
* default, a view's inferred column list), so the declaration says what an
|
|
9
|
+
* author would; `verbatim` keeps the statement as the server printed it.
|
|
10
|
+
*
|
|
11
|
+
* - `selector.type` is an entity type (`ClickHouse::Table`); `selector.name` is
|
|
12
|
+
* an object name, `db.name` or `name`.
|
|
13
|
+
* - `owned` keeps the objects whose comment carries chant's ownership marker
|
|
14
|
+
* (`../ownership.ts`), the trailer the applier stamps. The trailer itself is
|
|
15
|
+
* never written into a declaration: `readLiveSchema` takes it off.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { ExportedTemplate, ResourceSelector } from "@intentius/chant/lexicon";
|
|
19
|
+
import { bindClickHouse, type BindOptions } from "../live/bind";
|
|
20
|
+
import { readLiveSchema } from "../live/catalog";
|
|
21
|
+
import { objectsToIR, stripServerDefaults, type ImportedObject } from "./ir";
|
|
22
|
+
import { isChantManaged } from "../ownership";
|
|
23
|
+
|
|
24
|
+
export interface ExportOptions extends Omit<BindOptions, "environment"> {
|
|
25
|
+
environment: string;
|
|
26
|
+
stack?: string;
|
|
27
|
+
region?: string;
|
|
28
|
+
selector?: ResourceSelector;
|
|
29
|
+
owned?: boolean;
|
|
30
|
+
verbatim?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function exportResources(options: ExportOptions): Promise<ExportedTemplate> {
|
|
34
|
+
const target = await bindClickHouse(options);
|
|
35
|
+
const live = await readLiveSchema(target);
|
|
36
|
+
const selected = live.filter((o) => {
|
|
37
|
+
if (options.owned && !isChantManaged(o.comment)) return false;
|
|
38
|
+
if (options.selector?.type && o.type !== options.selector.type) return false;
|
|
39
|
+
const name = options.selector?.name;
|
|
40
|
+
if (name !== undefined && name !== o.name && name !== `${o.database}.${o.name}`) return false;
|
|
41
|
+
return true;
|
|
42
|
+
});
|
|
43
|
+
const objects: ImportedObject[] = selected
|
|
44
|
+
// The `default` database exists on every server; declaring it would make apply create what is there.
|
|
45
|
+
.filter((o) => !(o.type === "ClickHouse::Database" && o.name === "default"))
|
|
46
|
+
.map((o) => ({
|
|
47
|
+
type: o.type,
|
|
48
|
+
...(o.database ? { database: o.database } : {}),
|
|
49
|
+
name: o.name,
|
|
50
|
+
ddl: options.verbatim ? o.statement : stripServerDefaults(o.statement),
|
|
51
|
+
}));
|
|
52
|
+
return objectsToIR(objects) as ExportedTemplate;
|
|
53
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant import schema.sql`: a file of ClickHouse CREATE statements into the
|
|
3
|
+
* import IR. Each statement must parse; one that does not is reported in the
|
|
4
|
+
* IR's warnings and left out, with the parser's message.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { TemplateIR, TemplateParser } from "@intentius/chant/import/parser";
|
|
8
|
+
import { describeStatement, objectsToIR, splitStatements, type ImportedObject } from "./ir";
|
|
9
|
+
|
|
10
|
+
export class ClickHouseSqlParser implements TemplateParser {
|
|
11
|
+
parse(content: string): TemplateIR {
|
|
12
|
+
const objects: ImportedObject[] = [];
|
|
13
|
+
const warnings: string[] = [];
|
|
14
|
+
for (const stmt of splitStatements(content)) {
|
|
15
|
+
if (!/^\s*CREATE\b/i.test(stmt)) {
|
|
16
|
+
warnings.push(`not a CREATE statement, left out: ${stmt.split("\n")[0]!.slice(0, 80)}`);
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
objects.push(describeStatement(stmt));
|
|
21
|
+
} catch (err) {
|
|
22
|
+
warnings.push(`does not parse, left out (${(err as Error).message}): ${stmt.split("\n")[0]!.slice(0, 80)}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return objectsToIR(objects, warnings);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The import round trip, offline: a file of CREATE statements is imported as
|
|
3
|
+
* declarations, the declarations are built back into statements, and importing
|
|
4
|
+
* those gives the same declarations. Nothing the import writes is lost or
|
|
5
|
+
* reordered by the build.
|
|
6
|
+
*
|
|
7
|
+
* The same schema runs against two live servers in `../live/roundtrip.e2e.test.ts`
|
|
8
|
+
* (import, build, apply, catalog unchanged); this file is the part of that
|
|
9
|
+
* round trip that needs no Docker.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { afterAll, describe, expect, test } from "vitest";
|
|
15
|
+
import { build } from "@intentius/chant/build";
|
|
16
|
+
import type { SerializerResult } from "@intentius/chant/serializer";
|
|
17
|
+
import { sqlPlugin } from "../../plugin";
|
|
18
|
+
import { CLICKHOUSE_DDL_FILE, sqlSerializer } from "../../serializer";
|
|
19
|
+
import { SCHEMA } from "../testing/roundtrip-schema";
|
|
20
|
+
import { ClickHouseGenerator } from "./generator";
|
|
21
|
+
import { splitStatements } from "./ir";
|
|
22
|
+
import { ClickHouseSqlParser } from "./parser";
|
|
23
|
+
|
|
24
|
+
// Inside the package, so the declarations resolve `@intentius/chant-lexicon-sql/clickhouse` as the e2e test does.
|
|
25
|
+
const dir = join(import.meta.dirname, "..", "..", "..", `.roundtrip-offline-tmp-${process.pid}`);
|
|
26
|
+
afterAll(() => rmSync(dir, { recursive: true, force: true }));
|
|
27
|
+
|
|
28
|
+
const parser = new ClickHouseSqlParser();
|
|
29
|
+
const generator = new ClickHouseGenerator();
|
|
30
|
+
|
|
31
|
+
/** Whitespace folded: the build keeps an author's own line breaks and indent, and the import indents the text it writes. */
|
|
32
|
+
const squash = (text: string) => text.replace(/\s+/g, " ").trim();
|
|
33
|
+
|
|
34
|
+
/** A generated file as its export declarations, whitespace folded and sorted: the order follows dependencies. */
|
|
35
|
+
const declarations = (content: string) => content.split(/^export const /m).slice(1).map(squash).sort();
|
|
36
|
+
|
|
37
|
+
/** Declarations to the statements the build writes, in the order it wrote them. */
|
|
38
|
+
async function buildStatements(name: string, source: string): Promise<string[]> {
|
|
39
|
+
const project = join(dir, name);
|
|
40
|
+
mkdirSync(join(project, "src"), { recursive: true });
|
|
41
|
+
writeFileSync(join(project, "chant.config.ts"), 'export default { lexicons: ["sql"] };\n');
|
|
42
|
+
writeFileSync(join(project, "src", "schema.ts"), source);
|
|
43
|
+
const result = await build(join(project, "src"), [sqlSerializer], undefined, {
|
|
44
|
+
fold: true,
|
|
45
|
+
intrinsics: sqlPlugin.intrinsics!(),
|
|
46
|
+
lexicons: ["sql"],
|
|
47
|
+
});
|
|
48
|
+
expect(result.errors).toEqual([]);
|
|
49
|
+
return splitStatements((result.outputs.get("sql") as SerializerResult).files![CLICKHOUSE_DDL_FILE]!);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
describe("import, build, import again", () => {
|
|
53
|
+
const ir = parser.parse(SCHEMA.join(";\n"));
|
|
54
|
+
const [file] = generator.generate(ir);
|
|
55
|
+
|
|
56
|
+
test("every statement of the schema is imported", () => {
|
|
57
|
+
expect(ir.warnings ?? []).toEqual([]);
|
|
58
|
+
expect(ir.resources.map((r) => r.type)).toEqual([
|
|
59
|
+
"ClickHouse::Database",
|
|
60
|
+
"ClickHouse::Table",
|
|
61
|
+
"ClickHouse::Table",
|
|
62
|
+
"ClickHouse::Table",
|
|
63
|
+
"ClickHouse::MaterializedView",
|
|
64
|
+
"ClickHouse::View",
|
|
65
|
+
"ClickHouse::Table",
|
|
66
|
+
]);
|
|
67
|
+
expect(file!.content).toContain("export const events = table`");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("the declarations build back to one statement per object, dependencies first", async () => {
|
|
71
|
+
const statements = await buildStatements("first", file!.content);
|
|
72
|
+
expect(statements).toHaveLength(SCHEMA.length);
|
|
73
|
+
const at = (needle: string) => statements.findIndex((s) => s.includes(needle));
|
|
74
|
+
expect(at("CREATE DATABASE analytics")).toBeLessThan(at("analytics.events"));
|
|
75
|
+
expect(at("analytics.events")).toBeLessThan(at("daily_mv"));
|
|
76
|
+
expect(at("analytics.daily")).toBeLessThan(at("daily_mv"));
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("importing the built statements gives the same declarations", async () => {
|
|
80
|
+
const statements = await buildStatements("second", file!.content);
|
|
81
|
+
const again = generator.generate(parser.parse(statements.join(";\n")));
|
|
82
|
+
expect(declarations(again[0]!.content)).toEqual(declarations(file!.content));
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test("a second build writes the same statements, in whatever order dependencies allow", async () => {
|
|
86
|
+
const first = await buildStatements("third", file!.content);
|
|
87
|
+
const second = await buildStatements("fourth", generator.generate(parser.parse(first.join(";\n")))[0]!.content);
|
|
88
|
+
expect(second.map(squash).sort()).toEqual(first.map(squash).sort());
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which ClickHouse server a chant environment reads: the config lookup and
|
|
3
|
+
* the binding, shared by observation and live export so both read the same
|
|
4
|
+
* server.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ChantConfig } from "@intentius/chant/config";
|
|
8
|
+
import type { UnobservedReason } from "@intentius/chant/observation";
|
|
9
|
+
import { ClickHouseQueryError, clickhouseQuery, type ClickHouseEndpoint } from "../http";
|
|
10
|
+
|
|
11
|
+
export interface ClickHouseTarget {
|
|
12
|
+
endpoint: ClickHouseEndpoint;
|
|
13
|
+
/** Where the binding came from: `sql.profiles.prod` or `env CLICKHOUSE_URL`. */
|
|
14
|
+
source: string;
|
|
15
|
+
/** The databases in scope; undefined is every database but the server's own. */
|
|
16
|
+
databases?: string[];
|
|
17
|
+
defaultDatabase: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface UnresolvedTarget {
|
|
21
|
+
reason: "no-binding" | "no-credentials";
|
|
22
|
+
detail: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const isUnresolvedTarget = (v: ClickHouseTarget | UnresolvedTarget): v is UnresolvedTarget => "reason" in v;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The server an environment reads. Pure: `config` and `env` are passed in.
|
|
29
|
+
*
|
|
30
|
+
* 1. `sql.profiles.<environment>`. A profile naming a credential variable that
|
|
31
|
+
* is not set is `no-credentials`: the profile said how to authenticate.
|
|
32
|
+
* 2. `CLICKHOUSE_URL`, with `CLICKHOUSE_USER` and `CLICKHOUSE_PASSWORD` when set.
|
|
33
|
+
* 3. Otherwise `no-binding`.
|
|
34
|
+
*/
|
|
35
|
+
export function resolveClickHouseTarget(input: {
|
|
36
|
+
environment?: string;
|
|
37
|
+
config?: Pick<ChantConfig, "sql">;
|
|
38
|
+
env?: Record<string, string | undefined>;
|
|
39
|
+
}): ClickHouseTarget | UnresolvedTarget {
|
|
40
|
+
const env = input.env ?? process.env;
|
|
41
|
+
const profile = input.environment !== undefined ? input.config?.sql?.profiles?.[input.environment] : undefined;
|
|
42
|
+
if (profile) {
|
|
43
|
+
const source = `sql.profiles.${input.environment}`;
|
|
44
|
+
const endpoint: ClickHouseEndpoint = { url: profile.url.replace(/\/+$/, "") };
|
|
45
|
+
for (const key of ["user", "password"] as const) {
|
|
46
|
+
const ref = profile[key];
|
|
47
|
+
if (!ref) continue;
|
|
48
|
+
const value = env[ref.env];
|
|
49
|
+
if (value === undefined) return { reason: "no-credentials", detail: `${source}.${key} names ${ref.env}, which is not set` };
|
|
50
|
+
endpoint[key] = value;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
endpoint,
|
|
54
|
+
source,
|
|
55
|
+
...(profile.databases ? { databases: profile.databases } : {}),
|
|
56
|
+
defaultDatabase: profile.defaultDatabase ?? "default",
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const url = env.CLICKHOUSE_URL;
|
|
60
|
+
if (!url) {
|
|
61
|
+
const where = input.environment !== undefined ? `sql.profiles.${input.environment} is not declared and ` : "";
|
|
62
|
+
return { reason: "no-binding", detail: `${where}CLICKHOUSE_URL is not set, so there is no ClickHouse server to read` };
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
endpoint: {
|
|
66
|
+
url: url.replace(/\/+$/, ""),
|
|
67
|
+
...(env.CLICKHOUSE_USER !== undefined ? { user: env.CLICKHOUSE_USER } : {}),
|
|
68
|
+
...(env.CLICKHOUSE_PASSWORD !== undefined ? { password: env.CLICKHOUSE_PASSWORD } : {}),
|
|
69
|
+
},
|
|
70
|
+
source: "env CLICKHOUSE_URL",
|
|
71
|
+
defaultDatabase: "default",
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** A target that could not be resolved. */
|
|
76
|
+
export class ClickHouseBindingError extends Error {
|
|
77
|
+
constructor(readonly unresolved: UnresolvedTarget) {
|
|
78
|
+
super(unresolved.detail);
|
|
79
|
+
this.name = "ClickHouseBindingError";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface BindOptions {
|
|
84
|
+
environment?: string;
|
|
85
|
+
/** The project's config; loaded from `cwd` when omitted. */
|
|
86
|
+
config?: Pick<ChantConfig, "sql">;
|
|
87
|
+
cwd?: string;
|
|
88
|
+
env?: Record<string, string | undefined>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function loadConfig(cwd: string): Promise<Pick<ChantConfig, "sql"> | undefined> {
|
|
92
|
+
try {
|
|
93
|
+
const { loadChantConfig } = await import("@intentius/chant/config");
|
|
94
|
+
return (await loadChantConfig(cwd)).config;
|
|
95
|
+
} catch {
|
|
96
|
+
// No project config: the environment variables still bind.
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Resolve the environment's server. Throws {@link ClickHouseBindingError} when there is none. */
|
|
102
|
+
export async function bindClickHouse(options: BindOptions = {}): Promise<ClickHouseTarget> {
|
|
103
|
+
const config = options.config ?? (await loadConfig(options.cwd ?? process.cwd()));
|
|
104
|
+
const target = resolveClickHouseTarget({ environment: options.environment, config, env: options.env });
|
|
105
|
+
if (isUnresolvedTarget(target)) throw new ClickHouseBindingError(target);
|
|
106
|
+
return target;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** What a failed bind or read means, in the observation vocabulary. */
|
|
110
|
+
export function classifyClickHouseFailure(err: unknown): { reason: UnobservedReason; detail: string } {
|
|
111
|
+
if (err instanceof ClickHouseBindingError) return { reason: err.unresolved.reason, detail: err.unresolved.detail };
|
|
112
|
+
if (err instanceof ClickHouseQueryError) {
|
|
113
|
+
// 516 AUTHENTICATION_FAILED and 497 ACCESS_DENIED arrive as 401/403 or in the message.
|
|
114
|
+
if (err.status === 401 || err.status === 403 || /AUTHENTICATION_FAILED|ACCESS_DENIED|Code: 516|Code: 497/.test(err.serverMessage)) {
|
|
115
|
+
return { reason: "no-credentials", detail: `${err.message} (the server refused the credentials)` };
|
|
116
|
+
}
|
|
117
|
+
return { reason: "read-failed", detail: err.message };
|
|
118
|
+
}
|
|
119
|
+
return { reason: "read-failed", detail: err instanceof Error ? err.message.split("\n")[0]! : String(err) };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** `SELECT version()` on the target. */
|
|
123
|
+
export async function serverVersion(target: ClickHouseTarget): Promise<string> {
|
|
124
|
+
const [row] = await clickhouseQuery<{ v: string }>(target.endpoint, "SELECT version() AS v");
|
|
125
|
+
return row?.v ?? "";
|
|
126
|
+
}
|