@powersync/service-sync-rules 0.29.10 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/dist/BaseSqlDataQuery.d.ts +3 -9
  2. package/dist/BaseSqlDataQuery.js +11 -21
  3. package/dist/BaseSqlDataQuery.js.map +1 -1
  4. package/dist/BucketParameterQuerier.d.ts +42 -9
  5. package/dist/BucketParameterQuerier.js +30 -7
  6. package/dist/BucketParameterQuerier.js.map +1 -1
  7. package/dist/BucketSource.d.ts +94 -25
  8. package/dist/BucketSource.js +67 -0
  9. package/dist/BucketSource.js.map +1 -1
  10. package/dist/ExpressionType.d.ts +4 -2
  11. package/dist/ExpressionType.js.map +1 -1
  12. package/dist/HydratedSyncRules.d.ts +46 -0
  13. package/dist/HydratedSyncRules.js +88 -0
  14. package/dist/HydratedSyncRules.js.map +1 -0
  15. package/dist/HydrationState.d.ts +45 -0
  16. package/dist/HydrationState.js +41 -0
  17. package/dist/HydrationState.js.map +1 -0
  18. package/dist/SqlBucketDescriptor.d.ts +31 -28
  19. package/dist/SqlBucketDescriptor.js +89 -112
  20. package/dist/SqlBucketDescriptor.js.map +1 -1
  21. package/dist/SqlDataQuery.d.ts +4 -4
  22. package/dist/SqlDataQuery.js +5 -6
  23. package/dist/SqlDataQuery.js.map +1 -1
  24. package/dist/SqlParameterQuery.d.ts +17 -9
  25. package/dist/SqlParameterQuery.js +49 -23
  26. package/dist/SqlParameterQuery.js.map +1 -1
  27. package/dist/SqlSyncRules.d.ts +11 -53
  28. package/dist/SqlSyncRules.js +11 -376
  29. package/dist/SqlSyncRules.js.map +1 -1
  30. package/dist/StaticSqlParameterQuery.d.ts +13 -3
  31. package/dist/StaticSqlParameterQuery.js +38 -4
  32. package/dist/StaticSqlParameterQuery.js.map +1 -1
  33. package/dist/SyncConfig.d.ts +43 -0
  34. package/dist/SyncConfig.js +102 -0
  35. package/dist/SyncConfig.js.map +1 -0
  36. package/dist/TablePattern.d.ts +22 -4
  37. package/dist/TablePattern.js +57 -19
  38. package/dist/TablePattern.js.map +1 -1
  39. package/dist/TableValuedFunctionSqlParameterQuery.d.ts +14 -4
  40. package/dist/TableValuedFunctionSqlParameterQuery.js +41 -7
  41. package/dist/TableValuedFunctionSqlParameterQuery.js.map +1 -1
  42. package/dist/compatibility.d.ts +7 -0
  43. package/dist/compatibility.js +34 -0
  44. package/dist/compatibility.js.map +1 -1
  45. package/dist/compiler/bucket_resolver.d.ts +70 -0
  46. package/dist/compiler/bucket_resolver.js +131 -0
  47. package/dist/compiler/bucket_resolver.js.map +1 -0
  48. package/dist/compiler/compatibility.d.ts +16 -0
  49. package/dist/compiler/compatibility.js +12 -0
  50. package/dist/compiler/compatibility.js.map +1 -0
  51. package/dist/compiler/compiler.d.ts +110 -0
  52. package/dist/compiler/compiler.js +130 -0
  53. package/dist/compiler/compiler.js.map +1 -0
  54. package/dist/compiler/equality.d.ts +99 -0
  55. package/dist/compiler/equality.js +284 -0
  56. package/dist/compiler/equality.js.map +1 -0
  57. package/dist/compiler/expression.d.ts +77 -0
  58. package/dist/compiler/expression.js +122 -0
  59. package/dist/compiler/expression.js.map +1 -0
  60. package/dist/compiler/filter.d.ts +71 -0
  61. package/dist/compiler/filter.js +110 -0
  62. package/dist/compiler/filter.js.map +1 -0
  63. package/dist/compiler/filter_simplifier.d.ts +26 -0
  64. package/dist/compiler/filter_simplifier.js +119 -0
  65. package/dist/compiler/filter_simplifier.js.map +1 -0
  66. package/dist/compiler/ir_to_sync_plan.d.ts +37 -0
  67. package/dist/compiler/ir_to_sync_plan.js +163 -0
  68. package/dist/compiler/ir_to_sync_plan.js.map +1 -0
  69. package/dist/compiler/parser.d.ts +99 -0
  70. package/dist/compiler/parser.js +556 -0
  71. package/dist/compiler/parser.js.map +1 -0
  72. package/dist/compiler/querier_graph.d.ts +42 -0
  73. package/dist/compiler/querier_graph.js +365 -0
  74. package/dist/compiler/querier_graph.js.map +1 -0
  75. package/dist/compiler/rows.d.ts +113 -0
  76. package/dist/compiler/rows.js +156 -0
  77. package/dist/compiler/rows.js.map +1 -0
  78. package/dist/compiler/scope.d.ts +22 -0
  79. package/dist/compiler/scope.js +47 -0
  80. package/dist/compiler/scope.js.map +1 -0
  81. package/dist/compiler/sqlite.d.ts +77 -0
  82. package/dist/compiler/sqlite.js +412 -0
  83. package/dist/compiler/sqlite.js.map +1 -0
  84. package/dist/compiler/table.d.ts +66 -0
  85. package/dist/compiler/table.js +67 -0
  86. package/dist/compiler/table.js.map +1 -0
  87. package/dist/errors.d.ts +4 -2
  88. package/dist/errors.js +16 -1
  89. package/dist/errors.js.map +1 -1
  90. package/dist/events/SqlEventDescriptor.js +1 -1
  91. package/dist/events/SqlEventDescriptor.js.map +1 -1
  92. package/dist/events/SqlEventSourceQuery.d.ts +1 -1
  93. package/dist/events/SqlEventSourceQuery.js +1 -2
  94. package/dist/events/SqlEventSourceQuery.js.map +1 -1
  95. package/dist/from_yaml.d.ts +28 -0
  96. package/dist/from_yaml.js +411 -0
  97. package/dist/from_yaml.js.map +1 -0
  98. package/dist/index.d.ts +9 -0
  99. package/dist/index.js +9 -0
  100. package/dist/index.js.map +1 -1
  101. package/dist/json_schema.js +17 -1
  102. package/dist/json_schema.js.map +1 -1
  103. package/dist/request_functions.js.map +1 -1
  104. package/dist/schema-generators/DartSchemaGenerator.d.ts +3 -3
  105. package/dist/schema-generators/DartSchemaGenerator.js.map +1 -1
  106. package/dist/schema-generators/DotNetSchemaGenerator.d.ts +2 -2
  107. package/dist/schema-generators/DotNetSchemaGenerator.js.map +1 -1
  108. package/dist/schema-generators/JsLegacySchemaGenerator.d.ts +2 -2
  109. package/dist/schema-generators/JsLegacySchemaGenerator.js.map +1 -1
  110. package/dist/schema-generators/KotlinSchemaGenerator.d.ts +2 -2
  111. package/dist/schema-generators/KotlinSchemaGenerator.js.map +1 -1
  112. package/dist/schema-generators/RoomSchemaGenerator.d.ts +2 -2
  113. package/dist/schema-generators/RoomSchemaGenerator.js.map +1 -1
  114. package/dist/schema-generators/SchemaGenerator.d.ts +8 -3
  115. package/dist/schema-generators/SchemaGenerator.js +21 -14
  116. package/dist/schema-generators/SchemaGenerator.js.map +1 -1
  117. package/dist/schema-generators/SqlSchemaGenerator.d.ts +2 -2
  118. package/dist/schema-generators/SqlSchemaGenerator.js.map +1 -1
  119. package/dist/schema-generators/SwiftSchemaGenerator.d.ts +2 -2
  120. package/dist/schema-generators/SwiftSchemaGenerator.js.map +1 -1
  121. package/dist/schema-generators/TsSchemaGenerator.d.ts +2 -2
  122. package/dist/schema-generators/TsSchemaGenerator.js.map +1 -1
  123. package/dist/sql_functions.d.ts +4 -3
  124. package/dist/sql_functions.js +1 -1
  125. package/dist/sql_functions.js.map +1 -1
  126. package/dist/streams/filter.d.ts +34 -4
  127. package/dist/streams/filter.js +93 -23
  128. package/dist/streams/filter.js.map +1 -1
  129. package/dist/streams/from_sql.js +2 -5
  130. package/dist/streams/from_sql.js.map +1 -1
  131. package/dist/streams/parameter.d.ts +7 -6
  132. package/dist/streams/stream.d.ts +25 -15
  133. package/dist/streams/stream.js +59 -87
  134. package/dist/streams/stream.js.map +1 -1
  135. package/dist/streams/variant.d.ts +14 -21
  136. package/dist/streams/variant.js +68 -46
  137. package/dist/streams/variant.js.map +1 -1
  138. package/dist/sync_plan/engine/javascript.d.ts +6 -0
  139. package/dist/sync_plan/engine/javascript.js +208 -0
  140. package/dist/sync_plan/engine/javascript.js.map +1 -0
  141. package/dist/sync_plan/engine/scalar_expression_engine.d.ts +48 -0
  142. package/dist/sync_plan/engine/scalar_expression_engine.js +99 -0
  143. package/dist/sync_plan/engine/scalar_expression_engine.js.map +1 -0
  144. package/dist/sync_plan/engine/sqlite.d.ts +12 -0
  145. package/dist/sync_plan/engine/sqlite.js +53 -0
  146. package/dist/sync_plan/engine/sqlite.js.map +1 -0
  147. package/dist/sync_plan/evaluator/bucket_data_source.d.ts +24 -0
  148. package/dist/sync_plan/evaluator/bucket_data_source.js +139 -0
  149. package/dist/sync_plan/evaluator/bucket_data_source.js.map +1 -0
  150. package/dist/sync_plan/evaluator/bucket_source.d.ts +19 -0
  151. package/dist/sync_plan/evaluator/bucket_source.js +145 -0
  152. package/dist/sync_plan/evaluator/bucket_source.js.map +1 -0
  153. package/dist/sync_plan/evaluator/index.d.ts +17 -0
  154. package/dist/sync_plan/evaluator/index.js +32 -0
  155. package/dist/sync_plan/evaluator/index.js.map +1 -0
  156. package/dist/sync_plan/evaluator/parameter_evaluator.d.ts +138 -0
  157. package/dist/sync_plan/evaluator/parameter_evaluator.js +359 -0
  158. package/dist/sync_plan/evaluator/parameter_evaluator.js.map +1 -0
  159. package/dist/sync_plan/evaluator/parameter_index_lookup_creator.d.ts +20 -0
  160. package/dist/sync_plan/evaluator/parameter_index_lookup_creator.js +64 -0
  161. package/dist/sync_plan/evaluator/parameter_index_lookup_creator.js.map +1 -0
  162. package/dist/sync_plan/expression.d.ts +109 -0
  163. package/dist/sync_plan/expression.js +85 -0
  164. package/dist/sync_plan/expression.js.map +1 -0
  165. package/dist/sync_plan/expression_to_sql.d.ts +43 -0
  166. package/dist/sync_plan/expression_to_sql.js +190 -0
  167. package/dist/sync_plan/expression_to_sql.js.map +1 -0
  168. package/dist/sync_plan/expression_visitor.d.ts +57 -0
  169. package/dist/sync_plan/expression_visitor.js +181 -0
  170. package/dist/sync_plan/expression_visitor.js.map +1 -0
  171. package/dist/sync_plan/plan.d.ts +196 -0
  172. package/dist/sync_plan/plan.js +2 -0
  173. package/dist/sync_plan/plan.js.map +1 -0
  174. package/dist/sync_plan/schema_inference.d.ts +16 -0
  175. package/dist/sync_plan/schema_inference.js +123 -0
  176. package/dist/sync_plan/schema_inference.js.map +1 -0
  177. package/dist/sync_plan/serialize.d.ts +82 -0
  178. package/dist/sync_plan/serialize.js +214 -0
  179. package/dist/sync_plan/serialize.js.map +1 -0
  180. package/dist/types/custom_sqlite_value.d.ts +1 -1
  181. package/dist/types.d.ts +72 -29
  182. package/dist/types.js +30 -5
  183. package/dist/types.js.map +1 -1
  184. package/dist/utils.d.ts +10 -3
  185. package/dist/utils.js +26 -3
  186. package/dist/utils.js.map +1 -1
  187. package/package.json +4 -3
  188. package/schema/sync_rules.json +19 -3
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Stable value-based hashcodes for JavaScript. The sync streams compiler uses hashmaps derived from this to efficiently
3
+ * de-duplicate equivalent expressions and lookups.
4
+ *
5
+ * This is copied from Dart SDK sources, which in turn based the algorithm on Jenkins hash functions.
6
+ *
7
+ * Because hash codes are stable across restarts, they should not be used for untrusted inputs to avoid attacks
8
+ * provoking hash collisions and subpar hashmap performance. The sync rules package only uses these hashes to compile
9
+ * sync streams, but the compiled IR processing source rows does not need these hashes.
10
+ */
11
+ export class StableHasher {
12
+ static seed = 614160925; // 'PowerSync'.hashCode on the Dart VM
13
+ hash = StableHasher.seed;
14
+ addHash(value) {
15
+ let hash = 0x1fffffff & (this.hash + value);
16
+ hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
17
+ this.hash = hash ^ (hash >> 6);
18
+ }
19
+ reset() {
20
+ const old = this.hash;
21
+ this.hash = StableHasher.seed;
22
+ return old;
23
+ }
24
+ addString(value) {
25
+ for (let i = 0; i < value.length; i++) {
26
+ this.addHash(value.charCodeAt(i));
27
+ }
28
+ }
29
+ add(...e) {
30
+ for (const param of e) {
31
+ param.buildHash(this);
32
+ }
33
+ }
34
+ buildHashCode() {
35
+ let hash = this.hash;
36
+ hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
37
+ hash = hash ^ (hash >> 11);
38
+ return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
39
+ }
40
+ /**
41
+ * Hashes a value under the given equality implementation.
42
+ */
43
+ static hashWith(equality, value) {
44
+ const saved = this.hasher.reset();
45
+ equality.hash(this.hasher, value);
46
+ const result = this.hasher.buildHashCode();
47
+ this.hasher.hash = saved;
48
+ return result;
49
+ }
50
+ static hasher = new StableHasher();
51
+ /**
52
+ * The default equality for {@link Equatable} types.
53
+ */
54
+ static defaultEquality = {
55
+ hash(hasher, value) {
56
+ value.buildHash(hasher);
57
+ },
58
+ equals(a, b) {
59
+ return a.equals(b);
60
+ }
61
+ };
62
+ static defaultListEquality = listEquality(this.defaultEquality);
63
+ }
64
+ /**
65
+ * Creates an equality operator matching iterables with elements compared by an inner equality.
66
+ *
67
+ * Two iterables are considered equal if they contain the same elements in the same order.
68
+ */
69
+ export function listEquality(equality) {
70
+ return {
71
+ equals: (a, b) => {
72
+ if (a === b)
73
+ return true;
74
+ const iteratorA = a[Symbol.iterator]();
75
+ const iteratorB = b[Symbol.iterator]();
76
+ while (true) {
77
+ let nextA = iteratorA.next();
78
+ let nextB = iteratorB.next();
79
+ if (nextA.done != nextB.done) {
80
+ return false; // Different lengths
81
+ }
82
+ else if (nextA.done) {
83
+ return true; // Both done
84
+ }
85
+ else {
86
+ const elementA = nextA.value;
87
+ const elementB = nextB.value;
88
+ if (!equality.equals(elementA, elementB)) {
89
+ return false;
90
+ }
91
+ }
92
+ }
93
+ },
94
+ hash: (hasher, value) => {
95
+ for (const e of value) {
96
+ equality.hash(hasher, e);
97
+ }
98
+ }
99
+ };
100
+ }
101
+ /**
102
+ * Creates an equality operator matching iterables with elements compared by an inner equality.
103
+ *
104
+ * Two iterables are considered equal if they contain the same elements, in any order.
105
+ */
106
+ export function unorderedEquality(equality) {
107
+ return {
108
+ equals: (a, b) => {
109
+ if (a === b)
110
+ return true;
111
+ let counts = new HashMap(equality);
112
+ let length = 0;
113
+ // Count how often each element exists in a.
114
+ for (const e of a) {
115
+ counts.setOrUpdate(e, (old) => (old ?? 0) + 1);
116
+ length++;
117
+ }
118
+ // Then compare with b.
119
+ for (const e of b) {
120
+ let matched = false;
121
+ counts.setOrUpdate(e, (old) => {
122
+ matched = old != null && old > 0;
123
+ if (matched) {
124
+ return old - 1;
125
+ }
126
+ else {
127
+ return 0;
128
+ }
129
+ });
130
+ if (!matched) {
131
+ return false;
132
+ }
133
+ length--;
134
+ }
135
+ return length == 0;
136
+ },
137
+ hash: (hasher, value) => {
138
+ // https://github.com/dart-lang/core/blob/3e55c1ce7be48b469da5be043b5931fe6405f74a/pkgs/collection/lib/src/equality.dart#L236-L248
139
+ let hash = 0;
140
+ for (const element of value) {
141
+ hash = (hash + StableHasher.hashWith(equality, element)) & 0x7fffffff;
142
+ }
143
+ hasher.addHash(hash);
144
+ }
145
+ };
146
+ }
147
+ /**
148
+ * A hash map implementation based on a custom {@link Equality}.
149
+ *
150
+ * Like {@link Map}, this implementation also preserves insertion-order.
151
+ */
152
+ export class HashMap {
153
+ equality;
154
+ // We create one bucket per unique hash, and then store collisions in an array.
155
+ map = new Map();
156
+ first;
157
+ last;
158
+ constructor(equality) {
159
+ this.equality = equality;
160
+ }
161
+ computeHashCode(key) {
162
+ return StableHasher.hashWith(this.equality, key);
163
+ }
164
+ get isEmpty() {
165
+ return this.first == null;
166
+ }
167
+ get entries() {
168
+ return this.iterateEntries();
169
+ }
170
+ *iterateEntries() {
171
+ let next = this.first;
172
+ while (next != null) {
173
+ yield [next.key, next.value];
174
+ next = next.next;
175
+ }
176
+ }
177
+ get(key) {
178
+ const hashCode = this.computeHashCode(key);
179
+ const bucket = this.map.get(hashCode);
180
+ if (bucket) {
181
+ for (const entry of bucket) {
182
+ if (this.equality.equals(entry.key, key)) {
183
+ return entry.value;
184
+ }
185
+ }
186
+ }
187
+ }
188
+ set(key, value) {
189
+ const hashCode = this.computeHashCode(key);
190
+ let bucket = this.map.get(hashCode);
191
+ if (!bucket) {
192
+ bucket = [];
193
+ this.map.set(hashCode, bucket);
194
+ }
195
+ this.addEntryInBucket(bucket, key, value);
196
+ }
197
+ setOrUpdate(key, updater) {
198
+ const hashCode = this.computeHashCode(key);
199
+ let bucket = this.map.get(hashCode);
200
+ if (!bucket) {
201
+ bucket = [];
202
+ this.map.set(hashCode, bucket);
203
+ }
204
+ else {
205
+ for (const entry of bucket) {
206
+ if (this.equality.equals(entry.key, key)) {
207
+ entry.value = updater(entry.value, entry.key);
208
+ return;
209
+ }
210
+ }
211
+ }
212
+ this.addEntryInBucket(bucket, key, updater(undefined, undefined));
213
+ }
214
+ putIfAbsent(key, ifAbsent) {
215
+ let result = undefined;
216
+ this.setOrUpdate(key, (old) => {
217
+ if (old == null) {
218
+ return (result = ifAbsent());
219
+ }
220
+ else {
221
+ return (result = old);
222
+ }
223
+ });
224
+ return result;
225
+ }
226
+ addEntryInBucket(bucket, key, value) {
227
+ const entry = new LinkedHashMapEntry(key, value);
228
+ bucket.push(entry);
229
+ if (this.first) {
230
+ this.last.next = entry;
231
+ entry.prev = this.last;
232
+ this.last = entry;
233
+ }
234
+ else {
235
+ this.first = this.last = entry;
236
+ }
237
+ }
238
+ }
239
+ /**
240
+ * An insertion-order preserving hash set implementation based on {@link HashMap}.
241
+ */
242
+ export class HashSet {
243
+ inner;
244
+ constructor(equality) {
245
+ this.inner = new HashMap(equality);
246
+ }
247
+ [Symbol.iterator]() {
248
+ return this.entries()[Symbol.iterator]();
249
+ }
250
+ *entries() {
251
+ for (const [k, _] of this.inner.entries) {
252
+ yield k;
253
+ }
254
+ }
255
+ add(element) {
256
+ return this.getOrInsert(element)[1];
257
+ }
258
+ getOrInsert(element) {
259
+ let result = null;
260
+ this.inner.setOrUpdate(element, (old, oldKey) => {
261
+ if (oldKey == null) {
262
+ result = [element, true];
263
+ return HashSet.sentinel;
264
+ }
265
+ else {
266
+ result = [oldKey, false];
267
+ return oldKey;
268
+ }
269
+ });
270
+ return result;
271
+ }
272
+ static sentinel = new Object();
273
+ }
274
+ class LinkedHashMapEntry {
275
+ key;
276
+ prev;
277
+ next;
278
+ value;
279
+ constructor(key, value) {
280
+ this.key = key;
281
+ this.value = value;
282
+ }
283
+ }
284
+ //# sourceMappingURL=equality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"equality.js","sourceRoot":"","sources":["../../src/compiler/equality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,OAAO,YAAY;IACf,MAAM,CAAU,IAAI,GAAW,SAAS,CAAC,CAAC,sCAAsC;IAEhF,IAAI,GAAW,YAAY,CAAC,IAAI,CAAC;IAEzC,OAAO,CAAC,KAAa;QACnB,IAAI,IAAI,GAAG,UAAU,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QAC5C,IAAI,GAAG,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IACjC,CAAC;IAED,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC;QAC9B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,SAAS,CAAC,KAAa;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,GAAG,CAAC,GAAG,CAAc;QACnB,KAAK,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC;YACtB,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,aAAa;QACX,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACrB,IAAI,GAAG,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxD,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC3B,OAAO,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAI,QAAqB,EAAE,KAAQ;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,MAAM,CAAU,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;IAEpD;;OAEG;IACK,MAAM,CAAU,eAAe,GAAwB;QAC7D,IAAI,CAAC,MAAM,EAAE,KAAK;YAChB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;QACD,MAAM,CAAC,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC;KACF,CAAC;IAEF,MAAM,CAAU,mBAAmB,GAAG,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;;AA+B3E;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAI,QAAqB;IACnD,OAAO;QACL,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACf,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YAEzB,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAEvC,OAAO,IAAI,EAAE,CAAC;gBACZ,IAAI,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;gBAC7B,IAAI,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;gBAE7B,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;oBAC7B,OAAO,KAAK,CAAC,CAAC,oBAAoB;gBACpC,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;oBACtB,OAAO,IAAI,CAAC,CAAC,YAAY;gBAC3B,CAAC;qBAAM,CAAC;oBACN,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;oBAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC;oBAC7B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;wBACzC,OAAO,KAAK,CAAC;oBACf,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACtB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAI,QAAqB;IACxD,OAAO;QACL,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACf,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YAEzB,IAAI,MAAM,GAAG,IAAI,OAAO,CAAY,QAAQ,CAAC,CAAC;YAC9C,IAAI,MAAM,GAAG,CAAC,CAAC;YACf,4CAA4C;YAC5C,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClB,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC/C,MAAM,EAAE,CAAC;YACX,CAAC;YAED,uBAAuB;YACvB,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClB,IAAI,OAAO,GAAG,KAAK,CAAC;gBACpB,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;oBAC5B,OAAO,GAAG,GAAG,IAAI,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC;oBACjC,IAAI,OAAO,EAAE,CAAC;wBACZ,OAAO,GAAI,GAAG,CAAC,CAAC;oBAClB,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,CAAC;oBACX,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,MAAM,EAAE,CAAC;YACX,CAAC;YAED,OAAO,MAAM,IAAI,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACtB,kIAAkI;YAClI,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE,CAAC;gBAC5B,IAAI,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,GAAG,UAAU,CAAC;YACxE,CAAC;YAED,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,OAAO;IAOW;IAN7B,+EAA+E;IAC9D,GAAG,GAAG,IAAI,GAAG,EAAsC,CAAC;IAE7D,KAAK,CAAuC;IAC5C,IAAI,CAAuC;IAEnD,YAA6B,QAAqB;QAArB,aAAQ,GAAR,QAAQ,CAAa;IAAG,CAAC;IAE9C,eAAe,CAAC,GAAM;QAC5B,OAAO,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;IAC5B,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC;IAC/B,CAAC;IAEO,CAAC,cAAc;QACrB,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACtB,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAC7B,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;IAED,GAAG,CAAC,GAAM;QACR,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;oBACzC,OAAO,KAAK,CAAC,KAAK,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,GAAG,CAAC,GAAM,EAAE,KAAQ;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,EAAE,CAAC;YACZ,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC;IAED,WAAW,CAAC,GAAM,EAAE,OAAyD;QAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,EAAE,CAAC;YACZ,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;oBACzC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;oBAC9C,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,WAAW,CAAC,GAAM,EAAE,QAAiB;QACnC,IAAI,MAAM,GAAkB,SAAS,CAAC;QACtC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;YAC5B,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;gBAChB,OAAO,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;YACxB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,MAAO,CAAC;IACjB,CAAC;IAEO,gBAAgB,CAAC,MAAkC,EAAE,GAAM,EAAE,KAAQ;QAC3E,MAAM,KAAK,GAAG,IAAI,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,IAAK,CAAC,IAAI,GAAG,KAAK,CAAC;YACxB,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACvB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;QACjC,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,OAAO;IACD,KAAK,CAAqB;IAE3C,YAAY,QAAqB;QAC/B,IAAI,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,CAAC,MAAM,CAAC,QAAQ,CAAC;QACf,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC3C,CAAC;IAEO,CAAC,OAAO;QACd,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACxC,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAED,GAAG,CAAC,OAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,WAAW,CAAC,OAAU;QACpB,IAAI,MAAM,GAAwB,IAAI,CAAC;QACvC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;YAC9C,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBACzB,OAAO,OAAO,CAAC,QAAQ,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC,MAAO,EAAE,KAAK,CAAC,CAAC;gBAC1B,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,MAAO,CAAC;IACjB,CAAC;IAEO,MAAM,CAAU,QAAQ,GAAG,IAAI,MAAM,EAAE,CAAC;;AAGlD,MAAM,kBAAkB;IAOX;IANX,IAAI,CAAuC;IAC3C,IAAI,CAAuC;IAE3C,KAAK,CAAI;IAET,YACW,GAAM,EACf,KAAQ;QADC,QAAG,GAAH,GAAG,CAAG;QAGf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,77 @@
1
+ import { Expr, NodeLocation, PGNode } from 'pgsql-ast-parser';
2
+ import { SourceResultSet } from './table.js';
3
+ import { EqualsIgnoringResultSet } from './compatibility.js';
4
+ import { StableHasher } from './equality.js';
5
+ import { ConnectionParameterSource } from '../sync_plan/plan.js';
6
+ import { SqlExpression } from '../sync_plan/expression.js';
7
+ /**
8
+ * An analyzed SQL expression tracking dependencies on non-static data (i.e. rows or connection sources).
9
+ *
10
+ * Consider the sync stream `SELECT * FROM issues WHERE is_public OR auth.param('is_admin')`. To be able to explicitly
11
+ * track dependencies referenced in expressions, we transform them into a {@link SyncExpression}. For the `WHERE` clause
12
+ * in that example, the {@link sqlExpression} would be `?1 OR (?2 ->> 'is_admin')`, where `?1` is a {@link ColumnInRow}
13
+ * and `?2` is a {@link ConnectionParameter}.
14
+ *
15
+ * Once in this form, it's easy to reason about dependencies in expressions (used to later generate parameter match
16
+ * clauses) and to evaluate expressions at runtime (by preparing them as a statement and binding external values).
17
+ */
18
+ export declare class SyncExpression implements EqualsIgnoringResultSet {
19
+ #private;
20
+ /**
21
+ * The AST node backing {@link sql}.
22
+ *
23
+ * We use this to be able to compose expressions, e.g. to possibly merge them.
24
+ */
25
+ readonly node: SqlExpression<ExpressionInput>;
26
+ readonly locations: NodeLocations;
27
+ /**
28
+ * The original expression, where references to row or connection parameters have been replaced with SQL variables
29
+ * that are tracked through {@link instantiation}.
30
+ *
31
+ * This is only used to compute hash codes and to check instances for equality. {@link node} is the canonical
32
+ * representation of this expression.
33
+ */
34
+ get sql(): string;
35
+ /**
36
+ * The values to instantiate parameters in {@link sqlExpression} with to retain original semantics of the
37
+ * expression.
38
+ */
39
+ get instantiation(): readonly ExpressionInput[];
40
+ get location(): NodeLocation;
41
+ constructor(
42
+ /**
43
+ * The AST node backing {@link sql}.
44
+ *
45
+ * We use this to be able to compose expressions, e.g. to possibly merge them.
46
+ */
47
+ node: SqlExpression<ExpressionInput>, locations: NodeLocations);
48
+ equalsAssumingSameResultSet(other: EqualsIgnoringResultSet): boolean;
49
+ assumingSameResultSetEqualityHashCode(hasher: StableHasher): void;
50
+ }
51
+ export type ExpressionInput = ColumnInRow | ConnectionParameter;
52
+ export declare class ColumnInRow implements EqualsIgnoringResultSet {
53
+ readonly syntacticOrigin: Expr;
54
+ readonly resultSet: SourceResultSet;
55
+ readonly column: string;
56
+ constructor(syntacticOrigin: Expr, resultSet: SourceResultSet, column: string);
57
+ equalsAssumingSameResultSet(other: EqualsIgnoringResultSet): boolean;
58
+ assumingSameResultSetEqualityHashCode(hasher: StableHasher): void;
59
+ }
60
+ export declare class ConnectionParameter implements EqualsIgnoringResultSet {
61
+ readonly syntacticOrigin: Expr;
62
+ readonly source: ConnectionParameterSource;
63
+ constructor(syntacticOrigin: Expr, source: ConnectionParameterSource);
64
+ equalsAssumingSameResultSet(other: EqualsIgnoringResultSet): boolean;
65
+ assumingSameResultSetEqualityHashCode(hasher: StableHasher): void;
66
+ }
67
+ /**
68
+ * Tracks the original source location for translated {@link SqlExpression} nodes.
69
+ *
70
+ * We want to serialize translated expressions for sync plan, so embedding source offsets in them expands the size of
71
+ * sync plans and is tedious. We only need access to node locations while compiling sync streams, which we store in this
72
+ * in-memory map.
73
+ */
74
+ export declare class NodeLocations {
75
+ readonly sourceForNode: Map<SqlExpression<unknown>, PGNode | NodeLocation>;
76
+ locationFor(source: SqlExpression<unknown>): NodeLocation;
77
+ }
@@ -0,0 +1,122 @@
1
+ import { equalsIgnoringResultSetList } from './compatibility.js';
2
+ import { ExpressionToSqlite } from '../sync_plan/expression_to_sql.js';
3
+ import { RecursiveExpressionVisitor } from '../sync_plan/expression_visitor.js';
4
+ import { getLocation } from '../errors.js';
5
+ /**
6
+ * An analyzed SQL expression tracking dependencies on non-static data (i.e. rows or connection sources).
7
+ *
8
+ * Consider the sync stream `SELECT * FROM issues WHERE is_public OR auth.param('is_admin')`. To be able to explicitly
9
+ * track dependencies referenced in expressions, we transform them into a {@link SyncExpression}. For the `WHERE` clause
10
+ * in that example, the {@link sqlExpression} would be `?1 OR (?2 ->> 'is_admin')`, where `?1` is a {@link ColumnInRow}
11
+ * and `?2` is a {@link ConnectionParameter}.
12
+ *
13
+ * Once in this form, it's easy to reason about dependencies in expressions (used to later generate parameter match
14
+ * clauses) and to evaluate expressions at runtime (by preparing them as a statement and binding external values).
15
+ */
16
+ export class SyncExpression {
17
+ node;
18
+ locations;
19
+ #sql;
20
+ #instantiation;
21
+ /**
22
+ * The original expression, where references to row or connection parameters have been replaced with SQL variables
23
+ * that are tracked through {@link instantiation}.
24
+ *
25
+ * This is only used to compute hash codes and to check instances for equality. {@link node} is the canonical
26
+ * representation of this expression.
27
+ */
28
+ get sql() {
29
+ return (this.#sql ??= ExpressionToSqlite.toSqlite(this.node));
30
+ }
31
+ /**
32
+ * The values to instantiate parameters in {@link sqlExpression} with to retain original semantics of the
33
+ * expression.
34
+ */
35
+ get instantiation() {
36
+ if (this.#instantiation != null) {
37
+ return this.#instantiation;
38
+ }
39
+ const instantiation = [];
40
+ FindExternalData.instance.visit(this.node, instantiation);
41
+ return (this.#instantiation = instantiation);
42
+ }
43
+ get location() {
44
+ return this.locations.locationFor(this.node);
45
+ }
46
+ constructor(
47
+ /**
48
+ * The AST node backing {@link sql}.
49
+ *
50
+ * We use this to be able to compose expressions, e.g. to possibly merge them.
51
+ */
52
+ node, locations) {
53
+ this.node = node;
54
+ this.locations = locations;
55
+ }
56
+ equalsAssumingSameResultSet(other) {
57
+ return (other instanceof SyncExpression &&
58
+ other.sql == this.sql &&
59
+ equalsIgnoringResultSetList.equals(other.instantiation, this.instantiation));
60
+ }
61
+ assumingSameResultSetEqualityHashCode(hasher) {
62
+ hasher.addString(this.sql);
63
+ equalsIgnoringResultSetList.hash(hasher, this.instantiation);
64
+ }
65
+ }
66
+ class FindExternalData extends RecursiveExpressionVisitor {
67
+ defaultExpression(expr, arg) {
68
+ this.visitChildren(expr, arg);
69
+ }
70
+ visitExternalData(expr, arg) {
71
+ arg.push(expr.source);
72
+ }
73
+ static instance = new FindExternalData();
74
+ }
75
+ export class ColumnInRow {
76
+ syntacticOrigin;
77
+ resultSet;
78
+ column;
79
+ constructor(syntacticOrigin, resultSet, column) {
80
+ this.syntacticOrigin = syntacticOrigin;
81
+ this.resultSet = resultSet;
82
+ this.column = column;
83
+ }
84
+ equalsAssumingSameResultSet(other) {
85
+ return other instanceof ColumnInRow && other.column == this.column;
86
+ }
87
+ assumingSameResultSetEqualityHashCode(hasher) {
88
+ hasher.addString(this.column);
89
+ }
90
+ }
91
+ export class ConnectionParameter {
92
+ syntacticOrigin;
93
+ source;
94
+ constructor(syntacticOrigin, source) {
95
+ this.syntacticOrigin = syntacticOrigin;
96
+ this.source = source;
97
+ }
98
+ equalsAssumingSameResultSet(other) {
99
+ return other instanceof ConnectionParameter && other.source == this.source;
100
+ }
101
+ assumingSameResultSetEqualityHashCode(hasher) {
102
+ hasher.addString(this.source);
103
+ }
104
+ }
105
+ /**
106
+ * Tracks the original source location for translated {@link SqlExpression} nodes.
107
+ *
108
+ * We want to serialize translated expressions for sync plan, so embedding source offsets in them expands the size of
109
+ * sync plans and is tedious. We only need access to node locations while compiling sync streams, which we store in this
110
+ * in-memory map.
111
+ */
112
+ export class NodeLocations {
113
+ sourceForNode = new Map();
114
+ locationFor(source) {
115
+ const location = getLocation(this.sourceForNode.get(source));
116
+ if (location == null) {
117
+ throw new Error('Missing location');
118
+ }
119
+ return location;
120
+ }
121
+ }
122
+ //# sourceMappingURL=expression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression.js","sourceRoot":"","sources":["../../src/compiler/expression.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import { NodeLocation } from 'pgsql-ast-parser';
2
+ import { ExpressionInput, SyncExpression } from './expression.js';
3
+ import { SourceResultSet } from './table.js';
4
+ import { EqualsIgnoringResultSet } from './compatibility.js';
5
+ import { StableHasher } from './equality.js';
6
+ export interface Or {
7
+ terms: And[];
8
+ }
9
+ export interface And {
10
+ terms: BaseTerm[];
11
+ }
12
+ /**
13
+ * A boolean expression that doesn't have boolean operators with subexpressions referencing different tables in it.
14
+ *
15
+ * These basic terms form a filter by being composed into a distributive normal form. For analysis, we just need to know
16
+ * how terms from different tables relate to each other. So `users.id = auth.user_id() AND issues.is_public` need to be
17
+ * two terms in an {@link And}, but `users.is_deleted OR users.is_admin` can be represented as a single base term.
18
+ */
19
+ export type BaseTerm = SingleDependencyExpression | EqualsClause;
20
+ export declare function isBaseTerm(value: unknown): value is BaseTerm;
21
+ /**
22
+ * A {@link SyncExpression} that only depends on a single result set or connection data.
23
+ */
24
+ export declare class SingleDependencyExpression implements EqualsIgnoringResultSet {
25
+ readonly expression: SyncExpression;
26
+ /**
27
+ * The single result set on which the expression depends on.
28
+ *
29
+ * If null, the expression is allowed to depend on subscription parameters instead.
30
+ */
31
+ readonly resultSet: SourceResultSet | null;
32
+ /**
33
+ * Whether this expression depends on data derived from the connection or subscription.
34
+ */
35
+ readonly dependsOnConnection: boolean;
36
+ constructor(expression: SyncExpression | SingleDependencyExpression);
37
+ equalsAssumingSameResultSet(other: EqualsIgnoringResultSet): boolean;
38
+ assumingSameResultSetEqualityHashCode(hasher: StableHasher): void;
39
+ /**
40
+ * If all inputs have a single dependency, returns either the result set they all depend on or `null` and whether they
41
+ * depend on connection data.
42
+ *
43
+ * If the inputs have more than a single distinct dependency, returns null.
44
+ */
45
+ static extractSingleDependency(inputs: Iterable<ExpressionInput>): [SourceResultSet | null, boolean] | null;
46
+ }
47
+ /**
48
+ * A {@link SyncExpression} that only depends on data from a single row.
49
+ */
50
+ export declare class RowExpression extends SingleDependencyExpression {
51
+ readonly resultSet: SourceResultSet;
52
+ constructor(expression: SyncExpression | SingleDependencyExpression);
53
+ }
54
+ /**
55
+ * A {@link SyncExpression} that only depends on connection data.
56
+ */
57
+ export declare class RequestExpression extends SingleDependencyExpression {
58
+ constructor(expression: SyncExpression | SingleDependencyExpression);
59
+ }
60
+ /**
61
+ * An expression of the form `foo = bar`, where `foo` and `bar` are expressions allowed to depend on different sources.
62
+ */
63
+ export declare class EqualsClause {
64
+ readonly left: SingleDependencyExpression;
65
+ readonly right: SingleDependencyExpression;
66
+ constructor(left: SingleDependencyExpression, right: SingleDependencyExpression);
67
+ get location(): NodeLocation | undefined;
68
+ }
69
+ export declare class InvalidExpressionError extends Error {
70
+ constructor(message: string);
71
+ }
@@ -0,0 +1,110 @@
1
+ import { ColumnInRow, SyncExpression } from './expression.js';
2
+ import { expandNodeLocations } from '../errors.js';
3
+ export function isBaseTerm(value) {
4
+ return value instanceof SingleDependencyExpression || value instanceof EqualsClause;
5
+ }
6
+ /**
7
+ * A {@link SyncExpression} that only depends on a single result set or connection data.
8
+ */
9
+ export class SingleDependencyExpression {
10
+ expression;
11
+ /**
12
+ * The single result set on which the expression depends on.
13
+ *
14
+ * If null, the expression is allowed to depend on subscription parameters instead.
15
+ */
16
+ resultSet;
17
+ /**
18
+ * Whether this expression depends on data derived from the connection or subscription.
19
+ */
20
+ dependsOnConnection;
21
+ constructor(expression) {
22
+ if (expression instanceof SyncExpression) {
23
+ const checked = SingleDependencyExpression.extractSingleDependency(expression.instantiation);
24
+ if (checked == null) {
25
+ throw new InvalidExpressionError('Expression with multiple dependencies passed to SingleDependencyExpression');
26
+ }
27
+ this.expression = expression;
28
+ this.resultSet = checked[0];
29
+ this.dependsOnConnection = checked[1];
30
+ }
31
+ else {
32
+ this.expression = expression.expression;
33
+ this.resultSet = expression.resultSet;
34
+ this.dependsOnConnection = expression.dependsOnConnection;
35
+ }
36
+ }
37
+ equalsAssumingSameResultSet(other) {
38
+ return other instanceof SingleDependencyExpression && other.expression.equalsAssumingSameResultSet(this.expression);
39
+ }
40
+ assumingSameResultSetEqualityHashCode(hasher) {
41
+ this.expression.assumingSameResultSetEqualityHashCode(hasher);
42
+ }
43
+ /**
44
+ * If all inputs have a single dependency, returns either the result set they all depend on or `null` and whether they
45
+ * depend on connection data.
46
+ *
47
+ * If the inputs have more than a single distinct dependency, returns null.
48
+ */
49
+ static extractSingleDependency(inputs) {
50
+ let resultSet = null;
51
+ let hasSubscriptionDependency = false;
52
+ for (const dependency of inputs) {
53
+ if (dependency instanceof ColumnInRow) {
54
+ if ((resultSet != null && resultSet !== dependency.resultSet) || hasSubscriptionDependency) {
55
+ return null;
56
+ }
57
+ resultSet = dependency.resultSet;
58
+ }
59
+ else {
60
+ if (resultSet != null) {
61
+ return null;
62
+ }
63
+ hasSubscriptionDependency = true;
64
+ }
65
+ }
66
+ return [resultSet, hasSubscriptionDependency];
67
+ }
68
+ }
69
+ /**
70
+ * A {@link SyncExpression} that only depends on data from a single row.
71
+ */
72
+ export class RowExpression extends SingleDependencyExpression {
73
+ constructor(expression) {
74
+ super(expression);
75
+ if (this.dependsOnConnection) {
76
+ throw new InvalidExpressionError('Does not depend on a single result set');
77
+ }
78
+ }
79
+ }
80
+ /**
81
+ * A {@link SyncExpression} that only depends on connection data.
82
+ */
83
+ export class RequestExpression extends SingleDependencyExpression {
84
+ constructor(expression) {
85
+ super(expression);
86
+ if (this.resultSet != null) {
87
+ throw new InvalidExpressionError('Does not depend on connection data');
88
+ }
89
+ }
90
+ }
91
+ /**
92
+ * An expression of the form `foo = bar`, where `foo` and `bar` are expressions allowed to depend on different sources.
93
+ */
94
+ export class EqualsClause {
95
+ left;
96
+ right;
97
+ constructor(left, right) {
98
+ this.left = left;
99
+ this.right = right;
100
+ }
101
+ get location() {
102
+ return expandNodeLocations([this.left.expression.location, this.right.expression.location]);
103
+ }
104
+ }
105
+ export class InvalidExpressionError extends Error {
106
+ constructor(message) {
107
+ super(message);
108
+ }
109
+ }
110
+ //# sourceMappingURL=filter.js.map