| 622 | SchemaField* out); |
| 623 | |
| 624 | Status MapToSchemaField(const GroupNode& group, LevelInfo current_levels, |
| 625 | SchemaTreeContext* ctx, const SchemaField* parent, |
| 626 | SchemaField* out) { |
| 627 | if (group.field_count() != 1) { |
| 628 | return Status::Invalid("MAP-annotated groups must have a single child."); |
| 629 | } |
| 630 | // MAP-annotated groups cannot be repeated unless served as an element within a |
| 631 | // LIST-annotated group with 2-level structure. |
| 632 | if (group.is_repeated() && |
| 633 | (group.parent() == nullptr || !group.parent()->logical_type()->is_list())) { |
| 634 | return Status::Invalid("MAP-annotated groups must not be repeated."); |
| 635 | } |
| 636 | |
| 637 | const Node& key_value_node = *group.field(0); |
| 638 | |
| 639 | if (!key_value_node.is_repeated()) { |
| 640 | return Status::Invalid( |
| 641 | "Non-repeated key value in a MAP-annotated group are not supported."); |
| 642 | } |
| 643 | |
| 644 | if (!key_value_node.is_group()) { |
| 645 | return Status::Invalid("Key-value node must be a group."); |
| 646 | } |
| 647 | |
| 648 | const GroupNode& key_value = checked_cast<const GroupNode&>(key_value_node); |
| 649 | if (key_value.field_count() != 1 && key_value.field_count() != 2) { |
| 650 | return Status::Invalid("Key-value map node must have 1 or 2 child elements. Found: ", |
| 651 | key_value.field_count()); |
| 652 | } |
| 653 | const Node& key_node = *key_value.field(0); |
| 654 | if (!key_node.is_required()) { |
| 655 | return Status::Invalid("Map keys must be annotated as required."); |
| 656 | } |
| 657 | // Arrow doesn't support 1 column maps (i.e. Sets). The options are to either |
| 658 | // make the values column nullable, or process the map as a list. We choose the |
| 659 | // latter as it is simpler. |
| 660 | if (key_value.field_count() == 1) { |
| 661 | return ListToSchemaField(group, current_levels, ctx, parent, out); |
| 662 | } |
| 663 | |
| 664 | if (group.is_optional()) { |
| 665 | current_levels.IncrementOptional(); |
| 666 | } |
| 667 | int16_t repeated_ancestor_def_level = current_levels.IncrementRepeated(); |
| 668 | |
| 669 | out->children.resize(1); |
| 670 | SchemaField* key_value_field = &out->children[0]; |
| 671 | |
| 672 | key_value_field->children.resize(2); |
| 673 | SchemaField* key_field = &key_value_field->children[0]; |
| 674 | SchemaField* value_field = &key_value_field->children[1]; |
| 675 | |
| 676 | ctx->LinkParent(out, parent); |
| 677 | ctx->LinkParent(key_value_field, out); |
| 678 | ctx->LinkParent(key_field, key_value_field); |
| 679 | ctx->LinkParent(value_field, key_value_field); |
| 680 | |
| 681 | // required/optional group name=whatever { |
no test coverage detected