This is an automated email from the ASF dual-hosted git repository.
MaxGekk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 021b347d3f6c [SPARK-56893][SQL] Optimize Parquet dictionary decoding
with hasNull fast path and per-class updater overrides
021b347d3f6c is described below
commit 021b347d3f6ca6049061ce520d7190db79cefb99
Author: Ismaël Mejía <[email protected]>
AuthorDate: Tue Jun 23 09:43:17 2026 +0200
[SPARK-56893][SQL] Optimize Parquet dictionary decoding with hasNull fast
path and per-class updater overrides
### What changes were proposed in this pull request?
This PR adds two optimizations to the Parquet vectorized dictionary decode
path (`ParquetVectorUpdater.decodeDictionaryIds`):
1. **`hasNull()` fast path**: A new `static decodeBatch` helper on
`ParquetVectorUpdater` splits decoding into two loops — when `values.hasNull()`
is false, the per-element `isNullAt(i)` check is skipped entirely.
2. **Per-class `decodeDictionaryIds` overrides** in six hot-path updaters
(`IntegerUpdater`, `IntegerToLongUpdater`, `LongUpdater`, `FloatUpdater`,
`FloatToDoubleUpdater`, `DoubleUpdater`): each override is a one-line
delegation to `decodeBatch(... this)`. Although the logic is identical to the
default method, each per-class override gives the C2 JIT compiler its own
bytecode — and therefore a monomorphic call site for `decodeSingleDictionaryId`
— enabling full inlining of the type-sp [...]
Class hierarchy of the change:
```
ParquetVectorUpdater (interface)
├── default decodeDictionaryIds(...) → delegates to static
decodeBatch(... this)
├── static decodeBatch(...) → hasNull() branch + two loops
calling updater.decodeSingleDictionaryId()
│
└── Concrete updaters in ParquetVectorUpdaterFactory:
├── IntegerUpdater Override decodeDictionaryIds →
decodeBatch(... this)
├── IntegerToLongUpdater Override decodeDictionaryIds →
decodeBatch(... this)
├── LongUpdater Override decodeDictionaryIds →
decodeBatch(... this)
├── FloatUpdater Override decodeDictionaryIds →
decodeBatch(... this)
├── FloatToDoubleUpdater Override decodeDictionaryIds →
decodeBatch(... this)
└── DoubleUpdater Override decodeDictionaryIds →
decodeBatch(... this)
```
### Why are the changes needed?
The default `decodeDictionaryIds` method has two performance issues:
- **Unconditional `isNullAt` check**: Even when the column has no nulls
(common case), every element pays for an `isNullAt(i)` call.
`WritableColumnVector.hasNull()` is an O(1) flag check that allows skipping the
per-element null check entirely.
- **Megamorphic dispatch**: Java interface default methods compile to a
single bytecode shared by all implementors. C2 profiles one call site for
`decodeSingleDictionaryId` across ~30 updater types → megamorphic → no
inlining. Per-class overrides create per-class bytecode → per-class C2 profiles
→ monomorphic devirtualization → full inlining of the decode expression.
### Benchmark results
Baseline vs optimized on **AMD EPYC 9V74** (1M rows, dict size 100, Rate
M/s — higher is better):
**No nulls (fast-path target):**
| Updater | JDK 17 Baseline | JDK 17 Optimized | Speedup | JDK 21 Baseline
| JDK 21 Optimized | Speedup | JDK 25 Baseline | JDK 25 Optimized | Speedup |
|---------|----:|----:|:---:|----:|----:|:---:|----:|----:|:---:|
| IntegerUpdater | 186.7 | 227.6 | **1.22x** | 177.6 | 288.3 | **1.62x** |
179.1 | 222.6 | **1.24x** |
| LongUpdater | 185.1 | 224.1 | **1.21x** | 176.4 | 285.4 | **1.62x** |
178.6 | 221.1 | **1.24x** |
| FloatUpdater | 188.6 | 229.7 | **1.22x** | 178.3 | 287.4 | **1.61x** |
178.1 | 222.9 | **1.25x** |
| DoubleUpdater | 187.6 | 228.2 | **1.22x** | 177.2 | 286.5 | **1.62x** |
177.5 | 221.7 | **1.25x** |
| IntegerToLongUpdater | 184.4 | 224.1 | **1.22x** | 175.8 | 281.6 |
**1.60x** | 175.1 | 218.9 | **1.25x** |
| FloatToDoubleUpdater | 187.3 | 227.8 | **1.22x** | 172.2 | 268.8 |
**1.56x** | 178.8 | 222.2 | **1.24x** |
**10% nulls:**
| Updater | JDK 17 Speedup | JDK 21 Speedup | JDK 25 Speedup |
|---------|:---:|:---:|:---:|
| IntegerUpdater | 1.00x | **1.26x** | 0.99x |
| LongUpdater | 0.96x | **1.28x** | 0.99x |
| FloatUpdater | 1.00x | **1.28x** | 0.97x |
| DoubleUpdater | 1.00x | **1.24x** | 1.00x |
| IntegerToLongUpdater | 0.98x | **1.26x** | 0.99x |
| FloatToDoubleUpdater | 0.99x | **1.29x** | 0.99x |
**50% nulls:**
| Updater | JDK 17 Speedup | JDK 21 Speedup | JDK 25 Speedup |
|---------|:---:|:---:|:---:|
| IntegerUpdater | 0.99x | **1.25x** | 0.99x |
| LongUpdater | 1.01x | **1.25x** | 1.03x |
| FloatUpdater | 0.99x | **1.26x** | 0.98x |
| DoubleUpdater | 0.99x | **1.26x** | 0.98x |
| IntegerToLongUpdater | 0.99x | **1.26x** | 1.02x |
| FloatToDoubleUpdater | 1.00x | **1.25x** | 0.99x |
**Key observations:**
- JDK 17/25 no-nulls: consistent **1.21-1.25x** improvement.
- JDK 21 no-nulls: **1.56-1.62x** — JDK 21 C2 benefits dramatically from
monomorphic devirtualization.
- JDK 21 with-nulls: **1.24-1.29x** — the monomorphic call site alone
(independent of hasNull branch) improves throughput.
- JDK 17/25 with-nulls: neutral (~1.0x) — as expected, `isNullAt` dominates.
Baseline workflow runs (before optimization): [JDK
17](https://github.com/iemejia/spark/actions/runs/27978726935), [JDK
21](https://github.com/iemejia/spark/actions/runs/27967169001), [JDK
25](https://github.com/iemejia/spark/actions/runs/27977735937)
Optimized workflow runs: [JDK
17](https://github.com/iemejia/spark/actions/runs/27981015508), [JDK
21](https://github.com/iemejia/spark/actions/runs/27989226064), [JDK
25](https://github.com/iemejia/spark/actions/runs/27986201001)
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
- Existing tests: `ParquetVectorizedSuite`, `ParquetIOSuite` (123 tests
total) — all pass.
- Benchmark: `ParquetDictionaryDecodeBenchmark` (landed separately in
#56670) with global pre-warm that interleaves both `hasNull()` branches
(no-null and 50%-null) across all 6 updater types before measurement, avoiding
C2 uncommon-trap bias. Three benchmark groups: no nulls, 10% nulls, 50% nulls.
Baseline and optimized results committed on the same CPU (AMD EPYC 9V74).
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: OpenCode (Claude claude-opus-4.6)
Closes #55920 from iemejia/SPARK-56893-parquet-dict-decode-fast-path.
Authored-by: Ismaël Mejía <[email protected]>
Signed-off-by: Max Gekk <[email protected]>
---
...quetDictionaryDecodeBenchmark-jdk21-results.txt | 36 ++++++-------
...quetDictionaryDecodeBenchmark-jdk25-results.txt | 36 ++++++-------
.../ParquetDictionaryDecodeBenchmark-results.txt | 36 ++++++-------
.../datasources/parquet/ParquetVectorUpdater.java | 43 ++++++++++++++--
.../parquet/ParquetVectorUpdaterFactory.java | 60 ++++++++++++++++++++++
5 files changed, 152 insertions(+), 59 deletions(-)
diff --git
a/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-jdk21-results.txt
b/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-jdk21-results.txt
index 041372e7f0af..bca8e062ee23 100644
--- a/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-jdk21-results.txt
+++ b/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-jdk21-results.txt
@@ -6,12 +6,12 @@ OpenJDK 64-Bit Server VM 21.0.11+10-LTS on Linux
6.17.0-1018-azure
AMD EPYC 9V74 80-Core Processor
Dictionary Decode (no nulls): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
------------------------------------------------------------------------------------------------------------------------
-IntegerUpdater 6 6
0 177.6 5.6 1.0X
-LongUpdater 6 6
0 176.4 5.7 1.0X
-FloatUpdater 6 6
0 178.3 5.6 1.0X
-DoubleUpdater 6 6
0 177.2 5.6 1.0X
-IntegerToLongUpdater (INT32 -> Long) 6 6
0 175.8 5.7 1.0X
-FloatToDoubleUpdater (FLOAT -> Double) 6 6
0 172.2 5.8 1.0X
+IntegerUpdater 4 4
0 288.3 3.5 1.0X
+LongUpdater 4 4
0 285.4 3.5 1.0X
+FloatUpdater 4 4
0 287.4 3.5 1.0X
+DoubleUpdater 4 4
0 286.5 3.5 1.0X
+IntegerToLongUpdater (INT32 -> Long) 4 4
0 281.6 3.6 1.0X
+FloatToDoubleUpdater (FLOAT -> Double) 4 4
0 268.8 3.7 0.9X
================================================================================================
@@ -22,12 +22,12 @@ OpenJDK 64-Bit Server VM 21.0.11+10-LTS on Linux
6.17.0-1018-azure
AMD EPYC 9V74 80-Core Processor
Dictionary Decode (10% nulls): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
------------------------------------------------------------------------------------------------------------------------
-IntegerUpdater 7 7
0 159.9 6.3 1.0X
-LongUpdater 7 7
0 158.4 6.3 1.0X
-FloatUpdater 7 7
0 159.9 6.3 1.0X
-DoubleUpdater 7 7
0 159.8 6.3 1.0X
-IntegerToLongUpdater (INT32 -> Long) 7 7
0 160.4 6.2 1.0X
-FloatToDoubleUpdater (FLOAT -> Double) 7 7
0 157.0 6.4 1.0X
+IntegerUpdater 5 5
0 201.7 5.0 1.0X
+LongUpdater 5 5
0 202.2 4.9 1.0X
+FloatUpdater 5 5
0 203.9 4.9 1.0X
+DoubleUpdater 5 5
0 198.9 5.0 1.0X
+IntegerToLongUpdater (INT32 -> Long) 5 5
0 201.6 5.0 1.0X
+FloatToDoubleUpdater (FLOAT -> Double) 5 5
0 203.3 4.9 1.0X
================================================================================================
@@ -38,11 +38,11 @@ OpenJDK 64-Bit Server VM 21.0.11+10-LTS on Linux
6.17.0-1018-azure
AMD EPYC 9V74 80-Core Processor
Dictionary Decode (50% nulls): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
------------------------------------------------------------------------------------------------------------------------
-IntegerUpdater 9 9
0 113.2 8.8 1.0X
-LongUpdater 9 9
0 117.3 8.5 1.0X
-FloatUpdater 9 9
0 117.7 8.5 1.0X
-DoubleUpdater 9 9
0 117.4 8.5 1.0X
-IntegerToLongUpdater (INT32 -> Long) 9 9
0 113.5 8.8 1.0X
-FloatToDoubleUpdater (FLOAT -> Double) 9 9
0 117.6 8.5 1.0X
+IntegerUpdater 7 7
0 141.9 7.0 1.0X
+LongUpdater 7 7
0 147.2 6.8 1.0X
+FloatUpdater 7 7
0 147.8 6.8 1.0X
+DoubleUpdater 7 7
0 147.6 6.8 1.0X
+IntegerToLongUpdater (INT32 -> Long) 7 7
0 142.8 7.0 1.0X
+FloatToDoubleUpdater (FLOAT -> Double) 7 7
0 147.5 6.8 1.0X
diff --git
a/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-jdk25-results.txt
b/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-jdk25-results.txt
index 538cc8c3445b..7f342b50ac4d 100644
--- a/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-jdk25-results.txt
+++ b/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-jdk25-results.txt
@@ -6,12 +6,12 @@ OpenJDK 64-Bit Server VM 25.0.3+9-LTS on Linux
6.17.0-1018-azure
AMD EPYC 9V74 80-Core Processor
Dictionary Decode (no nulls): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
------------------------------------------------------------------------------------------------------------------------
-IntegerUpdater 6 6
0 179.1 5.6 1.0X
-LongUpdater 6 6
0 178.6 5.6 1.0X
-FloatUpdater 6 6
0 178.1 5.6 1.0X
-DoubleUpdater 6 6
0 177.5 5.6 1.0X
-IntegerToLongUpdater (INT32 -> Long) 6 6
0 175.1 5.7 1.0X
-FloatToDoubleUpdater (FLOAT -> Double) 6 6
0 178.8 5.6 1.0X
+IntegerUpdater 5 5
0 222.6 4.5 1.0X
+LongUpdater 5 5
0 221.1 4.5 1.0X
+FloatUpdater 5 5
0 222.9 4.5 1.0X
+DoubleUpdater 5 5
0 221.7 4.5 1.0X
+IntegerToLongUpdater (INT32 -> Long) 5 5
0 218.9 4.6 1.0X
+FloatToDoubleUpdater (FLOAT -> Double) 5 5
0 222.2 4.5 1.0X
================================================================================================
@@ -22,12 +22,12 @@ OpenJDK 64-Bit Server VM 25.0.3+9-LTS on Linux
6.17.0-1018-azure
AMD EPYC 9V74 80-Core Processor
Dictionary Decode (10% nulls): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
------------------------------------------------------------------------------------------------------------------------
-IntegerUpdater 7 7
0 159.0 6.3 1.0X
-LongUpdater 7 7
0 159.3 6.3 1.0X
-FloatUpdater 7 7
0 158.6 6.3 1.0X
-DoubleUpdater 7 7
0 158.2 6.3 1.0X
-IntegerToLongUpdater (INT32 -> Long) 7 7
0 158.6 6.3 1.0X
-FloatToDoubleUpdater (FLOAT -> Double) 7 7
0 159.2 6.3 1.0X
+IntegerUpdater 7 7
0 156.7 6.4 1.0X
+LongUpdater 7 7
0 157.1 6.4 1.0X
+FloatUpdater 7 7
0 154.1 6.5 1.0X
+DoubleUpdater 7 7
0 157.9 6.3 1.0X
+IntegerToLongUpdater (INT32 -> Long) 7 7
0 157.2 6.4 1.0X
+FloatToDoubleUpdater (FLOAT -> Double) 7 7
0 157.9 6.3 1.0X
================================================================================================
@@ -38,11 +38,11 @@ OpenJDK 64-Bit Server VM 25.0.3+9-LTS on Linux
6.17.0-1018-azure
AMD EPYC 9V74 80-Core Processor
Dictionary Decode (50% nulls): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
------------------------------------------------------------------------------------------------------------------------
-IntegerUpdater 9 9
0 116.4 8.6 1.0X
-LongUpdater 9 9
0 111.4 9.0 1.0X
-FloatUpdater 9 9
0 116.4 8.6 1.0X
-DoubleUpdater 9 9
0 116.6 8.6 1.0X
-IntegerToLongUpdater (INT32 -> Long) 9 9
0 114.0 8.8 1.0X
-FloatToDoubleUpdater (FLOAT -> Double) 9 9
0 116.2 8.6 1.0X
+IntegerUpdater 9 9
0 114.9 8.7 1.0X
+LongUpdater 9 9
0 114.8 8.7 1.0X
+FloatUpdater 9 9
0 114.6 8.7 1.0X
+DoubleUpdater 9 9
0 114.5 8.7 1.0X
+IntegerToLongUpdater (INT32 -> Long) 9 9
0 115.8 8.6 1.0X
+FloatToDoubleUpdater (FLOAT -> Double) 9 9
0 114.9 8.7 1.0X
diff --git a/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-results.txt
b/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-results.txt
index c43127858a13..53dcf356ec72 100644
--- a/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-results.txt
+++ b/sql/core/benchmarks/ParquetDictionaryDecodeBenchmark-results.txt
@@ -6,12 +6,12 @@ OpenJDK 64-Bit Server VM 17.0.19+10-LTS on Linux
6.17.0-1018-azure
AMD EPYC 9V74 80-Core Processor
Dictionary Decode (no nulls): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
------------------------------------------------------------------------------------------------------------------------
-IntegerUpdater 6 6
0 186.7 5.4 1.0X
-LongUpdater 6 6
0 185.1 5.4 1.0X
-FloatUpdater 6 6
0 188.6 5.3 1.0X
-DoubleUpdater 6 6
0 187.6 5.3 1.0X
-IntegerToLongUpdater (INT32 -> Long) 6 6
0 184.4 5.4 1.0X
-FloatToDoubleUpdater (FLOAT -> Double) 6 6
0 187.3 5.3 1.0X
+IntegerUpdater 5 5
0 227.6 4.4 1.0X
+LongUpdater 5 5
0 224.1 4.5 1.0X
+FloatUpdater 5 5
0 229.7 4.4 1.0X
+DoubleUpdater 5 5
0 228.2 4.4 1.0X
+IntegerToLongUpdater (INT32 -> Long) 5 5
0 224.1 4.5 1.0X
+FloatToDoubleUpdater (FLOAT -> Double) 5 5
0 227.8 4.4 1.0X
================================================================================================
@@ -22,12 +22,12 @@ OpenJDK 64-Bit Server VM 17.0.19+10-LTS on Linux
6.17.0-1018-azure
AMD EPYC 9V74 80-Core Processor
Dictionary Decode (10% nulls): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
------------------------------------------------------------------------------------------------------------------------
-IntegerUpdater 6 6
0 164.8 6.1 1.0X
-LongUpdater 6 6
0 165.7 6.0 1.0X
-FloatUpdater 6 6
0 166.1 6.0 1.0X
-DoubleUpdater 6 6
0 165.7 6.0 1.0X
-IntegerToLongUpdater (INT32 -> Long) 6 6
0 165.7 6.0 1.0X
-FloatToDoubleUpdater (FLOAT -> Double) 6 6
0 165.7 6.0 1.0X
+IntegerUpdater 6 6
0 164.2 6.1 1.0X
+LongUpdater 7 7
0 159.4 6.3 1.0X
+FloatUpdater 6 6
0 165.9 6.0 1.0X
+DoubleUpdater 6 6
0 165.2 6.1 1.0X
+IntegerToLongUpdater (INT32 -> Long) 6 6
0 163.1 6.1 1.0X
+FloatToDoubleUpdater (FLOAT -> Double) 6 6
0 163.2 6.1 1.0X
================================================================================================
@@ -38,11 +38,11 @@ OpenJDK 64-Bit Server VM 17.0.19+10-LTS on Linux
6.17.0-1018-azure
AMD EPYC 9V74 80-Core Processor
Dictionary Decode (50% nulls): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
------------------------------------------------------------------------------------------------------------------------
-IntegerUpdater 9 9
0 117.7 8.5 1.0X
-LongUpdater 9 9
0 116.2 8.6 1.0X
-FloatUpdater 9 9
0 117.7 8.5 1.0X
-DoubleUpdater 9 9
0 117.6 8.5 1.0X
-IntegerToLongUpdater (INT32 -> Long) 9 9
0 118.6 8.4 1.0X
-FloatToDoubleUpdater (FLOAT -> Double) 9 9
0 117.4 8.5 1.0X
+IntegerUpdater 9 9
0 117.0 8.5 1.0X
+LongUpdater 9 9
0 116.8 8.6 1.0X
+FloatUpdater 9 9
0 117.1 8.5 1.0X
+DoubleUpdater 9 9
0 116.9 8.6 1.0X
+IntegerToLongUpdater (INT32 -> Long) 9 9
0 117.1 8.5 1.0X
+FloatToDoubleUpdater (FLOAT -> Double) 9 9
0 117.0 8.5 1.0X
diff --git
a/sql/core/src/main/java/org/apache/spark/sql/execution/datasources/parquet/ParquetVectorUpdater.java
b/sql/core/src/main/java/org/apache/spark/sql/execution/datasources/parquet/ParquetVectorUpdater.java
index 9bb852987e65..0774b4ad3475 100644
---
a/sql/core/src/main/java/org/apache/spark/sql/execution/datasources/parquet/ParquetVectorUpdater.java
+++
b/sql/core/src/main/java/org/apache/spark/sql/execution/datasources/parquet/ParquetVectorUpdater.java
@@ -58,6 +58,14 @@ public interface ParquetVectorUpdater {
* should have already been filled, and fills the non-null slots using
dictionary IDs from
* `dictionaryIds`, together with Parquet `dictionary`.
*
+ * <p>The default implementation delegates to {@link #decodeBatch}, which
calls
+ * {@link #decodeSingleDictionaryId} per non-null element. Because this
default method's
+ * bytecode is shared by every implementor, C2 sees a megamorphic call site
for
+ * {@code decodeSingleDictionaryId} and cannot inline the per-element
decode. Hot-path
+ * updaters (e.g. {@code IntegerUpdater}) override this method with an
identical one-line
+ * delegation to {@code decodeBatch}; the per-class bytecode gives C2 a
monomorphic call
+ * site, enabling full inlining of the decode expression.
+ *
* @param total total number slots to process in `values`
* @param offset starting offset in `values`
* @param values destination value vector
@@ -70,11 +78,7 @@ public interface ParquetVectorUpdater {
WritableColumnVector values,
WritableColumnVector dictionaryIds,
Dictionary dictionary) {
- for (int i = offset; i < offset + total; i++) {
- if (!values.isNullAt(i)) {
- decodeSingleDictionaryId(i, values, dictionaryIds, dictionary);
- }
- }
+ decodeBatch(total, offset, values, dictionaryIds, dictionary, this);
}
/**
@@ -91,4 +95,33 @@ public interface ParquetVectorUpdater {
WritableColumnVector values,
WritableColumnVector dictionaryIds,
Dictionary dictionary);
+
+ /**
+ * Batch-decodes dictionary IDs with a no-null fast path.
+ *
+ * <p>When {@code values.hasNull()} is false the per-element {@code
isNullAt} check is
+ * skipped entirely. The loop body calls {@code
updater.decodeSingleDictionaryId}, which
+ * C2 can devirtualize and inline when the {@code updater} reference has a
known concrete
+ * type -- i.e. when this helper is called from a per-class override of
+ * {@link #decodeDictionaryIds} rather than from the shared default method.
+ */
+ static void decodeBatch(
+ int total,
+ int offset,
+ WritableColumnVector values,
+ WritableColumnVector dictionaryIds,
+ Dictionary dictionary,
+ ParquetVectorUpdater updater) {
+ if (!values.hasNull()) {
+ for (int i = offset; i < offset + total; i++) {
+ updater.decodeSingleDictionaryId(i, values, dictionaryIds, dictionary);
+ }
+ } else {
+ for (int i = offset; i < offset + total; i++) {
+ if (!values.isNullAt(i)) {
+ updater.decodeSingleDictionaryId(i, values, dictionaryIds,
dictionary);
+ }
+ }
+ }
+ }
}
diff --git
a/sql/core/src/main/java/org/apache/spark/sql/execution/datasources/parquet/ParquetVectorUpdaterFactory.java
b/sql/core/src/main/java/org/apache/spark/sql/execution/datasources/parquet/ParquetVectorUpdaterFactory.java
index 35936dc80e88..4fa4183e411c 100644
---
a/sql/core/src/main/java/org/apache/spark/sql/execution/datasources/parquet/ParquetVectorUpdaterFactory.java
+++
b/sql/core/src/main/java/org/apache/spark/sql/execution/datasources/parquet/ParquetVectorUpdaterFactory.java
@@ -355,6 +355,16 @@ public class ParquetVectorUpdaterFactory {
values.putInt(offset, valuesReader.readInteger());
}
+ @Override
+ public void decodeDictionaryIds(
+ int total,
+ int offset,
+ WritableColumnVector values,
+ WritableColumnVector dictionaryIds,
+ Dictionary dictionary) {
+ ParquetVectorUpdater.decodeBatch(total, offset, values, dictionaryIds,
dictionary, this);
+ }
+
@Override
public void decodeSingleDictionaryId(
int offset,
@@ -388,6 +398,16 @@ public class ParquetVectorUpdaterFactory {
values.putLong(offset, valuesReader.readInteger());
}
+ @Override
+ public void decodeDictionaryIds(
+ int total,
+ int offset,
+ WritableColumnVector values,
+ WritableColumnVector dictionaryIds,
+ Dictionary dictionary) {
+ ParquetVectorUpdater.decodeBatch(total, offset, values, dictionaryIds,
dictionary, this);
+ }
+
@Override
public void decodeSingleDictionaryId(
int offset,
@@ -680,6 +700,16 @@ public class ParquetVectorUpdaterFactory {
values.putLong(offset, valuesReader.readLong());
}
+ @Override
+ public void decodeDictionaryIds(
+ int total,
+ int offset,
+ WritableColumnVector values,
+ WritableColumnVector dictionaryIds,
+ Dictionary dictionary) {
+ ParquetVectorUpdater.decodeBatch(total, offset, values, dictionaryIds,
dictionary, this);
+ }
+
@Override
public void decodeSingleDictionaryId(
int offset,
@@ -985,6 +1015,16 @@ public class ParquetVectorUpdaterFactory {
values.putFloat(offset, valuesReader.readFloat());
}
+ @Override
+ public void decodeDictionaryIds(
+ int total,
+ int offset,
+ WritableColumnVector values,
+ WritableColumnVector dictionaryIds,
+ Dictionary dictionary) {
+ ParquetVectorUpdater.decodeBatch(total, offset, values, dictionaryIds,
dictionary, this);
+ }
+
@Override
public void decodeSingleDictionaryId(
int offset,
@@ -1018,6 +1058,16 @@ public class ParquetVectorUpdaterFactory {
values.putDouble(offset, valuesReader.readFloat());
}
+ @Override
+ public void decodeDictionaryIds(
+ int total,
+ int offset,
+ WritableColumnVector values,
+ WritableColumnVector dictionaryIds,
+ Dictionary dictionary) {
+ ParquetVectorUpdater.decodeBatch(total, offset, values, dictionaryIds,
dictionary, this);
+ }
+
@Override
public void decodeSingleDictionaryId(
int offset,
@@ -1051,6 +1101,16 @@ public class ParquetVectorUpdaterFactory {
values.putDouble(offset, valuesReader.readDouble());
}
+ @Override
+ public void decodeDictionaryIds(
+ int total,
+ int offset,
+ WritableColumnVector values,
+ WritableColumnVector dictionaryIds,
+ Dictionary dictionary) {
+ ParquetVectorUpdater.decodeBatch(total, offset, values, dictionaryIds,
dictionary, this);
+ }
+
@Override
public void decodeSingleDictionaryId(
int offset,
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]