|
29 | 29 | import java.util.Map; |
30 | 30 | import java.util.Objects; |
31 | 31 | import java.util.Optional; |
| 32 | +import java.util.function.Consumer; |
32 | 33 | import java.util.function.Function; |
33 | 34 | import java.util.stream.Collectors; |
34 | 35 | import java.util.stream.Stream; |
|
54 | 55 | import org.apache.hadoop.hive.metastore.partition.spec.PartitionSpecProxy; |
55 | 56 | import org.apache.hadoop.hive.metastore.utils.MetaStoreUtils; |
56 | 57 | import org.apache.hadoop.hive.ql.QueryState; |
| 58 | +import org.apache.hadoop.hive.ql.ddl.misc.sortoder.SortFieldDesc; |
57 | 59 | import org.apache.hadoop.hive.ql.ddl.table.AlterTableType; |
58 | 60 | import org.apache.hadoop.hive.ql.exec.SerializationUtilities; |
59 | 61 | import org.apache.hadoop.hive.ql.io.AcidUtils; |
|
85 | 87 | import org.apache.iceberg.FileScanTask; |
86 | 88 | import org.apache.iceberg.MetadataTableType; |
87 | 89 | import org.apache.iceberg.MetadataTableUtils; |
| 90 | +import org.apache.iceberg.NullOrder; |
88 | 91 | import org.apache.iceberg.PartitionData; |
89 | 92 | import org.apache.iceberg.PartitionField; |
90 | 93 | import org.apache.iceberg.PartitionSpec; |
91 | 94 | import org.apache.iceberg.PartitionSpecParser; |
92 | 95 | import org.apache.iceberg.PartitionsTable; |
| 96 | +import org.apache.iceberg.ReplaceSortOrder; |
93 | 97 | import org.apache.iceberg.Schema; |
94 | 98 | import org.apache.iceberg.SchemaParser; |
| 99 | +import org.apache.iceberg.SortOrder; |
| 100 | +import org.apache.iceberg.SortOrderParser; |
95 | 101 | import org.apache.iceberg.Table; |
96 | 102 | import org.apache.iceberg.TableMetadata; |
97 | 103 | import org.apache.iceberg.TableMetadataParser; |
@@ -624,15 +630,65 @@ private void alterTableProperties(org.apache.hadoop.hive.metastore.api.Table hms |
624 | 630 | Map<String, String> hmsTableParameters = hmsTable.getParameters(); |
625 | 631 | Splitter splitter = Splitter.on(PROPERTIES_SEPARATOR); |
626 | 632 | UpdateProperties icebergUpdateProperties = icebergTable.updateProperties(); |
| 633 | + |
627 | 634 | if (contextProperties.containsKey(SET_PROPERTIES)) { |
628 | | - splitter.splitToList(contextProperties.get(SET_PROPERTIES)) |
629 | | - .forEach(k -> icebergUpdateProperties.set(k, hmsTableParameters.get(k))); |
| 635 | + List<String> propertiesToSet = splitter.splitToList(contextProperties.get(SET_PROPERTIES)); |
| 636 | + |
| 637 | + // Define handlers for properties that need special processing |
| 638 | + Map<String, Consumer<String>> propertyHandlers = Maps.newHashMap(); |
| 639 | + propertyHandlers.put(TableProperties.DEFAULT_SORT_ORDER, |
| 640 | + key -> handleDefaultSortOrder(hmsTable, hmsTableParameters)); |
| 641 | + |
| 642 | + // Process each property using handlers or default behavior |
| 643 | + propertiesToSet.forEach(key -> |
| 644 | + propertyHandlers.getOrDefault(key, |
| 645 | + k -> icebergUpdateProperties.set(k, hmsTableParameters.get(k)) |
| 646 | + ).accept(key) |
| 647 | + ); |
630 | 648 | } else if (contextProperties.containsKey(UNSET_PROPERTIES)) { |
631 | 649 | splitter.splitToList(contextProperties.get(UNSET_PROPERTIES)).forEach(icebergUpdateProperties::remove); |
632 | 650 | } |
| 651 | + |
633 | 652 | icebergUpdateProperties.commit(); |
634 | 653 | } |
635 | 654 |
|
| 655 | + /** |
| 656 | + * Handles conversion of Hive SortFields JSON to Iceberg SortOrder. |
| 657 | + * Uses Iceberg's replaceSortOrder() API to properly handle the reserved property. |
| 658 | + */ |
| 659 | + private void handleDefaultSortOrder(org.apache.hadoop.hive.metastore.api.Table hmsTable, |
| 660 | + Map<String, String> hmsTableParameters) { |
| 661 | + String sortOrderJSONString = hmsTableParameters.get(TableProperties.DEFAULT_SORT_ORDER); |
| 662 | + |
| 663 | + List<SortFieldDesc> sortFieldDescList = parseSortFieldsJSON(sortOrderJSONString); |
| 664 | + if (sortFieldDescList != null) { |
| 665 | + try { |
| 666 | + ReplaceSortOrder replaceSortOrder = icebergTable.replaceSortOrder(); |
| 667 | + |
| 668 | + // Chain all the sort field additions |
| 669 | + for (SortFieldDesc fieldDesc : sortFieldDescList) { |
| 670 | + NullOrder nullOrder = convertNullOrder(fieldDesc.getNullOrdering()); |
| 671 | + |
| 672 | + if (fieldDesc.getDirection() == SortFieldDesc.SortDirection.ASC) { |
| 673 | + replaceSortOrder.asc(fieldDesc.getColumnName(), nullOrder); |
| 674 | + } else { |
| 675 | + replaceSortOrder.desc(fieldDesc.getColumnName(), nullOrder); |
| 676 | + } |
| 677 | + } |
| 678 | + |
| 679 | + replaceSortOrder.commit(); |
| 680 | + |
| 681 | + // Update HMS table parameters with the Iceberg SortOrder JSON |
| 682 | + SortOrder newSortOrder = icebergTable.sortOrder(); |
| 683 | + hmsTableParameters.put(TableProperties.DEFAULT_SORT_ORDER, SortOrderParser.toJson(newSortOrder)); |
| 684 | + |
| 685 | + LOG.info("Successfully set sort order for table {}: {}", hmsTable.getTableName(), newSortOrder); |
| 686 | + } catch (Exception e) { |
| 687 | + LOG.warn("Failed to apply sort order for table {}: {}", hmsTable.getTableName(), sortOrderJSONString, e); |
| 688 | + } |
| 689 | + } |
| 690 | + } |
| 691 | + |
636 | 692 | private void setupAlterOperationType(org.apache.hadoop.hive.metastore.api.Table hmsTable, |
637 | 693 | EnvironmentContext context) throws MetaException { |
638 | 694 | TableName tableName = new TableName(hmsTable.getCatName(), hmsTable.getDbName(), hmsTable.getTableName()); |
|
0 commit comments