You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@paimon.apache.org by lz...@apache.org on 2026/10/08 04:30:04 UTC

(paimon) branch master updated: [python] Skip redundant null masks in nested projections (#10421)

This is an automated email from the ASF dual-hosted git repository.

JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git


The following commit(s) were added to refs/heads/master by this push:
     new fe0c733455 [python] Skip redundant null masks in nested projections (#10421)
fe0c733455 is described below

commit fe0c733455febf4cf2f6c14baa8290510dcd8e7a
Author: XiaoHongbo <xi...@alibaba-inc.com>
AuthorDate: Thu Oct 8 12:29:57 2026 +0800

    [python] Skip redundant null masks in nested projections (#10421)
---
 paimon-python/pypaimon/read/read_type.py         |  3 ++-
 paimon-python/pypaimon/tests/native_read_test.py | 27 +++++++++++++++++++++++-
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/paimon-python/pypaimon/read/read_type.py b/paimon-python/pypaimon/read/read_type.py
index 70b4e78e49..f656e09abe 100644
--- a/paimon-python/pypaimon/read/read_type.py
+++ b/paimon-python/pypaimon/read/read_type.py
@@ -165,7 +165,8 @@ def extract_array(batch, path):
     parents = []
     for name in path[1:]:
         if pa.types.is_struct(array.type):
-            parents.append(pc.is_null(array))
+            if array.null_count:
+                parents.append(pc.is_null(array))
             array = array.field(name)
         elif pa.types.is_map(array.type):
             array = pc.map_lookup(array, name, 'first')
diff --git a/paimon-python/pypaimon/tests/native_read_test.py b/paimon-python/pypaimon/tests/native_read_test.py
index 46a568515f..3e117cb0a0 100644
--- a/paimon-python/pypaimon/tests/native_read_test.py
+++ b/paimon-python/pypaimon/tests/native_read_test.py
@@ -25,7 +25,8 @@ import pytest
 
 from pypaimon.read.query_auth_split import QueryAuthSplit
 from pypaimon.read.table_read import TableRead
-from pypaimon.read.read_type import OutputProjection, project_read_type, reader_adapter
+from pypaimon.read.read_type import (
+    OutputProjection, extract_array, project_read_type, reader_adapter)
 from pypaimon.read.variant_read_type import with_variant_extractions
 from pypaimon.schema.data_types import AtomicType, DataField, MapType, RowType
 
@@ -81,6 +82,30 @@ def _id_batch(values):
         [pa.array(values, type=pa.int32())], names=['id'])
 
 
+def test_extract_array_skips_mask_for_valid_parent():
+    parent = pa.array([
+        {'value': 1},
+        {'value': None},
+        {'value': 3},
+    ], type=pa.struct([('value', pa.int32())]))
+    batch = pa.record_batch([parent.slice(1)], names=['payload'])
+
+    with patch('pypaimon.read.read_type.pc.is_null',
+               side_effect=AssertionError('unneeded parent null mask')):
+        assert extract_array(batch, ['payload', 'value']).to_pylist() == [None, 3]
+
+
+def test_extract_array_preserves_null_parent():
+    parent = pa.array([
+        {'value': 1},
+        None,
+        {'value': 3},
+    ], type=pa.struct([('value', pa.int32())]))
+    batch = pa.record_batch([parent], names=['payload'])
+
+    assert extract_array(batch, ['payload', 'value']).to_pylist() == [1, None, 3]
+
+
 def test_native_read_falls_back_before_opening_primary_file_with_row_sidecar():
     read = _table_read()
     split = _Split()