Skip to content

[GH-3128] Fix geotiff.metadata partition values, scan identity, and option handling#3129

Merged
jiayuasu merged 2 commits into
apache:masterfrom
jiayuasu:fix/geotiff-metadata-3128
Jul 20, 2026
Merged

[GH-3128] Fix geotiff.metadata partition values, scan identity, and option handling#3129
jiayuasu merged 2 commits into
apache:masterfrom
jiayuasu:fix/geotiff-metadata-3128

Conversation

@jiayuasu

Copy link
Copy Markdown
Member

Did you read the Contributor Guide?

Is this PR related to a ticket?

What changes were proposed in this PR?

Apply to geotiff.metadata the fixes that hardened the same code patterns in netcdf.metadata during the #2829 reviews. netcdf.metadata was originally modeled on geotiff.metadata, so these defects exist identically in the GeoTIFF package on master.

Correctness (silent wrong results)

  1. Per-file partition values. A bin-packed partition wrapped one reader in a single PartitionReaderWithPartitionValues using partition.files.head.partitionValues, so files from different Hive partitions (e.g. year=2020/, year=2021/) all reported the first file's partition values. Each file's reader is now wrapped with its own values (GeoTiffMetadataConcatPartitionReader; sub-readers open lazily, at most one file open at a time).

  2. Scan equality and hashing include pushdown state. FileScan's concrete equals/hashCode suppress the case-class-synthesized versions, so pushedLimit and options did not participate in equality. Since the scan alone enforces the pushed limit (isPartiallyPushed = false removes the Limit operator), exchange/subquery reuse could serve a limited scan's result for an unlimited one. equals now includes both fields and hashCode is derived from every equality field.

Crash

  1. fallbackFileFormat no longer returns null. CREATE TABLE ... USING geotiff.metadata threw a NullPointerException. The fallback is now a stub FileFormat that fails on instantiation with a descriptive UnsupportedOperationException, which also rejects CREATE TABLE with an explicit schema (that path skips inferSchema).

Behavior

  1. Directory defaults never override explicit options. Single-directory loads forced recursiveFileLookup=true, overriding an explicit false and silently disabling Hive-style partition discovery; multi-directory loads bypassed the GeoTIFF extension filter entirely. Both are now defaults only, applied for any directory root.

  2. Option presence checks are case-insensitive. Defaults were guarded with containsKey on a copied HashMap, so an explicit mixed-case option (e.g. RecursiveFileLookup=false) could nondeterministically lose to the lowercase default.

  3. A glob path combined with an explicit pathGlobFilter keeps both constraints. .load("/dir/a*.tif") with pathGlobFilter="b*.tif" previously rewrote the path and kept only one filter; the rewrite is now skipped when the user supplied a filter, so Spark applies both natively.

Every fix mirrors its review-hardened counterpart in spark/common/.../io/netcdfmetadata/, adjusted only for naming and the .tif/.tiff extensions. Documentation gains the directory-load defaults and the unsupported-catalog-operations note, mirroring the NetCDF page.

How was this patch tested?

7 new tests in geotiffMetadataTest.scala (19 total), mirroring the netcdf.metadata regression coverage:

  • Hive-style partition discovery with an explicit mixed-case RecursiveFileLookup=false, asserting every row carries its own file's partition value even when bin-packed into one Spark partition
  • Scan hash/equality consistency across equal, limit-differing, and options-differing copies
  • Glob path + explicit pathGlobFilter returning the native empty intersection (with a glob-only sanity check)
  • Multi-directory loads filtering non-GeoTIFF files
  • CREATE TABLE ... USING geotiff.metadata failing with a clear error instead of an NPE, both without and with an explicit schema

Full geotiffMetadataTest, netcdfMetadataTest, and rasteralgebraTest suites pass on Spark 3.4/Scala 2.12 (240 tests); sources cross-compile on Spark 4.0/Scala 2.13.

Did this PR include necessary documentation updates?

  • Yes, I have updated the documentation.

jiayuasu added 2 commits July 19, 2026 20:58
… and option handling

Apply to geotiff.metadata the fixes that hardened the same code patterns in
netcdf.metadata (apacheGH-3115):

- Per-file partition values: a bin-packed partition wrapped one reader with
  the first file's partitionValues, so files from different Hive partitions
  reported the wrong partition columns. Each file's reader is now wrapped
  with its own values.
- Scan equality and hashing include options and pushedLimit; FileScan's
  concrete equals suppressed the case-class versions, letting exchange or
  subquery reuse serve a limited scan's result for an unlimited one.
- fallbackFileFormat returns a stub FileFormat that fails on instantiation
  with a descriptive error, so catalog DDL (CREATE TABLE ... USING, with or
  without an explicit schema) no longer throws a NullPointerException or
  leaves an unusable table.
- Directory defaults never override explicit options: presence checks are
  case-insensitive, recursiveFileLookup=false keeps Hive-style partition
  discovery, and the GeoTIFF extension filter also applies to
  multi-directory loads.
- A user-supplied pathGlobFilter disables the glob-path rewrite so Spark
  applies both the path glob and the filter natively.

Adds 7 tests (19 total) mirroring the netcdf.metadata regression coverage;
documents the directory-load defaults and unsupported catalog operations.
…tory loads, force bin-packing in tests

- Directory-scan defaults (recursiveFileLookup and the extension
  pathGlobFilter) now apply only when every supplied root is a directory.
  Spark applies pathGlobFilter to all roots, so a mixed
  load(directory, explicitFile) previously dropped an explicitly named file
  whose name did not match the extension filter. Applied to both
  geotiff.metadata and netcdf.metadata, which share this logic.
- The Hive partition-value regression tests now force deterministic
  bin-packing (openCostInBytes=0, minPartitionNum=1, maxPartitionBytes=1g)
  and assert a single Spark partition before checking per-file partition
  values; under the default local configuration each file received its own
  partition and the old broken implementation also passed.
- Adds mixed directory-and-file load tests (with an extensionless explicit
  file) to both suites.
@jiayuasu jiayuasu added this to the sedona-1.9.1 milestone Jul 20, 2026
@jiayuasu
jiayuasu merged commit 450bce4 into apache:master Jul 20, 2026
42 checks passed
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.

Fix geotiff.metadata defects found during the netcdf.metadata reviews

1 participant