Skip to content

Conversation

@openinx
Copy link
Member

@openinx openinx commented Jun 8, 2021

Add unit tests to address the introduced InternalRecordWrapper, RowDataWrapper, InternalRowWrapper. The intention of writing this test is : I find that the InternalRecordWrapper did not handle the nullable value correct ( I mean we will cast a null to the target value, that is incorrect), so I think preparing an unit tests for this is necessary.

public <T> T get(int pos, Class<T> javaClass) {
if (transforms[pos] != null) {
return javaClass.cast(transforms[pos].apply(wrapped.get(pos, Object.class)));
Object value = wrapped.get(pos, Object.class);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should change the behavior of the else case where the java class is passed to wrapped.get. For that case, the right thing to do is to delegate the operation to wrapped. The reason to use Object.class is when we have a transform function and know that the java class passed in won't work.

Object value = wrapped.get(pos, Object.class);

if (value == null) {
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it incorrect to call javaClass.cast(null)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't make this change, when running this unit tests we will encounter the exception:

temporal
java.lang.NullPointerException: temporal
	at java.util.Objects.requireNonNull(Objects.java:228)
	at java.time.LocalDate.from(LocalDate.java:364)
	at java.time.LocalDate.until(LocalDate.java:1602)
	at java.time.temporal.ChronoUnit.between(ChronoUnit.java:272)
	at org.apache.iceberg.util.DateTimeUtil.daysFromDate(DateTimeUtil.java:42)
	at org.apache.iceberg.data.InternalRecordWrapper.lambda$converter$2(InternalRecordWrapper.java:48)
	at org.apache.iceberg.data.InternalRecordWrapper.get(InternalRecordWrapper.java:84)
	at org.apache.iceberg.types.Comparators$StructLikeComparator.compare(Comparators.java:122)
	at org.apache.iceberg.types.Comparators$StructLikeComparator.compare(Comparators.java:102)
	at org.apache.iceberg.util.StructLikeWrapper.equals(StructLikeWrapper.java:76)
	at org.junit.Assert.isEquals(Assert.java:131)
	at org.junit.Assert.equalsRegardingNull(Assert.java:127)
	at org.junit.Assert.assertEquals(Assert.java:111)
	at org.apache.iceberg.spark.source.TestInternalRowWrapper.generateAndValidate(TestInternalRowWrapper.java:71)
	at org.apache.iceberg.RecordWrapperTest.generateAndValidate(RecordWrapperTest.java:112)
	at org.apache.iceberg.RecordWrapperTest.testSimpleStructWithoutTime(RecordWrapperTest.java:62)
	at java.lang.Thread.run(Thread.java:748)

As you said , javaClass.cast(null) is OK , but the key problem is the transforms[pos].apply(null). we have many transforms which don't allow to handle null values.


int expectedMilliseconds = (int) ((long) expected / 1000_000);
int actualMilliseconds = (int) ((long) actual / 1000_000);
Assert.assertEquals(message, expectedMilliseconds, actualMilliseconds);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this is valid. Millisecond truncation should never be allowed, except in Flink where it is unavoidable. In the data module, this is incorrect.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct, my. original idea was to put this method in the flink test class , but forget to move it to...

return javaClass.cast(transforms[pos].apply(wrapped.get(pos, Object.class)));
Object value = wrapped.get(pos, Object.class);
if (value == null) {
// transforms function don't allow to handle null values, so just return null here.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding a comment to clarify why you're making this change!

@rdblue rdblue merged commit ec69a25 into apache:master Jun 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants