@rocicorp/zero 1.12.0-canary.2 → 1.12.0-canary.4

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.
Files changed (803) hide show
  1. package/out/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.154.0/helpers/esm}/usingCtx.js +2 -2
  2. package/out/analyze-query/src/analyze-cli.js +2 -1
  3. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  4. package/out/analyze-query/src/bin-analyze.js +5 -3
  5. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  6. package/out/analyze-query/src/bin-transform.js +3 -2
  7. package/out/analyze-query/src/bin-transform.js.map +1 -1
  8. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  9. package/out/ast-to-zql/src/bin.js +3 -2
  10. package/out/ast-to-zql/src/bin.js.map +1 -1
  11. package/out/ast-to-zql/src/format.js.map +1 -1
  12. package/out/datadog/src/datadog-log-sink.js +5 -4
  13. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  14. package/out/otel/src/log-options.js.map +1 -1
  15. package/out/replicache/src/btree/node.js +13 -11
  16. package/out/replicache/src/btree/node.js.map +1 -1
  17. package/out/replicache/src/btree/read.js +4 -2
  18. package/out/replicache/src/btree/read.js.map +1 -1
  19. package/out/replicache/src/btree/splice.js.map +1 -1
  20. package/out/replicache/src/btree/write.js +9 -5
  21. package/out/replicache/src/btree/write.js.map +1 -1
  22. package/out/replicache/src/config.js +1 -2
  23. package/out/replicache/src/connection-loop.js.map +1 -1
  24. package/out/replicache/src/dag/chunk.js +1 -1
  25. package/out/replicache/src/dag/gc.js.map +1 -1
  26. package/out/replicache/src/dag/lazy-store.js +8 -7
  27. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  28. package/out/replicache/src/dag/store-impl.js +1 -1
  29. package/out/replicache/src/dag/store-impl.js.map +1 -1
  30. package/out/replicache/src/dag/visitor.js.map +1 -1
  31. package/out/replicache/src/db/commit.js +5 -3
  32. package/out/replicache/src/db/commit.js.map +1 -1
  33. package/out/replicache/src/db/read.js +1 -1
  34. package/out/replicache/src/db/read.js.map +1 -1
  35. package/out/replicache/src/db/rebase.js.map +1 -1
  36. package/out/replicache/src/db/write.js +5 -2
  37. package/out/replicache/src/db/write.js.map +1 -1
  38. package/out/replicache/src/deleted-clients.js +3 -2
  39. package/out/replicache/src/deleted-clients.js.map +1 -1
  40. package/out/replicache/src/expo-sqlite.js +1 -2
  41. package/out/replicache/src/frozen-json.js +1 -1
  42. package/out/replicache/src/frozen-json.js.map +1 -1
  43. package/out/replicache/src/get-default-puller.js +1 -1
  44. package/out/replicache/src/hash.js +1 -1
  45. package/out/replicache/src/hash.js.map +1 -1
  46. package/out/replicache/src/impl.js +1 -2
  47. package/out/replicache/src/index-defs.js +5 -3
  48. package/out/replicache/src/index-defs.js.map +1 -1
  49. package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
  50. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  51. package/out/replicache/src/kv/idb-store.js +1 -1
  52. package/out/replicache/src/kv/idb-store.js.map +1 -1
  53. package/out/replicache/src/kv/mem-fallback-store.js +1 -1
  54. package/out/replicache/src/kv/mem-fallback-store.js.map +1 -1
  55. package/out/replicache/src/kv/mem-store.js.map +1 -1
  56. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  57. package/out/replicache/src/kv/op-sqlite/types.js.map +1 -1
  58. package/out/replicache/src/kv/read-impl.js.map +1 -1
  59. package/out/replicache/src/kv/sqlite-store.js +1 -1
  60. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  61. package/out/replicache/src/kv/write-impl-base.js +4 -1
  62. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  63. package/out/replicache/src/kv/write-impl.js.map +1 -1
  64. package/out/replicache/src/log-options.js +2 -1
  65. package/out/replicache/src/log-options.js.map +1 -1
  66. package/out/replicache/src/make-idb-name.js +1 -1
  67. package/out/replicache/src/new-client-channel.js +9 -7
  68. package/out/replicache/src/new-client-channel.js.map +1 -1
  69. package/out/replicache/src/on-persist-channel.js +1 -1
  70. package/out/replicache/src/on-persist-channel.js.map +1 -1
  71. package/out/replicache/src/op-sqlite.js +1 -2
  72. package/out/replicache/src/pending-mutations.js +2 -1
  73. package/out/replicache/src/pending-mutations.js.map +1 -1
  74. package/out/replicache/src/persist/client-gc.js +2 -2
  75. package/out/replicache/src/persist/client-gc.js.map +1 -1
  76. package/out/replicache/src/persist/client-group-gc.js +2 -2
  77. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  78. package/out/replicache/src/persist/client-groups.js +1 -1
  79. package/out/replicache/src/persist/client-groups.js.map +1 -1
  80. package/out/replicache/src/persist/clients.js +1 -1
  81. package/out/replicache/src/persist/clients.js.map +1 -1
  82. package/out/replicache/src/persist/collect-idb-databases.js +5 -4
  83. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  84. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  85. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  86. package/out/replicache/src/persist/heartbeat.js +2 -2
  87. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  88. package/out/replicache/src/persist/idb-databases-store.js +1 -1
  89. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  90. package/out/replicache/src/persist/make-client-id.js +1 -1
  91. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  92. package/out/replicache/src/persist/persist.js +3 -2
  93. package/out/replicache/src/persist/persist.js.map +1 -1
  94. package/out/replicache/src/persist/refresh.js +8 -5
  95. package/out/replicache/src/persist/refresh.js.map +1 -1
  96. package/out/replicache/src/process-scheduler.js.map +1 -1
  97. package/out/replicache/src/replicache-impl.js +3 -3
  98. package/out/replicache/src/replicache-impl.js.map +1 -1
  99. package/out/replicache/src/scan-iterator.js.map +1 -1
  100. package/out/replicache/src/scan-options.js +7 -6
  101. package/out/replicache/src/scan-options.js.map +1 -1
  102. package/out/replicache/src/sqlite.js +1 -2
  103. package/out/replicache/src/subscriptions.js +1 -1
  104. package/out/replicache/src/subscriptions.js.map +1 -1
  105. package/out/replicache/src/sync/diff.js +3 -1
  106. package/out/replicache/src/sync/diff.js.map +1 -1
  107. package/out/replicache/src/sync/ids.js.map +1 -1
  108. package/out/replicache/src/sync/patch.js +2 -4
  109. package/out/replicache/src/sync/patch.js.map +1 -1
  110. package/out/replicache/src/sync/pull.js +3 -1
  111. package/out/replicache/src/sync/pull.js.map +1 -1
  112. package/out/replicache/src/sync/push.js.map +1 -1
  113. package/out/replicache/src/sync/request-id.js +1 -1
  114. package/out/replicache/src/sync/request-id.js.map +1 -1
  115. package/out/replicache/src/transactions.js +1 -1
  116. package/out/replicache/src/transactions.js.map +1 -1
  117. package/out/shared/src/arrays.js +4 -1
  118. package/out/shared/src/arrays.js.map +1 -1
  119. package/out/shared/src/asserts.js +1 -1
  120. package/out/shared/src/bigint-json.d.ts +9 -0
  121. package/out/shared/src/bigint-json.d.ts.map +1 -1
  122. package/out/shared/src/bigint-json.js +27 -2
  123. package/out/shared/src/bigint-json.js.map +1 -1
  124. package/out/shared/src/broadcast-channel.js +1 -1
  125. package/out/shared/src/btree-set.js +11 -8
  126. package/out/shared/src/btree-set.js.map +1 -1
  127. package/out/shared/src/cache.js.map +1 -1
  128. package/out/shared/src/config.js +1 -1
  129. package/out/shared/src/custom-key-map.js.map +1 -1
  130. package/out/shared/src/custom-key-set.js.map +1 -1
  131. package/out/shared/src/deep-clone.js +1 -1
  132. package/out/shared/src/document-visible.js.map +1 -1
  133. package/out/shared/src/dotenv.js.map +1 -1
  134. package/out/shared/src/error.js +1 -1
  135. package/out/shared/src/error.js.map +1 -1
  136. package/out/shared/src/hash.js +2 -2
  137. package/out/shared/src/hash.js.map +1 -1
  138. package/out/shared/src/iterables.js.map +1 -1
  139. package/out/shared/src/json-schema.js.map +1 -1
  140. package/out/shared/src/json.js.map +1 -1
  141. package/out/shared/src/logging-test-utils.js +1 -1
  142. package/out/shared/src/logging.js +1 -1
  143. package/out/shared/src/logging.js.map +1 -1
  144. package/out/shared/src/navigator.js +1 -1
  145. package/out/shared/src/options.js +9 -12
  146. package/out/shared/src/options.js.map +1 -1
  147. package/out/shared/src/promise-race.js.map +1 -1
  148. package/out/shared/src/queue.js.map +1 -1
  149. package/out/shared/src/record-proxy.js.map +1 -1
  150. package/out/shared/src/ring-buffer.js.map +1 -1
  151. package/out/shared/src/size-of-value.js +7 -10
  152. package/out/shared/src/size-of-value.js.map +1 -1
  153. package/out/shared/src/sorted-entries.js.map +1 -1
  154. package/out/shared/src/tdigest-schema.js.map +1 -1
  155. package/out/shared/src/tdigest.js.map +1 -1
  156. package/out/shared/src/valita.js +1 -1
  157. package/out/shared/src/valita.js.map +1 -1
  158. package/out/z2s/src/compiler.js +2 -4
  159. package/out/z2s/src/compiler.js.map +1 -1
  160. package/out/z2s/src/sql.js +1 -1
  161. package/out/z2s/src/sql.js.map +1 -1
  162. package/out/zero/package.js +212 -189
  163. package/out/zero/package.js.map +1 -1
  164. package/out/zero/src/adapters/drizzle.js +1 -2
  165. package/out/zero/src/adapters/kysely.js +1 -2
  166. package/out/zero/src/adapters/pg.js +1 -2
  167. package/out/zero/src/adapters/postgresjs.js +1 -2
  168. package/out/zero/src/adapters/prisma.js +1 -2
  169. package/out/zero/src/analyze.js +1 -2
  170. package/out/zero/src/change-protocol/v0.js +1 -2
  171. package/out/zero/src/expo-sqlite.js +1 -2
  172. package/out/zero/src/op-sqlite.js +1 -2
  173. package/out/zero/src/react-native.js.map +1 -1
  174. package/out/zero/src/sqlite.js +1 -2
  175. package/out/zero/src/zero-cache-dev.js +10 -9
  176. package/out/zero/src/zero-cache-dev.js.map +1 -1
  177. package/out/zero/src/zero-out.js +2 -1
  178. package/out/zero/src/zero-out.js.map +1 -1
  179. package/out/zero-cache/src/auth/auth.js +1 -1
  180. package/out/zero-cache/src/auth/auth.js.map +1 -1
  181. package/out/zero-cache/src/auth/jwt.js +4 -1
  182. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  183. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  184. package/out/zero-cache/src/auth/read-authorizer.js +3 -2
  185. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  186. package/out/zero-cache/src/auth/write-authorizer.js +5 -16
  187. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  188. package/out/zero-cache/src/config/network.js +1 -1
  189. package/out/zero-cache/src/config/network.js.map +1 -1
  190. package/out/zero-cache/src/config/server-context.js.map +1 -1
  191. package/out/zero-cache/src/config/zero-config.d.ts +9 -0
  192. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  193. package/out/zero-cache/src/config/zero-config.js +17 -2
  194. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  195. package/out/zero-cache/src/custom/fetch.js +1 -1
  196. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  197. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  198. package/out/zero-cache/src/db/create.js.map +1 -1
  199. package/out/zero-cache/src/db/index-predicate.js.map +1 -1
  200. package/out/zero-cache/src/db/lite-tables.d.ts +2 -2
  201. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  202. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  203. package/out/zero-cache/src/db/migration-lite.js +1 -1
  204. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  205. package/out/zero-cache/src/db/migration.js +5 -3
  206. package/out/zero-cache/src/db/migration.js.map +1 -1
  207. package/out/zero-cache/src/db/pg-copy-binary.js +4 -3
  208. package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
  209. package/out/zero-cache/src/db/pg-copy.js +0 -1
  210. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  211. package/out/zero-cache/src/db/pg-to-lite.js +1 -1
  212. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  213. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  214. package/out/zero-cache/src/db/specs.js +7 -5
  215. package/out/zero-cache/src/db/specs.js.map +1 -1
  216. package/out/zero-cache/src/db/sqlite-corruption.js.map +1 -1
  217. package/out/zero-cache/src/db/statements.d.ts.map +1 -1
  218. package/out/zero-cache/src/db/statements.js +9 -2
  219. package/out/zero-cache/src/db/statements.js.map +1 -1
  220. package/out/zero-cache/src/db/transaction-pool.js +5 -3
  221. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  222. package/out/zero-cache/src/db/warmup.js.map +1 -1
  223. package/out/zero-cache/src/observability/events.js.map +1 -1
  224. package/out/zero-cache/src/observability/log-throttle.js.map +1 -1
  225. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  226. package/out/zero-cache/src/scripts/deploy-permissions.js +4 -2
  227. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  228. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  229. package/out/zero-cache/src/server/anonymous-otel-start.js +2 -1
  230. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  231. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  232. package/out/zero-cache/src/server/change-streamer.js +2 -1
  233. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  234. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  235. package/out/zero-cache/src/server/logging.js +1 -1
  236. package/out/zero-cache/src/server/logging.js.map +1 -1
  237. package/out/zero-cache/src/server/main.js.map +1 -1
  238. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  239. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  240. package/out/zero-cache/src/server/reaper.js +2 -2
  241. package/out/zero-cache/src/server/reaper.js.map +1 -1
  242. package/out/zero-cache/src/server/replicator.js.map +1 -1
  243. package/out/zero-cache/src/server/runner/run-worker.js +2 -1
  244. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  245. package/out/zero-cache/src/server/runner/runtime.js +2 -1
  246. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  247. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  248. package/out/zero-cache/src/server/shadow-syncer.js +1 -1
  249. package/out/zero-cache/src/server/shadow-syncer.js.map +1 -1
  250. package/out/zero-cache/src/server/slot-keeper.js.map +1 -1
  251. package/out/zero-cache/src/server/syncer-assigner.js.map +1 -1
  252. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  253. package/out/zero-cache/src/server/syncer.js +6 -1
  254. package/out/zero-cache/src/server/syncer.js.map +1 -1
  255. package/out/zero-cache/src/server/worker-dispatcher.js +1 -1
  256. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  257. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  258. package/out/zero-cache/src/services/analyze.js +1 -1
  259. package/out/zero-cache/src/services/analyze.js.map +1 -1
  260. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +1 -1
  261. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  262. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  263. package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -1
  264. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
  265. package/out/zero-cache/src/services/change-source/common/replica-schema.js +3 -3
  266. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  267. package/out/zero-cache/src/services/change-source/custom/change-source.js +1 -1
  268. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  269. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  270. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +3 -3
  271. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  272. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -1
  273. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +2 -2
  274. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -1
  275. package/out/zero-cache/src/services/change-source/pg/change-source.js +4 -6
  276. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  277. package/out/zero-cache/src/services/change-source/pg/decommission.js +2 -1
  278. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  279. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +1 -0
  280. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  281. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +10 -8
  282. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  283. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  284. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  285. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +3 -2
  286. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  287. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  288. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +2 -2
  289. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -1
  290. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js +1 -1
  291. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js.map +1 -1
  292. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +3 -3
  293. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  294. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +1 -1
  295. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
  296. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +3 -3
  297. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  298. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +13 -12
  299. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  300. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts +1 -1
  301. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  302. package/out/zero-cache/src/services/change-source/pg/schema/init.js +8 -8
  303. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  304. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +1 -1
  305. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
  306. package/out/zero-cache/src/services/change-source/pg/schema/published.js +3 -2
  307. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  308. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -1
  309. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +2 -2
  310. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  311. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +13 -10
  312. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  313. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +1 -1
  314. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  315. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +1 -1
  316. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -1
  317. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  318. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  319. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  320. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  321. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  322. package/out/zero-cache/src/services/change-source/protocol/current.js +1 -1
  323. package/out/zero-cache/src/services/change-source/protocol/mod.js +1 -2
  324. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -1
  325. package/out/zero-cache/src/services/change-streamer/backfill-state.js +1 -1
  326. package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -1
  327. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  328. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  329. package/out/zero-cache/src/services/change-streamer/broadcast.js +1 -1
  330. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  331. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +1 -1
  332. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
  333. package/out/zero-cache/src/services/change-streamer/change-log-codec.js +2 -3
  334. package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
  335. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +2 -2
  336. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
  337. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js.map +1 -1
  338. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +4 -2
  339. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  340. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +21 -21
  341. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  342. package/out/zero-cache/src/services/change-streamer/change-streamer.js +1 -1
  343. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  344. package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -1
  345. package/out/zero-cache/src/services/change-streamer/forwarder.js +11 -10
  346. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  347. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +1 -1
  348. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -1
  349. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +3 -3
  350. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
  351. package/out/zero-cache/src/services/change-streamer/replica-poller.js +1 -1
  352. package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -1
  353. package/out/zero-cache/src/services/change-streamer/restore-admission.js +12 -1
  354. package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -1
  355. package/out/zero-cache/src/services/change-streamer/schema/init.js +1 -1
  356. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  357. package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
  358. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  359. package/out/zero-cache/src/services/change-streamer/snapshot-message.js +1 -1
  360. package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -1
  361. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
  362. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +1 -1
  363. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
  364. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +2 -2
  365. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -1
  366. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js.map +1 -1
  367. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -1
  368. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +1 -1
  369. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +4 -6
  370. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -1
  371. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +1 -3
  372. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
  373. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  374. package/out/zero-cache/src/services/change-streamer/storer.js +2 -2
  375. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  376. package/out/zero-cache/src/services/change-streamer/subscribe.js +1 -1
  377. package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -1
  378. package/out/zero-cache/src/services/change-streamer/subscriber.js +2 -2
  379. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  380. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +0 -1
  381. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  382. package/out/zero-cache/src/services/heapz.js +2 -1
  383. package/out/zero-cache/src/services/heapz.js.map +1 -1
  384. package/out/zero-cache/src/services/http-service.js.map +1 -1
  385. package/out/zero-cache/src/services/life-cycle.js +1 -1
  386. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  387. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js +4 -2
  388. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  389. package/out/zero-cache/src/services/litestream/commands.js +1 -1
  390. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  391. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +2 -2
  392. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
  393. package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
  394. package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
  395. package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -1
  396. package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
  397. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  398. package/out/zero-cache/src/services/mutagen/pusher.js +3 -2
  399. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  400. package/out/zero-cache/src/services/plannerz.js +4 -3
  401. package/out/zero-cache/src/services/plannerz.js.map +1 -1
  402. package/out/zero-cache/src/services/profz.js +5 -3
  403. package/out/zero-cache/src/services/profz.js.map +1 -1
  404. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
  405. package/out/zero-cache/src/services/replicator/change-log-db.js +3 -2
  406. package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
  407. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +1 -1
  408. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  409. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  410. package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -1
  411. package/out/zero-cache/src/services/replicator/incremental-sync.js +1 -1
  412. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  413. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  414. package/out/zero-cache/src/services/replicator/replication-status.js +4 -3
  415. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  416. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  417. package/out/zero-cache/src/services/replicator/reporter/recorder.js +1 -1
  418. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  419. package/out/zero-cache/src/services/replicator/reporter/report-schema.js +1 -1
  420. package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
  421. package/out/zero-cache/src/services/replicator/schema/backfilling.js +1 -1
  422. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
  423. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +19 -7
  424. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
  425. package/out/zero-cache/src/services/replicator/schema/change-log.js +31 -15
  426. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  427. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
  428. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  429. package/out/zero-cache/src/services/replicator/schema/replication-state.js +10 -7
  430. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  431. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  432. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +1 -1
  433. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
  434. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js +1 -1
  435. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js.map +1 -1
  436. package/out/zero-cache/src/services/replicator/write-worker-client.js +1 -1
  437. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  438. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  439. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  440. package/out/zero-cache/src/services/runner.js.map +1 -1
  441. package/out/zero-cache/src/services/running-state.js.map +1 -1
  442. package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js.map +1 -1
  443. package/out/zero-cache/src/services/statz.js +2 -1
  444. package/out/zero-cache/src/services/statz.js.map +1 -1
  445. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +2 -2
  446. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  447. package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -1
  448. package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -1
  449. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +18 -0
  450. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  451. package/out/zero-cache/src/services/view-syncer/client-handler.js +70 -23
  452. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  453. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts +15 -2
  454. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts.map +1 -1
  455. package/out/zero-cache/src/services/view-syncer/client-schema.js +46 -6
  456. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  457. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  458. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +2 -2
  459. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  460. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  461. package/out/zero-cache/src/services/view-syncer/cvr-store.js +10 -5
  462. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  463. package/out/zero-cache/src/services/view-syncer/cvr.js +12 -4
  464. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  465. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +1 -1
  466. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -1
  467. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  468. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js.map +1 -1
  469. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -1
  470. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +2 -2
  471. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -1
  472. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +5 -3
  473. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  474. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  475. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +8 -5
  476. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  477. package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -1
  478. package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -1
  479. package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -1
  480. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  481. package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -1
  482. package/out/zero-cache/src/services/view-syncer/query-stats.js +1 -1
  483. package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -1
  484. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  485. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +1 -1
  486. package/out/zero-cache/src/services/view-syncer/schema/types.js +1 -1
  487. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  488. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +7 -1
  489. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -1
  490. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +12 -4
  491. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  492. package/out/zero-cache/src/services/view-syncer/snapshotter.js +11 -7
  493. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  494. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  495. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  496. package/out/zero-cache/src/services/view-syncer/view-syncer.js +13 -9
  497. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  498. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  499. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  500. package/out/zero-cache/src/types/lite.js +1 -1
  501. package/out/zero-cache/src/types/lite.js.map +1 -1
  502. package/out/zero-cache/src/types/pg-data-type.js +1 -1
  503. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  504. package/out/zero-cache/src/types/pg.js +6 -4
  505. package/out/zero-cache/src/types/pg.js.map +1 -1
  506. package/out/zero-cache/src/types/poke-chunk.js +2 -2
  507. package/out/zero-cache/src/types/poke-chunk.js.map +1 -1
  508. package/out/zero-cache/src/types/processes.js +1 -1
  509. package/out/zero-cache/src/types/processes.js.map +1 -1
  510. package/out/zero-cache/src/types/profiler.js.map +1 -1
  511. package/out/zero-cache/src/types/row-key.js.map +1 -1
  512. package/out/zero-cache/src/types/sql.js.map +1 -1
  513. package/out/zero-cache/src/types/streams.js +10 -9
  514. package/out/zero-cache/src/types/streams.js.map +1 -1
  515. package/out/zero-cache/src/types/strings.js.map +1 -1
  516. package/out/zero-cache/src/types/subscription.js.map +1 -1
  517. package/out/zero-cache/src/types/timeout.js +1 -1
  518. package/out/zero-cache/src/types/websocket-handoff.js +1 -1
  519. package/out/zero-cache/src/types/ws.js +1 -1
  520. package/out/zero-cache/src/workers/connection.js +2 -3
  521. package/out/zero-cache/src/workers/connection.js.map +1 -1
  522. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  523. package/out/zero-cache/src/workers/replicator.js +5 -4
  524. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  525. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  526. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +9 -1
  527. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  528. package/out/zero-cache/src/workers/syncer.js +2 -2
  529. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  530. package/out/zero-client/src/client/active-clients-manager.js +1 -1
  531. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  532. package/out/zero-client/src/client/bindings.js +11 -11
  533. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  534. package/out/zero-client/src/client/connection.js +1 -1
  535. package/out/zero-client/src/client/connection.js.map +1 -1
  536. package/out/zero-client/src/client/context.js.map +1 -1
  537. package/out/zero-client/src/client/crud-impl.js +1 -1
  538. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  539. package/out/zero-client/src/client/crud.js +1 -1
  540. package/out/zero-client/src/client/crud.js.map +1 -1
  541. package/out/zero-client/src/client/custom.js +1 -1
  542. package/out/zero-client/src/client/custom.js.map +1 -1
  543. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  544. package/out/zero-client/src/client/enable-analytics.js +1 -1
  545. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  546. package/out/zero-client/src/client/error.js.map +1 -1
  547. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  548. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  549. package/out/zero-client/src/client/inspector/html-dialog-prompt.js +1 -1
  550. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  551. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  552. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  553. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  554. package/out/zero-client/src/client/ivm-branch.js +1 -3
  555. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  556. package/out/zero-client/src/client/keys.js +2 -1
  557. package/out/zero-client/src/client/keys.js.map +1 -1
  558. package/out/zero-client/src/client/log-options.js.map +1 -1
  559. package/out/zero-client/src/client/make-replicache-mutators.js +5 -3
  560. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  561. package/out/zero-client/src/client/metrics.js +3 -5
  562. package/out/zero-client/src/client/metrics.js.map +1 -1
  563. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  564. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  565. package/out/zero-client/src/client/options.js.map +1 -1
  566. package/out/zero-client/src/client/query-manager.js +2 -2
  567. package/out/zero-client/src/client/query-manager.js.map +1 -1
  568. package/out/zero-client/src/client/reload-error-handler.js +4 -3
  569. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  570. package/out/zero-client/src/client/version.js +1 -1
  571. package/out/zero-client/src/client/zero-poke-handler.js +1 -1
  572. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  573. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  574. package/out/zero-client/src/client/zero.js +19 -11
  575. package/out/zero-client/src/client/zero.js.map +1 -1
  576. package/out/zero-client/src/mod.js +23 -23
  577. package/out/zero-client/src/util/nanoid.js.map +1 -1
  578. package/out/zero-permissions/src/permissions.js +3 -2
  579. package/out/zero-permissions/src/permissions.js.map +1 -1
  580. package/out/zero-pg/src/mod.js +9 -9
  581. package/out/zero-protocol/src/analyze-query-result.js +1 -1
  582. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  583. package/out/zero-protocol/src/application-error.js.map +1 -1
  584. package/out/zero-protocol/src/ast.js +19 -9
  585. package/out/zero-protocol/src/ast.js.map +1 -1
  586. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  587. package/out/zero-protocol/src/client-schema.js +1 -1
  588. package/out/zero-protocol/src/client-schema.js.map +1 -1
  589. package/out/zero-protocol/src/close-connection.js +1 -1
  590. package/out/zero-protocol/src/close-connection.js.map +1 -1
  591. package/out/zero-protocol/src/connect.js +1 -1
  592. package/out/zero-protocol/src/connect.js.map +1 -1
  593. package/out/zero-protocol/src/custom-queries.js +1 -1
  594. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  595. package/out/zero-protocol/src/data.js +4 -2
  596. package/out/zero-protocol/src/data.js.map +1 -1
  597. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  598. package/out/zero-protocol/src/down.d.ts +27 -27
  599. package/out/zero-protocol/src/down.js.map +1 -1
  600. package/out/zero-protocol/src/error.js.map +1 -1
  601. package/out/zero-protocol/src/inspect-down.js +1 -1
  602. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  603. package/out/zero-protocol/src/inspect-up.js +1 -1
  604. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  605. package/out/zero-protocol/src/mutate-server.js +1 -1
  606. package/out/zero-protocol/src/mutate-server.js.map +1 -1
  607. package/out/zero-protocol/src/mutation-id.js.map +1 -1
  608. package/out/zero-protocol/src/mutation.js +1 -1
  609. package/out/zero-protocol/src/mutation.js.map +1 -1
  610. package/out/zero-protocol/src/mutations-patch.js +1 -1
  611. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  612. package/out/zero-protocol/src/ping.js +1 -1
  613. package/out/zero-protocol/src/ping.js.map +1 -1
  614. package/out/zero-protocol/src/poke.js +1 -1
  615. package/out/zero-protocol/src/poke.js.map +1 -1
  616. package/out/zero-protocol/src/pong.js +1 -1
  617. package/out/zero-protocol/src/pong.js.map +1 -1
  618. package/out/zero-protocol/src/primary-key.js.map +1 -1
  619. package/out/zero-protocol/src/protocol-version.js +1 -0
  620. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  621. package/out/zero-protocol/src/pull.js +1 -1
  622. package/out/zero-protocol/src/pull.js.map +1 -1
  623. package/out/zero-protocol/src/push.js +1 -1
  624. package/out/zero-protocol/src/push.js.map +1 -1
  625. package/out/zero-protocol/src/queries-patch.js +1 -1
  626. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  627. package/out/zero-protocol/src/query-hash-visitor.js.map +1 -1
  628. package/out/zero-protocol/src/query-hash.js +2 -2
  629. package/out/zero-protocol/src/query-server.js +1 -1
  630. package/out/zero-protocol/src/query-server.js.map +1 -1
  631. package/out/zero-protocol/src/row-patch.js.map +1 -1
  632. package/out/zero-protocol/src/up.js.map +1 -1
  633. package/out/zero-protocol/src/update-auth.js.map +1 -1
  634. package/out/zero-protocol/src/version.js.map +1 -1
  635. package/out/zero-react/src/bindings.js +11 -11
  636. package/out/zero-react/src/mod.js +5 -5
  637. package/out/zero-react/src/use-query.js +1 -1
  638. package/out/zero-react/src/use-query.js.map +1 -1
  639. package/out/zero-react/src/zero-provider.d.ts +1 -1
  640. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  641. package/out/zero-react/src/zero-provider.js +2 -1
  642. package/out/zero-react/src/zero-provider.js.map +1 -1
  643. package/out/zero-react/src/zero.js +23 -23
  644. package/out/zero-schema/src/builder/schema-builder.js +3 -2
  645. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  646. package/out/zero-schema/src/builder/table-builder.js +1 -1
  647. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  648. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  649. package/out/zero-schema/src/name-mapper.js +7 -5
  650. package/out/zero-schema/src/name-mapper.js.map +1 -1
  651. package/out/zero-schema/src/schema-config.js +1 -1
  652. package/out/zero-schema/src/schema-config.js.map +1 -1
  653. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  654. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  655. package/out/zero-server/src/adapters/pg.js.map +1 -1
  656. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  657. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  658. package/out/zero-server/src/closable-db-transaction.js.map +1 -1
  659. package/out/zero-server/src/custom.js +1 -1
  660. package/out/zero-server/src/custom.js.map +1 -1
  661. package/out/zero-server/src/mod.js +8 -8
  662. package/out/zero-server/src/process-mutations.js.map +1 -1
  663. package/out/zero-server/src/push-processor.js.map +1 -1
  664. package/out/zero-server/src/queries/process-queries.js +2 -1
  665. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  666. package/out/zero-server/src/schema.js +7 -7
  667. package/out/zero-server/src/schema.js.map +1 -1
  668. package/out/zero-server/src/zql-database.js.map +1 -1
  669. package/out/zero-solid/src/bindings.js +11 -11
  670. package/out/zero-solid/src/mod.js +5 -5
  671. package/out/zero-solid/src/solid-view.js +1 -1
  672. package/out/zero-solid/src/solid-view.js.map +1 -1
  673. package/out/zero-solid/src/use-connection-state.js +2 -1
  674. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  675. package/out/zero-solid/src/use-query.js.map +1 -1
  676. package/out/zero-solid/src/use-zero-online.js +2 -1
  677. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  678. package/out/zero-solid/src/use-zero.js +3 -2
  679. package/out/zero-solid/src/use-zero.js.map +1 -1
  680. package/out/zero-solid/src/zero.js +23 -23
  681. package/out/zero-types/src/name-mapper.js.map +1 -1
  682. package/out/zql/src/builder/builder.js +15 -13
  683. package/out/zql/src/builder/builder.js.map +1 -1
  684. package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -1
  685. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  686. package/out/zql/src/builder/like.js +0 -1
  687. package/out/zql/src/builder/like.js.map +1 -1
  688. package/out/zql/src/ivm/array-view.js.map +1 -1
  689. package/out/zql/src/ivm/cap.js +2 -4
  690. package/out/zql/src/ivm/cap.js.map +1 -1
  691. package/out/zql/src/ivm/constraint.js +1 -1
  692. package/out/zql/src/ivm/constraint.js.map +1 -1
  693. package/out/zql/src/ivm/data.js.map +1 -1
  694. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  695. package/out/zql/src/ivm/exists.js +20 -18
  696. package/out/zql/src/ivm/exists.js.map +1 -1
  697. package/out/zql/src/ivm/fan-in.js.map +1 -1
  698. package/out/zql/src/ivm/fan-out.js.map +1 -1
  699. package/out/zql/src/ivm/filter-operators.js +1 -1
  700. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  701. package/out/zql/src/ivm/filter-push.js.map +1 -1
  702. package/out/zql/src/ivm/filter.js.map +1 -1
  703. package/out/zql/src/ivm/flipped-join.js +1 -3
  704. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  705. package/out/zql/src/ivm/join-index-tap.js.map +1 -1
  706. package/out/zql/src/ivm/join-index.js.map +1 -1
  707. package/out/zql/src/ivm/join-utils.js +11 -13
  708. package/out/zql/src/ivm/join-utils.js.map +1 -1
  709. package/out/zql/src/ivm/join.js.map +1 -1
  710. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  711. package/out/zql/src/ivm/memory-source.js +26 -22
  712. package/out/zql/src/ivm/memory-source.js.map +1 -1
  713. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  714. package/out/zql/src/ivm/operator.js +2 -2
  715. package/out/zql/src/ivm/push-accumulated.js +0 -1
  716. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  717. package/out/zql/src/ivm/skip-yields.js.map +1 -1
  718. package/out/zql/src/ivm/skip.js.map +1 -1
  719. package/out/zql/src/ivm/take-gate.js.map +1 -1
  720. package/out/zql/src/ivm/take.js +3 -5
  721. package/out/zql/src/ivm/take.js.map +1 -1
  722. package/out/zql/src/ivm/union-fan-in.js +1 -1
  723. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  724. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  725. package/out/zql/src/ivm/view-apply-change.js +1 -1
  726. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  727. package/out/zql/src/mutate/crud.js +3 -2
  728. package/out/zql/src/mutate/crud.js.map +1 -1
  729. package/out/zql/src/planner/planner-builder.js +1 -1
  730. package/out/zql/src/planner/planner-builder.js.map +1 -1
  731. package/out/zql/src/planner/planner-connection.js.map +1 -1
  732. package/out/zql/src/planner/planner-debug.js.map +1 -1
  733. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  734. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  735. package/out/zql/src/planner/planner-filter.js.map +1 -1
  736. package/out/zql/src/planner/planner-graph.js +1 -5
  737. package/out/zql/src/planner/planner-graph.js.map +1 -1
  738. package/out/zql/src/planner/planner-join.js +1 -1
  739. package/out/zql/src/planner/planner-join.js.map +1 -1
  740. package/out/zql/src/planner/planner-source.js.map +1 -1
  741. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  742. package/out/zql/src/query/create-builder.js +2 -1
  743. package/out/zql/src/query/create-builder.js.map +1 -1
  744. package/out/zql/src/query/expression.js +1 -1
  745. package/out/zql/src/query/expression.js.map +1 -1
  746. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  747. package/out/zql/src/query/named.js +2 -1
  748. package/out/zql/src/query/named.js.map +1 -1
  749. package/out/zql/src/query/query-delegate-base.js +1 -1
  750. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  751. package/out/zql/src/query/query-impl.js +3 -2
  752. package/out/zql/src/query/query-impl.js.map +1 -1
  753. package/out/zql/src/query/query-registry.js +1 -1
  754. package/out/zql/src/query/query-registry.js.map +1 -1
  755. package/out/zql/src/query/query-transitions.js +1 -1
  756. package/out/zql/src/query/query-transitions.js.map +1 -1
  757. package/out/zql/src/query/runnable-query-impl.js +3 -2
  758. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  759. package/out/zql/src/query/static-query.js.map +1 -1
  760. package/out/zql/src/query/ttl.js +8 -8
  761. package/out/zql/src/query/ttl.js.map +1 -1
  762. package/out/zql/src/query/validate-input.js.map +1 -1
  763. package/out/zqlite/src/database-storage.d.ts +27 -8
  764. package/out/zqlite/src/database-storage.d.ts.map +1 -1
  765. package/out/zqlite/src/database-storage.js +195 -26
  766. package/out/zqlite/src/database-storage.js.map +1 -1
  767. package/out/zqlite/src/db.d.ts +47 -1
  768. package/out/zqlite/src/db.d.ts.map +1 -1
  769. package/out/zqlite/src/db.js +121 -21
  770. package/out/zqlite/src/db.js.map +1 -1
  771. package/out/zqlite/src/explain-queries.js.map +1 -1
  772. package/out/zqlite/src/fetch-sql.d.ts +27 -0
  773. package/out/zqlite/src/fetch-sql.d.ts.map +1 -0
  774. package/out/zqlite/src/fetch-sql.js +112 -0
  775. package/out/zqlite/src/fetch-sql.js.map +1 -0
  776. package/out/zqlite/src/index-usage.js.map +1 -1
  777. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  778. package/out/zqlite/src/internal/sql.js.map +1 -1
  779. package/out/zqlite/src/internal/statement-cache.d.ts +7 -0
  780. package/out/zqlite/src/internal/statement-cache.d.ts.map +1 -1
  781. package/out/zqlite/src/internal/statement-cache.js +11 -4
  782. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  783. package/out/zqlite/src/mod.js +5 -5
  784. package/out/zqlite/src/pending-delta.js.map +1 -1
  785. package/out/zqlite/src/query-builder.d.ts +11 -1
  786. package/out/zqlite/src/query-builder.d.ts.map +1 -1
  787. package/out/zqlite/src/query-builder.js +22 -7
  788. package/out/zqlite/src/query-builder.js.map +1 -1
  789. package/out/zqlite/src/query-delegate.js.map +1 -1
  790. package/out/zqlite/src/resolve-scalar-subqueries.js +2 -5
  791. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  792. package/out/zqlite/src/sqlite-cost-model.js +3 -2
  793. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  794. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  795. package/out/zqlite/src/table-source.d.ts +20 -2
  796. package/out/zqlite/src/table-source.d.ts.map +1 -1
  797. package/out/zqlite/src/table-source.js +73 -39
  798. package/out/zqlite/src/table-source.js.map +1 -1
  799. package/package.json +17 -15
  800. package/out/otel/src/maybe-time.d.ts +0 -3
  801. package/out/otel/src/maybe-time.d.ts.map +0 -1
  802. package/out/otel/src/maybe-time.js +0 -15
  803. package/out/otel/src/maybe-time.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ddl.js","names":[],"sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/ddl.ts"],"sourcesContent":["import {literal as lit} from 'pg-format';\nimport {assert} from '../../../../../../shared/src/asserts.ts';\nimport * as v from '../../../../../../shared/src/valita.ts';\nimport {upstreamSchema, type ShardConfig} from '../../../../types/shards.ts';\nimport {id} from '../../../../types/sql.ts';\nimport {publishedSchema, publishedSchemaQuery} from './published.ts';\n\n// Sent in the 'version' tag of \"ddlStart\" and \"ddlUpdate\" event messages.\n// This is used to ensure that the message constructed in the upstream\n// Trigger function is compatible with the code processing it in the zero-cache.\n//\n// Increment this when changing the format of the contents of the \"ddl\" events.\n// This will allow old / incompatible code to detect the change and abort.\nexport const PROTOCOL_VERSION = 1;\n\n// In protocol v2 (planned, not yet emitted), \"ddlStart\" events that are not\n// associated with a schema change will be context-only, omitting the\n// `schema` snapshot entirely. This avoids bloating the WAL with (large)\n// redundant schema snapshots for DDL commands that do not affect the\n// published schema, e.g. the CREATE/ALTER/DROP TABLE sub-commands executed\n// by REFRESH MATERIALIZED VIEW CONCURRENTLY.\n//\n// This release already accepts v2 events so that the (subsequent) release\n// that upgrades the triggers to emit them remains rollback safe with respect\n// to this one.\nconst versionSchema = v.literalUnion(PROTOCOL_VERSION, 2);\n\nconst triggerEvent = v.object({\n context: v.object({query: v.string()}).rest(v.string()),\n});\n\nexport const ddlEventSchema = triggerEvent.extend({\n version: versionSchema,\n event: v.object({tag: v.string()}),\n // Maps the OID of each published table to the `attnum`s of published\n // columns that were created in the (upstream) transaction that emitted\n // the event. Such columns are guaranteed to have the column default in\n // all pre-existing rows, and can thus be replicated without backfill if\n // the default value itself is replicable. Tables whose publication\n // entries (e.g. column lists) were modified in the same transaction are\n // excluded, since a newly *published* (as opposed to newly *created*)\n // column may hold arbitrary values in existing rows.\n //\n // The field is absent in messages from older versions of the upstream\n // functions (in which case backfill decisions fall back to the command\n // tag heuristic), and `null` when there are no such columns.\n newColumns: v.record(v.array(v.number())).nullable().optional(),\n});\n\n/**\n * A {@link DdlStartEvent} message is emitted before every DDL event,\n * containing the command `tag`.\n *\n * In most cases, the `DdlStartEvent` itself will not be associated with a\n * schema change, in which case the event is context-only (in protocol v2,\n * planned, both `previousSchema` and `schema` will be absent; in v1,\n * `schema` is set and `previousSchema` is `null`). The message is still\n * emitted to provide the command `tag` context in case an immediately\n * following `DdlStartEvent` tag is emitted with a schema change (which can\n * happen when another event trigger results in a nested ddl statement).\n *\n * In such cases, the `previousSchema` and `schema` fields of the latter event\n * are used to determine the necessary schema change operations (as they are\n * with `ddlUpdate` and `schemaSnapshot` events), and the `tag` of the\n * preceding start event indicates the command that precipitated the schema\n * change (e.g. a CREATE vs ALTER) to determine whether a backfill is\n * necessary.\n */\nexport const ddlStartEventSchema = ddlEventSchema.extend({\n type: v.literal('ddlStart'),\n // Set (along with `previousSchema`) only if the ddlStart event itself is\n // associated with a schema change. Absent in context-only (protocol v2,\n // planned) events. v1 events always contain the current `schema`.\n schema: publishedSchema.optional(),\n // For ddlStart messages, previousSchema is `null` (v1) or absent\n // (protocol v2, planned) if there was no change in schema detected.\n previousSchema: publishedSchema.nullable().optional(),\n // For backwards compatibility with previous versions of the trigger,\n // default an absent `event` field with a semantic equivalent. This\n // field override can be removed in a version that is rollback safe\n // with 1.4.0.\n event: v.object({tag: v.string()}).optional(() => ({tag: 'UNKNOWN'})),\n});\n\nexport type DdlStartEvent = v.Infer<typeof ddlStartEventSchema>;\n\n/**\n * A {@link DdlUpdateEvent} is emitted if there was a change in the schema.\n * It always contains `previousSchema` and (current) `schema` fields, leaving\n * it to the receiver to compute the necessary schema change operations.\n */\nexport const ddlUpdateEventSchema = ddlEventSchema.extend({\n type: v.literal('ddlUpdate'),\n // ddlUpdate messages are only emitted if the schema changed. `schema`\n // contains the current (i.e. post-change) snapshot.\n schema: publishedSchema,\n // The `previousSchema` contains the schema before the change.\n //\n // In 1.5.0 it is always set, and can be made non-optional when\n // rollback safe.\n previousSchema: publishedSchema.optional(),\n});\n\nexport type DdlUpdateEvent = v.Infer<typeof ddlUpdateEventSchema>;\n\n/**\n * The `schemaSnapshot` message is a snapshot of a schema taken in response to\n * a `COMMENT ON PUBLICATION` command, which is a hook recognized by zero\n * to manually emit `previousSchema` and `schema` snapshots when a difference\n * is detected. This is a workaround provided to support detection of schema\n * changes from `ALTER PUBLICATION` commands on supabase, which does not fire\n * event triggers for them (https://github.com/supabase/supautils/issues/123).\n *\n * The hook is exercised by trailing the publication change with a\n * `COMMENT ON PUBLICATION` statement, e.g.\n *\n * ```sql\n * BEGIN;\n * ALTER PUBLICATION my_publication ...;\n * COMMENT ON PUBLICATION my_publication IS 'whatever';\n * COMMIT;\n * ```\n *\n * Note that it is fine to invoke `COMMENT ON PUBLICATION` statements\n * on a database that *does* support event triggers on\n * `ALTER PUBLICATION` statements, as it will simply be a no-op.\n */\nexport const schemaSnapshotEventSchema = ddlEventSchema.extend({\n type: v.literal('schemaSnapshot'),\n schema: publishedSchema,\n previousSchema: publishedSchema.optional(),\n});\n\nexport type SchemaSnapshotEvent = v.Infer<typeof schemaSnapshotEventSchema>;\n\nexport const replicationEventSchema = v.union(\n ddlStartEventSchema,\n ddlUpdateEventSchema,\n schemaSnapshotEventSchema,\n);\n\nexport type ReplicationEvent = v.Infer<typeof replicationEventSchema>;\n\n// Creates a function that appends `_{shard-num}` to the input and\n// quotes the result to be a valid identifier.\nfunction append(shardNum: number) {\n return (name: string) => id(name + '_' + String(shardNum));\n}\n\n// pg_advisory_xact_lock key for serializing ddl statements in order to\n// produce correct schema change diffs.\nconst DDL_SERIALIZATION_LOCK = 0x3c6b8468f1bac0b0n;\n\n/**\n * Event trigger functions contain the core logic that are invoked by triggers.\n *\n * Note that although many of these functions can theoretically be parameterized and\n * shared across shards, it is advantageous to keep the functions in each shard\n * isolated from each other in order to avoid the complexity of shared-function\n * versioning.\n *\n * In a sense, shards (and their triggers and functions) should be thought of as\n * execution environments that can be updated at different schedules. If per-shard\n * triggers called into shared functions, we would have to consider versioning the\n * functions when changing their behavior, backwards compatibility, removal of\n * unused versions, etc. (not unlike versioning of npm packages).\n *\n * Instead, we opt for the simplicity and isolation of having each shard\n * completely own (and maintain) the entirety of its trigger/function stack.\n */\nexport function createEventFunctionStatements(shard: ShardConfig) {\n const {appID, shardNum, publications} = shard;\n const schema = id(upstreamSchema(shard)); // e.g. \"{APP_ID}_{SHARD_ID}\"\n return /*sql*/ `\nCREATE SCHEMA IF NOT EXISTS ${schema};\n\nCREATE OR REPLACE FUNCTION ${schema}.get_trigger_context()\nRETURNS record AS $$\nDECLARE\n result record;\nBEGIN\n SELECT COALESCE(current_query(), 'current_query() returned NULL') AS \"query\" into result;\n RETURN result;\nEND\n$$ LANGUAGE plpgsql;\n\n\nCREATE OR REPLACE FUNCTION ${schema}.notice_ignore(reason TEXT, tag TEXT, target record)\nRETURNS void AS $$\nBEGIN\n RAISE NOTICE '${appID}_${shardNum} ignoring % % %', reason, tag, \n COALESCE(row_to_json(target)::text, '');\nEND\n$$ LANGUAGE plpgsql;\n\n\n-- Note: DROP and CREATE to upgrade from v20 to v21 because the\n-- return type has changed. This can be simplified to CREATE OR REPLACE\n-- once 1.5.0 is rollback safe.\nDROP FUNCTION IF EXISTS ${schema}.schema_specs();\nCREATE FUNCTION ${schema}.schema_specs()\nRETURNS JSON \nSTABLE\nAS $$\n ${publishedSchemaQuery(publications)}\n$$ LANGUAGE sql;\n\n\n-- Stores the most recent published schema\nCREATE TABLE IF NOT EXISTS ${schema}.\"publishedSchema\" (\n current JSON,\n exists BOOL PRIMARY KEY DEFAULT true CHECK (exists)\n);\n\nINSERT INTO ${schema}.\"publishedSchema\" (current) VALUES (${schema}.schema_specs())\n ON CONFLICT (exists) DO \n UPDATE SET current = excluded.current;\n\n\nCREATE OR REPLACE FUNCTION ${schema}.update_schemas(event_type text, tag text, target record)\nRETURNS void AS $$\nDECLARE\n prev_schema_specs JSON;\n schema_specs JSON;\n message TEXT;\nBEGIN\n SELECT current FROM ${schema}.\"publishedSchema\" INTO prev_schema_specs;\n SELECT ${schema}.schema_specs() INTO schema_specs;\n \n IF prev_schema_specs::text != schema_specs::text THEN\n UPDATE ${schema}.\"publishedSchema\" SET current = schema_specs;\n ELSIF event_type = 'ddlStart' THEN\n -- ddlStart events are always be emitted to allow the zero-cache\n -- to track the context of the current command tag in the face of\n -- nested event triggers (e.g. start->start->end->end).\n prev_schema_specs = NULL;\n ELSIF event_type = 'ddlUpdate' THEN\n -- TODO: fold 'schemaSnapshot' into this condition too (i.e. make it \"ELSE\")\n -- when 1.5.0 is rollback safe. Until then, noop schemaSnapshots are sent\n -- for compatibility with 1.0.0 ~ 1.4.0.\n PERFORM ${schema}.notice_ignore('noop', tag, target);\n RETURN;\n END IF;\n\n SELECT json_build_object(\n 'type', event_type,\n 'version', ${PROTOCOL_VERSION},\n 'previousSchema', prev_schema_specs,\n 'schema', schema_specs,\n 'event', json_build_object('tag', tag),\n 'context', ${schema}.get_trigger_context()\n ) INTO message;\n\n PERFORM pg_logical_emit_message(true, '${appID}/${shardNum}/ddl', message);\n\n RAISE NOTICE 'Emitted ${appID}_${shardNum} % for % %', event_type, tag,\n COALESCE(row_to_json(target)::text, '');\nEND\n$$ LANGUAGE plpgsql;\n\n\n-- Hook/workaround to manually trigger replication of schema changes on DBs \n-- that do not support/allow event triggers.\nCREATE OR REPLACE FUNCTION ${schema}.update_schemas()\nRETURNS void AS $$\nBEGIN\n PERFORM ${schema}.update_schemas('schemaSnapshot', 'MANUAL', NULL);\nEND\n$$ LANGUAGE plpgsql;\n\n\nCREATE OR REPLACE FUNCTION ${schema}.emit_ddl_start()\nRETURNS event_trigger AS $$\nDECLARE\n schema_specs JSON;\n message TEXT;\nBEGIN\n -- serialize DDL statements to compute correct schema change diffs\n PERFORM pg_advisory_xact_lock(${DDL_SERIALIZATION_LOCK});\n PERFORM ${schema}.update_schemas('ddlStart', TG_TAG, NULL);\nEND\n$$ LANGUAGE plpgsql;\n\n\nCREATE OR REPLACE FUNCTION ${schema}.emit_ddl_end()\nRETURNS event_trigger AS $$\nDECLARE\n publications TEXT[];\n target RECORD;\n relevant RECORD;\n schema_specs JSON;\n message TEXT;\n event TEXT;\nBEGIN\n publications := ARRAY[${lit(publications)}];\n\n SELECT objid, object_type, object_identity \n FROM pg_event_trigger_ddl_commands() \n LIMIT 1 INTO target;\n\n -- Filter DDL updates that are not relevant to the shard (i.e. publications) when possible.\n SELECT true INTO relevant;\n\n -- Note: ALTER TABLE statements may *remove* the table from the set of published\n -- tables, and there is no way to determine if the table \"used to be\" in the\n -- set. Thus, all ALTER TABLE statements must produce a ddl update, similar to\n -- any DROP * statement.\n IF (target.object_type = 'table' AND TG_TAG != 'ALTER TABLE') \n OR target.object_type = 'table column' THEN\n SELECT ns.nspname AS \"schema\", c.relname AS \"name\" FROM pg_class AS c\n JOIN pg_namespace AS ns ON c.relnamespace = ns.oid\n JOIN pg_publication_tables AS pb ON pb.schemaname = ns.nspname AND pb.tablename = c.relname\n WHERE c.oid = target.objid AND pb.pubname = ANY (publications)\n INTO relevant;\n\n ELSIF target.object_type = 'index' THEN\n SELECT ns.nspname AS \"schema\", c.relname AS \"name\" FROM pg_class AS c\n JOIN pg_namespace AS ns ON c.relnamespace = ns.oid\n JOIN pg_indexes as ind ON ind.schemaname = ns.nspname AND ind.indexname = c.relname\n JOIN pg_publication_tables AS pb ON pb.schemaname = ns.nspname AND pb.tablename = ind.tablename\n WHERE c.oid = target.objid AND pb.pubname = ANY (publications)\n INTO relevant;\n\n ELSIF target.object_type = 'publication relation' THEN\n SELECT pb.pubname FROM pg_publication_rel AS rel\n JOIN pg_publication AS pb ON pb.oid = rel.prpubid\n WHERE rel.oid = target.objid AND pb.pubname = ANY (publications) \n INTO relevant;\n\n ELSIF target.object_type = 'publication namespace' THEN\n SELECT pb.pubname FROM pg_publication_namespace AS ns\n JOIN pg_publication AS pb ON pb.oid = ns.pnpubid\n WHERE ns.oid = target.objid AND pb.pubname = ANY (publications) \n INTO relevant;\n\n ELSIF target.object_type = 'schema' THEN\n SELECT ns.nspname AS \"schema\", c.relname AS \"name\" FROM pg_class AS c\n JOIN pg_namespace AS ns ON c.relnamespace = ns.oid\n JOIN pg_publication_tables AS pb ON pb.schemaname = ns.nspname AND pb.tablename = c.relname\n WHERE ns.oid = target.objid AND pb.pubname = ANY (publications)\n INTO relevant;\n\n ELSIF target.object_type = 'publication' THEN\n SELECT 1 WHERE target.object_identity = ANY (publications)\n INTO relevant;\n\n -- no-op CREATE IF NOT EXIST statements\n ELSIF TG_TAG LIKE 'CREATE %' AND target.object_type IS NULL THEN\n relevant := NULL;\n END IF;\n\n IF relevant IS NULL THEN\n PERFORM ${schema}.notice_ignore('irrelevant', TG_TAG, target);\n RETURN;\n END IF;\n\n IF TG_TAG = 'COMMENT' THEN\n -- Only make schemaSnapshots for COMMENT ON PUBLICATION\n IF target.object_type != 'publication' THEN\n PERFORM ${schema}.notice_ignore('irrelevant', TG_TAG, target);\n RETURN;\n END IF;\n PERFORM ${schema}.update_schemas('schemaSnapshot', TG_TAG, target);\n ELSE\n PERFORM ${schema}.update_schemas('ddlUpdate', TG_TAG, target);\n END IF;\n\nEND\n$$ LANGUAGE plpgsql;\n`;\n}\n\n// Exported for testing.\nexport const TAGS = [\n 'CREATE TABLE',\n 'ALTER TABLE',\n 'CREATE INDEX',\n 'DROP TABLE',\n 'DROP INDEX',\n 'ALTER PUBLICATION',\n 'ALTER SCHEMA',\n] as const;\n\nexport function createEventTriggerStatements(shard: ShardConfig) {\n // Better to assert here than get a cryptic syntax error from Postgres.\n assert(shard.publications.length, `shard publications must be non-empty`);\n\n // Unlike functions, which are namespaced in shard-specific schemas,\n // EVENT TRIGGER names are in the global namespace and thus must include\n // the appID and shardNum.\n const {appID, shardNum} = shard;\n const sharded = append(shardNum);\n const schema = id(upstreamSchema(shard));\n\n const triggers = [\n dropEventTriggerStatements(shard.appID, shard.shardNum),\n /*sql*/ `\nCREATE EVENT TRIGGER ${sharded(`${appID}_ddl_start`)}\n ON ddl_command_start\n WHEN TAG IN (${lit(TAGS)})\n EXECUTE PROCEDURE ${schema}.emit_ddl_start();\n\nCREATE EVENT TRIGGER ${sharded(`${appID}_ddl_end`)}\n ON ddl_command_end\n WHEN TAG IN (${lit([...TAGS, 'COMMENT'])})\n EXECUTE PROCEDURE ${schema}.emit_ddl_end();\n`,\n ];\n\n // Drop legacy functions / triggers.\n triggers.push(\n `DROP FUNCTION IF EXISTS ${schema}.emit_ddl_end(text) CASCADE;`,\n `DROP FUNCTION IF EXISTS ${schema}.notice_ignore(text, record);`,\n );\n for (const tag of [...TAGS, 'COMMENT']) {\n const tagID = tag.toLowerCase().replace(' ', '_');\n triggers.push(`DROP FUNCTION IF EXISTS ${schema}.emit_${tagID}() CASCADE;`);\n }\n return triggers.join('');\n}\n\n// Exported for testing.\nexport function dropEventTriggerStatements(\n appID: string,\n shardID: string | number,\n) {\n return /*sql*/ `\n DROP EVENT TRIGGER IF EXISTS ${id(`${appID}_ddl_start_${shardID}`)};\n DROP EVENT TRIGGER IF EXISTS ${id(`${appID}_ddl_end_${shardID}`)};\n `;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ddl.js","names":["v.literalUnion","v","lit"],"sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/ddl.ts"],"sourcesContent":["import {literal as lit} from 'pg-format';\nimport {assert} from '../../../../../../shared/src/asserts.ts';\nimport * as v from '../../../../../../shared/src/valita.ts';\nimport {upstreamSchema, type ShardConfig} from '../../../../types/shards.ts';\nimport {id} from '../../../../types/sql.ts';\nimport {publishedSchema, publishedSchemaQuery} from './published.ts';\n\n// Sent in the 'version' tag of \"ddlStart\" and \"ddlUpdate\" event messages.\n// This is used to ensure that the message constructed in the upstream\n// Trigger function is compatible with the code processing it in the zero-cache.\n//\n// Increment this when changing the format of the contents of the \"ddl\" events.\n// This will allow old / incompatible code to detect the change and abort.\nexport const PROTOCOL_VERSION = 1;\n\n// In protocol v2 (planned, not yet emitted), \"ddlStart\" events that are not\n// associated with a schema change will be context-only, omitting the\n// `schema` snapshot entirely. This avoids bloating the WAL with (large)\n// redundant schema snapshots for DDL commands that do not affect the\n// published schema, e.g. the CREATE/ALTER/DROP TABLE sub-commands executed\n// by REFRESH MATERIALIZED VIEW CONCURRENTLY.\n//\n// This release already accepts v2 events so that the (subsequent) release\n// that upgrades the triggers to emit them remains rollback safe with respect\n// to this one.\nconst versionSchema = v.literalUnion(PROTOCOL_VERSION, 2);\n\nconst triggerEvent = v.object({\n context: v.object({query: v.string()}).rest(v.string()),\n});\n\nexport const ddlEventSchema = triggerEvent.extend({\n version: versionSchema,\n event: v.object({tag: v.string()}),\n // Maps the OID of each published table to the `attnum`s of published\n // columns that were created in the (upstream) transaction that emitted\n // the event. Such columns are guaranteed to have the column default in\n // all pre-existing rows, and can thus be replicated without backfill if\n // the default value itself is replicable. Tables whose publication\n // entries (e.g. column lists) were modified in the same transaction are\n // excluded, since a newly *published* (as opposed to newly *created*)\n // column may hold arbitrary values in existing rows.\n //\n // The field is absent in messages from older versions of the upstream\n // functions (in which case backfill decisions fall back to the command\n // tag heuristic), and `null` when there are no such columns.\n newColumns: v.record(v.array(v.number())).nullable().optional(),\n});\n\n/**\n * A {@link DdlStartEvent} message is emitted before every DDL event,\n * containing the command `tag`.\n *\n * In most cases, the `DdlStartEvent` itself will not be associated with a\n * schema change, in which case the event is context-only (in protocol v2,\n * planned, both `previousSchema` and `schema` will be absent; in v1,\n * `schema` is set and `previousSchema` is `null`). The message is still\n * emitted to provide the command `tag` context in case an immediately\n * following `DdlStartEvent` tag is emitted with a schema change (which can\n * happen when another event trigger results in a nested ddl statement).\n *\n * In such cases, the `previousSchema` and `schema` fields of the latter event\n * are used to determine the necessary schema change operations (as they are\n * with `ddlUpdate` and `schemaSnapshot` events), and the `tag` of the\n * preceding start event indicates the command that precipitated the schema\n * change (e.g. a CREATE vs ALTER) to determine whether a backfill is\n * necessary.\n */\nexport const ddlStartEventSchema = ddlEventSchema.extend({\n type: v.literal('ddlStart'),\n // Set (along with `previousSchema`) only if the ddlStart event itself is\n // associated with a schema change. Absent in context-only (protocol v2,\n // planned) events. v1 events always contain the current `schema`.\n schema: publishedSchema.optional(),\n // For ddlStart messages, previousSchema is `null` (v1) or absent\n // (protocol v2, planned) if there was no change in schema detected.\n previousSchema: publishedSchema.nullable().optional(),\n // For backwards compatibility with previous versions of the trigger,\n // default an absent `event` field with a semantic equivalent. This\n // field override can be removed in a version that is rollback safe\n // with 1.4.0.\n event: v.object({tag: v.string()}).optional(() => ({tag: 'UNKNOWN'})),\n});\n\nexport type DdlStartEvent = v.Infer<typeof ddlStartEventSchema>;\n\n/**\n * A {@link DdlUpdateEvent} is emitted if there was a change in the schema.\n * It always contains `previousSchema` and (current) `schema` fields, leaving\n * it to the receiver to compute the necessary schema change operations.\n */\nexport const ddlUpdateEventSchema = ddlEventSchema.extend({\n type: v.literal('ddlUpdate'),\n // ddlUpdate messages are only emitted if the schema changed. `schema`\n // contains the current (i.e. post-change) snapshot.\n schema: publishedSchema,\n // The `previousSchema` contains the schema before the change.\n //\n // In 1.5.0 it is always set, and can be made non-optional when\n // rollback safe.\n previousSchema: publishedSchema.optional(),\n});\n\nexport type DdlUpdateEvent = v.Infer<typeof ddlUpdateEventSchema>;\n\n/**\n * The `schemaSnapshot` message is a snapshot of a schema taken in response to\n * a `COMMENT ON PUBLICATION` command, which is a hook recognized by zero\n * to manually emit `previousSchema` and `schema` snapshots when a difference\n * is detected. This is a workaround provided to support detection of schema\n * changes from `ALTER PUBLICATION` commands on supabase, which does not fire\n * event triggers for them (https://github.com/supabase/supautils/issues/123).\n *\n * The hook is exercised by trailing the publication change with a\n * `COMMENT ON PUBLICATION` statement, e.g.\n *\n * ```sql\n * BEGIN;\n * ALTER PUBLICATION my_publication ...;\n * COMMENT ON PUBLICATION my_publication IS 'whatever';\n * COMMIT;\n * ```\n *\n * Note that it is fine to invoke `COMMENT ON PUBLICATION` statements\n * on a database that *does* support event triggers on\n * `ALTER PUBLICATION` statements, as it will simply be a no-op.\n */\nexport const schemaSnapshotEventSchema = ddlEventSchema.extend({\n type: v.literal('schemaSnapshot'),\n schema: publishedSchema,\n previousSchema: publishedSchema.optional(),\n});\n\nexport type SchemaSnapshotEvent = v.Infer<typeof schemaSnapshotEventSchema>;\n\nexport const replicationEventSchema = v.union(\n ddlStartEventSchema,\n ddlUpdateEventSchema,\n schemaSnapshotEventSchema,\n);\n\nexport type ReplicationEvent = v.Infer<typeof replicationEventSchema>;\n\n// Creates a function that appends `_{shard-num}` to the input and\n// quotes the result to be a valid identifier.\nfunction append(shardNum: number) {\n return (name: string) => id(name + '_' + String(shardNum));\n}\n\n// pg_advisory_xact_lock key for serializing ddl statements in order to\n// produce correct schema change diffs.\nconst DDL_SERIALIZATION_LOCK = 0x3c6b8468f1bac0b0n;\n\n/**\n * Event trigger functions contain the core logic that are invoked by triggers.\n *\n * Note that although many of these functions can theoretically be parameterized and\n * shared across shards, it is advantageous to keep the functions in each shard\n * isolated from each other in order to avoid the complexity of shared-function\n * versioning.\n *\n * In a sense, shards (and their triggers and functions) should be thought of as\n * execution environments that can be updated at different schedules. If per-shard\n * triggers called into shared functions, we would have to consider versioning the\n * functions when changing their behavior, backwards compatibility, removal of\n * unused versions, etc. (not unlike versioning of npm packages).\n *\n * Instead, we opt for the simplicity and isolation of having each shard\n * completely own (and maintain) the entirety of its trigger/function stack.\n */\nexport function createEventFunctionStatements(\n shard: ShardConfig,\n includePartialIndexes = true,\n) {\n const {appID, shardNum, publications} = shard;\n const schema = id(upstreamSchema(shard)); // e.g. \"{APP_ID}_{SHARD_ID}\"\n return /*sql*/ `\nCREATE SCHEMA IF NOT EXISTS ${schema};\n\nCREATE OR REPLACE FUNCTION ${schema}.get_trigger_context()\nRETURNS record AS $$\nDECLARE\n result record;\nBEGIN\n SELECT COALESCE(current_query(), 'current_query() returned NULL') AS \"query\" into result;\n RETURN result;\nEND\n$$ LANGUAGE plpgsql;\n\n\nCREATE OR REPLACE FUNCTION ${schema}.notice_ignore(reason TEXT, tag TEXT, target record)\nRETURNS void AS $$\nBEGIN\n RAISE NOTICE '${appID}_${shardNum} ignoring % % %', reason, tag, \n COALESCE(row_to_json(target)::text, '');\nEND\n$$ LANGUAGE plpgsql;\n\n\n-- Note: DROP and CREATE to upgrade from v20 to v21 because the\n-- return type has changed. This can be simplified to CREATE OR REPLACE\n-- once 1.5.0 is rollback safe.\nDROP FUNCTION IF EXISTS ${schema}.schema_specs();\nCREATE FUNCTION ${schema}.schema_specs()\nRETURNS JSON \nSTABLE\nAS $$\n ${publishedSchemaQuery(publications, includePartialIndexes)}\n$$ LANGUAGE sql;\n\n\n-- Stores the most recent published schema\nCREATE TABLE IF NOT EXISTS ${schema}.\"publishedSchema\" (\n current JSON,\n exists BOOL PRIMARY KEY DEFAULT true CHECK (exists)\n);\n\nINSERT INTO ${schema}.\"publishedSchema\" (current) VALUES (${schema}.schema_specs())\n ON CONFLICT (exists) DO \n UPDATE SET current = excluded.current;\n\n\nCREATE OR REPLACE FUNCTION ${schema}.update_schemas(event_type text, tag text, target record)\nRETURNS void AS $$\nDECLARE\n prev_schema_specs JSON;\n schema_specs JSON;\n message TEXT;\nBEGIN\n SELECT current FROM ${schema}.\"publishedSchema\" INTO prev_schema_specs;\n SELECT ${schema}.schema_specs() INTO schema_specs;\n \n IF prev_schema_specs::text != schema_specs::text THEN\n UPDATE ${schema}.\"publishedSchema\" SET current = schema_specs;\n ELSIF event_type = 'ddlStart' THEN\n -- ddlStart events are always be emitted to allow the zero-cache\n -- to track the context of the current command tag in the face of\n -- nested event triggers (e.g. start->start->end->end).\n prev_schema_specs = NULL;\n ELSIF event_type = 'ddlUpdate' THEN\n -- TODO: fold 'schemaSnapshot' into this condition too (i.e. make it \"ELSE\")\n -- when 1.5.0 is rollback safe. Until then, noop schemaSnapshots are sent\n -- for compatibility with 1.0.0 ~ 1.4.0.\n PERFORM ${schema}.notice_ignore('noop', tag, target);\n RETURN;\n END IF;\n\n SELECT json_build_object(\n 'type', event_type,\n 'version', ${PROTOCOL_VERSION},\n 'previousSchema', prev_schema_specs,\n 'schema', schema_specs,\n 'event', json_build_object('tag', tag),\n 'context', ${schema}.get_trigger_context()\n ) INTO message;\n\n PERFORM pg_logical_emit_message(true, '${appID}/${shardNum}/ddl', message);\n\n RAISE NOTICE 'Emitted ${appID}_${shardNum} % for % %', event_type, tag,\n COALESCE(row_to_json(target)::text, '');\nEND\n$$ LANGUAGE plpgsql;\n\n\n-- Hook/workaround to manually trigger replication of schema changes on DBs \n-- that do not support/allow event triggers.\nCREATE OR REPLACE FUNCTION ${schema}.update_schemas()\nRETURNS void AS $$\nBEGIN\n PERFORM ${schema}.update_schemas('schemaSnapshot', 'MANUAL', NULL);\nEND\n$$ LANGUAGE plpgsql;\n\n\nCREATE OR REPLACE FUNCTION ${schema}.emit_ddl_start()\nRETURNS event_trigger AS $$\nDECLARE\n schema_specs JSON;\n message TEXT;\nBEGIN\n -- serialize DDL statements to compute correct schema change diffs\n PERFORM pg_advisory_xact_lock(${DDL_SERIALIZATION_LOCK});\n PERFORM ${schema}.update_schemas('ddlStart', TG_TAG, NULL);\nEND\n$$ LANGUAGE plpgsql;\n\n\nCREATE OR REPLACE FUNCTION ${schema}.emit_ddl_end()\nRETURNS event_trigger AS $$\nDECLARE\n publications TEXT[];\n target RECORD;\n relevant RECORD;\n schema_specs JSON;\n message TEXT;\n event TEXT;\nBEGIN\n publications := ARRAY[${lit(publications)}];\n\n SELECT objid, object_type, object_identity \n FROM pg_event_trigger_ddl_commands() \n LIMIT 1 INTO target;\n\n -- Filter DDL updates that are not relevant to the shard (i.e. publications) when possible.\n SELECT true INTO relevant;\n\n -- Note: ALTER TABLE statements may *remove* the table from the set of published\n -- tables, and there is no way to determine if the table \"used to be\" in the\n -- set. Thus, all ALTER TABLE statements must produce a ddl update, similar to\n -- any DROP * statement.\n IF (target.object_type = 'table' AND TG_TAG != 'ALTER TABLE') \n OR target.object_type = 'table column' THEN\n SELECT ns.nspname AS \"schema\", c.relname AS \"name\" FROM pg_class AS c\n JOIN pg_namespace AS ns ON c.relnamespace = ns.oid\n JOIN pg_publication_tables AS pb ON pb.schemaname = ns.nspname AND pb.tablename = c.relname\n WHERE c.oid = target.objid AND pb.pubname = ANY (publications)\n INTO relevant;\n\n ELSIF target.object_type = 'index' THEN\n SELECT ns.nspname AS \"schema\", c.relname AS \"name\" FROM pg_class AS c\n JOIN pg_namespace AS ns ON c.relnamespace = ns.oid\n JOIN pg_indexes as ind ON ind.schemaname = ns.nspname AND ind.indexname = c.relname\n JOIN pg_publication_tables AS pb ON pb.schemaname = ns.nspname AND pb.tablename = ind.tablename\n WHERE c.oid = target.objid AND pb.pubname = ANY (publications)\n INTO relevant;\n\n ELSIF target.object_type = 'publication relation' THEN\n SELECT pb.pubname FROM pg_publication_rel AS rel\n JOIN pg_publication AS pb ON pb.oid = rel.prpubid\n WHERE rel.oid = target.objid AND pb.pubname = ANY (publications) \n INTO relevant;\n\n ELSIF target.object_type = 'publication namespace' THEN\n SELECT pb.pubname FROM pg_publication_namespace AS ns\n JOIN pg_publication AS pb ON pb.oid = ns.pnpubid\n WHERE ns.oid = target.objid AND pb.pubname = ANY (publications) \n INTO relevant;\n\n ELSIF target.object_type = 'schema' THEN\n SELECT ns.nspname AS \"schema\", c.relname AS \"name\" FROM pg_class AS c\n JOIN pg_namespace AS ns ON c.relnamespace = ns.oid\n JOIN pg_publication_tables AS pb ON pb.schemaname = ns.nspname AND pb.tablename = c.relname\n WHERE ns.oid = target.objid AND pb.pubname = ANY (publications)\n INTO relevant;\n\n ELSIF target.object_type = 'publication' THEN\n SELECT 1 WHERE target.object_identity = ANY (publications)\n INTO relevant;\n\n -- no-op CREATE IF NOT EXIST statements\n ELSIF TG_TAG LIKE 'CREATE %' AND target.object_type IS NULL THEN\n relevant := NULL;\n END IF;\n\n IF relevant IS NULL THEN\n PERFORM ${schema}.notice_ignore('irrelevant', TG_TAG, target);\n RETURN;\n END IF;\n\n IF TG_TAG = 'COMMENT' THEN\n -- Only make schemaSnapshots for COMMENT ON PUBLICATION\n IF target.object_type != 'publication' THEN\n PERFORM ${schema}.notice_ignore('irrelevant', TG_TAG, target);\n RETURN;\n END IF;\n PERFORM ${schema}.update_schemas('schemaSnapshot', TG_TAG, target);\n ELSE\n PERFORM ${schema}.update_schemas('ddlUpdate', TG_TAG, target);\n END IF;\n\nEND\n$$ LANGUAGE plpgsql;\n`;\n}\n\n// Exported for testing.\nexport const TAGS = [\n 'CREATE TABLE',\n 'ALTER TABLE',\n 'CREATE INDEX',\n 'DROP TABLE',\n 'DROP INDEX',\n 'ALTER PUBLICATION',\n 'ALTER SCHEMA',\n] as const;\n\nexport function createEventTriggerStatements(shard: ShardConfig) {\n // Better to assert here than get a cryptic syntax error from Postgres.\n assert(shard.publications.length, `shard publications must be non-empty`);\n\n // Unlike functions, which are namespaced in shard-specific schemas,\n // EVENT TRIGGER names are in the global namespace and thus must include\n // the appID and shardNum.\n const {appID, shardNum} = shard;\n const sharded = append(shardNum);\n const schema = id(upstreamSchema(shard));\n\n const triggers = [\n dropEventTriggerStatements(shard.appID, shard.shardNum),\n /*sql*/ `\nCREATE EVENT TRIGGER ${sharded(`${appID}_ddl_start`)}\n ON ddl_command_start\n WHEN TAG IN (${lit(TAGS)})\n EXECUTE PROCEDURE ${schema}.emit_ddl_start();\n\nCREATE EVENT TRIGGER ${sharded(`${appID}_ddl_end`)}\n ON ddl_command_end\n WHEN TAG IN (${lit([...TAGS, 'COMMENT'])})\n EXECUTE PROCEDURE ${schema}.emit_ddl_end();\n`,\n ];\n\n // Drop legacy functions / triggers.\n triggers.push(\n `DROP FUNCTION IF EXISTS ${schema}.emit_ddl_end(text) CASCADE;`,\n `DROP FUNCTION IF EXISTS ${schema}.notice_ignore(text, record);`,\n );\n for (const tag of [...TAGS, 'COMMENT']) {\n const tagID = tag.toLowerCase().replace(' ', '_');\n triggers.push(`DROP FUNCTION IF EXISTS ${schema}.emit_${tagID}() CASCADE;`);\n }\n return triggers.join('');\n}\n\n// Exported for testing.\nexport function dropEventTriggerStatements(\n appID: string,\n shardID: string | number,\n) {\n return /*sql*/ `\n DROP EVENT TRIGGER IF EXISTS ${id(`${appID}_ddl_start_${shardID}`)};\n DROP EVENT TRIGGER IF EXISTS ${id(`${appID}_ddl_end_${shardID}`)};\n `;\n}\n"],"mappings":"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"}
