@rocicorp/zero 1.10.0-canary.2 → 1.10.0-canary.20
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/out/replicache/src/btree/read.d.ts +12 -1
- package/out/replicache/src/btree/read.d.ts.map +1 -1
- package/out/replicache/src/btree/read.js +24 -12
- package/out/replicache/src/btree/read.js.map +1 -1
- package/out/replicache/src/db/write.js.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js +27 -4
- package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/sqlite-store.d.ts +11 -0
- package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
- package/out/replicache/src/kv/sqlite-store.js +43 -3
- package/out/replicache/src/kv/sqlite-store.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +10 -0
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/transactions.d.ts.map +1 -1
- package/out/replicache/src/transactions.js +1 -1
- package/out/replicache/src/transactions.js.map +1 -1
- package/out/shared/src/error.d.ts +11 -0
- package/out/shared/src/error.d.ts.map +1 -1
- package/out/shared/src/error.js +35 -1
- package/out/shared/src/error.js.map +1 -1
- package/out/shared/src/hash.d.ts.map +1 -1
- package/out/shared/src/hash.js +105 -10
- package/out/shared/src/hash.js.map +1 -1
- package/out/shared/src/map.d.ts +7 -2
- package/out/shared/src/map.d.ts.map +1 -1
- package/out/shared/src/map.js.map +1 -1
- package/out/shared/src/promise-race.d.ts +14 -0
- package/out/shared/src/promise-race.d.ts.map +1 -1
- package/out/shared/src/promise-race.js +32 -1
- package/out/shared/src/promise-race.js.map +1 -1
- package/out/zero/package.js +2 -3
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +8 -1
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/normalize.d.ts +5 -0
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +16 -3
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +36 -7
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +121 -46
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/db/create.d.ts.map +1 -1
- package/out/zero-cache/src/db/create.js +4 -1
- package/out/zero-cache/src/db/create.js.map +1 -1
- package/out/zero-cache/src/db/index-predicate.d.ts +4 -0
- package/out/zero-cache/src/db/index-predicate.d.ts.map +1 -0
- package/out/zero-cache/src/db/index-predicate.js +46 -0
- package/out/zero-cache/src/db/index-predicate.js.map +1 -0
- package/out/zero-cache/src/db/lite-tables.d.ts +10 -2
- package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
- package/out/zero-cache/src/db/lite-tables.js +8 -3
- package/out/zero-cache/src/db/lite-tables.js.map +1 -1
- package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
- package/out/zero-cache/src/db/migration-lite.js +5 -3
- package/out/zero-cache/src/db/migration-lite.js.map +1 -1
- package/out/zero-cache/src/db/specs.d.ts +41 -0
- package/out/zero-cache/src/db/specs.d.ts.map +1 -1
- package/out/zero-cache/src/db/specs.js +30 -3
- package/out/zero-cache/src/db/specs.js.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.d.ts +5 -15
- package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.js +39 -73
- package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +27 -15
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +4 -4
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +8 -4
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +1 -1
- package/out/zero-cache/src/server/worker-urls.d.ts +0 -1
- package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-urls.js +1 -2
- package/out/zero-cache/src/server/worker-urls.js.map +1 -1
- package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
- package/out/zero-cache/src/services/analyze.js +1 -0
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts +12 -2
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +14 -3
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.js +10 -41
- package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts +3 -2
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +42 -16
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +34 -2
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +47 -19
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/decommission.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/decommission.js +20 -11
- package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +58 -80
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +20 -0
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +43 -3
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +24 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js +35 -5
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +1513 -229
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +2 -2
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts +19 -0
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +581 -0
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +15 -6
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +137 -20
- package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/published.js +82 -13
- package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +128 -21
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +5 -5
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +2 -0
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +3 -0
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts +1 -4
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +11 -18
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js +8 -3
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js +4 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.d.ts +34 -0
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.js +67 -0
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +2 -4
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +8 -2
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +34 -13
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +165 -36
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +4 -9
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.js +12 -3
- package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +11 -5
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/shard-sampling.d.ts +11 -0
- package/out/zero-cache/src/services/change-streamer/shard-sampling.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/shard-sampling.js +19 -0
- package/out/zero-cache/src/services/change-streamer/shard-sampling.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +11 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +38 -5
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts +25 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +95 -12
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.d.ts +83 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +417 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.d.ts +73 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js +157 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +8 -3
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +63 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +217 -49
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +8 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +10 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +29 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +154 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -0
- package/out/zero-cache/src/services/http-service.d.ts +1 -0
- package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/http-service.js +7 -3
- package/out/zero-cache/src/services/http-service.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +16 -7
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config-v5.yml +15 -1
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +131 -0
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -0
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +70 -0
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +1 -0
- package/out/zero-cache/src/services/litestream/litestream-controller.js +101 -0
- package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -0
- package/out/zero-cache/src/services/litestream/metrics.d.ts +1 -0
- package/out/zero-cache/src/services/litestream/metrics.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/metrics.js +4 -1
- package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-db.d.ts +10 -0
- package/out/zero-cache/src/services/replicator/change-log-db.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-db.js +15 -1
- package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +18 -21
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.js +2 -6
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.js +2 -2
- package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +3 -2
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +8 -6
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +27 -2
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js +3 -2
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +24 -5
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +3 -2
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +25 -17
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +14 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +3 -3
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +6 -2
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/downstream.d.ts +11 -0
- package/out/zero-cache/src/types/downstream.d.ts.map +1 -0
- package/out/zero-cache/src/types/pg.d.ts +15 -2
- package/out/zero-cache/src/types/pg.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg.js +21 -8
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/poke-chunk.d.ts +18 -0
- package/out/zero-cache/src/types/poke-chunk.d.ts.map +1 -0
- package/out/zero-cache/src/types/poke-chunk.js +57 -0
- package/out/zero-cache/src/types/poke-chunk.js.map +1 -0
- package/out/zero-cache/src/types/processes.js +1 -4
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/streams.d.ts +4 -9
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-cache/src/types/subscription.d.ts +2 -11
- package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
- package/out/zero-cache/src/types/subscription.js +4 -25
- package/out/zero-cache/src/types/subscription.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +22 -4
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +112 -14
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/replicator.d.ts +1 -0
- package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/workers/replicator.js +4 -2
- package/out/zero-cache/src/workers/replicator.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.js +46 -0
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +15 -0
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +44 -0
- package/out/zero-client/src/client/context.js.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.d.ts.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.js +19 -12
- package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
- package/out/zero-client/src/client/ivm-branch.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-poke-handler.d.ts +7 -2
- package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-poke-handler.js +52 -2
- package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.js +2 -1
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +98 -25
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-protocol/src/custom-queries.d.ts +1 -1
- package/out/zero-protocol/src/down.d.ts +1 -1
- package/out/zero-protocol/src/error.d.ts +4 -4
- package/out/zero-protocol/src/inspect-down.js +1 -1
- package/out/zero-protocol/src/mutate-server.d.ts +2 -2
- package/out/zero-protocol/src/poke.d.ts +89 -7
- package/out/zero-protocol/src/poke.d.ts.map +1 -1
- package/out/zero-protocol/src/poke.js +16 -8
- package/out/zero-protocol/src/poke.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +12 -7
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/push.d.ts +1 -1
- package/out/zero-protocol/src/query-server.d.ts +2 -2
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +5 -3
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js +8 -3
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/deferred-input.d.ts +44 -0
- package/out/zql/src/ivm/deferred-input.d.ts.map +1 -0
- package/out/zql/src/ivm/deferred-input.js +88 -0
- package/out/zql/src/ivm/deferred-input.js.map +1 -0
- package/out/zql/src/ivm/memory-source.d.ts +10 -2
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +19 -16
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/stream.d.ts +0 -1
- package/out/zql/src/ivm/stream.d.ts.map +1 -1
- package/out/zql/src/ivm/stream.js +1 -7
- package/out/zql/src/ivm/stream.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +11 -2
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +6 -1
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +6 -0
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +73 -10
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +22 -0
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.js +2 -1
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.js +1 -0
- package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts +1 -1
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +3 -2
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +2 -3
- package/out/zero-cache/src/server/backup-watermark-poller.js +0 -31
- package/out/zero-cache/src/server/backup-watermark-poller.js.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.d.ts +0 -57
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.js +0 -137
- package/out/zero-cache/src/services/litestream/vfs-watermark-poller.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAQjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAiB,KAAK,WAAW,EAAC,MAAM,6BAA6B,CAAC;AAY7E;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,UAAU,EACd,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAQjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAiB,KAAK,WAAW,EAAC,MAAM,6BAA6B,CAAC;AAY7E;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,UAAU,EACd,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,WAAW,EAClB,2BAA2B,UAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CAiBf;AAgOD,eAAO,MAAM,sBAAsB,QASwB,CAAC"}
|
|
@@ -10,13 +10,13 @@ import { runSchemaMigrations } from "../../../../db/migration.js";
|
|
|
10
10
|
/**
|
|
11
11
|
* Ensures that a shard is set up for initial sync.
|
|
12
12
|
*/
|
|
13
|
-
async function ensureShardSchema(lc, db, shard) {
|
|
13
|
+
async function ensureShardSchema(lc, db, shard, installPartialIndexTriggers = true) {
|
|
14
14
|
await runSchemaMigrations(lc, `upstream-shard-${shard.appID}`, upstreamSchema(shard), db, {
|
|
15
|
-
migrateSchema: (lc, tx) => setupTablesAndReplication(lc, tx, shard),
|
|
15
|
+
migrateSchema: (lc, tx) => setupTablesAndReplication(lc, tx, shard, installPartialIndexTriggers),
|
|
16
16
|
minSafeVersion: 1
|
|
17
|
-
}, getIncrementalMigrations(shard));
|
|
17
|
+
}, getIncrementalMigrations(shard, installPartialIndexTriggers));
|
|
18
18
|
}
|
|
19
|
-
function getIncrementalMigrations(shard) {
|
|
19
|
+
function getIncrementalMigrations(shard, installPartialIndexTriggers) {
|
|
20
20
|
const shardConfigTable = `${upstreamSchema(shard)}.shardConfig`;
|
|
21
21
|
return {
|
|
22
22
|
6: { migrateSchema: () => {
|
|
@@ -129,14 +129,23 @@ function getIncrementalMigrations(shard) {
|
|
|
129
129
|
ALTER TABLE ${sql(upstreamSchema(shard))}.replicas
|
|
130
130
|
ADD COLUMN "backupV5" BOOL DEFAULT false;
|
|
131
131
|
`;
|
|
132
|
-
} }
|
|
132
|
+
} },
|
|
133
|
+
...installPartialIndexTriggers ? { 26: { migrateSchema: async (lc, sql) => {
|
|
134
|
+
const [{ publications }] = await sql`
|
|
135
|
+
SELECT publications FROM ${sql(shardConfigTable)}`;
|
|
136
|
+
await setupTriggers(lc, sql, {
|
|
137
|
+
...shard,
|
|
138
|
+
publications
|
|
139
|
+
});
|
|
140
|
+
lc.info?.(`Upgraded DDL event triggers`);
|
|
141
|
+
} } } : {}
|
|
133
142
|
};
|
|
134
143
|
}
|
|
135
144
|
Object.keys(getIncrementalMigrations({
|
|
136
145
|
appID: "unused",
|
|
137
146
|
shardNum: 0,
|
|
138
147
|
publications: ["foo"]
|
|
139
|
-
})).reduce((prev, curr) => Math.max(prev, parseInt(curr)), 0);
|
|
148
|
+
}, true)).reduce((prev, curr) => Math.max(prev, parseInt(curr)), 0);
|
|
140
149
|
//#endregion
|
|
141
150
|
export { ensureShardSchema };
|
|
142
151
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","names":[],"sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/init.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert} from '../../../../../../shared/src/asserts.ts';\nimport * as v from '../../../../../../shared/src/valita.ts';\nimport {\n runSchemaMigrations,\n type IncrementalMigrationMap,\n type Migration,\n} from '../../../../db/migration.ts';\nimport type {PostgresDB} from '../../../../types/pg.ts';\nimport {upstreamSchema, type ShardConfig} from '../../../../types/shards.ts';\nimport {id} from '../../../../types/sql.ts';\nimport {AutoResetSignal} from '../../../change-streamer/schema/tables.ts';\nimport {publishedSchema} from './published.ts';\nimport {\n getMutationsTableDefinition,\n legacyReplicationSlot,\n metadataPublicationName,\n setupTablesAndReplication,\n setupTriggers,\n} from './shard.ts';\n\n/**\n * Ensures that a shard is set up for initial sync.\n */\nexport async function ensureShardSchema(\n lc: LogContext,\n db: PostgresDB,\n shard: ShardConfig,\n): Promise<void> {\n const initialSetup: Migration = {\n migrateSchema: (lc, tx) => setupTablesAndReplication(lc, tx, shard),\n minSafeVersion: 1,\n };\n await runSchemaMigrations(\n lc,\n `upstream-shard-${shard.appID}`,\n upstreamSchema(shard),\n db,\n initialSetup,\n // The incremental migration of any existing replicas will be replaced by\n // the incoming replica being synced, so the replicaVersion here is\n // unnecessary.\n getIncrementalMigrations(shard),\n );\n}\n\nfunction getIncrementalMigrations(shard: ShardConfig): IncrementalMigrationMap {\n const shardConfigTable = `${upstreamSchema(shard)}.shardConfig`;\n\n return {\n 6: {\n migrateSchema: () => {\n throw new AutoResetSignal('resetting to upgrade shard schema');\n },\n },\n\n // v7: Updates the DDL event trigger protocol to v2, and adds support for\n // ALTER SCHEMA x RENAME TO y\n // (migration logic subsumbed by v23)\n\n // v8: Adds support for non-disruptive resyncs, which tracks multiple\n // replicas with different slot names.\n 8: {\n migrateSchema: async (lc, sql) => {\n const legacyShardConfigSchema = v.object({\n replicaVersion: v.string().nullable(),\n initialSchema: publishedSchema.nullable(),\n });\n const result = await sql`\n SELECT \"replicaVersion\", \"initialSchema\" FROM ${sql(shardConfigTable)}`;\n assert(\n result.length === 1,\n () => `Expected exactly one shardConfig row, got ${result.length}`,\n );\n const {replicaVersion, initialSchema} = v.parse(\n result[0],\n legacyShardConfigSchema,\n 'passthrough',\n );\n\n await Promise.all([\n sql`\n CREATE TABLE ${sql(upstreamSchema(shard))}.replicas (\n \"slot\" TEXT PRIMARY KEY,\n \"version\" TEXT NOT NULL,\n \"initialSchema\" JSON NOT NULL\n );\n `,\n sql`\n INSERT INTO ${sql(upstreamSchema(shard))}.replicas ${sql({\n slot: legacyReplicationSlot(shard),\n version: replicaVersion,\n initialSchema,\n })}\n `,\n sql`\n ALTER TABLE ${sql(shardConfigTable)} DROP \"replicaVersion\", DROP \"initialSchema\"\n `,\n ]);\n lc.info?.(`Upgraded schema to support non-disruptive resyncs`);\n },\n },\n\n // v9: Fixes field ordering of compound indexes. This incremental migration\n // only fixes indexes resulting from new schema changes. A full resync is\n // required to fix existing indexes.\n //\n // The migration has been subsumed by the identical logic for migrating\n // to v12 (i.e. a trigger upgrade).\n\n // Adds the `mutations` table used to track mutation results.\n 10: {\n migrateSchema: async (lc, sql) => {\n await sql.unsafe(/*sql*/ `\n ${getMutationsTableDefinition(upstreamSchema(shard))}\n ALTER PUBLICATION ${id(metadataPublicationName(shard.appID, shard.shardNum))} ADD TABLE ${id(upstreamSchema(shard))}.\"mutations\";\n `);\n lc.info?.('Upgraded schema with new mutations table');\n },\n },\n\n // v11: Formerly dropped the schemaVersions table, but restored in the v13\n // migration for rollback safety.\n\n // v12: Upgrade DDL trigger to query schemaOID, needed information for auto-backfill.\n // (subsumed by v14)\n\n // Recreates the legacy schemaVersions table that was prematurely dropped\n // in the (former) v11 migration. It needs to remain present for at least one\n // release in order to be rollback safe.\n //\n // TODO: Drop the table once a release that no longer reads the table has\n // been rolled out.\n 13: {\n migrateSchema: async (_, sql) => {\n await sql`\n CREATE TABLE IF NOT EXISTS ${sql(upstreamSchema(shard))}.\"schemaVersions\" (\n \"minSupportedVersion\" INT4,\n \"maxSupportedVersion\" INT4,\n \"lock\" BOOL PRIMARY KEY DEFAULT true CHECK (lock)\n );`;\n await sql`\n INSERT INTO ${sql(upstreamSchema(shard))}.\"schemaVersions\" \n (\"lock\", \"minSupportedVersion\", \"maxSupportedVersion\")\n VALUES (true, 1, 1)\n ON CONFLICT DO NOTHING;\n `;\n },\n },\n\n // v14: Upgrade DDL trigger to log more info to PG logs.\n // (subsumed by v16)\n\n // Add initialSyncContext column to replicas table.\n 15: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas\n ADD COLUMN \"initialSyncContext\" JSON,\n ADD COLUMN \"subscriberContext\" JSON\n `;\n },\n },\n\n // v16: Upgrade DDL trigger to fire on all ALTER TABLE statements\n // to catch the *removal* of a table from the published set.\n // v17 (1.0.0): Upgrade DDL triggers to support the COMMENT ON PUBLICATION hook for\n // working around the lack of event trigger support for PUBLICATION\n // changes in supabase.\n // This also adds forwards-compatible support for hierarchical logical\n // message prefixes and unknown ddl event types.\n // v18: Pure refactoring of event trigger code.\n // v19 (1.4.0): Correctly handle concurrently issued DDL statements.\n // v20 (1.4.0): Handle nested DDL triggers\n // v21 (1.5.0): Handle cross-transaction DDL operations (i.e. concurrent\n // index operations), and support manual invocation of update_schemas().\n\n 22: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ALTER \"initialSchema\" DROP NOT NULL;\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n DROP CONSTRAINT replicas_pkey;\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN id TEXT PRIMARY KEY DEFAULT replace(gen_random_uuid()::text, '-', '');\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN rank BIGSERIAL;\n `;\n },\n },\n\n // v23 (1.6.0): Event triggers: Handle the case where current_query()\n // returns NULL. Add more logging to debug unexpected messages\n 23: {\n migrateSchema: async (lc, sql) => {\n const [{publications}] = await sql<{publications: string[]}[]>`\n SELECT publications FROM ${sql(shardConfigTable)}`;\n await setupTriggers(lc, sql, {...shard, publications});\n lc.info?.(`Upgraded DDL event triggers`);\n },\n },\n\n // v24 (1.10.0):\n // - adds the \"backupPath\" column for per-replica backups.\n // - adds the \"generation\" column to replace \"version\".\n 24: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN \"backupPath\" TEXT;\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN \"generation\" TEXT;\n `;\n },\n\n migrateData: async (_, sql) => {\n // Backfill the \"generation\" column to eventually replace \"version\"\n await sql`\n UPDATE ${sql(upstreamSchema(shard))}.replicas SET \"generation\" = \"version\";\n `;\n },\n },\n\n // v25 (1.10.0):\n // - adds the \"backupV5\" column to signal the current semantics\n // of the replication slot's confirmed_flush_lsn with respect to what\n // has been backed up.\n 25: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN \"backupV5\" BOOL DEFAULT false;\n `;\n },\n },\n };\n}\n\n// Referenced in tests.\nexport const CURRENT_SCHEMA_VERSION = Object.keys(\n getIncrementalMigrations({\n appID: 'unused',\n shardNum: 0,\n publications: ['foo'],\n }),\n).reduce((prev, curr) => Math.max(prev, parseInt(curr)), 0);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"init.js","names":[],"sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/init.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert} from '../../../../../../shared/src/asserts.ts';\nimport * as v from '../../../../../../shared/src/valita.ts';\nimport {\n runSchemaMigrations,\n type IncrementalMigrationMap,\n type Migration,\n} from '../../../../db/migration.ts';\nimport type {PostgresDB} from '../../../../types/pg.ts';\nimport {upstreamSchema, type ShardConfig} from '../../../../types/shards.ts';\nimport {id} from '../../../../types/sql.ts';\nimport {AutoResetSignal} from '../../../change-streamer/schema/tables.ts';\nimport {publishedSchema} from './published.ts';\nimport {\n getMutationsTableDefinition,\n legacyReplicationSlot,\n metadataPublicationName,\n setupTablesAndReplication,\n setupTriggers,\n} from './shard.ts';\n\n/**\n * Ensures that a shard is set up for initial sync.\n */\nexport async function ensureShardSchema(\n lc: LogContext,\n db: PostgresDB,\n shard: ShardConfig,\n installPartialIndexTriggers = true,\n): Promise<void> {\n const initialSetup: Migration = {\n migrateSchema: (lc, tx) =>\n setupTablesAndReplication(lc, tx, shard, installPartialIndexTriggers),\n minSafeVersion: 1,\n };\n await runSchemaMigrations(\n lc,\n `upstream-shard-${shard.appID}`,\n upstreamSchema(shard),\n db,\n initialSetup,\n // The incremental migration of any existing replicas will be replaced by\n // the incoming replica being synced, so the replicaVersion here is\n // unnecessary.\n getIncrementalMigrations(shard, installPartialIndexTriggers),\n );\n}\n\nfunction getIncrementalMigrations(\n shard: ShardConfig,\n installPartialIndexTriggers: boolean,\n): IncrementalMigrationMap {\n const shardConfigTable = `${upstreamSchema(shard)}.shardConfig`;\n\n return {\n 6: {\n migrateSchema: () => {\n throw new AutoResetSignal('resetting to upgrade shard schema');\n },\n },\n\n // v7: Updates the DDL event trigger protocol to v2, and adds support for\n // ALTER SCHEMA x RENAME TO y\n // (migration logic subsumbed by v23)\n\n // v8: Adds support for non-disruptive resyncs, which tracks multiple\n // replicas with different slot names.\n 8: {\n migrateSchema: async (lc, sql) => {\n const legacyShardConfigSchema = v.object({\n replicaVersion: v.string().nullable(),\n initialSchema: publishedSchema.nullable(),\n });\n const result = await sql`\n SELECT \"replicaVersion\", \"initialSchema\" FROM ${sql(shardConfigTable)}`;\n assert(\n result.length === 1,\n () => `Expected exactly one shardConfig row, got ${result.length}`,\n );\n const {replicaVersion, initialSchema} = v.parse(\n result[0],\n legacyShardConfigSchema,\n 'passthrough',\n );\n\n await Promise.all([\n sql`\n CREATE TABLE ${sql(upstreamSchema(shard))}.replicas (\n \"slot\" TEXT PRIMARY KEY,\n \"version\" TEXT NOT NULL,\n \"initialSchema\" JSON NOT NULL\n );\n `,\n sql`\n INSERT INTO ${sql(upstreamSchema(shard))}.replicas ${sql({\n slot: legacyReplicationSlot(shard),\n version: replicaVersion,\n initialSchema,\n })}\n `,\n sql`\n ALTER TABLE ${sql(shardConfigTable)} DROP \"replicaVersion\", DROP \"initialSchema\"\n `,\n ]);\n lc.info?.(`Upgraded schema to support non-disruptive resyncs`);\n },\n },\n\n // v9: Fixes field ordering of compound indexes. This incremental migration\n // only fixes indexes resulting from new schema changes. A full resync is\n // required to fix existing indexes.\n //\n // The migration has been subsumed by the identical logic for migrating\n // to v12 (i.e. a trigger upgrade).\n\n // Adds the `mutations` table used to track mutation results.\n 10: {\n migrateSchema: async (lc, sql) => {\n await sql.unsafe(/*sql*/ `\n ${getMutationsTableDefinition(upstreamSchema(shard))}\n ALTER PUBLICATION ${id(metadataPublicationName(shard.appID, shard.shardNum))} ADD TABLE ${id(upstreamSchema(shard))}.\"mutations\";\n `);\n lc.info?.('Upgraded schema with new mutations table');\n },\n },\n\n // v11: Formerly dropped the schemaVersions table, but restored in the v13\n // migration for rollback safety.\n\n // v12: Upgrade DDL trigger to query schemaOID, needed information for auto-backfill.\n // (subsumed by v14)\n\n // Recreates the legacy schemaVersions table that was prematurely dropped\n // in the (former) v11 migration. It needs to remain present for at least one\n // release in order to be rollback safe.\n //\n // TODO: Drop the table once a release that no longer reads the table has\n // been rolled out.\n 13: {\n migrateSchema: async (_, sql) => {\n await sql`\n CREATE TABLE IF NOT EXISTS ${sql(upstreamSchema(shard))}.\"schemaVersions\" (\n \"minSupportedVersion\" INT4,\n \"maxSupportedVersion\" INT4,\n \"lock\" BOOL PRIMARY KEY DEFAULT true CHECK (lock)\n );`;\n await sql`\n INSERT INTO ${sql(upstreamSchema(shard))}.\"schemaVersions\" \n (\"lock\", \"minSupportedVersion\", \"maxSupportedVersion\")\n VALUES (true, 1, 1)\n ON CONFLICT DO NOTHING;\n `;\n },\n },\n\n // v14: Upgrade DDL trigger to log more info to PG logs.\n // (subsumed by v16)\n\n // Add initialSyncContext column to replicas table.\n 15: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas\n ADD COLUMN \"initialSyncContext\" JSON,\n ADD COLUMN \"subscriberContext\" JSON\n `;\n },\n },\n\n // v16: Upgrade DDL trigger to fire on all ALTER TABLE statements\n // to catch the *removal* of a table from the published set.\n // v17 (1.0.0): Upgrade DDL triggers to support the COMMENT ON PUBLICATION hook for\n // working around the lack of event trigger support for PUBLICATION\n // changes in supabase.\n // This also adds forwards-compatible support for hierarchical logical\n // message prefixes and unknown ddl event types.\n // v18: Pure refactoring of event trigger code.\n // v19 (1.4.0): Correctly handle concurrently issued DDL statements.\n // v20 (1.4.0): Handle nested DDL triggers\n // v21 (1.5.0): Handle cross-transaction DDL operations (i.e. concurrent\n // index operations), and support manual invocation of update_schemas().\n\n 22: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ALTER \"initialSchema\" DROP NOT NULL;\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n DROP CONSTRAINT replicas_pkey;\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN id TEXT PRIMARY KEY DEFAULT replace(gen_random_uuid()::text, '-', '');\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN rank BIGSERIAL;\n `;\n },\n },\n\n // v23 (1.6.0): Event triggers: Handle the case where current_query()\n // returns NULL. Add more logging to debug unexpected messages\n 23: {\n migrateSchema: async (lc, sql) => {\n const [{publications}] = await sql<{publications: string[]}[]>`\n SELECT publications FROM ${sql(shardConfigTable)}`;\n await setupTriggers(lc, sql, {...shard, publications});\n lc.info?.(`Upgraded DDL event triggers`);\n },\n },\n\n // v24 (1.10.0):\n // - adds the \"backupPath\" column for per-replica backups.\n // - adds the \"generation\" column to replace \"version\".\n 24: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN \"backupPath\" TEXT;\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN \"generation\" TEXT;\n `;\n },\n\n migrateData: async (_, sql) => {\n // Backfill the \"generation\" column to eventually replace \"version\"\n await sql`\n UPDATE ${sql(upstreamSchema(shard))}.replicas SET \"generation\" = \"version\";\n `;\n },\n },\n\n // v25 (1.10.0):\n // - adds the \"backupV5\" column to signal the current semantics\n // of the replication slot's confirmed_flush_lsn with respect to what\n // has been backed up.\n 25: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN \"backupV5\" BOOL DEFAULT false;\n `;\n },\n },\n\n ...(installPartialIndexTriggers\n ? {\n // v26: Upgrade the DDL event triggers to include partial indexes in\n // schema snapshots. Note that setupTriggers() also refreshes the\n // stored \"publishedSchema\" so that the change in format does not\n // manifest as a spurious schema change.\n 26: {\n migrateSchema: async (lc, sql) => {\n const [{publications}] = await sql<{publications: string[]}[]>`\n SELECT publications FROM ${sql(shardConfigTable)}`;\n await setupTriggers(lc, sql, {...shard, publications});\n lc.info?.(`Upgraded DDL event triggers`);\n },\n },\n }\n : {}),\n };\n}\n\n// Referenced in tests.\nexport const CURRENT_SCHEMA_VERSION = Object.keys(\n getIncrementalMigrations(\n {\n appID: 'unused',\n shardNum: 0,\n publications: ['foo'],\n },\n true,\n ),\n).reduce((prev, curr) => Math.max(prev, parseInt(curr)), 0);\n"],"mappings":";;;;;;;;;;;;AAwBA,eAAsB,kBACpB,IACA,IACA,OACA,8BAA8B,MACf;CAMf,MAAM,oBACJ,IACA,kBAAkB,MAAM,SACxB,eAAe,KAAK,GACpB,IACA;EATA,gBAAgB,IAAI,OAClB,0BAA0B,IAAI,IAAI,OAAO,2BAA2B;EACtE,gBAAgB;CAOhB,GAIA,yBAAyB,OAAO,2BAA2B,CAC7D;AACF;AAEA,SAAS,yBACP,OACA,6BACyB;CACzB,MAAM,mBAAmB,GAAG,eAAe,KAAK,EAAE;CAElD,OAAO;EACL,GAAG,EACD,qBAAqB;GACnB,MAAM,IAAI,gBAAgB,mCAAmC;EAC/D,EACF;EAQA,GAAG,EACD,eAAe,OAAO,IAAI,QAAQ;GAChC,MAAM,0BAA0B,eAAE,OAAO;IACvC,gBAAgB,eAAE,OAAO,EAAE,SAAS;IACpC,eAAe,gBAAgB,SAAS;GAC1C,CAAC;GACD,MAAM,SAAS,MAAM,GAAG;0DAC0B,IAAI,gBAAgB;GACtE,OACE,OAAO,WAAW,SACZ,6CAA6C,OAAO,QAC5D;GACA,MAAM,EAAC,gBAAgB,kBAAiB,MACtC,OAAO,IACP,yBACA,aACF;GAEA,MAAM,QAAQ,IAAI;IAChB,GAAG;yBACY,IAAI,eAAe,KAAK,CAAC,EAAE;;;;;;IAM1C,GAAG;wBACW,IAAI,eAAe,KAAK,CAAC,EAAE,YAAY,IAAI;KACvD,MAAM,sBAAsB,KAAK;KACjC,SAAS;KACT;IACF,CAAC,EAAE;;IAEH,GAAG;wBACW,IAAI,gBAAgB,EAAE;;GAEtC,CAAC;GACD,GAAG,OAAO,mDAAmD;EAC/D,EACF;EAUA,IAAI,EACF,eAAe,OAAO,IAAI,QAAQ;GAChC,MAAM,IAAI,OAAe;YACrB,4BAA4B,eAAe,KAAK,CAAC,EAAE;8BACjC,GAAG,wBAAwB,MAAM,OAAO,MAAM,QAAQ,CAAC,EAAE,aAAa,GAAG,eAAe,KAAK,CAAC,EAAE;SACrH;GACD,GAAG,OAAO,0CAA0C;EACtD,EACF;EAcA,IAAI,EACF,eAAe,OAAO,GAAG,QAAQ;GAC/B,MAAM,GAAG;uCACsB,IAAI,eAAe,KAAK,CAAC,EAAE;;;;;GAK1D,MAAM,GAAG;wBACO,IAAI,eAAe,KAAK,CAAC,EAAE;;;;;EAK7C,EACF;EAMA,IAAI,EACF,eAAe,OAAO,GAAG,QAAQ;GAC/B,MAAM,GAAG;wBACO,IAAI,eAAe,KAAK,CAAC,EAAE;;;;EAI7C,EACF;EAeA,IAAI,EACF,eAAe,OAAO,GAAG,QAAQ;GAC/B,MAAM,GAAG;wBACO,IAAI,eAAe,KAAK,CAAC,EAAE;;;GAG3C,MAAM,GAAG;wBACO,IAAI,eAAe,KAAK,CAAC,EAAE;;;GAG3C,MAAM,GAAG;wBACO,IAAI,eAAe,KAAK,CAAC,EAAE;;;GAG3C,MAAM,GAAG;wBACO,IAAI,eAAe,KAAK,CAAC,EAAE;;;EAG7C,EACF;EAIA,IAAI,EACF,eAAe,OAAO,IAAI,QAAQ;GAChC,MAAM,CAAC,EAAC,kBAAiB,MAAM,GAA+B;qCACjC,IAAI,gBAAgB;GACjD,MAAM,cAAc,IAAI,KAAK;IAAC,GAAG;IAAO;GAAY,CAAC;GACrD,GAAG,OAAO,6BAA6B;EACzC,EACF;EAKA,IAAI;GACF,eAAe,OAAO,GAAG,QAAQ;IAC/B,MAAM,GAAG;wBACO,IAAI,eAAe,KAAK,CAAC,EAAE;;;IAG3C,MAAM,GAAG;wBACO,IAAI,eAAe,KAAK,CAAC,EAAE;;;GAG7C;GAEA,aAAa,OAAO,GAAG,QAAQ;IAE7B,MAAM,GAAG;mBACE,IAAI,eAAe,KAAK,CAAC,EAAE;;GAExC;EACF;EAMA,IAAI,EACF,eAAe,OAAO,GAAG,QAAQ;GAC/B,MAAM,GAAG;wBACO,IAAI,eAAe,KAAK,CAAC,EAAE;;;EAG7C,EACF;EAEA,GAAI,8BACA,EAKE,IAAI,EACF,eAAe,OAAO,IAAI,QAAQ;GAChC,MAAM,CAAC,EAAC,kBAAiB,MAAM,GAA+B;2CACjC,IAAI,gBAAgB;GACjD,MAAM,cAAc,IAAI,KAAK;IAAC,GAAG;IAAO;GAAY,CAAC;GACrD,GAAG,OAAO,6BAA6B;EACzC,EACF,EACF,IACA,CAAC;CACP;AACF;AAGsC,OAAO,KAC3C,yBACE;CACE,OAAO;CACP,UAAU;CACV,cAAc,CAAC,KAAK;AACtB,GACA,IACF,CACF,EAAE,QAAQ,MAAM,SAAS,KAAK,IAAI,MAAM,SAAS,IAAI,CAAC,GAAG,CAAC"}
|
|
@@ -1,38 +1,155 @@
|
|
|
1
|
+
import type { LogContext } from '@rocicorp/logger';
|
|
1
2
|
import type postgres from 'postgres';
|
|
2
3
|
import * as v from '../../../../../../shared/src/valita.ts';
|
|
3
|
-
|
|
4
|
+
import { type UnsupportedPredicateReason } from './index-predicate.ts';
|
|
5
|
+
export declare function publishedSchemaQuery(publications: readonly string[], includePartialIndexes?: boolean): string;
|
|
6
|
+
export type SkippedIndexDiagnostic = {
|
|
7
|
+
readonly schema: string;
|
|
8
|
+
readonly index: string;
|
|
9
|
+
readonly predicate: string;
|
|
10
|
+
readonly reason: UnsupportedPredicateReason;
|
|
11
|
+
};
|
|
12
|
+
export declare function getSkippedIndexDiagnostics(schema: PublishedSchema): readonly SkippedIndexDiagnostic[];
|
|
13
|
+
export declare function warnForSkippedIndexes(lc: LogContext, schema: PublishedSchema, warned?: Set<string>): void;
|
|
4
14
|
export declare const publishedSchema: v.Type<{
|
|
5
15
|
indexes: {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
readonly predicate?: {
|
|
17
|
+
readonly type: "and" | "or";
|
|
18
|
+
readonly conditions: readonly (/*elided*/ any | {
|
|
19
|
+
readonly type: "not";
|
|
20
|
+
readonly condition: /*elided*/ any | /*elided*/ any | {
|
|
21
|
+
readonly type: "null-test";
|
|
22
|
+
readonly column: string;
|
|
23
|
+
readonly op: "IS NULL" | "IS NOT NULL";
|
|
24
|
+
} | {
|
|
25
|
+
readonly type: "comparison";
|
|
26
|
+
readonly column: string;
|
|
27
|
+
readonly op: "=" | "<>" | "<" | "<=" | ">" | ">=";
|
|
28
|
+
readonly value: {
|
|
29
|
+
readonly type: "boolean";
|
|
30
|
+
readonly value: boolean;
|
|
31
|
+
} | {
|
|
32
|
+
readonly type: "integer";
|
|
33
|
+
readonly value: string;
|
|
34
|
+
} | {
|
|
35
|
+
readonly type: "string";
|
|
36
|
+
readonly value: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
} | {
|
|
40
|
+
readonly type: "null-test";
|
|
41
|
+
readonly column: string;
|
|
42
|
+
readonly op: "IS NULL" | "IS NOT NULL";
|
|
43
|
+
} | {
|
|
44
|
+
readonly type: "comparison";
|
|
45
|
+
readonly column: string;
|
|
46
|
+
readonly op: "=" | "<>" | "<" | "<=" | ">" | ">=";
|
|
47
|
+
readonly value: {
|
|
48
|
+
readonly type: "boolean";
|
|
49
|
+
readonly value: boolean;
|
|
50
|
+
} | {
|
|
51
|
+
readonly type: "integer";
|
|
52
|
+
readonly value: string;
|
|
53
|
+
} | {
|
|
54
|
+
readonly type: "string";
|
|
55
|
+
readonly value: string;
|
|
56
|
+
};
|
|
57
|
+
})[];
|
|
58
|
+
} | {
|
|
59
|
+
readonly type: "not";
|
|
60
|
+
readonly condition: {
|
|
61
|
+
readonly type: "and" | "or";
|
|
62
|
+
readonly conditions: readonly (/*elided*/ any | /*elided*/ any | {
|
|
63
|
+
readonly type: "null-test";
|
|
64
|
+
readonly column: string;
|
|
65
|
+
readonly op: "IS NULL" | "IS NOT NULL";
|
|
66
|
+
} | {
|
|
67
|
+
readonly type: "comparison";
|
|
68
|
+
readonly column: string;
|
|
69
|
+
readonly op: "=" | "<>" | "<" | "<=" | ">" | ">=";
|
|
70
|
+
readonly value: {
|
|
71
|
+
readonly type: "boolean";
|
|
72
|
+
readonly value: boolean;
|
|
73
|
+
} | {
|
|
74
|
+
readonly type: "integer";
|
|
75
|
+
readonly value: string;
|
|
76
|
+
} | {
|
|
77
|
+
readonly type: "string";
|
|
78
|
+
readonly value: string;
|
|
79
|
+
};
|
|
80
|
+
})[];
|
|
81
|
+
} | /*elided*/ any | {
|
|
82
|
+
readonly type: "null-test";
|
|
83
|
+
readonly column: string;
|
|
84
|
+
readonly op: "IS NULL" | "IS NOT NULL";
|
|
85
|
+
} | {
|
|
86
|
+
readonly type: "comparison";
|
|
87
|
+
readonly column: string;
|
|
88
|
+
readonly op: "=" | "<>" | "<" | "<=" | ">" | ">=";
|
|
89
|
+
readonly value: {
|
|
90
|
+
readonly type: "boolean";
|
|
91
|
+
readonly value: boolean;
|
|
92
|
+
} | {
|
|
93
|
+
readonly type: "integer";
|
|
94
|
+
readonly value: string;
|
|
95
|
+
} | {
|
|
96
|
+
readonly type: "string";
|
|
97
|
+
readonly value: string;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
} | {
|
|
101
|
+
readonly type: "null-test";
|
|
102
|
+
readonly column: string;
|
|
103
|
+
readonly op: "IS NULL" | "IS NOT NULL";
|
|
104
|
+
} | {
|
|
105
|
+
readonly type: "comparison";
|
|
106
|
+
readonly column: string;
|
|
107
|
+
readonly op: "=" | "<>" | "<" | "<=" | ">" | ">=";
|
|
108
|
+
readonly value: {
|
|
109
|
+
readonly type: "boolean";
|
|
110
|
+
readonly value: boolean;
|
|
111
|
+
} | {
|
|
112
|
+
readonly type: "integer";
|
|
113
|
+
readonly value: string;
|
|
114
|
+
} | {
|
|
115
|
+
readonly type: "string";
|
|
116
|
+
readonly value: string;
|
|
117
|
+
};
|
|
118
|
+
} | undefined;
|
|
119
|
+
readonly isReplicaIdentity?: boolean | undefined;
|
|
120
|
+
readonly isPrimaryKey?: boolean | undefined;
|
|
121
|
+
readonly isImmediate?: boolean | undefined;
|
|
122
|
+
readonly name: string;
|
|
123
|
+
readonly columns: {
|
|
124
|
+
readonly [x: string]: "ASC" | "DESC";
|
|
125
|
+
};
|
|
126
|
+
readonly schema: string;
|
|
127
|
+
readonly tableName: string;
|
|
128
|
+
readonly unique: boolean;
|
|
14
129
|
}[];
|
|
15
130
|
tables: {
|
|
16
131
|
replicaIdentityColumns: string[];
|
|
132
|
+
columns: {
|
|
133
|
+
[k: string]: {
|
|
134
|
+
pgTypeClass?: "e" | "d" | "b" | "c" | "p" | "r" | "m" | undefined;
|
|
135
|
+
elemPgTypeClass?: "e" | "d" | "b" | "c" | "p" | "r" | "m" | null | undefined;
|
|
136
|
+
characterMaximumLength?: number | null | undefined;
|
|
137
|
+
notNull?: boolean | null | undefined;
|
|
138
|
+
dflt?: string | null | undefined;
|
|
139
|
+
pos: number;
|
|
140
|
+
dataType: string;
|
|
141
|
+
typeOID: number;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
17
144
|
primaryKey?: string[] | undefined;
|
|
18
145
|
schemaOID?: number | undefined;
|
|
19
146
|
replicaIdentity?: "n" | "d" | "f" | "i" | undefined;
|
|
20
147
|
name: string;
|
|
21
148
|
schema: string;
|
|
22
|
-
oid: number;
|
|
23
|
-
columns: Record<string, {
|
|
24
|
-
pgTypeClass?: "e" | "d" | "b" | "c" | "p" | "r" | "m" | undefined;
|
|
25
|
-
elemPgTypeClass?: "e" | "d" | "b" | "c" | "p" | "r" | "m" | null | undefined;
|
|
26
|
-
characterMaximumLength?: number | null | undefined;
|
|
27
|
-
notNull?: boolean | null | undefined;
|
|
28
|
-
dflt?: string | null | undefined;
|
|
29
|
-
pos: number;
|
|
30
|
-
dataType: string;
|
|
31
|
-
typeOID: number;
|
|
32
|
-
}>;
|
|
33
149
|
publications: Record<string, {
|
|
34
150
|
rowFilter: string | null;
|
|
35
151
|
}>;
|
|
152
|
+
oid: number;
|
|
36
153
|
}[];
|
|
37
154
|
}>;
|
|
38
155
|
export type PublishedSchema = v.Infer<typeof publishedSchema>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"published.d.ts","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/published.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"published.d.ts","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/published.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AAIrC,OAAO,KAAK,CAAC,MAAM,wCAAwC,CAAC;AAc5D,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,sBAAsB,CAAC;AAE9B,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,qBAAqB,UAAO,UA+K7B;AAcD,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC;CAC7C,CAAC;AAMF,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,eAAe,GACtB,SAAS,sBAAsB,EAAE,CAEnC;AAED,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,eAAe,EACvB,MAAM,GAAE,GAAG,CAAC,MAAM,CAAa,GAC9B,IAAI,CAWN;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4FxB,CAAC;AAEL,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,MAAM,MAAM,iCAAiC,GAC3C,eAAe,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAUpC,QAAA,MAAM,wBAAwB;;;;;;cAA6B,CAAC;AAE5D,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG;IAC9C,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;CACxD,CAAC;AAEF;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,QAAQ,CAAC,GAAG,EACjB,YAAY,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,eAAe,CAAC,CAsD1B"}
|
|
@@ -2,13 +2,15 @@ import { assert } from "../../../../../../shared/src/asserts.js";
|
|
|
2
2
|
import { parse, valita_exports } from "../../../../../../shared/src/valita.js";
|
|
3
3
|
import { equals } from "../../../../../../shared/src/set-utils.js";
|
|
4
4
|
import { BigIntJSON } from "../../../../../../shared/src/bigint-json.js";
|
|
5
|
-
import { publishedIndexSpec, publishedTableSpec } from "../../../../db/specs.js";
|
|
5
|
+
import { publishedColumnSpec, publishedIndexSpec, publishedTableSpec } from "../../../../db/specs.js";
|
|
6
6
|
import { liteTableName } from "../../../../types/names.js";
|
|
7
7
|
import { mapPostgresToLite, mapPostgresToLiteIndex } from "../../../../db/pg-to-lite.js";
|
|
8
8
|
import { computeZqlSpecsFromLiteSpecs } from "../../../../db/lite-tables.js";
|
|
9
|
+
import { getOrCreateCounter } from "../../../../observability/metrics.js";
|
|
10
|
+
import { translatePostgresIndexPredicate } from "./index-predicate.js";
|
|
9
11
|
import { literal } from "pg-format";
|
|
10
12
|
//#region ../zero-cache/src/services/change-source/pg/schema/published.ts
|
|
11
|
-
function publishedSchemaQuery(publications) {
|
|
13
|
+
function publishedSchemaQuery(publications, includePartialIndexes = true) {
|
|
12
14
|
return `
|
|
13
15
|
WITH published_columns AS (SELECT
|
|
14
16
|
pc.oid::int8 AS "oid",
|
|
@@ -22,6 +24,7 @@ WITH published_columns AS (SELECT
|
|
|
22
24
|
atttypid::int8 AS "typeOID",
|
|
23
25
|
pt.typtype,
|
|
24
26
|
elem_pt.typtype AS "elemTyptype",
|
|
27
|
+
coll.collisdeterministic AS "collationIsDeterministic",
|
|
25
28
|
NULLIF(atttypmod, -1) AS "maxLen",
|
|
26
29
|
attndims "arrayDims",
|
|
27
30
|
attnotnull AS "notNull",
|
|
@@ -34,6 +37,7 @@ JOIN pg_class pc ON pc.oid = attrelid
|
|
|
34
37
|
JOIN pg_namespace pns ON pns.oid = relnamespace
|
|
35
38
|
JOIN pg_type pt ON atttypid = pt.oid
|
|
36
39
|
LEFT JOIN pg_type elem_pt ON elem_pt.oid = pt.typelem
|
|
40
|
+
LEFT JOIN pg_collation coll ON coll.oid = pg_attribute.attcollation
|
|
37
41
|
JOIN pg_publication_tables as pb ON
|
|
38
42
|
pb.schemaname = nspname AND
|
|
39
43
|
pb.tablename = pc.relname AND
|
|
@@ -61,6 +65,7 @@ tables AS (SELECT json_build_object(
|
|
|
61
65
|
'pgTypeClass', "typtype",
|
|
62
66
|
'elemPgTypeClass', "elemTyptype",
|
|
63
67
|
'typeOID', "typeOID",
|
|
68
|
+
'collationIsDeterministic', "collationIsDeterministic",
|
|
64
69
|
-- https://stackoverflow.com/a/52376230
|
|
65
70
|
'characterMaximumLength', CASE WHEN "typeOID" = 1043 OR "typeOID" = 1042
|
|
66
71
|
THEN "maxLen" - 4
|
|
@@ -90,10 +95,17 @@ tables AS (SELECT json_build_object(
|
|
|
90
95
|
pg_indexes.indexname as "name",
|
|
91
96
|
index_column.name as "col",
|
|
92
97
|
CASE WHEN pg_index.indoption[index_column.pos-1] & 1 = 1 THEN 'DESC' ELSE 'ASC' END as "dir",
|
|
93
|
-
|
|
98
|
+
-- Partial indexes are always reported as non-unique. Nothing on the
|
|
99
|
+
-- replica relies on the uniqueness of a partial index (it cannot serve
|
|
100
|
+
-- as a row key), and reporting it as non-unique keeps the ddl event
|
|
101
|
+
-- format compatible with older versions of the zero-cache, which
|
|
102
|
+
-- ignore "predicateSQL" and would otherwise create a full UNIQUE index
|
|
103
|
+
-- on the replica.
|
|
104
|
+
(pg_index.indisunique AND pg_index.indpred IS NULL) as "unique",
|
|
94
105
|
pg_index.indisprimary as "isPrimaryKey",
|
|
95
106
|
pg_index.indisreplident as "isReplicaIdentity",
|
|
96
|
-
pg_index.indimmediate as "isImmediate"
|
|
107
|
+
pg_index.indimmediate as "isImmediate",
|
|
108
|
+
pg_get_expr(pg_index.indpred, pg_index.indrelid, false) as "predicateSQL"
|
|
97
109
|
FROM pg_indexes
|
|
98
110
|
JOIN pg_namespace ON pg_indexes.schemaname = pg_namespace.nspname
|
|
99
111
|
JOIN pg_class pc ON
|
|
@@ -117,7 +129,7 @@ tables AS (SELECT json_build_object(
|
|
|
117
129
|
LEFT JOIN pg_constraint ON pg_constraint.conindid = pc.oid
|
|
118
130
|
WHERE pb.pubname IN (${literal(publications)})
|
|
119
131
|
AND pg_index.indexprs IS NULL
|
|
120
|
-
AND pg_index.indpred IS NULL
|
|
132
|
+
AND (${includePartialIndexes} OR pg_index.indpred IS NULL)
|
|
121
133
|
AND (pg_constraint.contype IS NULL OR pg_constraint.contype IN ('p', 'u'))
|
|
122
134
|
AND indexed.attnames <@ pb.attnames
|
|
123
135
|
AND (current_setting('server_version_num')::int >= 160000 OR false = ALL(indexed.generated))
|
|
@@ -135,10 +147,11 @@ tables AS (SELECT json_build_object(
|
|
|
135
147
|
'isPrimaryKey', "isPrimaryKey",
|
|
136
148
|
'isReplicaIdentity', "isReplicaIdentity",
|
|
137
149
|
'isImmediate', "isImmediate",
|
|
150
|
+
'predicateSQL', "predicateSQL",
|
|
138
151
|
'columns', json_object_agg("col", "dir")
|
|
139
152
|
) AS index FROM indexed_columns
|
|
140
153
|
GROUP BY "schema", "tableName", "name", "unique",
|
|
141
|
-
"isPrimaryKey", "isReplicaIdentity", "isImmediate")
|
|
154
|
+
"isPrimaryKey", "isReplicaIdentity", "isImmediate", "predicateSQL")
|
|
142
155
|
|
|
143
156
|
SELECT json_build_object(
|
|
144
157
|
'tables', COALESCE((SELECT json_agg("table") FROM tables), '[]'::json),
|
|
@@ -146,12 +159,63 @@ tables AS (SELECT json_build_object(
|
|
|
146
159
|
) as "publishedSchema"
|
|
147
160
|
`;
|
|
148
161
|
}
|
|
162
|
+
var rawPublishedColumnSpec = publishedColumnSpec.extend({ collationIsDeterministic: valita_exports.boolean().nullable().optional() });
|
|
163
|
+
var rawPublishedTableSpec = publishedTableSpec.extend({ columns: valita_exports.record(rawPublishedColumnSpec) });
|
|
164
|
+
var rawPublishedIndexSpec = publishedIndexSpec.extend({ predicateSQL: valita_exports.string().nullable().optional() });
|
|
165
|
+
var skippedIndexDiagnostics = /* @__PURE__ */ new WeakMap();
|
|
166
|
+
function getSkippedIndexDiagnostics(schema) {
|
|
167
|
+
return skippedIndexDiagnostics.get(schema) ?? [];
|
|
168
|
+
}
|
|
169
|
+
function warnForSkippedIndexes(lc, schema, warned = /* @__PURE__ */ new Set()) {
|
|
170
|
+
for (const diagnostic of getSkippedIndexDiagnostics(schema)) {
|
|
171
|
+
const key = JSON.stringify(diagnostic);
|
|
172
|
+
if (warned.has(key)) continue;
|
|
173
|
+
warned.add(key);
|
|
174
|
+
lc.warn?.("Skipping unsupported PostgreSQL partial index", diagnostic);
|
|
175
|
+
getOrCreateCounter("replication", "skipped_index", {
|
|
176
|
+
description: "Number of PostgreSQL indexes skipped during replication.",
|
|
177
|
+
unit: "{index}"
|
|
178
|
+
}).add(1, {
|
|
179
|
+
reason: diagnostic.reason,
|
|
180
|
+
partial: true
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
149
184
|
var publishedSchema = valita_exports.object({
|
|
150
|
-
tables: valita_exports.array(
|
|
151
|
-
indexes: valita_exports.array(
|
|
152
|
-
}).map(({ tables, indexes }) => {
|
|
185
|
+
tables: valita_exports.array(rawPublishedTableSpec),
|
|
186
|
+
indexes: valita_exports.array(rawPublishedIndexSpec)
|
|
187
|
+
}).map(({ tables: rawTables, indexes: rawIndexes }) => {
|
|
188
|
+
const diagnostics = [];
|
|
189
|
+
const indexes = [];
|
|
190
|
+
for (const rawIndex of rawIndexes) {
|
|
191
|
+
const { predicateSQL, ...index } = rawIndex;
|
|
192
|
+
if (predicateSQL !== null && predicateSQL !== void 0) {
|
|
193
|
+
const table = rawTables.find((candidate) => candidate.schema === index.schema && candidate.name === index.tableName);
|
|
194
|
+
const translation = table ? translatePostgresIndexPredicate(predicateSQL, table) : {
|
|
195
|
+
supported: false,
|
|
196
|
+
reason: "unpublished-column"
|
|
197
|
+
};
|
|
198
|
+
if (!translation.supported) {
|
|
199
|
+
diagnostics.push({
|
|
200
|
+
schema: index.schema,
|
|
201
|
+
index: index.name,
|
|
202
|
+
predicate: predicateSQL,
|
|
203
|
+
reason: translation.reason
|
|
204
|
+
});
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
indexes.push({
|
|
208
|
+
...index,
|
|
209
|
+
predicate: translation.predicate
|
|
210
|
+
});
|
|
211
|
+
} else indexes.push(index);
|
|
212
|
+
}
|
|
213
|
+
const tables = rawTables.map((table) => ({
|
|
214
|
+
...table,
|
|
215
|
+
columns: Object.fromEntries(Object.entries(table.columns).map(([name, { collationIsDeterministic: _, ...column }]) => [name, column]))
|
|
216
|
+
}));
|
|
153
217
|
const zqlSpecs = computeZqlSpecsFromLiteSpecs(tables.map((t) => mapPostgresToLite(t)), indexes.map(mapPostgresToLiteIndex), { includeBackfillingColumns: true });
|
|
154
|
-
|
|
218
|
+
const result = {
|
|
155
219
|
indexes,
|
|
156
220
|
tables: tables.map((table) => {
|
|
157
221
|
const replicaIdentityColumns = [];
|
|
@@ -174,6 +238,8 @@ var publishedSchema = valita_exports.object({
|
|
|
174
238
|
};
|
|
175
239
|
})
|
|
176
240
|
};
|
|
241
|
+
skippedIndexDiagnostics.set(result, diagnostics);
|
|
242
|
+
return result;
|
|
177
243
|
});
|
|
178
244
|
var publicationSchema = valita_exports.object({
|
|
179
245
|
pubname: valita_exports.string(),
|
|
@@ -212,12 +278,15 @@ async function getPublicationInfo(sql, publications) {
|
|
|
212
278
|
});
|
|
213
279
|
}
|
|
214
280
|
assert(result[2][0].publishedSchema, () => `Invalid publishedSchema result ${BigIntJSON.stringify(result[2])}`);
|
|
215
|
-
|
|
281
|
+
const schema = parse(result[2][0].publishedSchema, publishedSchema);
|
|
282
|
+
const info = {
|
|
216
283
|
publications: parse(result[1], publicationsResultSchema),
|
|
217
|
-
...
|
|
284
|
+
...schema
|
|
218
285
|
};
|
|
286
|
+
skippedIndexDiagnostics.set(info, getSkippedIndexDiagnostics(schema));
|
|
287
|
+
return info;
|
|
219
288
|
}
|
|
220
289
|
//#endregion
|
|
221
|
-
export { getPublicationInfo, publishedSchema, publishedSchemaQuery };
|
|
290
|
+
export { getPublicationInfo, publishedSchema, publishedSchemaQuery, warnForSkippedIndexes };
|
|
222
291
|
|
|
223
292
|
//# sourceMappingURL=published.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"published.js","names":[],"sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/published.ts"],"sourcesContent":["import {literal} from 'pg-format';\nimport type postgres from 'postgres';\nimport {assert} from '../../../../../../shared/src/asserts.ts';\nimport {BigIntJSON} from '../../../../../../shared/src/bigint-json.ts';\nimport {equals} from '../../../../../../shared/src/set-utils.ts';\nimport * as v from '../../../../../../shared/src/valita.ts';\nimport {computeZqlSpecsFromLiteSpecs} from '../../../../db/lite-tables.ts';\nimport {\n mapPostgresToLite,\n mapPostgresToLiteIndex,\n} from '../../../../db/pg-to-lite.ts';\nimport {publishedIndexSpec, publishedTableSpec} from '../../../../db/specs.ts';\nimport {liteTableName} from '../../../../types/names.ts';\n\nexport function publishedSchemaQuery(publications: readonly string[]) {\n // Notes:\n // * There's a bug in PG15 in which generated columns are incorrectly\n // included in pg_publication_tables.attnames, (even though the generated\n // column values are not be included in the replication stream).\n // The WHERE condition `attgenerated = ''` fixes this by explicitly excluding\n // generated columns from the list.\n return (\n /*sql*/ `\nWITH published_columns AS (SELECT \n pc.oid::int8 AS \"oid\",\n nspname AS \"schema\",\n pc.relnamespace::int8 AS \"schemaOID\" ,\n pc.relname AS \"name\", \n pc.relreplident AS \"replicaIdentity\",\n attnum AS \"pos\", \n attname AS \"col\", \n pt.typname AS \"type\", \n atttypid::int8 AS \"typeOID\", \n pt.typtype,\n elem_pt.typtype AS \"elemTyptype\",\n NULLIF(atttypmod, -1) AS \"maxLen\", \n attndims \"arrayDims\", \n attnotnull AS \"notNull\",\n pg_get_expr(pd.adbin, pd.adrelid) as \"dflt\",\n NULLIF(ARRAY_POSITION(conkey, attnum), -1) AS \"keyPos\", \n pb.rowfilter as \"rowFilter\",\n pb.pubname as \"publication\"\nFROM pg_attribute\nJOIN pg_class pc ON pc.oid = attrelid\nJOIN pg_namespace pns ON pns.oid = relnamespace\nJOIN pg_type pt ON atttypid = pt.oid\nLEFT JOIN pg_type elem_pt ON elem_pt.oid = pt.typelem\nJOIN pg_publication_tables as pb ON \n pb.schemaname = nspname AND \n pb.tablename = pc.relname AND\n attname = ANY(pb.attnames)\nLEFT JOIN pg_constraint pk ON pk.contype = 'p' AND pk.connamespace = relnamespace AND pk.conrelid = attrelid\nLEFT JOIN pg_attrdef pd ON pd.adrelid = attrelid AND pd.adnum = attnum\nWHERE pb.pubname IN (${literal(publications)}) AND \n (current_setting('server_version_num')::int >= 160000 OR attgenerated = '')\nORDER BY nspname, pc.relname),\n\ntables AS (SELECT json_build_object(\n 'oid', \"oid\",\n 'schema', \"schema\", \n 'schemaOID', \"schemaOID\",\n 'name', \"name\", \n 'replicaIdentity', \"replicaIdentity\",\n 'columns', json_object_agg(\n DISTINCT\n col,\n jsonb_build_object(\n 'pos', \"pos\",\n 'dataType', CASE WHEN \"arrayDims\" = 0 \n THEN \"type\" \n ELSE substring(\"type\" from 2) || repeat('[]', \"arrayDims\") END,\n 'pgTypeClass', \"typtype\",\n 'elemPgTypeClass', \"elemTyptype\",\n 'typeOID', \"typeOID\",\n -- https://stackoverflow.com/a/52376230\n 'characterMaximumLength', CASE WHEN \"typeOID\" = 1043 OR \"typeOID\" = 1042 \n THEN \"maxLen\" - 4 \n ELSE \"maxLen\" END,\n 'notNull', \"notNull\",\n 'dflt', \"dflt\"\n )\n ),\n 'primaryKey', ARRAY( SELECT json_object_keys(\n json_strip_nulls(\n json_object_agg(\n DISTINCT \"col\", \"keyPos\" ORDER BY \"keyPos\"\n )\n )\n )),\n 'publications', json_object_agg(\n DISTINCT \n \"publication\", \n jsonb_build_object('rowFilter', \"rowFilter\")\n )\n) AS \"table\" FROM published_columns \n GROUP BY \"schema\", \"schemaOID\", \"name\", \"oid\", \"replicaIdentity\"),\n ` +\n // Note: pg_attribute contains column names for tables and for indexes.\n // However, the latter does not get updated when a column in a table is\n // renamed.\n //\n // https://www.postgresql.org/message-id/5860814f-c91d-4ab0-b771-ded90d7b9c55%40www.fastmail.com\n //\n // To address this, the pg_attribute rows are looked up for the index's\n // table rather than the index itself, using the pg_index.indkey array\n // to determine the set and order of columns to include.\n //\n // Notes:\n // * The first bit of indoption is 1 for DESC and 0 for ASC:\n // https://github.com/postgres/postgres/blob/4e1fad37872e49a711adad5d9870516e5c71a375/src/include/catalog/pg_index.h#L89\n // * pg_index.indkey is an int2vector which is 0-based instead of 1-based.\n // * The additional check for attgenerated is required for the aforementioned\n // (in publishedTableQuery) bug in PG15 in which generated columns are\n // incorrectly included in pg_publication_tables.attnames\n /*sql*/ `\n indexed_columns AS (SELECT\n pg_indexes.schemaname as \"schema\",\n pg_indexes.tablename as \"tableName\",\n pg_indexes.indexname as \"name\",\n index_column.name as \"col\",\n CASE WHEN pg_index.indoption[index_column.pos-1] & 1 = 1 THEN 'DESC' ELSE 'ASC' END as \"dir\",\n pg_index.indisunique as \"unique\",\n pg_index.indisprimary as \"isPrimaryKey\",\n pg_index.indisreplident as \"isReplicaIdentity\",\n pg_index.indimmediate as \"isImmediate\"\n FROM pg_indexes\n JOIN pg_namespace ON pg_indexes.schemaname = pg_namespace.nspname\n JOIN pg_class pc ON\n pc.relname = pg_indexes.indexname\n AND pc.relnamespace = pg_namespace.oid\n JOIN pg_publication_tables as pb ON \n pb.schemaname = pg_indexes.schemaname AND \n pb.tablename = pg_indexes.tablename\n JOIN pg_index ON pg_index.indexrelid = pc.oid\n JOIN LATERAL (\n SELECT array_agg(attname) as attnames, array_agg(attgenerated != '') as generated FROM pg_attribute\n WHERE attrelid = pg_index.indrelid\n AND attnum = ANY( (pg_index.indkey::smallint[] )[:pg_index.indnkeyatts - 1] )\n ) as indexed ON true\n JOIN LATERAL (\n SELECT pg_attribute.attname as name, col.index_pos as pos\n FROM UNNEST( (pg_index.indkey::smallint[])[:pg_index.indnkeyatts - 1] ) \n WITH ORDINALITY as col(table_pos, index_pos)\n JOIN pg_attribute ON attrelid = pg_index.indrelid AND attnum = col.table_pos\n ) AS index_column ON true\n LEFT JOIN pg_constraint ON pg_constraint.conindid = pc.oid\n WHERE pb.pubname IN (${literal(publications)})\n AND pg_index.indexprs IS NULL\n AND pg_index.indpred IS NULL\n AND (pg_constraint.contype IS NULL OR pg_constraint.contype IN ('p', 'u'))\n AND indexed.attnames <@ pb.attnames\n AND (current_setting('server_version_num')::int >= 160000 OR false = ALL(indexed.generated))\n ORDER BY\n pg_indexes.schemaname,\n pg_indexes.tablename,\n pg_indexes.indexname,\n index_column.pos ASC),\n \n indexes AS (SELECT json_build_object(\n 'schema', \"schema\",\n 'tableName', \"tableName\",\n 'name', \"name\",\n 'unique', \"unique\",\n 'isPrimaryKey', \"isPrimaryKey\",\n 'isReplicaIdentity', \"isReplicaIdentity\",\n 'isImmediate', \"isImmediate\",\n 'columns', json_object_agg(\"col\", \"dir\")\n ) AS index FROM indexed_columns \n GROUP BY \"schema\", \"tableName\", \"name\", \"unique\", \n \"isPrimaryKey\", \"isReplicaIdentity\", \"isImmediate\")\n\n SELECT json_build_object(\n 'tables', COALESCE((SELECT json_agg(\"table\") FROM tables), '[]'::json),\n 'indexes', COALESCE((SELECT json_agg(\"index\") FROM indexes), '[]'::json)\n ) as \"publishedSchema\"\n `\n );\n}\n\nexport const publishedSchema = v\n .object({\n tables: v.array(publishedTableSpec),\n indexes: v.array(publishedIndexSpec),\n })\n .map(({tables, indexes}) => {\n const zqlSpecs = computeZqlSpecsFromLiteSpecs(\n tables.map(t => mapPostgresToLite(t)),\n indexes.map(mapPostgresToLiteIndex),\n {includeBackfillingColumns: true},\n );\n return {\n indexes,\n\n // Denormalize the schema such that each `table` includes the\n // `replicaIdentityColumns` corresponding to the table's\n // replica identity and associated primary key or index.\n tables: tables.map(table => {\n const replicaIdentityColumns: string[] = [];\n switch (table.replicaIdentity) {\n case 'd':\n replicaIdentityColumns.push(...(table.primaryKey ?? []));\n break;\n case 'i':\n replicaIdentityColumns.push(\n ...Object.keys(\n indexes.find(\n ind =>\n ind.schema === table.schema &&\n ind.tableName === table.name &&\n ind.isReplicaIdentity,\n )?.columns ?? {},\n ),\n );\n break;\n case 'f': {\n // For the key columns of replica identity \"full\", use the columns\n // that the replicator/change-processor will end up using\n // (in #getKey()) as the row key.\n const zqlTable = zqlSpecs.get(liteTableName(table));\n // Note: There zql spec will be absent if the table is not synced,\n // e.g. if it has no suitable unique indexes.\n if (zqlTable) {\n replicaIdentityColumns.push(...zqlTable.tableSpec.primaryKey);\n }\n break;\n }\n }\n return {\n ...table,\n replicaIdentityColumns,\n };\n }),\n };\n });\n\nexport type PublishedSchema = v.Infer<typeof publishedSchema>;\n\nexport type PublishedTableWithReplicaIdentity =\n PublishedSchema['tables'][number];\n\nconst publicationSchema = v.object({\n pubname: v.string(),\n pubinsert: v.boolean(),\n pubupdate: v.boolean(),\n pubdelete: v.boolean(),\n pubtruncate: v.boolean(),\n});\n\nconst publicationsResultSchema = v.array(publicationSchema);\n\nexport type PublicationInfo = PublishedSchema & {\n publications: v.Infer<typeof publicationsResultSchema>;\n};\n\n/**\n * Retrieves published tables and columns.\n */\nexport async function getPublicationInfo(\n sql: postgres.Sql,\n publications: string[],\n): Promise<PublicationInfo> {\n const result = await sql.unsafe(/*sql*/ `\n SELECT \n schemaname AS \"schema\",\n tablename AS \"table\", \n json_object_agg(pubname, attnames) AS \"publications\"\n FROM pg_publication_tables pb\n WHERE pb.pubname IN (${literal(publications)})\n GROUP BY schemaname, tablename;\n\n SELECT ${Object.keys(publicationSchema.shape).join(\n ',',\n )} FROM pg_publication pb\n WHERE pb.pubname IN (${literal(publications)})\n ORDER BY pubname;\n\n ${publishedSchemaQuery(publications)};\n`);\n\n // The first query is used to check that tables in multiple publications\n // always publish the same set of columns.\n const publishedColumns = result[0] as {\n schema: string;\n table: string;\n publications: Record<string, string[]>;\n }[];\n for (const {table, publications} of publishedColumns) {\n let expected: Set<string>;\n Object.entries(publications).forEach(([_, columns], i) => {\n const cols = new Set(columns);\n if (i === 0) {\n expected = cols;\n } else if (!equals(expected, cols)) {\n throw new Error(\n `Table ${table} is exported with different columns: [${[\n ...expected,\n ]}] vs [${[...cols]}]`,\n );\n }\n });\n }\n\n assert(\n result[2][0].publishedSchema,\n () => `Invalid publishedSchema result ${BigIntJSON.stringify(result[2])}`,\n );\n\n return {\n publications: v.parse(result[1], publicationsResultSchema),\n ...v.parse(result[2][0].publishedSchema, publishedSchema),\n };\n}\n"],"mappings":";;;;;;;;;;AAcA,SAAgB,qBAAqB,cAAiC;CAOpE,OACU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA+BW,QAAQ,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BA6FlB,QAAQ,YAAY,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BjD;AAEA,IAAa,kBAAkB,eAC5B,OAAO;CACN,QAAQ,eAAE,MAAM,kBAAkB;CAClC,SAAS,eAAE,MAAM,kBAAkB;AACrC,CAAC,EACA,KAAK,EAAC,QAAQ,cAAa;CAC1B,MAAM,WAAW,6BACf,OAAO,KAAI,MAAK,kBAAkB,CAAC,CAAC,GACpC,QAAQ,IAAI,sBAAsB,GAClC,EAAC,2BAA2B,KAAI,CAClC;CACA,OAAO;EACL;EAKA,QAAQ,OAAO,KAAI,UAAS;GAC1B,MAAM,yBAAmC,CAAC;GAC1C,QAAQ,MAAM,iBAAd;IACE,KAAK;KACH,uBAAuB,KAAK,GAAI,MAAM,cAAc,CAAC,CAAE;KACvD;IACF,KAAK;KACH,uBAAuB,KACrB,GAAG,OAAO,KACR,QAAQ,MACN,QACE,IAAI,WAAW,MAAM,UACrB,IAAI,cAAc,MAAM,QACxB,IAAI,iBACR,GAAG,WAAW,CAAC,CACjB,CACF;KACA;IACF,KAAK,KAAK;KAIR,MAAM,WAAW,SAAS,IAAI,cAAc,KAAK,CAAC;KAGlD,IAAI,UACF,uBAAuB,KAAK,GAAG,SAAS,UAAU,UAAU;KAE9D;IACF;GACF;GACA,OAAO;IACL,GAAG;IACH;GACF;EACF,CAAC;CACH;AACF,CAAC;AAOH,IAAM,oBAAoB,eAAE,OAAO;CACjC,SAAS,eAAE,OAAO;CAClB,WAAW,eAAE,QAAQ;CACrB,WAAW,eAAE,QAAQ;CACrB,WAAW,eAAE,QAAQ;CACrB,aAAa,eAAE,QAAQ;AACzB,CAAC;AAED,IAAM,2BAA2B,eAAE,MAAM,iBAAiB;;;;AAS1D,eAAsB,mBACpB,KACA,cAC0B;CAC1B,MAAM,SAAS,MAAM,IAAI,OAAe;;;;;;2BAMf,QAAQ,YAAY,EAAE;;;WAGtC,OAAO,KAAK,kBAAkB,KAAK,EAAE,KAC5C,GACF,EAAE;2BACuB,QAAQ,YAAY,EAAE;;;IAG7C,qBAAqB,YAAY,EAAE;CACtC;CAIC,MAAM,mBAAmB,OAAO;CAKhC,KAAK,MAAM,EAAC,OAAO,kBAAiB,kBAAkB;EACpD,IAAI;EACJ,OAAO,QAAQ,YAAY,EAAE,SAAS,CAAC,GAAG,UAAU,MAAM;GACxD,MAAM,OAAO,IAAI,IAAI,OAAO;GAC5B,IAAI,MAAM,GACR,WAAW;QACN,IAAI,CAAC,OAAO,UAAU,IAAI,GAC/B,MAAM,IAAI,MACR,SAAS,MAAM,wCAAwC,CACrD,GAAG,QACL,EAAE,QAAQ,CAAC,GAAG,IAAI,EAAE,EACtB;EAEJ,CAAC;CACH;CAEA,OACE,OAAO,GAAG,GAAG,uBACP,kCAAkC,WAAW,UAAU,OAAO,EAAE,GACxE;CAEA,OAAO;EACL,cAAc,MAAQ,OAAO,IAAI,wBAAwB;EACzD,GAAG,MAAQ,OAAO,GAAG,GAAG,iBAAiB,eAAe;CAC1D;AACF"}
|
|
1
|
+
{"version":3,"file":"published.js","names":[],"sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/published.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {literal} from 'pg-format';\nimport type postgres from 'postgres';\nimport {assert} from '../../../../../../shared/src/asserts.ts';\nimport {BigIntJSON} from '../../../../../../shared/src/bigint-json.ts';\nimport {equals} from '../../../../../../shared/src/set-utils.ts';\nimport * as v from '../../../../../../shared/src/valita.ts';\nimport {computeZqlSpecsFromLiteSpecs} from '../../../../db/lite-tables.ts';\nimport {\n mapPostgresToLite,\n mapPostgresToLiteIndex,\n} from '../../../../db/pg-to-lite.ts';\nimport {\n publishedColumnSpec,\n publishedIndexSpec,\n publishedTableSpec,\n type PublishedIndexSpec,\n} from '../../../../db/specs.ts';\nimport {getOrCreateCounter} from '../../../../observability/metrics.ts';\nimport {liteTableName} from '../../../../types/names.ts';\nimport {\n translatePostgresIndexPredicate,\n type UnsupportedPredicateReason,\n} from './index-predicate.ts';\n\nexport function publishedSchemaQuery(\n publications: readonly string[],\n includePartialIndexes = true,\n) {\n // Notes:\n // * There's a bug in PG15 in which generated columns are incorrectly\n // included in pg_publication_tables.attnames, (even though the generated\n // column values are not be included in the replication stream).\n // The WHERE condition `attgenerated = ''` fixes this by explicitly excluding\n // generated columns from the list.\n return (\n /*sql*/ `\nWITH published_columns AS (SELECT \n pc.oid::int8 AS \"oid\",\n nspname AS \"schema\",\n pc.relnamespace::int8 AS \"schemaOID\" ,\n pc.relname AS \"name\", \n pc.relreplident AS \"replicaIdentity\",\n attnum AS \"pos\", \n attname AS \"col\", \n pt.typname AS \"type\", \n atttypid::int8 AS \"typeOID\", \n pt.typtype,\n elem_pt.typtype AS \"elemTyptype\",\n coll.collisdeterministic AS \"collationIsDeterministic\",\n NULLIF(atttypmod, -1) AS \"maxLen\", \n attndims \"arrayDims\", \n attnotnull AS \"notNull\",\n pg_get_expr(pd.adbin, pd.adrelid) as \"dflt\",\n NULLIF(ARRAY_POSITION(conkey, attnum), -1) AS \"keyPos\", \n pb.rowfilter as \"rowFilter\",\n pb.pubname as \"publication\"\nFROM pg_attribute\nJOIN pg_class pc ON pc.oid = attrelid\nJOIN pg_namespace pns ON pns.oid = relnamespace\nJOIN pg_type pt ON atttypid = pt.oid\nLEFT JOIN pg_type elem_pt ON elem_pt.oid = pt.typelem\nLEFT JOIN pg_collation coll ON coll.oid = pg_attribute.attcollation\nJOIN pg_publication_tables as pb ON \n pb.schemaname = nspname AND \n pb.tablename = pc.relname AND\n attname = ANY(pb.attnames)\nLEFT JOIN pg_constraint pk ON pk.contype = 'p' AND pk.connamespace = relnamespace AND pk.conrelid = attrelid\nLEFT JOIN pg_attrdef pd ON pd.adrelid = attrelid AND pd.adnum = attnum\nWHERE pb.pubname IN (${literal(publications)}) AND \n (current_setting('server_version_num')::int >= 160000 OR attgenerated = '')\nORDER BY nspname, pc.relname),\n\ntables AS (SELECT json_build_object(\n 'oid', \"oid\",\n 'schema', \"schema\", \n 'schemaOID', \"schemaOID\",\n 'name', \"name\", \n 'replicaIdentity', \"replicaIdentity\",\n 'columns', json_object_agg(\n DISTINCT\n col,\n jsonb_build_object(\n 'pos', \"pos\",\n 'dataType', CASE WHEN \"arrayDims\" = 0 \n THEN \"type\" \n ELSE substring(\"type\" from 2) || repeat('[]', \"arrayDims\") END,\n 'pgTypeClass', \"typtype\",\n 'elemPgTypeClass', \"elemTyptype\",\n 'typeOID', \"typeOID\",\n 'collationIsDeterministic', \"collationIsDeterministic\",\n -- https://stackoverflow.com/a/52376230\n 'characterMaximumLength', CASE WHEN \"typeOID\" = 1043 OR \"typeOID\" = 1042 \n THEN \"maxLen\" - 4 \n ELSE \"maxLen\" END,\n 'notNull', \"notNull\",\n 'dflt', \"dflt\"\n )\n ),\n 'primaryKey', ARRAY( SELECT json_object_keys(\n json_strip_nulls(\n json_object_agg(\n DISTINCT \"col\", \"keyPos\" ORDER BY \"keyPos\"\n )\n )\n )),\n 'publications', json_object_agg(\n DISTINCT \n \"publication\", \n jsonb_build_object('rowFilter', \"rowFilter\")\n )\n) AS \"table\" FROM published_columns \n GROUP BY \"schema\", \"schemaOID\", \"name\", \"oid\", \"replicaIdentity\"),\n ` +\n // Note: pg_attribute contains column names for tables and for indexes.\n // However, the latter does not get updated when a column in a table is\n // renamed.\n //\n // https://www.postgresql.org/message-id/5860814f-c91d-4ab0-b771-ded90d7b9c55%40www.fastmail.com\n //\n // To address this, the pg_attribute rows are looked up for the index's\n // table rather than the index itself, using the pg_index.indkey array\n // to determine the set and order of columns to include.\n //\n // Notes:\n // * The first bit of indoption is 1 for DESC and 0 for ASC:\n // https://github.com/postgres/postgres/blob/4e1fad37872e49a711adad5d9870516e5c71a375/src/include/catalog/pg_index.h#L89\n // * pg_index.indkey is an int2vector which is 0-based instead of 1-based.\n // * The additional check for attgenerated is required for the aforementioned\n // (in publishedTableQuery) bug in PG15 in which generated columns are\n // incorrectly included in pg_publication_tables.attnames\n /*sql*/ `\n indexed_columns AS (SELECT\n pg_indexes.schemaname as \"schema\",\n pg_indexes.tablename as \"tableName\",\n pg_indexes.indexname as \"name\",\n index_column.name as \"col\",\n CASE WHEN pg_index.indoption[index_column.pos-1] & 1 = 1 THEN 'DESC' ELSE 'ASC' END as \"dir\",\n -- Partial indexes are always reported as non-unique. Nothing on the\n -- replica relies on the uniqueness of a partial index (it cannot serve\n -- as a row key), and reporting it as non-unique keeps the ddl event\n -- format compatible with older versions of the zero-cache, which\n -- ignore \"predicateSQL\" and would otherwise create a full UNIQUE index\n -- on the replica.\n (pg_index.indisunique AND pg_index.indpred IS NULL) as \"unique\",\n pg_index.indisprimary as \"isPrimaryKey\",\n pg_index.indisreplident as \"isReplicaIdentity\",\n pg_index.indimmediate as \"isImmediate\",\n pg_get_expr(pg_index.indpred, pg_index.indrelid, false) as \"predicateSQL\"\n FROM pg_indexes\n JOIN pg_namespace ON pg_indexes.schemaname = pg_namespace.nspname\n JOIN pg_class pc ON\n pc.relname = pg_indexes.indexname\n AND pc.relnamespace = pg_namespace.oid\n JOIN pg_publication_tables as pb ON \n pb.schemaname = pg_indexes.schemaname AND \n pb.tablename = pg_indexes.tablename\n JOIN pg_index ON pg_index.indexrelid = pc.oid\n JOIN LATERAL (\n SELECT array_agg(attname) as attnames, array_agg(attgenerated != '') as generated FROM pg_attribute\n WHERE attrelid = pg_index.indrelid\n AND attnum = ANY( (pg_index.indkey::smallint[] )[:pg_index.indnkeyatts - 1] )\n ) as indexed ON true\n JOIN LATERAL (\n SELECT pg_attribute.attname as name, col.index_pos as pos\n FROM UNNEST( (pg_index.indkey::smallint[])[:pg_index.indnkeyatts - 1] ) \n WITH ORDINALITY as col(table_pos, index_pos)\n JOIN pg_attribute ON attrelid = pg_index.indrelid AND attnum = col.table_pos\n ) AS index_column ON true\n LEFT JOIN pg_constraint ON pg_constraint.conindid = pc.oid\n WHERE pb.pubname IN (${literal(publications)})\n AND pg_index.indexprs IS NULL\n AND (${includePartialIndexes} OR pg_index.indpred IS NULL)\n AND (pg_constraint.contype IS NULL OR pg_constraint.contype IN ('p', 'u'))\n AND indexed.attnames <@ pb.attnames\n AND (current_setting('server_version_num')::int >= 160000 OR false = ALL(indexed.generated))\n ORDER BY\n pg_indexes.schemaname,\n pg_indexes.tablename,\n pg_indexes.indexname,\n index_column.pos ASC),\n \n indexes AS (SELECT json_build_object(\n 'schema', \"schema\",\n 'tableName', \"tableName\",\n 'name', \"name\",\n 'unique', \"unique\",\n 'isPrimaryKey', \"isPrimaryKey\",\n 'isReplicaIdentity', \"isReplicaIdentity\",\n 'isImmediate', \"isImmediate\",\n 'predicateSQL', \"predicateSQL\",\n 'columns', json_object_agg(\"col\", \"dir\")\n ) AS index FROM indexed_columns \n GROUP BY \"schema\", \"tableName\", \"name\", \"unique\", \n \"isPrimaryKey\", \"isReplicaIdentity\", \"isImmediate\", \"predicateSQL\")\n\n SELECT json_build_object(\n 'tables', COALESCE((SELECT json_agg(\"table\") FROM tables), '[]'::json),\n 'indexes', COALESCE((SELECT json_agg(\"index\") FROM indexes), '[]'::json)\n ) as \"publishedSchema\"\n `\n );\n}\n\nconst rawPublishedColumnSpec = publishedColumnSpec.extend({\n collationIsDeterministic: v.boolean().nullable().optional(),\n});\n\nconst rawPublishedTableSpec = publishedTableSpec.extend({\n columns: v.record(rawPublishedColumnSpec),\n});\n\nconst rawPublishedIndexSpec = publishedIndexSpec.extend({\n predicateSQL: v.string().nullable().optional(),\n});\n\nexport type SkippedIndexDiagnostic = {\n readonly schema: string;\n readonly index: string;\n readonly predicate: string;\n readonly reason: UnsupportedPredicateReason;\n};\n\nconst skippedIndexDiagnostics = new WeakMap<\n object,\n readonly SkippedIndexDiagnostic[]\n>();\nexport function getSkippedIndexDiagnostics(\n schema: PublishedSchema,\n): readonly SkippedIndexDiagnostic[] {\n return skippedIndexDiagnostics.get(schema) ?? [];\n}\n\nexport function warnForSkippedIndexes(\n lc: LogContext,\n schema: PublishedSchema,\n warned: Set<string> = new Set(),\n): void {\n for (const diagnostic of getSkippedIndexDiagnostics(schema)) {\n const key = JSON.stringify(diagnostic);\n if (warned.has(key)) continue;\n warned.add(key);\n lc.warn?.('Skipping unsupported PostgreSQL partial index', diagnostic);\n getOrCreateCounter('replication', 'skipped_index', {\n description: 'Number of PostgreSQL indexes skipped during replication.',\n unit: '{index}',\n }).add(1, {reason: diagnostic.reason, partial: true});\n }\n}\n\nexport const publishedSchema = v\n .object({\n tables: v.array(rawPublishedTableSpec),\n indexes: v.array(rawPublishedIndexSpec),\n })\n .map(({tables: rawTables, indexes: rawIndexes}) => {\n const diagnostics: SkippedIndexDiagnostic[] = [];\n const indexes: PublishedIndexSpec[] = [];\n for (const rawIndex of rawIndexes) {\n const {predicateSQL, ...index} = rawIndex;\n if (predicateSQL !== null && predicateSQL !== undefined) {\n const table = rawTables.find(\n candidate =>\n candidate.schema === index.schema &&\n candidate.name === index.tableName,\n );\n const translation = table\n ? translatePostgresIndexPredicate(predicateSQL, table)\n : {supported: false as const, reason: 'unpublished-column' as const};\n if (!translation.supported) {\n diagnostics.push({\n schema: index.schema,\n index: index.name,\n predicate: predicateSQL,\n reason: translation.reason,\n });\n continue;\n }\n indexes.push({...index, predicate: translation.predicate});\n } else {\n indexes.push(index);\n }\n }\n\n const tables = rawTables.map(table => ({\n ...table,\n columns: Object.fromEntries(\n Object.entries(table.columns).map(\n ([name, {collationIsDeterministic: _, ...column}]) => [name, column],\n ),\n ),\n }));\n const zqlSpecs = computeZqlSpecsFromLiteSpecs(\n tables.map(t => mapPostgresToLite(t)),\n indexes.map(mapPostgresToLiteIndex),\n {includeBackfillingColumns: true},\n );\n const result = {\n indexes,\n\n // Denormalize the schema such that each `table` includes the\n // `replicaIdentityColumns` corresponding to the table's\n // replica identity and associated primary key or index.\n tables: tables.map(table => {\n const replicaIdentityColumns: string[] = [];\n switch (table.replicaIdentity) {\n case 'd':\n replicaIdentityColumns.push(...(table.primaryKey ?? []));\n break;\n case 'i':\n replicaIdentityColumns.push(\n ...Object.keys(\n indexes.find(\n ind =>\n ind.schema === table.schema &&\n ind.tableName === table.name &&\n ind.isReplicaIdentity,\n )?.columns ?? {},\n ),\n );\n break;\n case 'f': {\n // For the key columns of replica identity \"full\", use the columns\n // that the replicator/change-processor will end up using\n // (in #getKey()) as the row key.\n const zqlTable = zqlSpecs.get(liteTableName(table));\n // Note: There zql spec will be absent if the table is not synced,\n // e.g. if it has no suitable unique indexes.\n if (zqlTable) {\n replicaIdentityColumns.push(...zqlTable.tableSpec.primaryKey);\n }\n break;\n }\n }\n return {\n ...table,\n replicaIdentityColumns,\n };\n }),\n };\n skippedIndexDiagnostics.set(result, diagnostics);\n return result;\n });\n\nexport type PublishedSchema = v.Infer<typeof publishedSchema>;\n\nexport type PublishedTableWithReplicaIdentity =\n PublishedSchema['tables'][number];\n\nconst publicationSchema = v.object({\n pubname: v.string(),\n pubinsert: v.boolean(),\n pubupdate: v.boolean(),\n pubdelete: v.boolean(),\n pubtruncate: v.boolean(),\n});\n\nconst publicationsResultSchema = v.array(publicationSchema);\n\nexport type PublicationInfo = PublishedSchema & {\n publications: v.Infer<typeof publicationsResultSchema>;\n};\n\n/**\n * Retrieves published tables and columns.\n */\nexport async function getPublicationInfo(\n sql: postgres.Sql,\n publications: string[],\n): Promise<PublicationInfo> {\n const result = await sql.unsafe(/*sql*/ `\n SELECT \n schemaname AS \"schema\",\n tablename AS \"table\", \n json_object_agg(pubname, attnames) AS \"publications\"\n FROM pg_publication_tables pb\n WHERE pb.pubname IN (${literal(publications)})\n GROUP BY schemaname, tablename;\n\n SELECT ${Object.keys(publicationSchema.shape).join(\n ',',\n )} FROM pg_publication pb\n WHERE pb.pubname IN (${literal(publications)})\n ORDER BY pubname;\n\n ${publishedSchemaQuery(publications)};\n`);\n\n // The first query is used to check that tables in multiple publications\n // always publish the same set of columns.\n const publishedColumns = result[0] as {\n schema: string;\n table: string;\n publications: Record<string, string[]>;\n }[];\n for (const {table, publications} of publishedColumns) {\n let expected: Set<string>;\n Object.entries(publications).forEach(([_, columns], i) => {\n const cols = new Set(columns);\n if (i === 0) {\n expected = cols;\n } else if (!equals(expected, cols)) {\n throw new Error(\n `Table ${table} is exported with different columns: [${[\n ...expected,\n ]}] vs [${[...cols]}]`,\n );\n }\n });\n }\n\n assert(\n result[2][0].publishedSchema,\n () => `Invalid publishedSchema result ${BigIntJSON.stringify(result[2])}`,\n );\n\n const schema = v.parse(result[2][0].publishedSchema, publishedSchema);\n const info = {\n publications: v.parse(result[1], publicationsResultSchema),\n ...schema,\n };\n skippedIndexDiagnostics.set(info, getSkippedIndexDiagnostics(schema));\n return info;\n}\n"],"mappings":"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"}
|