@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,33 @@
|
|
|
1
|
+
import { checkOf, indexesOf, leadingColumns, tablesOf } from "./postgres-helpers";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SQLPG110: a btree index whose columns are a leading prefix of another index.
|
|
5
|
+
*
|
|
6
|
+
* Doc: https://www.postgresql.org/docs/18/indexes-multicolumn.html ("a
|
|
7
|
+
* multicolumn B-tree index can be used with query conditions that involve any
|
|
8
|
+
* subset of the index's columns, but the index is most efficient when there
|
|
9
|
+
* are constraints on the leading (leftmost) columns"). A plain index on (a)
|
|
10
|
+
* is served by one on (a, b) or by the primary key (a, b). A unique index
|
|
11
|
+
* enforces a rule and is kept.
|
|
12
|
+
*/
|
|
13
|
+
export const sqlpg110 = checkOf({ id: "SQLPG110", description: "A btree index is a prefix of another index" }, (ctx, report) => {
|
|
14
|
+
const indexes = indexesOf(ctx).filter((i) => (i.method ?? "btree") === "btree");
|
|
15
|
+
for (const t of tablesOf(ctx)) {
|
|
16
|
+
const wider: Array<{ label: string; cols: string[] }> = [];
|
|
17
|
+
if (t.primaryKey) wider.push({ label: "the primary key", cols: t.primaryKey.columns });
|
|
18
|
+
for (const u of t.uniques) wider.push({ label: "a unique constraint", cols: u.columns });
|
|
19
|
+
const mine = indexes.filter((i) => i.tableName === t.sqlName);
|
|
20
|
+
for (const i of mine) if (!i.where) wider.push({ label: i.sqlName, cols: leadingColumns(i) });
|
|
21
|
+
for (const i of mine) {
|
|
22
|
+
if (i.unique || i.where || i.include || !i.elements.every((e) => e.column)) continue;
|
|
23
|
+
const cols = i.elements.map((e) => e.column!);
|
|
24
|
+
const cover = wider.find((w) => w.label !== i.sqlName && w.cols.length > cols.length && cols.every((c, n) => w.cols[n] === c));
|
|
25
|
+
if (!cover) continue;
|
|
26
|
+
report({
|
|
27
|
+
severity: "warning",
|
|
28
|
+
message: `${i.export} (${i.sqlName}) on (${cols.join(", ")}) is a prefix of ${cover.label} (${cover.cols.join(", ")}); drop it`,
|
|
29
|
+
entity: i.export,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { checkOf, indexesOf, isMaterializedView } from "./postgres-helpers";
|
|
2
|
+
import { postgresObjects } from "./sql-helpers";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SQLPG111: a materialized view with no unique index.
|
|
6
|
+
*
|
|
7
|
+
* Doc: https://www.postgresql.org/docs/18/sql-refreshmaterializedview.html
|
|
8
|
+
* ("CONCURRENTLY ... is only allowed if there is at least one UNIQUE index on
|
|
9
|
+
* the materialized view which uses only column names and includes all rows").
|
|
10
|
+
* Without one, every refresh takes an ACCESS EXCLUSIVE lock and blocks readers.
|
|
11
|
+
*/
|
|
12
|
+
export const sqlpg111 = checkOf({ id: "SQLPG111", description: "A materialized view has no unique index, so it cannot refresh concurrently" }, (ctx, report) => {
|
|
13
|
+
const indexes = indexesOf(ctx);
|
|
14
|
+
for (const v of postgresObjects(ctx).filter(isMaterializedView)) {
|
|
15
|
+
const ok = indexes.some((i) => i.tableName === v.sqlName && i.unique && !i.where && i.elements.every((e) => e.column));
|
|
16
|
+
if (ok) continue;
|
|
17
|
+
report({
|
|
18
|
+
severity: "warning",
|
|
19
|
+
message: `${v.export} (${v.sqlName}) has no unique index over plain columns; REFRESH MATERIALIZED VIEW CONCURRENTLY is refused and a plain refresh blocks readers`,
|
|
20
|
+
entity: v.export,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { checkOf, tablesOf } from "./postgres-helpers";
|
|
2
|
+
|
|
3
|
+
const SENSITIVE = /(^|_)(password|passwd|pwd|secret|token|api_?key|ssn|social_security|tax_id|credit_card|card_number|cvv|iban|passport|date_of_birth|dob|email|phone|address)(_|$)/i;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* SQLPG112: a secret- or PII-named column in a table with no comment.
|
|
7
|
+
*
|
|
8
|
+
* Doc: https://www.postgresql.org/docs/18/sql-comment.html. A COMMENT on the
|
|
9
|
+
* table or the column is where the retention, encryption or masking rule is
|
|
10
|
+
* written down, and where pg_dump, anonymizers and catalog scanners read it.
|
|
11
|
+
* A column or a table comment satisfies the check.
|
|
12
|
+
*/
|
|
13
|
+
export const sqlpg112 = checkOf({ id: "SQLPG112", description: "A secret- or PII-named column with no comment on it or its table" }, (ctx, report) => {
|
|
14
|
+
for (const t of tablesOf(ctx)) {
|
|
15
|
+
if (t.comment) continue;
|
|
16
|
+
for (const c of t.columns) {
|
|
17
|
+
if (c.comment || !SENSITIVE.test(c.name)) continue;
|
|
18
|
+
report({
|
|
19
|
+
severity: "warning",
|
|
20
|
+
message: `${t.export}.${c.name} looks like a secret or personal data and neither it nor ${t.sqlName} has a COMMENT; say what it holds and how it is protected`,
|
|
21
|
+
entity: t.export,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { checkOf } from "./postgres-helpers";
|
|
2
|
+
import { postgresObjects } from "./sql-helpers";
|
|
3
|
+
|
|
4
|
+
const PLACED = new Set(["Postgres::Table", "Postgres::View", "Postgres::MaterializedView", "Postgres::Sequence", "Postgres::Enum", "Postgres::Domain"]);
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* SQLPG113: an object in the public schema while the project declares schemas.
|
|
8
|
+
*
|
|
9
|
+
* Doc: https://www.postgresql.org/docs/18/ddl-schemas.html#DDL-SCHEMAS-PUBLIC
|
|
10
|
+
* and https://www.postgresql.org/docs/18/ddl-schemas.html#DDL-SCHEMAS-PATTERNS
|
|
11
|
+
* (the usage patterns recommend that applications not share `public`). An
|
|
12
|
+
* unqualified name is created in the first schema of search_path, usually
|
|
13
|
+
* public. Silent for a project that declares no schema.
|
|
14
|
+
*/
|
|
15
|
+
export const sqlpg113 = checkOf({ id: "SQLPG113", description: "An object is in the public schema though the project declares schemas" }, (ctx, report) => {
|
|
16
|
+
const objects = postgresObjects(ctx);
|
|
17
|
+
if (!objects.some((o) => o.type === "Postgres::Schema")) return;
|
|
18
|
+
for (const o of objects) {
|
|
19
|
+
if (!PLACED.has(o.type)) continue;
|
|
20
|
+
const schema = (o.schema as string | undefined) ?? "public";
|
|
21
|
+
if (schema !== "public") continue;
|
|
22
|
+
report({
|
|
23
|
+
severity: "warning",
|
|
24
|
+
message: `${o.export} (${o.sqlName}) is in the public schema; qualify it with one of the declared schemas`,
|
|
25
|
+
entity: o.export,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { STORAGE_PARAMETERS } from "../../generated/postgres";
|
|
2
|
+
import { checkOf, rangeOf, storageParams, storageTarget, targetMajor } from "./postgres-helpers";
|
|
3
|
+
import { postgresObjects } from "./sql-helpers";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* SQLPG114: a storage parameter the object's kind does not accept at the
|
|
7
|
+
* target major (`postgresMajor` in the output).
|
|
8
|
+
*
|
|
9
|
+
* Doc: https://www.postgresql.org/docs/18/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS
|
|
10
|
+
* (and the CREATE INDEX, CREATE VIEW and CREATE MATERIALIZED VIEW pages). The
|
|
11
|
+
* server refuses an unrecognized parameter at CREATE. The accepted names and
|
|
12
|
+
* the relation kinds they apply to come from the generated catalog, whose
|
|
13
|
+
* since/until data says which majors have each one: a parameter removed
|
|
14
|
+
* before the target major is reported as removed.
|
|
15
|
+
*/
|
|
16
|
+
export const sqlpg114 = checkOf({ id: "SQLPG114", description: "A storage parameter the object's kind or the target major does not accept" }, (ctx, report) => {
|
|
17
|
+
const major = targetMajor(ctx);
|
|
18
|
+
const specs = STORAGE_PARAMETERS as Record<string, { targets: readonly string[] } | undefined>;
|
|
19
|
+
for (const o of postgresObjects(ctx)) {
|
|
20
|
+
const target = storageTarget(o);
|
|
21
|
+
if (!target) continue;
|
|
22
|
+
for (const raw of storageParams(o.with as string | undefined).keys()) {
|
|
23
|
+
if (raw.startsWith("toast.")) continue;
|
|
24
|
+
const spec = specs[raw];
|
|
25
|
+
if (!spec) {
|
|
26
|
+
report({ severity: "error", message: `${o.export} (${o.sqlName}) sets ${raw}, which is not a Postgres ${major} storage parameter`, entity: o.export });
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const range = rangeOf("storageParameters", `${target}.${raw}`);
|
|
30
|
+
if (!spec.targets.includes(target)) {
|
|
31
|
+
report({ severity: "error", message: `${o.export} (${o.sqlName}) sets ${raw}, which applies to ${spec.targets.join(", ")} and not to a ${target}`, entity: o.export });
|
|
32
|
+
} else if (range?.until !== undefined && range.until < major) {
|
|
33
|
+
report({ severity: "error", message: `${o.export} (${o.sqlName}) sets ${raw}, which Postgres removed after ${range.until}`, entity: o.export });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { checkOf, rangeOf, storageParams, storageTarget, tablesOf, targetMajor } from "./postgres-helpers";
|
|
2
|
+
import { indexesOf } from "./postgres-helpers";
|
|
3
|
+
import { postgresObjects } from "./sql-helpers";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* SQLPG115: a feature newer than the target major.
|
|
7
|
+
*
|
|
8
|
+
* Doc: https://www.postgresql.org/docs/18/release-18.html (NOT ENFORCED
|
|
9
|
+
* constraints and virtual generated columns arrive in 18),
|
|
10
|
+
* https://www.postgresql.org/docs/15/release-15.html (NULLS NOT DISTINCT). Storage parameters read the generated catalog's
|
|
11
|
+
* `since` data. The target is `sql.postgresMajor`
|
|
12
|
+
* (recorded as `postgresMajor` in the output), else the newest pinned major;
|
|
13
|
+
* a feature is reported as a warning only when it is newer than the target,
|
|
14
|
+
* naming the first major that has it.
|
|
15
|
+
*/
|
|
16
|
+
export const sqlpg115 = checkOf({ id: "SQLPG115", description: "A feature newer than the target major" }, (ctx, report) => {
|
|
17
|
+
const major = targetMajor(ctx);
|
|
18
|
+
const note = (entity: string, what: string, since: number) =>
|
|
19
|
+
report({ severity: "warning", message: `${entity} uses ${what}, which needs Postgres ${since}; Postgres ${major} refuses it`, entity });
|
|
20
|
+
for (const o of postgresObjects(ctx)) {
|
|
21
|
+
const target = storageTarget(o);
|
|
22
|
+
if (!target) continue;
|
|
23
|
+
for (const name of storageParams(o.with as string | undefined).keys()) {
|
|
24
|
+
// SQLPG117 asks every view for security_invoker (15), so it is not also a portability finding.
|
|
25
|
+
if (name === "security_invoker") continue;
|
|
26
|
+
const since = rangeOf("storageParameters", `${target}.${name}`)?.since;
|
|
27
|
+
if (since !== undefined && since > major) note(o.export, `the storage parameter ${name}`, since);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
for (const t of tablesOf(ctx)) {
|
|
31
|
+
for (const c of t.checks) if (c.notEnforced !== undefined && major < 18) note(t.export, `a NOT ENFORCED / ENFORCED constraint${c.name ? ` ${c.name}` : ""}`, 18);
|
|
32
|
+
for (const fk of t.foreignKeys as Array<{ notEnforced?: boolean; name?: string }>) if (fk.notEnforced !== undefined && major < 18) note(t.export, `a NOT ENFORCED / ENFORCED foreign key${fk.name ? ` ${fk.name}` : ""}`, 18);
|
|
33
|
+
for (const c of t.columns) if (c.generated?.kind === "virtual" && major < 18) note(t.export, `the virtual generated column ${c.name}`, 18);
|
|
34
|
+
const nulls = [...t.uniques, ...(t.primaryKey ? [t.primaryKey] : [])].some((k) => k.nullsNotDistinct);
|
|
35
|
+
if (nulls && major < 15) note(t.export, "NULLS NOT DISTINCT", 15);
|
|
36
|
+
}
|
|
37
|
+
for (const i of indexesOf(ctx)) if ((i as { nullsNotDistinct?: boolean }).nullsNotDistinct && major < 15) note(i.export, "NULLS NOT DISTINCT", 15);
|
|
38
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { checkOf, rangeOf, targetMajor } from "./postgres-helpers";
|
|
2
|
+
import { postgresObjects } from "./sql-helpers";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SQLPG116: an extension the target major no longer ships.
|
|
6
|
+
*
|
|
7
|
+
* Doc: https://www.postgresql.org/docs/18/contrib.html and the release notes
|
|
8
|
+
* of the major that dropped it (adminpack and old_snapshot are gone after 16,
|
|
9
|
+
* https://www.postgresql.org/docs/17/release-17.html). The target is `postgresMajor` in the output. The extension names
|
|
10
|
+
* and their since/until majors come from the generated catalog, read from
|
|
11
|
+
* pg_available_extensions of each major's server image.
|
|
12
|
+
*/
|
|
13
|
+
export const sqlpg116 = checkOf({ id: "SQLPG116", description: "An extension the target major no longer ships" }, (ctx, report) => {
|
|
14
|
+
const major = targetMajor(ctx);
|
|
15
|
+
for (const o of postgresObjects(ctx)) {
|
|
16
|
+
if (o.type !== "Postgres::Extension") continue;
|
|
17
|
+
const until = rangeOf("extensions", o.name)?.until;
|
|
18
|
+
if (until === undefined || until >= major) continue;
|
|
19
|
+
report({
|
|
20
|
+
severity: "error",
|
|
21
|
+
message: `${o.export} installs the ${o.name} extension, which Postgres ${major} does not ship (last in ${until})`,
|
|
22
|
+
entity: o.export,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { checkOf, isView, storageParams } from "./postgres-helpers";
|
|
2
|
+
import { postgresObjects } from "./sql-helpers";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SQLPG117: a view that runs with its owner's privileges.
|
|
6
|
+
*
|
|
7
|
+
* Doc: https://www.postgresql.org/docs/18/sql-createview.html ("by default,
|
|
8
|
+
* access to the underlying base relations referenced in the view is determined
|
|
9
|
+
* by the permissions of the view owner"; with security_invoker = true it is the
|
|
10
|
+
* caller's, and the base tables' row-level security applies to the caller).
|
|
11
|
+
* A view over tables with RLS otherwise hands the owner's view of the rows to
|
|
12
|
+
* every role that can select from it.
|
|
13
|
+
*/
|
|
14
|
+
export const sqlpg117 = checkOf({ id: "SQLPG117", description: "A view without security_invoker runs with its owner's privileges" }, (ctx, report) => {
|
|
15
|
+
for (const v of postgresObjects(ctx).filter(isView)) {
|
|
16
|
+
const flag = storageParams(v.with).get("security_invoker");
|
|
17
|
+
if (flag === "true" || flag === "on" || flag === "1" || flag === "'true'" || flag === "'on'") continue;
|
|
18
|
+
report({
|
|
19
|
+
severity: "warning",
|
|
20
|
+
message: `${v.export} (${v.sqlName}) does not set security_invoker = true, so it reads its tables as its owner and skips the caller's row-level security`,
|
|
21
|
+
entity: v.export,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { checkOf, tablesOf } from "./postgres-helpers";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SQLPG118: a table that uses INHERITS.
|
|
5
|
+
*
|
|
6
|
+
* Doc: https://www.postgresql.org/docs/18/ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE-BEST-PRACTICES
|
|
7
|
+
* and https://www.postgresql.org/docs/18/ddl-inherit.html#DDL-INHERIT-CAVEATS
|
|
8
|
+
* (indexes, unique constraints and foreign keys are not inherited, so a
|
|
9
|
+
* constraint on the parent does not cover the children). Declarative
|
|
10
|
+
* partitioning (PARTITION BY ... / PARTITION OF) replaced inheritance for
|
|
11
|
+
* splitting a table; INHERITS is kept for its other uses.
|
|
12
|
+
*/
|
|
13
|
+
export const sqlpg118 = checkOf({ id: "SQLPG118", description: "A table uses INHERITS where declarative partitioning replaced it" }, (ctx, report) => {
|
|
14
|
+
for (const t of tablesOf(ctx)) {
|
|
15
|
+
if (t.inherits.length === 0) continue;
|
|
16
|
+
report({
|
|
17
|
+
severity: "warning",
|
|
18
|
+
message: `${t.export} (${t.sqlName}) uses INHERITS; its parent's unique and foreign keys do not cover it, so use PARTITION OF for a split table`,
|
|
19
|
+
entity: t.export,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { LintRule } from "@intentius/chant/lint/rule";
|
|
2
|
+
import { sqlch001 } from "./sqlch001";
|
|
3
|
+
import { sqlch002 } from "./sqlch002";
|
|
4
|
+
import { sqlch003 } from "./sqlch003";
|
|
5
|
+
import { sqlpg001 } from "./sqlpg001";
|
|
6
|
+
import { sqlpg002 } from "./sqlpg002";
|
|
7
|
+
import { sqlpg003 } from "./sqlpg003";
|
|
8
|
+
import { sqlpg004 } from "./sqlpg004";
|
|
9
|
+
|
|
10
|
+
export { sqlch001, sqlch002, sqlch003, sqlpg001, sqlpg002, sqlpg003, sqlpg004 };
|
|
11
|
+
|
|
12
|
+
/** The lexicon's source-level lint rules, returned by `lintRules()`. */
|
|
13
|
+
export const rules: LintRule[] = [sqlch001, sqlch002, sqlch003, sqlpg001, sqlpg002, sqlpg003, sqlpg004];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding the Postgres tags in a source file, for the source-level rules. A
|
|
3
|
+
* tag is Postgres's because of the module it is imported from: the
|
|
4
|
+
* `/postgres` subpath, or the package root for the tags whose names
|
|
5
|
+
* ClickHouse does not export (the root's `table` and `view` are
|
|
6
|
+
* ClickHouse's).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type * as ts from "typescript";
|
|
10
|
+
import { tokenize, type Token } from "../../postgres/tokens";
|
|
11
|
+
import type { PostgresTag } from "../../postgres/entities";
|
|
12
|
+
import { findSqlTemplates, type FoundTemplate, type TemplateSource } from "../../core/find-templates";
|
|
13
|
+
|
|
14
|
+
export { templatePosition, tokenPosition } from "../../core/find-templates";
|
|
15
|
+
|
|
16
|
+
export const POSTGRES_TEMPLATE_SOURCES: readonly TemplateSource<PostgresTag>[] = [
|
|
17
|
+
{
|
|
18
|
+
dialect: "postgres",
|
|
19
|
+
modules: ["@intentius/chant-lexicon-sql/postgres"],
|
|
20
|
+
tags: ["schema", "table", "index", "view", "sequence", "type", "domain", "extension"],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
dialect: "postgres",
|
|
24
|
+
modules: ["@intentius/chant-lexicon-sql"],
|
|
25
|
+
tags: ["schema", "index", "sequence", "type", "domain", "extension"],
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
export type PostgresFoundTemplate = FoundTemplate<PostgresTag>;
|
|
30
|
+
|
|
31
|
+
/** Every Postgres template in the file. */
|
|
32
|
+
export function findPostgresTemplates(source: ts.SourceFile): PostgresFoundTemplate[] {
|
|
33
|
+
return findSqlTemplates(source, POSTGRES_TEMPLATE_SOURCES);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const postgresTokensOf = (found: PostgresFoundTemplate): Token[] => tokenize(found.parts);
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import type { LintContext } from "@intentius/chant/lint/rule";
|
|
4
|
+
import { sqlch001 } from "./sqlch001";
|
|
5
|
+
import { sqlch002 } from "./sqlch002";
|
|
6
|
+
import { sqlch003 } from "./sqlch003";
|
|
7
|
+
import { sqlpg001 } from "./sqlpg001";
|
|
8
|
+
import { sqlpg002 } from "./sqlpg002";
|
|
9
|
+
import { sqlpg003 } from "./sqlpg003";
|
|
10
|
+
import { sqlpg004, providerFromConfig } from "./sqlpg004";
|
|
11
|
+
|
|
12
|
+
const ctx = (code: string): LintContext => ({
|
|
13
|
+
sourceFile: ts.createSourceFile("schema.ts", code, ts.ScriptTarget.Latest, true),
|
|
14
|
+
entities: [],
|
|
15
|
+
filePath: "schema.ts",
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const IMPORT = 'import { table, view } from "@intentius/chant-lexicon-sql/clickhouse";\n';
|
|
19
|
+
|
|
20
|
+
describe("SQLCH001: DDL that does not parse", () => {
|
|
21
|
+
test("is reported at the token, as a line and column of the .ts file", () => {
|
|
22
|
+
const code = `${IMPORT}export const t = table\`
|
|
23
|
+
CREATE TABLE t (
|
|
24
|
+
a Strin g
|
|
25
|
+
) ENGINE = Log\`;`;
|
|
26
|
+
const [d, ...rest] = sqlch001.check(ctx(code));
|
|
27
|
+
expect(rest).toEqual([]);
|
|
28
|
+
expect(d).toMatchObject({ ruleId: "SQLCH001", severity: "error", line: 4, column: 13 });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("a tag holding another statement is reported", () => {
|
|
32
|
+
const code = `${IMPORT}export const v = table\`CREATE VIEW v AS SELECT 1\`;`;
|
|
33
|
+
expect(sqlch001.check(ctx(code))[0]?.message).toMatch(/use the view tag/);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("valid DDL with interpolations is clean", () => {
|
|
37
|
+
const code = `${IMPORT}import { events } from "./events";
|
|
38
|
+
const name = "v";
|
|
39
|
+
export const v = view\`CREATE VIEW \${name} AS SELECT \${events.columns.kind} FROM \${events}\`;`;
|
|
40
|
+
expect(sqlch001.check(ctx(code))).toEqual([]);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("a tag of the same name from another module is not ours", () => {
|
|
44
|
+
const code = `import { table } from "./mine";\nexport const t = table\`not sql\`;`;
|
|
45
|
+
expect(sqlch001.check(ctx(code))).toEqual([]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("an aliased import is followed", () => {
|
|
49
|
+
const code = `import { table as chTable } from "@intentius/chant-lexicon-sql/clickhouse";\nexport const t = chTable\`CREATE TABLE\`;`;
|
|
50
|
+
expect(sqlch001.check(ctx(code))).toHaveLength(1);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe("SQLCH002: a Nullable column in a key", () => {
|
|
55
|
+
test("is reported at the column in ORDER BY", () => {
|
|
56
|
+
const code = `${IMPORT}export const t = table\`
|
|
57
|
+
CREATE TABLE t (id UInt64, region Nullable(String))
|
|
58
|
+
ENGINE = MergeTree
|
|
59
|
+
ORDER BY (region, id)\`;`;
|
|
60
|
+
const diags = sqlch002.check(ctx(code));
|
|
61
|
+
expect(diags).toHaveLength(1);
|
|
62
|
+
expect(diags[0]).toMatchObject({ ruleId: "SQLCH002", line: 5, column: 13 });
|
|
63
|
+
expect(diags[0]!.message).toMatch(/"region" is Nullable/);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("sees LowCardinality(Nullable(...)), the NULL modifier and PRIMARY KEY", () => {
|
|
67
|
+
const code = `${IMPORT}export const t = table\`
|
|
68
|
+
CREATE TABLE t (a LowCardinality(Nullable(String)), b UInt8 NULL, c UInt8)
|
|
69
|
+
ENGINE = MergeTree ORDER BY (a, b, c) PRIMARY KEY a\`;`;
|
|
70
|
+
expect(sqlch002.check(ctx(code)).map((d) => d.message.match(/"(\w+)"/)![1])).toEqual(["a", "b", "a"]);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("a function of a nullable column, or a non-key use, is not reported", () => {
|
|
74
|
+
const code = `${IMPORT}export const t = table\`
|
|
75
|
+
CREATE TABLE t (a Nullable(String), id UInt64)
|
|
76
|
+
ENGINE = MergeTree ORDER BY (id, ifNull(a, ''))\`;`;
|
|
77
|
+
expect(sqlch002.check(ctx(code))).toEqual([]);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("allow_nullable_key = 1 turns it off", () => {
|
|
81
|
+
const code = `${IMPORT}export const t = table\`
|
|
82
|
+
CREATE TABLE t (a Nullable(String)) ENGINE = MergeTree ORDER BY a SETTINGS allow_nullable_key = 1\`;`;
|
|
83
|
+
expect(sqlch002.check(ctx(code))).toEqual([]);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe("SQLCH003: a column interpolated without .columns", () => {
|
|
88
|
+
test("is reported for an entity declared in the file", () => {
|
|
89
|
+
const code = `${IMPORT}export const events = table\`CREATE TABLE events (kind String) ENGINE = Log\`;
|
|
90
|
+
export const v = view\`CREATE VIEW v AS SELECT \${events.kind} FROM \${events}\`;`;
|
|
91
|
+
const diags = sqlch003.check(ctx(code));
|
|
92
|
+
expect(diags).toHaveLength(1);
|
|
93
|
+
expect(diags[0]!.message).toMatch(/events\.columns\.kind/);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("is reported for an entity imported from another project file", () => {
|
|
97
|
+
const code = `${IMPORT}import { events } from "./events";
|
|
98
|
+
export const v = view\`CREATE VIEW v AS SELECT \${events.props} FROM \${events}\`;`;
|
|
99
|
+
expect(sqlch003.check(ctx(code))).toHaveLength(1);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("a composite's parameter object and .columns are not reported", () => {
|
|
103
|
+
const code = `${IMPORT}import { events } from "./events";
|
|
104
|
+
const make = (props: { kind: string }) => view\`CREATE VIEW \${props.kind} AS SELECT \${events.columns.kind} FROM \${events}\`;`;
|
|
105
|
+
expect(sqlch003.check(ctx(code))).toEqual([]);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const PG = 'import { index, sequence, table, view } from "@intentius/chant-lexicon-sql/postgres";\n';
|
|
110
|
+
|
|
111
|
+
describe("SQLPG001: Postgres DDL that does not parse", () => {
|
|
112
|
+
test("is reported at the token, as a line and column of the .ts file", () => {
|
|
113
|
+
const code = `${PG}export const t = table\`
|
|
114
|
+
CREATE TABLE t (
|
|
115
|
+
a text DEFAULT 'x' CHEK (a <> '')
|
|
116
|
+
)\`;`;
|
|
117
|
+
const [d, ...rest] = sqlpg001.check(ctx(code));
|
|
118
|
+
expect(rest).toEqual([]);
|
|
119
|
+
expect(d).toMatchObject({ ruleId: "SQLPG001", severity: "error", line: 4, column: 24 });
|
|
120
|
+
expect(d!.message).toMatch(/CHEK/);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("a tag holding another statement, a second CREATE and an unnamed index are reported", () => {
|
|
124
|
+
expect(sqlpg001.check(ctx(`${PG}export const i = table\`CREATE INDEX i ON t (a)\`;`))[0]?.message).toMatch(/use the index tag/);
|
|
125
|
+
expect(sqlpg001.check(ctx(`${PG}export const t = table\`CREATE TABLE a (x int); CREATE TABLE b (x int)\`;`))[0]?.message).toMatch(/second statement/);
|
|
126
|
+
const unnamed = sqlpg001.check(ctx(`${PG}export const i = index\`CREATE INDEX ON t (a)\`;`));
|
|
127
|
+
expect(unnamed[0]).toMatchObject({ line: 2, column: 37 });
|
|
128
|
+
expect(unnamed[0]!.message).toMatch(/an index needs a name/);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("valid DDL with interpolations is clean, and ClickHouse's tags are not read as Postgres", () => {
|
|
132
|
+
const code = `${PG}import { users } from "./users";
|
|
133
|
+
export const t = table\`CREATE TABLE \${"orders"} (id bigint PRIMARY KEY, user_id bigint REFERENCES \${users} (\${users.columns.id}))\`;`;
|
|
134
|
+
expect(sqlpg001.check(ctx(code))).toEqual([]);
|
|
135
|
+
const ch = 'import { table } from "@intentius/chant-lexicon-sql/clickhouse";\nexport const t = table`CREATE TABLE t (a String) ENGINE = Log`;';
|
|
136
|
+
expect(sqlpg001.check(ctx(ch))).toEqual([]);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("the package root's Postgres-only tags are Postgres's", () => {
|
|
140
|
+
const code = 'import { sequence } from "@intentius/chant-lexicon-sql";\nexport const s = sequence`CREATE SEQUENCE s START WITH`;';
|
|
141
|
+
expect(sqlpg001.check(ctx(code))).toHaveLength(1);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
describe("SQLPG002: a column interpolated without .columns", () => {
|
|
146
|
+
test("is reported for an entity declared in the file", () => {
|
|
147
|
+
const code = `${PG}export const users = table\`CREATE TABLE users (kind text)\`;
|
|
148
|
+
export const v = view\`CREATE VIEW v AS SELECT \${users.kind} FROM \${users}\`;`;
|
|
149
|
+
const diags = sqlpg002.check(ctx(code));
|
|
150
|
+
expect(diags).toHaveLength(1);
|
|
151
|
+
expect(diags[0]!.message).toMatch(/users\.columns\.kind/);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe("SQLPG003: an object named in a regclass string", () => {
|
|
156
|
+
test("nextval('...') and '...'::regclass are reported at the string", () => {
|
|
157
|
+
const code = `${PG}export const t = table\`CREATE TABLE t (
|
|
158
|
+
a bigint DEFAULT nextval('app.seq'),
|
|
159
|
+
b regclass DEFAULT 'app.t'::regclass
|
|
160
|
+
)\`;`;
|
|
161
|
+
const diags = sqlpg003.check(ctx(code));
|
|
162
|
+
expect(diags.map((d) => [d.line, d.column])).toEqual([[3, 30], [4, 24]]);
|
|
163
|
+
expect(diags[0]!.message).toMatch(/nextval\(\$\{\.\.\.\}\)/);
|
|
164
|
+
expect(diags[0]!.severity).toBe("warning");
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("an interpolated sequence is clean", () => {
|
|
168
|
+
const code = `${PG}import { seq } from "./seq";
|
|
169
|
+
export const t = table\`CREATE TABLE t (a bigint DEFAULT nextval(\${seq}))\`;`;
|
|
170
|
+
expect(sqlpg003.check(ctx(code))).toEqual([]);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
describe("SQLPG004: an extension the configured provider does not allow", () => {
|
|
175
|
+
const withConfig = (code: string, sql: unknown): LintContext => ({ ...ctx(code), projectConfig: { sql } as never });
|
|
176
|
+
const PGX = 'import { extension, schema } from "@intentius/chant-lexicon-sql/postgres";\n';
|
|
177
|
+
const ext = (stmt: string) => `${PGX}export const e = extension\`${stmt}\`;`;
|
|
178
|
+
|
|
179
|
+
test("is reported at the extension's name when the provider's list lacks it", () => {
|
|
180
|
+
const [d, ...rest] = sqlpg004.check(withConfig(ext("CREATE EXTENSION pg_squeeze"), { provider: "rds" }));
|
|
181
|
+
expect(rest).toEqual([]);
|
|
182
|
+
expect(d).toMatchObject({ ruleId: "SQLPG004", severity: "error", line: 2, column: 45 });
|
|
183
|
+
expect(d!.message).toMatch(/Amazon RDS for PostgreSQL does not allow the extension "pg_squeeze"/);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test("an allowed extension, IF NOT EXISTS and a quoted name are read", () => {
|
|
187
|
+
expect(sqlpg004.check(withConfig(ext("CREATE EXTENSION IF NOT EXISTS pgcrypto"), { provider: "neon" }))).toEqual([]);
|
|
188
|
+
expect(sqlpg004.check(withConfig(ext('CREATE EXTENSION "uuid-ossp"'), { provider: "neon" }))).toEqual([]);
|
|
189
|
+
const d = sqlpg004.check(withConfig(ext("CREATE EXTENSION IF NOT EXISTS plv8"), { provider: "neon" }));
|
|
190
|
+
expect(d).toHaveLength(1);
|
|
191
|
+
expect(d[0]!.column).toBe(59);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("each provider reports one name it lacks", () => {
|
|
195
|
+
const lacks: Record<string, string> = {
|
|
196
|
+
rds: "timescaledb",
|
|
197
|
+
aurora: "timescaledb",
|
|
198
|
+
"cloud-sql": "timescaledb",
|
|
199
|
+
azure: "pg_stat_monitor",
|
|
200
|
+
neon: "pg_squeeze",
|
|
201
|
+
};
|
|
202
|
+
for (const [provider, name] of Object.entries(lacks)) {
|
|
203
|
+
expect(sqlpg004.check(withConfig(ext(`CREATE EXTENSION ${name}`), { provider })), provider).toHaveLength(1);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test("a partial list (supabase) does not report a name outside it", () => {
|
|
208
|
+
expect(sqlpg004.check(withConfig(ext("CREATE EXTENSION pg_trgm"), { provider: "supabase" }))).toEqual([]);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("with no provider, or profiles that disagree, it is silent", () => {
|
|
212
|
+
expect(sqlpg004.check(ctx(ext("CREATE EXTENSION pg_squeeze")))).toEqual([]);
|
|
213
|
+
expect(sqlpg004.check(withConfig(ext("CREATE EXTENSION pg_squeeze"), { dialect: "postgres" }))).toEqual([]);
|
|
214
|
+
const split = { profiles: { a: { url: "x", provider: "rds" }, b: { url: "y", provider: "neon" } } };
|
|
215
|
+
expect(sqlpg004.check(withConfig(ext("CREATE EXTENSION pg_squeeze"), split))).toEqual([]);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test("profiles that all name one provider set it", () => {
|
|
219
|
+
expect(providerFromConfig({ sql: { profiles: { a: { url: "x", provider: "rds" }, b: { url: "y", provider: "rds" } } } })).toBe("rds");
|
|
220
|
+
expect(providerFromConfig({ sql: { provider: "azure", profiles: { a: { url: "x", provider: "rds" } } } })).toBe("azure");
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test("the ClickHouse tags and other statements are not read", () => {
|
|
224
|
+
const ch = 'import { table } from "@intentius/chant-lexicon-sql/clickhouse";\nexport const t = table`CREATE TABLE t (a String) ENGINE = Log`;';
|
|
225
|
+
expect(sqlpg004.check(withConfig(ch, { provider: "rds" }))).toEqual([]);
|
|
226
|
+
expect(sqlpg004.check(withConfig(`${PGX}export const s = schema\`CREATE SCHEMA app\`;`, { provider: "rds" }))).toEqual([]);
|
|
227
|
+
});
|
|
228
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { LintContext, LintDiagnostic, LintRule } from "@intentius/chant/lint/rule";
|
|
2
|
+
import { parseCreate } from "../../clickhouse/parser";
|
|
3
|
+
import { SqlSyntaxError } from "../../clickhouse/tokens";
|
|
4
|
+
import { findTemplates, templatePosition, tokensOf } from "./templates";
|
|
5
|
+
|
|
6
|
+
const STATEMENT: Record<string, string> = { database: "CREATE DATABASE", table: "CREATE TABLE", view: "CREATE VIEW" };
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* SQLCH001: the DDL in a `database`, `table` or `view` template does not parse, or holds another statement than its tag.
|
|
10
|
+
*
|
|
11
|
+
* The same parse runs when the build calls the tag, and fails the build there.
|
|
12
|
+
* This rule reports it in the editor and in `chant lint`, at the token, before
|
|
13
|
+
* anything is built. Interpolations are references here, since lint cannot
|
|
14
|
+
* know their values, so an error inside text a string interpolation supplies
|
|
15
|
+
* is left to the build.
|
|
16
|
+
*/
|
|
17
|
+
export const sqlch001: LintRule = {
|
|
18
|
+
id: "SQLCH001",
|
|
19
|
+
severity: "error",
|
|
20
|
+
category: "correctness",
|
|
21
|
+
description: "ClickHouse DDL in a database, table or view template does not parse",
|
|
22
|
+
|
|
23
|
+
check(context: LintContext): LintDiagnostic[] {
|
|
24
|
+
const source = context.sourceFile;
|
|
25
|
+
const out: LintDiagnostic[] = [];
|
|
26
|
+
for (const found of findTemplates(source)) {
|
|
27
|
+
let tokens;
|
|
28
|
+
try {
|
|
29
|
+
tokens = tokensOf(found);
|
|
30
|
+
const node = parseCreate(tokens);
|
|
31
|
+
if (node.statement !== found.tag) {
|
|
32
|
+
out.push({
|
|
33
|
+
ruleId: "SQLCH001",
|
|
34
|
+
severity: "error",
|
|
35
|
+
message: `${found.tag}\`...\` holds a ${STATEMENT[node.statement]}; use the ${node.statement} tag`,
|
|
36
|
+
file: context.filePath,
|
|
37
|
+
...templatePosition(source, found, 0, 0),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
} catch (err) {
|
|
41
|
+
if (!(err instanceof SqlSyntaxError)) throw err;
|
|
42
|
+
out.push({
|
|
43
|
+
ruleId: "SQLCH001",
|
|
44
|
+
severity: "error",
|
|
45
|
+
message: `ClickHouse DDL does not parse: ${err.message}`,
|
|
46
|
+
file: context.filePath,
|
|
47
|
+
...templatePosition(source, found, err.part, err.offset),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
},
|
|
53
|
+
};
|