Skip to content

Commit 3483efa

Browse files
committed
fix(modelql): ClassCastException in .mapIfNotNull
fixes MODELIX-552
1 parent 56384b7 commit 3483efa

File tree

4 files changed

+17
-10
lines changed

4 files changed

+17
-10
lines changed

modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/IfEmpty.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class IfEmptyStep<In : Out, Out>(val alternative: UnboundQuery<Unit, *, Out>) :
2626
override fun createFlow(input: StepFlow<In>, context: IFlowInstantiationContext): StepFlow<Out> {
2727
val downCastedInput: StepFlow<Out> = input
2828
return downCastedInput.map { MultiplexedOutput(0, it) }.onEmpty {
29-
emitAll(alternative.asFlow(context.evaluationContext, Unit).map { MultiplexedOutput(1, it) })
29+
emitAll(alternative.asFlow(context.evaluationContext, Unit.asStepOutput(null)).map { MultiplexedOutput(1, it) })
3030
}
3131
}
3232

modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/MapIfNotNullStep.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ class MapIfNotNullStep<In : Any, Out>(val query: MonoUnboundQuery<In, Out>) : Mo
3232
}
3333

3434
override fun createFlow(input: StepFlow<In?>, context: IFlowInstantiationContext): StepFlow<Out?> {
35-
return input.flatMapConcat {
36-
it.value?.let { query.asFlow(context.evaluationContext, it).map { MultiplexedOutput(1, it) } }
37-
?: flowOf(MultiplexedOutput(0, it as IStepOutput<Out?>))
35+
return input.flatMapConcat { stepOutput ->
36+
stepOutput.value?.let { query.asFlow(context.evaluationContext, stepOutput.upcast()).map { MultiplexedOutput(1, it) } }
37+
?: flowOf(MultiplexedOutput(0, stepOutput.upcast()))
3838
}
3939
}
4040

modelql-core/src/commonMain/kotlin/org/modelix/modelql/core/Query.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ interface IQueryExecutor<out In> {
3737

3838
class SimpleQueryExecutor<E>(val input: E) : IQueryExecutor<E> {
3939
override fun <ElementOut> createFlow(query: IUnboundQuery<E, *, ElementOut>): StepFlow<ElementOut> {
40-
return query.asFlow(QueryEvaluationContext.EMPTY, input)
40+
return query.asFlow(QueryEvaluationContext.EMPTY, input.asStepOutput(null))
4141
}
4242
}
4343

@@ -105,9 +105,8 @@ private class FluxBoundQuery<In, Out>(executor: IQueryExecutor<In>, override val
105105

106106
interface IUnboundQuery<in In, out AggregationOut, out ElementOut> {
107107
val reference: IQueryReference<IUnboundQuery<In, AggregationOut, ElementOut>>
108-
suspend fun execute(evaluationContext: QueryEvaluationContext, input: In): IStepOutput<AggregationOut>
108+
suspend fun execute(evaluationContext: QueryEvaluationContext, input: IStepOutput<In>): IStepOutput<AggregationOut>
109109
fun asFlow(evaluationContext: QueryEvaluationContext, input: StepFlow<In>): StepFlow<ElementOut>
110-
fun asFlow(evaluationContext: QueryEvaluationContext, input: In): StepFlow<ElementOut> = asFlow(evaluationContext, flowOf(input).asStepFlow(null))
111110
fun asFlow(evaluationContext: QueryEvaluationContext, input: IStepOutput<In>): StepFlow<ElementOut> = asFlow(evaluationContext, flowOf(input))
112111
fun asSequence(evaluationContext: QueryEvaluationContext, input: Sequence<In>): Sequence<ElementOut>
113112

@@ -165,7 +164,7 @@ class MonoUnboundQuery<In, ElementOut>(
165164

166165
override fun bind(executor: IQueryExecutor<In>): IMonoQuery<ElementOut> = MonoBoundQuery(executor, this)
167166

168-
override suspend fun execute(evaluationContext: QueryEvaluationContext, input: In): IStepOutput<ElementOut> {
167+
override suspend fun execute(evaluationContext: QueryEvaluationContext, input: IStepOutput<In>): IStepOutput<ElementOut> {
169168
try {
170169
return asFlow(evaluationContext, input).single()
171170
} catch (ex: NoSuchElementException) {
@@ -212,7 +211,7 @@ class FluxUnboundQuery<In, ElementOut>(
212211

213212
override fun bind(executor: IQueryExecutor<In>): IFluxQuery<ElementOut> = FluxBoundQuery(executor, this)
214213

215-
override suspend fun execute(evaluationContext: QueryEvaluationContext, input: In): IStepOutput<List<IStepOutput<ElementOut>>> {
214+
override suspend fun execute(evaluationContext: QueryEvaluationContext, input: IStepOutput<In>): IStepOutput<List<IStepOutput<ElementOut>>> {
216215
return asFlow(evaluationContext, input).toList().asStepOutput(null)
217216
}
218217

modelql-core/src/commonTest/kotlin/org/modelix/modelql/core/ModelQLTest.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,14 @@ class ModelQLTest {
329329
assertEquals(testDatabase.products, result)
330330
}
331331

332+
@Test
333+
fun mapIfNotNull() = runTestWithTimeout {
334+
val result = remoteProductDatabaseQuery { db ->
335+
"a".asMono().mapIfNotNull { it.identity() }.mapIfNotNull { it.identity() }
336+
}
337+
assertEquals("a", result)
338+
}
339+
332340
@Test
333341
fun zipElementAccess() = runTestWithTimeout {
334342
val result = remoteProductDatabaseQuery { db ->
@@ -385,7 +393,7 @@ suspend fun <ResultT> doRemoteProductDatabaseQuery(body: (IMonoStep<ProductDatab
385393
val deserializedQuery = json.decodeFromString<QueryGraphDescriptor>(serializedQuery).createRootQuery() as MonoUnboundQuery<ProductDatabase, ResultT>
386394
println("original query : $query")
387395
println("deserialized query: $deserializedQuery")
388-
val remoteResult: IStepOutput<ResultT> = deserializedQuery.execute(QueryEvaluationContext.EMPTY, testDatabase)
396+
val remoteResult: IStepOutput<ResultT> = deserializedQuery.execute(QueryEvaluationContext.EMPTY, testDatabase.asStepOutput(null))
389397
val serializedResult = json.encodeToString(deserializedQuery.getAggregationOutputSerializer(json.serializersModule), remoteResult)
390398
// println(serializedResult)
391399
return json.decodeFromString(query.getAggregationOutputSerializer(json.serializersModule), serializedResult).value

0 commit comments

Comments
 (0)