Description
We need to introduce means to expose an intermediate type for MAP aggregate, to make it is possible to construct a correctly typed plan w/o special casing DECIMAL type that return a correct type.
See PlanUtils::addAccumulatorFields
A brief overview of current implementation of accumulators in the sql engine.
AggregateCall: logical aggregate
AggregateCall: Func(ArgType) -> RetType
Accumulator: implementation of a logical aggregate
Accumulator: FuncImpl(RunArgType) -> RunRetType
Two-phase aggregate implementation:
MAP runArg = CAST(arg of type ArgType TO RunArgType) mapRes = MapFuncImpl(runArg) return mapRes // !!! No type transformation here, returns RunArgType or a type returned by MapFuncImpl REDUCE runArg = arg // mapRes w/o casting reduceRes = ReduceFuncImpl(runArg) return CAST(reduceRes of type ReduceFuncImpl's result to RetType)
An acute observer can see a problem here, when an aggregate is split into functions that produce results of different type there is a type mismatch between MAP and REDUCE.
This mismatch is currently fixed in PlanUtil::create*AggRowType, via call to Accumulator::returnType. But this method does not provide correct / precision and scale.
P.S.
This mismatch can not be fixed via standard Projection operator, because it type checks its input (so it is rejects handcrafted input-refs that return types that are correct according to AI-3 logic, but aren't according to actual relational operators).
Attachments
Issue Links
- relates to
-
IGNITE-21954 Reuse Calcite map-reduce aggregates code.
- Open