@intentius/chant-lexicon-sql 0.0.0-stage → 0.112.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -2
- package/dist/clickhouse/apply/apply.d.ts +82 -0
- package/dist/clickhouse/apply/apply.d.ts.map +1 -0
- package/dist/clickhouse/apply/mutations.d.ts +46 -0
- package/dist/clickhouse/apply/mutations.d.ts.map +1 -0
- package/dist/clickhouse/apply/statements.d.ts +99 -0
- package/dist/clickhouse/apply/statements.d.ts.map +1 -0
- package/dist/clickhouse/catalog-types.d.ts +76 -0
- package/dist/clickhouse/catalog-types.d.ts.map +1 -0
- package/dist/clickhouse/container.d.ts +63 -0
- package/dist/clickhouse/container.d.ts.map +1 -0
- package/dist/clickhouse/engine-syntax.d.ts +43 -0
- package/dist/clickhouse/engine-syntax.d.ts.map +1 -0
- package/dist/clickhouse/entities.d.ts +183 -0
- package/dist/clickhouse/entities.d.ts.map +1 -0
- package/dist/clickhouse/http.d.ts +40 -0
- package/dist/clickhouse/http.d.ts.map +1 -0
- package/dist/clickhouse/import/generator.d.ts +16 -0
- package/dist/clickhouse/import/generator.d.ts.map +1 -0
- package/dist/clickhouse/import/ir.d.ts +52 -0
- package/dist/clickhouse/import/ir.d.ts.map +1 -0
- package/dist/clickhouse/import/live-export.d.ts +28 -0
- package/dist/clickhouse/import/live-export.d.ts.map +1 -0
- package/dist/clickhouse/import/parser.d.ts +10 -0
- package/dist/clickhouse/import/parser.d.ts.map +1 -0
- package/dist/clickhouse/live/bind.d.ts +56 -0
- package/dist/clickhouse/live/bind.d.ts.map +1 -0
- package/dist/clickhouse/live/catalog.d.ts +39 -0
- package/dist/clickhouse/live/catalog.d.ts.map +1 -0
- package/dist/clickhouse/live/describe-resources.d.ts +34 -0
- package/dist/clickhouse/live/describe-resources.d.ts.map +1 -0
- package/dist/clickhouse/overlays/codecs.d.ts +28 -0
- package/dist/clickhouse/overlays/codecs.d.ts.map +1 -0
- package/dist/clickhouse/overlays/engines.d.ts +20 -0
- package/dist/clickhouse/overlays/engines.d.ts.map +1 -0
- package/dist/clickhouse/overlays/kinds.d.ts +38 -0
- package/dist/clickhouse/overlays/kinds.d.ts.map +1 -0
- package/dist/clickhouse/overlays/projections.d.ts +27 -0
- package/dist/clickhouse/overlays/projections.d.ts.map +1 -0
- package/dist/clickhouse/overlays/skip-indexes.d.ts +10 -0
- package/dist/clickhouse/overlays/skip-indexes.d.ts.map +1 -0
- package/dist/clickhouse/overlays/ttl.d.ts +35 -0
- package/dist/clickhouse/overlays/ttl.d.ts.map +1 -0
- package/dist/clickhouse/overlays/types.d.ts +21 -0
- package/dist/clickhouse/overlays/types.d.ts.map +1 -0
- package/dist/clickhouse/ownership.d.ts +71 -0
- package/dist/clickhouse/ownership.d.ts.map +1 -0
- package/dist/clickhouse/parser.d.ts +130 -0
- package/dist/clickhouse/parser.d.ts.map +1 -0
- package/dist/clickhouse/plan/commands.d.ts +26 -0
- package/dist/clickhouse/plan/commands.d.ts.map +1 -0
- package/dist/clickhouse/plan/deep.d.ts +32 -0
- package/dist/clickhouse/plan/deep.d.ts.map +1 -0
- package/dist/clickhouse/plan/diff.d.ts +37 -0
- package/dist/clickhouse/plan/diff.d.ts.map +1 -0
- package/dist/clickhouse/plan/disruption.d.ts +17 -0
- package/dist/clickhouse/plan/disruption.d.ts.map +1 -0
- package/dist/clickhouse/plan/normalize.d.ts +97 -0
- package/dist/clickhouse/plan/normalize.d.ts.map +1 -0
- package/dist/clickhouse/plan/rebuild-handoff.d.ts +38 -0
- package/dist/clickhouse/plan/rebuild-handoff.d.ts.map +1 -0
- package/dist/clickhouse/plan/report.d.ts +6 -0
- package/dist/clickhouse/plan/report.d.ts.map +1 -0
- package/dist/clickhouse/plan/rules.d.ts +60 -0
- package/dist/clickhouse/plan/rules.d.ts.map +1 -0
- package/dist/clickhouse/plan/schema.d.ts +23 -0
- package/dist/clickhouse/plan/schema.d.ts.map +1 -0
- package/dist/clickhouse/plan/server-format.d.ts +12 -0
- package/dist/clickhouse/plan/server-format.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/backfill.d.ts +70 -0
- package/dist/clickhouse/rebuild/backfill.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/observe.d.ts +157 -0
- package/dist/clickhouse/rebuild/observe.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/op.d.ts +108 -0
- package/dist/clickhouse/rebuild/op.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/partitions.d.ts +24 -0
- package/dist/clickhouse/rebuild/partitions.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/receipts.d.ts +76 -0
- package/dist/clickhouse/rebuild/receipts.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/replicas.d.ts +78 -0
- package/dist/clickhouse/rebuild/replicas.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/steps.d.ts +151 -0
- package/dist/clickhouse/rebuild/steps.d.ts.map +1 -0
- package/dist/clickhouse/rebuild/verify.d.ts +51 -0
- package/dist/clickhouse/rebuild/verify.d.ts.map +1 -0
- package/dist/clickhouse/testing/fake-server.d.ts +27 -0
- package/dist/clickhouse/testing/fake-server.d.ts.map +1 -0
- package/dist/clickhouse/testing/roundtrip-schema.d.ts +3 -0
- package/dist/clickhouse/testing/roundtrip-schema.d.ts.map +1 -0
- package/dist/clickhouse/testing/writable-server.d.ts +35 -0
- package/dist/clickhouse/testing/writable-server.d.ts.map +1 -0
- package/dist/clickhouse/tokens.d.ts +15 -0
- package/dist/clickhouse/tokens.d.ts.map +1 -0
- package/dist/clickhouse.d.ts +24 -0
- package/dist/clickhouse.d.ts.map +1 -0
- package/dist/codegen/classifier-page.d.ts +6 -0
- package/dist/codegen/classifier-page.d.ts.map +1 -0
- package/dist/codegen/clickhouse-module.d.ts +23 -0
- package/dist/codegen/clickhouse-module.d.ts.map +1 -0
- package/dist/codegen/docs-cli.d.ts +3 -0
- package/dist/codegen/docs-cli.d.ts.map +1 -0
- package/dist/codegen/docs.d.ts +8 -0
- package/dist/codegen/docs.d.ts.map +1 -0
- package/dist/codegen/generate-cli.d.ts +3 -0
- package/dist/codegen/generate-cli.d.ts.map +1 -0
- package/dist/codegen/generate.d.ts +40 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/codegen/package.d.ts +7 -0
- package/dist/codegen/package.d.ts.map +1 -0
- package/dist/codegen/postgres-classifier-page.d.ts +7 -0
- package/dist/codegen/postgres-classifier-page.d.ts.map +1 -0
- package/dist/codegen/postgres-module.d.ts +30 -0
- package/dist/codegen/postgres-module.d.ts.map +1 -0
- package/dist/codegen/registry.d.ts +12 -0
- package/dist/codegen/registry.d.ts.map +1 -0
- package/dist/composites/audit-log-table.d.ts +31 -0
- package/dist/composites/audit-log-table.d.ts.map +1 -0
- package/dist/composites/catalog.d.ts +3 -0
- package/dist/composites/catalog.d.ts.map +1 -0
- package/dist/composites/cdc-mirror.d.ts +32 -0
- package/dist/composites/cdc-mirror.d.ts.map +1 -0
- package/dist/composites/clickhouse.d.ts +7 -0
- package/dist/composites/clickhouse.d.ts.map +1 -0
- package/dist/composites/events-table.d.ts +32 -0
- package/dist/composites/events-table.d.ts.map +1 -0
- package/dist/composites/index.d.ts +9 -0
- package/dist/composites/index.d.ts.map +1 -0
- package/dist/composites/join-table.d.ts +41 -0
- package/dist/composites/join-table.d.ts.map +1 -0
- package/dist/composites/postgres.d.ts +7 -0
- package/dist/composites/postgres.d.ts.map +1 -0
- package/dist/composites/refreshed-view.d.ts +32 -0
- package/dist/composites/refreshed-view.d.ts.map +1 -0
- package/dist/composites/replacing-table.d.ts +34 -0
- package/dist/composites/replacing-table.d.ts.map +1 -0
- package/dist/composites/rollup-view.d.ts +39 -0
- package/dist/composites/rollup-view.d.ts.map +1 -0
- package/dist/composites/sharded-table.d.ts +35 -0
- package/dist/composites/sharded-table.d.ts.map +1 -0
- package/dist/composites/soft-delete-table.d.ts +40 -0
- package/dist/composites/soft-delete-table.d.ts.map +1 -0
- package/dist/composites/tenant-table.d.ts +34 -0
- package/dist/composites/tenant-table.d.ts.map +1 -0
- package/dist/config.d.ts +213 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/core/apply.d.ts +89 -0
- package/dist/core/apply.d.ts.map +1 -0
- package/dist/core/classifier.d.ts +88 -0
- package/dist/core/classifier.d.ts.map +1 -0
- package/dist/core/container.d.ts +45 -0
- package/dist/core/container.d.ts.map +1 -0
- package/dist/core/cursor.d.ts +67 -0
- package/dist/core/cursor.d.ts.map +1 -0
- package/dist/core/diff.d.ts +49 -0
- package/dist/core/diff.d.ts.map +1 -0
- package/dist/core/entity.d.ts +41 -0
- package/dist/core/entity.d.ts.map +1 -0
- package/dist/core/find-templates.d.ts +69 -0
- package/dist/core/find-templates.d.ts.map +1 -0
- package/dist/core/handoff.d.ts +36 -0
- package/dist/core/handoff.d.ts.map +1 -0
- package/dist/core/index.d.ts +61 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/interpolation.d.ts +88 -0
- package/dist/core/interpolation.d.ts.map +1 -0
- package/dist/core/normalize.d.ts +18 -0
- package/dist/core/normalize.d.ts.map +1 -0
- package/dist/core/ownership.d.ts +60 -0
- package/dist/core/ownership.d.ts.map +1 -0
- package/dist/core/receipts.d.ts +28 -0
- package/dist/core/receipts.d.ts.map +1 -0
- package/dist/core/references.d.ts +37 -0
- package/dist/core/references.d.ts.map +1 -0
- package/dist/core/template.d.ts +41 -0
- package/dist/core/template.d.ts.map +1 -0
- package/dist/core/testing/http-stub.d.ts +17 -0
- package/dist/core/testing/http-stub.d.ts.map +1 -0
- package/dist/core/tokens.d.ts +102 -0
- package/dist/core/tokens.d.ts.map +1 -0
- package/dist/coverage.d.ts +25 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/detect.d.ts +15 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/dialects.d.ts +20 -0
- package/dist/dialects.d.ts.map +1 -0
- package/dist/generated/clickhouse-types.d.ts +4380 -0
- package/dist/generated/clickhouse-types.d.ts.map +1 -0
- package/dist/generated/clickhouse.d.ts +11 -0
- package/dist/generated/clickhouse.d.ts.map +1 -0
- package/dist/generated/postgres-types.d.ts +1579 -0
- package/dist/generated/postgres-types.d.ts.map +1 -0
- package/dist/generated/postgres.d.ts +9 -0
- package/dist/generated/postgres.d.ts.map +1 -0
- package/dist/import-generator.d.ts +8 -0
- package/dist/import-generator.d.ts.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/init-templates.d.ts +20 -0
- package/dist/init-templates.d.ts.map +1 -0
- package/dist/integrity.json +61 -0
- package/dist/lint/audit-catalog.d.ts +10 -0
- package/dist/lint/audit-catalog.d.ts.map +1 -0
- package/dist/lint/audit-lineage.d.ts +25 -0
- package/dist/lint/audit-lineage.d.ts.map +1 -0
- package/dist/lint/post-synth/audit-entries.d.ts +8 -0
- package/dist/lint/post-synth/audit-entries.d.ts.map +1 -0
- package/dist/lint/post-synth/clickhouse-helpers.d.ts +85 -0
- package/dist/lint/post-synth/clickhouse-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/index.d.ts +3 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -0
- package/dist/lint/post-synth/postgres-audit-entries.d.ts +9 -0
- package/dist/lint/post-synth/postgres-audit-entries.d.ts.map +1 -0
- package/dist/lint/post-synth/postgres-helpers.d.ts +89 -0
- package/dist/lint/post-synth/postgres-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/sql-helpers.d.ts +27 -0
- package/dist/lint/post-synth/sql-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch101.d.ts +12 -0
- package/dist/lint/post-synth/sqlch101.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch102.d.ts +9 -0
- package/dist/lint/post-synth/sqlch102.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch103.d.ts +10 -0
- package/dist/lint/post-synth/sqlch103.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch104.d.ts +9 -0
- package/dist/lint/post-synth/sqlch104.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch105.d.ts +10 -0
- package/dist/lint/post-synth/sqlch105.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch106.d.ts +11 -0
- package/dist/lint/post-synth/sqlch106.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch107.d.ts +10 -0
- package/dist/lint/post-synth/sqlch107.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch108.d.ts +11 -0
- package/dist/lint/post-synth/sqlch108.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch109.d.ts +10 -0
- package/dist/lint/post-synth/sqlch109.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch110.d.ts +12 -0
- package/dist/lint/post-synth/sqlch110.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch111.d.ts +11 -0
- package/dist/lint/post-synth/sqlch111.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch112.d.ts +12 -0
- package/dist/lint/post-synth/sqlch112.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch113.d.ts +9 -0
- package/dist/lint/post-synth/sqlch113.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch114.d.ts +8 -0
- package/dist/lint/post-synth/sqlch114.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch115.d.ts +13 -0
- package/dist/lint/post-synth/sqlch115.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch116.d.ts +10 -0
- package/dist/lint/post-synth/sqlch116.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch117.d.ts +9 -0
- package/dist/lint/post-synth/sqlch117.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch118.d.ts +10 -0
- package/dist/lint/post-synth/sqlch118.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch119.d.ts +11 -0
- package/dist/lint/post-synth/sqlch119.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch120.d.ts +10 -0
- package/dist/lint/post-synth/sqlch120.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg101.d.ts +12 -0
- package/dist/lint/post-synth/sqlpg101.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg102.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg102.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg103.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg103.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg104.d.ts +10 -0
- package/dist/lint/post-synth/sqlpg104.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg105.d.ts +10 -0
- package/dist/lint/post-synth/sqlpg105.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg106.d.ts +9 -0
- package/dist/lint/post-synth/sqlpg106.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg107.d.ts +10 -0
- package/dist/lint/post-synth/sqlpg107.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg108.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg108.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg109.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg109.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg110.d.ts +12 -0
- package/dist/lint/post-synth/sqlpg110.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg111.d.ts +10 -0
- package/dist/lint/post-synth/sqlpg111.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg112.d.ts +10 -0
- package/dist/lint/post-synth/sqlpg112.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg113.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg113.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg114.d.ts +13 -0
- package/dist/lint/post-synth/sqlpg114.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg115.d.ts +13 -0
- package/dist/lint/post-synth/sqlpg115.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg116.d.ts +11 -0
- package/dist/lint/post-synth/sqlpg116.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg117.d.ts +12 -0
- package/dist/lint/post-synth/sqlpg117.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlpg118.d.ts +12 -0
- package/dist/lint/post-synth/sqlpg118.d.ts.map +1 -0
- package/dist/lint/rules/index.d.ts +12 -0
- package/dist/lint/rules/index.d.ts.map +1 -0
- package/dist/lint/rules/postgres-templates.d.ts +18 -0
- package/dist/lint/rules/postgres-templates.d.ts.map +1 -0
- package/dist/lint/rules/sqlch001.d.ts +12 -0
- package/dist/lint/rules/sqlch001.d.ts.map +1 -0
- package/dist/lint/rules/sqlch002.d.ts +11 -0
- package/dist/lint/rules/sqlch002.d.ts.map +1 -0
- package/dist/lint/rules/sqlch003.d.ts +12 -0
- package/dist/lint/rules/sqlch003.d.ts.map +1 -0
- package/dist/lint/rules/sqlpg001.d.ts +16 -0
- package/dist/lint/rules/sqlpg001.d.ts.map +1 -0
- package/dist/lint/rules/sqlpg002.d.ts +12 -0
- package/dist/lint/rules/sqlpg002.d.ts.map +1 -0
- package/dist/lint/rules/sqlpg003.d.ts +16 -0
- package/dist/lint/rules/sqlpg003.d.ts.map +1 -0
- package/dist/lint/rules/sqlpg004.d.ts +21 -0
- package/dist/lint/rules/sqlpg004.d.ts.map +1 -0
- package/dist/lint/rules/templates.d.ts +23 -0
- package/dist/lint/rules/templates.d.ts.map +1 -0
- package/dist/live-dialect.d.ts +25 -0
- package/dist/live-dialect.d.ts.map +1 -0
- package/dist/lsp/catalog.d.ts +22 -0
- package/dist/lsp/catalog.d.ts.map +1 -0
- package/dist/lsp/completions.d.ts +13 -0
- package/dist/lsp/completions.d.ts.map +1 -0
- package/dist/lsp/hover.d.ts +12 -0
- package/dist/lsp/hover.d.ts.map +1 -0
- package/dist/lsp/postgres-catalog.d.ts +85 -0
- package/dist/lsp/postgres-catalog.d.ts.map +1 -0
- package/dist/lsp/postgres-template.d.ts +35 -0
- package/dist/lsp/postgres-template.d.ts.map +1 -0
- package/dist/lsp/postgres.d.ts +20 -0
- package/dist/lsp/postgres.d.ts.map +1 -0
- package/dist/lsp/refs.d.ts +8 -0
- package/dist/lsp/refs.d.ts.map +1 -0
- package/dist/lsp/registry.d.ts +4 -0
- package/dist/lsp/registry.d.ts.map +1 -0
- package/dist/lsp/template.d.ts +34 -0
- package/dist/lsp/template.d.ts.map +1 -0
- package/dist/manifest.json +8 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/postgres.d.ts +32 -0
- package/dist/mcp/postgres.d.ts.map +1 -0
- package/dist/meta.json +67 -0
- package/dist/okf/index.md +67 -0
- package/dist/okf/rules/SQLCH001.md +11 -0
- package/dist/okf/rules/SQLCH002.md +11 -0
- package/dist/okf/rules/SQLCH003.md +11 -0
- package/dist/okf/rules/SQLCH101.md +15 -0
- package/dist/okf/rules/SQLCH102.md +11 -0
- package/dist/okf/rules/SQLCH103.md +11 -0
- package/dist/okf/rules/SQLCH104.md +11 -0
- package/dist/okf/rules/SQLCH105.md +11 -0
- package/dist/okf/rules/SQLCH106.md +11 -0
- package/dist/okf/rules/SQLCH107.md +11 -0
- package/dist/okf/rules/SQLCH108.md +15 -0
- package/dist/okf/rules/SQLCH109.md +11 -0
- package/dist/okf/rules/SQLCH110.md +11 -0
- package/dist/okf/rules/SQLCH111.md +11 -0
- package/dist/okf/rules/SQLCH112.md +11 -0
- package/dist/okf/rules/SQLCH113.md +11 -0
- package/dist/okf/rules/SQLCH114.md +11 -0
- package/dist/okf/rules/SQLCH115.md +11 -0
- package/dist/okf/rules/SQLCH116.md +11 -0
- package/dist/okf/rules/SQLCH117.md +15 -0
- package/dist/okf/rules/SQLCH118.md +15 -0
- package/dist/okf/rules/SQLCH119.md +15 -0
- package/dist/okf/rules/SQLCH120.md +15 -0
- package/dist/okf/rules/SQLPG001.md +11 -0
- package/dist/okf/rules/SQLPG002.md +11 -0
- package/dist/okf/rules/SQLPG003.md +11 -0
- package/dist/okf/rules/SQLPG004.md +11 -0
- package/dist/okf/rules/SQLPG101.md +11 -0
- package/dist/okf/rules/SQLPG102.md +11 -0
- package/dist/okf/rules/SQLPG103.md +11 -0
- package/dist/okf/rules/SQLPG104.md +11 -0
- package/dist/okf/rules/SQLPG105.md +11 -0
- package/dist/okf/rules/SQLPG106.md +11 -0
- package/dist/okf/rules/SQLPG107.md +11 -0
- package/dist/okf/rules/SQLPG108.md +11 -0
- package/dist/okf/rules/SQLPG109.md +11 -0
- package/dist/okf/rules/SQLPG110.md +11 -0
- package/dist/okf/rules/SQLPG111.md +11 -0
- package/dist/okf/rules/SQLPG112.md +11 -0
- package/dist/okf/rules/SQLPG113.md +24 -0
- package/dist/okf/rules/SQLPG114.md +11 -0
- package/dist/okf/rules/SQLPG115.md +11 -0
- package/dist/okf/rules/SQLPG116.md +15 -0
- package/dist/okf/rules/SQLPG117.md +11 -0
- package/dist/okf/rules/SQLPG118.md +11 -0
- package/dist/okf/types/Database.md +15 -0
- package/dist/okf/types/MaterializedView.md +14 -0
- package/dist/okf/types/PostgresDomain.md +13 -0
- package/dist/okf/types/PostgresEnum.md +13 -0
- package/dist/okf/types/PostgresExtension.md +13 -0
- package/dist/okf/types/PostgresIndex.md +9 -0
- package/dist/okf/types/PostgresMaterializedView.md +13 -0
- package/dist/okf/types/PostgresSchema.md +13 -0
- package/dist/okf/types/PostgresSequence.md +13 -0
- package/dist/okf/types/PostgresTable.md +13 -0
- package/dist/okf/types/PostgresView.md +13 -0
- package/dist/okf/types/Table.md +15 -0
- package/dist/okf/types/View.md +13 -0
- package/dist/op/activities/clickhouse-apply.d.ts +56 -0
- package/dist/op/activities/clickhouse-apply.d.ts.map +1 -0
- package/dist/op/activities/clickhouse-emulator.d.ts +26 -0
- package/dist/op/activities/clickhouse-emulator.d.ts.map +1 -0
- package/dist/op/activities/clickhouse-rebuild.d.ts +43 -0
- package/dist/op/activities/clickhouse-rebuild.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +19 -0
- package/dist/op/activities/index.d.ts.map +1 -0
- package/dist/op/activities/postgres-apply.d.ts +69 -0
- package/dist/op/activities/postgres-apply.d.ts.map +1 -0
- package/dist/op/activities/postgres-emulator.d.ts +33 -0
- package/dist/op/activities/postgres-emulator.d.ts.map +1 -0
- package/dist/op/activities/postgres-migration.d.ts +48 -0
- package/dist/op/activities/postgres-migration.d.ts.map +1 -0
- package/dist/op/activity-contracts.d.ts +464 -0
- package/dist/op/activity-contracts.d.ts.map +1 -0
- package/dist/package-cli.d.ts +3 -0
- package/dist/package-cli.d.ts.map +1 -0
- package/dist/plugin.d.ts +12 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/postgres/apply/apply.d.ts +163 -0
- package/dist/postgres/apply/apply.d.ts.map +1 -0
- package/dist/postgres/apply/statements.d.ts +138 -0
- package/dist/postgres/apply/statements.d.ts.map +1 -0
- package/dist/postgres/catalog-types.d.ts +50 -0
- package/dist/postgres/catalog-types.d.ts.map +1 -0
- package/dist/postgres/container.d.ts +23 -0
- package/dist/postgres/container.d.ts.map +1 -0
- package/dist/postgres/entities.d.ts +322 -0
- package/dist/postgres/entities.d.ts.map +1 -0
- package/dist/postgres/entity-types.d.ts +17 -0
- package/dist/postgres/entity-types.d.ts.map +1 -0
- package/dist/postgres/import/generator.d.ts +28 -0
- package/dist/postgres/import/generator.d.ts.map +1 -0
- package/dist/postgres/import/ir.d.ts +24 -0
- package/dist/postgres/import/ir.d.ts.map +1 -0
- package/dist/postgres/import/live-export.d.ts +26 -0
- package/dist/postgres/import/live-export.d.ts.map +1 -0
- package/dist/postgres/keywords.d.ts +22 -0
- package/dist/postgres/keywords.d.ts.map +1 -0
- package/dist/postgres/live/bind.d.ts +76 -0
- package/dist/postgres/live/bind.d.ts.map +1 -0
- package/dist/postgres/live/catalog.d.ts +98 -0
- package/dist/postgres/live/catalog.d.ts.map +1 -0
- package/dist/postgres/live/client.d.ts +32 -0
- package/dist/postgres/live/client.d.ts.map +1 -0
- package/dist/postgres/live/describe-resources.d.ts +41 -0
- package/dist/postgres/live/describe-resources.d.ts.map +1 -0
- package/dist/postgres/migrate/backfill.d.ts +103 -0
- package/dist/postgres/migrate/backfill.d.ts.map +1 -0
- package/dist/postgres/migrate/batches.d.ts +90 -0
- package/dist/postgres/migrate/batches.d.ts.map +1 -0
- package/dist/postgres/migrate/carry.d.ts +196 -0
- package/dist/postgres/migrate/carry.d.ts.map +1 -0
- package/dist/postgres/migrate/handoff.d.ts +46 -0
- package/dist/postgres/migrate/handoff.d.ts.map +1 -0
- package/dist/postgres/migrate/names.d.ts +55 -0
- package/dist/postgres/migrate/names.d.ts.map +1 -0
- package/dist/postgres/migrate/observe.d.ts +139 -0
- package/dist/postgres/migrate/observe.d.ts.map +1 -0
- package/dist/postgres/migrate/op.d.ts +128 -0
- package/dist/postgres/migrate/op.d.ts.map +1 -0
- package/dist/postgres/migrate/receipts.d.ts +63 -0
- package/dist/postgres/migrate/receipts.d.ts.map +1 -0
- package/dist/postgres/migrate/replication.d.ts +80 -0
- package/dist/postgres/migrate/replication.d.ts.map +1 -0
- package/dist/postgres/migrate/steps.d.ts +225 -0
- package/dist/postgres/migrate/steps.d.ts.map +1 -0
- package/dist/postgres/overlays/columns.d.ts +6 -0
- package/dist/postgres/overlays/columns.d.ts.map +1 -0
- package/dist/postgres/overlays/constraints.d.ts +8 -0
- package/dist/postgres/overlays/constraints.d.ts.map +1 -0
- package/dist/postgres/overlays/indexes.d.ts +8 -0
- package/dist/postgres/overlays/indexes.d.ts.map +1 -0
- package/dist/postgres/overlays/kinds.d.ts +48 -0
- package/dist/postgres/overlays/kinds.d.ts.map +1 -0
- package/dist/postgres/overlays/partitioning.d.ts +5 -0
- package/dist/postgres/overlays/partitioning.d.ts.map +1 -0
- package/dist/postgres/overlays/relations.d.ts +6 -0
- package/dist/postgres/overlays/relations.d.ts.map +1 -0
- package/dist/postgres/overlays/storage.d.ts +28 -0
- package/dist/postgres/overlays/storage.d.ts.map +1 -0
- package/dist/postgres/overlays/type-ddl.d.ts +7 -0
- package/dist/postgres/overlays/type-ddl.d.ts.map +1 -0
- package/dist/postgres/overlays/types.d.ts +24 -0
- package/dist/postgres/overlays/types.d.ts.map +1 -0
- package/dist/postgres/parser.d.ts +216 -0
- package/dist/postgres/parser.d.ts.map +1 -0
- package/dist/postgres/plan/commands.d.ts +61 -0
- package/dist/postgres/plan/commands.d.ts.map +1 -0
- package/dist/postgres/plan/deep.d.ts +33 -0
- package/dist/postgres/plan/deep.d.ts.map +1 -0
- package/dist/postgres/plan/diff.d.ts +45 -0
- package/dist/postgres/plan/diff.d.ts.map +1 -0
- package/dist/postgres/plan/disruption.d.ts +14 -0
- package/dist/postgres/plan/disruption.d.ts.map +1 -0
- package/dist/postgres/plan/normalize.d.ts +108 -0
- package/dist/postgres/plan/normalize.d.ts.map +1 -0
- package/dist/postgres/plan/report.d.ts +6 -0
- package/dist/postgres/plan/report.d.ts.map +1 -0
- package/dist/postgres/plan/rules.d.ts +84 -0
- package/dist/postgres/plan/rules.d.ts.map +1 -0
- package/dist/postgres/plan/schema.d.ts +50 -0
- package/dist/postgres/plan/schema.d.ts.map +1 -0
- package/dist/postgres/plan/server-normalize.d.ts +26 -0
- package/dist/postgres/plan/server-normalize.d.ts.map +1 -0
- package/dist/postgres/providers/aurora.d.ts +12 -0
- package/dist/postgres/providers/aurora.d.ts.map +1 -0
- package/dist/postgres/providers/azure.d.ts +14 -0
- package/dist/postgres/providers/azure.d.ts.map +1 -0
- package/dist/postgres/providers/cloud-sql.d.ts +11 -0
- package/dist/postgres/providers/cloud-sql.d.ts.map +1 -0
- package/dist/postgres/providers/index.d.ts +35 -0
- package/dist/postgres/providers/index.d.ts.map +1 -0
- package/dist/postgres/providers/neon.d.ts +13 -0
- package/dist/postgres/providers/neon.d.ts.map +1 -0
- package/dist/postgres/providers/rds.d.ts +10 -0
- package/dist/postgres/providers/rds.d.ts.map +1 -0
- package/dist/postgres/providers/supabase.d.ts +12 -0
- package/dist/postgres/providers/supabase.d.ts.map +1 -0
- package/dist/postgres/providers/types.d.ts +59 -0
- package/dist/postgres/providers/types.d.ts.map +1 -0
- package/dist/postgres/testing/fake-client.d.ts +38 -0
- package/dist/postgres/testing/fake-client.d.ts.map +1 -0
- package/dist/postgres/testing/migration.d.ts +25 -0
- package/dist/postgres/testing/migration.d.ts.map +1 -0
- package/dist/postgres/testing/roundtrip-schema.d.ts +11 -0
- package/dist/postgres/testing/roundtrip-schema.d.ts.map +1 -0
- package/dist/postgres/testing/server.d.ts +17 -0
- package/dist/postgres/testing/server.d.ts.map +1 -0
- package/dist/postgres/testing/writable-server.d.ts +45 -0
- package/dist/postgres/testing/writable-server.d.ts.map +1 -0
- package/dist/postgres/tokens.d.ts +26 -0
- package/dist/postgres/tokens.d.ts.map +1 -0
- package/dist/postgres.d.ts +13 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/rules/audit-entries.ts +29 -0
- package/dist/rules/clickhouse-helpers.ts +206 -0
- package/dist/rules/postgres-audit-entries.ts +29 -0
- package/dist/rules/postgres-helpers.ts +126 -0
- package/dist/rules/postgres-templates.ts +36 -0
- package/dist/rules/sql-helpers.ts +53 -0
- package/dist/rules/sqlch001.ts +53 -0
- package/dist/rules/sqlch002.ts +115 -0
- package/dist/rules/sqlch003.ts +68 -0
- package/dist/rules/sqlch101.ts +35 -0
- package/dist/rules/sqlch102.ts +23 -0
- package/dist/rules/sqlch103.ts +45 -0
- package/dist/rules/sqlch104.ts +42 -0
- package/dist/rules/sqlch105.ts +35 -0
- package/dist/rules/sqlch106.ts +27 -0
- package/dist/rules/sqlch107.ts +35 -0
- package/dist/rules/sqlch108.ts +27 -0
- package/dist/rules/sqlch109.ts +21 -0
- package/dist/rules/sqlch110.ts +29 -0
- package/dist/rules/sqlch111.ts +40 -0
- package/dist/rules/sqlch112.ts +30 -0
- package/dist/rules/sqlch113.ts +20 -0
- package/dist/rules/sqlch114.ts +26 -0
- package/dist/rules/sqlch115.ts +31 -0
- package/dist/rules/sqlch116.ts +22 -0
- package/dist/rules/sqlch117.ts +25 -0
- package/dist/rules/sqlch118.ts +26 -0
- package/dist/rules/sqlch119.ts +31 -0
- package/dist/rules/sqlch120.ts +21 -0
- package/dist/rules/sqlpg001.ts +88 -0
- package/dist/rules/sqlpg002.ts +68 -0
- package/dist/rules/sqlpg003.ts +59 -0
- package/dist/rules/sqlpg004.ts +73 -0
- package/dist/rules/sqlpg101.ts +24 -0
- package/dist/rules/sqlpg102.ts +30 -0
- package/dist/rules/sqlpg103.ts +23 -0
- package/dist/rules/sqlpg104.ts +23 -0
- package/dist/rules/sqlpg105.ts +22 -0
- package/dist/rules/sqlpg106.ts +22 -0
- package/dist/rules/sqlpg107.ts +22 -0
- package/dist/rules/sqlpg108.ts +27 -0
- package/dist/rules/sqlpg109.ts +37 -0
- package/dist/rules/sqlpg110.ts +33 -0
- package/dist/rules/sqlpg111.ts +23 -0
- package/dist/rules/sqlpg112.ts +25 -0
- package/dist/rules/sqlpg113.ts +28 -0
- package/dist/rules/sqlpg114.ts +37 -0
- package/dist/rules/sqlpg115.ts +38 -0
- package/dist/rules/sqlpg116.ts +25 -0
- package/dist/rules/sqlpg117.ts +24 -0
- package/dist/rules/sqlpg118.ts +22 -0
- package/dist/rules/templates.ts +35 -0
- package/dist/serializer.d.ts +37 -0
- package/dist/serializer.d.ts.map +1 -0
- package/dist/skill-defs.d.ts +3 -0
- package/dist/skill-defs.d.ts.map +1 -0
- package/dist/spec/catalog.d.ts +125 -0
- package/dist/spec/catalog.d.ts.map +1 -0
- package/dist/spec/fetch.d.ts +43 -0
- package/dist/spec/fetch.d.ts.map +1 -0
- package/dist/spec/pin.d.ts +39 -0
- package/dist/spec/pin.d.ts.map +1 -0
- package/dist/spec/postgres-catalog.d.ts +108 -0
- package/dist/spec/postgres-catalog.d.ts.map +1 -0
- package/dist/spec/postgres-fetch.d.ts +46 -0
- package/dist/spec/postgres-fetch.d.ts.map +1 -0
- package/dist/spec/postgres-pin.d.ts +67 -0
- package/dist/spec/postgres-pin.d.ts.map +1 -0
- package/dist/types/index.d.ts +4386 -0
- package/dist/validate-cli.d.ts +3 -0
- package/dist/validate-cli.d.ts.map +1 -0
- package/dist/validate.d.ts +15 -0
- package/dist/validate.d.ts.map +1 -0
- package/package.json +74 -4
- package/src/clickhouse/apply/apply.ts +288 -0
- package/src/clickhouse/apply/mutations.ts +90 -0
- package/src/clickhouse/apply/statements.ts +393 -0
- package/src/clickhouse/catalog-types.ts +84 -0
- package/src/clickhouse/container.ts +176 -0
- package/src/clickhouse/engine-syntax.test.ts +53 -0
- package/src/clickhouse/engine-syntax.ts +173 -0
- package/src/clickhouse/entities.test.ts +188 -0
- package/src/clickhouse/entities.ts +425 -0
- package/src/clickhouse/http.ts +76 -0
- package/src/clickhouse/import/generator.ts +153 -0
- package/src/clickhouse/import/import.test.ts +157 -0
- package/src/clickhouse/import/ir.ts +171 -0
- package/src/clickhouse/import/live-export.ts +53 -0
- package/src/clickhouse/import/parser.ts +27 -0
- package/src/clickhouse/import/roundtrip.test.ts +90 -0
- package/src/clickhouse/live/bind.ts +126 -0
- package/src/clickhouse/live/catalog.ts +96 -0
- package/src/clickhouse/live/describe-resources.ts +98 -0
- package/src/clickhouse/live/live.test.ts +143 -0
- package/src/clickhouse/live/roundtrip.e2e.test.ts +93 -0
- package/src/clickhouse/overlays/codecs.ts +68 -0
- package/src/clickhouse/overlays/engines.ts +108 -0
- package/src/clickhouse/overlays/kinds.ts +38 -0
- package/src/clickhouse/overlays/projections.ts +36 -0
- package/src/clickhouse/overlays/skip-indexes.ts +44 -0
- package/src/clickhouse/overlays/ttl.ts +55 -0
- package/src/clickhouse/overlays/types.ts +58 -0
- package/src/clickhouse/ownership.test.ts +20 -0
- package/src/clickhouse/ownership.ts +103 -0
- package/src/clickhouse/parser.test.ts +166 -0
- package/src/clickhouse/parser.ts +459 -0
- package/src/clickhouse/plan/commands.ts +101 -0
- package/src/clickhouse/plan/deep.ts +124 -0
- package/src/clickhouse/plan/diff.ts +203 -0
- package/src/clickhouse/plan/disruption.ts +61 -0
- package/src/clickhouse/plan/normalize.ts +352 -0
- package/src/clickhouse/plan/plan-wiring.test.ts +77 -0
- package/src/clickhouse/plan/plan.e2e.test.ts +77 -0
- package/src/clickhouse/plan/plan.test.ts +201 -0
- package/src/clickhouse/plan/rebuild-handoff.ts +59 -0
- package/src/clickhouse/plan/report.ts +19 -0
- package/src/clickhouse/plan/rules.ts +241 -0
- package/src/clickhouse/plan/schema.ts +56 -0
- package/src/clickhouse/plan/server-format.ts +39 -0
- package/src/clickhouse/rebuild/backfill.ts +186 -0
- package/src/clickhouse/rebuild/observe.ts +380 -0
- package/src/clickhouse/rebuild/op.ts +206 -0
- package/src/clickhouse/rebuild/partitions.ts +62 -0
- package/src/clickhouse/rebuild/rebuild-replicated.e2e.test.ts +513 -0
- package/src/clickhouse/rebuild/rebuild.e2e.test.ts +351 -0
- package/src/clickhouse/rebuild/rebuild.test.ts +190 -0
- package/src/clickhouse/rebuild/receipts.ts +143 -0
- package/src/clickhouse/rebuild/replicas.test.ts +70 -0
- package/src/clickhouse/rebuild/replicas.ts +148 -0
- package/src/clickhouse/rebuild/steps.ts +382 -0
- package/src/clickhouse/rebuild/verify.ts +124 -0
- package/src/clickhouse/testdata/NOTICE +5 -0
- package/src/clickhouse/testdata/clickhouse-tests-corpus.json +302 -0
- package/src/clickhouse/testing/fake-server.ts +65 -0
- package/src/clickhouse/testing/roundtrip-schema.ts +25 -0
- package/src/clickhouse/testing/writable-server.ts +141 -0
- package/src/clickhouse/tokens.ts +28 -0
- package/src/clickhouse.ts +63 -0
- package/src/codegen/classifier-page.test.ts +16 -0
- package/src/codegen/classifier-page.ts +76 -0
- package/src/codegen/clickhouse-module.test.ts +63 -0
- package/src/codegen/clickhouse-module.ts +269 -0
- package/src/codegen/docs-cli.ts +4 -0
- package/src/codegen/docs.ts +225 -0
- package/src/codegen/generate-cli.ts +13 -0
- package/src/codegen/generate.ts +126 -0
- package/src/codegen/package.ts +36 -0
- package/src/codegen/postgres-classifier-page.ts +81 -0
- package/src/codegen/postgres-module.test.ts +77 -0
- package/src/codegen/postgres-module.ts +434 -0
- package/src/codegen/registry.ts +36 -0
- package/src/composites/audit-log-table.ts +54 -0
- package/src/composites/catalog.test.ts +61 -0
- package/src/composites/catalog.ts +529 -0
- package/src/composites/cdc-mirror.ts +54 -0
- package/src/composites/clickhouse.ts +7 -0
- package/src/composites/composites.test.ts +758 -0
- package/src/composites/events-table.ts +49 -0
- package/src/composites/index.ts +9 -0
- package/src/composites/join-table.ts +57 -0
- package/src/composites/postgres.ts +7 -0
- package/src/composites/refreshed-view.ts +46 -0
- package/src/composites/replacing-table.ts +49 -0
- package/src/composites/rollup-view.ts +55 -0
- package/src/composites/sharded-table.ts +49 -0
- package/src/composites/soft-delete-table.ts +61 -0
- package/src/composites/tenant-table.ts +50 -0
- package/src/config.ts +157 -0
- package/src/core/apply.ts +153 -0
- package/src/core/classifier.ts +186 -0
- package/src/core/container.ts +93 -0
- package/src/core/core.test.ts +254 -0
- package/src/core/cursor.ts +189 -0
- package/src/core/diff.ts +72 -0
- package/src/core/entity.ts +85 -0
- package/src/core/find-templates.ts +158 -0
- package/src/core/handoff.ts +44 -0
- package/src/core/index.ts +61 -0
- package/src/core/interpolation.ts +225 -0
- package/src/core/normalize.ts +39 -0
- package/src/core/ownership.test.ts +36 -0
- package/src/core/ownership.ts +133 -0
- package/src/core/receipts.ts +29 -0
- package/src/core/references.ts +74 -0
- package/src/core/template.ts +83 -0
- package/src/core/testing/http-stub.ts +33 -0
- package/src/core/tokens.ts +252 -0
- package/src/coverage.ts +64 -0
- package/src/detect.ts +32 -0
- package/src/dialects.ts +21 -0
- package/src/generated/clickhouse-types.ts +4386 -0
- package/src/generated/clickhouse.ts +2476 -0
- package/src/generated/index.d.ts +4386 -0
- package/src/generated/lexicon-sql.json +67 -0
- package/src/generated/postgres-types.ts +1190 -0
- package/src/generated/postgres.ts +1039 -0
- package/src/import-generator.ts +18 -0
- package/src/index.ts +21 -0
- package/src/init-templates.test.ts +108 -0
- package/src/init-templates.ts +327 -0
- package/src/lint/audit-catalog.ts +73 -0
- package/src/lint/audit-lineage.ts +47 -0
- package/src/lint/post-synth/audit-entries.ts +29 -0
- package/src/lint/post-synth/clickhouse-checks.test.ts +278 -0
- package/src/lint/post-synth/clickhouse-helpers.ts +206 -0
- package/src/lint/post-synth/index.ts +81 -0
- package/src/lint/post-synth/post-synth.test.ts +33 -0
- package/src/lint/post-synth/postgres-audit-entries.ts +29 -0
- package/src/lint/post-synth/postgres-checks.test.ts +257 -0
- package/src/lint/post-synth/postgres-helpers.ts +126 -0
- package/src/lint/post-synth/sql-helpers.ts +53 -0
- package/src/lint/post-synth/sqlch101.ts +35 -0
- package/src/lint/post-synth/sqlch102.ts +23 -0
- package/src/lint/post-synth/sqlch103.ts +45 -0
- package/src/lint/post-synth/sqlch104.ts +42 -0
- package/src/lint/post-synth/sqlch105.ts +35 -0
- package/src/lint/post-synth/sqlch106.ts +27 -0
- package/src/lint/post-synth/sqlch107.ts +35 -0
- package/src/lint/post-synth/sqlch108.ts +27 -0
- package/src/lint/post-synth/sqlch109.ts +21 -0
- package/src/lint/post-synth/sqlch110.ts +29 -0
- package/src/lint/post-synth/sqlch111.ts +40 -0
- package/src/lint/post-synth/sqlch112.ts +30 -0
- package/src/lint/post-synth/sqlch113.ts +20 -0
- package/src/lint/post-synth/sqlch114.ts +26 -0
- package/src/lint/post-synth/sqlch115.ts +31 -0
- package/src/lint/post-synth/sqlch116.ts +22 -0
- package/src/lint/post-synth/sqlch117.ts +25 -0
- package/src/lint/post-synth/sqlch118.ts +26 -0
- package/src/lint/post-synth/sqlch119.ts +31 -0
- package/src/lint/post-synth/sqlch120.ts +21 -0
- package/src/lint/post-synth/sqlpg101.ts +24 -0
- package/src/lint/post-synth/sqlpg102.ts +30 -0
- package/src/lint/post-synth/sqlpg103.ts +23 -0
- package/src/lint/post-synth/sqlpg104.ts +23 -0
- package/src/lint/post-synth/sqlpg105.ts +22 -0
- package/src/lint/post-synth/sqlpg106.ts +22 -0
- package/src/lint/post-synth/sqlpg107.ts +22 -0
- package/src/lint/post-synth/sqlpg108.ts +27 -0
- package/src/lint/post-synth/sqlpg109.ts +37 -0
- package/src/lint/post-synth/sqlpg110.ts +33 -0
- package/src/lint/post-synth/sqlpg111.ts +23 -0
- package/src/lint/post-synth/sqlpg112.ts +25 -0
- package/src/lint/post-synth/sqlpg113.ts +28 -0
- package/src/lint/post-synth/sqlpg114.ts +37 -0
- package/src/lint/post-synth/sqlpg115.ts +38 -0
- package/src/lint/post-synth/sqlpg116.ts +25 -0
- package/src/lint/post-synth/sqlpg117.ts +24 -0
- package/src/lint/post-synth/sqlpg118.ts +22 -0
- package/src/lint/rules/index.ts +13 -0
- package/src/lint/rules/postgres-templates.ts +36 -0
- package/src/lint/rules/rules.test.ts +228 -0
- package/src/lint/rules/sqlch001.ts +53 -0
- package/src/lint/rules/sqlch002.ts +115 -0
- package/src/lint/rules/sqlch003.ts +68 -0
- package/src/lint/rules/sqlpg001.ts +88 -0
- package/src/lint/rules/sqlpg002.ts +68 -0
- package/src/lint/rules/sqlpg003.ts +59 -0
- package/src/lint/rules/sqlpg004.ts +73 -0
- package/src/lint/rules/templates.ts +35 -0
- package/src/live-dialect.ts +37 -0
- package/src/lsp/catalog.ts +60 -0
- package/src/lsp/completions.test.ts +111 -0
- package/src/lsp/completions.ts +128 -0
- package/src/lsp/diagnostics.test.ts +26 -0
- package/src/lsp/hover.test.ts +90 -0
- package/src/lsp/hover.ts +113 -0
- package/src/lsp/postgres-catalog.ts +234 -0
- package/src/lsp/postgres-template.ts +161 -0
- package/src/lsp/postgres.test.ts +150 -0
- package/src/lsp/postgres.ts +270 -0
- package/src/lsp/refs.ts +53 -0
- package/src/lsp/registry.ts +19 -0
- package/src/lsp/template.ts +166 -0
- package/src/mcp/index.ts +304 -0
- package/src/mcp/mcp.test.ts +184 -0
- package/src/mcp/postgres.ts +125 -0
- package/src/op/activities/clickhouse-apply.e2e.test.ts +150 -0
- package/src/op/activities/clickhouse-apply.test.ts +265 -0
- package/src/op/activities/clickhouse-apply.ts +113 -0
- package/src/op/activities/clickhouse-emulator.test.ts +23 -0
- package/src/op/activities/clickhouse-emulator.ts +37 -0
- package/src/op/activities/clickhouse-rebuild.ts +136 -0
- package/src/op/activities/index.ts +50 -0
- package/src/op/activities/postgres-apply.e2e.test.ts +184 -0
- package/src/op/activities/postgres-apply.test.ts +304 -0
- package/src/op/activities/postgres-apply.ts +170 -0
- package/src/op/activities/postgres-emulator.test.ts +26 -0
- package/src/op/activities/postgres-emulator.ts +44 -0
- package/src/op/activities/postgres-migration.ts +182 -0
- package/src/op/activity-contracts.ts +210 -0
- package/src/package-cli.ts +17 -0
- package/src/plugin.test.ts +74 -0
- package/src/plugin.ts +242 -0
- package/src/postgres/apply/apply.ts +582 -0
- package/src/postgres/apply/statements.test.ts +155 -0
- package/src/postgres/apply/statements.ts +603 -0
- package/src/postgres/catalog-types.ts +59 -0
- package/src/postgres/container.ts +72 -0
- package/src/postgres/entities.test.ts +170 -0
- package/src/postgres/entities.ts +1016 -0
- package/src/postgres/entity-types.ts +18 -0
- package/src/postgres/import/generator.ts +176 -0
- package/src/postgres/import/import.test.ts +71 -0
- package/src/postgres/import/ir.ts +67 -0
- package/src/postgres/import/live-export.ts +53 -0
- package/src/postgres/import/live-warnings.test.ts +45 -0
- package/src/postgres/keywords.ts +40 -0
- package/src/postgres/live/bind.ts +146 -0
- package/src/postgres/live/catalog.ts +581 -0
- package/src/postgres/live/client.ts +84 -0
- package/src/postgres/live/describe-resources.ts +111 -0
- package/src/postgres/live/live.test.ts +198 -0
- package/src/postgres/live/roundtrip.e2e.test.ts +111 -0
- package/src/postgres/migrate/backfill.ts +233 -0
- package/src/postgres/migrate/batches.e2e.test.ts +163 -0
- package/src/postgres/migrate/batches.test.ts +36 -0
- package/src/postgres/migrate/batches.ts +159 -0
- package/src/postgres/migrate/carry.e2e.test.ts +335 -0
- package/src/postgres/migrate/carry.test.ts +103 -0
- package/src/postgres/migrate/carry.ts +653 -0
- package/src/postgres/migrate/handoff.ts +73 -0
- package/src/postgres/migrate/kinds.e2e.test.ts +204 -0
- package/src/postgres/migrate/migrate.e2e.test.ts +362 -0
- package/src/postgres/migrate/migrate.test.ts +322 -0
- package/src/postgres/migrate/names.ts +93 -0
- package/src/postgres/migrate/observe.ts +521 -0
- package/src/postgres/migrate/op.ts +242 -0
- package/src/postgres/migrate/receipts.ts +135 -0
- package/src/postgres/migrate/replication.ts +151 -0
- package/src/postgres/migrate/steps.ts +657 -0
- package/src/postgres/overlays/columns.ts +34 -0
- package/src/postgres/overlays/constraints.ts +56 -0
- package/src/postgres/overlays/indexes.ts +27 -0
- package/src/postgres/overlays/kinds.ts +53 -0
- package/src/postgres/overlays/partitioning.ts +26 -0
- package/src/postgres/overlays/relations.ts +29 -0
- package/src/postgres/overlays/storage.ts +75 -0
- package/src/postgres/overlays/type-ddl.ts +38 -0
- package/src/postgres/overlays/types.ts +56 -0
- package/src/postgres/parser.test.ts +214 -0
- package/src/postgres/parser.ts +1062 -0
- package/src/postgres/plan/commands.ts +124 -0
- package/src/postgres/plan/deep.ts +177 -0
- package/src/postgres/plan/diff.ts +323 -0
- package/src/postgres/plan/disruption.ts +52 -0
- package/src/postgres/plan/normalize.test.ts +148 -0
- package/src/postgres/plan/normalize.ts +542 -0
- package/src/postgres/plan/plan.e2e.test.ts +117 -0
- package/src/postgres/plan/plan.test.ts +244 -0
- package/src/postgres/plan/report.ts +24 -0
- package/src/postgres/plan/rules.ts +276 -0
- package/src/postgres/plan/schema.ts +114 -0
- package/src/postgres/plan/server-normalize.ts +123 -0
- package/src/postgres/providers/aurora.ts +45 -0
- package/src/postgres/providers/azure.ts +54 -0
- package/src/postgres/providers/cloud-sql.ts +42 -0
- package/src/postgres/providers/index.ts +90 -0
- package/src/postgres/providers/neon.ts +45 -0
- package/src/postgres/providers/providers.test.ts +136 -0
- package/src/postgres/providers/rds.ts +48 -0
- package/src/postgres/providers/supabase.ts +46 -0
- package/src/postgres/providers/types.ts +70 -0
- package/src/postgres/testdata/NOTICE +31 -0
- package/src/postgres/testdata/postgres-regress-corpus.json +460 -0
- package/src/postgres/testing/fake-client.ts +42 -0
- package/src/postgres/testing/migration.ts +52 -0
- package/src/postgres/testing/roundtrip-schema.ts +46 -0
- package/src/postgres/testing/server.ts +58 -0
- package/src/postgres/testing/writable-server.ts +188 -0
- package/src/postgres/tokens.ts +46 -0
- package/src/postgres.ts +75 -0
- package/src/serializer.test.ts +128 -0
- package/src/serializer.ts +148 -0
- package/src/skill-defs.test.ts +81 -0
- package/src/skill-defs.ts +102 -0
- package/src/skills/chant-sql-plan.md +123 -0
- package/src/skills/chant-sql-postgres-migration.md +126 -0
- package/src/skills/chant-sql-postgres-plan.md +194 -0
- package/src/skills/chant-sql-postgres.md +165 -0
- package/src/skills/chant-sql-rebuild.md +68 -0
- package/src/skills/chant-sql.md +123 -0
- package/src/spec/catalog.e2e.test.ts +29 -0
- package/src/spec/catalog.test.ts +56 -0
- package/src/spec/catalog.ts +311 -0
- package/src/spec/clickhouse-catalog.snapshot.json +5246 -0
- package/src/spec/fetch.test.ts +77 -0
- package/src/spec/fetch.ts +112 -0
- package/src/spec/pin.ts +47 -0
- package/src/spec/postgres-catalog-14.snapshot.json +3494 -0
- package/src/spec/postgres-catalog-15.snapshot.json +3529 -0
- package/src/spec/postgres-catalog-16.snapshot.json +3597 -0
- package/src/spec/postgres-catalog-17.snapshot.json +3656 -0
- package/src/spec/postgres-catalog-18.snapshot.json +3747 -0
- package/src/spec/postgres-catalog.test.ts +43 -0
- package/src/spec/postgres-catalog.ts +301 -0
- package/src/spec/postgres-fetch.test.ts +75 -0
- package/src/spec/postgres-fetch.ts +112 -0
- package/src/spec/postgres-pin.test.ts +64 -0
- package/src/spec/postgres-pin.ts +101 -0
- package/src/typecheck.test.ts +104 -0
- package/src/validate-cli.ts +6 -0
- package/src/validate.ts +149 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shared core, exercised with a toy dialect so nothing here depends on
|
|
3
|
+
* ClickHouse: whatever a second dialect reuses has to work without it.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, test } from "vitest";
|
|
7
|
+
import type { Declarable } from "@intentius/chant";
|
|
8
|
+
import {
|
|
9
|
+
SqlLiteral,
|
|
10
|
+
SqlObject,
|
|
11
|
+
SqlTemplateError,
|
|
12
|
+
applyOrder,
|
|
13
|
+
changedEntries,
|
|
14
|
+
changesByObject,
|
|
15
|
+
classifiedChange,
|
|
16
|
+
classifierRule,
|
|
17
|
+
classifyDisruptionWith,
|
|
18
|
+
interpolationLine,
|
|
19
|
+
isColumnRefOf,
|
|
20
|
+
isSqlObjectOf,
|
|
21
|
+
lineageJson,
|
|
22
|
+
makeSqlEntity,
|
|
23
|
+
matchByIdentity,
|
|
24
|
+
migrationOpName,
|
|
25
|
+
missingDependencies,
|
|
26
|
+
notAttemptedOutcome,
|
|
27
|
+
previouslyIn,
|
|
28
|
+
readBuildObjects,
|
|
29
|
+
receiptAddress,
|
|
30
|
+
renderChangeSet,
|
|
31
|
+
renderMigrationOps,
|
|
32
|
+
resolveOwnershipMarker,
|
|
33
|
+
spliceText,
|
|
34
|
+
splitTopLevel,
|
|
35
|
+
SqlApplyError,
|
|
36
|
+
templateParts,
|
|
37
|
+
toApplyResult,
|
|
38
|
+
type ChangeClasses,
|
|
39
|
+
type Keyed,
|
|
40
|
+
} from "./index";
|
|
41
|
+
|
|
42
|
+
// ── A toy dialect ────────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
abstract class ToyObject extends SqlObject {
|
|
45
|
+
declare readonly entityType: "Toy::Table";
|
|
46
|
+
}
|
|
47
|
+
const toy = (sqlName: string, columns: string[], dependsOn: unknown[] = []) =>
|
|
48
|
+
makeSqlEntity(ToyObject.prototype as ToyObject, "Toy::Table", sqlName, { name: sqlName }, columns, dependsOn) as ToyObject & {
|
|
49
|
+
columns: Record<string, unknown>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
type ToyClass = "safe" | "locks" | "create" | "drop";
|
|
53
|
+
const CLASSES: ChangeClasses<ToyClass> = {
|
|
54
|
+
order: ["create", "safe", "locks", "drop"],
|
|
55
|
+
label: { create: "create", safe: "safe", locks: "TAKES A LOCK", drop: "drop" },
|
|
56
|
+
disruption: { create: "in-place", safe: "in-place", locks: "replace", drop: "destroy" },
|
|
57
|
+
};
|
|
58
|
+
const RULES = {
|
|
59
|
+
TOY200: classifierRule("TOY200", "create" as ToyClass, "Create", "Nothing existing changes.", "https://example.test/create"),
|
|
60
|
+
TOY201: classifierRule("TOY201", "safe" as ToyClass, "Add a column", "Metadata only.", "https://example.test/add"),
|
|
61
|
+
TOY202: classifierRule("TOY202", "locks" as ToyClass, "Change a type", "Rewrites under a lock.", "https://example.test/type"),
|
|
62
|
+
TOY250: classifierRule("TOY250", "drop" as ToyClass, "Drop", "Not undone.", "https://example.test/drop"),
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
describe("entities", () => {
|
|
66
|
+
test("hide everything but dependsOn, and hand out column references", () => {
|
|
67
|
+
const users = toy("users", ["id", "email"]);
|
|
68
|
+
const orders = toy("orders", ["user_id"], [users]);
|
|
69
|
+
expect(Object.keys(orders)).toEqual(["dependsOn"]);
|
|
70
|
+
expect(orders).toBeInstanceOf(ToyObject);
|
|
71
|
+
expect(orders.lexicon).toBe("sql");
|
|
72
|
+
expect(isSqlObjectOf(orders, "Toy::")).toBe(true);
|
|
73
|
+
expect(isSqlObjectOf(orders, "ClickHouse::")).toBe(false);
|
|
74
|
+
expect(isColumnRefOf(users.columns.id, (p) => isSqlObjectOf(p, "Toy::"))).toBe(true);
|
|
75
|
+
expect(isColumnRefOf("id", (p) => isSqlObjectOf(p, "Toy::"))).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("order by references, ties by export name, and refuse a cycle", () => {
|
|
79
|
+
const users = toy("users", ["id"]);
|
|
80
|
+
const orders = toy("orders", ["user_id"], [users.columns.id]);
|
|
81
|
+
const names = new Map<Declarable, string>([
|
|
82
|
+
[users, "users"],
|
|
83
|
+
[orders, "orders"],
|
|
84
|
+
]);
|
|
85
|
+
expect(applyOrder(new Map([["orders", orders], ["users", users]]), names)).toEqual(["users", "orders"]);
|
|
86
|
+
expect(lineageJson([{ output: "id", expr: "id", from: [users.columns.id as never] }], names)).toEqual([{ output: "id", expr: "id", from: ["users.id"] }]);
|
|
87
|
+
const a = { dependsOn: [] as unknown[] };
|
|
88
|
+
const b = { dependsOn: [a] };
|
|
89
|
+
a.dependsOn.push(b);
|
|
90
|
+
expect(() => applyOrder(new Map([["a", a], ["b", b]]), new Map<Declarable, string>([[a as never, "a"], [b as never, "b"]]))).toThrow(/reference cycle.*a -> b -> a/);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe("templates", () => {
|
|
95
|
+
test("splice values, and undo the two forced escapes", () => {
|
|
96
|
+
expect(spliceText("x + 1")).toBe("x + 1");
|
|
97
|
+
expect(spliceText(2n)).toBe("2");
|
|
98
|
+
expect(spliceText(null)).toBe("NULL");
|
|
99
|
+
expect(spliceText(new SqlLiteral("'a'"))).toBe("'a'");
|
|
100
|
+
expect(spliceText(undefined)).toMatchObject({ error: expect.stringMatching(/\.columns/) });
|
|
101
|
+
expect(spliceText({})).toMatchObject({ error: expect.stringMatching(/an object/) });
|
|
102
|
+
expect(templateParts(Object.assign(["a \\` b \\${c}"], { raw: ["a \\` b \\${c}"] }) as unknown as TemplateStringsArray)).toEqual(["a ` b ${c}"]);
|
|
103
|
+
expect(interpolationLine(["a\nb", "c"], 0)).toBe(2);
|
|
104
|
+
expect(new SqlTemplateError("table", "bad", 0, 0).message).toBe("table`...`: bad");
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe("identity, diff and the classifier", () => {
|
|
109
|
+
type O = { name: string; schema: string; type: string; previously?: string };
|
|
110
|
+
const keyed = (key: string, o: O): Keyed<O> => ({ key, canonical: o });
|
|
111
|
+
const rules = {
|
|
112
|
+
qualified: (o: O) => `${o.schema}.${o.name}`,
|
|
113
|
+
previously: (o: O) => o.previously,
|
|
114
|
+
previousNames: (o: O, prev: string) => [prev, `${o.schema}.${prev}`],
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
test("match by key, then by a rename hint, and list the rest as created and dropped", () => {
|
|
118
|
+
const before = [keyed("public.users", { name: "users", schema: "public", type: "int" }), keyed("public.old", { name: "old", schema: "public", type: "int" })];
|
|
119
|
+
const after = [
|
|
120
|
+
keyed("public.users", { name: "users", schema: "public", type: "bigint" }),
|
|
121
|
+
keyed("public.accounts", { name: "accounts", schema: "public", type: "int", previously: "old" }),
|
|
122
|
+
keyed("public.fresh", { name: "fresh", schema: "public", type: "int" }),
|
|
123
|
+
];
|
|
124
|
+
expect(matchByIdentity(before, after, rules).map((m) => [m.kind, m.kind === "dropped" ? m.before.key : m.after.key])).toEqual([
|
|
125
|
+
["matched", "public.users"],
|
|
126
|
+
["matched", "public.accounts"],
|
|
127
|
+
["created", "public.fresh"],
|
|
128
|
+
]);
|
|
129
|
+
expect(matchByIdentity(before, after.slice(0, 1), rules).map((m) => m.kind)).toEqual(["matched", "dropped"]);
|
|
130
|
+
expect(changedEntries({ a: "1", b: "2" }, { b: "3", c: "4" })).toEqual(["a", "b", "c"]);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test("class each change from its rule, report it, and map it onto classifyDisruption", () => {
|
|
134
|
+
const changes = [
|
|
135
|
+
classifiedChange(RULES, "users", "columns.id.type", "TOY202", "int", "bigint"),
|
|
136
|
+
classifiedChange(RULES, "users", "columns.email", "TOY201", undefined, "email text"),
|
|
137
|
+
];
|
|
138
|
+
expect(changes[0]).toEqual({ object: "users", field: "columns.id.type", before: "int", after: "bigint", rule: "TOY202", class: "locks" });
|
|
139
|
+
expect(changesByObject(changes).get("users")).toHaveLength(2);
|
|
140
|
+
const text = renderChangeSet({ changes, hints: ["a hint"] }, { title: "base -> head", rules: RULES, classes: CLASSES, trailer: ["", "Refused."] });
|
|
141
|
+
expect(text.split("\n")).toEqual([
|
|
142
|
+
"base -> head",
|
|
143
|
+
"",
|
|
144
|
+
"users",
|
|
145
|
+
" [TAKES A LOCK] columns.id.type: int -> bigint",
|
|
146
|
+
" TOY202 Change a type. Rewrites under a lock. https://example.test/type",
|
|
147
|
+
" [safe] columns.email: email text",
|
|
148
|
+
" TOY201 Add a column. Metadata only. https://example.test/add",
|
|
149
|
+
"",
|
|
150
|
+
"1 safe, 1 TAKES A LOCK",
|
|
151
|
+
"hint: a hint",
|
|
152
|
+
"",
|
|
153
|
+
"Refused.",
|
|
154
|
+
]);
|
|
155
|
+
expect(renderChangeSet({ changes: [], hints: [] }, { rules: RULES, classes: CLASSES, trailer: ["never"] })).toBe("No changes.");
|
|
156
|
+
|
|
157
|
+
const ruleFor = (path: string) => (path.startsWith("type") ? "TOY202" : path.startsWith("add") ? "TOY201" : path === "?" ? "ambiguous" : undefined) as "TOY201" | "TOY202" | "ambiguous" | undefined;
|
|
158
|
+
const classify = (paths: string[], type = "Toy::Table") =>
|
|
159
|
+
classifyDisruptionWith(
|
|
160
|
+
{ typePrefix: "Toy::", rules: RULES, classes: CLASSES, ruleFor, ambiguousDetail: "needs the plan" },
|
|
161
|
+
{ environment: "e", changes: [{ name: "t", type, deltas: paths.map((path) => ({ path })) } as never] },
|
|
162
|
+
);
|
|
163
|
+
expect(classify(["add", "type"]).t).toEqual({ disruption: "replace", because: ["type"], detail: "TOY201 Add a column; TOY202 Change a type" });
|
|
164
|
+
expect(classify(["add", "?"]).t).toEqual({ disruption: "unknown", because: ["add", "?"], detail: "needs the plan" });
|
|
165
|
+
expect(classify(["add"], "Other::Thing")).toEqual({});
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe("normalization helpers", () => {
|
|
170
|
+
test("read the rename hint, and split on top-level commas", () => {
|
|
171
|
+
expect(previouslyIn(["-- previously: old_name"])).toBe("old_name");
|
|
172
|
+
expect(previouslyIn(['-- previously: "Old"'])).toBe("Old");
|
|
173
|
+
expect(previouslyIn(["-- a comment"])).toBeUndefined();
|
|
174
|
+
expect(splitTopLevel("a , f ( b , c ) , [ d , e ]")).toEqual(["a", "f ( b , c )", "[ d , e ]"]);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
describe("apply plumbing", () => {
|
|
179
|
+
const doc = (dialect: string, objects: unknown[]) => JSON.stringify({ sql: { dialect, objects } });
|
|
180
|
+
|
|
181
|
+
test("reads a build's objects for one dialect, nested or not", () => {
|
|
182
|
+
const objects = readBuildObjects(doc("toy", [{ export: "t", type: "Toy::Table", ddl: "CREATE TABLE t ()", dependsOn: ["s", "s.id", 3] }]), "toy", (o) => o);
|
|
183
|
+
expect(objects).toEqual([{ export: "t", type: "Toy::Table", ddl: "CREATE TABLE t ()", dependsOn: ["s"] }]);
|
|
184
|
+
expect(() => readBuildObjects(doc("other", []), "toy", (o) => o)).toThrow('expected { dialect: "toy", objects: [...] }');
|
|
185
|
+
expect(() => readBuildObjects(doc("toy", [{ export: "t" }]), "toy", (o) => o)).toThrow("objects[0] has no export, type or ddl");
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test("keeps the tri-state, projects it onto the envelope, and names the dialect in its error", () => {
|
|
189
|
+
const outcome = notAttemptedOutcome([{ kind: "Toy::Table", name: "t" }], "no-binding", "nothing bound");
|
|
190
|
+
expect(toApplyResult(outcome).notAttempted).toEqual([{ kind: "Toy::Table", name: "t", reason: "no-binding", detail: "nothing bound" }]);
|
|
191
|
+
const failed = { ...outcome, target: "toy://x", notAttempted: [], failed: [{ kind: "Toy::Table", name: "t", error: "refused", statements: [] }] };
|
|
192
|
+
const err = new SqlApplyError("Toy", failed);
|
|
193
|
+
expect(err.message).toBe("Toy apply to toy://x: 1 object(s) failed (Toy::Table/t: refused); 0 applied, 0 pruned, 0 not attempted before and after");
|
|
194
|
+
expect(err.outcome).toBe(failed);
|
|
195
|
+
expect(missingDependencies("v", ["t", "v", "external"], new Set(["t", "v"]), new Set())).toEqual(["t"]);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test("resolves the ownership marker from args, then config", () => {
|
|
199
|
+
expect(resolveOwnershipMarker({ stack: "a" }, { ownership: { stack: "b", env: "prod" } }, "toy apply")).toEqual({ stack: "a", env: "prod" });
|
|
200
|
+
expect(resolveOwnershipMarker({}, { ownership: { stack: "b", enabled: false } }, "toy apply")).toBeUndefined();
|
|
201
|
+
expect(() => resolveOwnershipMarker({}, { ownership: { stack: "b", env: { param: "env" } } as never }, "toy apply")).toThrow(/^toy apply: ownership.env/);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
describe("receipts and the migration hand-off", () => {
|
|
206
|
+
test("address receipts by stack, env and effect", () => {
|
|
207
|
+
expect(receiptAddress({ stack: "shop", env: "prod" }, "migrate/users/1")).toBe("shop/prod/migrate/users/1");
|
|
208
|
+
expect(receiptAddress({}, "e")).toBe("-/-/e");
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("name and render the Op to run instead", () => {
|
|
212
|
+
expect(migrationOpName("migrate", "public.Users")).toBe("migrate-public-users");
|
|
213
|
+
const op = { table: "public.users", name: "migrate-public-users", env: "prod", declaration: "export const { op } = ToyOp({});" };
|
|
214
|
+
expect(renderMigrationOps([op], { what: "the toy Op", exportName: "ToyOp", importPath: "toy" })).toEqual([
|
|
215
|
+
"",
|
|
216
|
+
'Run it as the toy Op, declared in an *.op.ts file (import { ToyOp } from "toy"), then `chant run <name>` until it is done:',
|
|
217
|
+
" export const { op } = ToyOp({});",
|
|
218
|
+
]);
|
|
219
|
+
expect(renderMigrationOps([], { what: "x", exportName: "X", importPath: "x" })).toEqual([]);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
describe("tokens, cursor and template finding", () => {
|
|
224
|
+
test("a dialect's lexical rules decide quotes and punctuation", async () => {
|
|
225
|
+
const { tokenizeText } = await import("./tokens");
|
|
226
|
+
const rules = { identQuotes: '"', backslashEscapes: false, punct: "(),;.", opChars: /[=<>]/ };
|
|
227
|
+
expect(tokenizeText('"a""b" = \'x\\\'', 0, rules).map((t) => [t.kind, t.text])).toEqual([
|
|
228
|
+
["qident", '"a""b"'],
|
|
229
|
+
["ws", " "],
|
|
230
|
+
["op", "="],
|
|
231
|
+
["ws", " "],
|
|
232
|
+
["string", "'x\\'"],
|
|
233
|
+
]);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test("a tag is a dialect's by the module it is imported from", async () => {
|
|
237
|
+
const ts = await import("typescript");
|
|
238
|
+
const { findSqlTemplates } = await import("./find-templates");
|
|
239
|
+
const source = ts.createSourceFile(
|
|
240
|
+
"f.ts",
|
|
241
|
+
'import { table } from "toy-a";\nimport { table as t2 } from "toy-b";\nexport const x = table`CREATE TABLE x (a int)`;\nexport const y = t2`CREATE TABLE y (${x}) b`;',
|
|
242
|
+
ts.ScriptTarget.Latest,
|
|
243
|
+
true,
|
|
244
|
+
);
|
|
245
|
+
const found = findSqlTemplates(source, [
|
|
246
|
+
{ dialect: "a", modules: ["toy-a"], tags: ["table"] },
|
|
247
|
+
{ dialect: "b", modules: ["toy-b"], tags: ["table"] },
|
|
248
|
+
]);
|
|
249
|
+
expect(found.map((f) => [f.dialect, f.tag, f.parts])).toEqual([
|
|
250
|
+
["a", "table", ["CREATE TABLE x (a int)"]],
|
|
251
|
+
["b", "table", ["CREATE TABLE y (", ") b"]],
|
|
252
|
+
]);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dialect-neutral half of a hand-written CREATE parser (chant #3196,
|
|
3
|
+
* #3278): a cursor over a statement's significant tokens, keyword and
|
|
4
|
+
* punctuation tests, spans, and expressions kept as balanced token spans.
|
|
5
|
+
*
|
|
6
|
+
* Statement structure is a dialect's to parse; expressions are not parsed. An
|
|
7
|
+
* expression (a default, a key, a view's SELECT) is a span of tokens: its
|
|
8
|
+
* source text, verbatim, and the interpolations inside it. A dialect parser
|
|
9
|
+
* extends {@link SqlCursor} with its statements, and says where an expression
|
|
10
|
+
* stops ({@link SqlCursor.stopsAt}) and how a token nests
|
|
11
|
+
* ({@link SqlCursor.depthChange}).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { isTrivia, SqlSyntaxError, type Token } from "./tokens";
|
|
15
|
+
|
|
16
|
+
/** A run of tokens [from, to) in the token list, trivia included. */
|
|
17
|
+
export interface Span {
|
|
18
|
+
from: number;
|
|
19
|
+
to: number;
|
|
20
|
+
/** Value indexes of the interpolations inside the span. */
|
|
21
|
+
refs: number[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Whether `t` is a bare word, any of `words`, case-insensitively. */
|
|
25
|
+
export const kw = (t: Token | undefined, ...words: string[]): boolean =>
|
|
26
|
+
t !== undefined && t.kind === "ident" && words.includes(t.text.toUpperCase());
|
|
27
|
+
|
|
28
|
+
/** `name` with its identifier quotes taken off and doubled quotes undone; `quotes` are the dialect's identifier quotes. */
|
|
29
|
+
export const unquoteWith = (text: string, quotes: string): string => {
|
|
30
|
+
if (text.length < 2 || !quotes.includes(text[0]!) || !quotes.includes(text[text.length - 1]!)) return text;
|
|
31
|
+
let inner = text.slice(1, -1);
|
|
32
|
+
for (const q of quotes) inner = inner.split(q + q).join(q);
|
|
33
|
+
return inner;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export class SqlCursor {
|
|
37
|
+
/** Indexes of the significant (non-trivia) tokens. */
|
|
38
|
+
protected readonly sig: number[];
|
|
39
|
+
protected p = 0;
|
|
40
|
+
|
|
41
|
+
constructor(protected readonly tokens: Token[]) {
|
|
42
|
+
this.sig = tokens.map((t, i) => (isTrivia(t) ? -1 : i)).filter((i) => i >= 0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
protected peek(n = 0): Token | undefined {
|
|
46
|
+
const idx = this.sig[this.p + n];
|
|
47
|
+
return idx === undefined ? undefined : this.tokens[idx];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Token-list index of the significant token `n` ahead. */
|
|
51
|
+
protected idx(n = 0): number {
|
|
52
|
+
return this.sig[this.p + n] ?? this.tokens.length;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
protected next(): Token {
|
|
56
|
+
const t = this.peek();
|
|
57
|
+
if (!t) this.fail("unexpected end of statement");
|
|
58
|
+
this.p++;
|
|
59
|
+
return t;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fail(message: string, t: Token | undefined = this.peek()): never {
|
|
63
|
+
const at = t ?? this.lastToken();
|
|
64
|
+
const shown = t ? ` at '${t.kind === "ref" ? "${...}" : t.text}'` : "";
|
|
65
|
+
throw new SqlSyntaxError(`${message}${shown}`, at?.part ?? 0, t ? at!.start : (at?.end ?? 0), at);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
protected lastToken(): Token | undefined {
|
|
69
|
+
const last = this.sig[this.sig.length - 1];
|
|
70
|
+
return last === undefined ? undefined : this.tokens[last];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected accept(...words: string[]): boolean {
|
|
74
|
+
if (kw(this.peek(), ...words)) {
|
|
75
|
+
this.p++;
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
protected expect(...words: string[]): void {
|
|
82
|
+
if (!this.accept(...words)) this.fail(`expected ${words.join(" or ")}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Whether the next significant tokens are the bare words `words`, in order. */
|
|
86
|
+
protected is(...words: string[]): boolean {
|
|
87
|
+
return words.every((w, n) => kw(this.peek(n), w));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Accept a sequence of bare words, all of them or none. */
|
|
91
|
+
protected acceptSeq(...words: string[]): boolean {
|
|
92
|
+
if (!this.is(...words)) return false;
|
|
93
|
+
this.p += words.length;
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
protected isPunct(c: string, n = 0): boolean {
|
|
98
|
+
const t = this.peek(n);
|
|
99
|
+
return t !== undefined && t.kind === "punct" && t.text === c;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected acceptPunct(c: string): boolean {
|
|
103
|
+
if (this.isPunct(c)) {
|
|
104
|
+
this.p++;
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
protected expectPunct(c: string): void {
|
|
111
|
+
if (!this.acceptPunct(c)) this.fail(`expected '${c}'`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
protected atEnd(): boolean {
|
|
115
|
+
return this.peek() === undefined || this.isPunct(";");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
protected span(from: number, refs: number[]): Span {
|
|
119
|
+
return { from, to: this.idx(-1) + 1, refs };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Whether the expression being read stops at the current token, a top-level
|
|
124
|
+
* bare word: by default when it is one of `stop`. A dialect overrides this
|
|
125
|
+
* for its multi-word stops (ClickHouse stops at `ORDER` only before `BY`).
|
|
126
|
+
*/
|
|
127
|
+
protected stopsAt(stop: readonly string[]): boolean {
|
|
128
|
+
const t = this.peek();
|
|
129
|
+
return t !== undefined && t.kind === "ident" && stop.includes(t.text.toUpperCase());
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** How `t` changes the nesting depth of an expression: `(` opens and `)` closes. */
|
|
133
|
+
protected depthChange(t: Token): number {
|
|
134
|
+
if (t.kind === "punct" && t.text === "(") return 1;
|
|
135
|
+
if (t.kind === "punct" && t.text === ")") return -1;
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* An expression as a token span: everything up to a top-level `,` (unless
|
|
141
|
+
* `stopAtComma` is false), `)` or `;`, or a top-level stop word. Nesting is
|
|
142
|
+
* balanced, not parsed.
|
|
143
|
+
*/
|
|
144
|
+
protected expr(stop: readonly string[] = [], stopAtComma = true): Span {
|
|
145
|
+
const from = this.idx();
|
|
146
|
+
const refs: number[] = [];
|
|
147
|
+
let depth = 0;
|
|
148
|
+
const startP = this.p;
|
|
149
|
+
for (;;) {
|
|
150
|
+
const t = this.peek();
|
|
151
|
+
if (t === undefined) break;
|
|
152
|
+
if (depth === 0) {
|
|
153
|
+
if (t.kind === "punct" && (t.text === ")" || t.text === ";" || (stopAtComma && t.text === ","))) break;
|
|
154
|
+
if (this.stopsAt(stop)) break;
|
|
155
|
+
}
|
|
156
|
+
depth += this.depthChange(t);
|
|
157
|
+
if (t.kind === "ref") refs.push(t.part);
|
|
158
|
+
this.p++;
|
|
159
|
+
}
|
|
160
|
+
if (this.p === startP) this.fail("expected an expression");
|
|
161
|
+
return this.span(from, refs);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** `( ... )` balanced: the span between the parentheses. */
|
|
165
|
+
protected parenthesized(): Span {
|
|
166
|
+
this.expectPunct("(");
|
|
167
|
+
if (this.isPunct(")")) {
|
|
168
|
+
const at = this.idx();
|
|
169
|
+
this.p++;
|
|
170
|
+
return { from: at, to: at, refs: [] };
|
|
171
|
+
}
|
|
172
|
+
const inner = this.exprList();
|
|
173
|
+
this.expectPunct(")");
|
|
174
|
+
return inner;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** A comma-separated expression list as one span. */
|
|
178
|
+
protected exprList(stop: readonly string[] = []): Span {
|
|
179
|
+
const first = this.expr(stop);
|
|
180
|
+
let last = first;
|
|
181
|
+
const refs = [...first.refs];
|
|
182
|
+
while (this.isPunct(",")) {
|
|
183
|
+
this.p++;
|
|
184
|
+
last = this.expr(stop);
|
|
185
|
+
refs.push(...last.refs);
|
|
186
|
+
}
|
|
187
|
+
return { from: first.from, to: last.to, refs };
|
|
188
|
+
}
|
|
189
|
+
}
|
package/src/core/diff.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity and renames between two schemas, the same in every dialect
|
|
3
|
+
* (#3047 question 3).
|
|
4
|
+
*
|
|
5
|
+
* An object is identified by its key: its export name between two revisions
|
|
6
|
+
* of the declarations, its qualified name against a live server, which has no
|
|
7
|
+
* export names. An `after` object whose key is new but whose `previously` hint
|
|
8
|
+
* (`-- previously: <old name>`) names a `before` object with no `after`
|
|
9
|
+
* counterpart is that object, renamed. What changed inside a matched pair,
|
|
10
|
+
* and how each change is classed, is the dialect's.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** One side of a comparison: an object's identity and its canonical definition. */
|
|
14
|
+
export interface Keyed<O> {
|
|
15
|
+
/** The object's identity in the comparison: an export name, or a qualified name against live. */
|
|
16
|
+
key: string;
|
|
17
|
+
canonical: O;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type IdentityMatch<O> =
|
|
21
|
+
| { kind: "created"; after: Keyed<O> }
|
|
22
|
+
| { kind: "matched"; before: Keyed<O>; after: Keyed<O> }
|
|
23
|
+
| { kind: "dropped"; before: Keyed<O> };
|
|
24
|
+
|
|
25
|
+
export interface IdentityRules<O> {
|
|
26
|
+
/** The object's qualified name, which a `previously` hint may name. */
|
|
27
|
+
qualified(o: O): string;
|
|
28
|
+
/** The `-- previously: <old name>` hint on the object, if any. */
|
|
29
|
+
previously(o: O): string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* The qualified names a hint may mean, tried in order after the hint as a
|
|
32
|
+
* key: the hint itself, and for a dialect with schemas or databases the hint
|
|
33
|
+
* qualified with the object's own.
|
|
34
|
+
*/
|
|
35
|
+
previousNames(o: O, previously: string): readonly string[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Match `after` to `before` by key, then by rename hint. Returns every `after`
|
|
40
|
+
* object in order, created or matched, then every `before` object no `after`
|
|
41
|
+
* object matched, dropped.
|
|
42
|
+
*/
|
|
43
|
+
export function matchByIdentity<O>(before: readonly Keyed<O>[], after: readonly Keyed<O>[], rules: IdentityRules<O>): IdentityMatch<O>[] {
|
|
44
|
+
const out: IdentityMatch<O>[] = [];
|
|
45
|
+
const byKey = new Map(before.map((o) => [o.key, o]));
|
|
46
|
+
const byQualified = new Map(before.map((o) => [rules.qualified(o.canonical), o]));
|
|
47
|
+
const afterKeys = new Set(after.map((o) => o.key));
|
|
48
|
+
const matched = new Set<string>();
|
|
49
|
+
|
|
50
|
+
for (const a of after) {
|
|
51
|
+
let b = byKey.get(a.key);
|
|
52
|
+
const prev = rules.previously(a.canonical);
|
|
53
|
+
if (!b && prev) {
|
|
54
|
+
let candidate = byKey.get(prev);
|
|
55
|
+
for (const name of rules.previousNames(a.canonical, prev)) candidate ??= byQualified.get(name);
|
|
56
|
+
if (candidate && !afterKeys.has(candidate.key)) b = candidate;
|
|
57
|
+
}
|
|
58
|
+
if (!b) {
|
|
59
|
+
out.push({ kind: "created", after: a });
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
matched.add(b.key);
|
|
63
|
+
out.push({ kind: "matched", before: b, after: a });
|
|
64
|
+
}
|
|
65
|
+
for (const b of before) if (!matched.has(b.key)) out.push({ kind: "dropped", before: b });
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** The names whose values differ between two records, sorted. */
|
|
70
|
+
export function changedEntries(before: Readonly<Record<string, string>>, after: Readonly<Record<string, string>>): string[] {
|
|
71
|
+
return [...new Set([...Object.keys(before), ...Object.keys(after)])].sort().filter((name) => before[name] !== after[name]);
|
|
72
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The entity base every dialect's objects share: the Declarable fields core
|
|
3
|
+
* reads, the hidden-property construction that keeps them out of a build's
|
|
4
|
+
* props, and the column references (`${t.columns.x}`) a relation hands out.
|
|
5
|
+
*
|
|
6
|
+
* A dialect subclasses {@link SqlObject} with its own entity types
|
|
7
|
+
* (`ClickHouse::Table`), builds its entities with {@link makeSqlEntity} on its
|
|
8
|
+
* subclass's prototype, and recognizes its own objects by their type prefix.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { DECLARABLE_MARKER, type Declarable } from "@intentius/chant/declarable";
|
|
12
|
+
import { AttrRef } from "@intentius/chant/attrref";
|
|
13
|
+
|
|
14
|
+
/** The lexicon every dialect's entities belong to. */
|
|
15
|
+
export const SQL_LEXICON = "sql";
|
|
16
|
+
|
|
17
|
+
/** The members a schema object has besides its props, in every dialect. */
|
|
18
|
+
export abstract class SqlObject implements Declarable {
|
|
19
|
+
declare readonly [DECLARABLE_MARKER]: true;
|
|
20
|
+
declare readonly lexicon: "sql";
|
|
21
|
+
declare readonly entityType: string;
|
|
22
|
+
declare readonly kind: "resource";
|
|
23
|
+
/** The name the object is referred to by in SQL, qualified as the dialect writes it. */
|
|
24
|
+
declare readonly sqlName: string;
|
|
25
|
+
/** The parsed definition; each entity kind narrows it. */
|
|
26
|
+
declare readonly props: object;
|
|
27
|
+
/**
|
|
28
|
+
* Everything the DDL references, enumerable so core's dependency graph and
|
|
29
|
+
* `chant graph` see the edges.
|
|
30
|
+
*/
|
|
31
|
+
declare readonly dependsOn: readonly unknown[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const hidden = (target: object, key: string | symbol, value: unknown) =>
|
|
35
|
+
Object.defineProperty(target, key, { value, enumerable: false, writable: false, configurable: false });
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* One entity on `prototype` (a dialect's {@link SqlObject} subclass). Every
|
|
39
|
+
* field but `dependsOn` is hidden, so a build's props are the parsed
|
|
40
|
+
* definition alone. With `columnNames`, the entity gets a frozen `columns`
|
|
41
|
+
* record holding one {@link AttrRef} per column.
|
|
42
|
+
*/
|
|
43
|
+
export function makeSqlEntity<T extends SqlObject>(
|
|
44
|
+
prototype: T,
|
|
45
|
+
entityType: string,
|
|
46
|
+
sqlName: string,
|
|
47
|
+
props: object,
|
|
48
|
+
columnNames: readonly string[] | undefined,
|
|
49
|
+
dependsOn: unknown[],
|
|
50
|
+
): T {
|
|
51
|
+
const entity = Object.create(prototype) as T;
|
|
52
|
+
hidden(entity, DECLARABLE_MARKER, true);
|
|
53
|
+
hidden(entity, "lexicon", SQL_LEXICON);
|
|
54
|
+
hidden(entity, "entityType", entityType);
|
|
55
|
+
hidden(entity, "kind", "resource");
|
|
56
|
+
hidden(entity, "props", props);
|
|
57
|
+
hidden(entity, "sqlName", sqlName);
|
|
58
|
+
if (columnNames) {
|
|
59
|
+
const columns: Record<string, AttrRef> = {};
|
|
60
|
+
for (const name of columnNames) columns[name] = new AttrRef(entity, name);
|
|
61
|
+
hidden(entity, "columns", Object.freeze(columns));
|
|
62
|
+
}
|
|
63
|
+
Object.defineProperty(entity, "dependsOn", { value: dependsOn, enumerable: true });
|
|
64
|
+
return entity;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Whether `value` is a sql lexicon entity whose type starts with `typePrefix` (`ClickHouse::`). */
|
|
68
|
+
export function isSqlObjectOf(value: unknown, typePrefix: string): value is SqlObject {
|
|
69
|
+
return (
|
|
70
|
+
typeof value === "object" &&
|
|
71
|
+
value !== null &&
|
|
72
|
+
(value as Declarable).lexicon === SQL_LEXICON &&
|
|
73
|
+
typeof (value as SqlObject).sqlName === "string" &&
|
|
74
|
+
typeof (value as Declarable).entityType === "string" &&
|
|
75
|
+
(value as Declarable).entityType.startsWith(typePrefix)
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** A column reference: an AttrRef whose parent `isOwner` accepts. */
|
|
80
|
+
export function isColumnRefOf(value: unknown, isOwner: (parent: unknown) => boolean): value is AttrRef {
|
|
81
|
+
if (typeof value !== "object" || value === null) return false;
|
|
82
|
+
const v = value as Partial<AttrRef>;
|
|
83
|
+
if (typeof v.attribute !== "string" || typeof v.parent?.deref !== "function") return false;
|
|
84
|
+
return isOwner(v.parent.deref());
|
|
85
|
+
}
|