| 258 | |
| 259 | template <bool COLLECT_VAR_LEN_VALS> |
| 260 | void RawValue::WriteStruct(const void* value, Tuple* tuple, |
| 261 | const SlotDescriptor* slot_desc, MemPool* pool, vector<StringValue*>* string_values, |
| 262 | vector<pair<CollectionValue*, int64_t>>* collection_values) { |
| 263 | DCHECK(tuple != nullptr); |
| 264 | DCHECK(slot_desc->type().IsStructType()); |
| 265 | DCHECK(slot_desc->children_tuple_descriptor() != nullptr); |
| 266 | if (value == nullptr) { |
| 267 | tuple->SetStructToNull(slot_desc); |
| 268 | return; |
| 269 | } |
| 270 | const StructVal* src = reinterpret_cast<const StructVal*>(value); |
| 271 | const TupleDescriptor* children_tuple_desc = slot_desc->children_tuple_descriptor(); |
| 272 | DCHECK_EQ(src->num_children, children_tuple_desc->slots().size()); |
| 273 | |
| 274 | for (int i = 0; i < src->num_children; ++i) { |
| 275 | SlotDescriptor* child_slot = children_tuple_desc->slots()[i]; |
| 276 | uint8_t* src_child = src->ptr[i]; |
| 277 | // TODO IMPALA-12160: Handle collections in structs. |
| 278 | if (child_slot->type().IsStructType()) { |
| 279 | // Recursive call in case of nested structs. |
| 280 | WriteStruct<COLLECT_VAR_LEN_VALS>(src_child, tuple, child_slot, pool, |
| 281 | string_values, collection_values); |
| 282 | } else if (src_child == nullptr) { |
| 283 | tuple->SetNull(child_slot->null_indicator_offset()); |
| 284 | } else { |
| 285 | WritePrimitiveCollectVarlen<COLLECT_VAR_LEN_VALS>(src_child, tuple, child_slot, |
| 286 | pool, string_values); |
| 287 | } |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | template <bool COLLECT_VAR_LEN_VALS> |
| 292 | void RawValue::WriteCollection(const void* value, Tuple* tuple, |
nothing calls this directly
no test coverage detected