@@ -190,7 +190,7 @@ var Parser = class {
190
190
  if (!this.#take(type)) throw new UnsupportedPredicateError("unsupported-syntax");
191
191
  }
192
192
  };
193
- var unsupportedOperatorWords = new Set([
193
+ var unsupportedOperatorWords = /* @__PURE__ */ new Set([
194
194
  "ALL",
195
195
  "BETWEEN",
196
196
  "ILIKE",
@@ -351,7 +351,7 @@ function resolveLiteral(expression, column) {
351
351
  if (literal.type !== "literal" || literal.value === null) throw new UnsupportedPredicateError("unsupported-syntax");
352
352
  switch (column.category) {
353
353
  case "boolean":
354
- validateLiteralCast(cast, new Set(["bool"]));
354
+ validateLiteralCast(cast, /* @__PURE__ */ new Set(["bool"]));
355
355
  if (literal.literalType !== "boolean") throw new UnsupportedPredicateError("unsupported-type");
356
356
  return {
357
357
  type: "boolean",
@@ -368,7 +368,7 @@ function resolveLiteral(expression, column) {
368
368
  value: canonicalInteger(String(literal.value), column.rank)
369
369
  };
370
370
  case "text":
371
- validateLiteralCast(cast, new Set(["text", "varchar"]));
371
+ validateLiteralCast(cast, /* @__PURE__ */ new Set(["text", "varchar"]));
372
372
  if (literal.literalType !== "string") throw new UnsupportedPredicateError("unsupported-type");
373
373
  return {
374
374
  type: "string",
@@ -382,7 +382,7 @@ function resolveLiteral(expression, column) {
382
382
  value: String(literal.value)
383
383
  };
384
384
  case "uuid": {
385
- validateLiteralCast(cast, new Set(["uuid"]));
385
+ validateLiteralCast(cast, /* @__PURE__ */ new Set(["uuid"]));
386
386
  const value = String(literal.value).toLowerCase();
387
387
  if (literal.literalType !== "string" || !UUID_RE.test(value)) throw new UnsupportedPredicateError("unsupported-type");
388
388
  return {
@@ -529,14 +529,15 @@ function readQuoted(sql, start, quote, escapes) {
529
529
  let value = "";
530
530
  for (let i = start + 1; i < sql.length; i++) {
531
531
  const char = sql[i];
532
- if (char === quote) if (sql[i + 1] === quote) {
533
- value += quote;
534
- i++;
535
- } else return {
536
- value,
537
- end: i + 1
538
- };
539
- else if (escapes && char === "\\") {
532
+ if (char === quote) {
533
+ if (sql[i + 1] === quote) {
534
+ value += quote;
535
+ i++;
536
+ } else return {
537
+ value,
538
+ end: i + 1
539
+ };
540
+ } else if (escapes && char === "\\") {
540
541
  const escape = sql[++i];
541
542
  if (escape === void 0) throw new UnsupportedPredicateError("unsupported-syntax");
542
543
  if (escape === "x") {
@@ -1 +1 @@
1
- {"version":3,"file":"index-predicate.js","names":["#tokens","#parseOr","#parseAnd","#take","#parseNot","#parseComparison","#parseOperand","#position","#parseOperandList","#takeIdentifier","#parseLiteralArray","#expectIdentifier","#parseCastName","#parsePrimary"],"sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/index-predicate.ts"],"sourcesContent":["import * as PostgresTypeClass from '../../../../db/postgres-type-class-enum.ts';\nimport type {\n IndexPredicate,\n IndexPredicateValue,\n PublishedTableSpec,\n} from '../../../../db/specs.ts';\n\nconst UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\nconst INTEGER_RE = /^[+-]?\\d+$/;\nconst WHITESPACE_RE = /\\s/;\nconst OPERATOR_TOKEN_RE = /^(?:::|<>|!=|<=|>=|=|<|>)/;\nconst UNSUPPORTED_OPERATOR_TOKEN_RE = /^(?:!~\\*|!~|~\\*|~)/;\nconst INTEGER_TOKEN_RE = /^[+-]?\\d+/;\nconst WORD_TOKEN_RE = /^[A-Za-z_][A-Za-z0-9_$]*/;\nconst SIMPLE_ESCAPES: Readonly<Record<string, string>> = {\n b: '\\b',\n f: '\\f',\n n: '\\n',\n r: '\\r',\n t: '\\t',\n v: '\\v',\n};\n\nexport const unsupportedPredicateReasons = [\n 'unpublished-column',\n 'unsupported-type',\n 'unsupported-operator',\n 'unsupported-function',\n 'unsupported-cast',\n 'unsupported-syntax',\n 'non-deterministic-collation',\n] as const;\n\nexport type UnsupportedPredicateReason =\n (typeof unsupportedPredicateReasons)[number];\n\nexport type PredicateTranslation =\n | {readonly supported: true; readonly predicate: IndexPredicate}\n | {readonly supported: false; readonly reason: UnsupportedPredicateReason};\n\ntype PredicateColumnSpec = PublishedTableSpec['columns'][string] & {\n readonly collationIsDeterministic?: boolean | null | undefined;\n};\n\ntype PredicateTableSpec = Omit<PublishedTableSpec, 'columns'> & {\n readonly columns: Readonly<Record<string, PredicateColumnSpec>>;\n};\n\ntype Expr =\n | {readonly type: 'column'; readonly name: string}\n | {\n readonly type: 'literal';\n readonly value: boolean | string | null;\n readonly literalType: 'boolean' | 'integer' | 'string' | 'null';\n }\n | {readonly type: 'cast'; readonly expression: Expr; readonly cast: string}\n | {readonly type: 'not'; readonly expression: Expr}\n | {\n readonly type: 'and' | 'or';\n readonly expressions: readonly Expr[];\n }\n | {\n readonly type: 'comparison';\n readonly left: Expr;\n readonly op: '=' | '<>' | '!=' | '<' | '<=' | '>' | '>=';\n readonly right: Expr;\n }\n | {\n readonly type: 'null-test';\n readonly expression: Expr;\n readonly not: boolean;\n };\n\ntype Token =\n | {readonly type: 'identifier'; readonly value: string}\n | {\n readonly type: 'literal';\n readonly value: boolean | string | null;\n readonly literalType: 'boolean' | 'integer' | 'string' | 'null';\n }\n | {\n readonly type:\n | '('\n | ')'\n | '['\n | ']'\n | ','\n | '.'\n | '::'\n | '='\n | '<>'\n | '!='\n | '<'\n | '<='\n | '>'\n | '>='\n | 'AND'\n | 'OR'\n | 'NOT'\n | 'IN'\n | 'IS'\n | 'EOF';\n }\n | {readonly type: 'unsupported'; readonly value: string};\n\nclass UnsupportedPredicateError extends Error {\n readonly reason: UnsupportedPredicateReason;\n\n constructor(reason: UnsupportedPredicateReason) {\n super(reason);\n this.reason = reason;\n }\n}\n\nexport function translatePostgresIndexPredicate(\n sql: string,\n table: PredicateTableSpec,\n): PredicateTranslation {\n try {\n const parser = new Parser(tokenize(sql));\n const expression = parser.parse();\n parser.expect('EOF');\n return {supported: true, predicate: normalize(expression, table)};\n } catch (error) {\n return {\n supported: false,\n reason:\n error instanceof UnsupportedPredicateError\n ? error.reason\n : 'unsupported-syntax',\n };\n }\n}\n\nclass Parser {\n readonly #tokens: readonly Token[];\n #position = 0;\n\n constructor(tokens: readonly Token[]) {\n this.#tokens = tokens;\n }\n\n parse(): Expr {\n return this.#parseOr();\n }\n\n #parseOr(): Expr {\n const expressions = [this.#parseAnd()];\n while (this.#take('OR')) expressions.push(this.#parseAnd());\n return expressions.length === 1\n ? expressions[0]\n : {type: 'or', expressions};\n }\n\n #parseAnd(): Expr {\n const expressions = [this.#parseNot()];\n while (this.#take('AND')) expressions.push(this.#parseNot());\n return expressions.length === 1\n ? expressions[0]\n : {type: 'and', expressions};\n }\n\n #parseNot(): Expr {\n if (this.#take('NOT')) {\n return {type: 'not', expression: this.#parseNot()};\n }\n return this.#parseComparison();\n }\n\n #parseComparison(): Expr {\n const left = this.#parseOperand();\n if (this.#take('IS')) {\n const not = this.#take('NOT');\n const token = this.#tokens[this.#position++];\n if (token?.type !== 'literal' || token.literalType !== 'null') {\n throw new UnsupportedPredicateError('unsupported-operator');\n }\n return {type: 'null-test', expression: left, not};\n }\n if (this.#take('IN')) {\n this.expect('(');\n const values = this.#parseOperandList(')');\n this.expect(')');\n return comparisons(left, values);\n }\n const op = this.#tokens[this.#position]?.type;\n if (isComparison(op)) {\n this.#position++;\n if (op === '=' && this.#takeIdentifier('ANY')) {\n return comparisons(left, this.#parseLiteralArray());\n }\n return {\n type: 'comparison',\n left,\n op,\n right: this.#parseOperand(),\n };\n }\n const next = this.#tokens[this.#position];\n if (next?.type === 'identifier' && next.value.toUpperCase() === 'COLLATE') {\n throw new UnsupportedPredicateError('non-deterministic-collation');\n }\n if (\n next?.type === 'unsupported' &&\n UNSUPPORTED_OPERATOR_TOKEN_RE.test(next.value)\n ) {\n throw new UnsupportedPredicateError('unsupported-operator');\n }\n if (\n next?.type === 'identifier' &&\n unsupportedOperatorWords.has(next.value.toUpperCase())\n ) {\n throw new UnsupportedPredicateError('unsupported-operator');\n }\n return left;\n }\n\n #parseLiteralArray(): readonly Expr[] {\n this.expect('(');\n this.#expectIdentifier('ARRAY');\n this.expect('[');\n const values = this.#parseOperandList(']');\n this.expect(']');\n if (this.#take('::')) {\n this.#parseCastName();\n this.expect('[');\n this.expect(']');\n }\n this.expect(')');\n return values;\n }\n\n #parseOperandList(end: ')' | ']'): readonly Expr[] {\n const values: Expr[] = [];\n if (this.#tokens[this.#position]?.type === end) return values;\n values.push(this.#parseOperand());\n while (this.#take(',')) values.push(this.#parseOperand());\n return values;\n }\n\n #parseOperand(): Expr {\n let expression = this.#parsePrimary();\n while (this.#take('::')) {\n expression = {\n type: 'cast',\n expression,\n cast: this.#parseCastName(),\n };\n }\n return expression;\n }\n\n #parsePrimary(): Expr {\n if (this.#take('(')) {\n const expression = this.#parseOr();\n this.expect(')');\n return expression;\n }\n const token = this.#tokens[this.#position++];\n if (token?.type === 'literal') {\n return {\n type: 'literal',\n value: token.value,\n literalType: token.literalType,\n };\n }\n if (token?.type === 'identifier') {\n if (this.#tokens[this.#position]?.type === '(') {\n throw new UnsupportedPredicateError('unsupported-function');\n }\n if (this.#tokens[this.#position]?.type === '.') {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n if (token.value.toUpperCase() === 'COLLATE') {\n throw new UnsupportedPredicateError('non-deterministic-collation');\n }\n return {type: 'column', name: token.value};\n }\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n\n #parseCastName(): string {\n const first = this.#expectIdentifier();\n const parts = [first];\n let separator = '.';\n while (this.#take('.')) parts.push(this.#expectIdentifier());\n const next = this.#tokens[this.#position];\n if (\n first.toLowerCase() === 'character' &&\n next?.type === 'identifier' &&\n next.value.toLowerCase() === 'varying'\n ) {\n parts.push(this.#expectIdentifier());\n separator = ' ';\n }\n if (this.#tokens[this.#position]?.type === '(') {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return parts.join(separator);\n }\n\n #expectIdentifier(expected?: string): string {\n const token = this.#tokens[this.#position++];\n if (\n token?.type !== 'identifier' ||\n (expected !== undefined && token.value.toUpperCase() !== expected)\n ) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return token.value;\n }\n\n #takeIdentifier(expected: string): boolean {\n const token = this.#tokens[this.#position];\n if (\n token?.type !== 'identifier' ||\n token.value.toUpperCase() !== expected\n ) {\n return false;\n }\n this.#position++;\n return true;\n }\n\n #take(type: Token['type']): boolean {\n if (this.#tokens[this.#position]?.type !== type) return false;\n this.#position++;\n return true;\n }\n\n expect(type: Token['type']): void {\n if (!this.#take(type)) {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n }\n}\n\nconst unsupportedOperatorWords = new Set([\n 'ALL',\n 'BETWEEN',\n 'ILIKE',\n 'LIKE',\n 'SIMILAR',\n]);\n\nfunction comparisons(left: Expr, values: readonly Expr[]): Expr {\n if (values.length === 0) {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n const expressions = values.map(\n right => ({type: 'comparison', left, op: '=', right}) as const,\n );\n return expressions.length === 1 ? expressions[0] : {type: 'or', expressions};\n}\n\nfunction normalize(\n expression: Expr,\n table: PredicateTableSpec,\n): IndexPredicate {\n switch (expression.type) {\n case 'and':\n case 'or': {\n const conditions = expression.expressions.map(expr =>\n normalize(expr, table),\n );\n return {\n type: expression.type,\n conditions: conditions.flatMap(condition =>\n condition.type === expression.type\n ? condition.conditions\n : [condition],\n ),\n };\n }\n case 'not': {\n const booleanColumn = resolveBareBooleanColumn(\n expression.expression,\n table,\n );\n if (booleanColumn) {\n return booleanComparison(booleanColumn, false);\n }\n return {type: 'not', condition: normalize(expression.expression, table)};\n }\n case 'column': {\n const column = resolveColumn(expression, table);\n if (column.category !== 'boolean') {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return booleanComparison(column.name, true);\n }\n case 'cast': {\n const column = resolveColumnOperand(expression, table);\n if (column.category !== 'boolean') {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return booleanComparison(column.name, true);\n }\n case 'null-test': {\n const column = resolveNullTestColumn(expression.expression, table);\n return {\n type: 'null-test',\n column,\n op: expression.not ? 'IS NOT NULL' : 'IS NULL',\n };\n }\n case 'comparison':\n return normalizeComparison(expression, table);\n case 'literal':\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n}\n\nfunction resolveNullTestColumn(\n expression: Expr,\n table: PredicateTableSpec,\n): string {\n if (expression.type === 'cast') {\n return resolveColumnOperand(expression, table).name;\n }\n if (expression.type === 'column' && !table.columns[expression.name]) {\n throw new UnsupportedPredicateError('unpublished-column');\n }\n if (expression.type === 'column') return expression.name;\n throw new UnsupportedPredicateError('unsupported-syntax');\n}\n\nfunction resolveBareBooleanColumn(\n expression: Expr,\n table: PredicateTableSpec,\n): string | undefined {\n if (expression.type !== 'column' && expression.type !== 'cast') {\n return undefined;\n }\n const column = resolveColumnOperand(expression, table);\n return column.category === 'boolean' ? column.name : undefined;\n}\n\nfunction booleanComparison(column: string, value: boolean): IndexPredicate {\n return {\n type: 'comparison',\n column,\n op: '=',\n value: {type: 'boolean', value},\n };\n}\n\ntype ColumnCategory =\n | {readonly category: 'boolean'; readonly name: string}\n | {\n readonly category: 'integer';\n readonly name: string;\n readonly rank: 0 | 1 | 2;\n }\n | {readonly category: 'text'; readonly name: string}\n | {\n readonly category: 'enum';\n readonly name: string;\n readonly enumName: string;\n }\n | {readonly category: 'uuid'; readonly name: string};\n\nfunction normalizeComparison(\n expression: Extract<Expr, {type: 'comparison'}>,\n table: PredicateTableSpec,\n): IndexPredicate {\n const column = resolveColumnOperand(expression.left, table);\n const op = expression.op === '!=' ? '<>' : expression.op;\n if (column.category !== 'integer' && op !== '=' && op !== '<>') {\n throw new UnsupportedPredicateError('unsupported-operator');\n }\n const value = resolveLiteral(expression.right, column);\n return {type: 'comparison', column: column.name, op, value};\n}\n\nfunction resolveColumnOperand(\n expression: Expr,\n table: PredicateTableSpec,\n): ColumnCategory {\n if (expression.type === 'column') return resolveColumn(expression, table);\n if (expression.type !== 'cast') {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n const column = resolveColumnOperand(expression.expression, table);\n const cast = canonicalTypeName(expression.cast);\n switch (column.category) {\n case 'integer': {\n const rank = integerRank(cast);\n if (rank === undefined || rank < column.rank) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return {...column, rank};\n }\n case 'text':\n if (cast !== 'text' && cast !== 'varchar') {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return column;\n case 'boolean':\n if (cast !== 'bool') {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return column;\n case 'uuid':\n if (cast !== 'uuid') {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return column;\n case 'enum':\n if (lastTypeName(expression.cast) !== column.enumName.toLowerCase()) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return column;\n }\n}\n\nfunction resolveColumn(\n expression: Extract<Expr, {type: 'column'}>,\n table: PredicateTableSpec,\n): ColumnCategory {\n const spec = table.columns[expression.name];\n if (!spec) throw new UnsupportedPredicateError('unpublished-column');\n const dataType = canonicalTypeName(spec.dataType);\n if (dataType === 'bool') return {category: 'boolean', name: expression.name};\n const rank = integerRank(dataType);\n if (rank !== undefined) {\n return {category: 'integer', name: expression.name, rank};\n }\n if (dataType === 'text' || dataType === 'varchar') {\n if (spec.collationIsDeterministic === false) {\n throw new UnsupportedPredicateError('non-deterministic-collation');\n }\n return {category: 'text', name: expression.name};\n }\n if (dataType === 'uuid') return {category: 'uuid', name: expression.name};\n if (spec.pgTypeClass === PostgresTypeClass.Enum) {\n return {\n category: 'enum',\n name: expression.name,\n enumName: spec.dataType.toLowerCase(),\n };\n }\n throw new UnsupportedPredicateError('unsupported-type');\n}\n\nfunction resolveLiteral(\n expression: Expr,\n column: ColumnCategory,\n): IndexPredicateValue {\n let literal = expression;\n let cast: string | undefined;\n while (literal.type === 'cast') {\n cast = literal.cast;\n literal = literal.expression;\n }\n if (literal.type !== 'literal' || literal.value === null) {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n\n switch (column.category) {\n case 'boolean': {\n validateLiteralCast(cast, new Set(['bool']));\n if (literal.literalType !== 'boolean') {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return {type: 'boolean', value: literal.value as boolean};\n }\n case 'integer': {\n if (cast !== undefined) {\n const castRank = integerRank(canonicalTypeName(cast));\n if (castRank === undefined || castRank > column.rank) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n }\n if (\n literal.literalType !== 'integer' &&\n !(literal.literalType === 'string' && cast !== undefined)\n ) {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return {\n type: 'integer',\n value: canonicalInteger(String(literal.value), column.rank),\n };\n }\n case 'text':\n validateLiteralCast(cast, new Set(['text', 'varchar']));\n if (literal.literalType !== 'string') {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return {type: 'string', value: String(literal.value)};\n case 'enum':\n if (\n cast !== undefined &&\n lastTypeName(cast) !== column.enumName.toLowerCase()\n ) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n if (literal.literalType !== 'string') {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return {type: 'string', value: String(literal.value)};\n case 'uuid': {\n validateLiteralCast(cast, new Set(['uuid']));\n const value = String(literal.value).toLowerCase();\n if (literal.literalType !== 'string' || !UUID_RE.test(value)) {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return {type: 'string', value};\n }\n }\n}\n\nfunction validateLiteralCast(\n cast: string | undefined,\n allowed: ReadonlySet<string>,\n): void {\n if (cast !== undefined && !allowed.has(canonicalTypeName(cast))) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n}\n\nfunction canonicalInteger(value: string, rank: 0 | 1 | 2): string {\n if (!INTEGER_RE.test(value)) {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n let integer: bigint;\n try {\n integer = BigInt(value);\n } catch {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n const bounds = [\n [-32768n, 32767n],\n [-2147483648n, 2147483647n],\n [-9223372036854775808n, 9223372036854775807n],\n ] as const;\n if (integer < bounds[rank][0] || integer > bounds[rank][1]) {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return integer.toString();\n}\n\nfunction canonicalTypeName(type: string): string {\n const name = lastTypeName(type).replace(/\\s+/g, ' ');\n switch (name) {\n case 'boolean':\n return 'bool';\n case 'smallint':\n return 'int2';\n case 'integer':\n return 'int4';\n case 'bigint':\n return 'int8';\n case 'character varying':\n return 'varchar';\n default:\n return name;\n }\n}\n\nfunction lastTypeName(type: string): string {\n return type.split('.').at(-1)?.toLowerCase() ?? '';\n}\n\nfunction integerRank(type: string): 0 | 1 | 2 | undefined {\n switch (type) {\n case 'int2':\n return 0;\n case 'int4':\n return 1;\n case 'int8':\n return 2;\n default:\n return undefined;\n }\n}\n\nfunction isComparison(\n type: Token['type'] | undefined,\n): type is '=' | '<>' | '!=' | '<' | '<=' | '>' | '>=' {\n return (\n type === '=' ||\n type === '<>' ||\n type === '!=' ||\n type === '<' ||\n type === '<=' ||\n type === '>' ||\n type === '>='\n );\n}\n\nfunction tokenize(sql: string): readonly Token[] {\n const tokens: Token[] = [];\n for (let i = 0; i < sql.length;) {\n const char = sql[i];\n if (WHITESPACE_RE.test(char)) {\n i++;\n continue;\n }\n if (char === '\"') {\n const result = readQuoted(sql, i, '\"', false);\n tokens.push({type: 'identifier', value: result.value});\n i = result.end;\n continue;\n }\n const escapeString = (char === 'E' || char === 'e') && sql[i + 1] === \"'\";\n if (char === \"'\" || escapeString) {\n const result = readQuoted(\n sql,\n i + (escapeString ? 1 : 0),\n \"'\",\n escapeString,\n );\n tokens.push({\n type: 'literal',\n literalType: 'string',\n value: result.value,\n });\n i = result.end;\n continue;\n }\n const operator = OPERATOR_TOKEN_RE.exec(sql.slice(i))?.[0];\n if (operator) {\n tokens.push({\n type: operator as '::' | '=' | '<>' | '!=' | '<' | '<=' | '>' | '>=',\n });\n i += operator.length;\n continue;\n }\n const unsupportedOperator = UNSUPPORTED_OPERATOR_TOKEN_RE.exec(\n sql.slice(i),\n )?.[0];\n if (unsupportedOperator) {\n tokens.push({type: 'unsupported', value: unsupportedOperator});\n i += unsupportedOperator.length;\n continue;\n }\n if (\n char === '(' ||\n char === ')' ||\n char === '[' ||\n char === ']' ||\n char === ',' ||\n char === '.'\n ) {\n tokens.push({type: char});\n i++;\n continue;\n }\n const integer = INTEGER_TOKEN_RE.exec(sql.slice(i))?.[0];\n if (integer) {\n tokens.push({type: 'literal', literalType: 'integer', value: integer});\n i += integer.length;\n continue;\n }\n const word = WORD_TOKEN_RE.exec(sql.slice(i))?.[0];\n if (word) {\n const keyword = word.toUpperCase();\n if (unsupportedOperatorWords.has(keyword)) {\n throw new UnsupportedPredicateError('unsupported-operator');\n }\n if (keyword === 'TRUE' || keyword === 'FALSE') {\n tokens.push({\n type: 'literal',\n literalType: 'boolean',\n value: keyword === 'TRUE',\n });\n } else if (keyword === 'NULL') {\n tokens.push({type: 'literal', literalType: 'null', value: null});\n } else if (\n keyword === 'AND' ||\n keyword === 'OR' ||\n keyword === 'NOT' ||\n keyword === 'IN' ||\n keyword === 'IS'\n ) {\n tokens.push({type: keyword});\n } else {\n tokens.push({type: 'identifier', value: word.toLowerCase()});\n }\n i += word.length;\n continue;\n }\n tokens.push({type: 'unsupported', value: char});\n i++;\n }\n tokens.push({type: 'EOF'});\n return tokens;\n}\n\nfunction readQuoted(\n sql: string,\n start: number,\n quote: '\"' | \"'\",\n escapes: boolean,\n): {readonly value: string; readonly end: number} {\n let value = '';\n for (let i = start + 1; i < sql.length; i++) {\n const char = sql[i];\n if (char === quote) {\n if (sql[i + 1] === quote) {\n value += quote;\n i++;\n } else {\n return {value, end: i + 1};\n }\n } else if (escapes && char === '\\\\') {\n const escape = sql[++i];\n if (escape === undefined) {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n if (escape === 'x') {\n const hex = readEscapeDigits(sql, i + 1, 2, 16, 1);\n value += String.fromCharCode(hex.value);\n i = hex.end - 1;\n } else if (escape === 'u' || escape === 'U') {\n const hex = readEscapeDigits(sql, i + 1, escape === 'u' ? 4 : 8, 16);\n try {\n value += String.fromCodePoint(hex.value);\n } catch {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n i = hex.end - 1;\n } else if (escape >= '0' && escape <= '7') {\n let octal = escape;\n while (\n octal.length < 3 &&\n sql[i + 1] !== undefined &&\n sql[i + 1] >= '0' &&\n sql[i + 1] <= '7'\n ) {\n octal += sql[++i];\n }\n value += String.fromCharCode(Number.parseInt(octal, 8));\n } else if (escape === '\\n') {\n // A backslash-newline pair is a line continuation.\n } else if (escape === '\\r' && sql[i + 1] === '\\n') {\n i++;\n } else {\n value += SIMPLE_ESCAPES[escape] ?? escape;\n }\n } else {\n value += char;\n }\n }\n throw new UnsupportedPredicateError('unsupported-syntax');\n}\n\nfunction readEscapeDigits(\n sql: string,\n start: number,\n length: number,\n radix: 16,\n minLength = length,\n): {readonly value: number; readonly end: number} {\n let end = start;\n while (end < start + length) {\n const digit = sql[end];\n if (\n digit === undefined ||\n !(\n (digit >= '0' && digit <= '9') ||\n (digit.toLowerCase() >= 'a' && digit.toLowerCase() <= 'f')\n )\n ) {\n break;\n }\n end++;\n }\n const digits = sql.slice(start, end);\n if (digits.length < minLength) {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n return {value: Number.parseInt(digits, radix), end};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index-predicate.js","names":[],"sources":["../../../../../../../../zero-cache/src/services/change-source/pg/schema/index-predicate.ts"],"sourcesContent":["import * as PostgresTypeClass from '../../../../db/postgres-type-class-enum.ts';\nimport type {\n IndexPredicate,\n IndexPredicateValue,\n PublishedTableSpec,\n} from '../../../../db/specs.ts';\n\nconst UUID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\nconst INTEGER_RE = /^[+-]?\\d+$/;\nconst WHITESPACE_RE = /\\s/;\nconst OPERATOR_TOKEN_RE = /^(?:::|<>|!=|<=|>=|=|<|>)/;\nconst UNSUPPORTED_OPERATOR_TOKEN_RE = /^(?:!~\\*|!~|~\\*|~)/;\nconst INTEGER_TOKEN_RE = /^[+-]?\\d+/;\nconst WORD_TOKEN_RE = /^[A-Za-z_][A-Za-z0-9_$]*/;\nconst SIMPLE_ESCAPES: Readonly<Record<string, string>> = {\n b: '\\b',\n f: '\\f',\n n: '\\n',\n r: '\\r',\n t: '\\t',\n v: '\\v',\n};\n\nexport const unsupportedPredicateReasons = [\n 'unpublished-column',\n 'unsupported-type',\n 'unsupported-operator',\n 'unsupported-function',\n 'unsupported-cast',\n 'unsupported-syntax',\n 'non-deterministic-collation',\n] as const;\n\nexport type UnsupportedPredicateReason =\n (typeof unsupportedPredicateReasons)[number];\n\nexport type PredicateTranslation =\n | {readonly supported: true; readonly predicate: IndexPredicate}\n | {readonly supported: false; readonly reason: UnsupportedPredicateReason};\n\ntype PredicateColumnSpec = PublishedTableSpec['columns'][string] & {\n readonly collationIsDeterministic?: boolean | null | undefined;\n};\n\ntype PredicateTableSpec = Omit<PublishedTableSpec, 'columns'> & {\n readonly columns: Readonly<Record<string, PredicateColumnSpec>>;\n};\n\ntype Expr =\n | {readonly type: 'column'; readonly name: string}\n | {\n readonly type: 'literal';\n readonly value: boolean | string | null;\n readonly literalType: 'boolean' | 'integer' | 'string' | 'null';\n }\n | {readonly type: 'cast'; readonly expression: Expr; readonly cast: string}\n | {readonly type: 'not'; readonly expression: Expr}\n | {\n readonly type: 'and' | 'or';\n readonly expressions: readonly Expr[];\n }\n | {\n readonly type: 'comparison';\n readonly left: Expr;\n readonly op: '=' | '<>' | '!=' | '<' | '<=' | '>' | '>=';\n readonly right: Expr;\n }\n | {\n readonly type: 'null-test';\n readonly expression: Expr;\n readonly not: boolean;\n };\n\ntype Token =\n | {readonly type: 'identifier'; readonly value: string}\n | {\n readonly type: 'literal';\n readonly value: boolean | string | null;\n readonly literalType: 'boolean' | 'integer' | 'string' | 'null';\n }\n | {\n readonly type:\n | '('\n | ')'\n | '['\n | ']'\n | ','\n | '.'\n | '::'\n | '='\n | '<>'\n | '!='\n | '<'\n | '<='\n | '>'\n | '>='\n | 'AND'\n | 'OR'\n | 'NOT'\n | 'IN'\n | 'IS'\n | 'EOF';\n }\n | {readonly type: 'unsupported'; readonly value: string};\n\nclass UnsupportedPredicateError extends Error {\n readonly reason: UnsupportedPredicateReason;\n\n constructor(reason: UnsupportedPredicateReason) {\n super(reason);\n this.reason = reason;\n }\n}\n\nexport function translatePostgresIndexPredicate(\n sql: string,\n table: PredicateTableSpec,\n): PredicateTranslation {\n try {\n const parser = new Parser(tokenize(sql));\n const expression = parser.parse();\n parser.expect('EOF');\n return {supported: true, predicate: normalize(expression, table)};\n } catch (error) {\n return {\n supported: false,\n reason:\n error instanceof UnsupportedPredicateError\n ? error.reason\n : 'unsupported-syntax',\n };\n }\n}\n\nclass Parser {\n readonly #tokens: readonly Token[];\n #position = 0;\n\n constructor(tokens: readonly Token[]) {\n this.#tokens = tokens;\n }\n\n parse(): Expr {\n return this.#parseOr();\n }\n\n #parseOr(): Expr {\n const expressions = [this.#parseAnd()];\n while (this.#take('OR')) expressions.push(this.#parseAnd());\n return expressions.length === 1\n ? expressions[0]\n : {type: 'or', expressions};\n }\n\n #parseAnd(): Expr {\n const expressions = [this.#parseNot()];\n while (this.#take('AND')) expressions.push(this.#parseNot());\n return expressions.length === 1\n ? expressions[0]\n : {type: 'and', expressions};\n }\n\n #parseNot(): Expr {\n if (this.#take('NOT')) {\n return {type: 'not', expression: this.#parseNot()};\n }\n return this.#parseComparison();\n }\n\n #parseComparison(): Expr {\n const left = this.#parseOperand();\n if (this.#take('IS')) {\n const not = this.#take('NOT');\n const token = this.#tokens[this.#position++];\n if (token?.type !== 'literal' || token.literalType !== 'null') {\n throw new UnsupportedPredicateError('unsupported-operator');\n }\n return {type: 'null-test', expression: left, not};\n }\n if (this.#take('IN')) {\n this.expect('(');\n const values = this.#parseOperandList(')');\n this.expect(')');\n return comparisons(left, values);\n }\n const op = this.#tokens[this.#position]?.type;\n if (isComparison(op)) {\n this.#position++;\n if (op === '=' && this.#takeIdentifier('ANY')) {\n return comparisons(left, this.#parseLiteralArray());\n }\n return {\n type: 'comparison',\n left,\n op,\n right: this.#parseOperand(),\n };\n }\n const next = this.#tokens[this.#position];\n if (next?.type === 'identifier' && next.value.toUpperCase() === 'COLLATE') {\n throw new UnsupportedPredicateError('non-deterministic-collation');\n }\n if (\n next?.type === 'unsupported' &&\n UNSUPPORTED_OPERATOR_TOKEN_RE.test(next.value)\n ) {\n throw new UnsupportedPredicateError('unsupported-operator');\n }\n if (\n next?.type === 'identifier' &&\n unsupportedOperatorWords.has(next.value.toUpperCase())\n ) {\n throw new UnsupportedPredicateError('unsupported-operator');\n }\n return left;\n }\n\n #parseLiteralArray(): readonly Expr[] {\n this.expect('(');\n this.#expectIdentifier('ARRAY');\n this.expect('[');\n const values = this.#parseOperandList(']');\n this.expect(']');\n if (this.#take('::')) {\n this.#parseCastName();\n this.expect('[');\n this.expect(']');\n }\n this.expect(')');\n return values;\n }\n\n #parseOperandList(end: ')' | ']'): readonly Expr[] {\n const values: Expr[] = [];\n if (this.#tokens[this.#position]?.type === end) return values;\n values.push(this.#parseOperand());\n while (this.#take(',')) values.push(this.#parseOperand());\n return values;\n }\n\n #parseOperand(): Expr {\n let expression = this.#parsePrimary();\n while (this.#take('::')) {\n expression = {\n type: 'cast',\n expression,\n cast: this.#parseCastName(),\n };\n }\n return expression;\n }\n\n #parsePrimary(): Expr {\n if (this.#take('(')) {\n const expression = this.#parseOr();\n this.expect(')');\n return expression;\n }\n const token = this.#tokens[this.#position++];\n if (token?.type === 'literal') {\n return {\n type: 'literal',\n value: token.value,\n literalType: token.literalType,\n };\n }\n if (token?.type === 'identifier') {\n if (this.#tokens[this.#position]?.type === '(') {\n throw new UnsupportedPredicateError('unsupported-function');\n }\n if (this.#tokens[this.#position]?.type === '.') {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n if (token.value.toUpperCase() === 'COLLATE') {\n throw new UnsupportedPredicateError('non-deterministic-collation');\n }\n return {type: 'column', name: token.value};\n }\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n\n #parseCastName(): string {\n const first = this.#expectIdentifier();\n const parts = [first];\n let separator = '.';\n while (this.#take('.')) parts.push(this.#expectIdentifier());\n const next = this.#tokens[this.#position];\n if (\n first.toLowerCase() === 'character' &&\n next?.type === 'identifier' &&\n next.value.toLowerCase() === 'varying'\n ) {\n parts.push(this.#expectIdentifier());\n separator = ' ';\n }\n if (this.#tokens[this.#position]?.type === '(') {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return parts.join(separator);\n }\n\n #expectIdentifier(expected?: string): string {\n const token = this.#tokens[this.#position++];\n if (\n token?.type !== 'identifier' ||\n (expected !== undefined && token.value.toUpperCase() !== expected)\n ) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return token.value;\n }\n\n #takeIdentifier(expected: string): boolean {\n const token = this.#tokens[this.#position];\n if (\n token?.type !== 'identifier' ||\n token.value.toUpperCase() !== expected\n ) {\n return false;\n }\n this.#position++;\n return true;\n }\n\n #take(type: Token['type']): boolean {\n if (this.#tokens[this.#position]?.type !== type) return false;\n this.#position++;\n return true;\n }\n\n expect(type: Token['type']): void {\n if (!this.#take(type)) {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n }\n}\n\nconst unsupportedOperatorWords = new Set([\n 'ALL',\n 'BETWEEN',\n 'ILIKE',\n 'LIKE',\n 'SIMILAR',\n]);\n\nfunction comparisons(left: Expr, values: readonly Expr[]): Expr {\n if (values.length === 0) {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n const expressions = values.map(\n right => ({type: 'comparison', left, op: '=', right}) as const,\n );\n return expressions.length === 1 ? expressions[0] : {type: 'or', expressions};\n}\n\nfunction normalize(\n expression: Expr,\n table: PredicateTableSpec,\n): IndexPredicate {\n switch (expression.type) {\n case 'and':\n case 'or': {\n const conditions = expression.expressions.map(expr =>\n normalize(expr, table),\n );\n return {\n type: expression.type,\n conditions: conditions.flatMap(condition =>\n condition.type === expression.type\n ? condition.conditions\n : [condition],\n ),\n };\n }\n case 'not': {\n const booleanColumn = resolveBareBooleanColumn(\n expression.expression,\n table,\n );\n if (booleanColumn) {\n return booleanComparison(booleanColumn, false);\n }\n return {type: 'not', condition: normalize(expression.expression, table)};\n }\n case 'column': {\n const column = resolveColumn(expression, table);\n if (column.category !== 'boolean') {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return booleanComparison(column.name, true);\n }\n case 'cast': {\n const column = resolveColumnOperand(expression, table);\n if (column.category !== 'boolean') {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return booleanComparison(column.name, true);\n }\n case 'null-test': {\n const column = resolveNullTestColumn(expression.expression, table);\n return {\n type: 'null-test',\n column,\n op: expression.not ? 'IS NOT NULL' : 'IS NULL',\n };\n }\n case 'comparison':\n return normalizeComparison(expression, table);\n case 'literal':\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n}\n\nfunction resolveNullTestColumn(\n expression: Expr,\n table: PredicateTableSpec,\n): string {\n if (expression.type === 'cast') {\n return resolveColumnOperand(expression, table).name;\n }\n if (expression.type === 'column' && !table.columns[expression.name]) {\n throw new UnsupportedPredicateError('unpublished-column');\n }\n if (expression.type === 'column') return expression.name;\n throw new UnsupportedPredicateError('unsupported-syntax');\n}\n\nfunction resolveBareBooleanColumn(\n expression: Expr,\n table: PredicateTableSpec,\n): string | undefined {\n if (expression.type !== 'column' && expression.type !== 'cast') {\n return undefined;\n }\n const column = resolveColumnOperand(expression, table);\n return column.category === 'boolean' ? column.name : undefined;\n}\n\nfunction booleanComparison(column: string, value: boolean): IndexPredicate {\n return {\n type: 'comparison',\n column,\n op: '=',\n value: {type: 'boolean', value},\n };\n}\n\ntype ColumnCategory =\n | {readonly category: 'boolean'; readonly name: string}\n | {\n readonly category: 'integer';\n readonly name: string;\n readonly rank: 0 | 1 | 2;\n }\n | {readonly category: 'text'; readonly name: string}\n | {\n readonly category: 'enum';\n readonly name: string;\n readonly enumName: string;\n }\n | {readonly category: 'uuid'; readonly name: string};\n\nfunction normalizeComparison(\n expression: Extract<Expr, {type: 'comparison'}>,\n table: PredicateTableSpec,\n): IndexPredicate {\n const column = resolveColumnOperand(expression.left, table);\n const op = expression.op === '!=' ? '<>' : expression.op;\n if (column.category !== 'integer' && op !== '=' && op !== '<>') {\n throw new UnsupportedPredicateError('unsupported-operator');\n }\n const value = resolveLiteral(expression.right, column);\n return {type: 'comparison', column: column.name, op, value};\n}\n\nfunction resolveColumnOperand(\n expression: Expr,\n table: PredicateTableSpec,\n): ColumnCategory {\n if (expression.type === 'column') return resolveColumn(expression, table);\n if (expression.type !== 'cast') {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n const column = resolveColumnOperand(expression.expression, table);\n const cast = canonicalTypeName(expression.cast);\n switch (column.category) {\n case 'integer': {\n const rank = integerRank(cast);\n if (rank === undefined || rank < column.rank) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return {...column, rank};\n }\n case 'text':\n if (cast !== 'text' && cast !== 'varchar') {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return column;\n case 'boolean':\n if (cast !== 'bool') {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return column;\n case 'uuid':\n if (cast !== 'uuid') {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return column;\n case 'enum':\n if (lastTypeName(expression.cast) !== column.enumName.toLowerCase()) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n return column;\n }\n}\n\nfunction resolveColumn(\n expression: Extract<Expr, {type: 'column'}>,\n table: PredicateTableSpec,\n): ColumnCategory {\n const spec = table.columns[expression.name];\n if (!spec) throw new UnsupportedPredicateError('unpublished-column');\n const dataType = canonicalTypeName(spec.dataType);\n if (dataType === 'bool') return {category: 'boolean', name: expression.name};\n const rank = integerRank(dataType);\n if (rank !== undefined) {\n return {category: 'integer', name: expression.name, rank};\n }\n if (dataType === 'text' || dataType === 'varchar') {\n if (spec.collationIsDeterministic === false) {\n throw new UnsupportedPredicateError('non-deterministic-collation');\n }\n return {category: 'text', name: expression.name};\n }\n if (dataType === 'uuid') return {category: 'uuid', name: expression.name};\n if (spec.pgTypeClass === PostgresTypeClass.Enum) {\n return {\n category: 'enum',\n name: expression.name,\n enumName: spec.dataType.toLowerCase(),\n };\n }\n throw new UnsupportedPredicateError('unsupported-type');\n}\n\nfunction resolveLiteral(\n expression: Expr,\n column: ColumnCategory,\n): IndexPredicateValue {\n let literal = expression;\n let cast: string | undefined;\n while (literal.type === 'cast') {\n cast = literal.cast;\n literal = literal.expression;\n }\n if (literal.type !== 'literal' || literal.value === null) {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n\n switch (column.category) {\n case 'boolean': {\n validateLiteralCast(cast, new Set(['bool']));\n if (literal.literalType !== 'boolean') {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return {type: 'boolean', value: literal.value as boolean};\n }\n case 'integer': {\n if (cast !== undefined) {\n const castRank = integerRank(canonicalTypeName(cast));\n if (castRank === undefined || castRank > column.rank) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n }\n if (\n literal.literalType !== 'integer' &&\n !(literal.literalType === 'string' && cast !== undefined)\n ) {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return {\n type: 'integer',\n value: canonicalInteger(String(literal.value), column.rank),\n };\n }\n case 'text':\n validateLiteralCast(cast, new Set(['text', 'varchar']));\n if (literal.literalType !== 'string') {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return {type: 'string', value: String(literal.value)};\n case 'enum':\n if (\n cast !== undefined &&\n lastTypeName(cast) !== column.enumName.toLowerCase()\n ) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n if (literal.literalType !== 'string') {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return {type: 'string', value: String(literal.value)};\n case 'uuid': {\n validateLiteralCast(cast, new Set(['uuid']));\n const value = String(literal.value).toLowerCase();\n if (literal.literalType !== 'string' || !UUID_RE.test(value)) {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return {type: 'string', value};\n }\n }\n}\n\nfunction validateLiteralCast(\n cast: string | undefined,\n allowed: ReadonlySet<string>,\n): void {\n if (cast !== undefined && !allowed.has(canonicalTypeName(cast))) {\n throw new UnsupportedPredicateError('unsupported-cast');\n }\n}\n\nfunction canonicalInteger(value: string, rank: 0 | 1 | 2): string {\n if (!INTEGER_RE.test(value)) {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n let integer: bigint;\n try {\n integer = BigInt(value);\n } catch {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n const bounds = [\n [-32768n, 32767n],\n [-2147483648n, 2147483647n],\n [-9223372036854775808n, 9223372036854775807n],\n ] as const;\n if (integer < bounds[rank][0] || integer > bounds[rank][1]) {\n throw new UnsupportedPredicateError('unsupported-type');\n }\n return integer.toString();\n}\n\nfunction canonicalTypeName(type: string): string {\n const name = lastTypeName(type).replace(/\\s+/g, ' ');\n switch (name) {\n case 'boolean':\n return 'bool';\n case 'smallint':\n return 'int2';\n case 'integer':\n return 'int4';\n case 'bigint':\n return 'int8';\n case 'character varying':\n return 'varchar';\n default:\n return name;\n }\n}\n\nfunction lastTypeName(type: string): string {\n return type.split('.').at(-1)?.toLowerCase() ?? '';\n}\n\nfunction integerRank(type: string): 0 | 1 | 2 | undefined {\n switch (type) {\n case 'int2':\n return 0;\n case 'int4':\n return 1;\n case 'int8':\n return 2;\n default:\n return undefined;\n }\n}\n\nfunction isComparison(\n type: Token['type'] | undefined,\n): type is '=' | '<>' | '!=' | '<' | '<=' | '>' | '>=' {\n return (\n type === '=' ||\n type === '<>' ||\n type === '!=' ||\n type === '<' ||\n type === '<=' ||\n type === '>' ||\n type === '>='\n );\n}\n\nfunction tokenize(sql: string): readonly Token[] {\n const tokens: Token[] = [];\n for (let i = 0; i < sql.length;) {\n const char = sql[i];\n if (WHITESPACE_RE.test(char)) {\n i++;\n continue;\n }\n if (char === '\"') {\n const result = readQuoted(sql, i, '\"', false);\n tokens.push({type: 'identifier', value: result.value});\n i = result.end;\n continue;\n }\n const escapeString = (char === 'E' || char === 'e') && sql[i + 1] === \"'\";\n if (char === \"'\" || escapeString) {\n const result = readQuoted(\n sql,\n i + (escapeString ? 1 : 0),\n \"'\",\n escapeString,\n );\n tokens.push({\n type: 'literal',\n literalType: 'string',\n value: result.value,\n });\n i = result.end;\n continue;\n }\n const operator = OPERATOR_TOKEN_RE.exec(sql.slice(i))?.[0];\n if (operator) {\n tokens.push({\n type: operator as '::' | '=' | '<>' | '!=' | '<' | '<=' | '>' | '>=',\n });\n i += operator.length;\n continue;\n }\n const unsupportedOperator = UNSUPPORTED_OPERATOR_TOKEN_RE.exec(\n sql.slice(i),\n )?.[0];\n if (unsupportedOperator) {\n tokens.push({type: 'unsupported', value: unsupportedOperator});\n i += unsupportedOperator.length;\n continue;\n }\n if (\n char === '(' ||\n char === ')' ||\n char === '[' ||\n char === ']' ||\n char === ',' ||\n char === '.'\n ) {\n tokens.push({type: char});\n i++;\n continue;\n }\n const integer = INTEGER_TOKEN_RE.exec(sql.slice(i))?.[0];\n if (integer) {\n tokens.push({type: 'literal', literalType: 'integer', value: integer});\n i += integer.length;\n continue;\n }\n const word = WORD_TOKEN_RE.exec(sql.slice(i))?.[0];\n if (word) {\n const keyword = word.toUpperCase();\n if (unsupportedOperatorWords.has(keyword)) {\n throw new UnsupportedPredicateError('unsupported-operator');\n }\n if (keyword === 'TRUE' || keyword === 'FALSE') {\n tokens.push({\n type: 'literal',\n literalType: 'boolean',\n value: keyword === 'TRUE',\n });\n } else if (keyword === 'NULL') {\n tokens.push({type: 'literal', literalType: 'null', value: null});\n } else if (\n keyword === 'AND' ||\n keyword === 'OR' ||\n keyword === 'NOT' ||\n keyword === 'IN' ||\n keyword === 'IS'\n ) {\n tokens.push({type: keyword});\n } else {\n tokens.push({type: 'identifier', value: word.toLowerCase()});\n }\n i += word.length;\n continue;\n }\n tokens.push({type: 'unsupported', value: char});\n i++;\n }\n tokens.push({type: 'EOF'});\n return tokens;\n}\n\nfunction readQuoted(\n sql: string,\n start: number,\n quote: '\"' | \"'\",\n escapes: boolean,\n): {readonly value: string; readonly end: number} {\n let value = '';\n for (let i = start + 1; i < sql.length; i++) {\n const char = sql[i];\n if (char === quote) {\n if (sql[i + 1] === quote) {\n value += quote;\n i++;\n } else {\n return {value, end: i + 1};\n }\n } else if (escapes && char === '\\\\') {\n const escape = sql[++i];\n if (escape === undefined) {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n if (escape === 'x') {\n const hex = readEscapeDigits(sql, i + 1, 2, 16, 1);\n value += String.fromCharCode(hex.value);\n i = hex.end - 1;\n } else if (escape === 'u' || escape === 'U') {\n const hex = readEscapeDigits(sql, i + 1, escape === 'u' ? 4 : 8, 16);\n try {\n value += String.fromCodePoint(hex.value);\n } catch {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n i = hex.end - 1;\n } else if (escape >= '0' && escape <= '7') {\n let octal = escape;\n while (\n octal.length < 3 &&\n sql[i + 1] !== undefined &&\n sql[i + 1] >= '0' &&\n sql[i + 1] <= '7'\n ) {\n octal += sql[++i];\n }\n value += String.fromCharCode(Number.parseInt(octal, 8));\n } else if (escape === '\\n') {\n // A backslash-newline pair is a line continuation.\n } else if (escape === '\\r' && sql[i + 1] === '\\n') {\n i++;\n } else {\n value += SIMPLE_ESCAPES[escape] ?? escape;\n }\n } else {\n value += char;\n }\n }\n throw new UnsupportedPredicateError('unsupported-syntax');\n}\n\nfunction readEscapeDigits(\n sql: string,\n start: number,\n length: number,\n radix: 16,\n minLength = length,\n): {readonly value: number; readonly end: number} {\n let end = start;\n while (end < start + length) {\n const digit = sql[end];\n if (\n digit === undefined ||\n !(\n (digit >= '0' && digit <= '9') ||\n (digit.toLowerCase() >= 'a' && digit.toLowerCase() <= 'f')\n )\n ) {\n break;\n }\n end++;\n }\n const digits = sql.slice(start, end);\n if (digits.length < minLength) {\n throw new UnsupportedPredicateError('unsupported-syntax');\n }\n return {value: Number.parseInt(digits, radix), end};\n}\n"],"mappings":"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"}
@@ -4,6 +4,6 @@ import { type ShardConfig } from '../../../../types/shards.ts';
4
4
  /**
5
5
  * Ensures that a shard is set up for initial sync.
6
6
  */
7
- export declare function ensureShardSchema(lc: LogContext, db: PostgresDB, shard: ShardConfig): Promise<void>;
7
+ export declare function ensureShardSchema(lc: LogContext, db: PostgresDB, shard: ShardConfig, installPartialIndexTriggers?: boolean): Promise<void>;
8
8
  export declare const CURRENT_SCHEMA_VERSION: number;
9
9
  //# sourceMappingURL=init.d.ts.map
@@ -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;AAa7E;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,UAAU,EACd,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAuSD,eAAO,MAAM,sBAAsB,QAMwB,CAAC"}
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;AAa7E;;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;AA8SD,eAAO,MAAM,sBAAsB,QASwB,CAAC"}
@@ -11,13 +11,13 @@ import { runSchemaMigrations } from "../../../../db/migration.js";
11
11
  /**
12
12
  * Ensures that a shard is set up for initial sync.
13
13
  */
14
- async function ensureShardSchema(lc, db, shard) {
14
+ async function ensureShardSchema(lc, db, shard, installPartialIndexTriggers = true) {
15
15
  await runSchemaMigrations(lc, `upstream-shard-${shard.appID}`, upstreamSchema(shard), db, {
16
- migrateSchema: (lc, tx) => setupTablesAndReplication(lc, tx, shard),
16
+ migrateSchema: (lc, tx) => setupTablesAndReplication(lc, tx, shard, installPartialIndexTriggers),
17
17
  minSafeVersion: 1
18
- }, getIncrementalMigrations(shard));
18
+ }, getIncrementalMigrations(shard, installPartialIndexTriggers));
19
19
  }
20
- function getIncrementalMigrations(shard) {
20
+ function getIncrementalMigrations(shard, installPartialIndexTriggers) {
21
21
  const shardConfigTable = `${upstreamSchema(shard)}.shardConfig`;
22
22
  return {
23
23
  6: { migrateSchema: () => {
@@ -175,22 +175,22 @@ function getIncrementalMigrations(shard) {
175
175
  `;
176
176
  }
177
177
  },
178
- 31: { migrateSchema: async (lc, sql) => {
178
+ ...installPartialIndexTriggers ? { 31: { migrateSchema: async (lc, sql) => {
179
179
  const [{ publications }] = await sql`
180
- SELECT publications FROM ${sql(shardConfigTable)}`;
180
+ SELECT publications FROM ${sql(shardConfigTable)}`;
181
181
  await setupTriggers(lc, sql, {
182
182
  ...shard,
183
183
  publications
184
184
  });
185
185
  lc.info?.(`Upgraded DDL event triggers`);
186
- } }
186
+ } } } : {}
187
187
  };
188
188
  }
189
189
  Object.keys(getIncrementalMigrations({
190
190
  appID: "unused",
191
191
  shardNum: 0,
192
192
  publications: ["foo"]
193
- })).reduce((prev, curr) => Math.max(prev, parseInt(curr)), 0);
193
+ }, true)).reduce((prev, curr) => Math.max(prev, parseInt(curr)), 0);
194
194
  //#endregion
195
195
  export { ensureShardSchema };
196
196
 
@@ -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 * as ReplicaStage from './replica-stage-enum.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 //\n // Note: This is retained (despite v31 also upgrading the triggers) because\n // the v28 migration depends on the update_schemas() function.\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 // v27 (1.11.0):\n // - make `generation` NOT NULL and stop reading `version`\n 27: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas ALTER \"generation\" SET NOT NULL;\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas ALTER \"version\" DROP NOT NULL;\n `;\n },\n },\n\n 28: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas ADD \"epoch\" INT4 DEFAULT 0;\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas ADD \"stage\" INT4 DEFAULT 0; -- ReplicaStage.InitialSync\n `;\n\n const metapub = metadataPublicationName(shard.appID, shard.shardNum);\n await sql`\n ALTER PUBLICATION ${sql(metapub)} ADD TABLE ${sql(upstreamSchema(shard))}.replicas (id);\n `;\n // Make sure supabase gets the ALTER PUBLICATION change\n await sql`\n SELECT ${sql(upstreamSchema(shard))}.update_schemas();\n `;\n },\n\n migrateData: async (_, sql) => {\n await sql`\n UPDATE ${sql(upstreamSchema(shard))}.replicas SET \"stage\" = ${ReplicaStage.Replicate}\n WHERE \"subscriberContext\" IS NOT NULL;\n `;\n },\n },\n\n // v30: Adds the \"pgChangeLog\" column, which records whether the\n // replication-manager that took over a replica's slot acks it only after\n // storing transactions in the PG change log (RMv1.5), in which case a\n // slot position past the change log's head reflects acked keepalives\n // rather than missing transactions.\n //\n // The column defaults to false (i.e. unknown), so that a slot is assumed\n // to be possibly ahead of the change log until it is taken over by a\n // replication-manager that sets it. Existing replicas that have been taken\n // over are backfilled as true (see migrateData). Note that a replication-manager that\n // predates this column does not reset it when taking over a slot, so\n // once the column is set, RMv2 (in which acks are not gated on the PG\n // change log) must run at least this version.\n 30: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN IF NOT EXISTS \"pgChangeLog\" BOOL DEFAULT false;\n `;\n },\n\n // Existing replicas whose slots have been taken over (i.e. that have a\n // subscriberContext) were acked by RMv1 or RMv1.5, which store\n // transactions in the PG change log before acking them. This assumes\n // that no RMv2 is running when the migration is run. Replicas that have\n // not been taken over (e.g. fork destinations) remain unknown, as their\n // slots have not been acked.\n migrateData: async (_, sql) => {\n await sql`\n UPDATE ${sql(upstreamSchema(shard))}.replicas SET \"pgChangeLog\" = true\n WHERE \"subscriberContext\" IS NOT NULL;\n `;\n },\n },\n\n // v31: 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 31: {\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// 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":["v","v.parse"],"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 * as ReplicaStage from './replica-stage-enum.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 // v27 (1.11.0):\n // - make `generation` NOT NULL and stop reading `version`\n 27: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas ALTER \"generation\" SET NOT NULL;\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas ALTER \"version\" DROP NOT NULL;\n `;\n },\n },\n\n 28: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas ADD \"epoch\" INT4 DEFAULT 0;\n `;\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas ADD \"stage\" INT4 DEFAULT 0; -- ReplicaStage.InitialSync\n `;\n\n const metapub = metadataPublicationName(shard.appID, shard.shardNum);\n await sql`\n ALTER PUBLICATION ${sql(metapub)} ADD TABLE ${sql(upstreamSchema(shard))}.replicas (id);\n `;\n // Make sure supabase gets the ALTER PUBLICATION change\n await sql`\n SELECT ${sql(upstreamSchema(shard))}.update_schemas();\n `;\n },\n\n migrateData: async (_, sql) => {\n await sql`\n UPDATE ${sql(upstreamSchema(shard))}.replicas SET \"stage\" = ${ReplicaStage.Replicate}\n WHERE \"subscriberContext\" IS NOT NULL;\n `;\n },\n },\n\n // v30: Adds the \"pgChangeLog\" column, which records whether the\n // replication-manager that took over a replica's slot acks it only after\n // storing transactions in the PG change log (RMv1.5), in which case a\n // slot position past the change log's head reflects acked keepalives\n // rather than missing transactions.\n //\n // The column defaults to false (i.e. unknown), so that a slot is assumed\n // to be possibly ahead of the change log until it is taken over by a\n // replication-manager that sets it. Existing replicas that have been taken\n // over are backfilled as true (see migrateData). Note that a replication-manager that\n // predates this column does not reset it when taking over a slot, so\n // once the column is set, RMv2 (in which acks are not gated on the PG\n // change log) must run at least this version.\n 30: {\n migrateSchema: async (_, sql) => {\n await sql`\n ALTER TABLE ${sql(upstreamSchema(shard))}.replicas \n ADD COLUMN IF NOT EXISTS \"pgChangeLog\" BOOL DEFAULT false;\n `;\n },\n\n // Existing replicas whose slots have been taken over (i.e. that have a\n // subscriberContext) were acked by RMv1 or RMv1.5, which store\n // transactions in the PG change log before acking them. This assumes\n // that no RMv2 is running when the migration is run. Replicas that have\n // not been taken over (e.g. fork destinations) remain unknown, as their\n // slots have not been acked.\n migrateData: async (_, sql) => {\n await sql`\n UPDATE ${sql(upstreamSchema(shard))}.replicas SET \"pgChangeLog\" = true\n WHERE \"subscriberContext\" IS NOT NULL;\n `;\n },\n },\n\n // Note: While this is conditional, it always has to be bumped to the last\n // version. (It was v29, and is re-run for shards at v29 when it is bumped,\n // which is harmless as setupTriggers() is idempotent.)\n ...(installPartialIndexTriggers\n ? {\n // v31: 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 31: {\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":"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"}
@@ -2,7 +2,7 @@ import type { LogContext } from '@rocicorp/logger';
2
2
  import type postgres from 'postgres';
3
3
  import * as v from '../../../../../../shared/src/valita.ts';
4
4
  import { type UnsupportedPredicateReason } from './index-predicate.ts';
5
- export declare function publishedSchemaQuery(publications: readonly string[]): string;
5
+ export declare function publishedSchemaQuery(publications: readonly string[], includePartialIndexes?: boolean): string;
6
6
  export type SkippedIndexDiagnostic = {
7
7
  readonly schema: string;
8
8
  readonly index: string;
@@ -1 +1 @@
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,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,UA6KnE;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"}
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"}
@@ -10,7 +10,7 @@ import { getOrCreateCounter } from "../../../../observability/metrics.js";
10
10
  import { translatePostgresIndexPredicate } from "./index-predicate.js";
11
11
  import { literal } from "pg-format";
12
12
  //#region ../zero-cache/src/services/change-source/pg/schema/published.ts
13
- function publishedSchemaQuery(publications) {
13
+ function publishedSchemaQuery(publications, includePartialIndexes = true) {
14
14
  return `
15
15
  WITH published_columns AS (SELECT
16
16
  pc.oid::int8 AS "oid",
@@ -129,6 +129,7 @@ tables AS (SELECT json_build_object(
129
129
  LEFT JOIN pg_constraint ON pg_constraint.conindid = pc.oid
130
130
  WHERE pb.pubname IN (${literal(publications)})
131
131
  AND pg_index.indexprs IS NULL
132
+ AND (${includePartialIndexes} OR pg_index.indpred IS NULL)
132
133
  AND (pg_constraint.contype IS NULL OR pg_constraint.contype IN ('p', 'u'))
133
134
  AND indexed.attnames <@ pb.attnames
134
135
  AND (current_setting('server_version_num')::int >= 160000 OR false = ALL(indexed.generated))
@@ -286,6 +287,6 @@ async function getPublicationInfo(sql, publications) {
286
287
  return info;
287
288
  }
288
289
  //#endregion
289
- export { getPublicationInfo, publishedSchema, publishedSchemaQuery, warnForSkippedIndexes };
290
+ export { getPublicationInfo, getSkippedIndexDiagnostics, publishedSchema, publishedSchemaQuery, warnForSkippedIndexes };
290
291
 
291
292
  //# sourceMappingURL=published.js.map