|
50 | 50 | import org.apache.iceberg.Table; |
51 | 51 | import org.apache.iceberg.catalog.Catalog; |
52 | 52 | import org.apache.iceberg.catalog.TableIdentifier; |
53 | | -import org.apache.iceberg.data.GenericRecord; |
| 53 | +import org.apache.iceberg.data.InternalRecordWrapper; |
54 | 54 | import org.apache.iceberg.data.Record; |
55 | 55 | import org.apache.iceberg.exceptions.AlreadyExistsException; |
56 | 56 | import org.apache.iceberg.exceptions.NoSuchTableException; |
57 | | -import org.apache.iceberg.expressions.Literal; |
58 | | -import org.apache.iceberg.transforms.Transform; |
59 | 57 | import org.apache.iceberg.transforms.Transforms; |
60 | | -import org.apache.iceberg.types.Types; |
61 | 58 | import org.checkerframework.checker.nullness.qual.Nullable; |
62 | 59 | import org.slf4j.Logger; |
63 | 60 | import org.slf4j.LoggerFactory; |
@@ -106,12 +103,14 @@ class DestinationState { |
106 | 103 | @VisibleForTesting final Map<PartitionKey, Integer> writerCounts = Maps.newHashMap(); |
107 | 104 | private final Map<String, PartitionField> partitionFieldMap = Maps.newHashMap(); |
108 | 105 | private final List<Exception> exceptions = Lists.newArrayList(); |
| 106 | + private final InternalRecordWrapper wrapper; // wrapper that facilitates partitioning |
109 | 107 |
|
110 | 108 | DestinationState(IcebergDestination icebergDestination, Table table) { |
111 | 109 | this.icebergDestination = icebergDestination; |
112 | 110 | this.schema = table.schema(); |
113 | 111 | this.spec = table.spec(); |
114 | 112 | this.routingPartitionKey = new PartitionKey(spec, schema); |
| 113 | + this.wrapper = new InternalRecordWrapper(schema.asStruct()); |
115 | 114 | this.table = table; |
116 | 115 | for (PartitionField partitionField : spec.fields()) { |
117 | 116 | partitionFieldMap.put(partitionField.name(), partitionField); |
@@ -156,7 +155,7 @@ class DestinationState { |
156 | 155 | * can't create a new writer, the {@link Record} is rejected and {@code false} is returned. |
157 | 156 | */ |
158 | 157 | boolean write(Record record) { |
159 | | - routingPartitionKey.partition(getPartitionableRecord(record)); |
| 158 | + routingPartitionKey.partition(wrapper.wrap(record)); |
160 | 159 |
|
161 | 160 | @Nullable RecordWriter writer = writers.getIfPresent(routingPartitionKey); |
162 | 161 | if (writer == null && openWriters >= maxNumWriters) { |
@@ -207,30 +206,6 @@ private RecordWriter createWriter(PartitionKey partitionKey) { |
207 | 206 | e); |
208 | 207 | } |
209 | 208 | } |
210 | | - |
211 | | - /** |
212 | | - * Resolves an input {@link Record}'s partition values and returns another {@link Record} that |
213 | | - * can be applied to the destination's {@link PartitionSpec}. |
214 | | - */ |
215 | | - private Record getPartitionableRecord(Record record) { |
216 | | - if (spec.isUnpartitioned()) { |
217 | | - return record; |
218 | | - } |
219 | | - Record output = GenericRecord.create(schema); |
220 | | - for (PartitionField partitionField : spec.fields()) { |
221 | | - Transform<?, ?> transform = partitionField.transform(); |
222 | | - Types.NestedField field = schema.findField(partitionField.sourceId()); |
223 | | - String name = field.name(); |
224 | | - Object value = record.getField(name); |
225 | | - @Nullable Literal<Object> literal = Literal.of(value.toString()).to(field.type()); |
226 | | - if (literal == null || transform.isVoid() || transform.isIdentity()) { |
227 | | - output.setField(name, value); |
228 | | - } else { |
229 | | - output.setField(name, literal.value()); |
230 | | - } |
231 | | - } |
232 | | - return output; |
233 | | - } |
234 | 209 | } |
235 | 210 |
|
236 | 211 | /** |
|
0 commit comments