* Ensure that the current transition value is a child of the aggcontext, * rather than the per-tuple context. * * NB: This can change the current memory context. */
| 4445 | * NB: This can change the current memory context. |
| 4446 | */ |
| 4447 | Datum |
| 4448 | ExecAggTransReparent(AggState *aggstate, AggStatePerTrans pertrans, |
| 4449 | Datum newValue, bool newValueIsNull, |
| 4450 | Datum oldValue, bool oldValueIsNull) |
| 4451 | { |
| 4452 | Assert(newValue != oldValue); |
| 4453 | |
| 4454 | if (!newValueIsNull) |
| 4455 | { |
| 4456 | MemoryContextSwitchTo(aggstate->curaggcontext->ecxt_per_tuple_memory); |
| 4457 | if (DatumIsReadWriteExpandedObject(newValue, |
| 4458 | false, |
| 4459 | pertrans->transtypeLen) && |
| 4460 | MemoryContextGetParent(DatumGetEOHP(newValue)->eoh_context) == CurrentMemoryContext) |
| 4461 | /* do nothing */ ; |
| 4462 | else |
| 4463 | newValue = datumCopy(newValue, |
| 4464 | pertrans->transtypeByVal, |
| 4465 | pertrans->transtypeLen); |
| 4466 | } |
| 4467 | else |
| 4468 | { |
| 4469 | /* |
| 4470 | * Ensure that AggStatePerGroup->transValue ends up being 0, so |
| 4471 | * callers can safely compare newValue/oldValue without having to |
| 4472 | * check their respective nullness. |
| 4473 | */ |
| 4474 | newValue = (Datum) 0; |
| 4475 | } |
| 4476 | |
| 4477 | if (!oldValueIsNull) |
| 4478 | { |
| 4479 | if (DatumIsReadWriteExpandedObject(oldValue, |
| 4480 | false, |
| 4481 | pertrans->transtypeLen)) |
| 4482 | DeleteExpandedObject(oldValue); |
| 4483 | else |
| 4484 | pfree(DatumGetPointer(oldValue)); |
| 4485 | } |
| 4486 | |
| 4487 | return newValue; |
| 4488 | } |
| 4489 | |
| 4490 | /* |
| 4491 | * Invoke ordered transition function, with a datum argument. |
no test coverage detected