MCPcopy Create free account
hub / github.com/apache/datafusion / general_except

Function general_except

datafusion/functions-nested/src/except.rs:165–239  ·  view source on GitHub ↗
(
    l: &GenericListArray<OffsetSize>,
    r: &GenericListArray<OffsetSize>,
    field: &FieldRef,
)

Source from the content-addressed store, hash-verified

163}
164
165fn general_except<OffsetSize: OffsetSizeTrait>(
166 l: &GenericListArray<OffsetSize>,
167 r: &GenericListArray<OffsetSize>,
168 field: &FieldRef,
169) -> Result<GenericListArray<OffsetSize>> {
170 let converter = RowConverter::new(vec![SortField::new(l.value_type())])?;
171
172 // Only convert the visible portion of the values array. For sliced
173 // ListArrays, values() returns the full underlying array but only
174 // elements between the first and last offset are referenced.
175 let l_first = l.offsets()[0].as_usize();
176 let l_len = l.offsets()[l.len()].as_usize() - l_first;
177 let l_values = converter.convert_columns(&[l.values().slice(l_first, l_len)])?;
178
179 let r_first = r.offsets()[0].as_usize();
180 let r_len = r.offsets()[r.len()].as_usize() - r_first;
181 let r_values = converter.convert_columns(&[r.values().slice(r_first, r_len)])?;
182
183 let mut offsets = Vec::<OffsetSize>::with_capacity(l.len() + 1);
184 offsets.push(OffsetSize::usize_as(0));
185
186 let mut indices: Vec<usize> = Vec::with_capacity(l_values.num_rows());
187 let mut dedup = HashSet::new();
188
189 let nulls = NullBuffer::union(l.nulls(), r.nulls());
190
191 let l_offsets_iter = l.offsets().iter().tuple_windows();
192 let r_offsets_iter = r.offsets().iter().tuple_windows();
193 for (list_index, ((l_start, l_end), (r_start, r_end))) in
194 l_offsets_iter.zip(r_offsets_iter).enumerate()
195 {
196 if nulls
197 .as_ref()
198 .is_some_and(|nulls| nulls.is_null(list_index))
199 {
200 offsets.push(OffsetSize::usize_as(indices.len()));
201 continue;
202 }
203
204 for element_index in r_start.as_usize() - r_first..r_end.as_usize() - r_first {
205 let right_row = r_values.row(element_index);
206 dedup.insert(right_row);
207 }
208 for element_index in l_start.as_usize() - l_first..l_end.as_usize() - l_first {
209 let left_row = l_values.row(element_index);
210 if dedup.insert(left_row) {
211 indices.push(element_index + l_first);
212 }
213 }
214
215 offsets.push(OffsetSize::usize_as(indices.len()));
216 dedup.clear();
217 }
218
219 // Gather distinct left-side values by index.
220 // Use UInt64Array for LargeList to support values arrays exceeding u32::MAX.
221 let values = if indices.is_empty() {
222 arrow::array::new_empty_array(&l.value_type())

Callers

nothing calls this directly

Calls 15

newFunction · 0.85
offsetsMethod · 0.80
sliceMethod · 0.80
rowMethod · 0.80
value_typeMethod · 0.80
unionFunction · 0.50
as_usizeMethod · 0.45
lenMethod · 0.45
valuesMethod · 0.45
pushMethod · 0.45
nullsMethod · 0.45
iterMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…