@intentius/chant-lexicon-sql 0.124.45 → 0.124.48
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/dist/change-set.d.ts +1 -1
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +2 -1
- package/dist/clickhouse/apply/statements.d.ts +9 -0
- package/dist/clickhouse/apply/statements.d.ts.map +1 -1
- package/dist/clickhouse/apply/statements.js +24 -0
- package/dist/clickhouse/import/live-export.d.ts +7 -3
- package/dist/clickhouse/import/live-export.d.ts.map +1 -1
- package/dist/clickhouse/import/live-export.js +21 -5
- package/dist/clickhouse/live/named-collections.d.ts +27 -0
- package/dist/clickhouse/live/named-collections.d.ts.map +1 -0
- package/dist/clickhouse/live/named-collections.js +53 -0
- package/dist/clickhouse/live/undeclarable.d.ts +15 -3
- package/dist/clickhouse/live/undeclarable.d.ts.map +1 -1
- package/dist/clickhouse/live/undeclarable.js +18 -4
- package/dist/clickhouse/named-collections.d.ts +83 -0
- package/dist/clickhouse/named-collections.d.ts.map +1 -0
- package/dist/clickhouse/named-collections.js +203 -0
- package/dist/clickhouse/parser.d.ts.map +1 -1
- package/dist/clickhouse/parser.js +1 -1
- package/dist/clickhouse/plan/commands.d.ts +2 -1
- package/dist/clickhouse/plan/commands.d.ts.map +1 -1
- package/dist/clickhouse/plan/commands.js +17 -2
- package/dist/clickhouse/plan/diff.d.ts +15 -0
- package/dist/clickhouse/plan/diff.d.ts.map +1 -1
- package/dist/clickhouse/plan/diff.js +43 -1
- package/dist/clickhouse/plan/disruption.d.ts.map +1 -1
- package/dist/clickhouse/plan/disruption.js +5 -0
- package/dist/clickhouse/plan/rebuild-handoff.d.ts.map +1 -1
- package/dist/clickhouse/plan/rebuild-handoff.js +4 -0
- package/dist/clickhouse/plan/report.d.ts.map +1 -1
- package/dist/clickhouse/plan/report.js +6 -1
- package/dist/clickhouse/plan/rules.d.ts +5 -1
- package/dist/clickhouse/plan/rules.d.ts.map +1 -1
- package/dist/clickhouse/plan/rules.js +7 -3
- package/dist/clickhouse/plan/stream.d.ts +40 -0
- package/dist/clickhouse/plan/stream.d.ts.map +1 -0
- package/dist/clickhouse/plan/stream.js +107 -0
- package/dist/clickhouse/rebuild/observe.d.ts +3 -1
- package/dist/clickhouse/rebuild/observe.d.ts.map +1 -1
- package/dist/clickhouse/rebuild/observe.js +14 -1
- package/dist/clickhouse/review-catalog.d.ts +213 -0
- package/dist/clickhouse/review-catalog.d.ts.map +1 -0
- package/dist/clickhouse/review-catalog.js +330 -0
- package/dist/codegen/classifier-page.d.ts.map +1 -1
- package/dist/codegen/classifier-page.js +21 -4
- package/dist/codegen/clickhouse-module.d.ts.map +1 -1
- package/dist/codegen/clickhouse-module.js +3 -0
- package/dist/codegen/coverage-page.d.ts.map +1 -1
- package/dist/codegen/coverage-page.js +5 -3
- package/dist/codegen/docs.js +1 -1
- package/dist/codegen/postgres-classifier-page.js +1 -1
- package/dist/codegen/registry.d.ts.map +1 -1
- package/dist/codegen/registry.js +5 -0
- package/dist/composites/catalog.d.ts.map +1 -1
- package/dist/composites/catalog.js +100 -0
- package/dist/composites/clickhouse.d.ts +2 -0
- package/dist/composites/clickhouse.d.ts.map +1 -1
- package/dist/composites/clickhouse.js +2 -0
- package/dist/composites/otel-tables.d.ts +100 -0
- package/dist/composites/otel-tables.d.ts.map +1 -0
- package/dist/composites/otel-tables.js +282 -0
- package/dist/composites/stream-ingest.d.ts +63 -0
- package/dist/composites/stream-ingest.d.ts.map +1 -0
- package/dist/composites/stream-ingest.js +39 -0
- package/dist/coverage/clickhouse.json +1 -1
- package/dist/coverage/postgres.json +7 -7
- package/dist/coverage.d.ts +16 -6
- package/dist/coverage.d.ts.map +1 -1
- package/dist/coverage.js +10 -5
- package/dist/drizzle-command.d.ts +17 -0
- package/dist/drizzle-command.d.ts.map +1 -0
- package/dist/drizzle-command.js +91 -0
- package/dist/drizzle.d.ts +70 -0
- package/dist/drizzle.d.ts.map +1 -0
- package/dist/drizzle.js +684 -0
- package/dist/files/clickhouse.d.ts.map +1 -1
- package/dist/files/clickhouse.js +8 -1
- package/dist/files/common.d.ts +13 -0
- package/dist/files/common.d.ts.map +1 -1
- package/dist/files/common.js +5 -0
- package/dist/files/postgres.js +12 -2
- package/dist/generated/clickhouse.d.ts +2 -0
- package/dist/generated/clickhouse.d.ts.map +1 -1
- package/dist/generated/clickhouse.js +2 -0
- package/dist/import-parser.d.ts +21 -1
- package/dist/import-parser.d.ts.map +1 -1
- package/dist/import-parser.js +79 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/integrity.json +6 -5
- package/dist/lint/post-synth/audit-entries.d.ts.map +1 -1
- package/dist/lint/post-synth/audit-entries.js +1 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/post-synth/index.js +2 -0
- package/dist/lint/post-synth/sqlch128.d.ts +18 -0
- package/dist/lint/post-synth/sqlch128.d.ts.map +1 -0
- package/dist/lint/post-synth/sqlch128.js +222 -0
- package/dist/lint/rules/postgres-templates.js +2 -2
- package/dist/lsp/postgres-template.d.ts.map +1 -1
- package/dist/lsp/postgres-template.js +11 -0
- package/dist/manifest.json +1 -1
- package/dist/mcp/postgres.js +1 -1
- package/dist/meta.json +25 -0
- package/dist/migrate/from-postgres/detect.d.ts +4 -0
- package/dist/migrate/from-postgres/detect.d.ts.map +1 -0
- package/dist/migrate/from-postgres/detect.js +7 -0
- package/dist/migrate/from-postgres/emit.d.ts +26 -0
- package/dist/migrate/from-postgres/emit.d.ts.map +1 -0
- package/dist/migrate/from-postgres/emit.js +86 -0
- package/dist/migrate/from-postgres/index.d.ts +51 -0
- package/dist/migrate/from-postgres/index.d.ts.map +1 -0
- package/dist/migrate/from-postgres/index.js +115 -0
- package/dist/migrate/from-postgres/translate.d.ts +73 -0
- package/dist/migrate/from-postgres/translate.d.ts.map +1 -0
- package/dist/migrate/from-postgres/translate.js +261 -0
- package/dist/migrate/from-postgres/types.d.ts +51 -0
- package/dist/migrate/from-postgres/types.d.ts.map +1 -0
- package/dist/migrate/from-postgres/types.js +211 -0
- package/dist/migration-replay.d.ts +73 -0
- package/dist/migration-replay.d.ts.map +1 -0
- package/dist/migration-replay.js +294 -0
- package/dist/okf/index.md +6 -0
- package/dist/okf/rules/SQLCH128.md +11 -0
- package/dist/okf/types/PostgresForeignDataWrapper.md +9 -0
- package/dist/okf/types/PostgresForeignServer.md +9 -0
- package/dist/okf/types/PostgresOperator.md +9 -0
- package/dist/okf/types/PostgresPublication.md +9 -0
- package/dist/okf/types/PostgresStatistics.md +9 -0
- package/dist/op/activities/postgres-migration.d.ts.map +1 -1
- package/dist/op/activities/postgres-migration.js +4 -0
- package/dist/op/activity-contracts.d.ts +20 -0
- package/dist/op/activity-contracts.d.ts.map +1 -1
- package/dist/op/activity-contracts.js +2 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +36 -2
- package/dist/postgres/apply/apply.js +8 -1
- package/dist/postgres/apply/statements.d.ts.map +1 -1
- package/dist/postgres/apply/statements.js +87 -2
- package/dist/postgres/constraint-names.d.ts +30 -0
- package/dist/postgres/constraint-names.d.ts.map +1 -0
- package/dist/postgres/constraint-names.js +72 -0
- package/dist/postgres/entities.d.ts +110 -1
- package/dist/postgres/entities.d.ts.map +1 -1
- package/dist/postgres/entities.js +146 -0
- package/dist/postgres/entity-types.d.ts +5 -0
- package/dist/postgres/entity-types.d.ts.map +1 -1
- package/dist/postgres/entity-types.js +5 -0
- package/dist/postgres/import/generator.d.ts.map +1 -1
- package/dist/postgres/import/generator.js +50 -2
- package/dist/postgres/import/live-export.d.ts.map +1 -1
- package/dist/postgres/import/live-export.js +2 -0
- package/dist/postgres/live/catalog-kinds.d.ts +14 -0
- package/dist/postgres/live/catalog-kinds.d.ts.map +1 -1
- package/dist/postgres/live/catalog-kinds.js +206 -0
- package/dist/postgres/live/catalog.d.ts +2 -0
- package/dist/postgres/live/catalog.d.ts.map +1 -1
- package/dist/postgres/live/catalog.js +3 -1
- package/dist/postgres/live/describe-resources.d.ts.map +1 -1
- package/dist/postgres/live/describe-resources.js +10 -2
- package/dist/postgres/migrate/backfill.d.ts +2 -0
- package/dist/postgres/migrate/backfill.d.ts.map +1 -1
- package/dist/postgres/migrate/backfill.js +7 -1
- package/dist/postgres/migrate/carry.d.ts +45 -1
- package/dist/postgres/migrate/carry.d.ts.map +1 -1
- package/dist/postgres/migrate/carry.js +72 -8
- package/dist/postgres/migrate/observe.d.ts +28 -4
- package/dist/postgres/migrate/observe.d.ts.map +1 -1
- package/dist/postgres/migrate/observe.js +41 -12
- package/dist/postgres/migrate/op.d.ts +26 -1
- package/dist/postgres/migrate/op.d.ts.map +1 -1
- package/dist/postgres/migrate/op.js +3 -1
- package/dist/postgres/migrate/steps.d.ts +35 -2
- package/dist/postgres/migrate/steps.d.ts.map +1 -1
- package/dist/postgres/migrate/steps.js +158 -12
- package/dist/postgres/parser.d.ts +72 -1
- package/dist/postgres/parser.d.ts.map +1 -1
- package/dist/postgres/parser.js +194 -2
- package/dist/postgres/plan/deep.d.ts.map +1 -1
- package/dist/postgres/plan/deep.js +29 -1
- package/dist/postgres/plan/diff.d.ts.map +1 -1
- package/dist/postgres/plan/diff.js +39 -1
- package/dist/postgres/plan/normalize.d.ts +17 -2
- package/dist/postgres/plan/normalize.d.ts.map +1 -1
- package/dist/postgres/plan/normalize.js +109 -1
- package/dist/postgres/plan/rules.d.ts +1 -0
- package/dist/postgres/plan/rules.d.ts.map +1 -1
- package/dist/postgres/plan/rules.js +3 -2
- package/dist/postgres/plan/schema.js +1 -1
- package/dist/postgres/secret-options.d.ts +10 -0
- package/dist/postgres/secret-options.d.ts.map +1 -0
- package/dist/postgres/secret-options.js +9 -0
- package/dist/postgres/testing/roundtrip-schema.d.ts +3 -2
- package/dist/postgres/testing/roundtrip-schema.d.ts.map +1 -1
- package/dist/postgres/testing/roundtrip-schema.js +13 -1
- package/dist/postgres.d.ts +1 -1
- package/dist/postgres.d.ts.map +1 -1
- package/dist/postgres.js +1 -1
- package/dist/rules/audit-entries.ts +1 -0
- package/dist/rules/postgres-templates.ts +2 -2
- package/dist/rules/sqlch128.ts +230 -0
- package/dist/serializer.d.ts +5 -0
- package/dist/serializer.d.ts.map +1 -1
- package/dist/serializer.js +13 -2
- package/dist/sql-types-command.d.ts +13 -0
- package/dist/sql-types-command.d.ts.map +1 -1
- package/dist/sql-types-command.js +31 -16
- package/dist/sql-types.d.ts +22 -0
- package/dist/sql-types.d.ts.map +1 -1
- package/dist/sql-types.js +10 -6
- package/dist/sqlserver/lexer.d.ts +37 -0
- package/dist/sqlserver/lexer.d.ts.map +1 -0
- package/dist/sqlserver/lexer.js +254 -0
- package/dist/sqlserver/parse.d.ts +185 -0
- package/dist/sqlserver/parse.d.ts.map +1 -0
- package/dist/sqlserver/parse.js +767 -0
- package/dist/sqlserver/translate.d.ts +34 -0
- package/dist/sqlserver/translate.d.ts.map +1 -0
- package/dist/sqlserver/translate.js +495 -0
- package/dist/sqlserver/types.d.ts +44 -0
- package/dist/sqlserver/types.d.ts.map +1 -0
- package/dist/sqlserver/types.js +133 -0
- package/dist/sqlserver/validate.d.ts +31 -0
- package/dist/sqlserver/validate.d.ts.map +1 -0
- package/dist/sqlserver/validate.js +67 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +5 -0
- package/package.json +2 -2
- package/src/change-set.ts +2 -1
- package/src/clickhouse/apply/statements.ts +25 -0
- package/src/clickhouse/import/live-export.ts +20 -5
- package/src/clickhouse/live/named-collections.e2e.test.ts +88 -0
- package/src/clickhouse/live/named-collections.ts +61 -0
- package/src/clickhouse/live/undeclarable.e2e.test.ts +5 -3
- package/src/clickhouse/live/undeclarable.ts +20 -4
- package/src/clickhouse/named-collections.test.ts +187 -0
- package/src/clickhouse/named-collections.ts +224 -0
- package/src/clickhouse/parser.ts +2 -1
- package/src/clickhouse/plan/commands.ts +17 -2
- package/src/clickhouse/plan/diff.ts +57 -1
- package/src/clickhouse/plan/disruption.ts +5 -0
- package/src/clickhouse/plan/rebuild-handoff.ts +3 -0
- package/src/clickhouse/plan/report.ts +6 -1
- package/src/clickhouse/plan/rules.ts +14 -4
- package/src/clickhouse/plan/stream-s3queue.e2e.test.ts +148 -0
- package/src/clickhouse/plan/stream.test.ts +237 -0
- package/src/clickhouse/plan/stream.ts +111 -0
- package/src/clickhouse/rebuild/observe.ts +15 -1
- package/src/clickhouse/review-catalog.test.ts +181 -0
- package/src/clickhouse/review-catalog.ts +489 -0
- package/src/codegen/classifier-page.ts +21 -4
- package/src/codegen/clickhouse-module.ts +3 -0
- package/src/codegen/coverage-page.ts +5 -3
- package/src/codegen/docs.ts +1 -1
- package/src/codegen/postgres-classifier-page.ts +1 -1
- package/src/codegen/registry.ts +5 -0
- package/src/composites/catalog.test.ts +6 -1
- package/src/composites/catalog.ts +100 -0
- package/src/composites/clickhouse.ts +2 -0
- package/src/composites/composites.test.ts +1 -1
- package/src/composites/otel-tables.test.ts +118 -0
- package/src/composites/otel-tables.ts +339 -0
- package/src/composites/stream-ingest.test.ts +114 -0
- package/src/composites/stream-ingest.ts +82 -0
- package/src/core/undeclarable.test.ts +6 -5
- package/src/coverage/clickhouse.json +1 -1
- package/src/coverage/postgres.json +7 -7
- package/src/coverage.test.ts +27 -2
- package/src/coverage.ts +18 -7
- package/src/drizzle-command.ts +94 -0
- package/src/drizzle-kit.e2e.test.ts +89 -0
- package/src/drizzle-types.e2e.test.ts +67 -0
- package/src/drizzle.test.ts +358 -0
- package/src/drizzle.ts +737 -0
- package/src/files/clickhouse.ts +8 -1
- package/src/files/common.ts +14 -1
- package/src/files/postgres.ts +12 -2
- package/src/generated/clickhouse.ts +3 -0
- package/src/generated/lexicon-sql.json +25 -0
- package/src/import-parser.sqlserver.test.ts +92 -0
- package/src/import-parser.ts +79 -5
- package/src/index.ts +1 -1
- package/src/lint/post-synth/audit-entries.ts +1 -0
- package/src/lint/post-synth/index.ts +2 -0
- package/src/lint/post-synth/sqlch128.test.ts +107 -0
- package/src/lint/post-synth/sqlch128.ts +230 -0
- package/src/lint/rules/postgres-templates.ts +2 -2
- package/src/lsp/postgres-template.ts +11 -0
- package/src/mcp/postgres.ts +1 -1
- package/src/migrate/from-postgres/cli.test.ts +165 -0
- package/src/migrate/from-postgres/detect.ts +7 -0
- package/src/migrate/from-postgres/emit.ts +96 -0
- package/src/migrate/from-postgres/example.test.ts +205 -0
- package/src/migrate/from-postgres/index.ts +122 -0
- package/src/migrate/from-postgres/translate.test.ts +242 -0
- package/src/migrate/from-postgres/translate.ts +359 -0
- package/src/migrate/from-postgres/types.test.ts +116 -0
- package/src/migrate/from-postgres/types.ts +236 -0
- package/src/migrate/from-postgres/validate.e2e.test.ts +44 -0
- package/src/migrate/from-postgres/workspace.e2e.test.ts +114 -0
- package/src/migration-replay.e2e.test.ts +155 -0
- package/src/migration-replay.test.ts +173 -0
- package/src/migration-replay.ts +289 -0
- package/src/op/__snapshots__/watch-pipeline.test.ts.snap +2 -2
- package/src/op/activities/postgres-migration.ts +4 -0
- package/src/op/activity-contracts.ts +2 -0
- package/src/plugin.ts +37 -2
- package/src/postgres/apply/apply.ts +9 -1
- package/src/postgres/apply/statements.ts +74 -1
- package/src/postgres/constraint-names.ts +71 -0
- package/src/postgres/database-kinds.test.ts +384 -0
- package/src/postgres/entities.ts +266 -1
- package/src/postgres/entity-types.ts +5 -0
- package/src/postgres/import/generator.ts +42 -2
- package/src/postgres/import/live-export.ts +1 -0
- package/src/postgres/live/catalog-kinds.ts +223 -0
- package/src/postgres/live/catalog.ts +6 -1
- package/src/postgres/live/database-kinds.e2e.test.ts +164 -0
- package/src/postgres/live/describe-resources.ts +11 -2
- package/src/postgres/live/undeclarable.e2e.test.ts +13 -6
- package/src/postgres/migrate/backfill.ts +13 -1
- package/src/postgres/migrate/carry.ts +103 -8
- package/src/postgres/migrate/followups.e2e.test.ts +218 -0
- package/src/postgres/migrate/followups.test.ts +199 -0
- package/src/postgres/migrate/kinds.e2e.test.ts +5 -5
- package/src/postgres/migrate/observe.ts +53 -14
- package/src/postgres/migrate/op.ts +28 -1
- package/src/postgres/migrate/partition.e2e.test.ts +129 -0
- package/src/postgres/migrate/partition.test.ts +206 -0
- package/src/postgres/migrate/steps.ts +157 -12
- package/src/postgres/parser.ts +234 -2
- package/src/postgres/plan/deep.ts +28 -1
- package/src/postgres/plan/diff.ts +36 -1
- package/src/postgres/plan/normalize.ts +122 -1
- package/src/postgres/plan/rules.ts +10 -3
- package/src/postgres/plan/schema.ts +1 -1
- package/src/postgres/secret-options.ts +10 -0
- package/src/postgres/testing/roundtrip-schema.ts +13 -1
- package/src/postgres.ts +16 -0
- package/src/serializer.ts +13 -2
- package/src/skills/chant-sql-postgres-migration.md +3 -3
- package/src/skills/chant-sql-postgres.md +6 -1
- package/src/skills/chant-sql.md +2 -1
- package/src/sql-types-command.ts +38 -16
- package/src/sql-types.ts +11 -6
- package/src/sqlserver/fixture.test.ts +186 -0
- package/src/sqlserver/import-cli.test.ts +61 -0
- package/src/sqlserver/lexer.ts +260 -0
- package/src/sqlserver/parse.ts +865 -0
- package/src/sqlserver/translate.test.ts +396 -0
- package/src/sqlserver/translate.ts +558 -0
- package/src/sqlserver/types.test.ts +102 -0
- package/src/sqlserver/types.ts +154 -0
- package/src/sqlserver/validate.e2e.test.ts +32 -0
- package/src/sqlserver/validate.test.ts +49 -0
- package/src/sqlserver/validate.ts +76 -0
- package/src/validate.ts +5 -0
- package/src/workspace-kinds.test.ts +11 -0
- package/workspace-kinds.json +100 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options that hold a credential. A foreign data wrapper's or server's
|
|
3
|
+
* `OPTIONS (...)` can carry any name, and a password in one would be written
|
|
4
|
+
* into a schema file by import and sent to every reader of the plan. The
|
|
5
|
+
* environment supplies credentials, in a user mapping (which is not declared)
|
|
6
|
+
* or its own secret store, as for a role's password (`./entities.ts`).
|
|
7
|
+
*/
|
|
8
|
+
/** Whether an option name reads as a credential: `password`, `sslpassword`, `secret_key`, `api_token`. */
|
|
9
|
+
export const isSecretOption = (name) => /pass(word|wd)?|secret|token|api[_-]?key|credential/i.test(name);
|
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
* sequence options, storage parameters, comments), an extension and the
|
|
6
6
|
* domain over its type, a collation, composite and range types (and a
|
|
7
7
|
* multirange column), plain and ordered-set aggregates, a cast and an event
|
|
8
|
-
* trigger
|
|
8
|
+
* trigger, an operator, extended statistics, a foreign data wrapper and server, and a
|
|
9
|
+
* publication (#3911), a partitioned table and a partition, an ORM's
|
|
9
10
|
* revision table that import leaves out, and an object carrying chant's
|
|
10
11
|
* ownership trailer.
|
|
11
12
|
*/
|
|
12
|
-
export declare const ROUNDTRIP_SCHEMA = "\nCREATE SCHEMA app;\nCOMMENT ON SCHEMA app IS 'The shop';\nCREATE EXTENSION citext WITH SCHEMA app;\nCREATE TYPE app.order_status AS ENUM ('placed', 'paid', 'shipped');\nCREATE DOMAIN app.email AS app.citext CONSTRAINT email_shape CHECK (VALUE LIKE '%@%');\nCOMMENT ON CONSTRAINT email_shape ON DOMAIN app.email IS 'needs an @';\nCREATE SEQUENCE app.invoice_seq AS integer START WITH 1000 CACHE 10;\nCREATE TABLE app.users (\n id bigint GENERATED ALWAYS AS IDENTITY (START WITH 10) PRIMARY KEY,\n email app.email NOT NULL UNIQUE,\n plan text NOT NULL DEFAULT 'free' CHECK (plan IN ('free', 'pro')),\n created_at timestamptz NOT NULL DEFAULT now()\n) WITH (fillfactor = 90);\nCOMMENT ON TABLE app.users IS 'Accounts [chant managed-by=chant stack=shop env=e2e]';\nCOMMENT ON COLUMN app.users.email IS 'Login name';\nCREATE TABLE app.orders (\n id serial PRIMARY KEY,\n user_id bigint NOT NULL REFERENCES app.users (id) ON DELETE CASCADE,\n invoice_no integer NOT NULL DEFAULT nextval('app.invoice_seq'),\n status app.order_status NOT NULL DEFAULT 'placed',\n amount numeric(12, 2) NOT NULL CONSTRAINT amount_positive CHECK (amount >= 0),\n discount int DEFAULT -1,\n total numeric GENERATED ALWAYS AS (amount * 2) STORED,\n placed_at timestamp(3) without time zone\n);\nCREATE INDEX orders_user_idx ON app.orders (user_id, placed_at DESC) WHERE status <> 'shipped';\nCREATE UNIQUE INDEX orders_invoice_idx ON app.orders USING btree (invoice_no) INCLUDE (amount);\nCREATE TABLE app.measures (ts date NOT NULL, v double precision) PARTITION BY RANGE (ts);\nCREATE TABLE app.measures_2026 PARTITION OF app.measures FOR VALUES FROM ('2026-01-01') TO ('2027-01-01');\nCREATE VIEW app.order_totals AS\n SELECT u.id AS user_id, u.email, count(o.id) AS n, coalesce(sum(o.amount), 0) AS total\n FROM app.users u LEFT JOIN app.orders o ON o.user_id = u.id\n GROUP BY u.id, u.email;\nCREATE MATERIALIZED VIEW app.daily AS SELECT placed_at::date AS day, count(*) AS n FROM app.orders GROUP BY 1 WITH NO DATA;\nCREATE COLLATION app.ci (provider = icu, locale = 'und-u-ks-level2', deterministic = false);\nCOMMENT ON COLLATION app.ci IS 'Case-insensitive';\nCREATE TYPE app.pair AS (a integer, b text COLLATE \"C\");\nCOMMENT ON TYPE app.pair IS 'Two values';\nCREATE TYPE app.floatrange AS RANGE (SUBTYPE = float8, SUBTYPE_DIFF = float8mi);\nCREATE TABLE app.people (id integer PRIMARY KEY, nick text COLLATE app.ci, span app.floatrange, tags app.floatmultirange);\nCREATE FUNCTION app.add2(a integer, b integer) RETURNS integer LANGUAGE sql IMMUTABLE AS $$ SELECT a + b $$;\nCREATE AGGREGATE app.total(integer) (SFUNC = app.add2, STYPE = integer, INITCOND = '0', PARALLEL = SAFE);\nCOMMENT ON AGGREGATE app.total(integer) IS 'A sum';\nCREATE FUNCTION app.middle(v double precision[]) RETURNS double precision LANGUAGE sql IMMUTABLE AS $$ SELECT v[(array_length(v, 1) + 1) / 2] $$;\nCREATE AGGREGATE app.median_of(ORDER BY double precision) (SFUNC = pg_catalog.array_append, STYPE = double precision[], FINALFUNC = app.middle);\nCREATE FUNCTION app.pair_text(p app.pair) RETURNS text LANGUAGE sql IMMUTABLE AS $$ SELECT p.a || ':' || p.b $$;\nCREATE CAST (app.pair AS text) WITH FUNCTION app.pair_text(app.pair) AS ASSIGNMENT;\nCOMMENT ON CAST (app.pair AS text) IS 'a:b';\nCREATE FUNCTION app.audit() RETURNS event_trigger LANGUAGE plpgsql AS $$ BEGIN END $$;\nCREATE EVENT TRIGGER app_audit ON ddl_command_end WHEN TAG IN ('CREATE TABLE') EXECUTE FUNCTION app.audit();\nCREATE TABLE public._prisma_migrations (id varchar(36) PRIMARY KEY, checksum varchar(64) NOT NULL);\n";
|
|
13
|
+
export declare const ROUNDTRIP_SCHEMA = "\nCREATE SCHEMA app;\nCOMMENT ON SCHEMA app IS 'The shop';\nCREATE EXTENSION citext WITH SCHEMA app;\nCREATE TYPE app.order_status AS ENUM ('placed', 'paid', 'shipped');\nCREATE DOMAIN app.email AS app.citext CONSTRAINT email_shape CHECK (VALUE LIKE '%@%');\nCOMMENT ON CONSTRAINT email_shape ON DOMAIN app.email IS 'needs an @';\nCREATE SEQUENCE app.invoice_seq AS integer START WITH 1000 CACHE 10;\nCREATE TABLE app.users (\n id bigint GENERATED ALWAYS AS IDENTITY (START WITH 10) PRIMARY KEY,\n email app.email NOT NULL UNIQUE,\n plan text NOT NULL DEFAULT 'free' CHECK (plan IN ('free', 'pro')),\n created_at timestamptz NOT NULL DEFAULT now()\n) WITH (fillfactor = 90);\nCOMMENT ON TABLE app.users IS 'Accounts [chant managed-by=chant stack=shop env=e2e]';\nCOMMENT ON COLUMN app.users.email IS 'Login name';\nCREATE TABLE app.orders (\n id serial PRIMARY KEY,\n user_id bigint NOT NULL REFERENCES app.users (id) ON DELETE CASCADE,\n invoice_no integer NOT NULL DEFAULT nextval('app.invoice_seq'),\n status app.order_status NOT NULL DEFAULT 'placed',\n amount numeric(12, 2) NOT NULL CONSTRAINT amount_positive CHECK (amount >= 0),\n discount int DEFAULT -1,\n total numeric GENERATED ALWAYS AS (amount * 2) STORED,\n placed_at timestamp(3) without time zone\n);\nCREATE INDEX orders_user_idx ON app.orders (user_id, placed_at DESC) WHERE status <> 'shipped';\nCREATE UNIQUE INDEX orders_invoice_idx ON app.orders USING btree (invoice_no) INCLUDE (amount);\nCREATE TABLE app.measures (ts date NOT NULL, v double precision) PARTITION BY RANGE (ts);\nCREATE TABLE app.measures_2026 PARTITION OF app.measures FOR VALUES FROM ('2026-01-01') TO ('2027-01-01');\nCREATE VIEW app.order_totals AS\n SELECT u.id AS user_id, u.email, count(o.id) AS n, coalesce(sum(o.amount), 0) AS total\n FROM app.users u LEFT JOIN app.orders o ON o.user_id = u.id\n GROUP BY u.id, u.email;\nCREATE MATERIALIZED VIEW app.daily AS SELECT placed_at::date AS day, count(*) AS n FROM app.orders GROUP BY 1 WITH NO DATA;\nCREATE COLLATION app.ci (provider = icu, locale = 'und-u-ks-level2', deterministic = false);\nCOMMENT ON COLLATION app.ci IS 'Case-insensitive';\nCREATE TYPE app.pair AS (a integer, b text COLLATE \"C\");\nCOMMENT ON TYPE app.pair IS 'Two values';\nCREATE TYPE app.floatrange AS RANGE (SUBTYPE = float8, SUBTYPE_DIFF = float8mi);\nCREATE TABLE app.people (id integer PRIMARY KEY, nick text COLLATE app.ci, span app.floatrange, tags app.floatmultirange);\nCREATE FUNCTION app.add2(a integer, b integer) RETURNS integer LANGUAGE sql IMMUTABLE AS $$ SELECT a + b $$;\nCREATE AGGREGATE app.total(integer) (SFUNC = app.add2, STYPE = integer, INITCOND = '0', PARALLEL = SAFE);\nCOMMENT ON AGGREGATE app.total(integer) IS 'A sum';\nCREATE FUNCTION app.middle(v double precision[]) RETURNS double precision LANGUAGE sql IMMUTABLE AS $$ SELECT v[(array_length(v, 1) + 1) / 2] $$;\nCREATE AGGREGATE app.median_of(ORDER BY double precision) (SFUNC = pg_catalog.array_append, STYPE = double precision[], FINALFUNC = app.middle);\nCREATE FUNCTION app.pair_text(p app.pair) RETURNS text LANGUAGE sql IMMUTABLE AS $$ SELECT p.a || ':' || p.b $$;\nCREATE CAST (app.pair AS text) WITH FUNCTION app.pair_text(app.pair) AS ASSIGNMENT;\nCOMMENT ON CAST (app.pair AS text) IS 'a:b';\nCREATE FUNCTION app.audit() RETURNS event_trigger LANGUAGE plpgsql AS $$ BEGIN END $$;\nCREATE EVENT TRIGGER app_audit ON ddl_command_end WHEN TAG IN ('CREATE TABLE') EXECUTE FUNCTION app.audit();\nCREATE FUNCTION app.int_same(a integer, b integer) RETURNS boolean LANGUAGE sql IMMUTABLE AS $$ SELECT a = b $$;\nCREATE OPERATOR app.=== (FUNCTION = app.int_same, LEFTARG = integer, RIGHTARG = integer, COMMUTATOR = OPERATOR(app.===), RESTRICT = eqsel, JOIN = eqjoinsel, HASHES, MERGES);\nCOMMENT ON OPERATOR app.===(integer, integer) IS 'Same value';\nCREATE STATISTICS app.orders_stats (dependencies) ON user_id, status FROM app.orders;\nCOMMENT ON STATISTICS app.orders_stats IS 'Users and their order states';\nCREATE FOREIGN DATA WRAPPER app_fdw OPTIONS (debug 'true');\nCOMMENT ON FOREIGN DATA WRAPPER app_fdw IS 'Remote tables';\nCREATE SERVER app_replica TYPE 'pg' VERSION '16' FOREIGN DATA WRAPPER app_fdw OPTIONS (host 'db.internal', port '5432');\nCOMMENT ON SERVER app_replica IS 'The read replica';\nCREATE PUBLICATION app_pub FOR TABLE app.orders, app.users WITH (publish = 'insert, update');\nCOMMENT ON PUBLICATION app_pub IS 'Order changes';\nCREATE TABLE public._prisma_migrations (id varchar(36) PRIMARY KEY, checksum varchar(64) NOT NULL);\n";
|
|
13
14
|
//# sourceMappingURL=roundtrip-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roundtrip-schema.d.ts","sourceRoot":"","sources":["../../../src/postgres/testing/roundtrip-schema.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"roundtrip-schema.d.ts","sourceRoot":"","sources":["../../../src/postgres/testing/roundtrip-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,27IA+D5B,CAAC"}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* sequence options, storage parameters, comments), an extension and the
|
|
6
6
|
* domain over its type, a collation, composite and range types (and a
|
|
7
7
|
* multirange column), plain and ordered-set aggregates, a cast and an event
|
|
8
|
-
* trigger
|
|
8
|
+
* trigger, an operator, extended statistics, a foreign data wrapper and server, and a
|
|
9
|
+
* publication (#3911), a partitioned table and a partition, an ORM's
|
|
9
10
|
* revision table that import leaves out, and an object carrying chant's
|
|
10
11
|
* ownership trailer.
|
|
11
12
|
*/
|
|
@@ -60,5 +61,16 @@ CREATE CAST (app.pair AS text) WITH FUNCTION app.pair_text(app.pair) AS ASSIGNME
|
|
|
60
61
|
COMMENT ON CAST (app.pair AS text) IS 'a:b';
|
|
61
62
|
CREATE FUNCTION app.audit() RETURNS event_trigger LANGUAGE plpgsql AS $$ BEGIN END $$;
|
|
62
63
|
CREATE EVENT TRIGGER app_audit ON ddl_command_end WHEN TAG IN ('CREATE TABLE') EXECUTE FUNCTION app.audit();
|
|
64
|
+
CREATE FUNCTION app.int_same(a integer, b integer) RETURNS boolean LANGUAGE sql IMMUTABLE AS $$ SELECT a = b $$;
|
|
65
|
+
CREATE OPERATOR app.=== (FUNCTION = app.int_same, LEFTARG = integer, RIGHTARG = integer, COMMUTATOR = OPERATOR(app.===), RESTRICT = eqsel, JOIN = eqjoinsel, HASHES, MERGES);
|
|
66
|
+
COMMENT ON OPERATOR app.===(integer, integer) IS 'Same value';
|
|
67
|
+
CREATE STATISTICS app.orders_stats (dependencies) ON user_id, status FROM app.orders;
|
|
68
|
+
COMMENT ON STATISTICS app.orders_stats IS 'Users and their order states';
|
|
69
|
+
CREATE FOREIGN DATA WRAPPER app_fdw OPTIONS (debug 'true');
|
|
70
|
+
COMMENT ON FOREIGN DATA WRAPPER app_fdw IS 'Remote tables';
|
|
71
|
+
CREATE SERVER app_replica TYPE 'pg' VERSION '16' FOREIGN DATA WRAPPER app_fdw OPTIONS (host 'db.internal', port '5432');
|
|
72
|
+
COMMENT ON SERVER app_replica IS 'The read replica';
|
|
73
|
+
CREATE PUBLICATION app_pub FOR TABLE app.orders, app.users WITH (publish = 'insert, update');
|
|
74
|
+
COMMENT ON PUBLICATION app_pub IS 'Order changes';
|
|
63
75
|
CREATE TABLE public._prisma_migrations (id varchar(36) PRIMARY KEY, checksum varchar(64) NOT NULL);
|
|
64
76
|
`;
|
package/dist/postgres.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* the statements are Postgres's own DDL, parsed at build time into entities,
|
|
6
6
|
* and the names fold and quote as Postgres folds and quotes them.
|
|
7
7
|
*/
|
|
8
|
-
export { schema, table, index, view, sequence, type, domain, extension, func, procedure, aggregate, trigger, eventTrigger, collation, cast, policy, role, grant, literal, SqlLiteral, SqlTemplateError, PostgresObject, POSTGRES_ENTITY_TYPES, isPostgresObject, isColumnRef, quoteIdent, type PostgresEntityType, type PostgresSchema, type PostgresRelation, type PostgresTable, type PostgresView, type PostgresIndex, type PostgresSequence, type PostgresEnum, type PostgresCompositeType, type PostgresRangeType, type PostgresType, type PostgresDomain, type PostgresAggregate, type PostgresCollation, type PostgresCast, type PostgresEventTrigger, type PostgresExtension, type PostgresFunction, type PostgresProcedure, type PostgresTrigger, type PostgresPolicy, type PostgresRole, type PostgresGrant, type ColumnDef, type KeyDef, type CheckDef, type ForeignKeyDef, type ExclusionDef, type SchemaProps, type TableProps, type IndexProps, type ViewProps, type SequenceProps, type EnumProps, type CompositeTypeProps, type CompositeAttributeDef, type RangeTypeProps, type AggregateProps, type AggregateArgDef, type CollationProps, type CastProps, type EventTriggerProps, type DomainProps, type ExtensionProps, type RoutineProps, type RoutineArgDef, type FunctionProps, type ProcedureProps, type TriggerProps, type PolicyProps, type RoleProps, type GrantProps, type DefaultPrivilegesProps, type PrivilegeDef, type LineageEdge, type SqlSchema, type RowOf, type Column, type ColumnTraits, type AnyColumn, type UncheckedColumn, type KeyColumn, type NotNullColumn, type Named, type Unnamed, } from "./postgres/entities.js";
|
|
8
|
+
export { schema, table, index, view, sequence, type, domain, extension, func, procedure, aggregate, trigger, eventTrigger, operator, statistics, foreignDataWrapper, foreignServer, publication, collation, cast, policy, role, grant, literal, SqlLiteral, SqlTemplateError, PostgresObject, POSTGRES_ENTITY_TYPES, isPostgresObject, isColumnRef, quoteIdent, type PostgresEntityType, type PostgresSchema, type PostgresRelation, type PostgresTable, type PostgresView, type PostgresIndex, type PostgresSequence, type PostgresEnum, type PostgresCompositeType, type PostgresRangeType, type PostgresType, type PostgresDomain, type PostgresAggregate, type PostgresCollation, type PostgresCast, type PostgresEventTrigger, type PostgresOperator, type PostgresStatistics, type PostgresForeignDataWrapper, type PostgresForeignServer, type PostgresPublication, type PostgresExtension, type PostgresFunction, type PostgresProcedure, type PostgresTrigger, type PostgresPolicy, type PostgresRole, type PostgresGrant, type ColumnDef, type KeyDef, type CheckDef, type ForeignKeyDef, type ExclusionDef, type SchemaProps, type TableProps, type IndexProps, type ViewProps, type SequenceProps, type EnumProps, type CompositeTypeProps, type CompositeAttributeDef, type RangeTypeProps, type AggregateProps, type AggregateArgDef, type CollationProps, type CastProps, type EventTriggerProps, type OperatorProps, type StatisticsProps, type ForeignDataWrapperProps, type ForeignServerProps, type PublicationProps, type PublicationTableDef, type DomainProps, type ExtensionProps, type RoutineProps, type RoutineArgDef, type FunctionProps, type ProcedureProps, type TriggerProps, type PolicyProps, type RoleProps, type GrantProps, type DefaultPrivilegesProps, type PrivilegeDef, type LineageEdge, type SqlSchema, type RowOf, type Column, type ColumnTraits, type AnyColumn, type UncheckedColumn, type KeyColumn, type NotNullColumn, type Named, type Unnamed, } from "./postgres/entities.js";
|
|
9
9
|
export { POSTGRES_PROVIDERS, COMMON_REFUSED, providerData, isPostgresProvider, providerAllowsExtension, isProviderOwned, refusedStatement, normalizeStatement, type PostgresProvider, type ProviderData, type ProviderSource, type RefusedStatement, type LiveObjectRef, } from "./postgres/providers/index.js";
|
|
10
10
|
export { PostgresMigrationOp, type PostgresMigrationOpConfig, type PostgresMigrationOpResources, type PostgresMigrationArgs, } from "./postgres/migrate/op.js";
|
|
11
11
|
export { POSTGRES_RECEIPTS_TABLE } from "./postgres/migrate/receipts.js";
|
package/dist/postgres.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,MAAM,EACN,KAAK,EACL,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,SAAS,EACT,IAAI,EACJ,SAAS,EACT,SAAS,EACT,OAAO,EACP,YAAY,EACZ,SAAS,EACT,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,KAAK,EACL,OAAO,EACP,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,KAAK,EACV,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,OAAO,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,uBAAuB,EACvB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,mBAAmB,EACnB,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,cAAc,uBAAuB,CAAC;AAItC,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,MAAM,EACN,KAAK,EACL,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,SAAS,EACT,IAAI,EACJ,SAAS,EACT,SAAS,EACT,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,SAAS,EACT,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,KAAK,EACL,OAAO,EACP,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,KAAK,EACV,KAAK,MAAM,EACX,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,OAAO,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,uBAAuB,EACvB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,mBAAmB,EACnB,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,cAAc,uBAAuB,CAAC;AAItC,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC"}
|
package/dist/postgres.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* the statements are Postgres's own DDL, parsed at build time into entities,
|
|
6
6
|
* and the names fold and quote as Postgres folds and quotes them.
|
|
7
7
|
*/
|
|
8
|
-
export { schema, table, index, view, sequence, type, domain, extension, func, procedure, aggregate, trigger, eventTrigger, collation, cast, policy, role, grant, literal, SqlLiteral, SqlTemplateError, PostgresObject, POSTGRES_ENTITY_TYPES, isPostgresObject, isColumnRef, quoteIdent, } from "./postgres/entities.js";
|
|
8
|
+
export { schema, table, index, view, sequence, type, domain, extension, func, procedure, aggregate, trigger, eventTrigger, operator, statistics, foreignDataWrapper, foreignServer, publication, collation, cast, policy, role, grant, literal, SqlLiteral, SqlTemplateError, PostgresObject, POSTGRES_ENTITY_TYPES, isPostgresObject, isColumnRef, quoteIdent, } from "./postgres/entities.js";
|
|
9
9
|
export { POSTGRES_PROVIDERS, COMMON_REFUSED, providerData, isPostgresProvider, providerAllowsExtension, isProviderOwned, refusedStatement, normalizeStatement, } from "./postgres/providers/index.js";
|
|
10
10
|
export { PostgresMigrationOp, } from "./postgres/migrate/op.js";
|
|
11
11
|
export { POSTGRES_RECEIPTS_TABLE } from "./postgres/migrate/receipts.js";
|
|
@@ -33,4 +33,5 @@ export const sqlPostSynthAuditEntries: Record<string, RuleMeta> = {
|
|
|
33
33
|
SQLCH125: auditRule("SQLCH125", "merge-worthy", "guidance", "A codec parameter is outside what the codec takes", "Give the codec a parameter within its range or set, or drop the parameter for the default.", { category: "correctness" }),
|
|
34
34
|
SQLCH126: auditRule("SQLCH126", "merge-worthy", "guidance", "A GRANT column list names a column the table does not declare", "Fix the column name, or declare the column on the table.", { category: "correctness" }),
|
|
35
35
|
SQLCH127: auditRule("SQLCH127", "merge-worthy", "guidance", "An expression calls a function the pinned server does not have", "Fix the function name, use one from the pinned server's system.functions, or declare it with func.", { category: "correctness" }),
|
|
36
|
+
SQLCH128: auditRule("SQLCH128", "merge-worthy", "guidance", "An integration engine or table function argument holds a literal credential", "Create a named collection with the credentials on the server and name it in place of the arguments: ENGINE = S3(lake_creds, format = 'Parquet').", { category: "security" }),
|
|
36
37
|
};
|
|
@@ -17,12 +17,12 @@ export const POSTGRES_TEMPLATE_SOURCES: readonly TemplateSource<PostgresTag>[] =
|
|
|
17
17
|
{
|
|
18
18
|
dialect: "postgres",
|
|
19
19
|
modules: ["@intentius/chant-lexicon-sql/postgres"],
|
|
20
|
-
tags: ["schema", "table", "index", "view", "sequence", "type", "domain", "extension", "func", "procedure", "aggregate", "trigger", "eventTrigger", "collation", "cast", "policy", "role", "grant"],
|
|
20
|
+
tags: ["schema", "table", "index", "view", "sequence", "type", "domain", "extension", "func", "procedure", "aggregate", "trigger", "eventTrigger", "operator", "statistics", "foreignDataWrapper", "foreignServer", "publication", "collation", "cast", "policy", "role", "grant"],
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
dialect: "postgres",
|
|
24
24
|
modules: ["@intentius/chant-lexicon-sql"],
|
|
25
|
-
tags: ["schema", "index", "sequence", "type", "domain", "extension", "func", "procedure", "aggregate", "trigger", "eventTrigger", "collation", "cast", "policy", "role", "grant"],
|
|
25
|
+
tags: ["schema", "index", "sequence", "type", "domain", "extension", "func", "procedure", "aggregate", "trigger", "eventTrigger", "operator", "statistics", "foreignDataWrapper", "foreignServer", "publication", "collation", "cast", "policy", "role", "grant"],
|
|
26
26
|
},
|
|
27
27
|
];
|
|
28
28
|
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { DATABASE_ENGINES, FORMATS, TABLE_ENGINES } from "../../generated/clickhouse";
|
|
2
|
+
import { parseEngineSyntax } from "../../clickhouse/engine-syntax";
|
|
3
|
+
import { COLLECTION_ENGINES, engineCollection } from "../../clickhouse/named-collections";
|
|
4
|
+
import { isTrivia, tokenizeText, type Token } from "../../clickhouse/tokens";
|
|
5
|
+
import { checkOf, splitTop } from "./clickhouse-helpers";
|
|
6
|
+
import { clickhouseObjects, type OutputObject } from "./sql-helpers";
|
|
7
|
+
|
|
8
|
+
/** A syntax-line argument that holds a secret: `password`, `secret_access_key`, `account_key`, `session_token`, `oauth_token`. */
|
|
9
|
+
const SECRET_ARGUMENT = /password|secret|account_key|session_token|oauth_token/i;
|
|
10
|
+
|
|
11
|
+
/** A `key = value` argument or a setting that holds a secret: the above, and `kafka_sasl_password`, `nats_token`. */
|
|
12
|
+
const SECRET_KEY = /password|secret|account_key|session_token|oauth_token|(?:^|_)token$|private_key/i;
|
|
13
|
+
|
|
14
|
+
/** Credentials written inside another value: a URL's `user:password@`, an Azure connection string's key or signature. */
|
|
15
|
+
const EMBEDDED = [
|
|
16
|
+
{ re: /^[a-z][a-z0-9+.-]*:\/\/[^/@:\s]+:[^/@\s]+@/i, what: "a URL with a password in it" },
|
|
17
|
+
{ re: /(?:^|;)\s*(?:AccountKey|SharedAccessSignature)\s*=/i, what: "a connection string with an account key or signature in it" },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
/** Compression methods the integration engines take after the format. */
|
|
21
|
+
const COMPRESSION = new Set(["none", "auto", "gzip", "gz", "deflate", "br", "brotli", "xz", "lzma", "zstd", "zst", "lz4", "bz2", "snappy"]);
|
|
22
|
+
const FORMAT_NAMES = new Set(FORMATS.map((f) => f.toLowerCase()));
|
|
23
|
+
|
|
24
|
+
/** The table functions whose arguments follow an engine's syntax line, lower case, by engine. */
|
|
25
|
+
const FUNCTION_ENGINE: Readonly<Record<string, string>> = {
|
|
26
|
+
s3: "S3",
|
|
27
|
+
gcs: "S3",
|
|
28
|
+
oss: "S3",
|
|
29
|
+
cosn: "S3",
|
|
30
|
+
url: "URL",
|
|
31
|
+
mysql: "MySQL",
|
|
32
|
+
postgresql: "PostgreSQL",
|
|
33
|
+
mongodb: "MongoDB",
|
|
34
|
+
azureblobstorage: "AzureBlobStorage",
|
|
35
|
+
iceberg: "Iceberg",
|
|
36
|
+
icebergs3: "IcebergS3",
|
|
37
|
+
icebergazure: "IcebergAzure",
|
|
38
|
+
deltalake: "DeltaLake",
|
|
39
|
+
deltalakes3: "DeltaLakeS3",
|
|
40
|
+
deltalakeazure: "DeltaLakeAzure",
|
|
41
|
+
hudi: "Hudi",
|
|
42
|
+
paimon: "Paimon",
|
|
43
|
+
paimons3: "PaimonS3",
|
|
44
|
+
arrowflight: "ArrowFlight",
|
|
45
|
+
ytsaurus: "YTsaurus",
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** `remote('addresses', db, table, 'user', 'password')`: no syntax line says it, so its password's position is written here. */
|
|
49
|
+
const FUNCTION_SECRETS: Readonly<Record<string, Array<{ name: string; position: number }>>> = {
|
|
50
|
+
remote: [{ name: "password", position: 4 }],
|
|
51
|
+
remotesecure: [{ name: "password", position: 4 }],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const ENGINE_SYNTAX = { ...TABLE_ENGINES, ...DATABASE_ENGINES } as Readonly<Record<string, { syntax: string } | undefined>>;
|
|
55
|
+
|
|
56
|
+
/** The secret arguments an engine's syntax line names, with their positions. */
|
|
57
|
+
function secretPositions(engine: string): Array<{ name: string; position: number }> {
|
|
58
|
+
const syntax = ENGINE_SYNTAX[engine]?.syntax;
|
|
59
|
+
const parsed = syntax ? parseEngineSyntax(syntax) : undefined;
|
|
60
|
+
if (!parsed) return [];
|
|
61
|
+
return parsed.args
|
|
62
|
+
.filter((a) => !a.named && a.name.split("|").some((n) => SECRET_ARGUMENT.test(n)))
|
|
63
|
+
.map((a) => ({ name: a.name.split("|").find((n) => SECRET_ARGUMENT.test(n))!, position: a.position }));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** The text of a string literal, or undefined for anything else. */
|
|
67
|
+
function stringValue(text: string): string | undefined {
|
|
68
|
+
const t = text.trim();
|
|
69
|
+
if (!/^'(?:[^'\\]|\\.|'')*'$/.test(t)) return undefined;
|
|
70
|
+
return t.slice(1, -1).replace(/\\(.)/g, "$1").replace(/''/g, "'");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Whether the arguments before `position` leave it where the syntax line puts
|
|
75
|
+
* it. An optional group (`[, access_key_id, secret_access_key]`) may be left
|
|
76
|
+
* out, and the format and compression move up into its place:
|
|
77
|
+
* `S3('url', 'Parquet', 'gzip')`. When a format, a compression method or
|
|
78
|
+
* `NOSIGN` comes earlier, the position says nothing.
|
|
79
|
+
*/
|
|
80
|
+
function aligned(args: readonly string[], position: number): boolean {
|
|
81
|
+
for (const a of args.slice(1, position)) {
|
|
82
|
+
const t = a.trim();
|
|
83
|
+
if (t.toUpperCase() === "NOSIGN") return false;
|
|
84
|
+
const v = stringValue(t)?.toLowerCase();
|
|
85
|
+
if (v !== undefined && (FORMAT_NAMES.has(v) || COMPRESSION.has(v))) return false;
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface Finding {
|
|
91
|
+
where: string;
|
|
92
|
+
what: string;
|
|
93
|
+
masked: boolean;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** The literal credentials in one engine's or table function's arguments. */
|
|
97
|
+
function argumentFindings(label: string, args: readonly string[], secrets: ReadonlyArray<{ name: string; position: number }>, collection: boolean): Finding[] {
|
|
98
|
+
const out: Finding[] = [];
|
|
99
|
+
const add = (where: string, what: string, value: string) => out.push({ where, what, masked: value === "[HIDDEN]" });
|
|
100
|
+
// After a named collection, the arguments are `key = value` overrides, not positions.
|
|
101
|
+
if (!collection) {
|
|
102
|
+
for (const s of secrets) {
|
|
103
|
+
const arg = args[s.position];
|
|
104
|
+
const value = arg !== undefined ? stringValue(arg) : undefined;
|
|
105
|
+
if (value && aligned(args, s.position)) add(`${label} argument ${s.name}`, "a literal credential", value);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
args.forEach((arg, i) => {
|
|
109
|
+
const kv = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*([\s\S]+)$/.exec(arg);
|
|
110
|
+
if (kv) {
|
|
111
|
+
const value = stringValue(kv[2]!);
|
|
112
|
+
if (value && SECRET_KEY.test(kv[1]!)) add(`${label} argument ${kv[1]}`, "a literal credential", value);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const value = stringValue(arg);
|
|
116
|
+
if (!value) return;
|
|
117
|
+
for (const e of EMBEDDED) if (e.re.test(value)) add(`${label} argument ${i + 1}`, e.what, value);
|
|
118
|
+
});
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Each table function call in a SQL text, with its arguments as written. */
|
|
123
|
+
function functionCalls(text: string): Array<{ name: string; args: string[] }> {
|
|
124
|
+
let tokens: Token[];
|
|
125
|
+
try {
|
|
126
|
+
tokens = tokenizeText(text, 0);
|
|
127
|
+
} catch {
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
const sig = tokens.map((t, i) => ({ t, i })).filter(({ t }) => !isTrivia(t));
|
|
131
|
+
const out: Array<{ name: string; args: string[] }> = [];
|
|
132
|
+
for (let k = 0; k + 1 < sig.length; k++) {
|
|
133
|
+
const fn = sig[k]!.t;
|
|
134
|
+
const open = sig[k + 1]!;
|
|
135
|
+
if (fn.kind !== "ident" || open.t.kind !== "punct" || open.t.text !== "(") continue;
|
|
136
|
+
const lower = fn.text.toLowerCase();
|
|
137
|
+
const base = lower.endsWith("cluster") ? lower.slice(0, -"cluster".length) : lower;
|
|
138
|
+
if (!(base in FUNCTION_ENGINE) && !(base in FUNCTION_SECRETS)) continue;
|
|
139
|
+
let depth = 0;
|
|
140
|
+
let end = open.i;
|
|
141
|
+
for (let j = open.i; j < tokens.length; j++) {
|
|
142
|
+
const t = tokens[j]!;
|
|
143
|
+
if (t.kind === "punct" && t.text === "(") depth++;
|
|
144
|
+
else if (t.kind === "punct" && t.text === ")" && --depth === 0) {
|
|
145
|
+
end = j;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const inner = tokens
|
|
150
|
+
.slice(open.i + 1, end)
|
|
151
|
+
.map((t) => t.text)
|
|
152
|
+
.join("");
|
|
153
|
+
out.push({ name: fn.text, args: inner.trim() === "" ? [] : splitTop(inner) });
|
|
154
|
+
}
|
|
155
|
+
return out;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** The literal credentials in each table function call a SQL text makes. */
|
|
159
|
+
function callFindings(text: string): Finding[] {
|
|
160
|
+
return functionCalls(text).flatMap((call) => {
|
|
161
|
+
const lower = call.name.toLowerCase();
|
|
162
|
+
const clustered = lower.endsWith("cluster") && !(lower in FUNCTION_ENGINE);
|
|
163
|
+
const base = clustered ? lower.slice(0, -"cluster".length) : lower;
|
|
164
|
+
// `s3Cluster(cluster, url, ...)`: the cluster comes first.
|
|
165
|
+
const args = clustered ? call.args.slice(1) : call.args;
|
|
166
|
+
const engine = FUNCTION_ENGINE[base];
|
|
167
|
+
const secrets = engine ? secretPositions(engine) : (FUNCTION_SECRETS[base] ?? []);
|
|
168
|
+
const collection = args[0] !== undefined && /^\s*(?:[A-Za-z_][A-Za-z0-9_]*|`[^`]+`)\s*$/.test(args[0]) && args[0].trim().toUpperCase() !== "NOSIGN";
|
|
169
|
+
return argumentFindings(`${call.name}()`, args, secrets, collection);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** The literal credentials in a table's or database's engine and its settings. */
|
|
174
|
+
function engineFindings(o: OutputObject & { settings?: Record<string, string> }): Finding[] {
|
|
175
|
+
const engine = o.engine;
|
|
176
|
+
if (!engine) return [];
|
|
177
|
+
const out = argumentFindings(`ENGINE = ${engine.name}`, engine.args ?? [], secretPositions(engine.name), engineCollection(engine) !== undefined);
|
|
178
|
+
if (COLLECTION_ENGINES.has(engine.name)) {
|
|
179
|
+
for (const [key, raw] of Object.entries(o.settings ?? {})) {
|
|
180
|
+
const value = stringValue(raw);
|
|
181
|
+
if (value && SECRET_KEY.test(key)) out.push({ where: `${engine.name} setting ${key}`, what: "a literal credential", masked: value === "[HIDDEN]" });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return out;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** `PASSWORD 'secret'` in a dictionary's source. */
|
|
188
|
+
function sourceFindings(dataSource: string): Finding[] {
|
|
189
|
+
const m = /\bPASSWORD\s+('(?:[^'\\]|\\.|'')*')/i.exec(dataSource);
|
|
190
|
+
const value = m ? stringValue(m[1]!) : undefined;
|
|
191
|
+
return value ? [{ where: "SOURCE PASSWORD", what: "a literal credential", masked: value === "[HIDDEN]" }] : [];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* SQLCH128: an integration engine's or table function's argument holds a
|
|
196
|
+
* literal credential (#4395): `ENGINE = S3('https://...', 'AKIA...', 'secret')`,
|
|
197
|
+
* `mysql('db:3306', 'shop', 'orders', 'app', 'secret')`, a Kafka table's
|
|
198
|
+
* `kafka_sasl_password` setting, a dictionary source's `PASSWORD`.
|
|
199
|
+
*
|
|
200
|
+
* A credential is the environment's, so it does not belong in a declaration,
|
|
201
|
+
* the build output or `clickhouse.sql`, as `IDENTIFIED BY` does not on a
|
|
202
|
+
* user (`../../clickhouse/access.ts`). The secret arguments are found by name
|
|
203
|
+
* from each engine's syntax line in the pinned catalog (`password`,
|
|
204
|
+
* `secret_access_key`, `account_key`, `session_token`, `oauth_token`), as
|
|
205
|
+
* `key = value` overrides and settings by the same names, and inside a URL
|
|
206
|
+
* (`user:password@`) or an Azure connection string (`AccountKey=`). The fix
|
|
207
|
+
* is a named collection the environment creates, named in place of the
|
|
208
|
+
* arguments: `ENGINE = S3(lake_creds, format = 'Parquet')`.
|
|
209
|
+
*/
|
|
210
|
+
export const sqlch128 = checkOf({ id: "SQLCH128", description: "An integration engine or table function argument holds a literal credential" }, (ctx, report) => {
|
|
211
|
+
for (const o of clickhouseObjects(ctx)) {
|
|
212
|
+
const props = o as OutputObject & { settings?: Record<string, string>; asFunction?: string; select?: string; dataSource?: string };
|
|
213
|
+
const findings = [
|
|
214
|
+
...engineFindings(props),
|
|
215
|
+
...(props.asFunction ? callFindings(props.asFunction) : []),
|
|
216
|
+
...(props.select ? callFindings(props.select) : []),
|
|
217
|
+
...(props.dataSource ? sourceFindings(props.dataSource) : []),
|
|
218
|
+
];
|
|
219
|
+
for (const f of findings) {
|
|
220
|
+
const held = f.masked ? "holds '[HIDDEN]', the server's mask for a credential, in place of one" : `holds ${f.what}, which is the environment's`;
|
|
221
|
+
report({
|
|
222
|
+
severity: "error",
|
|
223
|
+
message:
|
|
224
|
+
`${o.export} (${o.name}): ${f.where} ${held}. ` +
|
|
225
|
+
"Create a named collection with the credentials on the server and name it in place of the arguments (ENGINE = S3(lake_creds, format = 'Parquet'), s3(lake_creds), SOURCE(MYSQL(NAME mysql_creds))); chant sql plan checks that it exists",
|
|
226
|
+
entity: o.export,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
});
|
package/dist/serializer.d.ts
CHANGED
|
@@ -21,6 +21,11 @@
|
|
|
21
21
|
* of each. Two databases of different dialects are two projects (two
|
|
22
22
|
* workspace members, #3047 question 1).
|
|
23
23
|
*
|
|
24
|
+
* A ClickHouse object that names a named collection (an engine's first
|
|
25
|
+
* argument, a table function's, a dictionary source's `NAME`) carries
|
|
26
|
+
* `namedCollections`, and the document lists every one the build names, so
|
|
27
|
+
* a plan can check each exists on the server (#4395).
|
|
28
|
+
*
|
|
24
29
|
* A Postgres document also carries `postgresMajor`, the major the project
|
|
25
30
|
* targets (`sql.postgresMajor`, else the newest pinned major). Post-synth
|
|
26
31
|
* checks and the lock classifier read it; ClickHouse output has no such field.
|
package/dist/serializer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAoB,MAAM,kBAAkB,CAAC;AAajF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAkBnF;AAED,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD,gEAAgE;AAChE,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAsEhD,eAAO,MAAM,aAAa,EAAE,UA6C3B,CAAC"}
|
package/dist/serializer.js
CHANGED
|
@@ -21,6 +21,11 @@
|
|
|
21
21
|
* of each. Two databases of different dialects are two projects (two
|
|
22
22
|
* workspace members, #3047 question 1).
|
|
23
23
|
*
|
|
24
|
+
* A ClickHouse object that names a named collection (an engine's first
|
|
25
|
+
* argument, a table function's, a dictionary source's `NAME`) carries
|
|
26
|
+
* `namedCollections`, and the document lists every one the build names, so
|
|
27
|
+
* a plan can check each exists on the server (#4395).
|
|
28
|
+
*
|
|
24
29
|
* A Postgres document also carries `postgresMajor`, the major the project
|
|
25
30
|
* targets (`sql.postgresMajor`, else the newest pinned major). Post-synth
|
|
26
31
|
* checks and the lock classifier read it; ClickHouse output has no such field.
|
|
@@ -39,6 +44,7 @@ import { applyOrder, lineageJson, referenceName } from "./core/references.js";
|
|
|
39
44
|
import { sqlFileLineOf, sqlFileOf, sqlFileReferences } from "./sql-files.js";
|
|
40
45
|
import { relative } from "node:path";
|
|
41
46
|
import { getProvenance } from "@intentius/chant/provenance";
|
|
47
|
+
import { namedCollectionReferences } from "./clickhouse/named-collections.js";
|
|
42
48
|
export { applyOrder } from "./core/references.js";
|
|
43
49
|
/**
|
|
44
50
|
* A warning for each clause chant's parser does not know (#3872): where it
|
|
@@ -81,7 +87,8 @@ function objectJson(name, obj, names, extra = []) {
|
|
|
81
87
|
props.lineage = lineageJson(props.lineage, names);
|
|
82
88
|
}
|
|
83
89
|
const dependsOn = [...new Set([...obj.dependsOn.map((r) => referenceName(r, names)).filter((n) => n !== undefined), ...extra])];
|
|
84
|
-
|
|
90
|
+
const collections = namedCollectionReferences(props);
|
|
91
|
+
return JSON.parse(JSON.stringify({ export: name, type: obj.entityType, sqlName: obj.sqlName, ...props, dependsOn, ...(collections.length > 0 ? { namedCollections: collections } : {}), ddl }));
|
|
85
92
|
}
|
|
86
93
|
/** A props value with every entity and column reference in it written as its export name (`users`, `users.id`). */
|
|
87
94
|
function postgresJsonValue(v, names) {
|
|
@@ -153,10 +160,14 @@ export const sqlSerializer = {
|
|
|
153
160
|
names.set(entity, name);
|
|
154
161
|
const extra = sqlFileReferences("clickhouse", objects);
|
|
155
162
|
const order = applyOrder(objects, names, extra);
|
|
163
|
+
const json = order.map((n) => objectJson(n, objects.get(n), names, extra.get(n)));
|
|
164
|
+
// The named collections the build references (#4395), each once, by name: a plan checks each exists.
|
|
165
|
+
const collections = [...new Set(json.flatMap((o) => o.namedCollections ?? []))].sort();
|
|
156
166
|
const doc = {
|
|
157
167
|
dialect: "clickhouse",
|
|
158
168
|
applyOrder: order,
|
|
159
|
-
|
|
169
|
+
...(collections.length > 0 ? { namedCollections: collections } : {}),
|
|
170
|
+
objects: json,
|
|
160
171
|
};
|
|
161
172
|
const ddl = order
|
|
162
173
|
.map((n) => `${objects.get(n).props.ddl};`)
|
|
@@ -13,7 +13,20 @@
|
|
|
13
13
|
* the file instead of writing it: exit 1, naming the file, when they differ.
|
|
14
14
|
*/
|
|
15
15
|
import type { CommandGroupContext } from "@intentius/chant/cli/command-group";
|
|
16
|
+
export interface ProjectLocation {
|
|
17
|
+
config: Awaited<ReturnType<typeof import("@intentius/chant/config").loadChantConfigUpward>>["config"];
|
|
18
|
+
projectDir: string;
|
|
19
|
+
sourceDir: string;
|
|
20
|
+
}
|
|
16
21
|
/** The file tsc would read instead of `path`: `sql-types.ts` beside `sql-types.d.ts`. */
|
|
17
22
|
export declare function shadowingSource(path: string): string | undefined;
|
|
23
|
+
/** The project the working directory belongs to: its config, its root and its source directory. */
|
|
24
|
+
export declare function loadProject(cwd: string): Promise<ProjectLocation>;
|
|
25
|
+
/**
|
|
26
|
+
* The fold build's entities: what `chant build` declares, `.sql` files and
|
|
27
|
+
* composite members included. Prints the build's errors and returns
|
|
28
|
+
* undefined when it fails.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildFolded(project: ProjectLocation, command: string, consequence: string): Promise<import("@intentius/chant").BuildResult | undefined>;
|
|
18
31
|
export declare function runTypes(ctx: CommandGroupContext): Promise<number>;
|
|
19
32
|
//# sourceMappingURL=sql-types-command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-types-command.d.ts","sourceRoot":"","sources":["../src/sql-types-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"sql-types-command.d.ts","sourceRoot":"","sources":["../src/sql-types-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAG9E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,cAAc,yBAAyB,EAAE,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACtG,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAoBD,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIhE;AAED,mGAAmG;AACnG,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAKvE;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,+DAe/F;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuCxE"}
|
|
@@ -43,37 +43,52 @@ export function shadowingSource(path) {
|
|
|
43
43
|
const source = `${path.slice(0, -".d.ts".length)}.ts`;
|
|
44
44
|
return existsSync(source) ? source : undefined;
|
|
45
45
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if ("error" in args) {
|
|
49
|
-
console.error(`${args.error}\n${USAGE}`);
|
|
50
|
-
return 1;
|
|
51
|
-
}
|
|
52
|
-
const cwd = process.cwd();
|
|
46
|
+
/** The project the working directory belongs to: its config, its root and its source directory. */
|
|
47
|
+
export async function loadProject(cwd) {
|
|
53
48
|
const { loadChantConfigUpward } = await import("@intentius/chant/config");
|
|
54
49
|
const { config, configPath } = await loadChantConfigUpward(cwd);
|
|
55
50
|
const projectDir = configPath ? dirname(configPath) : cwd;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
51
|
+
return { config, projectDir, sourceDir: resolve(projectDir, config.sourceDir ?? ".") };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The fold build's entities: what `chant build` declares, `.sql` files and
|
|
55
|
+
* composite members included. Prints the build's errors and returns
|
|
56
|
+
* undefined when it fails.
|
|
57
|
+
*/
|
|
58
|
+
export async function buildFolded(project, command, consequence) {
|
|
59
|
+
const { config, projectDir, sourceDir } = project;
|
|
63
60
|
const { build } = await import("@intentius/chant/build");
|
|
64
61
|
const { resolveBuildModes, resolveProjectBuildOptions } = await import("@intentius/chant/cli/build-options");
|
|
65
62
|
const { loadPlugins, resolveProjectLexicons } = await import("@intentius/chant/cli/plugins");
|
|
66
63
|
const { sqlSerializer } = await import("./serializer.js");
|
|
67
64
|
const plugins = await loadPlugins(await resolveProjectLexicons(projectDir, { lexicon: "sql" }));
|
|
68
|
-
// The fold build's entities: what `chant build` declares, `.sql` files and composite members included.
|
|
69
65
|
const options = resolveProjectBuildOptions({ config, configDir: projectDir, plugins, modes: resolveBuildModes(config, { fold: true }) });
|
|
70
66
|
const result = await build(sourceDir, [sqlSerializer], undefined, options);
|
|
71
67
|
if (result.errors.length > 0) {
|
|
72
68
|
for (const e of result.errors)
|
|
73
69
|
console.error(e instanceof Error ? e.message : String(e));
|
|
74
|
-
console.error(
|
|
70
|
+
console.error(`${command}: the build failed, so ${consequence}`);
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
export async function runTypes(ctx) {
|
|
76
|
+
const args = parseArgs(ctx.rawArgs);
|
|
77
|
+
if ("error" in args) {
|
|
78
|
+
console.error(`${args.error}\n${USAGE}`);
|
|
75
79
|
return 1;
|
|
76
80
|
}
|
|
81
|
+
const cwd = process.cwd();
|
|
82
|
+
const { config, projectDir, sourceDir } = await loadProject(cwd);
|
|
83
|
+
const output = args.output !== undefined ? resolve(cwd, args.output) : join(sourceDir, SQL_TYPES_FILE);
|
|
84
|
+
const shadow = shadowingSource(output);
|
|
85
|
+
if (shadow) {
|
|
86
|
+
console.error(`chant sql types: ${relative(cwd, shadow) || basename(shadow)} sits beside ${relative(cwd, output) || basename(output)}, and tsc reads it instead of the declarations; rename one`);
|
|
87
|
+
return 1;
|
|
88
|
+
}
|
|
89
|
+
const result = await buildFolded({ config, projectDir, sourceDir }, "chant sql types", "nothing was written");
|
|
90
|
+
if (!result)
|
|
91
|
+
return 1;
|
|
77
92
|
const text = renderSqlTypes(result.entities, { projectDir, config: config });
|
|
78
93
|
const shown = relative(cwd, output);
|
|
79
94
|
const named = shown && !shown.startsWith("..") ? shown : output;
|
package/dist/sql-types.d.ts
CHANGED
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
*/
|
|
31
31
|
import type { Declarable } from "@intentius/chant/declarable";
|
|
32
32
|
import type { SqlDialect } from "./dialects.js";
|
|
33
|
+
import { type PgProject } from "./lint/post-synth/postgres-names.js";
|
|
34
|
+
import type { OutputObject } from "./lint/post-synth/sql-helpers.js";
|
|
33
35
|
/** The file `chant sql types` writes, in the project's source directory. */
|
|
34
36
|
export declare const SQL_TYPES_FILE = "sql-types.d.ts";
|
|
35
37
|
/**
|
|
@@ -47,6 +49,26 @@ export interface RenderSqlTypesOptions {
|
|
|
47
49
|
/** The project's config: `sql.postgresMajor` for the catalog, `sql.dialect` when nothing is declared. */
|
|
48
50
|
config?: Record<string, unknown>;
|
|
49
51
|
}
|
|
52
|
+
/** The names a relation's `.columns` record holds at run time, in order. */
|
|
53
|
+
export declare const runtimeColumns: (entity: Declarable | undefined) => string[];
|
|
54
|
+
/** A view's column that passes one column through: that column's export and name. */
|
|
55
|
+
export declare function passthrough(o: OutputObject, name: string, quote: (c: string) => string): {
|
|
56
|
+
export: string;
|
|
57
|
+
column: string;
|
|
58
|
+
} | undefined;
|
|
59
|
+
/** A Postgres type's spelling, row type, and whether the type itself forbids NULL (a serial, a NOT NULL domain). */
|
|
60
|
+
export declare function pgType(p: PgProject, text: string | undefined, depth?: number): {
|
|
61
|
+
sqlType: string;
|
|
62
|
+
ts: string;
|
|
63
|
+
notNull: boolean;
|
|
64
|
+
};
|
|
65
|
+
/** The dialect a build's entities declare, else the config's, else ClickHouse. */
|
|
66
|
+
export declare function dialectOf(entities: ReadonlyMap<string, Declarable>, config: Record<string, unknown>): SqlDialect;
|
|
67
|
+
/** The build's sql output as `chant build` writes it: the objects, and the Postgres major they were built for. */
|
|
68
|
+
export declare function serializedObjects(entities: ReadonlyMap<string, Declarable>, config: Record<string, unknown>): {
|
|
69
|
+
objects: OutputObject[];
|
|
70
|
+
postgresMajor?: number;
|
|
71
|
+
};
|
|
50
72
|
/**
|
|
51
73
|
* The `sql-types.d.ts` for a build's entities: one module that augments the
|
|
52
74
|
* dialect's `SqlSchema` with each table, view and dictionary, in key order.
|
package/dist/sql-types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-types.d.ts","sourceRoot":"","sources":["../src/sql-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAW9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"sql-types.d.ts","sourceRoot":"","sources":["../src/sql-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAW9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK7C,OAAO,EAA6E,KAAK,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAC7I,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,4EAA4E;AAC5E,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAGpG;AAED,kGAAkG;AAClG,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EACzC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,qBAA0B,GAC/B,SAAS,GAAG,OAAO,GAAG,SAAS,CASjC;AAED,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAGjE,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,yGAAyG;IACzG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yGAAyG;IACzG,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AA2CD,4EAA4E;AAC5E,eAAO,MAAM,cAAc,GAAI,QAAQ,UAAU,GAAG,SAAS,KAAG,MAAM,EAA8E,CAAC;AAcrJ,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAQvI;AAoBD,oHAAoH;AACpH,wBAAgB,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,SAAI,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAwB3H;AAsHD,kFAAkF;AAClF,wBAAgB,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAMhH;AAED,kHAAkH;AAClH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,OAAO,EAAE,YAAY,EAAE,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAGjK;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,GAAE,qBAA0B,GAAG,MAAM,CAgClH"}
|