| 687 | } |
| 688 | |
| 689 | Status ParquetSchemaResolver::ResolvePathHelper(ArrayEncoding array_encoding, |
| 690 | const SchemaPath& path, SchemaNode** node, bool* pos_field, |
| 691 | bool* missing_field) const { |
| 692 | DCHECK(schema_.element != NULL) |
| 693 | << "schema_ must be initialized before calling ResolvePath()"; |
| 694 | |
| 695 | *pos_field = false; |
| 696 | *missing_field = false; |
| 697 | *node = const_cast<SchemaNode*>(&schema_); |
| 698 | const ColumnType* col_type = NULL; |
| 699 | |
| 700 | // Traverse 'path' and resolve 'node' to the corresponding SchemaNode in 'schema_' (by |
| 701 | // ordinal), or set 'node' to NULL if 'path' doesn't exist in this file's schema. |
| 702 | for (int i = 0; i < path.size(); ++i) { |
| 703 | // Advance '*node' if necessary |
| 704 | if (i == 0 || col_type->type != TYPE_ARRAY || array_encoding == THREE_LEVEL) { |
| 705 | *node = NextSchemaNode(col_type, path, i, *node, missing_field); |
| 706 | if (*missing_field) return Status::OK(); |
| 707 | } else { |
| 708 | // We just resolved an array, meaning *node is set to the repeated field of the |
| 709 | // array. Since we are trying to resolve using one- or two-level array encoding, the |
| 710 | // repeated field represents both the array and the array's item (i.e. there is no |
| 711 | // explict item field), so we don't advance *node in this case. |
| 712 | DCHECK(col_type != NULL); |
| 713 | DCHECK_EQ(col_type->type, TYPE_ARRAY); |
| 714 | DCHECK(array_encoding == ONE_LEVEL || array_encoding == TWO_LEVEL); |
| 715 | DCHECK((*node)->is_repeated()); |
| 716 | } |
| 717 | |
| 718 | // Advance 'col_type' |
| 719 | int table_idx = path[i]; |
| 720 | col_type = i == 0 ? &tbl_desc_.col_descs()[table_idx].type() |
| 721 | : &col_type->children[table_idx]; |
| 722 | |
| 723 | // Resolve path[i] |
| 724 | if (col_type->type == TYPE_ARRAY) { |
| 725 | DCHECK_EQ(col_type->children.size(), 1); |
| 726 | RETURN_IF_ERROR( |
| 727 | ResolveArray(array_encoding, path, i, node, pos_field, missing_field)); |
| 728 | if (*missing_field || *pos_field) return Status::OK(); |
| 729 | } else if (col_type->type == TYPE_MAP) { |
| 730 | DCHECK_EQ(col_type->children.size(), 2); |
| 731 | RETURN_IF_ERROR(ResolveMap(path, i, node, missing_field)); |
| 732 | if (*missing_field) return Status::OK(); |
| 733 | } else if (col_type->type == TYPE_STRUCT) { |
| 734 | DCHECK_GT(col_type->children.size(), 0); |
| 735 | RETURN_IF_ERROR(ResolveStruct(**node, *col_type, path, i)); |
| 736 | } else { |
| 737 | DCHECK(!col_type->IsComplexType()); |
| 738 | DCHECK_EQ(i, path.size() - 1); |
| 739 | RETURN_IF_ERROR(ValidateScalarNode(**node, *col_type, path, i)); |
| 740 | } |
| 741 | } |
| 742 | DCHECK(*node != NULL); |
| 743 | return Status::OK(); |
| 744 | } |
| 745 | |
| 746 | SchemaNode* ParquetSchemaResolver::NextSchemaNode( |
nothing calls this directly
no test coverage detected