[ https://issues.apache.org/jira/browse/IGNITE-21838?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Maksim Zhuravkov updated IGNITE-21838: -------------------------------------- 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: {code:python} 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) {code} 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). was: 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. ---- 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: {code:python} 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) {code} 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). > Sql. Provide correct type information for intermediate results of MAP > aggregates > -------------------------------------------------------------------------------- > > Key: IGNITE-21838 > URL: https://issues.apache.org/jira/browse/IGNITE-21838 > Project: Ignite > Issue Type: Improvement > Components: sql > Reporter: Maksim Zhuravkov > Priority: Major > Labels: ignite-3 > > 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: > {code:python} > 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) > {code} > 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). -- This message was sent by Atlassian Jira (v8.20.10#820010)