@@ -146,7 +146,10 @@ export class StreamVariant {
146146 const staticBuckets : ResolvedBucket [ ] = [ ] ;
147147 if ( dynamicParameters . length == 0 && dynamicRequestFilters . length == 0 ) {
148148 // When we have no dynamic parameters, the partial evaluation is a full instantiation.
149- staticBuckets . push ( this . resolveBucket ( stream , instantiation as SqliteJsonValue [ ] , reason ) ) ;
149+ const instantiations = this . cartesianProductOfParameterInstantiations ( instantiation as SqliteJsonValue [ ] [ ] ) ;
150+ for ( const instantiation of instantiations ) {
151+ staticBuckets . push ( this . resolveBucket ( stream , instantiation , reason ) ) ;
152+ }
150153 }
151154
152155 const variant = this ;
@@ -173,7 +176,13 @@ export class StreamVariant {
173176
174177 const perParameterInstantiation : ( SqliteJsonValue | BucketParameter ) [ ] [ ] = [ ] ;
175178 for ( const parameter of instantiation ) {
176- perParameterInstantiation . push ( [ parameter ] ) ;
179+ if ( Array . isArray ( parameter ) ) {
180+ // Statically-resolved values
181+ perParameterInstantiation . push ( parameter ) ;
182+ } else {
183+ // to be instantiated with dynamic lookup
184+ perParameterInstantiation . push ( [ parameter as BucketParameter ] ) ;
185+ }
177186 }
178187
179188 for ( const lookup of dynamicParameters ) {
@@ -189,13 +198,13 @@ export class StreamVariant {
189198 } ;
190199 }
191200
192- findStaticInstantiation ( params : RequestParameters ) : SqliteJsonValue [ ] | null {
201+ findStaticInstantiations ( params : RequestParameters ) : SqliteJsonValue [ ] [ ] {
193202 if ( this . subqueries . length ) {
194- return null ;
203+ return [ ] ;
195204 }
196205
197206 // This will be an array of values (i.e. a total evaluation) because there are no dynamic parameters.
198- return this . partiallyEvaluateParameters ( params ) as SqliteJsonValue [ ] ;
207+ return this . partiallyEvaluateParameters ( params ) as SqliteJsonValue [ ] [ ] ;
199208 }
200209
201210 /**
@@ -239,23 +248,25 @@ export class StreamVariant {
239248 * Dynamic parameters that depend on subquery results are not replaced.
240249 * This returns null if there's a {@link StaticRequestFilter} that doesn't match the request.
241250 */
242- private partiallyEvaluateParameters ( params : RequestParameters ) : ( SqliteJsonValue | BucketParameter ) [ ] | null {
251+ private partiallyEvaluateParameters ( params : RequestParameters ) : ( SqliteJsonValue [ ] | BucketParameter ) [ ] | null {
243252 for ( const filter of this . requestFilters ) {
244253 if ( filter . type == 'static' && ! filter . matches ( params ) ) {
245254 return null ;
246255 }
247256 }
248257
249- const instantiation : ( SqliteJsonValue | BucketParameter ) [ ] = [ ] ;
258+ const instantiation : ( SqliteJsonValue [ ] | BucketParameter ) [ ] = [ ] ;
250259 for ( const parameter of this . parameters ) {
251260 const lookup = parameter . lookup ;
252261 if ( lookup . type == 'static' ) {
253- const value = lookup . fromRequest ( params ) ;
254- if ( isJsonValue ( value ) ) {
255- instantiation . push ( value ) ;
256- } else {
262+ const values = lookup . fromRequest ( params ) ?. filter ( isJsonValue ) ;
263+ if ( values . length == 0 ) {
264+ // Parameter not instantiable for this request. Since parameters in a single variant form a conjunction, that
265+ // means the whole request won't find anything here.
257266 return null ;
258267 }
268+
269+ instantiation . push ( values ) ;
259270 } else {
260271 instantiation . push ( parameter ) ;
261272 }
0 commit comments