Uh oh!
There was an error while loading. Please reload this page.
[SPARK-21583][SQL] Create a ColumnarBatch from ArrowColumnVectors - #18787
[SPARK-21583][SQL] Create a ColumnarBatch from ArrowColumnVectors#18787BryanCutler wants to merge 13 commits into
Conversation
SparkQA
commented
Jul 31, 2017
Test build #80094 has finished for PR 18787 at commit
|
SparkQA
commented
Aug 1, 2017
Test build #80099 has finished for PR 18787 at commit
|
SparkQA
commented
Aug 1, 2017
Test build #80108 has finished for PR 18787 at commit
|
| ReadOnlyColumnVector[] columns, | ||
| int numRows) { | ||
| for (ReadOnlyColumnVector c: columns) { | ||
| assert(c.capacity >= numRows); |
There was a problem hiding this comment.
Is there any good way to move this assert into other loop?
I am afraid that the loop with no body is executed in a production.
There was a problem hiding this comment.
Maybe this should throw an exception then?
| public static ColumnarBatch createReadOnly( | ||
| StructType schema, | ||
| ReadOnlyColumnVector[] columns, |
There was a problem hiding this comment.
Do we need to restrict this to only ReadOnlyColumnVector?
There was a problem hiding this comment.
Is it necessary? What impact will it cause?
There was a problem hiding this comment.
It doesn't need to be restricted, but if they are ReadOnlyColumnVectors then it means they are already populated and it is safe to call setNumRows(numRows) here. If it took in any ColumnVector then it might cause issues by someone passing in unallocated vectors.
| return batch; | ||
| } | ||
| private static ColumnarBatch create(StructType schema, ColumnVector[] columns, int capacity) { |
There was a problem hiding this comment.
@ueshin , if we want to allow creating a ColumnarBatch from any Array of ColumnVectors then we could make this public as it doesn't call setNumRows and assume they are allocated already
BryanCutler
commented
Aug 1, 2017
@cloud-fan@icexelloss, this just adds the ability to create a |
| close() | ||
| } | ||
| private var _batch: ColumnarBatch = _ |
SparkQA
commented
Aug 9, 2017
Test build #80430 has finished for PR 18787 at commit
|
BryanCutler
commented
Aug 9, 2017
jenkins retest this please |
SparkQA
commented
Aug 9, 2017
Test build #80438 has finished for PR 18787 at commit
|
| int numRows) { | ||
| assert(schema.length() == columns.length); | ||
| ColumnarBatch batch = new ColumnarBatch(schema, columns, numRows); | ||
| batch.setNumRows(numRows); |
There was a problem hiding this comment.
Do we need to check each ReadOnlyColumnVector has numRows?
| ReadOnlyColumnVector[] columns, | ||
| int numRows) { | ||
| assert(schema.length() == columns.length); | ||
| ColumnarBatch batch = new ColumnarBatch(schema, columns, numRows); |
There was a problem hiding this comment.
Why the capacity is set to numRows inside the ctor but need to call batch.setNumRows() manually?
There was a problem hiding this comment.
The max capacity only has meaning when allocating ColumnVectors so it doesn't really do
anything for read-only vectors. You need to callsetNumRows to tell the batch how many rows there for the given columns, it doesn't look at the capacity in the individual vectors.
BryanCutler
commented
Aug 9, 2017
@ueshin@cloud-fan , what are your thoughts on merging this to enable |
cloud-fan
commented
Aug 14, 2017
Actually I think |
BryanCutler
commented
Aug 15, 2017
Yes, I agree with changing the interfaces as you suggest @cloud-fan , is there currently a JIRA open for that? I'm ok with holding off if it's planned to be soon, but I would like to get started on SPARK-20791 that will create a Spark DataFrame from Pandas with Arrow, which depends on this also. I don't think the changes you are suggesting would affect this PR much, just renaming the classes used. Any chance we can merge this first? |
BryanCutler
commented
Aug 25, 2017
Updated to use the new API for ColumnarBatch, please take a look @ueshin@cloud-fan |
SparkQA
commented
Aug 25, 2017
Test build #81122 has finished for PR 18787 at commit
|
| new ArrowRowIterator { | ||
| private var reader: ArrowFileReader = null | ||
| private var schemaRead = StructType(Seq.empty) |
There was a problem hiding this comment.
We can simply put Iterator.empty here.
There was a problem hiding this comment.
nextBatch() returns the row iterator, so rowIter needs to be initialized here to the first row in the first batch
There was a problem hiding this comment.
nvm, I thought the first call of hasNext would initialize it.
| } | ||
| } | ||
| test("create read-only batch") { |
There was a problem hiding this comment.
create a columnar batch from Arrow column vectors or something?
| batch.getRow(100) | ||
| } | ||
| columnVectors.foreach(_.close()) |
| val schema = StructType(Seq(StructField("int", IntegerType))) | ||
| val batch = new ColumnarBatch(schema, Array[ColumnVector](new ArrowColumnVector(vector)), 11) |
There was a problem hiding this comment.
Btw, do we need to use ColumnarBatch for this test?
I guess we can simply create Iterator[InternalRow] and use it.
There was a problem hiding this comment.
you mean just calling something like new ColumnarBatch(..).rowIterator()? We still need to set the number of rows in the batch I believe
There was a problem hiding this comment.
Oh, you mean not using ArrowColumnVector at all and just make an Iterator[InternalRow] some other way? That would probably work, but I figured why not test out the columnar batch this way also.
There was a problem hiding this comment.
Yes, I meant your second comment.
We do test the columnar batch with ArrowColumnVector in ColumnarBatchSuite and also we use it in ArrowConverters.fromPayloadIterator(), so I thought we don't need to use it here.
| test("roundtrip payloads") { | ||
| val allocator = ArrowUtils.rootAllocator.newChildAllocator("int", 0, Long.MaxValue) | ||
| val vector = ArrowUtils.toArrowField("int", IntegerType, nullable = true) | ||
| .createVector(allocator).asInstanceOf[NullableIntVector] |
There was a problem hiding this comment.
Should the allocator and the vector be closed at the end of this test?
There was a problem hiding this comment.
yes, thanks for catching that. I close them now.
SparkQA
commented
Aug 29, 2017
Test build #81225 has finished for PR 18787 at commit
|
BryanCutler
commented
Aug 30, 2017
@ueshin I updated and had a couple of questions on your comments, please take a look, thanks! |
BryanCutler
commented
Aug 31, 2017
@ueshin I updated the test to use a seq of Rows now |
ueshin
commented
Aug 31, 2017
LGTM, pending Jenkins. |
SparkQA
commented
Aug 31, 2017
Test build #81270 has finished for PR 18787 at commit
|
ueshin
commented
Aug 31, 2017
Thanks! merging to master. |
BryanCutler
commented
Aug 31, 2017
Thanks @ueshin! |
| } | ||
| intercept[java.lang.AssertionError] { | ||
| batch.getRow(100) |
There was a problem hiding this comment.
Hi, @BryanCutler and @ueshin .
This seems to make master branch fail. Could you take a look once more? Thank you in advance!
There was a problem hiding this comment.
Hmm, that is strange. I'll take a look, thanks.
There was a problem hiding this comment.
Thanks! It seems to happen Maven only. sbt-hadoop-2.6 passed.
There was a problem hiding this comment.
It's probably because the assert is being compiled out.. This should probably not be in the test then.
There was a problem hiding this comment.
Then, please check the error message here. Please ignore this.
There was a problem hiding this comment.
I think the problem is that if the Java assertion is compiled out, then no error is produced and the test fails.
There was a problem hiding this comment.
I just made #19098 to remove this check - it's not really testing the functionality added here anyway but maybe another test should be added for checkout index out of bounds errors.
What changes were proposed in this pull request?
This PR allows the creation of a
ColumnarBatchfromReadOnlyColumnVectorswhere previously a columnar batch could only allocate vectors internally. This is useful for usingArrowColumnVectorsin a batch form to do row-based iteration. Also addedArrowConverter.fromPayloadIteratorwhich convertsArrowPayloaditerator toInternalRowiterator and uses aColumnarBatchinternally.How was this patch tested?
Added a new unit test for creating a
ColumnarBatchwithReadOnlyColumnVectorsand a test to verify the roundtrip of rows -> ArrowPayload -> rows, usingtoPayloadIteratorandfromPayloadIterator.