@rocicorp/zero 1.10.0-canary.21 → 1.10.0-canary.22

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 (224) hide show
  1. package/out/analyze-query/src/analyze-cli.js +2 -2
  2. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  3. package/out/replicache/src/dag/gc.d.ts.map +1 -1
  4. package/out/replicache/src/dag/gc.js +2 -1
  5. package/out/replicache/src/dag/gc.js.map +1 -1
  6. package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
  7. package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
  8. package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
  9. package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
  10. package/out/replicache/src/dag/store-impl.d.ts +12 -2
  11. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  12. package/out/replicache/src/dag/store-impl.js +22 -8
  13. package/out/replicache/src/dag/store-impl.js.map +1 -1
  14. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
  15. package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
  16. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  17. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +15 -5
  18. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +1 -1
  19. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +25 -25
  20. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -1
  21. package/out/replicache/src/kv/idb-store.d.ts +9 -0
  22. package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
  23. package/out/replicache/src/kv/idb-store.js +14 -2
  24. package/out/replicache/src/kv/idb-store.js.map +1 -1
  25. package/out/replicache/src/kv/mem-store.d.ts +1 -0
  26. package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
  27. package/out/replicache/src/kv/mem-store.js +3 -0
  28. package/out/replicache/src/kv/mem-store.js.map +1 -1
  29. package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
  30. package/out/replicache/src/kv/op-sqlite/store.js +1 -1
  31. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  32. package/out/replicache/src/kv/sqlite-store.d.ts +2 -1
  33. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  34. package/out/replicache/src/kv/sqlite-store.js +6 -1
  35. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  36. package/out/replicache/src/kv/store.d.ts +6 -0
  37. package/out/replicache/src/kv/store.d.ts.map +1 -1
  38. package/out/replicache/src/persist/collect-idb-databases.d.ts +10 -5
  39. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  40. package/out/replicache/src/persist/collect-idb-databases.js +16 -9
  41. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  42. package/out/replicache/src/replicache-impl.d.ts +14 -3
  43. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  44. package/out/replicache/src/replicache-impl.js +104 -9
  45. package/out/replicache/src/replicache-impl.js.map +1 -1
  46. package/out/shared/src/arrays.js +1 -15
  47. package/out/shared/src/arrays.js.map +1 -1
  48. package/out/shared/src/hash.d.ts +1 -0
  49. package/out/shared/src/hash.d.ts.map +1 -1
  50. package/out/shared/src/hash.js +10 -28
  51. package/out/shared/src/hash.js.map +1 -1
  52. package/out/shared/src/iterables.d.ts +2 -0
  53. package/out/shared/src/iterables.d.ts.map +1 -1
  54. package/out/shared/src/iterables.js +18 -1
  55. package/out/shared/src/iterables.js.map +1 -1
  56. package/out/shared/src/json.d.ts.map +1 -1
  57. package/out/shared/src/json.js +2 -2
  58. package/out/shared/src/json.js.map +1 -1
  59. package/out/shared/src/ring-buffer.d.ts +8 -0
  60. package/out/shared/src/ring-buffer.d.ts.map +1 -1
  61. package/out/shared/src/ring-buffer.js +22 -1
  62. package/out/shared/src/ring-buffer.js.map +1 -1
  63. package/out/shared/src/xxhash32.d.ts +36 -0
  64. package/out/shared/src/xxhash32.d.ts.map +1 -0
  65. package/out/shared/src/xxhash32.js +51 -0
  66. package/out/shared/src/xxhash32.js.map +1 -0
  67. package/out/z2s/src/compiler.js +1 -1
  68. package/out/zero/package.js +1 -1
  69. package/out/zero/package.js.map +1 -1
  70. package/out/zero-cache/src/auth/read-authorizer.js +1 -1
  71. package/out/zero-cache/src/custom-queries/transform-query.js +1 -1
  72. package/out/zero-cache/src/server/inspector-delegate.js +3 -2
  73. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  74. package/out/zero-cache/src/services/change-source/custom/change-source.js +2 -2
  75. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  76. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +3 -3
  77. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  78. package/out/zero-cache/src/services/mutagen/pusher.js +1 -1
  79. package/out/zero-cache/src/services/run-ast.js +1 -1
  80. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  81. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +6 -10
  82. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  83. package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
  84. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  85. package/out/zero-cache/src/workers/connection.js +3 -3
  86. package/out/zero-cache/src/workers/connection.js.map +1 -1
  87. package/out/zero-client/src/client/connection-manager.d.ts +20 -0
  88. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  89. package/out/zero-client/src/client/connection-manager.js +32 -14
  90. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  91. package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
  92. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  93. package/out/zero-client/src/client/connection-status-enum.js +3 -1
  94. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  95. package/out/zero-client/src/client/connection.d.ts +6 -0
  96. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  97. package/out/zero-client/src/client/connection.js +2 -1
  98. package/out/zero-client/src/client/connection.js.map +1 -1
  99. package/out/zero-client/src/client/context.d.ts +8 -11
  100. package/out/zero-client/src/client/context.d.ts.map +1 -1
  101. package/out/zero-client/src/client/context.js +11 -15
  102. package/out/zero-client/src/client/context.js.map +1 -1
  103. package/out/zero-client/src/client/custom.js +2 -2
  104. package/out/zero-client/src/client/custom.js.map +1 -1
  105. package/out/zero-client/src/client/error.js +1 -1
  106. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  107. package/out/zero-client/src/client/mutator-proxy.js +2 -1
  108. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  109. package/out/zero-client/src/client/options.d.ts +3 -0
  110. package/out/zero-client/src/client/options.d.ts.map +1 -1
  111. package/out/zero-client/src/client/options.js.map +1 -1
  112. package/out/zero-client/src/client/query-manager.d.ts +2 -0
  113. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  114. package/out/zero-client/src/client/query-manager.js +48 -9
  115. package/out/zero-client/src/client/query-manager.js.map +1 -1
  116. package/out/zero-client/src/client/version.js +1 -1
  117. package/out/zero-client/src/client/zero.d.ts +18 -3
  118. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  119. package/out/zero-client/src/client/zero.js +59 -12
  120. package/out/zero-client/src/client/zero.js.map +1 -1
  121. package/out/zero-client/src/types/query-result.d.ts +2 -0
  122. package/out/zero-client/src/types/query-result.d.ts.map +1 -1
  123. package/out/zero-protocol/src/ast.d.ts +64 -1
  124. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  125. package/out/zero-protocol/src/ast.js +223 -51
  126. package/out/zero-protocol/src/ast.js.map +1 -1
  127. package/out/zero-protocol/src/query-hash-visitor.d.ts +81 -0
  128. package/out/zero-protocol/src/query-hash-visitor.d.ts.map +1 -0
  129. package/out/zero-protocol/src/query-hash-visitor.js +324 -0
  130. package/out/zero-protocol/src/query-hash-visitor.js.map +1 -0
  131. package/out/zero-protocol/src/query-hash.d.ts +7 -2
  132. package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
  133. package/out/zero-protocol/src/query-hash.js +12 -9
  134. package/out/zero-protocol/src/query-hash.js.map +1 -1
  135. package/out/zero-react/src/use-query.d.ts +5 -4
  136. package/out/zero-react/src/use-query.d.ts.map +1 -1
  137. package/out/zero-react/src/use-query.js +86 -9
  138. package/out/zero-react/src/use-query.js.map +1 -1
  139. package/out/zero-solid/src/solid-view.d.ts +10 -0
  140. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  141. package/out/zero-solid/src/solid-view.js +27 -0
  142. package/out/zero-solid/src/solid-view.js.map +1 -1
  143. package/out/zero-solid/src/use-query.js +5 -3
  144. package/out/zero-solid/src/use-query.js.map +1 -1
  145. package/out/zql/src/ivm/array-view.d.ts +10 -0
  146. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  147. package/out/zql/src/ivm/array-view.js +20 -8
  148. package/out/zql/src/ivm/array-view.js.map +1 -1
  149. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  150. package/out/zql/src/ivm/cap.js +5 -3
  151. package/out/zql/src/ivm/cap.js.map +1 -1
  152. package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
  153. package/out/zql/src/ivm/deferred-input.js +3 -2
  154. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  155. package/out/zql/src/ivm/exists.d.ts +1 -1
  156. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  157. package/out/zql/src/ivm/exists.js +1 -1
  158. package/out/zql/src/ivm/exists.js.map +1 -1
  159. package/out/zql/src/ivm/fan-in.d.ts +2 -2
  160. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  161. package/out/zql/src/ivm/fan-in.js +6 -5
  162. package/out/zql/src/ivm/fan-in.js.map +1 -1
  163. package/out/zql/src/ivm/fan-out.d.ts +2 -2
  164. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  165. package/out/zql/src/ivm/fan-out.js.map +1 -1
  166. package/out/zql/src/ivm/filter-operators.d.ts +4 -4
  167. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  168. package/out/zql/src/ivm/filter-operators.js +10 -8
  169. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  170. package/out/zql/src/ivm/filter.d.ts +2 -2
  171. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  172. package/out/zql/src/ivm/filter.js +7 -4
  173. package/out/zql/src/ivm/filter.js.map +1 -1
  174. package/out/zql/src/ivm/flipped-join.js +2 -2
  175. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  176. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  177. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  178. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
  179. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  180. package/out/zql/src/ivm/memory-source.d.ts +2 -2
  181. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  182. package/out/zql/src/ivm/memory-source.js +9 -9
  183. package/out/zql/src/ivm/memory-source.js.map +1 -1
  184. package/out/zql/src/ivm/take.d.ts.map +1 -1
  185. package/out/zql/src/ivm/take.js +3 -4
  186. package/out/zql/src/ivm/take.js.map +1 -1
  187. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  188. package/out/zql/src/ivm/union-fan-in.js +9 -7
  189. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  190. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  191. package/out/zql/src/ivm/view-apply-change.js +3 -3
  192. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  193. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  194. package/out/zql/src/mutate/mutator-registry.js +2 -2
  195. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  196. package/out/zql/src/query/query-delegate-base.d.ts +2 -0
  197. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  198. package/out/zql/src/query/query-delegate-base.js +58 -31
  199. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  200. package/out/zql/src/query/query-delegate.d.ts +11 -1
  201. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  202. package/out/zql/src/query/query-impl.d.ts +25 -14
  203. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  204. package/out/zql/src/query/query-impl.js +414 -94
  205. package/out/zql/src/query/query-impl.js.map +1 -1
  206. package/out/zql/src/query/query-internals.d.ts +21 -11
  207. package/out/zql/src/query/query-internals.d.ts.map +1 -1
  208. package/out/zql/src/query/query-internals.js.map +1 -1
  209. package/out/zql/src/query/query-transitions.d.ts +171 -0
  210. package/out/zql/src/query/query-transitions.d.ts.map +1 -0
  211. package/out/zql/src/query/query-transitions.js +207 -0
  212. package/out/zql/src/query/query-transitions.js.map +1 -0
  213. package/out/zql/src/query/query.d.ts +7 -1
  214. package/out/zql/src/query/query.d.ts.map +1 -1
  215. package/out/zql/src/query/runnable-query-impl.d.ts +3 -2
  216. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  217. package/out/zql/src/query/runnable-query-impl.js +23 -2
  218. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  219. package/out/zql/src/query/typed-view.d.ts +1 -1
  220. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  221. package/out/zqlite/src/table-source.d.ts.map +1 -1
  222. package/out/zqlite/src/table-source.js +7 -5
  223. package/out/zqlite/src/table-source.js.map +1 -1
  224. package/package.json +1 -1
@@ -3,6 +3,8 @@ export type QueryResultDetails = {
3
3
  readonly type: 'complete';
4
4
  } | {
5
5
  readonly type: 'unknown';
6
+ } | {
7
+ readonly type: 'cached';
6
8
  } | {
7
9
  readonly type: 'error';
8
10
  readonly retry: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"query-result.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/types/query-result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AAEnE,MAAM,MAAM,kBAAkB,GAC1B;IACE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC1B,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,sCAAsC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,KAAK,EACV;QACE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;KACtC,GACD;QACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;KACtC,CAAC;CACP,CAAC;AAEN,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"query-result.d.ts","sourceRoot":"","sources":["../../../../../zero-client/src/types/query-result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AAEnE,MAAM,MAAM,kBAAkB,GAC1B;IACE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC1B,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;CACzB,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,sCAAsC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,KAAK,EACV;QACE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;KACtC,GACD;QACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;KACtC,CAAC;CACP,CAAC;AAEN,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,CAAC,CAAC"}
@@ -146,7 +146,70 @@ export type CorrelatedSubqueryCondition = {
146
146
  [planIdSymbol]?: number | undefined;
147
147
  };
148
148
  export type CorrelatedSubqueryConditionOperator = 'EXISTS' | 'NOT EXISTS';
149
- export declare function normalizeAST(ast: AST): Required<AST>;
149
+ declare const normalizedTag: unique symbol;
150
+ /**
151
+ * An {@link AST} in its normalized form: `related` is sorted, `where` is
152
+ * flattened and sorted, and every field is present, in a fixed order. Two ASTs
153
+ * that describe the same query have the same JSON encoding, and thus the same
154
+ * hash, once normalized.
155
+ *
156
+ * The tag only exists in the type, so the only way to get one is from
157
+ * {@link normalizeAST}, {@link normalizedAST} or {@link tableAST}. Spreading
158
+ * one keeps the tag, which is what lets a query builder derive a normalized
159
+ * AST from another one by replacing a field it knows to be safe.
160
+ */
161
+ export type NormalizedAST = Required<AST> & {
162
+ readonly [normalizedTag]: true;
163
+ };
164
+ export declare function normalizeAST(ast: AST): NormalizedAST;
165
+ /**
166
+ * Normalizes a single level of an AST, assuming that the ASTs of its
167
+ * subqueries (i.e. those in `related` and in correlated subquery conditions)
168
+ * are already normalized and that the `related` entries have the shape that
169
+ * {@link normalizedRelated} gives them.
170
+ *
171
+ * This lets a query builder keep its AST normalized as it builds it up
172
+ * instead of normalizing the whole tree afterwards. A builder that knows
173
+ * which of the rules a step can break at all is better off applying just
174
+ * those (see {@link tableAST}, {@link insertRelated} and
175
+ * {@link normalizeCondition}).
176
+ */
177
+ export declare function normalizedAST(ast: AST): NormalizedAST;
178
+ /**
179
+ * The normalized AST that selects a whole table. Spreading it (or any other
180
+ * normalized AST) and replacing a field keeps the field order, since a
181
+ * normalized AST has every field.
182
+ */
183
+ export declare function tableAST(table: string, alias?: string | undefined): NormalizedAST;
184
+ /**
185
+ * Adds `subquery` to the `related` of a normalized AST, at the position that
186
+ * keeps it sorted.
187
+ */
188
+ export declare function insertRelated(related: readonly CorrelatedSubquery[] | undefined, subquery: CorrelatedSubquery): readonly CorrelatedSubquery[];
189
+ /**
190
+ * Gives a correlated subquery the shape that a normalized AST has: every
191
+ * field, in a fixed order (see {@link normalizedAST}). Its `subquery` must
192
+ * already be normalized.
193
+ */
194
+ export declare function normalizedRelated(related: CorrelatedSubquery): Required<CorrelatedSubquery>;
195
+ /**
196
+ * Normalizes a condition, assuming that the ASTs of any correlated subqueries
197
+ * it contains are already normalized.
198
+ *
199
+ * Like {@link normalizedAST}, this rebuilds every node with its fields in a
200
+ * fixed order, so that structurally equal conditions have the same JSON
201
+ * encoding (and thus the same hash) no matter how they were put together.
202
+ * That includes a round trip through Postgres, whose jsonb type reorders
203
+ * object keys: without the rebuild, every query record reloaded from the CVR
204
+ * re-hashed to a different transformationHash than was stored, making it look
205
+ * changed and re-execute on every view-syncer restart.
206
+ */
207
+ export declare function normalizeCondition(cond: Condition): Condition;
208
+ /**
209
+ * Maps the table and column names of `ast`. The result is not a
210
+ * {@link NormalizedAST} even if `ast` was normalized: the names it sorts by
211
+ * are the ones that changed.
212
+ */
150
213
  export declare function mapAST(ast: AST, mapper: NameMapper): Required<AST>;
151
214
  export declare function mapCondition(cond: Condition, table: string, mapper: NameMapper): Condition;
152
215
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../../../zero-protocol/src/ast.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../../../zero-protocol/src/ast.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { assert } from "../../shared/src/asserts.js";
2
2
  import { literalUnion, readonly, readonlyArray, readonlyObject, valita_exports } from "../../shared/src/valita.js";
3
- import { defined } from "../../shared/src/arrays.js";
4
3
  import { must } from "../../shared/src/must.js";
5
4
  import { rowSchema } from "./data.js";
6
5
  import { compareUTF8 } from "compare-utf8";
@@ -109,13 +108,12 @@ function transformAST(ast, transform) {
109
108
  const key = (table, k) => {
110
109
  return mustCompoundKey(k.map((col) => columnName(table, col)));
111
110
  };
112
- const where = ast.where ? transform.where(ast.where) : void 0;
113
111
  return {
114
112
  schema: ast.schema,
115
113
  table: tableName(ast.table),
116
114
  alias: ast.alias,
117
- where: where ? transformWhere(where, ast.table, transform) : void 0,
118
- related: ast.related ? transform.related(ast.related.map((r) => ({
115
+ where: ast.where ? transformWhere(ast.where, ast.table, transform) : void 0,
116
+ related: ast.related?.map((r) => ({
119
117
  correlation: {
120
118
  parentField: key(ast.table, r.correlation.parentField),
121
119
  childField: key(r.subquery.table, r.correlation.childField)
@@ -123,7 +121,7 @@ function transformAST(ast, transform) {
123
121
  hidden: r.hidden,
124
122
  subquery: transformAST(r.subquery, transform),
125
123
  system: r.system
126
- }))) : void 0,
124
+ })),
127
125
  start: ast.start ? {
128
126
  ...ast.start,
129
127
  row: Object.fromEntries(Object.entries(ast.start.row).map(([col, val]) => [colName(col), val]))
@@ -161,46 +159,208 @@ function transformWhere(where, table, transform) {
161
159
  }
162
160
  return {
163
161
  type: where.type,
164
- conditions: transform.conditions(where.conditions.map((c) => transformWhere(c, table, transform)))
162
+ conditions: where.conditions.map((c) => transformWhere(c, table, transform))
165
163
  };
166
164
  }
165
+ function asNormalized(ast) {
166
+ return ast;
167
+ }
167
168
  var normalizeCache = /* @__PURE__ */ new WeakMap();
168
- var NORMALIZE_TRANSFORM = {
169
- tableName: (t) => t,
170
- columnName: (_, c) => c,
171
- related: sortedRelated,
172
- where: flattened,
173
- conditions: (c) => c.sort(cmpCondition)
174
- };
175
169
  function normalizeAST(ast) {
176
170
  let normalized = normalizeCache.get(ast);
177
171
  if (!normalized) {
178
- normalized = transformAST(ast, NORMALIZE_TRANSFORM);
172
+ const { where, related } = ast;
173
+ normalized = normalizedAST({
174
+ ...ast,
175
+ where: where && normalizeSubqueries(where),
176
+ related: related?.map((r) => normalizedRelated({
177
+ ...r,
178
+ subquery: normalizeAST(r.subquery)
179
+ }))
180
+ });
179
181
  normalizeCache.set(ast, normalized);
180
182
  }
181
183
  return normalized;
182
184
  }
185
+ /**
186
+ * Normalizes the ASTs of the correlated subqueries of `cond`. The condition
187
+ * itself is normalized by {@link normalizeCondition}.
188
+ */
189
+ function normalizeSubqueries(cond) {
190
+ switch (cond.type) {
191
+ case "simple": return cond;
192
+ case "correlatedSubquery": return {
193
+ ...cond,
194
+ related: {
195
+ ...cond.related,
196
+ subquery: normalizeAST(cond.related.subquery)
197
+ }
198
+ };
199
+ default: return {
200
+ type: cond.type,
201
+ conditions: cond.conditions.map(normalizeSubqueries)
202
+ };
203
+ }
204
+ }
205
+ /**
206
+ * Normalizes a single level of an AST, assuming that the ASTs of its
207
+ * subqueries (i.e. those in `related` and in correlated subquery conditions)
208
+ * are already normalized and that the `related` entries have the shape that
209
+ * {@link normalizedRelated} gives them.
210
+ *
211
+ * This lets a query builder keep its AST normalized as it builds it up
212
+ * instead of normalizing the whole tree afterwards. A builder that knows
213
+ * which of the rules a step can break at all is better off applying just
214
+ * those (see {@link tableAST}, {@link insertRelated} and
215
+ * {@link normalizeCondition}).
216
+ */
217
+ function normalizedAST(ast) {
218
+ const { schema, table, alias, where, related, start, limit, orderBy } = ast;
219
+ return asNormalized({
220
+ schema,
221
+ table,
222
+ alias,
223
+ where: where === void 0 ? void 0 : normalizeCondition(where),
224
+ related: related === void 0 ? void 0 : normalizeRelated(related),
225
+ start,
226
+ limit,
227
+ orderBy
228
+ });
229
+ }
230
+ /**
231
+ * The normalized AST that selects a whole table. Spreading it (or any other
232
+ * normalized AST) and replacing a field keeps the field order, since a
233
+ * normalized AST has every field.
234
+ */
235
+ function tableAST(table, alias) {
236
+ return asNormalized({
237
+ schema: void 0,
238
+ table,
239
+ alias,
240
+ where: void 0,
241
+ related: void 0,
242
+ start: void 0,
243
+ limit: void 0,
244
+ orderBy: void 0
245
+ });
246
+ }
247
+ /**
248
+ * Adds `subquery` to the `related` of a normalized AST, at the position that
249
+ * keeps it sorted.
250
+ */
251
+ function insertRelated(related, subquery) {
252
+ const normalized = normalizedRelated(subquery);
253
+ if (related === void 0) return [normalized];
254
+ let i = related.length;
255
+ while (i > 0 && cmpRelated(related[i - 1], normalized) > 0) i--;
256
+ return related.toSpliced(i, 0, normalized);
257
+ }
258
+ var normalizedConditions = /* @__PURE__ */ new WeakSet();
259
+ function normalizeRelated(related) {
260
+ for (let i = 1; i < related.length; i++) if (cmpRelated(related[i - 1], related[i]) > 0) return related.toSorted(cmpRelated);
261
+ return related;
262
+ }
263
+ /**
264
+ * Gives a correlated subquery the shape that a normalized AST has: every
265
+ * field, in a fixed order (see {@link normalizedAST}). Its `subquery` must
266
+ * already be normalized.
267
+ */
268
+ function normalizedRelated(related) {
269
+ const { correlation, hidden, subquery, system } = related;
270
+ return {
271
+ correlation: {
272
+ parentField: correlation.parentField,
273
+ childField: correlation.childField
274
+ },
275
+ hidden,
276
+ subquery,
277
+ system
278
+ };
279
+ }
280
+ function normalizeValuePosition(v) {
281
+ switch (v.type) {
282
+ case "literal": return {
283
+ type: "literal",
284
+ value: v.value
285
+ };
286
+ case "column": return {
287
+ type: "column",
288
+ name: v.name
289
+ };
290
+ default: return {
291
+ type: "static",
292
+ anchor: v.anchor,
293
+ field: v.field
294
+ };
295
+ }
296
+ }
297
+ /**
298
+ * Normalizes a condition, assuming that the ASTs of any correlated subqueries
299
+ * it contains are already normalized.
300
+ *
301
+ * Like {@link normalizedAST}, this rebuilds every node with its fields in a
302
+ * fixed order, so that structurally equal conditions have the same JSON
303
+ * encoding (and thus the same hash) no matter how they were put together.
304
+ * That includes a round trip through Postgres, whose jsonb type reorders
305
+ * object keys: without the rebuild, every query record reloaded from the CVR
306
+ * re-hashed to a different transformationHash than was stored, making it look
307
+ * changed and re-execute on every view-syncer restart.
308
+ */
309
+ function normalizeCondition(cond) {
310
+ if (normalizedConditions.has(cond)) return cond;
311
+ if (cond.type === "simple") {
312
+ const normalized = {
313
+ type: "simple",
314
+ op: cond.op,
315
+ left: normalizeValuePosition(cond.left),
316
+ right: normalizeValuePosition(cond.right)
317
+ };
318
+ normalizedConditions.add(normalized);
319
+ return normalized;
320
+ }
321
+ if (cond.type === "correlatedSubquery") {
322
+ const normalized = {
323
+ type: "correlatedSubquery",
324
+ related: normalizedRelated(cond.related),
325
+ op: cond.op,
326
+ flip: cond.flip,
327
+ scalar: cond.scalar
328
+ };
329
+ normalizedConditions.add(normalized);
330
+ return normalized;
331
+ }
332
+ const conditions = [];
333
+ for (const c of cond.conditions) {
334
+ const n = normalizeCondition(c);
335
+ if (n.type === cond.type) conditions.push(...n.conditions);
336
+ else conditions.push(n);
337
+ }
338
+ if (conditions.length === 1) return conditions[0];
339
+ conditions.sort(cmpCondition);
340
+ const normalized = {
341
+ type: cond.type,
342
+ conditions
343
+ };
344
+ normalizedConditions.add(normalized);
345
+ return normalized;
346
+ }
347
+ /**
348
+ * Maps the table and column names of `ast`. The result is not a
349
+ * {@link NormalizedAST} even if `ast` was normalized: the names it sorts by
350
+ * are the ones that changed.
351
+ */
183
352
  function mapAST(ast, mapper) {
184
353
  return transformAST(ast, {
185
354
  tableName: (table) => mapper.tableName(table),
186
- columnName: (table, col) => mapper.columnName(table, col),
187
- related: (r) => r,
188
- where: (w) => w,
189
- conditions: (c) => c
355
+ columnName: (table, col) => mapper.columnName(table, col)
190
356
  });
191
357
  }
192
358
  function mapCondition(cond, table, mapper) {
193
359
  return transformWhere(cond, table, {
194
360
  tableName: (table) => mapper.tableName(table),
195
- columnName: (table, col) => mapper.columnName(table, col),
196
- related: (r) => r,
197
- where: (w) => w,
198
- conditions: (c) => c
361
+ columnName: (table, col) => mapper.columnName(table, col)
199
362
  });
200
363
  }
201
- function sortedRelated(related) {
202
- return related.sort(cmpRelated);
203
- }
204
364
  function cmpCondition(a, b) {
205
365
  if (a.type === "simple") {
206
366
  if (b.type !== "simple") return -1;
@@ -225,39 +385,51 @@ function compareValuePosition(a, b) {
225
385
  switch (a.type) {
226
386
  case "literal":
227
387
  assert(b.type === "literal", "Expected literal type for comparison");
228
- return compareUTF8(String(a.value), String(b.value));
388
+ return cmpLiteralValue(a.value, b.value);
229
389
  case "column":
230
390
  assert(b.type === "column", "Expected column type for comparison");
231
391
  return compareUTF8(a.name, b.name);
232
- case "static": throw new Error("Static parameters should be resolved before normalization");
392
+ case "static":
393
+ assert(b.type === "static", "Expected static type for comparison");
394
+ return compareUTF8(a.anchor, b.anchor) || cmpLiteralValue(a.field, b.field);
233
395
  }
234
396
  }
235
- function cmpRelated(a, b) {
236
- return compareUTF8(must(a.subquery.alias), must(b.subquery.alias));
397
+ var LITERAL_VALUE_TYPES = [
398
+ "object",
399
+ "boolean",
400
+ "number",
401
+ "string"
402
+ ];
403
+ function literalValueType(value) {
404
+ return Array.isArray(value) ? LITERAL_VALUE_TYPES.length : LITERAL_VALUE_TYPES.indexOf(typeof value);
237
405
  }
238
- /**
239
- * Returns a flattened version of the Conditions in which nested Conjunctions with
240
- * the same operation ('AND' or 'OR') are flattened to the same level. e.g.
241
- *
242
- * ```
243
- * ((a AND b) AND (c AND (d OR (e OR f)))) -> (a AND b AND c AND (d OR e OR f))
244
- * ```
245
- *
246
- * Also flattens singleton Conjunctions regardless of operator, and removes
247
- * empty Conjunctions.
248
- */
249
- function flattened(cond) {
250
- if (cond.type === "simple" || cond.type === "correlatedSubquery") return cond;
251
- const conditions = defined(cond.conditions.flatMap((c) => c.type === cond.type ? c.conditions.map((c) => flattened(c)) : flattened(c)));
252
- switch (conditions.length) {
253
- case 0: return;
254
- case 1: return conditions[0];
255
- default: return {
256
- type: cond.type,
257
- conditions
258
- };
406
+ function cmpLiteralValue(a, b) {
407
+ const type = literalValueType(a) - literalValueType(b);
408
+ if (type !== 0) return type;
409
+ if (Array.isArray(a)) {
410
+ assert(Array.isArray(b), "Expected array for comparison");
411
+ for (let i = 0; i < a.length && i < b.length; i++) {
412
+ const val = cmpLiteralValue(a[i], b[i]);
413
+ if (val !== 0) return val;
414
+ }
415
+ return a.length - b.length;
416
+ }
417
+ switch (typeof a) {
418
+ case "string":
419
+ assert(typeof b === "string", "Expected string for comparison");
420
+ return compareUTF8(a, b);
421
+ case "number":
422
+ assert(typeof b === "number", "Expected number for comparison");
423
+ return a < b ? -1 : a > b ? 1 : 0;
424
+ case "boolean":
425
+ assert(typeof b === "boolean", "Expected boolean for comparison");
426
+ return Number(a) - Number(b);
427
+ default: return 0;
259
428
  }
260
429
  }
430
+ function cmpRelated(a, b) {
431
+ return compareUTF8(must(a.subquery.alias), must(b.subquery.alias));
432
+ }
261
433
  function compareUTF8MaybeNull(a, b) {
262
434
  if (a !== null && b !== null) return compareUTF8(a, b);
263
435
  if (b !== null) return -1;
@@ -269,6 +441,6 @@ function cmpOptionalBool(a, b) {
269
441
  return toNum(a) - toNum(b);
270
442
  }
271
443
  //#endregion
272
- export { SUBQ_PREFIX, astSchema, compoundKeySchema, conditionSchema, mapAST, mapCondition, normalizeAST, orderingSchema, planIdSymbol, toStaticParam };
444
+ export { SUBQ_PREFIX, astSchema, compoundKeySchema, conditionSchema, insertRelated, mapAST, mapCondition, normalizeAST, normalizeCondition, normalizedRelated, orderingSchema, planIdSymbol, tableAST, toStaticParam };
273
445
 
274
446
  //# sourceMappingURL=ast.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ast.js","names":[],"sources":["../../../../zero-protocol/src/ast.ts"],"sourcesContent":["/**\n * Wire-format representation of the zql AST interface.\n *\n * `v.Type<...>` types are explicitly declared to facilitate Typescript verification\n * that the schemas satisfy the zql type definitions. (Incidentally, explicit types\n * are also required for recursive schema definitions.)\n */\n\nimport {compareUTF8} from 'compare-utf8';\nimport {defined} from '../../shared/src/arrays.ts';\nimport {assert} from '../../shared/src/asserts.ts';\nimport {must} from '../../shared/src/must.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport type {NameMapper} from '../../zero-types/src/name-mapper.ts';\nimport {rowSchema, type Row} from './data.ts';\n\nexport const SUBQ_PREFIX = 'zsubq_';\n\nexport const selectorSchema = v.string();\nexport const toStaticParam = Symbol();\nexport const planIdSymbol = Symbol('planId');\n\nconst orderingElementSchema = v.readonly(\n v.tuple([selectorSchema, v.literalUnion('asc', 'desc')]),\n);\n\nexport const orderingSchema = v.readonlyArray(orderingElementSchema);\nexport type System = 'permissions' | 'client' | 'test';\n\nexport const primitiveSchema = v.union(\n v.string(),\n v.number(),\n v.boolean(),\n v.null(),\n);\n\nexport const equalityOpsSchema = v.literalUnion('=', '!=', 'IS', 'IS NOT');\n\nexport const orderOpsSchema = v.literalUnion('<', '>', '<=', '>=');\n\nexport const likeOpsSchema = v.literalUnion(\n 'LIKE',\n 'NOT LIKE',\n 'ILIKE',\n 'NOT ILIKE',\n);\n\nexport const inOpsSchema = v.literalUnion('IN', 'NOT IN');\n\nexport const simpleOperatorSchema = v.union(\n equalityOpsSchema,\n orderOpsSchema,\n likeOpsSchema,\n inOpsSchema,\n);\n\nconst literalReferenceSchema: v.Type<LiteralReference> = v.readonlyObject({\n type: v.literal('literal'),\n value: v.union(\n v.string(),\n v.number(),\n v.boolean(),\n v.null(),\n v.readonlyArray(v.union(v.string(), v.number(), v.boolean())),\n ),\n});\nconst columnReferenceSchema: v.Type<ColumnReference> = v.readonlyObject({\n type: v.literal('column'),\n name: v.string(),\n});\n\n/**\n * A parameter is a value that is not known at the time the query is written\n * and is resolved at runtime.\n *\n * Static parameters refer to something provided by the caller.\n * Static parameters are injected when the query pipeline is built from the AST\n * and do not change for the life of that pipeline.\n *\n * An example static parameter is the current authentication data.\n * When a user is authenticated, queries on the server have access\n * to the user's authentication data in order to evaluate authorization rules.\n * Authentication data doesn't change over the life of a query as a change\n * in auth data would represent a log-in / log-out of the user.\n *\n * AncestorParameters refer to rows encountered while running the query.\n * They are used by subqueries to refer to rows emitted by parent queries.\n */\nconst parameterReferenceSchema = v.readonlyObject({\n type: v.literal('static'),\n // The \"namespace\" of the injected parameter.\n // Write authorization will send the value of a row\n // prior to the mutation being run (preMutationRow).\n // Read and write authorization will both send the\n // current authentication data (authData).\n anchor: v.literalUnion('authData', 'preMutationRow'),\n field: v.union(v.string(), v.array(v.string())),\n});\n\nconst conditionValueSchema = v.union(\n literalReferenceSchema,\n columnReferenceSchema,\n parameterReferenceSchema,\n);\n\nexport type Parameter = v.Infer<typeof parameterReferenceSchema>;\n\nexport const simpleConditionSchema: v.Type<SimpleCondition> = v.readonlyObject({\n type: v.literal('simple'),\n op: simpleOperatorSchema,\n left: conditionValueSchema,\n right: v.union(parameterReferenceSchema, literalReferenceSchema),\n});\n\ntype ConditionValue = v.Infer<typeof conditionValueSchema>;\n\nexport const correlatedSubqueryConditionOperatorSchema: v.Type<CorrelatedSubqueryConditionOperator> =\n v.literalUnion('EXISTS', 'NOT EXISTS');\n\nexport const correlatedSubqueryConditionSchema: v.Type<CorrelatedSubqueryCondition> =\n v.readonlyObject({\n type: v.literal('correlatedSubquery'),\n related: v.lazy(() => correlatedSubquerySchema),\n op: correlatedSubqueryConditionOperatorSchema,\n flip: v.boolean().optional(),\n scalar: v.boolean().optional(),\n });\n\nexport const conditionSchema: v.Type<Condition> = v.union(\n simpleConditionSchema,\n v.lazy(() => conjunctionSchema),\n v.lazy(() => disjunctionSchema),\n correlatedSubqueryConditionSchema,\n);\n\nconst conjunctionSchema: v.Type<Conjunction> = v.readonlyObject({\n type: v.literal('and'),\n conditions: v.readonlyArray(conditionSchema),\n});\n\nconst disjunctionSchema: v.Type<Disjunction> = v.readonlyObject({\n type: v.literal('or'),\n conditions: v.readonlyArray(conditionSchema),\n});\n\nexport type CompoundKey = readonly [string, ...string[]];\n\nfunction mustCompoundKey(field: readonly string[]): CompoundKey {\n assert(\n Array.isArray(field) && field.length >= 1,\n 'Expected non-empty array for compound key',\n );\n return field as unknown as CompoundKey;\n}\n\nexport const compoundKeySchema: v.Type<CompoundKey> = v.readonly(\n // oxlint-disable-next-line e18e/prefer-spread-syntax\n v.tuple([v.string()]).concat(v.array(v.string())),\n);\n\nconst correlationSchema = v.readonlyObject({\n parentField: compoundKeySchema,\n childField: compoundKeySchema,\n});\n\n// Split out so that its inferred type can be checked against\n// Omit<CorrelatedSubquery, 'correlation'> in ast-type-test.ts.\n// The mutually-recursive reference of the 'other' field to astSchema\n// is the only thing added in v.lazy. The v.lazy is necessary due to the\n// mutually-recursive types, but v.lazy prevents inference of the resulting\n// type.\nexport const correlatedSubquerySchemaOmitSubquery = v.readonlyObject({\n correlation: correlationSchema,\n hidden: v.boolean().optional(),\n system: v.literalUnion('permissions', 'client', 'test').optional(),\n});\n\nexport const correlatedSubquerySchema: v.Type<CorrelatedSubquery> =\n correlatedSubquerySchemaOmitSubquery.extend({\n subquery: v.lazy(() => astSchema),\n });\n\nexport const astSchema: v.Type<AST> = v.readonlyObject({\n schema: v.string().optional(),\n table: v.string(),\n alias: v.string().optional(),\n where: conditionSchema.optional(),\n related: v.readonlyArray(correlatedSubquerySchema).optional(),\n limit: v.number().optional(),\n orderBy: orderingSchema.optional(),\n start: v\n .object({\n row: rowSchema,\n exclusive: v.boolean(),\n })\n .optional(),\n});\n\nexport type Bound = {\n row: Row;\n exclusive: boolean;\n};\n\n/**\n * As in SQL you can have multiple orderings. We don't currently\n * support ordering on anything other than the root query.\n */\nexport type OrderPart = readonly [field: string, direction: 'asc' | 'desc'];\nexport type Ordering = readonly OrderPart[];\n\nexport type SimpleOperator = EqualityOps | OrderOps | LikeOps | InOps;\nexport type EqualityOps = '=' | '!=' | 'IS' | 'IS NOT';\nexport type OrderOps = '<' | '>' | '<=' | '>=';\nexport type LikeOps = 'LIKE' | 'NOT LIKE' | 'ILIKE' | 'NOT ILIKE';\nexport type InOps = 'IN' | 'NOT IN';\n\nexport type AST = {\n readonly schema?: string | undefined;\n readonly table: string;\n\n // A query would be aliased if the AST is a subquery.\n // e.g., when two subqueries select from the same table\n // they need an alias to differentiate them.\n // `SELECT\n // [SELECT * FROM issue WHERE issue.id = outer.parentId] AS parent\n // [SELECT * FROM issue WHERE issue.parentId = outer.id] AS children\n // FROM issue as outer`\n readonly alias?: string | undefined;\n\n // `select` is missing given we return all columns for now.\n\n // The PipelineBuilder will pick what to use to correlate\n // a subquery with a parent query. It can choose something from the\n // where conditions or choose the _first_ `related` entry.\n // Choosing the first `related` entry is almost always the best choice if\n // one exists.\n readonly where?: Condition | undefined;\n\n readonly related?: readonly CorrelatedSubquery[] | undefined;\n readonly start?: Bound | undefined;\n readonly limit?: number | undefined;\n readonly orderBy?: Ordering | undefined;\n};\n\nexport type Correlation = {\n readonly parentField: CompoundKey;\n readonly childField: CompoundKey;\n};\n\nexport type CorrelatedSubquery = {\n /**\n * Only equality correlation are supported for now.\n * E.g., direct foreign key relationships.\n */\n readonly correlation: Correlation;\n readonly subquery: AST;\n readonly system?: System | undefined;\n // If a hop in the subquery chain should be hidden from the output view.\n // A common example is junction edges. The query API provides the illusion\n // that they don't exist: `issue.related('labels')` instead of `issue.related('issue_labels').related('labels')`.\n // To maintain this illusion, the junction edge should be hidden.\n // When `hidden` is set to true, this hop will not be included in the output view\n // but its children will be.\n readonly hidden?: boolean | undefined;\n};\n\nexport type ValuePosition = LiteralReference | Parameter | ColumnReference;\n\nexport type ColumnReference = {\n readonly type: 'column';\n /**\n * Not a path yet as we're currently not allowing\n * comparisons across tables. This will need to\n * be a path through the tree in the near future.\n */\n readonly name: string;\n};\n\nexport type LiteralReference = {\n readonly type: 'literal';\n readonly value: LiteralValue;\n};\n\nexport type LiteralValue =\n | string\n | number\n | boolean\n | null\n | ReadonlyArray<string | number | boolean>;\n\n/**\n * Starting only with SimpleCondition for now.\n * ivm1 supports Conjunctions and Disjunctions.\n * We'll support them in the future.\n */\nexport type Condition =\n | SimpleCondition\n | Conjunction\n | Disjunction\n | CorrelatedSubqueryCondition;\n\nexport type SimpleCondition = {\n readonly type: 'simple';\n readonly op: SimpleOperator;\n readonly left: ValuePosition;\n\n /**\n * `null` is absent since we do not have an `IS` or `IS NOT`\n * operator defined and `null != null` in SQL.\n */\n readonly right: Exclude<ValuePosition, ColumnReference>;\n};\n\nexport type Conjunction = {\n type: 'and';\n conditions: readonly Condition[];\n};\n\nexport type Disjunction = {\n type: 'or';\n conditions: readonly Condition[];\n};\n\nexport type CorrelatedSubqueryCondition = {\n type: 'correlatedSubquery';\n related: CorrelatedSubquery;\n op: CorrelatedSubqueryConditionOperator;\n flip?: boolean | undefined;\n scalar?: boolean | undefined;\n [planIdSymbol]?: number | undefined;\n};\n\nexport type CorrelatedSubqueryConditionOperator = 'EXISTS' | 'NOT EXISTS';\n\ninterface ASTTransform {\n tableName(orig: string): string;\n columnName(origTable: string, origColumn: string): string;\n related(subqueries: CorrelatedSubquery[]): readonly CorrelatedSubquery[];\n where(cond: Condition): Condition | undefined;\n // conjunction or disjunction, called when traversing the return value of where()\n conditions(conds: Condition[]): readonly Condition[];\n}\n\nfunction transformAST(ast: AST, transform: ASTTransform): Required<AST> {\n // Name mapping functions (e.g. to server names)\n const {tableName, columnName} = transform;\n const colName = (c: string) => columnName(ast.table, c);\n const key = (table: string, k: CompoundKey) => {\n const serverKey = k.map(col => columnName(table, col));\n return mustCompoundKey(serverKey);\n };\n\n const where = ast.where ? transform.where(ast.where) : undefined;\n const transformed = {\n schema: ast.schema,\n table: tableName(ast.table),\n alias: ast.alias,\n where: where ? transformWhere(where, ast.table, transform) : undefined,\n related: ast.related\n ? transform.related(\n ast.related.map(\n r =>\n ({\n correlation: {\n parentField: key(ast.table, r.correlation.parentField),\n childField: key(r.subquery.table, r.correlation.childField),\n },\n hidden: r.hidden,\n subquery: transformAST(r.subquery, transform),\n system: r.system,\n }) satisfies Required<CorrelatedSubquery>,\n ),\n )\n : undefined,\n start: ast.start\n ? {\n ...ast.start,\n row: Object.fromEntries(\n Object.entries(ast.start.row).map(([col, val]) => [\n colName(col),\n val,\n ]),\n ),\n }\n : undefined,\n limit: ast.limit,\n orderBy: ast.orderBy?.map(([col, dir]) => [colName(col), dir] as const),\n };\n\n return transformed;\n}\n\nfunction transformWhere(\n where: Condition,\n table: string,\n transform: ASTTransform,\n): Condition {\n // Name mapping functions (e.g. to server names)\n const {columnName} = transform;\n const condValue = (c: ConditionValue) =>\n c.type !== 'column' ? c : {...c, name: columnName(table, c.name)};\n const key = (table: string, k: CompoundKey) => {\n const serverKey = k.map(col => columnName(table, col));\n return mustCompoundKey(serverKey);\n };\n\n if (where.type === 'simple') {\n return {...where, left: condValue(where.left)};\n } else if (where.type === 'correlatedSubquery') {\n const {correlation, subquery} = where.related;\n return {\n ...where,\n related: {\n ...where.related,\n correlation: {\n parentField: key(table, correlation.parentField),\n childField: key(subquery.table, correlation.childField),\n },\n subquery: transformAST(subquery, transform),\n },\n };\n }\n\n return {\n type: where.type,\n conditions: transform.conditions(\n where.conditions.map(c => transformWhere(c, table, transform)),\n ),\n };\n}\n\nconst normalizeCache = new WeakMap<AST, Required<AST>>();\n\nconst NORMALIZE_TRANSFORM: ASTTransform = {\n tableName: t => t,\n columnName: (_, c) => c,\n related: sortedRelated,\n where: flattened,\n conditions: c => c.sort(cmpCondition),\n};\n\nexport function normalizeAST(ast: AST): Required<AST> {\n let normalized = normalizeCache.get(ast);\n if (!normalized) {\n normalized = transformAST(ast, NORMALIZE_TRANSFORM);\n normalizeCache.set(ast, normalized);\n }\n return normalized;\n}\n\nexport function mapAST(ast: AST, mapper: NameMapper) {\n return transformAST(ast, {\n tableName: table => mapper.tableName(table),\n columnName: (table, col) => mapper.columnName(table, col),\n related: r => r,\n where: w => w,\n conditions: c => c,\n });\n}\n\nexport function mapCondition(\n cond: Condition,\n table: string,\n mapper: NameMapper,\n) {\n return transformWhere(cond, table, {\n tableName: table => mapper.tableName(table),\n columnName: (table, col) => mapper.columnName(table, col),\n related: r => r,\n where: w => w,\n conditions: c => c,\n });\n}\n\nfunction sortedRelated(\n related: CorrelatedSubquery[],\n): readonly CorrelatedSubquery[] {\n return related.sort(cmpRelated);\n}\n\nfunction cmpCondition(a: Condition, b: Condition): number {\n if (a.type === 'simple') {\n if (b.type !== 'simple') {\n return -1; // Order SimpleConditions first\n }\n\n return (\n compareValuePosition(a.left, b.left) ||\n compareUTF8MaybeNull(a.op, b.op) ||\n compareValuePosition(a.right, b.right)\n );\n }\n\n if (b.type === 'simple') {\n return 1; // Order SimpleConditions first\n }\n\n if (a.type === 'correlatedSubquery') {\n if (b.type !== 'correlatedSubquery') {\n return -1; // Order subquery before conjuctions/disjuctions\n }\n return (\n cmpRelated(a.related, b.related) ||\n compareUTF8MaybeNull(a.op, b.op) ||\n cmpOptionalBool(a.flip, b.flip) ||\n cmpOptionalBool(a.scalar, b.scalar)\n );\n }\n if (b.type === 'correlatedSubquery') {\n return -1; // Order correlatedSubquery before conjuctions/disjuctions\n }\n\n const val = compareUTF8MaybeNull(a.type, b.type);\n if (val !== 0) {\n return val;\n }\n for (\n let l = 0, r = 0;\n l < a.conditions.length && r < b.conditions.length;\n l++, r++\n ) {\n const val = cmpCondition(a.conditions[l], b.conditions[r]);\n if (val !== 0) {\n return val;\n }\n }\n // prefixes first\n return a.conditions.length - b.conditions.length;\n}\n\nfunction compareValuePosition(a: ValuePosition, b: ValuePosition): number {\n if (a.type !== b.type) {\n return compareUTF8(a.type, b.type);\n }\n switch (a.type) {\n case 'literal':\n assert(b.type === 'literal', 'Expected literal type for comparison');\n return compareUTF8(String(a.value), String(b.value));\n case 'column':\n assert(b.type === 'column', 'Expected column type for comparison');\n return compareUTF8(a.name, b.name);\n case 'static':\n throw new Error(\n 'Static parameters should be resolved before normalization',\n );\n }\n}\n\nfunction cmpRelated(a: CorrelatedSubquery, b: CorrelatedSubquery): number {\n return compareUTF8(must(a.subquery.alias), must(b.subquery.alias));\n}\n\n/**\n * Returns a flattened version of the Conditions in which nested Conjunctions with\n * the same operation ('AND' or 'OR') are flattened to the same level. e.g.\n *\n * ```\n * ((a AND b) AND (c AND (d OR (e OR f)))) -> (a AND b AND c AND (d OR e OR f))\n * ```\n *\n * Also flattens singleton Conjunctions regardless of operator, and removes\n * empty Conjunctions.\n */\nfunction flattened(cond: Condition): Condition | undefined {\n if (cond.type === 'simple' || cond.type === 'correlatedSubquery') {\n return cond;\n }\n const conditions = defined(\n cond.conditions.flatMap(c =>\n c.type === cond.type ? c.conditions.map(c => flattened(c)) : flattened(c),\n ),\n );\n\n switch (conditions.length) {\n case 0:\n return undefined;\n case 1:\n return conditions[0];\n default:\n return {\n type: cond.type,\n conditions,\n };\n }\n}\n\nfunction compareUTF8MaybeNull(a: string | null, b: string | null): number {\n if (a !== null && b !== null) {\n return compareUTF8(a, b);\n }\n if (b !== null) {\n return -1;\n }\n if (a !== null) {\n return 1;\n }\n return 0;\n}\n\nfunction cmpOptionalBool(\n a: boolean | undefined,\n b: boolean | undefined,\n): number {\n // undefined < false < true\n const toNum = (v: boolean | undefined) => (v === undefined ? 0 : v ? 2 : 1);\n return toNum(a) - toNum(b);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ast.js","names":[],"sources":["../../../../zero-protocol/src/ast.ts"],"sourcesContent":["/**\n * Wire-format representation of the zql AST interface.\n *\n * `v.Type<...>` types are explicitly declared to facilitate Typescript verification\n * that the schemas satisfy the zql type definitions. (Incidentally, explicit types\n * are also required for recursive schema definitions.)\n */\n\nimport {compareUTF8} from 'compare-utf8';\nimport {assert} from '../../shared/src/asserts.ts';\nimport {must} from '../../shared/src/must.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport type {NameMapper} from '../../zero-types/src/name-mapper.ts';\nimport {rowSchema, type Row} from './data.ts';\n\nexport const SUBQ_PREFIX = 'zsubq_';\n\nexport const selectorSchema = v.string();\nexport const toStaticParam = Symbol();\nexport const planIdSymbol = Symbol('planId');\n\nconst orderingElementSchema = v.readonly(\n v.tuple([selectorSchema, v.literalUnion('asc', 'desc')]),\n);\n\nexport const orderingSchema = v.readonlyArray(orderingElementSchema);\nexport type System = 'permissions' | 'client' | 'test';\n\nexport const primitiveSchema = v.union(\n v.string(),\n v.number(),\n v.boolean(),\n v.null(),\n);\n\nexport const equalityOpsSchema = v.literalUnion('=', '!=', 'IS', 'IS NOT');\n\nexport const orderOpsSchema = v.literalUnion('<', '>', '<=', '>=');\n\nexport const likeOpsSchema = v.literalUnion(\n 'LIKE',\n 'NOT LIKE',\n 'ILIKE',\n 'NOT ILIKE',\n);\n\nexport const inOpsSchema = v.literalUnion('IN', 'NOT IN');\n\nexport const simpleOperatorSchema = v.union(\n equalityOpsSchema,\n orderOpsSchema,\n likeOpsSchema,\n inOpsSchema,\n);\n\nconst literalReferenceSchema: v.Type<LiteralReference> = v.readonlyObject({\n type: v.literal('literal'),\n value: v.union(\n v.string(),\n v.number(),\n v.boolean(),\n v.null(),\n v.readonlyArray(v.union(v.string(), v.number(), v.boolean())),\n ),\n});\nconst columnReferenceSchema: v.Type<ColumnReference> = v.readonlyObject({\n type: v.literal('column'),\n name: v.string(),\n});\n\n/**\n * A parameter is a value that is not known at the time the query is written\n * and is resolved at runtime.\n *\n * Static parameters refer to something provided by the caller.\n * Static parameters are injected when the query pipeline is built from the AST\n * and do not change for the life of that pipeline.\n *\n * An example static parameter is the current authentication data.\n * When a user is authenticated, queries on the server have access\n * to the user's authentication data in order to evaluate authorization rules.\n * Authentication data doesn't change over the life of a query as a change\n * in auth data would represent a log-in / log-out of the user.\n *\n * AncestorParameters refer to rows encountered while running the query.\n * They are used by subqueries to refer to rows emitted by parent queries.\n */\nconst parameterReferenceSchema = v.readonlyObject({\n type: v.literal('static'),\n // The \"namespace\" of the injected parameter.\n // Write authorization will send the value of a row\n // prior to the mutation being run (preMutationRow).\n // Read and write authorization will both send the\n // current authentication data (authData).\n anchor: v.literalUnion('authData', 'preMutationRow'),\n field: v.union(v.string(), v.array(v.string())),\n});\n\nconst conditionValueSchema = v.union(\n literalReferenceSchema,\n columnReferenceSchema,\n parameterReferenceSchema,\n);\n\nexport type Parameter = v.Infer<typeof parameterReferenceSchema>;\n\nexport const simpleConditionSchema: v.Type<SimpleCondition> = v.readonlyObject({\n type: v.literal('simple'),\n op: simpleOperatorSchema,\n left: conditionValueSchema,\n right: v.union(parameterReferenceSchema, literalReferenceSchema),\n});\n\ntype ConditionValue = v.Infer<typeof conditionValueSchema>;\n\nexport const correlatedSubqueryConditionOperatorSchema: v.Type<CorrelatedSubqueryConditionOperator> =\n v.literalUnion('EXISTS', 'NOT EXISTS');\n\nexport const correlatedSubqueryConditionSchema: v.Type<CorrelatedSubqueryCondition> =\n v.readonlyObject({\n type: v.literal('correlatedSubquery'),\n related: v.lazy(() => correlatedSubquerySchema),\n op: correlatedSubqueryConditionOperatorSchema,\n flip: v.boolean().optional(),\n scalar: v.boolean().optional(),\n });\n\nexport const conditionSchema: v.Type<Condition> = v.union(\n simpleConditionSchema,\n v.lazy(() => conjunctionSchema),\n v.lazy(() => disjunctionSchema),\n correlatedSubqueryConditionSchema,\n);\n\nconst conjunctionSchema: v.Type<Conjunction> = v.readonlyObject({\n type: v.literal('and'),\n conditions: v.readonlyArray(conditionSchema),\n});\n\nconst disjunctionSchema: v.Type<Disjunction> = v.readonlyObject({\n type: v.literal('or'),\n conditions: v.readonlyArray(conditionSchema),\n});\n\nexport type CompoundKey = readonly [string, ...string[]];\n\nfunction mustCompoundKey(field: readonly string[]): CompoundKey {\n assert(\n Array.isArray(field) && field.length >= 1,\n 'Expected non-empty array for compound key',\n );\n return field as unknown as CompoundKey;\n}\n\nexport const compoundKeySchema: v.Type<CompoundKey> = v.readonly(\n // oxlint-disable-next-line e18e/prefer-spread-syntax\n v.tuple([v.string()]).concat(v.array(v.string())),\n);\n\nconst correlationSchema = v.readonlyObject({\n parentField: compoundKeySchema,\n childField: compoundKeySchema,\n});\n\n// Split out so that its inferred type can be checked against\n// Omit<CorrelatedSubquery, 'correlation'> in ast-type-test.ts.\n// The mutually-recursive reference of the 'other' field to astSchema\n// is the only thing added in v.lazy. The v.lazy is necessary due to the\n// mutually-recursive types, but v.lazy prevents inference of the resulting\n// type.\nexport const correlatedSubquerySchemaOmitSubquery = v.readonlyObject({\n correlation: correlationSchema,\n hidden: v.boolean().optional(),\n system: v.literalUnion('permissions', 'client', 'test').optional(),\n});\n\nexport const correlatedSubquerySchema: v.Type<CorrelatedSubquery> =\n correlatedSubquerySchemaOmitSubquery.extend({\n subquery: v.lazy(() => astSchema),\n });\n\nexport const astSchema: v.Type<AST> = v.readonlyObject({\n schema: v.string().optional(),\n table: v.string(),\n alias: v.string().optional(),\n where: conditionSchema.optional(),\n related: v.readonlyArray(correlatedSubquerySchema).optional(),\n limit: v.number().optional(),\n orderBy: orderingSchema.optional(),\n start: v\n .object({\n row: rowSchema,\n exclusive: v.boolean(),\n })\n .optional(),\n});\n\nexport type Bound = {\n row: Row;\n exclusive: boolean;\n};\n\n/**\n * As in SQL you can have multiple orderings. We don't currently\n * support ordering on anything other than the root query.\n */\nexport type OrderPart = readonly [field: string, direction: 'asc' | 'desc'];\nexport type Ordering = readonly OrderPart[];\n\nexport type SimpleOperator = EqualityOps | OrderOps | LikeOps | InOps;\nexport type EqualityOps = '=' | '!=' | 'IS' | 'IS NOT';\nexport type OrderOps = '<' | '>' | '<=' | '>=';\nexport type LikeOps = 'LIKE' | 'NOT LIKE' | 'ILIKE' | 'NOT ILIKE';\nexport type InOps = 'IN' | 'NOT IN';\n\nexport type AST = {\n readonly schema?: string | undefined;\n readonly table: string;\n\n // A query would be aliased if the AST is a subquery.\n // e.g., when two subqueries select from the same table\n // they need an alias to differentiate them.\n // `SELECT\n // [SELECT * FROM issue WHERE issue.id = outer.parentId] AS parent\n // [SELECT * FROM issue WHERE issue.parentId = outer.id] AS children\n // FROM issue as outer`\n readonly alias?: string | undefined;\n\n // `select` is missing given we return all columns for now.\n\n // The PipelineBuilder will pick what to use to correlate\n // a subquery with a parent query. It can choose something from the\n // where conditions or choose the _first_ `related` entry.\n // Choosing the first `related` entry is almost always the best choice if\n // one exists.\n readonly where?: Condition | undefined;\n\n readonly related?: readonly CorrelatedSubquery[] | undefined;\n readonly start?: Bound | undefined;\n readonly limit?: number | undefined;\n readonly orderBy?: Ordering | undefined;\n};\n\nexport type Correlation = {\n readonly parentField: CompoundKey;\n readonly childField: CompoundKey;\n};\n\nexport type CorrelatedSubquery = {\n /**\n * Only equality correlation are supported for now.\n * E.g., direct foreign key relationships.\n */\n readonly correlation: Correlation;\n readonly subquery: AST;\n readonly system?: System | undefined;\n // If a hop in the subquery chain should be hidden from the output view.\n // A common example is junction edges. The query API provides the illusion\n // that they don't exist: `issue.related('labels')` instead of `issue.related('issue_labels').related('labels')`.\n // To maintain this illusion, the junction edge should be hidden.\n // When `hidden` is set to true, this hop will not be included in the output view\n // but its children will be.\n readonly hidden?: boolean | undefined;\n};\n\nexport type ValuePosition = LiteralReference | Parameter | ColumnReference;\n\nexport type ColumnReference = {\n readonly type: 'column';\n /**\n * Not a path yet as we're currently not allowing\n * comparisons across tables. This will need to\n * be a path through the tree in the near future.\n */\n readonly name: string;\n};\n\nexport type LiteralReference = {\n readonly type: 'literal';\n readonly value: LiteralValue;\n};\n\nexport type LiteralValue =\n | string\n | number\n | boolean\n | null\n | ReadonlyArray<string | number | boolean>;\n\n/**\n * Starting only with SimpleCondition for now.\n * ivm1 supports Conjunctions and Disjunctions.\n * We'll support them in the future.\n */\nexport type Condition =\n | SimpleCondition\n | Conjunction\n | Disjunction\n | CorrelatedSubqueryCondition;\n\nexport type SimpleCondition = {\n readonly type: 'simple';\n readonly op: SimpleOperator;\n readonly left: ValuePosition;\n\n /**\n * `null` is absent since we do not have an `IS` or `IS NOT`\n * operator defined and `null != null` in SQL.\n */\n readonly right: Exclude<ValuePosition, ColumnReference>;\n};\n\nexport type Conjunction = {\n type: 'and';\n conditions: readonly Condition[];\n};\n\nexport type Disjunction = {\n type: 'or';\n conditions: readonly Condition[];\n};\n\nexport type CorrelatedSubqueryCondition = {\n type: 'correlatedSubquery';\n related: CorrelatedSubquery;\n op: CorrelatedSubqueryConditionOperator;\n flip?: boolean | undefined;\n scalar?: boolean | undefined;\n [planIdSymbol]?: number | undefined;\n};\n\nexport type CorrelatedSubqueryConditionOperator = 'EXISTS' | 'NOT EXISTS';\n\ninterface ASTTransform {\n tableName(orig: string): string;\n columnName(origTable: string, origColumn: string): string;\n}\n\nfunction transformAST(ast: AST, transform: ASTTransform): Required<AST> {\n // Name mapping functions (e.g. to server names)\n const {tableName, columnName} = transform;\n const colName = (c: string) => columnName(ast.table, c);\n const key = (table: string, k: CompoundKey) => {\n const serverKey = k.map(col => columnName(table, col));\n return mustCompoundKey(serverKey);\n };\n\n const transformed = {\n schema: ast.schema,\n table: tableName(ast.table),\n alias: ast.alias,\n where: ast.where\n ? transformWhere(ast.where, ast.table, transform)\n : undefined,\n related: ast.related?.map(\n r =>\n ({\n correlation: {\n parentField: key(ast.table, r.correlation.parentField),\n childField: key(r.subquery.table, r.correlation.childField),\n },\n hidden: r.hidden,\n subquery: transformAST(r.subquery, transform),\n system: r.system,\n }) satisfies Required<CorrelatedSubquery>,\n ),\n start: ast.start\n ? {\n ...ast.start,\n row: Object.fromEntries(\n Object.entries(ast.start.row).map(([col, val]) => [\n colName(col),\n val,\n ]),\n ),\n }\n : undefined,\n limit: ast.limit,\n orderBy: ast.orderBy?.map(([col, dir]) => [colName(col), dir] as const),\n };\n\n return transformed;\n}\n\nfunction transformWhere(\n where: Condition,\n table: string,\n transform: ASTTransform,\n): Condition {\n // Name mapping functions (e.g. to server names)\n const {columnName} = transform;\n const condValue = (c: ConditionValue) =>\n c.type !== 'column' ? c : {...c, name: columnName(table, c.name)};\n const key = (table: string, k: CompoundKey) => {\n const serverKey = k.map(col => columnName(table, col));\n return mustCompoundKey(serverKey);\n };\n\n if (where.type === 'simple') {\n return {...where, left: condValue(where.left)};\n } else if (where.type === 'correlatedSubquery') {\n const {correlation, subquery} = where.related;\n return {\n ...where,\n related: {\n ...where.related,\n correlation: {\n parentField: key(table, correlation.parentField),\n childField: key(subquery.table, correlation.childField),\n },\n subquery: transformAST(subquery, transform),\n },\n };\n }\n\n return {\n type: where.type,\n conditions: where.conditions.map(c => transformWhere(c, table, transform)),\n };\n}\n\ndeclare const normalizedTag: unique symbol;\n\n/**\n * An {@link AST} in its normalized form: `related` is sorted, `where` is\n * flattened and sorted, and every field is present, in a fixed order. Two ASTs\n * that describe the same query have the same JSON encoding, and thus the same\n * hash, once normalized.\n *\n * The tag only exists in the type, so the only way to get one is from\n * {@link normalizeAST}, {@link normalizedAST} or {@link tableAST}. Spreading\n * one keeps the tag, which is what lets a query builder derive a normalized\n * AST from another one by replacing a field it knows to be safe.\n */\nexport type NormalizedAST = Required<AST> & {readonly [normalizedTag]: true};\n\nfunction asNormalized(ast: Required<AST>): NormalizedAST {\n return ast as NormalizedAST;\n}\n\nconst normalizeCache = new WeakMap<AST, NormalizedAST>();\n\nexport function normalizeAST(ast: AST): NormalizedAST {\n let normalized = normalizeCache.get(ast);\n if (!normalized) {\n // normalizedAST() normalizes a single level, so normalize the subqueries\n // first.\n const {where, related} = ast;\n normalized = normalizedAST({\n ...ast,\n where: where && normalizeSubqueries(where),\n related: related?.map(r =>\n normalizedRelated({...r, subquery: normalizeAST(r.subquery)}),\n ),\n });\n normalizeCache.set(ast, normalized);\n }\n return normalized;\n}\n\n/**\n * Normalizes the ASTs of the correlated subqueries of `cond`. The condition\n * itself is normalized by {@link normalizeCondition}.\n */\nfunction normalizeSubqueries(cond: Condition): Condition {\n switch (cond.type) {\n case 'simple':\n return cond;\n case 'correlatedSubquery':\n return {\n ...cond,\n related: {\n ...cond.related,\n subquery: normalizeAST(cond.related.subquery),\n },\n };\n default:\n return {\n type: cond.type,\n conditions: cond.conditions.map(normalizeSubqueries),\n };\n }\n}\n\n/**\n * Normalizes a single level of an AST, assuming that the ASTs of its\n * subqueries (i.e. those in `related` and in correlated subquery conditions)\n * are already normalized and that the `related` entries have the shape that\n * {@link normalizedRelated} gives them.\n *\n * This lets a query builder keep its AST normalized as it builds it up\n * instead of normalizing the whole tree afterwards. A builder that knows\n * which of the rules a step can break at all is better off applying just\n * those (see {@link tableAST}, {@link insertRelated} and\n * {@link normalizeCondition}).\n */\nexport function normalizedAST(ast: AST): NormalizedAST {\n const {schema, table, alias, where, related, start, limit, orderBy} = ast;\n // Every field is written, in the same order, so that all normalized ASTs\n // have the same shape (one hidden class) and the same JSON encoding (and\n // thus the same hash) no matter how they were put together. The fields that\n // are undefined are dropped by JSON.stringify() anyway.\n return asNormalized({\n schema,\n table,\n alias,\n where: where === undefined ? undefined : normalizeCondition(where),\n related: related === undefined ? undefined : normalizeRelated(related),\n start,\n limit,\n orderBy,\n });\n}\n\n/**\n * The normalized AST that selects a whole table. Spreading it (or any other\n * normalized AST) and replacing a field keeps the field order, since a\n * normalized AST has every field.\n */\nexport function tableAST(\n table: string,\n alias?: string | undefined,\n): NormalizedAST {\n return asNormalized({\n schema: undefined,\n table,\n alias,\n where: undefined,\n related: undefined,\n start: undefined,\n limit: undefined,\n orderBy: undefined,\n });\n}\n\n/**\n * Adds `subquery` to the `related` of a normalized AST, at the position that\n * keeps it sorted.\n */\nexport function insertRelated(\n related: readonly CorrelatedSubquery[] | undefined,\n subquery: CorrelatedSubquery,\n): readonly CorrelatedSubquery[] {\n const normalized = normalizedRelated(subquery);\n if (related === undefined) {\n return [normalized];\n }\n // Sorting is stable, so an entry goes after the ones it compares equal to.\n let i = related.length;\n while (i > 0 && cmpRelated(related[i - 1], normalized) > 0) {\n i--;\n }\n return related.toSpliced(i, 0, normalized);\n}\n\n// Conjunctions and disjunctions that are known to be normalized. The query\n// builder rebuilds its AST for every step, so this keeps the conditions that\n// did not change from being normalized over and over again.\nconst normalizedConditions = new WeakSet<Condition>();\n\nfunction normalizeRelated(\n related: readonly CorrelatedSubquery[],\n): readonly CorrelatedSubquery[] {\n for (let i = 1; i < related.length; i++) {\n if (cmpRelated(related[i - 1], related[i]) > 0) {\n return related.toSorted(cmpRelated);\n }\n }\n return related;\n}\n\n/**\n * Gives a correlated subquery the shape that a normalized AST has: every\n * field, in a fixed order (see {@link normalizedAST}). Its `subquery` must\n * already be normalized.\n */\nexport function normalizedRelated(\n related: CorrelatedSubquery,\n): Required<CorrelatedSubquery> {\n const {correlation, hidden, subquery, system} = related;\n return {\n correlation: {\n parentField: correlation.parentField,\n childField: correlation.childField,\n },\n hidden,\n subquery,\n system,\n };\n}\n\nfunction normalizeValuePosition<T extends ValuePosition>(v: T): T {\n switch (v.type) {\n case 'literal':\n return {type: 'literal', value: v.value} as T;\n case 'column':\n return {type: 'column', name: v.name} as T;\n default:\n return {type: 'static', anchor: v.anchor, field: v.field} as T;\n }\n}\n\n/**\n * Normalizes a condition, assuming that the ASTs of any correlated subqueries\n * it contains are already normalized.\n *\n * Like {@link normalizedAST}, this rebuilds every node with its fields in a\n * fixed order, so that structurally equal conditions have the same JSON\n * encoding (and thus the same hash) no matter how they were put together.\n * That includes a round trip through Postgres, whose jsonb type reorders\n * object keys: without the rebuild, every query record reloaded from the CVR\n * re-hashed to a different transformationHash than was stored, making it look\n * changed and re-execute on every view-syncer restart.\n */\nexport function normalizeCondition(cond: Condition): Condition {\n if (normalizedConditions.has(cond)) {\n return cond;\n }\n if (cond.type === 'simple') {\n const normalized: Condition = {\n type: 'simple',\n op: cond.op,\n left: normalizeValuePosition(cond.left),\n right: normalizeValuePosition(cond.right),\n };\n normalizedConditions.add(normalized);\n return normalized;\n }\n if (cond.type === 'correlatedSubquery') {\n const normalized: Condition = {\n type: 'correlatedSubquery',\n related: normalizedRelated(cond.related),\n op: cond.op,\n flip: cond.flip,\n scalar: cond.scalar,\n };\n normalizedConditions.add(normalized);\n return normalized;\n }\n\n // Flatten the conditions of nested conjunctions of the same type and sort\n // them. The nested conditions are normalized (and thus flattened and sorted)\n // first.\n const conditions: Condition[] = [];\n for (const c of cond.conditions) {\n const n = normalizeCondition(c);\n if (n.type === cond.type) {\n conditions.push(...n.conditions);\n } else {\n conditions.push(n);\n }\n }\n\n // A singleton conjunction is the same as the condition itself. Empty\n // conjunctions, on the other hand, are meaningful: an empty 'and' is always\n // true and an empty 'or' is always false.\n if (conditions.length === 1) {\n return conditions[0];\n }\n conditions.sort(cmpCondition);\n const normalized: Condition = {type: cond.type, conditions};\n normalizedConditions.add(normalized);\n return normalized;\n}\n\n/**\n * Maps the table and column names of `ast`. The result is not a\n * {@link NormalizedAST} even if `ast` was normalized: the names it sorts by\n * are the ones that changed.\n */\nexport function mapAST(ast: AST, mapper: NameMapper) {\n return transformAST(ast, {\n tableName: table => mapper.tableName(table),\n columnName: (table, col) => mapper.columnName(table, col),\n });\n}\n\nexport function mapCondition(\n cond: Condition,\n table: string,\n mapper: NameMapper,\n) {\n return transformWhere(cond, table, {\n tableName: table => mapper.tableName(table),\n columnName: (table, col) => mapper.columnName(table, col),\n });\n}\n\nfunction cmpCondition(a: Condition, b: Condition): number {\n if (a.type === 'simple') {\n if (b.type !== 'simple') {\n return -1; // Order SimpleConditions first\n }\n\n return (\n compareValuePosition(a.left, b.left) ||\n compareUTF8MaybeNull(a.op, b.op) ||\n compareValuePosition(a.right, b.right)\n );\n }\n\n if (b.type === 'simple') {\n return 1; // Order SimpleConditions first\n }\n\n if (a.type === 'correlatedSubquery') {\n if (b.type !== 'correlatedSubquery') {\n return -1; // Order subquery before conjuctions/disjuctions\n }\n return (\n cmpRelated(a.related, b.related) ||\n compareUTF8MaybeNull(a.op, b.op) ||\n cmpOptionalBool(a.flip, b.flip) ||\n cmpOptionalBool(a.scalar, b.scalar)\n );\n }\n if (b.type === 'correlatedSubquery') {\n return -1; // Order correlatedSubquery before conjuctions/disjuctions\n }\n\n const val = compareUTF8MaybeNull(a.type, b.type);\n if (val !== 0) {\n return val;\n }\n for (\n let l = 0, r = 0;\n l < a.conditions.length && r < b.conditions.length;\n l++, r++\n ) {\n const val = cmpCondition(a.conditions[l], b.conditions[r]);\n if (val !== 0) {\n return val;\n }\n }\n // prefixes first\n return a.conditions.length - b.conditions.length;\n}\n\nfunction compareValuePosition(a: ValuePosition, b: ValuePosition): number {\n if (a.type !== b.type) {\n return compareUTF8(a.type, b.type);\n }\n switch (a.type) {\n case 'literal':\n assert(b.type === 'literal', 'Expected literal type for comparison');\n return cmpLiteralValue(a.value, b.value);\n case 'column':\n assert(b.type === 'column', 'Expected column type for comparison');\n return compareUTF8(a.name, b.name);\n case 'static':\n assert(b.type === 'static', 'Expected static type for comparison');\n // A field is a string or a path of strings, which cmpLiteralValue()\n // tells apart.\n return (\n compareUTF8(a.anchor, b.anchor) || cmpLiteralValue(a.field, b.field)\n );\n }\n}\n\n// null < boolean < number < string < array. Ordering values of different\n// types by their string form would make distinct values compare equal (['a',\n// 'b'] and 'a,b', or 1 and '1'), which would leave their order up to the\n// order they were written in, and with it the hash of the query.\nconst LITERAL_VALUE_TYPES = ['object', 'boolean', 'number', 'string'];\n\nfunction literalValueType(value: LiteralValue): number {\n return Array.isArray(value)\n ? LITERAL_VALUE_TYPES.length\n : LITERAL_VALUE_TYPES.indexOf(typeof value);\n}\n\nfunction cmpLiteralValue(a: LiteralValue, b: LiteralValue): number {\n const type = literalValueType(a) - literalValueType(b);\n if (type !== 0) {\n return type;\n }\n\n if (Array.isArray(a)) {\n assert(Array.isArray(b), 'Expected array for comparison');\n for (let i = 0; i < a.length && i < b.length; i++) {\n const val = cmpLiteralValue(a[i], b[i]);\n if (val !== 0) {\n return val;\n }\n }\n // prefixes first\n return a.length - b.length;\n }\n\n switch (typeof a) {\n case 'string':\n assert(typeof b === 'string', 'Expected string for comparison');\n return compareUTF8(a, b);\n case 'number':\n assert(typeof b === 'number', 'Expected number for comparison');\n return a < b ? -1 : a > b ? 1 : 0;\n case 'boolean':\n assert(typeof b === 'boolean', 'Expected boolean for comparison');\n return Number(a) - Number(b);\n default:\n return 0; // null\n }\n}\n\nfunction cmpRelated(a: CorrelatedSubquery, b: CorrelatedSubquery): number {\n return compareUTF8(must(a.subquery.alias), must(b.subquery.alias));\n}\n\nfunction compareUTF8MaybeNull(a: string | null, b: string | null): number {\n if (a !== null && b !== null) {\n return compareUTF8(a, b);\n }\n if (b !== null) {\n return -1;\n }\n if (a !== null) {\n return 1;\n }\n return 0;\n}\n\nfunction cmpOptionalBool(\n a: boolean | undefined,\n b: boolean | undefined,\n): number {\n // undefined < false < true\n const toNum = (v: boolean | undefined) => (v === undefined ? 0 : v ? 2 : 1);\n return toNum(a) - toNum(b);\n}\n"],"mappings":"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"}