| 391 | } |
| 392 | |
| 393 | void AggFnEvaluator::SerializeOrFinalize(Tuple* src, |
| 394 | const SlotDescriptor& dst_slot_desc, Tuple* dst, void* fn) { |
| 395 | // No fn was given and the src and dst are identical. Nothing to be done. |
| 396 | if (fn == nullptr && src == dst) return; |
| 397 | // src != dst means we are performing a Finalize(), so even if fn == null we |
| 398 | // still must copy the value of the src slot into dst. |
| 399 | |
| 400 | const SlotDescriptor& slot_desc = intermediate_slot_desc(); |
| 401 | bool src_slot_null = src->IsNull(slot_desc.null_indicator_offset()); |
| 402 | void* src_slot = nullptr; |
| 403 | if (!src_slot_null) src_slot = src->GetSlot(slot_desc.tuple_offset()); |
| 404 | |
| 405 | // No fn was given but the src and dst tuples are different (doing a Finalize()). |
| 406 | // Just copy the src slot into the dst tuple. |
| 407 | if (fn == nullptr) { |
| 408 | DCHECK_EQ(intermediate_type(), dst_slot_desc.type()); |
| 409 | RawValue::Write(src_slot, dst, &dst_slot_desc, nullptr); |
| 410 | return; |
| 411 | } |
| 412 | |
| 413 | AnyValUtil::SetAnyVal(src_slot, intermediate_type(), staging_intermediate_val_); |
| 414 | switch (dst_slot_desc.type().type) { |
| 415 | case TYPE_BOOLEAN: { |
| 416 | typedef BooleanVal(*Fn)(FunctionContext*, AnyVal*); |
| 417 | BooleanVal v = reinterpret_cast<Fn>(fn)( |
| 418 | agg_fn_ctx_.get(), staging_intermediate_val_); |
| 419 | SetDstSlot(&v, dst_slot_desc, dst); |
| 420 | break; |
| 421 | } |
| 422 | case TYPE_TINYINT: { |
| 423 | typedef TinyIntVal(*Fn)(FunctionContext*, AnyVal*); |
| 424 | TinyIntVal v = reinterpret_cast<Fn>(fn)( |
| 425 | agg_fn_ctx_.get(), staging_intermediate_val_); |
| 426 | SetDstSlot(&v, dst_slot_desc, dst); |
| 427 | break; |
| 428 | } |
| 429 | case TYPE_SMALLINT: { |
| 430 | typedef SmallIntVal(*Fn)(FunctionContext*, AnyVal*); |
| 431 | SmallIntVal v = reinterpret_cast<Fn>(fn)( |
| 432 | agg_fn_ctx_.get(), staging_intermediate_val_); |
| 433 | SetDstSlot(&v, dst_slot_desc, dst); |
| 434 | break; |
| 435 | } |
| 436 | case TYPE_INT: { |
| 437 | typedef IntVal(*Fn)(FunctionContext*, AnyVal*); |
| 438 | IntVal v = reinterpret_cast<Fn>(fn)( |
| 439 | agg_fn_ctx_.get(), staging_intermediate_val_); |
| 440 | SetDstSlot(&v, dst_slot_desc, dst); |
| 441 | break; |
| 442 | } |
| 443 | case TYPE_BIGINT: { |
| 444 | typedef BigIntVal(*Fn)(FunctionContext*, AnyVal*); |
| 445 | BigIntVal v = reinterpret_cast<Fn>(fn)( |
| 446 | agg_fn_ctx_.get(), staging_intermediate_val_); |
| 447 | SetDstSlot(&v, dst_slot_desc, dst); |
| 448 | break; |
| 449 | } |
| 450 | case TYPE_FLOAT: { |
nothing calls this directly
no test coverage detected