Skip to content

Implementing DataSource V2 Read Path - #162

Open
wchevreuil wants to merge 8 commits into
apache:HBASE-30189from
wchevreuil:HBASE-30189
Open

Implementing DataSource V2 Read Path#162
wchevreuil wants to merge 8 commits into
apache:HBASE-30189from
wchevreuil:HBASE-30189

Conversation

@wchevreuil

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Implements the Spark 4 DataSource V2 read path for HBase, including filter pushdown, partition planning, and row conversion.

Changes:

  • Adds the V2 provider, table, scan, batch, partition, and reader pipeline.
  • Ports row-key range and predicate handling.
  • Adds unit and mini-cluster integration tests.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
ScanRange.scala Adds row-key range operations.
HBaseTableProvider.scala Adds the V2 provider entry point.
HBaseTable.scala Declares table schema and read capability.
HBaseScanBuilder.scala Negotiates filters and projections.
HBaseScan.scala Builds the logical HBase scan.
HBaseBatch.scala Plans region-based input partitions.
HBaseInputPartition.scala Defines serializable partitions.
HBasePartitionReaderFactory.scala Creates partition readers.
HBasePartitionReader.scala Executes scans and creates rows.
ScanRangeSuite.scala Tests range operations.
HBaseScanBuilderSuite.scala Tests filter and column pushdown.
HBaseTableCatalogSuite.scala Tests catalog parsing.
HBaseTableProviderSuite.scala Tests end-to-end reads.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@taklwu taklwu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

may you fix the commit title with JIRA prefix HBASE-30189 ?

.orElse(intersectedPoints.lastOption.map(Utils.incrementByteArray))
.orElse(region.end)
.orNull
Some(HBaseInputPartition(region.index, startRow, stopRow): InputPartition)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

seems like a behavior difference from V1 that HBaseInputPartition that uses HBasePartitionReader.scala are scanning instead of Get , do you think this is good ? if not , please try to align what Spark3 does with Get.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We should use Get too. Changing this in the next commit.

extends Batch
with Logging {

override def planInputPartitions(): Array[InputPartition] = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we may need to support getPreferredLocations like V1 does , you can have it in the future PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This method is defined in the RDD class, which is the model used in V1. V2 uses the Batch model, so there's no RDD subclassing.

@wchevreuil

Copy link
Copy Markdown
Contributor Author

may you fix the commit title with JIRA prefix HBASE-30189 ?

I'm actually targeting this PR to the HBASE-30189 branch, which already has two previous commits related to this HBASE-30189. The idea was to split HBASE-30189 into several PRs for ease of review. After all PRs are in HBASE-30189, I'm going to merge it into master as a single commit for HBASE-30189.

@wchevreuil
wchevreuil requested review from taklwu and a balanced review from Copilot September 8, 2026 16:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 8 comments.

@Apache-HBase

Copy link
Copy Markdown

(!) A patch to the testing environment has been detected.
Re-executing against the patched versions to perform further tests.
The console is at https://ci-hbase.apache.org/job/HBase-Connectors-PreCommit/job/PR-162/7/console in case of problems.

@Apache-HBase

Copy link
Copy Markdown

(!) A patch to the testing environment has been detected.
Re-executing against the patched versions to perform further tests.
The console is at https://ci-hbase.apache.org/job/HBase-Connectors-PreCommit/job/PR-162/8/console in case of problems.

wchevreuil and others added 7 commits September 10, 2026 10:07
…job (apache#164)

Signed-off-by: Tak Lon (Stephen) Wu <taklwu@apache.org>
Signed-off-by: Dávid Paksy <paksyd@apache.org>
Reviewed-by: Kevin Geiszler <kevin.j.geiszler@gmail.com>
Co-authored-by: Claude Code (claude-opus-4-6) <no-reply@anthropic.com>
Signed-off-by: Peter Somogyi <psomogyi@apache.org>
…emas (apache#160)

Co-authored-by: Claude Code (claude-opus-4-6) <no-reply@anthropic.com>
    
Signed-off-by: Peter Somogyi <psomogyi@apache.org>
@Apache-HBase

Copy link
Copy Markdown

(!) A patch to the testing environment has been detected.
Re-executing against the patched versions to perform further tests.
The console is at https://ci-hbase.apache.org/job/HBase-Connectors-PreCommit/job/PR-162/10/console in case of problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Composite keys, unions, null handling, and configuration propagation still contain correctness or scalability defects.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

spark4/hbase-spark4/src/main/scala/org/apache/hadoop/hbase/spark/datasources/HBasePartitionReader.scala:198

  • The same missing-qualifier problem affects point reads: a Get restricted to the IsNull qualifier returns an empty Result when that qualifier is absent, and line 202 drops it before the predicate can accept it. For pushed expressions that can match a missing cell, do not restrict the Get to only those qualifiers (or otherwise fetch an existence column).
        scanFields.foreach { f =>
          g.addColumn(f.cfBytes, f.colBytes)
        }
  • Files reviewed: 17/17 changed files
  • Comments generated: 8
  • Review effort level: Balanced

Comment on lines +55 to +57
val conf = HBaseConfiguration.create()
val configResources = properties.get(HBaseSparkConf.HBASE_CONFIG_LOCATION)
configResources.foreach(_.split(",").foreach(r => conf.addResource(new Path(r))))
Comment on lines +182 to +184
scanFields.foreach { f =>
scan.addColumn(f.cfBytes, f.colBytes)
}
Comment on lines +68 to +75
case EqualTo(attr, _) => catalog.sMap.map.contains(attr)
case LessThan(attr, _) => catalog.sMap.map.contains(attr)
case GreaterThan(attr, _) => catalog.sMap.map.contains(attr)
case LessThanOrEqual(attr, _) => catalog.sMap.map.contains(attr)
case GreaterThanOrEqual(attr, _) => catalog.sMap.map.contains(attr)
case StringStartsWith(attr, _) => catalog.sMap.map.contains(attr)
case IsNull(attr) => catalog.sMap.map.contains(attr)
case IsNotNull(attr) => catalog.sMap.map.contains(attr)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressing on next comment.

Comment on lines +148 to +159
def mergeUnion(other: RowKeyFilter): RowKeyFilter = {
other.points.foreach(p => points += p)

other.ranges.foreach { otherR =>
var doesOverLap = false
ranges.foreach { r =>
if (r.getOverLapScanRange(otherR) != null) {
r.mergeUnion(otherR)
doesOverLap = true
}
}
if (!doesOverLap) ranges += otherR

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have checked this with claude code and it's indeed an issue that also affects the spark3 module. I think we should address this on a separate PR, fixing it on both modules.

Comment on lines +75 to +79
if (scanRanges.isEmpty && points.isEmpty) {
regions.map { region =>
val fullRange = Range(region)
HBaseInputPartition(region.index, Seq(fullRange), Seq.empty): InputPartition
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressing on next commit.

Comment on lines +151 to +155
private def setStopRow(scan: Scan, bound: Bound): Scan = {
if (bound.inc) {
val incremented = Utils.incrementByteArray(bound.b)
if (incremented != null) scan.withStopRow(incremented)
else scan

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixing in next commit.

Comment on lines +31 to +35
case class HBaseInputPartition(
index: Int,
scanRanges: Seq[Range],
points: Seq[Array[Byte]])
extends InputPartition
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants