1+ package org .apache .gluten .substrait .rel ;
2+
3+ import io .substrait .proto .ReadRel ;
4+ import org .apache .iceberg .DeleteFile ;
5+ import org .apache .iceberg .FileContent ;
6+ import org .apache .iceberg .FileFormat ;
7+ import org .apache .iceberg .StructLike ;
8+ import org .junit .Assert ;
9+ import org .junit .Test ;
10+
11+ import java .nio .ByteBuffer ;
12+ import java .util .Base64 ;
13+ import java .util .Collections ;
14+ import java .util .List ;
15+ import java .util .Map ;
16+
17+ public class IcebergLocalFilesNodeBoundsTest {
18+ private static final int ICEBERG_POS_FIELD_ID = 2147483545 ;
19+
20+ @ Test
21+ public void serializesDeleteFileLowerAndUpperBounds () {
22+ byte [] lowerBytes = new byte [] {1 , 2 , 3 , 4 };
23+ byte [] upperBytes = new byte [] {5 , 6 , 7 , 8 };
24+
25+ FakeDeleteFile deleteFile =
26+ new FakeDeleteFile (
27+ FileContent .POSITION_DELETES ,
28+ FileFormat .PARQUET ,
29+ "/tmp/delete.parquet" ,
30+ 2L ,
31+ 123L ,
32+ Collections .emptyList (),
33+ Collections .singletonMap (ICEBERG_POS_FIELD_ID , ByteBuffer .wrap (lowerBytes )),
34+ Collections .singletonMap (ICEBERG_POS_FIELD_ID , ByteBuffer .wrap (upperBytes )),
35+ null );
36+ IcebergLocalFilesNode node =
37+ new IcebergLocalFilesNode (
38+ 0 ,
39+ Collections .singletonList ("/tmp/data.parquet" ),
40+ Collections .singletonList (0L ),
41+ Collections .singletonList (100L ),
42+ Collections .singletonList (Collections .emptyMap ()),
43+ LocalFilesNode .ReadFileFormat .ParquetReadFormat ,
44+ Collections .emptyList (),
45+ Collections .singletonList (Collections .singletonList (deleteFile )),
46+ Collections .singletonList (Collections .emptyMap ()));
47+
48+ ReadRel .LocalFiles .FileOrFiles .Builder fileBuilder =
49+ ReadRel .LocalFiles .FileOrFiles .newBuilder ();
50+
51+ node .processFileBuilder (fileBuilder , 0 );
52+
53+ ReadRel .LocalFiles .FileOrFiles .IcebergReadOptions .DeleteFile actualDelete =
54+ fileBuilder .getIceberg ().getDeleteFiles (0 );
55+
56+ Assert .assertEquals (1 , actualDelete .getLowerBounds ().getKeyValuesCount ());
57+ Assert .assertEquals (
58+ ICEBERG_POS_FIELD_ID ,
59+ actualDelete .getLowerBounds ().getKeyValues (0 ).getKey ());
60+ Assert .assertEquals (
61+ Base64 .getEncoder ().encodeToString (lowerBytes ),
62+ actualDelete .getLowerBounds ().getKeyValues (0 ).getValue ());
63+
64+ Assert .assertEquals (1 , actualDelete .getUpperBounds ().getKeyValuesCount ());
65+ Assert .assertEquals (
66+ ICEBERG_POS_FIELD_ID ,
67+ actualDelete .getUpperBounds ().getKeyValues (0 ).getKey ());
68+ Assert .assertEquals (
69+ Base64 .getEncoder ().encodeToString (upperBytes ),
70+ actualDelete .getUpperBounds ().getKeyValues (0 ).getValue ());
71+ }
72+
73+ private static final class FakeDeleteFile implements DeleteFile {
74+ private final FileContent content ;
75+ private final FileFormat format ;
76+ private final String path ;
77+ private final long recordCount ;
78+ private final long fileSizeInBytes ;
79+ private final List <Integer > equalityFieldIds ;
80+ private final Map <Integer , ByteBuffer > lowerBounds ;
81+ private final Map <Integer , ByteBuffer > upperBounds ;
82+ private final Long dataSequenceNumber ;
83+
84+ private FakeDeleteFile (
85+ FileContent content ,
86+ FileFormat format ,
87+ String path ,
88+ long recordCount ,
89+ long fileSizeInBytes ,
90+ List <Integer > equalityFieldIds ,
91+ Map <Integer , ByteBuffer > lowerBounds ,
92+ Map <Integer , ByteBuffer > upperBounds ,
93+ Long dataSequenceNumber ) {
94+ this .content = content ;
95+ this .format = format ;
96+ this .path = path ;
97+ this .recordCount = recordCount ;
98+ this .fileSizeInBytes = fileSizeInBytes ;
99+ this .equalityFieldIds = equalityFieldIds ;
100+ this .lowerBounds = lowerBounds ;
101+ this .upperBounds = upperBounds ;
102+ this .dataSequenceNumber = dataSequenceNumber ;
103+ }
104+
105+ @ Override
106+ public Long pos () {
107+ return 0L ;
108+ }
109+
110+ @ Override
111+ public int specId () {
112+ return 0 ;
113+ }
114+
115+ @ Override
116+ public FileContent content () {
117+ return content ;
118+ }
119+
120+ @ Override
121+ public CharSequence path () {
122+ return path ;
123+ }
124+
125+ @ Override
126+ public FileFormat format () {
127+ return format ;
128+ }
129+
130+ @ Override
131+ public StructLike partition () {
132+ return null ;
133+ }
134+
135+ @ Override
136+ public long recordCount () {
137+ return recordCount ;
138+ }
139+
140+ @ Override
141+ public long fileSizeInBytes () {
142+ return fileSizeInBytes ;
143+ }
144+
145+ @ Override
146+ public Map <Integer , Long > columnSizes () {
147+ return null ;
148+ }
149+
150+ @ Override
151+ public Map <Integer , Long > valueCounts () {
152+ return null ;
153+ }
154+
155+ @ Override
156+ public Map <Integer , Long > nullValueCounts () {
157+ return null ;
158+ }
159+
160+ @ Override
161+ public Map <Integer , Long > nanValueCounts () {
162+ return null ;
163+ }
164+
165+ @ Override
166+ public Map <Integer , ByteBuffer > lowerBounds () {
167+ return lowerBounds ;
168+ }
169+
170+ @ Override
171+ public Map <Integer , ByteBuffer > upperBounds () {
172+ return upperBounds ;
173+ }
174+
175+ @ Override
176+ public ByteBuffer keyMetadata () {
177+ return null ;
178+ }
179+
180+ @ Override
181+ public List <Integer > equalityFieldIds () {
182+ return equalityFieldIds ;
183+ }
184+
185+ @ Override
186+ public Long dataSequenceNumber () {
187+ return dataSequenceNumber ;
188+ }
189+
190+ @ Override
191+ public DeleteFile copy () {
192+ return this ;
193+ }
194+
195+ @ Override
196+ public DeleteFile copyWithoutStats () {
197+ return this ;
198+ }
199+ }
200+ }
0 commit comments