@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.
- package/dist/BaseSqlDataQuery.d.ts +3 -9
- package/dist/BaseSqlDataQuery.js +11 -21
- package/dist/BaseSqlDataQuery.js.map +1 -1
- package/dist/BucketParameterQuerier.d.ts +42 -9
- package/dist/BucketParameterQuerier.js +30 -7
- package/dist/BucketParameterQuerier.js.map +1 -1
- package/dist/BucketSource.d.ts +94 -25
- package/dist/BucketSource.js +67 -0
- package/dist/BucketSource.js.map +1 -1
- package/dist/ExpressionType.d.ts +4 -2
- package/dist/ExpressionType.js.map +1 -1
- package/dist/HydratedSyncRules.d.ts +46 -0
- package/dist/HydratedSyncRules.js +88 -0
- package/dist/HydratedSyncRules.js.map +1 -0
- package/dist/HydrationState.d.ts +45 -0
- package/dist/HydrationState.js +41 -0
- package/dist/HydrationState.js.map +1 -0
- package/dist/SqlBucketDescriptor.d.ts +31 -28
- package/dist/SqlBucketDescriptor.js +89 -112
- package/dist/SqlBucketDescriptor.js.map +1 -1
- package/dist/SqlDataQuery.d.ts +4 -4
- package/dist/SqlDataQuery.js +5 -6
- package/dist/SqlDataQuery.js.map +1 -1
- package/dist/SqlParameterQuery.d.ts +17 -9
- package/dist/SqlParameterQuery.js +49 -23
- package/dist/SqlParameterQuery.js.map +1 -1
- package/dist/SqlSyncRules.d.ts +11 -53
- package/dist/SqlSyncRules.js +11 -376
- package/dist/SqlSyncRules.js.map +1 -1
- package/dist/StaticSqlParameterQuery.d.ts +13 -3
- package/dist/StaticSqlParameterQuery.js +38 -4
- package/dist/StaticSqlParameterQuery.js.map +1 -1
- package/dist/SyncConfig.d.ts +43 -0
- package/dist/SyncConfig.js +102 -0
- package/dist/SyncConfig.js.map +1 -0
- package/dist/TablePattern.d.ts +22 -4
- package/dist/TablePattern.js +57 -19
- package/dist/TablePattern.js.map +1 -1
- package/dist/TableValuedFunctionSqlParameterQuery.d.ts +14 -4
- package/dist/TableValuedFunctionSqlParameterQuery.js +41 -7
- package/dist/TableValuedFunctionSqlParameterQuery.js.map +1 -1
- package/dist/compatibility.d.ts +7 -0
- package/dist/compatibility.js +34 -0
- package/dist/compatibility.js.map +1 -1
- package/dist/compiler/bucket_resolver.d.ts +70 -0
- package/dist/compiler/bucket_resolver.js +131 -0
- package/dist/compiler/bucket_resolver.js.map +1 -0
- package/dist/compiler/compatibility.d.ts +16 -0
- package/dist/compiler/compatibility.js +12 -0
- package/dist/compiler/compatibility.js.map +1 -0
- package/dist/compiler/compiler.d.ts +110 -0
- package/dist/compiler/compiler.js +130 -0
- package/dist/compiler/compiler.js.map +1 -0
- package/dist/compiler/equality.d.ts +99 -0
- package/dist/compiler/equality.js +284 -0
- package/dist/compiler/equality.js.map +1 -0
- package/dist/compiler/expression.d.ts +77 -0
- package/dist/compiler/expression.js +122 -0
- package/dist/compiler/expression.js.map +1 -0
- package/dist/compiler/filter.d.ts +71 -0
- package/dist/compiler/filter.js +110 -0
- package/dist/compiler/filter.js.map +1 -0
- package/dist/compiler/filter_simplifier.d.ts +26 -0
- package/dist/compiler/filter_simplifier.js +119 -0
- package/dist/compiler/filter_simplifier.js.map +1 -0
- package/dist/compiler/ir_to_sync_plan.d.ts +37 -0
- package/dist/compiler/ir_to_sync_plan.js +163 -0
- package/dist/compiler/ir_to_sync_plan.js.map +1 -0
- package/dist/compiler/parser.d.ts +99 -0
- package/dist/compiler/parser.js +556 -0
- package/dist/compiler/parser.js.map +1 -0
- package/dist/compiler/querier_graph.d.ts +42 -0
- package/dist/compiler/querier_graph.js +365 -0
- package/dist/compiler/querier_graph.js.map +1 -0
- package/dist/compiler/rows.d.ts +113 -0
- package/dist/compiler/rows.js +156 -0
- package/dist/compiler/rows.js.map +1 -0
- package/dist/compiler/scope.d.ts +22 -0
- package/dist/compiler/scope.js +47 -0
- package/dist/compiler/scope.js.map +1 -0
- package/dist/compiler/sqlite.d.ts +77 -0
- package/dist/compiler/sqlite.js +412 -0
- package/dist/compiler/sqlite.js.map +1 -0
- package/dist/compiler/table.d.ts +66 -0
- package/dist/compiler/table.js +67 -0
- package/dist/compiler/table.js.map +1 -0
- package/dist/errors.d.ts +4 -2
- package/dist/errors.js +16 -1
- package/dist/errors.js.map +1 -1
- package/dist/events/SqlEventDescriptor.js +1 -1
- package/dist/events/SqlEventDescriptor.js.map +1 -1
- package/dist/events/SqlEventSourceQuery.d.ts +1 -1
- package/dist/events/SqlEventSourceQuery.js +1 -2
- package/dist/events/SqlEventSourceQuery.js.map +1 -1
- package/dist/from_yaml.d.ts +28 -0
- package/dist/from_yaml.js +411 -0
- package/dist/from_yaml.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/json_schema.js +17 -1
- package/dist/json_schema.js.map +1 -1
- package/dist/request_functions.js.map +1 -1
- package/dist/schema-generators/DartSchemaGenerator.d.ts +3 -3
- package/dist/schema-generators/DartSchemaGenerator.js.map +1 -1
- package/dist/schema-generators/DotNetSchemaGenerator.d.ts +2 -2
- package/dist/schema-generators/DotNetSchemaGenerator.js.map +1 -1
- package/dist/schema-generators/JsLegacySchemaGenerator.d.ts +2 -2
- package/dist/schema-generators/JsLegacySchemaGenerator.js.map +1 -1
- package/dist/schema-generators/KotlinSchemaGenerator.d.ts +2 -2
- package/dist/schema-generators/KotlinSchemaGenerator.js.map +1 -1
- package/dist/schema-generators/RoomSchemaGenerator.d.ts +2 -2
- package/dist/schema-generators/RoomSchemaGenerator.js.map +1 -1
- package/dist/schema-generators/SchemaGenerator.d.ts +8 -3
- package/dist/schema-generators/SchemaGenerator.js +21 -14
- package/dist/schema-generators/SchemaGenerator.js.map +1 -1
- package/dist/schema-generators/SqlSchemaGenerator.d.ts +2 -2
- package/dist/schema-generators/SqlSchemaGenerator.js.map +1 -1
- package/dist/schema-generators/SwiftSchemaGenerator.d.ts +2 -2
- package/dist/schema-generators/SwiftSchemaGenerator.js.map +1 -1
- package/dist/schema-generators/TsSchemaGenerator.d.ts +2 -2
- package/dist/schema-generators/TsSchemaGenerator.js.map +1 -1
- package/dist/sql_functions.d.ts +4 -3
- package/dist/sql_functions.js +1 -1
- package/dist/sql_functions.js.map +1 -1
- package/dist/streams/filter.d.ts +34 -4
- package/dist/streams/filter.js +93 -23
- package/dist/streams/filter.js.map +1 -1
- package/dist/streams/from_sql.js +2 -5
- package/dist/streams/from_sql.js.map +1 -1
- package/dist/streams/parameter.d.ts +7 -6
- package/dist/streams/stream.d.ts +25 -15
- package/dist/streams/stream.js +59 -87
- package/dist/streams/stream.js.map +1 -1
- package/dist/streams/variant.d.ts +14 -21
- package/dist/streams/variant.js +68 -46
- package/dist/streams/variant.js.map +1 -1
- package/dist/sync_plan/engine/javascript.d.ts +6 -0
- package/dist/sync_plan/engine/javascript.js +208 -0
- package/dist/sync_plan/engine/javascript.js.map +1 -0
- package/dist/sync_plan/engine/scalar_expression_engine.d.ts +48 -0
- package/dist/sync_plan/engine/scalar_expression_engine.js +99 -0
- package/dist/sync_plan/engine/scalar_expression_engine.js.map +1 -0
- package/dist/sync_plan/engine/sqlite.d.ts +12 -0
- package/dist/sync_plan/engine/sqlite.js +53 -0
- package/dist/sync_plan/engine/sqlite.js.map +1 -0
- package/dist/sync_plan/evaluator/bucket_data_source.d.ts +24 -0
- package/dist/sync_plan/evaluator/bucket_data_source.js +139 -0
- package/dist/sync_plan/evaluator/bucket_data_source.js.map +1 -0
- package/dist/sync_plan/evaluator/bucket_source.d.ts +19 -0
- package/dist/sync_plan/evaluator/bucket_source.js +145 -0
- package/dist/sync_plan/evaluator/bucket_source.js.map +1 -0
- package/dist/sync_plan/evaluator/index.d.ts +17 -0
- package/dist/sync_plan/evaluator/index.js +32 -0
- package/dist/sync_plan/evaluator/index.js.map +1 -0
- package/dist/sync_plan/evaluator/parameter_evaluator.d.ts +138 -0
- package/dist/sync_plan/evaluator/parameter_evaluator.js +359 -0
- package/dist/sync_plan/evaluator/parameter_evaluator.js.map +1 -0
- package/dist/sync_plan/evaluator/parameter_index_lookup_creator.d.ts +20 -0
- package/dist/sync_plan/evaluator/parameter_index_lookup_creator.js +64 -0
- package/dist/sync_plan/evaluator/parameter_index_lookup_creator.js.map +1 -0
- package/dist/sync_plan/expression.d.ts +109 -0
- package/dist/sync_plan/expression.js +85 -0
- package/dist/sync_plan/expression.js.map +1 -0
- package/dist/sync_plan/expression_to_sql.d.ts +43 -0
- package/dist/sync_plan/expression_to_sql.js +190 -0
- package/dist/sync_plan/expression_to_sql.js.map +1 -0
- package/dist/sync_plan/expression_visitor.d.ts +57 -0
- package/dist/sync_plan/expression_visitor.js +181 -0
- package/dist/sync_plan/expression_visitor.js.map +1 -0
- package/dist/sync_plan/plan.d.ts +196 -0
- package/dist/sync_plan/plan.js +2 -0
- package/dist/sync_plan/plan.js.map +1 -0
- package/dist/sync_plan/schema_inference.d.ts +16 -0
- package/dist/sync_plan/schema_inference.js +123 -0
- package/dist/sync_plan/schema_inference.js.map +1 -0
- package/dist/sync_plan/serialize.d.ts +82 -0
- package/dist/sync_plan/serialize.js +214 -0
- package/dist/sync_plan/serialize.js.map +1 -0
- package/dist/types/custom_sqlite_value.d.ts +1 -1
- package/dist/types.d.ts +72 -29
- package/dist/types.js +30 -5
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +10 -3
- package/dist/utils.js +26 -3
- package/dist/utils.js.map +1 -1
- package/package.json +4 -3
- package/schema/sync_rules.json +19 -3
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { EvaluateTableValuedFunction, IntersectionParameterValue, LookupResultParameterValue, ParameterLookup, RequestParameterValue, ResolveBucket, StreamResolver } from './bucket_resolver.js';
|
|
2
|
+
import { equalsIgnoringResultSet } from './compatibility.js';
|
|
3
|
+
import { EqualsClause, RequestExpression, RowExpression, SingleDependencyExpression } from './filter.js';
|
|
4
|
+
import { PartitionKey, PointLookup, RowEvaluator } from './rows.js';
|
|
5
|
+
import { PhysicalSourceResultSet } from './table.js';
|
|
6
|
+
import { HashMap, HashSet, StableHasher } from './equality.js';
|
|
7
|
+
/**
|
|
8
|
+
* Builds stream resolvers for a single stream, potentially consisting of multiple queries.
|
|
9
|
+
*/
|
|
10
|
+
export class QuerierGraphBuilder {
|
|
11
|
+
compiler;
|
|
12
|
+
options;
|
|
13
|
+
resolvers = [];
|
|
14
|
+
counter;
|
|
15
|
+
constructor(compiler, options) {
|
|
16
|
+
this.compiler = compiler;
|
|
17
|
+
this.options = options;
|
|
18
|
+
this.counter = new UniqueCounter();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Adds a given query to the stream compiled by this builder.
|
|
22
|
+
*/
|
|
23
|
+
process(query, errors) {
|
|
24
|
+
for (const variant of query.where.terms) {
|
|
25
|
+
const resolved = new PendingQuerierPath(this, query, errors, variant).resolvePrimaryInput();
|
|
26
|
+
this.resolvers.push(resolved);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Merges created stream resolvers and adds them to the compiler.
|
|
31
|
+
*/
|
|
32
|
+
finish() {
|
|
33
|
+
this.compiler.output.resolvers.push(...this.mergeBuckets());
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Merges bucket definitions from multiple queries if they're compatible.
|
|
37
|
+
*
|
|
38
|
+
* As an example, consider a stream defined with two queries:
|
|
39
|
+
*
|
|
40
|
+
* - `SELECT * FROM settings WHERE user_id = auth.user_id()`
|
|
41
|
+
* - `SELECT * FROM notes WHERE user_id = auth.user_id()`
|
|
42
|
+
*
|
|
43
|
+
* While the two queries select from different source rows (meaning that their {@link RowEvaluator}s are distinct),
|
|
44
|
+
* they also don't really need independent buckets.
|
|
45
|
+
*
|
|
46
|
+
* This method merges two stream resolvers if they have {@link ResolveBucket} steps with the same instantiation (as
|
|
47
|
+
* in, the same stream subscription + connection is guaranteed to evaluate to the same parameters).
|
|
48
|
+
*/
|
|
49
|
+
mergeBuckets() {
|
|
50
|
+
const resolvers = new HashSet({
|
|
51
|
+
equals: (a, b) => a.hasIdenticalInstantiation(b),
|
|
52
|
+
hash: (hasher, value) => value.buildInstantiationHash(hasher)
|
|
53
|
+
});
|
|
54
|
+
for (const sourceResolver of this.resolvers) {
|
|
55
|
+
const [existing, didInsert] = resolvers.getOrInsert(sourceResolver);
|
|
56
|
+
if (!didInsert) {
|
|
57
|
+
for (const newEvaluator of sourceResolver.resolvedBucket.evaluators) {
|
|
58
|
+
existing.resolvedBucket.evaluators.add(newEvaluator);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return [...resolvers];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Splits a logical conjunction ({@link And}) to create source row processors and parameter lookups.
|
|
67
|
+
*
|
|
68
|
+
* This works by first processing subterms related to the source set selected from. If the subterm is a row expression,
|
|
69
|
+
* we add it as a filter to the row processor or parameter lookup. If it is a match expression, we create a partition
|
|
70
|
+
* key and obtain the value by recursively applying this algorithm to resolve the other side.
|
|
71
|
+
*
|
|
72
|
+
* To visualize this algorithm, consider the following example query:
|
|
73
|
+
*
|
|
74
|
+
* ```SQL
|
|
75
|
+
* SELECT * FROM comments c, issues i, users u
|
|
76
|
+
* WHERE u.user_id = auth.user_id() AND c.issue_id = i.id AND u.id = i.owner_id AND u.is_admin
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* First, {@link resolvePrimaryInput} is called, which calls {@link resolveResultSet} on `comments c`. While resolving a
|
|
80
|
+
* result set, we extract conditions mentioning that result set. In this case, the only such expression is
|
|
81
|
+
* `c.issue_id = i.id`. Because this is an {@link EqualsClause}, we know we need to introduce a parameter (in this case,
|
|
82
|
+
* `c.issue_id` because that's the half depending on the current result set). We then look at the other half and
|
|
83
|
+
* recursively resolve `issues i` (via {@link resolvePointLookup}). When we're done resolving that, we add `i.id` as to
|
|
84
|
+
* {@link PendingExpandingLookup.usedOutputs}.
|
|
85
|
+
*
|
|
86
|
+
* To resolve `issues i`, we extract the only remaining expression mentioning it, `u.id = i.owner_id`. We once again
|
|
87
|
+
* recursve to resolve `users u` and will add `u.id` as a used output.
|
|
88
|
+
*
|
|
89
|
+
* Finally, we find `u.user_id = auth.user_id()` and `u.is_admin`. The first expression creates a parameter, but doesn't
|
|
90
|
+
* need to resolve any further result sets since the input depends on connection data. The second expression only
|
|
91
|
+
* depends on the row itself, so we add it as a static condition to only create parameter lookups for rows matching that
|
|
92
|
+
* condition.
|
|
93
|
+
*
|
|
94
|
+
* This algorithm gives us the bucket creator as well as parameter lookups with their partition keys and values, which
|
|
95
|
+
* is the sync plan.
|
|
96
|
+
*/
|
|
97
|
+
class PendingQuerierPath {
|
|
98
|
+
builder;
|
|
99
|
+
query;
|
|
100
|
+
errors;
|
|
101
|
+
// Terms in the And that have not yet been handled.
|
|
102
|
+
pendingFactors = [];
|
|
103
|
+
pendingLookups = new Map();
|
|
104
|
+
/**
|
|
105
|
+
* A stack of result sets currently being analyzed.
|
|
106
|
+
*
|
|
107
|
+
* This is used to guard against circular references, although those should never happen.
|
|
108
|
+
*/
|
|
109
|
+
resolveStack = [];
|
|
110
|
+
pendingStage = { lookups: [] };
|
|
111
|
+
constructor(builder, query, errors, condition) {
|
|
112
|
+
this.builder = builder;
|
|
113
|
+
this.query = query;
|
|
114
|
+
this.errors = errors;
|
|
115
|
+
this.pendingFactors.push(...condition.terms);
|
|
116
|
+
}
|
|
117
|
+
resolvePrimaryInput() {
|
|
118
|
+
const state = this.resolveResultSet(this.query.sourceTable);
|
|
119
|
+
const [partitions, partitionValues] = state.resolvePartitions();
|
|
120
|
+
const evaluator = this.builder.compiler.output.canonicalizeEvaluator(new RowEvaluator({
|
|
121
|
+
columns: this.query.resultColumns,
|
|
122
|
+
syntacticSource: this.query.sourceTable,
|
|
123
|
+
filters: state.filters,
|
|
124
|
+
partitionBy: partitions
|
|
125
|
+
}));
|
|
126
|
+
this.processExistsOperators();
|
|
127
|
+
// Resolving a result set removes its conditions from pendingFactors, so remaining conditions must be related to the
|
|
128
|
+
// request (e.g. where `auth.parameter('is_admin')`).
|
|
129
|
+
const requestConditions = [];
|
|
130
|
+
for (const remaining of this.pendingFactors) {
|
|
131
|
+
if (remaining instanceof SingleDependencyExpression) {
|
|
132
|
+
if (remaining.resultSet != null) {
|
|
133
|
+
this.errors.report('This filter is unrelated to the request or the table being synced, and not supported.', remaining.expression.location);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
requestConditions.push(new RequestExpression(remaining));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.errors.report('Unable to associate this filter with added tables', remaining.location);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return new StreamResolver(this.builder.options, requestConditions, this.materializeLookupStages(), new ResolveBucket(evaluator, partitionValues), this.builder.counter.use(this.builder.options.name));
|
|
144
|
+
}
|
|
145
|
+
pushStage() {
|
|
146
|
+
const childStage = this.pendingStage;
|
|
147
|
+
this.pendingStage = childStage.parent ??= { lookups: [] };
|
|
148
|
+
return childStage;
|
|
149
|
+
}
|
|
150
|
+
popStage(stage) {
|
|
151
|
+
this.pendingStage = stage;
|
|
152
|
+
}
|
|
153
|
+
resolvePointLookup(resultSet) {
|
|
154
|
+
const resolved = this.resolveResultSet(resultSet);
|
|
155
|
+
const [partitionKeys, partitionInputs] = resolved.resolvePartitions();
|
|
156
|
+
return new PendingExpandingLookup({
|
|
157
|
+
type: 'point',
|
|
158
|
+
pattern: resultSet,
|
|
159
|
+
filters: resolved.filters,
|
|
160
|
+
partitionKeys: partitionKeys,
|
|
161
|
+
inputs: partitionInputs
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
resolveTableValuedLookup(resultSet) {
|
|
165
|
+
const resolved = this.resolveResultSet(resultSet);
|
|
166
|
+
if (!resolved.partition.isEmpty) {
|
|
167
|
+
// At the moment, inputs to a table-valued functions must be static or only depend on the request. We may lift
|
|
168
|
+
// this restriction in the future.
|
|
169
|
+
this.errors.report('Table-valued result sets cannot be partitioned', resultSet.source.origin);
|
|
170
|
+
}
|
|
171
|
+
return new PendingExpandingLookup({ type: 'table_valued', resultSet, filters: resolved.filters });
|
|
172
|
+
}
|
|
173
|
+
resolveExpandingLookup(resultSet) {
|
|
174
|
+
const existing = this.pendingLookups.get(resultSet);
|
|
175
|
+
if (existing != null) {
|
|
176
|
+
return existing;
|
|
177
|
+
}
|
|
178
|
+
// Something depends on this lookup when resolveExpandingLookup is called, so we have to push this into a new stage
|
|
179
|
+
// to ensure we have results before the current stage.
|
|
180
|
+
const childStage = this.pushStage();
|
|
181
|
+
const resolved = resultSet instanceof PhysicalSourceResultSet
|
|
182
|
+
? this.resolvePointLookup(resultSet)
|
|
183
|
+
: this.resolveTableValuedLookup(resultSet);
|
|
184
|
+
this.pendingLookups.set(resultSet, resolved);
|
|
185
|
+
this.pendingStage.lookups.push(resolved);
|
|
186
|
+
this.popStage(childStage);
|
|
187
|
+
return resolved;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Extracts filters, partition keys and partition instantiations for a given source result set.
|
|
191
|
+
*/
|
|
192
|
+
resolveResultSet(source) {
|
|
193
|
+
if (this.resolveStack.indexOf(source) != -1) {
|
|
194
|
+
throw new Error('internal error: circular reference when resolving result set');
|
|
195
|
+
}
|
|
196
|
+
this.resolveStack.push(source);
|
|
197
|
+
const state = new ResolvedResultSet();
|
|
198
|
+
for (const expression of [...this.pendingFactors]) {
|
|
199
|
+
if (expression instanceof SingleDependencyExpression) {
|
|
200
|
+
if (expression.resultSet === source) {
|
|
201
|
+
// This expression only depends on the table, so we add it as a filter for the row or parameter evaluator.
|
|
202
|
+
state.filters.push(new RowExpression(expression));
|
|
203
|
+
this.removePendingExpression(expression);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
// Must be a match term.
|
|
208
|
+
const partitionBy = (thisRow, otherRow) => {
|
|
209
|
+
this.removePendingExpression(expression);
|
|
210
|
+
const key = new PartitionKey(new RowExpression(thisRow));
|
|
211
|
+
const values = state.partition.putIfAbsent(key, () => []);
|
|
212
|
+
if (otherRow.resultSet != null) {
|
|
213
|
+
const lookup = this.resolveExpandingLookup(otherRow.resultSet);
|
|
214
|
+
const index = lookup.addOutput(new RowExpression(otherRow));
|
|
215
|
+
const value = new LookupResultParameterValue(index);
|
|
216
|
+
lookup.dependents.push(value);
|
|
217
|
+
values.push(value);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
// Other row doesn't depend on a source row, so we can read the value out of the connection.
|
|
221
|
+
values.push(new RequestParameterValue(otherRow));
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
if (expression.left.resultSet === source) {
|
|
225
|
+
partitionBy(expression.left, expression.right);
|
|
226
|
+
}
|
|
227
|
+
else if (expression.right.resultSet === source) {
|
|
228
|
+
partitionBy(expression.right, expression.left);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
// Unrelated match clause.
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const popped = this.resolveStack.pop();
|
|
237
|
+
if (popped !== source) {
|
|
238
|
+
throw new Error('internal error: resolve stack broken');
|
|
239
|
+
}
|
|
240
|
+
return state;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Handles `EXIST`-like subquery operators.
|
|
244
|
+
*
|
|
245
|
+
* Consider a filter like `WHERE auth.user_id() IN (SELECT id FROM users WHERE is_admin)`. This gets represented as an
|
|
246
|
+
* {@link EqualsClause}, but it doesn't introduce any bucket parameters.
|
|
247
|
+
*
|
|
248
|
+
* We handle these in a special way: The `auth.user_id()` equality is pushed into the subquery, effectively resulting
|
|
249
|
+
* in `WHERE EXISTS (SELECT id FROM users WHERE is_admin AND id = auth.user_id())`. This is implemented by pushing a
|
|
250
|
+
* parameter lookup that is never used, but still evaluated to skip connections where it doesn't match.
|
|
251
|
+
*/
|
|
252
|
+
processExistsOperators() {
|
|
253
|
+
for (const expression of [...this.pendingFactors]) {
|
|
254
|
+
if (expression instanceof EqualsClause) {
|
|
255
|
+
const process = (connection, other) => {
|
|
256
|
+
if (other.resultSet != null) {
|
|
257
|
+
// We just need to add the lookup to implement EXISTS semantics, it will never be used anywhere.
|
|
258
|
+
this.resolveExpandingLookup(other.resultSet);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
if (expression.left.dependsOnConnection) {
|
|
262
|
+
process(expression.left, expression.right);
|
|
263
|
+
}
|
|
264
|
+
else if (expression.right.dependsOnConnection) {
|
|
265
|
+
process(expression.right, expression.left);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
removePendingExpression(removed) {
|
|
271
|
+
const index = this.pendingFactors.indexOf(removed);
|
|
272
|
+
this.pendingFactors.splice(index, 1);
|
|
273
|
+
}
|
|
274
|
+
materializeLookupStages() {
|
|
275
|
+
const targets = [];
|
|
276
|
+
this.materializeLookupStage(this.pendingStage, targets);
|
|
277
|
+
return targets;
|
|
278
|
+
}
|
|
279
|
+
materializeLookupStage(stage, target) {
|
|
280
|
+
if (stage.parent != null) {
|
|
281
|
+
this.materializeLookupStage(stage.parent, target);
|
|
282
|
+
}
|
|
283
|
+
if (stage.lookups.length != 0) {
|
|
284
|
+
const lookups = [];
|
|
285
|
+
target.push(lookups);
|
|
286
|
+
for (const lookup of stage.lookups) {
|
|
287
|
+
const data = lookup.data;
|
|
288
|
+
let lookupWithInputs;
|
|
289
|
+
if (data.type == 'point') {
|
|
290
|
+
const canonicalized = this.builder.compiler.output.canonicalizePointLookup(new PointLookup({
|
|
291
|
+
syntacticSource: data.pattern,
|
|
292
|
+
filters: data.filters,
|
|
293
|
+
partitionBy: data.partitionKeys,
|
|
294
|
+
result: lookup.usedOutputs
|
|
295
|
+
}));
|
|
296
|
+
lookupWithInputs = new ParameterLookup(canonicalized, data.inputs);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
lookupWithInputs = new EvaluateTableValuedFunction(data.resultSet, lookup.usedOutputs, data.filters);
|
|
300
|
+
}
|
|
301
|
+
lookups.push(lookupWithInputs);
|
|
302
|
+
for (const usage of lookup.dependents) {
|
|
303
|
+
usage.lookup = lookupWithInputs;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
class ResolvedResultSet {
|
|
310
|
+
filters = [];
|
|
311
|
+
partition = new HashMap(equalsIgnoringResultSet);
|
|
312
|
+
resolvePartitions() {
|
|
313
|
+
const entries = [];
|
|
314
|
+
for (const [key, values] of this.partition.entries) {
|
|
315
|
+
if (values.length == 1) {
|
|
316
|
+
entries.push([key, values[0]]);
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
entries.push([key, new IntersectionParameterValue(values)]);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// The order of partition keys is arbitrary (and typically depends on their order in syntax). Semantically though,
|
|
323
|
+
// partition keys should be unordered: Instantiating a bucket is a `Map<Parameter, Value>` that just happens to be
|
|
324
|
+
// encoded as `Value[]` since parameters are known from context.
|
|
325
|
+
// To make it easier to merge buckets, we sort parameters by some stable hash.
|
|
326
|
+
entries.sort((a, b) => StableHasher.hashWith(equalsIgnoringResultSet, a[0]) - StableHasher.hashWith(equalsIgnoringResultSet, b[0]));
|
|
327
|
+
const keys = [];
|
|
328
|
+
const values = [];
|
|
329
|
+
for (const [key, value] of entries) {
|
|
330
|
+
keys.push(key);
|
|
331
|
+
values.push(value);
|
|
332
|
+
}
|
|
333
|
+
return [keys, values];
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
class PendingExpandingLookup {
|
|
337
|
+
data;
|
|
338
|
+
usedOutputs = [];
|
|
339
|
+
dependents = [];
|
|
340
|
+
constructor(data) {
|
|
341
|
+
this.data = data;
|
|
342
|
+
}
|
|
343
|
+
addOutput(param) {
|
|
344
|
+
for (let i = 0; i < this.usedOutputs.length; i++) {
|
|
345
|
+
const existing = this.usedOutputs[i];
|
|
346
|
+
if (existing.equalsAssumingSameResultSet(param)) {
|
|
347
|
+
return i;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
const index = this.usedOutputs.length;
|
|
351
|
+
this.usedOutputs.push(param);
|
|
352
|
+
return index;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
class UniqueCounter {
|
|
356
|
+
current;
|
|
357
|
+
constructor() {
|
|
358
|
+
this.current = 0;
|
|
359
|
+
}
|
|
360
|
+
use(prefix) {
|
|
361
|
+
const value = this.current++;
|
|
362
|
+
return `${prefix}|${value}`;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
//# sourceMappingURL=querier_graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"querier_graph.js","sourceRoot":"","sources":["../../src/compiler/querier_graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { StableHasher } from './equality.js';
|
|
2
|
+
import { EqualsIgnoringResultSet } from './compatibility.js';
|
|
3
|
+
import { RowExpression } from './filter.js';
|
|
4
|
+
import { PhysicalSourceResultSet } from './table.js';
|
|
5
|
+
import { ImplicitSchemaTablePattern } from '../TablePattern.js';
|
|
6
|
+
/**
|
|
7
|
+
* A key describing how buckets or parameter lookups are parameterized.
|
|
8
|
+
*
|
|
9
|
+
* When constructing buckets, a value needs to be passed for each such key.
|
|
10
|
+
* WHen invoking parameter lookups, values need to be passed as inputs.
|
|
11
|
+
*/
|
|
12
|
+
export declare class PartitionKey implements EqualsIgnoringResultSet {
|
|
13
|
+
readonly expression: RowExpression;
|
|
14
|
+
constructor(expression: RowExpression);
|
|
15
|
+
equalsAssumingSameResultSet(other: EqualsIgnoringResultSet): boolean;
|
|
16
|
+
assumingSameResultSetEqualityHashCode(hasher: StableHasher): void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Something that processes source rows during replication.
|
|
20
|
+
*
|
|
21
|
+
* This includes {@link RowEvaluator}s, which assigns rows into buckets, and {@link PointLookup}, which creates
|
|
22
|
+
* parameter lookups used to resolve bucket ids when a user connects.
|
|
23
|
+
*/
|
|
24
|
+
export type SourceRowProcessor = RowEvaluator | PointLookup;
|
|
25
|
+
interface SourceProcessorOptions {
|
|
26
|
+
readonly syntacticSource: PhysicalSourceResultSet;
|
|
27
|
+
readonly filters: RowExpression[];
|
|
28
|
+
readonly partitionBy: PartitionKey[];
|
|
29
|
+
}
|
|
30
|
+
declare abstract class BaseSourceRowProcessor {
|
|
31
|
+
/**
|
|
32
|
+
* The table names being matched, along with an AST reference describing its syntactic source.
|
|
33
|
+
*/
|
|
34
|
+
readonly syntacticSource: PhysicalSourceResultSet;
|
|
35
|
+
/**
|
|
36
|
+
* Filters which all depend on {@link syntacticSource} exclusively.
|
|
37
|
+
*
|
|
38
|
+
* This processor is only active on rows matching these filters.
|
|
39
|
+
*/
|
|
40
|
+
readonly filters: RowExpression[];
|
|
41
|
+
readonly partitionBy: PartitionKey[];
|
|
42
|
+
constructor(options: SourceProcessorOptions);
|
|
43
|
+
/**
|
|
44
|
+
* A hash code for the equivalence relation formed by {@link behavesIdenticalTo}.
|
|
45
|
+
*/
|
|
46
|
+
abstract buildBehaviorHashCode(hasher: StableHasher): void;
|
|
47
|
+
get behaviorHashCode(): number;
|
|
48
|
+
/**
|
|
49
|
+
* Whether two source row processors behave identically.
|
|
50
|
+
*
|
|
51
|
+
* If this is the case, they can be re-used across different stream definitions or even different sync rule instances
|
|
52
|
+
* (for incremental reprocessing).
|
|
53
|
+
*/
|
|
54
|
+
abstract behavesIdenticalTo(other: this): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* The table pattern matched by this bucket or parameter lookup creator.
|
|
57
|
+
*/
|
|
58
|
+
get tablePattern(): ImplicitSchemaTablePattern;
|
|
59
|
+
protected addBaseHashCode(hasher: StableHasher): void;
|
|
60
|
+
protected baseMatchesOther(other: BaseSourceRowProcessor): boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A row evaluator, evaluating rows to sync from a row in the source database.
|
|
64
|
+
*
|
|
65
|
+
* During replication, instances of these are implemented as {@link BucketDataSource}.
|
|
66
|
+
*/
|
|
67
|
+
export declare class RowEvaluator extends BaseSourceRowProcessor {
|
|
68
|
+
/**
|
|
69
|
+
* Expressions and names for columns to sync.
|
|
70
|
+
*/
|
|
71
|
+
readonly columns: ColumnSource[];
|
|
72
|
+
constructor(options: SourceProcessorOptions & {
|
|
73
|
+
columns: ColumnSource[];
|
|
74
|
+
});
|
|
75
|
+
get outputName(): string | undefined;
|
|
76
|
+
buildBehaviorHashCode(hasher: StableHasher): void;
|
|
77
|
+
behavesIdenticalTo(other: RowEvaluator): boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A point lookup, creating a materialized index.
|
|
81
|
+
*
|
|
82
|
+
* These are used to implement subqueries. E.g for `SELECT * FROM users WHERE org IN (SELECT id FROM orgs WHERE name =
|
|
83
|
+
* auth.param('org'))`, we would create a point lookup on `orgs` with a partition key of `name` and a result including
|
|
84
|
+
* `id`.
|
|
85
|
+
*
|
|
86
|
+
* During replication, instances of these are implemented as {@link ParameterIndexLookupCreator}s.
|
|
87
|
+
*/
|
|
88
|
+
export declare class PointLookup extends BaseSourceRowProcessor {
|
|
89
|
+
/**
|
|
90
|
+
* Outputs of the point lookup, which can be used when querying for buckets.
|
|
91
|
+
*/
|
|
92
|
+
readonly result: RowExpression[];
|
|
93
|
+
constructor(options: SourceProcessorOptions & {
|
|
94
|
+
result: RowExpression[];
|
|
95
|
+
});
|
|
96
|
+
buildBehaviorHashCode(hasher: StableHasher): void;
|
|
97
|
+
behavesIdenticalTo(other: PointLookup): boolean;
|
|
98
|
+
}
|
|
99
|
+
export type ColumnSource = StarColumnSource | ExpressionColumnSource;
|
|
100
|
+
export declare class StarColumnSource implements EqualsIgnoringResultSet {
|
|
101
|
+
private constructor();
|
|
102
|
+
equalsAssumingSameResultSet(other: EqualsIgnoringResultSet): boolean;
|
|
103
|
+
assumingSameResultSetEqualityHashCode(): void;
|
|
104
|
+
static readonly instance: StarColumnSource;
|
|
105
|
+
}
|
|
106
|
+
export declare class ExpressionColumnSource implements EqualsIgnoringResultSet {
|
|
107
|
+
readonly expression: RowExpression;
|
|
108
|
+
readonly alias: string;
|
|
109
|
+
constructor(expression: RowExpression, alias: string);
|
|
110
|
+
equalsAssumingSameResultSet(other: EqualsIgnoringResultSet): boolean;
|
|
111
|
+
assumingSameResultSetEqualityHashCode(hasher: StableHasher): void;
|
|
112
|
+
}
|
|
113
|
+
export {};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { StableHasher } from './equality.js';
|
|
2
|
+
import { equalsIgnoringResultSetList, equalsIgnoringResultSetUnordered } from './compatibility.js';
|
|
3
|
+
/**
|
|
4
|
+
* A key describing how buckets or parameter lookups are parameterized.
|
|
5
|
+
*
|
|
6
|
+
* When constructing buckets, a value needs to be passed for each such key.
|
|
7
|
+
* WHen invoking parameter lookups, values need to be passed as inputs.
|
|
8
|
+
*/
|
|
9
|
+
export class PartitionKey {
|
|
10
|
+
expression;
|
|
11
|
+
constructor(expression) {
|
|
12
|
+
this.expression = expression;
|
|
13
|
+
}
|
|
14
|
+
equalsAssumingSameResultSet(other) {
|
|
15
|
+
return (other instanceof PartitionKey &&
|
|
16
|
+
other.expression.expression.equalsAssumingSameResultSet(this.expression.expression));
|
|
17
|
+
}
|
|
18
|
+
assumingSameResultSetEqualityHashCode(hasher) {
|
|
19
|
+
this.expression.expression.assumingSameResultSetEqualityHashCode(hasher);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
class BaseSourceRowProcessor {
|
|
23
|
+
/**
|
|
24
|
+
* The table names being matched, along with an AST reference describing its syntactic source.
|
|
25
|
+
*/
|
|
26
|
+
syntacticSource;
|
|
27
|
+
/**
|
|
28
|
+
* Filters which all depend on {@link syntacticSource} exclusively.
|
|
29
|
+
*
|
|
30
|
+
* This processor is only active on rows matching these filters.
|
|
31
|
+
*/
|
|
32
|
+
filters;
|
|
33
|
+
partitionBy;
|
|
34
|
+
constructor(options) {
|
|
35
|
+
this.syntacticSource = options.syntacticSource;
|
|
36
|
+
this.filters = options.filters;
|
|
37
|
+
this.partitionBy = options.partitionBy;
|
|
38
|
+
}
|
|
39
|
+
get behaviorHashCode() {
|
|
40
|
+
const hasher = new StableHasher();
|
|
41
|
+
this.buildBehaviorHashCode(hasher);
|
|
42
|
+
return hasher.buildHashCode();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The table pattern matched by this bucket or parameter lookup creator.
|
|
46
|
+
*/
|
|
47
|
+
get tablePattern() {
|
|
48
|
+
return this.syntacticSource.tablePattern;
|
|
49
|
+
}
|
|
50
|
+
addBaseHashCode(hasher) {
|
|
51
|
+
hasher.add(this.tablePattern);
|
|
52
|
+
equalsIgnoringResultSetUnordered.hash(hasher, this.filters.map((f) => f.expression));
|
|
53
|
+
equalsIgnoringResultSetList.hash(hasher, this.partitionBy);
|
|
54
|
+
}
|
|
55
|
+
baseMatchesOther(other) {
|
|
56
|
+
if (!other.tablePattern.equals(this.tablePattern)) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (!equalsIgnoringResultSetList.equals(other.partitionBy, this.partitionBy)) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
if (!equalsIgnoringResultSetUnordered.equals(other.filters, this.filters)) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* A row evaluator, evaluating rows to sync from a row in the source database.
|
|
70
|
+
*
|
|
71
|
+
* During replication, instances of these are implemented as {@link BucketDataSource}.
|
|
72
|
+
*/
|
|
73
|
+
export class RowEvaluator extends BaseSourceRowProcessor {
|
|
74
|
+
/**
|
|
75
|
+
* Expressions and names for columns to sync.
|
|
76
|
+
*/
|
|
77
|
+
columns;
|
|
78
|
+
constructor(options) {
|
|
79
|
+
super(options);
|
|
80
|
+
this.columns = options.columns;
|
|
81
|
+
}
|
|
82
|
+
get outputName() {
|
|
83
|
+
const alias = this.syntacticSource.source.explicitName;
|
|
84
|
+
if (this.syntacticSource.tablePattern.isWildcard) {
|
|
85
|
+
if (alias == null) {
|
|
86
|
+
// Unaliased wildcard, use source table name.
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return alias ?? this.syntacticSource.tablePattern.tablePattern;
|
|
91
|
+
}
|
|
92
|
+
buildBehaviorHashCode(hasher) {
|
|
93
|
+
this.addBaseHashCode(hasher);
|
|
94
|
+
equalsIgnoringResultSetList.hash(hasher, this.columns);
|
|
95
|
+
if (this.outputName) {
|
|
96
|
+
hasher.addString(this.outputName);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
behavesIdenticalTo(other) {
|
|
100
|
+
return (this.baseMatchesOther(other) &&
|
|
101
|
+
equalsIgnoringResultSetList.equals(other.columns, this.columns) &&
|
|
102
|
+
other.outputName == this.outputName);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* A point lookup, creating a materialized index.
|
|
107
|
+
*
|
|
108
|
+
* These are used to implement subqueries. E.g for `SELECT * FROM users WHERE org IN (SELECT id FROM orgs WHERE name =
|
|
109
|
+
* auth.param('org'))`, we would create a point lookup on `orgs` with a partition key of `name` and a result including
|
|
110
|
+
* `id`.
|
|
111
|
+
*
|
|
112
|
+
* During replication, instances of these are implemented as {@link ParameterIndexLookupCreator}s.
|
|
113
|
+
*/
|
|
114
|
+
export class PointLookup extends BaseSourceRowProcessor {
|
|
115
|
+
/**
|
|
116
|
+
* Outputs of the point lookup, which can be used when querying for buckets.
|
|
117
|
+
*/
|
|
118
|
+
result;
|
|
119
|
+
constructor(options) {
|
|
120
|
+
super(options);
|
|
121
|
+
this.result = options.result;
|
|
122
|
+
}
|
|
123
|
+
buildBehaviorHashCode(hasher) {
|
|
124
|
+
this.addBaseHashCode(hasher);
|
|
125
|
+
equalsIgnoringResultSetList.hash(hasher, this.result);
|
|
126
|
+
}
|
|
127
|
+
behavesIdenticalTo(other) {
|
|
128
|
+
return this.baseMatchesOther(other) && equalsIgnoringResultSetList.equals(other.result, this.result);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export class StarColumnSource {
|
|
132
|
+
constructor() { }
|
|
133
|
+
equalsAssumingSameResultSet(other) {
|
|
134
|
+
return other instanceof StarColumnSource;
|
|
135
|
+
}
|
|
136
|
+
assumingSameResultSetEqualityHashCode() { }
|
|
137
|
+
static instance = new StarColumnSource();
|
|
138
|
+
}
|
|
139
|
+
export class ExpressionColumnSource {
|
|
140
|
+
expression;
|
|
141
|
+
alias;
|
|
142
|
+
constructor(expression, alias) {
|
|
143
|
+
this.expression = expression;
|
|
144
|
+
this.alias = alias;
|
|
145
|
+
}
|
|
146
|
+
equalsAssumingSameResultSet(other) {
|
|
147
|
+
return (other instanceof ExpressionColumnSource &&
|
|
148
|
+
other.alias == this.alias &&
|
|
149
|
+
other.expression.equalsAssumingSameResultSet(this.expression));
|
|
150
|
+
}
|
|
151
|
+
assumingSameResultSetEqualityHashCode(hasher) {
|
|
152
|
+
this.expression.assumingSameResultSetEqualityHashCode(hasher);
|
|
153
|
+
hasher.addString(this.alias);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rows.js","sourceRoot":"","sources":["../../src/compiler/rows.ts"],"names":[],"mappings":"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"}
|