@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,43 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import { CATALOG_SECTIONS, majorOf, parseCatalog, stringifyCatalog } from "./postgres-catalog";
|
|
4
|
+
import { snapshotFile } from "./postgres-fetch";
|
|
5
|
+
import { POSTGRES_PINS } from "./postgres-pin";
|
|
6
|
+
|
|
7
|
+
const read = (major: number) => readFileSync(snapshotFile(major), "utf-8");
|
|
8
|
+
|
|
9
|
+
describe.each(POSTGRES_PINS.map((p) => [p.major, p.version, p.digest] as const))("the %i snapshot", (major, version, digest) => {
|
|
10
|
+
const text = read(major);
|
|
11
|
+
const catalog = parseCatalog(text);
|
|
12
|
+
|
|
13
|
+
test("is the pinned version, read from the pinned image", () => {
|
|
14
|
+
expect(catalog.version).toBe(version);
|
|
15
|
+
expect(majorOf(catalog.version)).toBe(major);
|
|
16
|
+
expect(catalog.versionNum).toBe(Number(`${major}${version.split(".")[1]!.padStart(4, "0")}`));
|
|
17
|
+
expect(catalog.image).toBe(`postgres:${version}@${digest}`);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("round-trips to the same bytes, one entry per line", () => {
|
|
21
|
+
expect(stringifyCatalog(catalog)).toBe(text);
|
|
22
|
+
expect(text.split("\n").length).toBeGreaterThan(3000);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test("has every section, sorted by name", () => {
|
|
26
|
+
for (const section of CATALOG_SECTIONS) expect(catalog[section].length).toBeGreaterThan(0);
|
|
27
|
+
const names = catalog.settings.map((s) => s.name);
|
|
28
|
+
expect(names).toEqual([...names].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)));
|
|
29
|
+
expect(catalog.settings.some((s) => s.name.startsWith("server_version"))).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("records the storage parameters the server accepts", () => {
|
|
33
|
+
expect(catalog.storageParameters.table).toContain("fillfactor");
|
|
34
|
+
expect(catalog.storageParameters["index:gin"]).toContain("fastupdate");
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe("parseCatalog", () => {
|
|
39
|
+
test("refuses another dialect's catalog and a missing section", () => {
|
|
40
|
+
expect(() => parseCatalog('{"dialect":"clickhouse"}')).toThrow(/not a Postgres catalog/);
|
|
41
|
+
expect(() => parseCatalog('{"dialect":"postgres","version":"18.6"}')).toThrow(/section types/);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Postgres catalog: what generation reads from one pinned server's
|
|
3
|
+
* catalog, in the shape the committed snapshot stores (one snapshot per major).
|
|
4
|
+
*
|
|
5
|
+
* Every section is sorted with an explicit `COLLATE "C"`, and the snapshot is
|
|
6
|
+
* written one entry per line, so a pin move is a line diff a reviewer can
|
|
7
|
+
* read. Nothing here depends on the host: `pg_settings.setting` and
|
|
8
|
+
* `reset_val` reflect the scratch server's configuration and are never read
|
|
9
|
+
* (`boot_val` is the compiled default), the Debian build suffix is stripped
|
|
10
|
+
* from `server_version`, and nothing is timestamped.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { STORAGE_PARAMETER_SEED } from "../postgres/overlays/storage";
|
|
14
|
+
|
|
15
|
+
/** Runs a SQL script whose last statement returns one JSON value. A server, or a stub in a test. */
|
|
16
|
+
export interface PostgresReader {
|
|
17
|
+
query(sql: string): Promise<unknown>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface TypeRow {
|
|
21
|
+
/** `pg_type.typname`: `int4`. */
|
|
22
|
+
name: string;
|
|
23
|
+
/** `format_type()`: `integer`. */
|
|
24
|
+
sqlName: string;
|
|
25
|
+
/** `typtype`: base `b`, domain `d`, enum `e`, multirange `m`, pseudo `p`, range `r`. */
|
|
26
|
+
kind: string;
|
|
27
|
+
category: string;
|
|
28
|
+
len: number;
|
|
29
|
+
byval: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface AccessMethodRow {
|
|
33
|
+
name: string;
|
|
34
|
+
/** `i` for an index access method, `t` for a table access method. */
|
|
35
|
+
type: string;
|
|
36
|
+
/** What `pg_indexam_has_property` reports for the method (`can_unique`, `can_include`...); index methods only. */
|
|
37
|
+
properties: string[] | null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface OpClassRow {
|
|
41
|
+
am: string;
|
|
42
|
+
name: string;
|
|
43
|
+
inputType: string;
|
|
44
|
+
default: boolean;
|
|
45
|
+
family: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface FunctionRow {
|
|
49
|
+
name: string;
|
|
50
|
+
/** `prokind`s over the overloads, sorted: `f` function, `a` aggregate, `p` procedure, `w` window. */
|
|
51
|
+
kinds: string;
|
|
52
|
+
overloads: number;
|
|
53
|
+
/** `pg_*`, `binary_upgrade*`, `*support`, or only ever an aggregate's support function: not for a user to call. */
|
|
54
|
+
internal: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface OperatorRow {
|
|
58
|
+
name: string;
|
|
59
|
+
kinds: string;
|
|
60
|
+
overloads: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface SettingRow {
|
|
64
|
+
name: string;
|
|
65
|
+
/** `bool`, `integer`, `real`, `string` or `enum`. */
|
|
66
|
+
type: string;
|
|
67
|
+
context: string;
|
|
68
|
+
category: string;
|
|
69
|
+
unit: string | null;
|
|
70
|
+
/** The compiled default (`boot_val`). */
|
|
71
|
+
default: string | null;
|
|
72
|
+
min: string | null;
|
|
73
|
+
max: string | null;
|
|
74
|
+
enumvals: string[] | null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface KeywordRow {
|
|
78
|
+
word: string;
|
|
79
|
+
/** `U` unreserved, `C` column name, `T` reserved as function or type name, `R` reserved. */
|
|
80
|
+
code: string;
|
|
81
|
+
description: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface ExtensionRow {
|
|
85
|
+
name: string;
|
|
86
|
+
defaultVersion: string;
|
|
87
|
+
description: string | null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Storage parameter names the server accepts, by relation kind: `table`, `toast`, `view`, `materialized view`, `index:<method>`. */
|
|
91
|
+
export type StorageParameters = Record<string, string[]>;
|
|
92
|
+
|
|
93
|
+
export interface PostgresCatalog {
|
|
94
|
+
dialect: "postgres";
|
|
95
|
+
/** `server_version` without the build suffix: `18.6`. */
|
|
96
|
+
version: string;
|
|
97
|
+
/** `server_version_num`: `180006`. */
|
|
98
|
+
versionNum: number;
|
|
99
|
+
/** The image reference that server ran. */
|
|
100
|
+
image: string;
|
|
101
|
+
types: TypeRow[];
|
|
102
|
+
accessMethods: AccessMethodRow[];
|
|
103
|
+
opclasses: OpClassRow[];
|
|
104
|
+
functions: FunctionRow[];
|
|
105
|
+
operators: OperatorRow[];
|
|
106
|
+
settings: SettingRow[];
|
|
107
|
+
keywords: KeywordRow[];
|
|
108
|
+
extensions: ExtensionRow[];
|
|
109
|
+
storageParameters: StorageParameters;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** The list sections, in the order the snapshot writes them; `storageParameters` follows. */
|
|
113
|
+
export const CATALOG_SECTIONS = [
|
|
114
|
+
"types",
|
|
115
|
+
"accessMethods",
|
|
116
|
+
"opclasses",
|
|
117
|
+
"functions",
|
|
118
|
+
"operators",
|
|
119
|
+
"settings",
|
|
120
|
+
"keywords",
|
|
121
|
+
"extensions",
|
|
122
|
+
] as const satisfies readonly (keyof PostgresCatalog)[];
|
|
123
|
+
|
|
124
|
+
/** The major of a version string: `18.6` is 18. */
|
|
125
|
+
export function majorOf(version: string): number {
|
|
126
|
+
return Number.parseInt(version, 10);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ── Reading a server ─────────────────────────────────────────────────
|
|
130
|
+
|
|
131
|
+
const C = `collate "C"`;
|
|
132
|
+
const agg = (select: string, order: string) =>
|
|
133
|
+
`select coalesce(json_agg(t order by ${order}), '[]'::json) from (${select}) t;`;
|
|
134
|
+
|
|
135
|
+
const AGG_SUPPORT_OIDS = `select unnest(array[aggtransfn::oid, aggfinalfn::oid, aggcombinefn::oid, aggserialfn::oid, aggdeserialfn::oid, aggmtransfn::oid, aggminvtransfn::oid, aggmfinalfn::oid]) as oid from pg_aggregate`;
|
|
136
|
+
|
|
137
|
+
const QUERIES = {
|
|
138
|
+
version: `select to_json(split_part(current_setting('server_version'), ' ', 1));`,
|
|
139
|
+
versionNum: `select to_json(current_setting('server_version_num')::int);`,
|
|
140
|
+
// Non-array, non-composite types in pg_catalog. format_type() is the SQL
|
|
141
|
+
// spelling, so int4 is integer and bool is boolean.
|
|
142
|
+
types: agg(
|
|
143
|
+
`select t.typname::text as name, format_type(t.oid, null) as "sqlName", t.typtype::text as kind,
|
|
144
|
+
t.typcategory::text as category, t.typlen::int as len, t.typbyval as byval
|
|
145
|
+
from pg_type t join pg_namespace n on n.oid = t.typnamespace
|
|
146
|
+
where n.nspname = 'pg_catalog' and t.typtype in ('b','d','e','m','p','r')
|
|
147
|
+
and not (t.typcategory = 'A' and t.typname like '\\_%')`,
|
|
148
|
+
`t.name ${C}`,
|
|
149
|
+
),
|
|
150
|
+
accessMethods: agg(
|
|
151
|
+
`select a.amname::text as name, a.amtype::text as type,
|
|
152
|
+
case when a.amtype = 'i' then (select json_agg(p order by p ${C}) from unnest(array['asc','desc','nulls_first','nulls_last','orderable','distance_orderable','returnable','search_array','search_nulls','clusterable','index_scan','bitmap_scan','backward_scan','can_order','can_unique','can_multi_col','can_exclude','can_include']) p where pg_indexam_has_property(a.oid, p)) end as properties
|
|
153
|
+
from pg_am a`,
|
|
154
|
+
`t.name ${C}`,
|
|
155
|
+
),
|
|
156
|
+
opclasses: agg(
|
|
157
|
+
`select am.amname::text as am, c.opcname::text as name, format_type(c.opcintype, null) as "inputType",
|
|
158
|
+
c.opcdefault as "default", f.opfname::text as family
|
|
159
|
+
from pg_opclass c join pg_am am on am.oid = c.opcmethod join pg_opfamily f on f.oid = c.opcfamily
|
|
160
|
+
join pg_namespace n on n.oid = c.opcnamespace where n.nspname = 'pg_catalog'`,
|
|
161
|
+
`t.am ${C}, t.name ${C}, t."inputType" ${C}`,
|
|
162
|
+
),
|
|
163
|
+
// One row per name in pg_catalog. Type I/O functions are not callable in any useful way.
|
|
164
|
+
functions: agg(
|
|
165
|
+
`select p.proname::text as name, string_agg(distinct p.prokind::text, '' order by p.prokind::text) as kinds, count(*)::int as overloads,
|
|
166
|
+
(p.proname like 'pg\\_%' or p.proname like 'binary\\_upgrade%' or p.proname like '%support'
|
|
167
|
+
or coalesce(bool_and(p.oid in (${AGG_SUPPORT_OIDS})), false)) as internal
|
|
168
|
+
from pg_proc p join pg_namespace n on n.oid = p.pronamespace
|
|
169
|
+
where n.nspname = 'pg_catalog'
|
|
170
|
+
and p.oid not in (select unnest(array[typinput::oid, typoutput::oid, typreceive::oid, typsend::oid, typmodin::oid, typmodout::oid, typanalyze::oid, typsubscript::oid]) from pg_type)
|
|
171
|
+
group by p.proname`,
|
|
172
|
+
`t.name ${C}`,
|
|
173
|
+
),
|
|
174
|
+
operators: agg(
|
|
175
|
+
`select o.oprname::text as name, string_agg(distinct o.oprkind::text, '' order by o.oprkind::text) as kinds, count(*)::int as overloads
|
|
176
|
+
from pg_operator o join pg_namespace n on n.oid = o.oprnamespace where n.nspname = 'pg_catalog' group by o.oprname`,
|
|
177
|
+
`t.name ${C}`,
|
|
178
|
+
),
|
|
179
|
+
settings: agg(
|
|
180
|
+
`select name::text, vartype::text as type, context::text, category::text, unit::text, boot_val as "default", min_val as min, max_val as max, enumvals::text[] as enumvals
|
|
181
|
+
from pg_settings where name not like 'server\\_version%'`,
|
|
182
|
+
`t.name ${C}`,
|
|
183
|
+
),
|
|
184
|
+
keywords: agg(`select word::text, catcode::text as code, catdesc::text as description from pg_get_keywords()`, `t.word ${C}, t.code ${C}`),
|
|
185
|
+
extensions: agg(
|
|
186
|
+
`select name::text, default_version::text as "defaultVersion", comment::text as description from pg_available_extensions`,
|
|
187
|
+
`t.name ${C}`,
|
|
188
|
+
),
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Storage parameters (reloptions) are compiled into `reloptions.c`; no catalog
|
|
193
|
+
* lists them. Try every candidate on every relation kind and keep the names
|
|
194
|
+
* the server does not reject as unrecognized. Candidates are every
|
|
195
|
+
* `pg_settings` name plus the overlay's seed. An out-of-range value error
|
|
196
|
+
* counts as accepted.
|
|
197
|
+
*/
|
|
198
|
+
function storageProbe(): string {
|
|
199
|
+
const index = { btree: "a", hash: "a", brin: "a", gin: "arr", gist: "r", spgist: "r" } as const;
|
|
200
|
+
const targets: Array<[string, string]> = [
|
|
201
|
+
["table", "create table probe.x (a int) with (%C=1)"],
|
|
202
|
+
["toast", "create table probe.x (a text) with (toast.%C=1)"],
|
|
203
|
+
["view", "create view probe.x with (%C=1) as select 1 as a"],
|
|
204
|
+
["materialized view", "create materialized view probe.x with (%C=1) as select 1 as a"],
|
|
205
|
+
...(Object.entries(index) as Array<[string, string]>).map(
|
|
206
|
+
([am, col]): [string, string] => [`index:${am}`, `create index x on probe.base using ${am} (${col}) with (%C=1)`],
|
|
207
|
+
),
|
|
208
|
+
];
|
|
209
|
+
const cases = targets.map(([t, s]) => `('${t}', $q$${s}$q$)`).join(",\n");
|
|
210
|
+
return `
|
|
211
|
+
drop schema if exists probe cascade; create schema probe;
|
|
212
|
+
create table probe.base (a int, arr int[], r int4range);
|
|
213
|
+
create temp table res (target text, cand text);
|
|
214
|
+
do $do$
|
|
215
|
+
declare t record; c record; msg text;
|
|
216
|
+
begin
|
|
217
|
+
for t in select * from (values ${cases}) v(target, stmt) loop
|
|
218
|
+
for c in select distinct n as cand from (select name::text as n from pg_settings union select unnest(string_to_array($seed$${STORAGE_PARAMETER_SEED.join(",")}$seed$, ','))) s(n) loop
|
|
219
|
+
begin
|
|
220
|
+
execute replace(t.stmt, '%C', quote_ident(c.cand));
|
|
221
|
+
insert into res values (t.target, c.cand);
|
|
222
|
+
execute case when t.target like 'index%' then 'drop index probe.x'
|
|
223
|
+
when t.target like 'mat%' then 'drop materialized view probe.x'
|
|
224
|
+
when t.target = 'view' then 'drop view probe.x' else 'drop table probe.x' end;
|
|
225
|
+
exception when others then
|
|
226
|
+
get stacked diagnostics msg = message_text;
|
|
227
|
+
if msg not like 'unrecognized parameter%' and msg not like 'syntax error%' then
|
|
228
|
+
insert into res values (t.target, c.cand);
|
|
229
|
+
end if;
|
|
230
|
+
end;
|
|
231
|
+
end loop;
|
|
232
|
+
end loop;
|
|
233
|
+
end $do$;
|
|
234
|
+
drop schema probe cascade;
|
|
235
|
+
${agg(`select target, cand as name from res`, `t.target ${C}, t.name ${C}`)}`;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Read the catalog from a server. The caller checks that its version is the pin. */
|
|
239
|
+
export async function readCatalog(reader: PostgresReader, image: string): Promise<PostgresCatalog> {
|
|
240
|
+
const q = async <T>(key: keyof typeof QUERIES): Promise<T> => (await reader.query(QUERIES[key])) as T;
|
|
241
|
+
const catalog: PostgresCatalog = {
|
|
242
|
+
dialect: "postgres",
|
|
243
|
+
version: await q<string>("version"),
|
|
244
|
+
versionNum: await q<number>("versionNum"),
|
|
245
|
+
image,
|
|
246
|
+
types: await q<TypeRow[]>("types"),
|
|
247
|
+
accessMethods: await q<AccessMethodRow[]>("accessMethods"),
|
|
248
|
+
opclasses: await q<OpClassRow[]>("opclasses"),
|
|
249
|
+
functions: await q<FunctionRow[]>("functions"),
|
|
250
|
+
operators: await q<OperatorRow[]>("operators"),
|
|
251
|
+
settings: await q<SettingRow[]>("settings"),
|
|
252
|
+
keywords: await q<KeywordRow[]>("keywords"),
|
|
253
|
+
extensions: await q<ExtensionRow[]>("extensions"),
|
|
254
|
+
storageParameters: {},
|
|
255
|
+
};
|
|
256
|
+
const probed = (await reader.query(storageProbe())) as Array<{ target: string; name: string }>;
|
|
257
|
+
for (const r of probed) (catalog.storageParameters[r.target] ??= []).push(r.name);
|
|
258
|
+
return catalog;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// ── The snapshot's text form ─────────────────────────────────────────
|
|
262
|
+
|
|
263
|
+
/** Write the catalog with one array entry per line, so a pin move is one changed line per changed entry. */
|
|
264
|
+
export function stringifyCatalog(catalog: PostgresCatalog): string {
|
|
265
|
+
const lines: string[] = ["{"];
|
|
266
|
+
lines.push(` "dialect": ${JSON.stringify(catalog.dialect)},`);
|
|
267
|
+
lines.push(` "version": ${JSON.stringify(catalog.version)},`);
|
|
268
|
+
lines.push(` "versionNum": ${catalog.versionNum},`);
|
|
269
|
+
lines.push(` "image": ${JSON.stringify(catalog.image)},`);
|
|
270
|
+
for (const section of CATALOG_SECTIONS) {
|
|
271
|
+
const rows = catalog[section] as unknown[];
|
|
272
|
+
if (rows.length === 0) {
|
|
273
|
+
lines.push(` ${JSON.stringify(section)}: [],`);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
lines.push(` ${JSON.stringify(section)}: [`);
|
|
277
|
+
rows.forEach((row, j) => lines.push(` ${JSON.stringify(row)}${j === rows.length - 1 ? "" : ","}`));
|
|
278
|
+
lines.push(" ],");
|
|
279
|
+
}
|
|
280
|
+
const targets = Object.keys(catalog.storageParameters);
|
|
281
|
+
lines.push(` "storageParameters": {`);
|
|
282
|
+
targets.forEach((t, j) =>
|
|
283
|
+
lines.push(` ${JSON.stringify(t)}: ${JSON.stringify(catalog.storageParameters[t])}${j === targets.length - 1 ? "" : ","}`),
|
|
284
|
+
);
|
|
285
|
+
lines.push(" }", "}");
|
|
286
|
+
return `${lines.join("\n")}\n`;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** Parse and shape-check a snapshot. Throws naming the first section that is missing or not a list. */
|
|
290
|
+
export function parseCatalog(text: string): PostgresCatalog {
|
|
291
|
+
const value = JSON.parse(text) as Partial<PostgresCatalog>;
|
|
292
|
+
if (value.dialect !== "postgres") throw new Error(`not a Postgres catalog (dialect ${String(value.dialect)})`);
|
|
293
|
+
if (typeof value.version !== "string") throw new Error("catalog has no version");
|
|
294
|
+
for (const section of CATALOG_SECTIONS) {
|
|
295
|
+
if (!Array.isArray(value[section])) throw new Error(`catalog section ${section} is missing or not a list`);
|
|
296
|
+
}
|
|
297
|
+
if (typeof value.storageParameters !== "object" || value.storageParameters === null) {
|
|
298
|
+
throw new Error("catalog section storageParameters is missing");
|
|
299
|
+
}
|
|
300
|
+
return value as PostgresCatalog;
|
|
301
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { copyFileSync, mkdtempSync, readFileSync, readdirSync, rmSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
5
|
+
import { fetchCatalogs, snapshotFile, type FetchCatalogsOptions } from "./postgres-fetch";
|
|
6
|
+
import { POSTGRES_PINS } from "./postgres-pin";
|
|
7
|
+
|
|
8
|
+
let dir: string;
|
|
9
|
+
const quiet = () => undefined;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
dir = mkdtempSync(join(tmpdir(), "chant-sql-pgfetch-"));
|
|
13
|
+
for (const p of POSTGRES_PINS) copyFileSync(snapshotFile(p.major), snapshotFile(p.major, dir));
|
|
14
|
+
});
|
|
15
|
+
afterEach(() => rmSync(dir, { recursive: true, force: true }));
|
|
16
|
+
|
|
17
|
+
/** A server stand-in that reports `version` and returns no rows for the rest. */
|
|
18
|
+
function stub(version: string, log: string[]): NonNullable<FetchCatalogsOptions["startServer"]> {
|
|
19
|
+
return async (image) => {
|
|
20
|
+
log.push(`start ${image}`);
|
|
21
|
+
return {
|
|
22
|
+
reader: {
|
|
23
|
+
query: async (sql) => {
|
|
24
|
+
if (sql.includes("server_version'), ' ', 1")) return version;
|
|
25
|
+
if (sql.includes("server_version_num")) return 0;
|
|
26
|
+
return sql.includes("drop schema") ? [] : [];
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
stop: async () => {
|
|
30
|
+
log.push("stop");
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe("where generation gets the Postgres catalogs", () => {
|
|
37
|
+
test("snapshots at their pins are read as they are, and no server is started", async () => {
|
|
38
|
+
const log: string[] = [];
|
|
39
|
+
const catalogs = await fetchCatalogs({ snapshotDir: dir, log: quiet, startServer: stub("1.0", log) });
|
|
40
|
+
expect(catalogs.map((c) => c.version)).toEqual(POSTGRES_PINS.map((p) => p.version));
|
|
41
|
+
expect(log).toEqual([]);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("a snapshot behind its pin starts that major's image only, and refuses a server at another version", async () => {
|
|
45
|
+
const file = snapshotFile(17, dir);
|
|
46
|
+
const stale = readFileSync(file, "utf-8").replace('"version": "17.11"', '"version": "17.9"');
|
|
47
|
+
const { writeFileSync } = await import("node:fs");
|
|
48
|
+
writeFileSync(file, stale);
|
|
49
|
+
const log: string[] = [];
|
|
50
|
+
await expect(fetchCatalogs({ snapshotDir: dir, log: quiet, startServer: stub("17.9", log) })).rejects.toThrow(
|
|
51
|
+
/Postgres 17 is 17\.9, not the pinned 17\.11/,
|
|
52
|
+
);
|
|
53
|
+
expect(log).toEqual([expect.stringMatching(/^start postgres:17\.11@sha256:/), "stop"]);
|
|
54
|
+
expect(readFileSync(file, "utf-8")).toBe(stale);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("a server at the pin rewrites the snapshot", async () => {
|
|
58
|
+
const file = snapshotFile(16, dir);
|
|
59
|
+
rmSync(file);
|
|
60
|
+
const log: string[] = [];
|
|
61
|
+
const catalogs = await fetchCatalogs({ snapshotDir: dir, majors: [16], log: quiet, startServer: stub("16.15", log) });
|
|
62
|
+
expect(catalogs.find((c) => c.version === "16.15")?.types).toEqual([]);
|
|
63
|
+
expect(readFileSync(file, "utf-8")).toContain('"version": "16.15"');
|
|
64
|
+
expect(log).toHaveLength(2);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("force reads only the majors named", async () => {
|
|
68
|
+
const log: string[] = [];
|
|
69
|
+
await expect(
|
|
70
|
+
fetchCatalogs({ snapshotDir: dir, force: true, majors: [18], log: quiet, startServer: stub("18.6", log) }),
|
|
71
|
+
).resolves.toHaveLength(5);
|
|
72
|
+
expect(log).toEqual([expect.stringContaining("postgres:18.6@"), "stop"]);
|
|
73
|
+
expect(readdirSync(dir)).toHaveLength(5);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where generation gets the Postgres catalogs.
|
|
3
|
+
*
|
|
4
|
+
* The committed snapshots, `postgres-catalog-<major>.snapshot.json`, are the
|
|
5
|
+
* source every ordinary run reads: a fresh clone, CI and `npm run prepack`
|
|
6
|
+
* generate from them with no Docker and no network. A server is read, one per
|
|
7
|
+
* major, only when a snapshot cannot serve its pin:
|
|
8
|
+
*
|
|
9
|
+
* - the major's pin moved (its `version` in `postgres-pin.ts` differs from the
|
|
10
|
+
* snapshot's) or the snapshot is missing or unreadable, or
|
|
11
|
+
* - `force` is set.
|
|
12
|
+
*
|
|
13
|
+
* Reading a server means starting that major's image by tag and digest in a
|
|
14
|
+
* throwaway container, checking that its `server_version` is the pin, reading
|
|
15
|
+
* the catalog, and rewriting the snapshot. A server at any other version is
|
|
16
|
+
* refused: a snapshot labelled with one pin and holding another's surface is
|
|
17
|
+
* the failure the pin exists to prevent.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
21
|
+
import { dirname, join } from "node:path";
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
import { POSTGRES_PINS, postgresImage, postgresPin, type PostgresPin } from "./postgres-pin";
|
|
24
|
+
import { parseCatalog, readCatalog, stringifyCatalog, type PostgresCatalog, type PostgresReader } from "./postgres-catalog";
|
|
25
|
+
import { startScratchPostgres } from "../postgres/container";
|
|
26
|
+
|
|
27
|
+
const specDir = dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
|
|
29
|
+
/** The committed snapshot of one major. */
|
|
30
|
+
export const snapshotFile = (major: number, dir: string = specDir): string =>
|
|
31
|
+
join(dir, `postgres-catalog-${major}.snapshot.json`);
|
|
32
|
+
|
|
33
|
+
export interface FetchCatalogsOptions {
|
|
34
|
+
/** Read a server even when the snapshot matches the pin. */
|
|
35
|
+
force?: boolean;
|
|
36
|
+
/** Only these majors (the default is all). */
|
|
37
|
+
majors?: readonly number[];
|
|
38
|
+
/** The directory holding the snapshots. Tests point it elsewhere. */
|
|
39
|
+
snapshotDir?: string;
|
|
40
|
+
/** Start the server for a major. Tests stub it; the default runs the pinned image. */
|
|
41
|
+
startServer?: (image: string) => Promise<{ reader: PostgresReader; stop(): Promise<void> }>;
|
|
42
|
+
/** Log a line saying which route was taken. */
|
|
43
|
+
log?: (line: string) => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function readSnapshot(file: string): PostgresCatalog | undefined {
|
|
47
|
+
try {
|
|
48
|
+
return parseCatalog(readFileSync(file, "utf-8"));
|
|
49
|
+
} catch {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Read one pin's catalog from a server and refuse any other version. */
|
|
55
|
+
export async function catalogFromServer(reader: PostgresReader, pin: PostgresPin, image: string): Promise<PostgresCatalog> {
|
|
56
|
+
const catalog = await readCatalog(reader, image);
|
|
57
|
+
if (catalog.version !== pin.version) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`the server for Postgres ${pin.major} is ${catalog.version}, not the pinned ${pin.version}. ` +
|
|
60
|
+
`Run the pinned image, or update the ${pin.major} line of src/spec/postgres-pin.ts: version and digest together.`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
return catalog;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const defaultStart: NonNullable<FetchCatalogsOptions["startServer"]> = async (image) => {
|
|
67
|
+
const server = await startScratchPostgres(image, { namePrefix: "chant-sql-pg-catalog" });
|
|
68
|
+
return {
|
|
69
|
+
reader: { query: async (sql) => JSON.parse((await server.psql(sql)).trim()) as unknown },
|
|
70
|
+
stop: server.stop,
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The catalogs for the current pins, oldest major first: each snapshot that
|
|
76
|
+
* matches its pin, and a fresh read (which rewrites the snapshot) for each
|
|
77
|
+
* that does not. Servers run one at a time.
|
|
78
|
+
*/
|
|
79
|
+
export async function fetchCatalogs(options: FetchCatalogsOptions = {}): Promise<PostgresCatalog[]> {
|
|
80
|
+
const log = options.log ?? ((line: string) => console.error(line));
|
|
81
|
+
const start = options.startServer ?? defaultStart;
|
|
82
|
+
const wanted = options.majors ?? POSTGRES_PINS.map((p) => p.major);
|
|
83
|
+
const catalogs: PostgresCatalog[] = [];
|
|
84
|
+
for (const pin of POSTGRES_PINS) {
|
|
85
|
+
const file = snapshotFile(pin.major, options.snapshotDir);
|
|
86
|
+
const snapshot = readSnapshot(file);
|
|
87
|
+
const read = wanted.includes(pin.major);
|
|
88
|
+
if (snapshot && snapshot.version === pin.version && !(options.force && read)) {
|
|
89
|
+
log(`[sql] postgres ${pin.major} catalog: committed snapshot at ${snapshot.version}`);
|
|
90
|
+
catalogs.push(snapshot);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const reason = !snapshot
|
|
94
|
+
? "no readable snapshot"
|
|
95
|
+
: snapshot.version !== pin.version
|
|
96
|
+
? `the pin moved from ${snapshot.version} to ${pin.version}`
|
|
97
|
+
: "force";
|
|
98
|
+
const image = postgresImage(pin.major);
|
|
99
|
+
log(`[sql] postgres ${pin.major} catalog: starting ${image} (${reason})`);
|
|
100
|
+
const server = await start(image);
|
|
101
|
+
let catalog: PostgresCatalog;
|
|
102
|
+
try {
|
|
103
|
+
catalog = await catalogFromServer(server.reader, postgresPin(pin.major), image);
|
|
104
|
+
} finally {
|
|
105
|
+
await server.stop();
|
|
106
|
+
}
|
|
107
|
+
writeFileSync(file, stringifyCatalog(catalog));
|
|
108
|
+
log(`[sql] postgres ${pin.major} catalog: wrote ${file}`);
|
|
109
|
+
catalogs.push(catalog);
|
|
110
|
+
}
|
|
111
|
+
return catalogs;
|
|
112
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
POSTGRES_LATEST_MAJOR,
|
|
4
|
+
POSTGRES_MAJORS,
|
|
5
|
+
POSTGRES_PINS,
|
|
6
|
+
postgresImage,
|
|
7
|
+
postgresUpstreamPin,
|
|
8
|
+
versionFromReleaseTag,
|
|
9
|
+
} from "./postgres-pin";
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
|
|
14
|
+
const pinFile = readFileSync(join(dirname(fileURLToPath(import.meta.url)), "postgres-pin.ts"), "utf-8");
|
|
15
|
+
|
|
16
|
+
describe("the Postgres pins", () => {
|
|
17
|
+
test("one pin per supported major, 14 to 18, each an exact minor with an image digest", () => {
|
|
18
|
+
expect(POSTGRES_MAJORS).toEqual([14, 15, 16, 17, 18]);
|
|
19
|
+
expect(POSTGRES_LATEST_MAJOR).toBe(18);
|
|
20
|
+
expect(POSTGRES_PINS.map((p) => p.version)).toEqual(["14.24", "15.19", "16.15", "17.11", "18.6"]);
|
|
21
|
+
for (const p of POSTGRES_PINS) {
|
|
22
|
+
expect(p.version.startsWith(`${p.major}.`)).toBe(true);
|
|
23
|
+
expect(p.digest).toMatch(/^sha256:[0-9a-f]{64}$/);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("the image is the tag and the digest together", () => {
|
|
28
|
+
expect(postgresImage(18)).toBe(
|
|
29
|
+
"postgres:18.6@sha256:5a5a84b19854a9ffaa54082c166ff4ec27473a361e496e5ea167f298f2da9722",
|
|
30
|
+
);
|
|
31
|
+
expect(() => postgresImage(13)).toThrow(/not a supported major/);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("the upstream pins", () => {
|
|
36
|
+
test("a git tag maps to the version; betas, release candidates and old spellings are skipped", () => {
|
|
37
|
+
expect(versionFromReleaseTag("REL_18_6")).toBe("18.6");
|
|
38
|
+
expect(versionFromReleaseTag("REL_17_11")).toBe("17.11");
|
|
39
|
+
for (const tag of ["REL_18_BETA1", "REL_18_RC1", "REL9_6_24", "Release_2_0"]) {
|
|
40
|
+
expect(versionFromReleaseTag(tag)).toBeNull();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test.each(POSTGRES_PINS.map((p) => [p.major, p.version] as const))("the %i pin finds its own line and writes the new version back", (major, version) => {
|
|
45
|
+
const pin = postgresUpstreamPin(major);
|
|
46
|
+
const line = pinFile.split("\n").find((l) => pin.pattern.test(l));
|
|
47
|
+
expect(line).toBeDefined();
|
|
48
|
+
expect(pin.pattern.exec(line!)?.[1]).toBe(version);
|
|
49
|
+
const next = pin.replace("REL_99_9", line!);
|
|
50
|
+
expect(next).toContain('version: "99.9"');
|
|
51
|
+
expect(next).toContain(`major: ${major},`);
|
|
52
|
+
expect(next).toContain("digest:");
|
|
53
|
+
expect(pin.upstream).toMatchObject({ owner: "postgres", repo: "postgres", kind: "tags", trackMajor: true });
|
|
54
|
+
expect(pin.upstream.tagVersion?.("REL_18_6")).toBe("18.6");
|
|
55
|
+
expect(pin.alsoMoves).toContain(`postgres-catalog-${major}.snapshot.json`);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("no pattern matches another major's line", () => {
|
|
59
|
+
for (const p of POSTGRES_PINS) {
|
|
60
|
+
const matching = pinFile.split("\n").filter((l) => postgresUpstreamPin(p.major).pattern.test(l));
|
|
61
|
+
expect(matching).toHaveLength(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|