voonhous commented on code in PR #19809:
URL: https://github.com/apache/hudi/pull/19809#discussion_r3916659640
##########
hudi-common/src/test/java/org/apache/hudi/common/schema/TestHoodieSchemaUtils.java:
##########
@@ -2198,4 +2083,78 @@ public void testGetNestedFieldComplexNestedMapAndArray()
{
assertEquals("value", result.get().getRight().name());
assertEquals(HoodieSchemaType.LONG,
result.get().getRight().schema().getType());
}
+
+ private static HoodieSchema deleteLogTableSchema() {
+ return HoodieSchema.createRecord(
+ "TestRecord",
+ null,
+ null,
+ Arrays.asList(
+ HoodieSchemaField.of("ts",
HoodieSchema.create(HoodieSchemaType.LONG), "ordering field doc", null),
+ HoodieSchemaField.of("name",
HoodieSchema.create(HoodieSchemaType.STRING)),
+ HoodieSchemaField.of("seq",
HoodieSchema.create(HoodieSchemaType.STRING)),
+ HoodieSchemaField.of("opt_ts", HoodieSchema.createUnion(
+ HoodieSchema.create(HoodieSchemaType.LONG),
HoodieSchema.create(HoodieSchemaType.NULL)))
+ )
+ );
+ }
+
+ @Test
+ public void testCreateDeleteLogSchema() {
+ HoodieSchema deleteLogSchema =
+ HoodieSchemaUtils.createDeleteLogSchema(deleteLogTableSchema(),
Collections.singletonList("ts"));
+
+ assertEquals("hudi_delete_log_record", deleteLogSchema.getName());
+ assertEquals(2, deleteLogSchema.getFields().size());
+
+ // The record key is always present and never nullable.
+ HoodieSchemaField recordKeyField = deleteLogSchema.getFields().get(0);
+ assertEquals(HoodieRecord.RECORD_KEY_METADATA_FIELD,
recordKeyField.name());
+ assertEquals(HoodieSchemaType.STRING, recordKeyField.schema().getType());
+ assertFalse(recordKeyField.isNullable());
+
+ // The ordering field keeps its doc but is made nullable with a null
default, even though
+ // the table schema marks it required.
+ HoodieSchemaField orderingField = deleteLogSchema.getFields().get(1);
+ assertEquals("ts", orderingField.name());
+ assertTrue(orderingField.isNullable());
+ assertEquals(HoodieSchemaType.LONG,
orderingField.getNonNullSchema().getType());
+ assertEquals("ordering field doc", orderingField.doc().get());
+ assertEquals(HoodieSchema.NULL_VALUE, orderingField.defaultVal().get());
+ }
+
+ @Test
+ public void testCreateDeleteLogSchemaOrderingFieldVariants() {
Review Comment:
Done in 6094dce391a3: `ts_ms` (timestamp-millis) and `amount` (decimal 10,2)
added to the fixture; type, precision and scale asserted after the nullable
wrapping.
##########
hudi-common/src/test/java/org/apache/hudi/common/schema/TestHoodieSchemaUtils.java:
##########
@@ -2198,4 +2083,78 @@ public void testGetNestedFieldComplexNestedMapAndArray()
{
assertEquals("value", result.get().getRight().name());
assertEquals(HoodieSchemaType.LONG,
result.get().getRight().schema().getType());
}
+
+ private static HoodieSchema deleteLogTableSchema() {
+ return HoodieSchema.createRecord(
+ "TestRecord",
+ null,
+ null,
+ Arrays.asList(
+ HoodieSchemaField.of("ts",
HoodieSchema.create(HoodieSchemaType.LONG), "ordering field doc", null),
+ HoodieSchemaField.of("name",
HoodieSchema.create(HoodieSchemaType.STRING)),
+ HoodieSchemaField.of("seq",
HoodieSchema.create(HoodieSchemaType.STRING)),
+ HoodieSchemaField.of("opt_ts", HoodieSchema.createUnion(
+ HoodieSchema.create(HoodieSchemaType.LONG),
HoodieSchema.create(HoodieSchemaType.NULL)))
+ )
+ );
+ }
+
+ @Test
+ public void testCreateDeleteLogSchema() {
+ HoodieSchema deleteLogSchema =
+ HoodieSchemaUtils.createDeleteLogSchema(deleteLogTableSchema(),
Collections.singletonList("ts"));
+
+ assertEquals("hudi_delete_log_record", deleteLogSchema.getName());
+ assertEquals(2, deleteLogSchema.getFields().size());
+
+ // The record key is always present and never nullable.
+ HoodieSchemaField recordKeyField = deleteLogSchema.getFields().get(0);
+ assertEquals(HoodieRecord.RECORD_KEY_METADATA_FIELD,
recordKeyField.name());
+ assertEquals(HoodieSchemaType.STRING, recordKeyField.schema().getType());
+ assertFalse(recordKeyField.isNullable());
+
+ // The ordering field keeps its doc but is made nullable with a null
default, even though
+ // the table schema marks it required.
+ HoodieSchemaField orderingField = deleteLogSchema.getFields().get(1);
+ assertEquals("ts", orderingField.name());
+ assertTrue(orderingField.isNullable());
+ assertEquals(HoodieSchemaType.LONG,
orderingField.getNonNullSchema().getType());
+ assertEquals("ordering field doc", orderingField.doc().get());
+ assertEquals(HoodieSchema.NULL_VALUE, orderingField.defaultVal().get());
+ }
+
+ @Test
+ public void testCreateDeleteLogSchemaOrderingFieldVariants() {
+ HoodieSchema tableSchema = deleteLogTableSchema();
+
+ // Multiple ordering fields keep the caller's order and their own types.
+ HoodieSchema multiOrderingSchema =
HoodieSchemaUtils.createDeleteLogSchema(tableSchema, Arrays.asList("ts",
"seq"));
+ assertEquals(Arrays.asList(HoodieRecord.RECORD_KEY_METADATA_FIELD, "ts",
"seq"),
+
multiOrderingSchema.getFields().stream().map(HoodieSchemaField::name).collect(Collectors.toList()));
+ HoodieSchemaField seqField = multiOrderingSchema.getFields().get(2);
+ assertEquals("seq", seqField.name());
+ assertTrue(seqField.isNullable());
+ assertEquals(HoodieSchemaType.STRING,
seqField.getNonNullSchema().getType());
+ assertEquals(HoodieSchema.NULL_VALUE, seqField.defaultVal().get());
+
+ // No ordering fields leaves the record key alone.
+ assertEquals(1, HoodieSchemaUtils.createDeleteLogSchema(tableSchema,
Collections.emptyList()).getFields().size());
+
+ // An already-nullable ordering field is left as-is rather than
double-wrapped.
Review Comment:
Done in 6094dce391a3: the `[LONG, NULL]` branch order is asserted directly
and the tautological line is gone.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]