Skip to main content

risingwave_common/array/
list_array.rs

1// Copyright 2022 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::borrow::Cow;
16use std::cmp::Ordering;
17use std::fmt::{self, Debug, Display};
18use std::future::Future;
19use std::mem::{ManuallyDrop, size_of};
20
21use bytes::{Buf, BufMut};
22use itertools::Itertools;
23use risingwave_common_estimate_size::EstimateSize;
24use risingwave_pb::data::{ListArrayData, PbArray, PbArrayType};
25use serde::{Deserialize, Serializer};
26use thiserror_ext::AsReport;
27
28use super::{
29    Array, ArrayBuilder, ArrayBuilderImpl, ArrayImpl, ArrayResult, BoolArray, PrimitiveArray,
30    PrimitiveArrayItemType, RowRef, Utf8Array,
31};
32use crate::bitmap::{Bitmap, BitmapBuilder};
33use crate::row::Row;
34use crate::types::{
35    DataType, Datum, DatumRef, DefaultOrd, ListType, Scalar, ScalarImpl, ScalarRef, ScalarRefImpl,
36    ToDatumRef, ToText, hash_datum,
37};
38use crate::util::memcmp_encoding;
39use crate::util::value_encoding::estimate_serialize_datum_size;
40
41#[derive(Debug, Clone, EstimateSize)]
42pub struct ListArrayBuilder {
43    bitmap: BitmapBuilder,
44    offsets: Vec<u32>,
45    value: Box<ArrayBuilderImpl>,
46}
47
48impl ArrayBuilder for ListArrayBuilder {
49    type ArrayType = ListArray;
50
51    #[cfg(not(test))]
52    fn new(_capacity: usize) -> Self {
53        panic!("please use `ListArrayBuilder::with_type` instead");
54    }
55
56    #[cfg(test)]
57    fn new(capacity: usize) -> Self {
58        // TODO: deprecate this
59        Self::with_type(
60            capacity,
61            // Default datatype
62            DataType::Int16.list(),
63        )
64    }
65
66    fn with_type(capacity: usize, ty: DataType) -> Self {
67        let DataType::List(list_ty) = ty else {
68            panic!("data type must be DataType::List");
69        };
70        let mut offsets = Vec::with_capacity(capacity + 1);
71        offsets.push(0);
72        Self {
73            bitmap: BitmapBuilder::with_capacity(capacity),
74            offsets,
75            value: Box::new(list_ty.elem().create_array_builder(capacity)),
76        }
77    }
78
79    fn append_n(&mut self, n: usize, value: Option<ListRef<'_>>) {
80        match value {
81            None => {
82                self.bitmap.append_n(n, false);
83                let last = *self.offsets.last().unwrap();
84                for _ in 0..n {
85                    self.offsets.push(last);
86                }
87            }
88            Some(v) => {
89                self.bitmap.append_n(n, true);
90                for _ in 0..n {
91                    let last = *self.offsets.last().unwrap();
92                    let elems = v.iter();
93                    self.offsets.push(
94                        last.checked_add(elems.len() as u32)
95                            .expect("offset overflow"),
96                    );
97                    for elem in elems {
98                        self.value.append(elem);
99                    }
100                }
101            }
102        }
103    }
104
105    fn append_array(&mut self, other: &ListArray) {
106        self.bitmap.append_bitmap(&other.bitmap);
107        let last = *self.offsets.last().unwrap();
108        self.offsets
109            .append(&mut other.offsets[1..].iter().map(|o| *o + last).collect());
110        self.value.append_array(&other.value);
111    }
112
113    fn pop(&mut self) -> Option<()> {
114        self.bitmap.pop()?;
115        let start = self.offsets.pop().unwrap();
116        let end = *self.offsets.last().unwrap();
117        for _ in end..start {
118            self.value.pop().unwrap();
119        }
120        Some(())
121    }
122
123    fn len(&self) -> usize {
124        self.bitmap.len()
125    }
126
127    fn finish(self) -> ListArray {
128        ListArray {
129            bitmap: self.bitmap.finish(),
130            offsets: self.offsets.into(),
131            value: Box::new(self.value.finish()),
132        }
133    }
134}
135
136impl ListArrayBuilder {
137    pub fn append_row_ref(&mut self, row: RowRef<'_>) {
138        self.bitmap.append(true);
139        let last = *self.offsets.last().unwrap();
140        self.offsets
141            .push(last.checked_add(row.len() as u32).expect("offset overflow"));
142        for v in row.iter() {
143            self.value.append(v);
144        }
145    }
146
147    pub fn writer(&mut self) -> ListWriter<'_> {
148        ListWriter::new(self)
149    }
150}
151
152/// Each item of this `ListArray` is a `List<T>`, or called `T[]` (T array).
153///
154/// * As other arrays, there is a null bitmap, with `1` meaning nonnull and `0` meaning null.
155/// * As [`super::BytesArray`], there is an offsets `Vec` and a value `Array`. The value `Array` has
156///   all items concatenated, and the offsets `Vec` stores start and end indices into it for
157///   slicing. Effectively, the inner array is the flattened form, and `offsets.len() == n + 1`.
158///
159/// For example, `values (array[1]), (array[]::int[]), (null), (array[2, 3]);` stores an inner
160///  `I32Array` with `[1, 2, 3]`, along with offsets `[0, 1, 1, 1, 3]` and null bitmap `TTFT`.
161#[derive(Debug, Clone, PartialEq, Eq)]
162pub struct ListArray {
163    pub(super) bitmap: Bitmap,
164    pub(super) offsets: Box<[u32]>,
165    pub(super) value: Box<ArrayImpl>,
166}
167
168impl EstimateSize for ListArray {
169    fn estimated_heap_size(&self) -> usize {
170        self.bitmap.estimated_heap_size()
171            + self.offsets.len() * size_of::<u32>()
172            + self.value.estimated_size()
173    }
174}
175
176impl Array for ListArray {
177    type Builder = ListArrayBuilder;
178    type OwnedItem = ListValue;
179    type RefItem<'a> = ListRef<'a>;
180
181    unsafe fn raw_value_at_unchecked(&self, idx: usize) -> Self::RefItem<'_> {
182        unsafe {
183            ListRef {
184                array: &self.value,
185                start: *self.offsets.get_unchecked(idx),
186                end: *self.offsets.get_unchecked(idx + 1),
187            }
188        }
189    }
190
191    fn len(&self) -> usize {
192        self.bitmap.len()
193    }
194
195    fn to_protobuf(&self) -> PbArray {
196        let value = self.value.to_protobuf();
197        PbArray {
198            array_type: PbArrayType::List as i32,
199            struct_array_data: None,
200            list_array_data: Some(Box::new(ListArrayData {
201                offsets: self.offsets.to_vec(),
202                value: Some(Box::new(value)),
203                value_type: Some(self.value.data_type().to_protobuf()),
204                elem_size: None,
205            })),
206            null_bitmap: Some(self.bitmap.to_protobuf()),
207            values: vec![],
208        }
209    }
210
211    fn null_bitmap(&self) -> &Bitmap {
212        &self.bitmap
213    }
214
215    fn into_null_bitmap(self) -> Bitmap {
216        self.bitmap
217    }
218
219    fn set_bitmap(&mut self, bitmap: Bitmap) {
220        self.bitmap = bitmap;
221    }
222
223    fn data_type(&self) -> DataType {
224        DataType::list(self.value.data_type())
225    }
226}
227
228impl ListArray {
229    /// Flatten the list array into a single array.
230    ///
231    /// # Example
232    ///
233    /// ```text
234    /// [[1,2,3],NULL,[4,5]] => [1,2,3,4,5]
235    /// [[[1],[2]],[[3],[4]]] => [1,2,3,4]
236    /// ```
237    pub fn flatten(&self) -> ArrayImpl {
238        match &*self.value {
239            ArrayImpl::List(inner) => inner.flatten(),
240            a => a.clone(),
241        }
242    }
243
244    /// Return the inner array of the list array.
245    pub fn values(&self) -> &ArrayImpl {
246        &self.value
247    }
248
249    pub fn from_protobuf(array: &PbArray) -> ArrayResult<ArrayImpl> {
250        ensure!(
251            array.values.is_empty(),
252            "Must have no buffer in a list array"
253        );
254        debug_assert!(
255            (array.array_type == PbArrayType::List as i32)
256                || (array.array_type == PbArrayType::Map as i32),
257            "invalid array type for list: {}",
258            array.array_type
259        );
260        let bitmap: Bitmap = array.get_null_bitmap()?.into();
261        let array_data = array.get_list_array_data()?.to_owned();
262        let flatten_len = match array_data.offsets.last() {
263            Some(&n) => n as usize,
264            None => bail!("Must have at least one element in offsets"),
265        };
266        let value = ArrayImpl::from_protobuf(array_data.value.as_ref().unwrap(), flatten_len)?;
267        let arr = ListArray {
268            bitmap,
269            offsets: array_data.offsets.into(),
270            value: Box::new(value),
271        };
272        Ok(arr.into())
273    }
274
275    /// Apply the function on the underlying elements.
276    /// e.g. `map_inner([[1,2,3],NULL,[4,5]], DOUBLE) = [[2,4,6],NULL,[8,10]]`
277    pub fn map_inner_sync<E, F>(self, f: F) -> std::result::Result<ListArray, E>
278    where
279        F: FnOnce(ArrayImpl) -> std::result::Result<ArrayImpl, E>,
280    {
281        let new_value = (f)(*self.value)?;
282
283        Ok(Self {
284            offsets: self.offsets,
285            bitmap: self.bitmap,
286            value: Box::new(new_value),
287        })
288    }
289
290    /// Apply the async function on the underlying elements.
291    /// e.g. `map_inner([[1,2,3],NULL,[4,5]], DOUBLE) = [[2,4,6],NULL,[8,10]]`
292    pub async fn map_inner<E, Fut, F>(self, f: F) -> std::result::Result<ListArray, E>
293    where
294        F: FnOnce(ArrayImpl) -> Fut,
295        Fut: Future<Output = std::result::Result<ArrayImpl, E>>,
296    {
297        let new_value = (f)(*self.value).await?;
298
299        Ok(Self {
300            offsets: self.offsets,
301            bitmap: self.bitmap,
302            value: Box::new(new_value),
303        })
304    }
305
306    /// Returns the offsets of this list.
307    ///
308    /// # Example
309    /// ```text
310    /// list    = [[a, b, c], [], NULL, [d], [NULL, f]]
311    /// offsets = [0, 3, 3, 3, 4, 6]
312    /// ```
313    pub fn offsets(&self) -> &[u32] {
314        &self.offsets
315    }
316}
317
318impl<T, L> FromIterator<Option<L>> for ListArray
319where
320    T: PrimitiveArrayItemType,
321    L: IntoIterator<Item = T>,
322{
323    fn from_iter<I: IntoIterator<Item = Option<L>>>(iter: I) -> Self {
324        let iter = iter.into_iter();
325        let mut builder =
326            ListArrayBuilder::with_type(iter.size_hint().0, DataType::list(T::DATA_TYPE));
327        for v in iter {
328            match v {
329                None => builder.append(None),
330                Some(v) => {
331                    builder.append(Some(v.into_iter().collect::<ListValue>().as_scalar_ref()))
332                }
333            }
334        }
335        builder.finish()
336    }
337}
338
339impl FromIterator<ListValue> for ListArray {
340    fn from_iter<I: IntoIterator<Item = ListValue>>(iter: I) -> Self {
341        let mut iter = iter.into_iter();
342        let first = iter.next().expect("empty iterator");
343        let mut builder =
344            ListArrayBuilder::with_type(iter.size_hint().0, DataType::list(first.elem_type()));
345        builder.append(Some(first.as_scalar_ref()));
346        for v in iter {
347            builder.append(Some(v.as_scalar_ref()));
348        }
349        builder.finish()
350    }
351}
352
353#[derive(Clone, PartialEq, Eq, EstimateSize)]
354pub struct ListValue {
355    values: Box<ArrayImpl>,
356}
357
358impl Debug for ListValue {
359    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
360        self.as_scalar_ref().fmt(f)
361    }
362}
363
364impl Display for ListValue {
365    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
366        self.as_scalar_ref().write(f)
367    }
368}
369
370impl ListValue {
371    pub fn new(values: ArrayImpl) -> Self {
372        Self {
373            values: Box::new(values),
374        }
375    }
376
377    /// Convert this list into an [`Array`] of the element type.
378    pub fn into_array(self) -> ArrayImpl {
379        *self.values
380    }
381
382    /// Creates a new empty `ListValue` with the given element type.
383    pub fn empty(elem_type: &DataType) -> Self {
384        Self::new(elem_type.create_array_builder(0).finish())
385    }
386
387    /// Creates a new `ListValue` from an iterator of elements with the given element type.
388    pub fn from_datum_iter<T: ToDatumRef>(
389        elem_type: &DataType,
390        iter: impl IntoIterator<Item = T>,
391    ) -> Self {
392        let iter = iter.into_iter();
393        let mut builder = elem_type.create_array_builder(iter.size_hint().0);
394        for datum in iter {
395            builder.append(datum);
396        }
397        Self::new(builder.finish())
398    }
399
400    /// Returns the length of the list.
401    pub fn len(&self) -> usize {
402        self.values.len()
403    }
404
405    /// Returns `true` if the list has a length of 0.
406    pub fn is_empty(&self) -> bool {
407        self.values.is_empty()
408    }
409
410    /// Iterates over the elements of the list.
411    pub fn iter(&self) -> impl DoubleEndedIterator + ExactSizeIterator<Item = DatumRef<'_>> {
412        self.values.iter()
413    }
414
415    /// Get the element at the given index. Returns `None` if the index is out of bounds.
416    pub fn get(&self, index: usize) -> Option<DatumRef<'_>> {
417        if index < self.len() {
418            Some(self.values.value_at(index))
419        } else {
420            None
421        }
422    }
423
424    /// Returns the data type of the elements in the list.
425    pub fn elem_type(&self) -> DataType {
426        self.values.data_type()
427    }
428
429    pub fn memcmp_deserialize(
430        list_type: &ListType,
431        deserializer: &mut memcomparable::Deserializer<impl Buf>,
432    ) -> memcomparable::Result<Self> {
433        let elem_type = list_type.elem();
434
435        let bytes = serde_bytes::ByteBuf::deserialize(deserializer)?;
436        let mut inner_deserializer = memcomparable::Deserializer::new(bytes.as_slice());
437        let mut builder = elem_type.create_array_builder(0);
438        while inner_deserializer.has_remaining() {
439            builder.append(memcmp_encoding::deserialize_datum_in_composite(
440                elem_type,
441                &mut inner_deserializer,
442            )?)
443        }
444        Ok(Self::new(builder.finish()))
445    }
446
447    // Used to display ListValue in explain for better readibilty.
448    pub fn display_for_explain(&self) -> String {
449        // Example of ListValue display: ARRAY[1, 2, null]
450        format!(
451            "ARRAY[{}]",
452            self.iter()
453                .map(|v| {
454                    match v.as_ref() {
455                        None => "null".into(),
456                        Some(scalar) => scalar.to_text(),
457                    }
458                })
459                .format(", ")
460        )
461    }
462
463    /// Returns a mutable slice if the list is of type `int64[]`.
464    pub fn as_i64_mut_slice(&mut self) -> Option<&mut [i64]> {
465        match self.values.as_mut() {
466            ArrayImpl::Int64(array) => Some(array.as_mut_slice()),
467            _ => None,
468        }
469    }
470}
471
472impl PartialOrd for ListValue {
473    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
474        Some(self.cmp(other))
475    }
476}
477
478impl Ord for ListValue {
479    fn cmp(&self, other: &Self) -> Ordering {
480        self.as_scalar_ref().cmp(&other.as_scalar_ref())
481    }
482}
483
484// Construction helpers:
485
486// [Some(1), None].collect()
487impl<T: PrimitiveArrayItemType> FromIterator<Option<T>> for ListValue {
488    fn from_iter<I: IntoIterator<Item = Option<T>>>(iter: I) -> Self {
489        Self::new(iter.into_iter().collect::<PrimitiveArray<T>>().into())
490    }
491}
492// [1, 2].collect()
493impl<T: PrimitiveArrayItemType> FromIterator<T> for ListValue {
494    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
495        Self::new(iter.into_iter().collect::<PrimitiveArray<T>>().into())
496    }
497}
498// [true, false].collect()
499impl FromIterator<bool> for ListValue {
500    fn from_iter<I: IntoIterator<Item = bool>>(iter: I) -> Self {
501        Self::new(iter.into_iter().collect::<BoolArray>().into())
502    }
503}
504// [Some("hello"), None].collect()
505impl<'a> FromIterator<Option<&'a str>> for ListValue {
506    fn from_iter<I: IntoIterator<Item = Option<&'a str>>>(iter: I) -> Self {
507        Self::new(iter.into_iter().collect::<Utf8Array>().into())
508    }
509}
510// ["hello", "world"].collect()
511impl<'a> FromIterator<&'a str> for ListValue {
512    fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
513        Self::new(iter.into_iter().collect::<Utf8Array>().into())
514    }
515}
516// nested: [ListValue::from_iter([1,2,3]), ListValue::from_iter([4,5])].collect()
517impl FromIterator<ListValue> for ListValue {
518    fn from_iter<I: IntoIterator<Item = ListValue>>(iter: I) -> Self {
519        Self::new(iter.into_iter().collect::<ListArray>().into())
520    }
521}
522
523/// A slice of an array
524#[derive(Copy, Clone)]
525pub struct ListRef<'a> {
526    array: &'a ArrayImpl,
527    start: u32,
528    end: u32,
529}
530
531impl<'a> ListRef<'a> {
532    /// Returns the length of the list.
533    pub fn len(&self) -> usize {
534        (self.end - self.start) as usize
535    }
536
537    /// Returns `true` if the list has a length of 0.
538    pub fn is_empty(&self) -> bool {
539        self.start == self.end
540    }
541
542    /// Returns the data type of the elements in the list.
543    pub fn elem_type(&self) -> DataType {
544        self.array.data_type()
545    }
546
547    /// Returns the elements in the flattened list.
548    pub fn flatten(self) -> ListRef<'a> {
549        match self.array {
550            ArrayImpl::List(inner) => ListRef {
551                array: &inner.value,
552                start: inner.offsets[self.start as usize],
553                end: inner.offsets[self.end as usize],
554            }
555            .flatten(),
556            _ => self,
557        }
558    }
559
560    /// Iterates over the elements of the list.
561    pub fn iter(self) -> impl DoubleEndedIterator + ExactSizeIterator<Item = DatumRef<'a>> + 'a {
562        (self.start..self.end).map(|i| self.array.value_at(i as usize))
563    }
564
565    /// Get the element at the given index. Returns `None` if the index is out of bounds.
566    pub fn get(self, index: usize) -> Option<DatumRef<'a>> {
567        if index < self.len() {
568            Some(self.array.value_at(self.start as usize + index))
569        } else {
570            None
571        }
572    }
573
574    pub fn memcmp_serialize(
575        self,
576        serializer: &mut memcomparable::Serializer<impl BufMut>,
577    ) -> memcomparable::Result<()> {
578        let mut inner_serializer = memcomparable::Serializer::new(vec![]);
579        for datum_ref in self.iter() {
580            memcmp_encoding::serialize_datum_in_composite(datum_ref, &mut inner_serializer)?
581        }
582        serializer.serialize_bytes(&inner_serializer.into_inner())
583    }
584
585    pub fn hash_scalar_inner<H: std::hash::Hasher>(self, state: &mut H) {
586        for datum_ref in self.iter() {
587            hash_datum(datum_ref, state);
588        }
589    }
590
591    /// estimate the serialized size with value encoding
592    pub fn estimate_serialize_size_inner(self) -> usize {
593        self.iter().map(estimate_serialize_datum_size).sum()
594    }
595
596    pub fn as_primitive_slice<T: PrimitiveArrayItemType>(self) -> Option<&'a [T]> {
597        T::try_into_array_ref(self.array)
598            .map(|prim_arr| &prim_arr.as_slice()[self.start as usize..self.end as usize])
599    }
600
601    /// Returns a slice if the list is of type `int64[]`.
602    pub fn as_i64_slice(&self) -> Option<&[i64]> {
603        self.as_primitive_slice()
604    }
605
606    /// # Panics
607    /// Panics if the list is not a map's internal representation (See [`super::MapArray`]).
608    pub(super) fn as_map_kv(self) -> (ListRef<'a>, ListRef<'a>) {
609        let (k, v) = self.array.as_struct().fields().collect_tuple().unwrap();
610        (
611            ListRef {
612                array: k,
613                start: self.start,
614                end: self.end,
615            },
616            ListRef {
617                array: v,
618                start: self.start,
619                end: self.end,
620            },
621        )
622    }
623}
624
625impl PartialEq for ListRef<'_> {
626    fn eq(&self, other: &Self) -> bool {
627        self.iter().eq(other.iter())
628    }
629}
630
631impl Eq for ListRef<'_> {}
632
633impl PartialOrd for ListRef<'_> {
634    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
635        Some(self.cmp(other))
636    }
637}
638
639impl Ord for ListRef<'_> {
640    fn cmp(&self, other: &Self) -> Ordering {
641        self.iter().cmp_by(other.iter(), |a, b| a.default_cmp(&b))
642    }
643}
644
645impl Debug for ListRef<'_> {
646    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
647        f.debug_list().entries(self.iter()).finish()
648    }
649}
650
651impl Row for ListRef<'_> {
652    fn datum_at(&self, index: usize) -> DatumRef<'_> {
653        self.array.value_at(self.start as usize + index)
654    }
655
656    unsafe fn datum_at_unchecked(&self, index: usize) -> DatumRef<'_> {
657        unsafe { self.array.value_at_unchecked(self.start as usize + index) }
658    }
659
660    fn len(&self) -> usize {
661        self.len()
662    }
663
664    fn iter(&self) -> impl Iterator<Item = DatumRef<'_>> {
665        (*self).iter()
666    }
667}
668
669impl ToText for ListRef<'_> {
670    // This function will be invoked when pgwire prints a list value in string.
671    // Refer to PostgreSQL `array_out` or `appendPGArray`.
672    fn write<W: std::fmt::Write>(&self, f: &mut W) -> std::fmt::Result {
673        write!(
674            f,
675            "{{{}}}",
676            self.iter().format_with(",", |datum_ref, f| {
677                let s = datum_ref.to_text();
678                // Never quote null or inner list, but quote empty, verbatim 'null', special
679                // chars and whitespaces.
680                let need_quote = !matches!(datum_ref, None | Some(ScalarRefImpl::List(_)))
681                    && (s.is_empty()
682                        || s.eq_ignore_ascii_case("null")
683                        || s.contains([
684                            '"', '\\', ',',
685                            // whilespace:
686                            // PostgreSQL `array_isspace` includes '\x0B' but rust
687                            // [`char::is_ascii_whitespace`] does not.
688                            ' ', '\t', '\n', '\r', '\x0B', '\x0C', // list-specific:
689                            '{', '}',
690                        ]));
691                if need_quote {
692                    f(&"\"")?;
693                    s.chars().try_for_each(|c| {
694                        if c == '"' || c == '\\' {
695                            f(&"\\")?;
696                        }
697                        f(&c)
698                    })?;
699                    f(&"\"")
700                } else {
701                    f(&s)
702                }
703            })
704        )
705    }
706
707    fn write_with_type<W: std::fmt::Write>(&self, ty: &DataType, f: &mut W) -> std::fmt::Result {
708        match ty {
709            DataType::List { .. } => self.write(f),
710            _ => unreachable!(),
711        }
712    }
713}
714
715/// Implement `Scalar` for `ListValue`.
716impl Scalar for ListValue {
717    type ScalarRefType<'a> = ListRef<'a>;
718
719    fn as_scalar_ref(&self) -> ListRef<'_> {
720        ListRef {
721            array: &self.values,
722            start: 0,
723            end: self.len() as u32,
724        }
725    }
726}
727
728/// Implement `Scalar` for `ListValue`.
729impl<'a> ScalarRef<'a> for ListRef<'a> {
730    type ScalarType = ListValue;
731
732    fn to_owned_scalar(&self) -> ListValue {
733        let mut builder = self.array.create_builder(self.len());
734        for datum_ref in self.iter() {
735            builder.append(datum_ref);
736        }
737        ListValue::new(builder.finish())
738    }
739
740    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
741        self.hash_scalar_inner(state)
742    }
743}
744
745impl ListValue {
746    /// Construct an array from literal string and the data type of the list.
747    pub fn from_str(input: &str, data_type: &DataType) -> Result<Self, String> {
748        struct Parser<'a> {
749            input: &'a str,
750            data_type: &'a DataType,
751        }
752
753        impl Parser<'_> {
754            /// Parse a datum.
755            fn parse(&mut self) -> Result<Datum, String> {
756                self.skip_whitespace();
757                if self.data_type.is_array() {
758                    if self.try_parse_null() {
759                        return Ok(None);
760                    }
761                    Ok(Some(self.parse_array()?.into()))
762                } else {
763                    self.parse_value()
764                }
765            }
766
767            /// Parse an array.
768            fn parse_array(&mut self) -> Result<ListValue, String> {
769                self.skip_whitespace();
770                if !self.try_consume('{') {
771                    return Err("Array value must start with \"{\"".to_owned());
772                }
773                self.skip_whitespace();
774                if self.try_consume('}') {
775                    return Ok(ListValue::empty(self.data_type.as_list_elem()));
776                }
777                let mut builder =
778                    ArrayBuilderImpl::with_type(0, self.data_type.as_list_elem().clone());
779                loop {
780                    let mut parser = Self {
781                        input: self.input,
782                        data_type: self.data_type.as_list_elem(),
783                    };
784                    builder.append(parser.parse()?);
785                    self.input = parser.input;
786
787                    // expect ',' or '}'
788                    self.skip_whitespace();
789                    match self.peek() {
790                        Some(',') => {
791                            self.try_consume(',');
792                        }
793                        Some('}') => {
794                            self.try_consume('}');
795                            break;
796                        }
797                        None => return Err(Self::eoi()),
798                        _ => return Err("Unexpected array element.".to_owned()),
799                    }
800                }
801                Ok(ListValue::new(builder.finish()))
802            }
803
804            /// Parse a non-array value.
805            fn parse_value(&mut self) -> Result<Datum, String> {
806                if self.peek() == Some('"') {
807                    return Ok(Some(self.parse_quoted()?));
808                }
809                // peek until the next unescaped ',' or '}'
810                let mut chars = self.input.char_indices();
811                let mut has_escape = false;
812                let s = loop {
813                    match chars.next().ok_or_else(Self::eoi)? {
814                        (_, '\\') => {
815                            has_escape = true;
816                            chars.next().ok_or_else(Self::eoi)?;
817                        }
818                        (i, c @ ',' | c @ '}') => {
819                            let s = &self.input[..i];
820                            // consume the value and leave the ',' or '}' for parent
821                            self.input = &self.input[i..];
822
823                            break if has_escape {
824                                Cow::Owned(Self::unescape_trim_end(s))
825                            } else {
826                                let trimmed = s.trim_end();
827                                if trimmed.is_empty() {
828                                    return Err(format!("Unexpected \"{c}\" character."));
829                                }
830                                if trimmed.eq_ignore_ascii_case("null") {
831                                    return Ok(None);
832                                }
833                                Cow::Borrowed(trimmed)
834                            };
835                        }
836                        (_, '{') => return Err("Unexpected \"{\" character.".to_owned()),
837                        (_, '"') => return Err("Unexpected array element.".to_owned()),
838                        _ => {}
839                    }
840                };
841                Ok(Some(
842                    ScalarImpl::from_text(&s, self.data_type).map_err(|e| e.to_report_string())?,
843                ))
844            }
845
846            /// Parse a double quoted non-array value.
847            fn parse_quoted(&mut self) -> Result<ScalarImpl, String> {
848                assert!(self.try_consume('"'));
849                // peek until the next unescaped '"'
850                let mut chars = self.input.char_indices();
851                let mut has_escape = false;
852                let s = loop {
853                    match chars.next().ok_or_else(Self::eoi)? {
854                        (_, '\\') => {
855                            has_escape = true;
856                            chars.next().ok_or_else(Self::eoi)?;
857                        }
858                        (i, '"') => {
859                            let s = &self.input[..i];
860                            self.input = &self.input[i + 1..];
861                            break if has_escape {
862                                Cow::Owned(Self::unescape(s))
863                            } else {
864                                Cow::Borrowed(s)
865                            };
866                        }
867                        _ => {}
868                    }
869                };
870                ScalarImpl::from_text(&s, self.data_type).map_err(|e| e.to_report_string())
871            }
872
873            /// Unescape a string.
874            fn unescape(s: &str) -> String {
875                let mut unescaped = String::with_capacity(s.len());
876                let mut chars = s.chars();
877                while let Some(mut c) = chars.next() {
878                    if c == '\\' {
879                        c = chars.next().unwrap();
880                    }
881                    unescaped.push(c);
882                }
883                unescaped
884            }
885
886            /// Unescape a string and trim the trailing whitespaces.
887            ///
888            /// Example: `"\  " -> " "`
889            fn unescape_trim_end(s: &str) -> String {
890                let mut unescaped = String::with_capacity(s.len());
891                let mut chars = s.chars();
892                let mut len_after_last_escaped_char = 0;
893                while let Some(mut c) = chars.next() {
894                    if c == '\\' {
895                        c = chars.next().unwrap();
896                        unescaped.push(c);
897                        len_after_last_escaped_char = unescaped.len();
898                    } else {
899                        unescaped.push(c);
900                    }
901                }
902                let l = unescaped[len_after_last_escaped_char..].trim_end().len();
903                unescaped.truncate(len_after_last_escaped_char + l);
904                unescaped
905            }
906
907            /// Consume the next 4 characters if it matches "null".
908            ///
909            /// Note: We don't use this function when parsing non-array values.
910            ///       Because we can't decide whether it is a null value or a string starts with "null".
911            ///       Consider this case: `{null value}` => `["null value"]`
912            fn try_parse_null(&mut self) -> bool {
913                if let Some(s) = self.input.get(..4)
914                    && s.eq_ignore_ascii_case("null")
915                {
916                    let next_char = self.input[4..].chars().next();
917                    match next_char {
918                        None | Some(',' | '}') => {}
919                        Some(c) if c.is_ascii_whitespace() => {}
920                        // following normal characters
921                        _ => return false,
922                    }
923                    self.input = &self.input[4..];
924                    true
925                } else {
926                    false
927                }
928            }
929
930            /// Consume the next character if it matches `c`.
931            fn try_consume(&mut self, c: char) -> bool {
932                if self.peek() == Some(c) {
933                    self.input = &self.input[c.len_utf8()..];
934                    true
935                } else {
936                    false
937                }
938            }
939
940            /// Expect end of input.
941            fn expect_end(&mut self) -> Result<(), String> {
942                self.skip_whitespace();
943                match self.peek() {
944                    Some(_) => Err("Junk after closing right brace.".to_owned()),
945                    None => Ok(()),
946                }
947            }
948
949            /// Skip whitespaces.
950            fn skip_whitespace(&mut self) {
951                self.input = match self
952                    .input
953                    .char_indices()
954                    .find(|(_, c)| !c.is_ascii_whitespace())
955                {
956                    Some((i, _)) => &self.input[i..],
957                    None => "",
958                };
959            }
960
961            /// Peek the next character.
962            fn peek(&self) -> Option<char> {
963                self.input.chars().next()
964            }
965
966            /// Return the error message for unexpected end of input.
967            fn eoi() -> String {
968                "Unexpected end of input.".into()
969            }
970        }
971
972        let mut parser = Parser { input, data_type };
973        let array = parser.parse_array()?;
974        parser.expect_end()?;
975        Ok(array)
976    }
977}
978
979pub struct ListWriter<'a> {
980    builder: &'a mut ListArrayBuilder,
981}
982
983impl<'a> ListWriter<'a> {
984    pub fn new(builder: &'a mut ListArrayBuilder) -> Self {
985        Self { builder }
986    }
987
988    /// `finish` will be called when the entire record is successfully written.
989    /// The partial data was committed and the `builder` can no longer be used.
990    pub fn finish(self) {
991        self.builder.offsets.push(
992            self.builder
993                .value
994                .len()
995                .try_into()
996                .expect("offset overflow"),
997        );
998        self.builder.bitmap.append(true);
999        let _ = ManuallyDrop::new(self); // prevent drop
1000    }
1001
1002    /// `rollback` will be called while the entire record is abandoned.
1003    /// The partial data was cleaned and the `builder` can be safely used.
1004    pub fn rollback(self) {
1005        // just drop self, the drop impl will rollback the partial data
1006    }
1007}
1008
1009impl Drop for ListWriter<'_> {
1010    /// If the writer is dropped without calling `finish` or `rollback`,
1011    /// we rollback the partial data by default.
1012    fn drop(&mut self) {
1013        let last = *self.builder.offsets.last().unwrap() as usize;
1014        let cur = self.builder.value.len();
1015        for _ in last..cur {
1016            self.builder.value.pop().unwrap();
1017        }
1018    }
1019}
1020
1021pub trait ListWrite {
1022    fn write(&mut self, value: impl ToDatumRef);
1023
1024    fn write_iter(&mut self, values: impl IntoIterator<Item = impl ToDatumRef>) {
1025        for v in values {
1026            self.write(v);
1027        }
1028    }
1029}
1030
1031impl<'a> ListWrite for ListWriter<'a> {
1032    fn write(&mut self, value: impl ToDatumRef) {
1033        self.builder.value.append(value);
1034    }
1035}
1036
1037impl ListWrite for ArrayBuilderImpl {
1038    fn write(&mut self, value: impl ToDatumRef) {
1039        self.append(value);
1040    }
1041}
1042
1043#[cfg(test)]
1044mod tests {
1045    use more_asserts::{assert_gt, assert_lt};
1046
1047    use super::*;
1048
1049    #[test]
1050    fn test_protobuf() {
1051        use crate::array::*;
1052        let array = ListArray::from_iter([
1053            Some(vec![12i32, -7, 25]),
1054            None,
1055            Some(vec![0, -127, 127, 50]),
1056            Some(vec![]),
1057        ]);
1058        let actual = ListArray::from_protobuf(&array.to_protobuf()).unwrap();
1059        assert_eq!(actual, ArrayImpl::List(array));
1060    }
1061
1062    #[test]
1063    fn test_append_array() {
1064        let part1 = ListArray::from_iter([Some([12i32, -7, 25]), None]);
1065        let part2 = ListArray::from_iter([Some(vec![0, -127, 127, 50]), Some(vec![])]);
1066
1067        let mut builder = ListArrayBuilder::with_type(4, DataType::Int32.list());
1068        builder.append_array(&part1);
1069        builder.append_array(&part2);
1070
1071        let expected = ListArray::from_iter([
1072            Some(vec![12i32, -7, 25]),
1073            None,
1074            Some(vec![0, -127, 127, 50]),
1075            Some(vec![]),
1076        ]);
1077        assert_eq!(builder.finish(), expected);
1078    }
1079
1080    // Ensure `create_builder` exactly copies the same metadata.
1081    #[test]
1082    fn test_list_create_builder() {
1083        use crate::array::*;
1084        let arr = ListArray::from_iter([Some([F32::from(2.0), F32::from(42.0), F32::from(1.0)])]);
1085        let arr2 = arr.create_builder(0).finish();
1086        assert_eq!(arr.data_type(), arr2.data_type());
1087    }
1088
1089    #[test]
1090    fn test_builder_pop() {
1091        use crate::array::*;
1092
1093        {
1094            let mut builder = ListArrayBuilder::with_type(1, DataType::Int32.list());
1095            let val = ListValue::from_iter([1i32, 2, 3]);
1096            builder.append(Some(val.as_scalar_ref()));
1097            assert!(builder.pop().is_some());
1098            assert!(builder.pop().is_none());
1099            let arr = builder.finish();
1100            assert!(arr.is_empty());
1101        }
1102
1103        {
1104            let data_type = DataType::Int32.list().list();
1105            let mut builder = ListArrayBuilder::with_type(2, data_type);
1106            let val1 = ListValue::from_iter([1, 2, 3]);
1107            let val2 = ListValue::from_iter([1, 2, 3]);
1108            let list1 = ListValue::from_iter([val1, val2]);
1109            builder.append(Some(list1.as_scalar_ref()));
1110
1111            let val3 = ListValue::from_iter([1, 2, 3]);
1112            let val4 = ListValue::from_iter([1, 2, 3]);
1113            let list2 = ListValue::from_iter([val3, val4]);
1114
1115            builder.append(Some(list2.as_scalar_ref()));
1116
1117            assert!(builder.pop().is_some());
1118
1119            let arr = builder.finish();
1120            assert_eq!(arr.len(), 1);
1121            assert_eq!(arr.value_at(0).unwrap(), list1.as_scalar_ref());
1122        }
1123    }
1124
1125    #[test]
1126    fn test_list_nested_layout() {
1127        use crate::array::*;
1128
1129        let listarray1 = ListArray::from_iter([Some([1i32, 2]), Some([3, 4])]);
1130        let listarray2 = ListArray::from_iter([Some(vec![5, 6, 7]), None, Some(vec![8])]);
1131        let listarray3 = ListArray::from_iter([Some([9, 10])]);
1132
1133        let nestarray = ListArray::from_iter(
1134            [listarray1, listarray2, listarray3]
1135                .into_iter()
1136                .map(|l| ListValue::new(l.into())),
1137        );
1138        let actual = ListArray::from_protobuf(&nestarray.to_protobuf()).unwrap();
1139        assert_eq!(ArrayImpl::List(nestarray), actual);
1140    }
1141
1142    #[test]
1143    fn test_list_value_cmp() {
1144        // ARRAY[1, 1] < ARRAY[1, 2, 1]
1145        assert_lt!(
1146            ListValue::from_iter([1, 1]),
1147            ListValue::from_iter([1, 2, 1]),
1148        );
1149        // ARRAY[1, 2] < ARRAY[1, 2, 1]
1150        assert_lt!(
1151            ListValue::from_iter([1, 2]),
1152            ListValue::from_iter([1, 2, 1]),
1153        );
1154        // ARRAY[1, 3] > ARRAY[1, 2, 1]
1155        assert_gt!(
1156            ListValue::from_iter([1, 3]),
1157            ListValue::from_iter([1, 2, 1]),
1158        );
1159        // null > 1
1160        assert_gt!(
1161            ListValue::from_iter([None::<i32>]),
1162            ListValue::from_iter([1]),
1163        );
1164        // ARRAY[1, 2, null] > ARRAY[1, 2, 1]
1165        assert_gt!(
1166            ListValue::from_iter([Some(1), Some(2), None]),
1167            ListValue::from_iter([Some(1), Some(2), Some(1)]),
1168        );
1169        // Null value in first ARRAY results into a Greater ordering regardless of the smaller ARRAY
1170        // length. ARRAY[1, null] > ARRAY[1, 2, 3]
1171        assert_gt!(
1172            ListValue::from_iter([Some(1), None]),
1173            ListValue::from_iter([Some(1), Some(2), Some(3)]),
1174        );
1175        // ARRAY[1, null] == ARRAY[1, null]
1176        assert_eq!(
1177            ListValue::from_iter([Some(1), None]),
1178            ListValue::from_iter([Some(1), None]),
1179        );
1180    }
1181
1182    #[test]
1183    fn test_list_ref_display() {
1184        let v = ListValue::from_iter([Some(1), None]);
1185        assert_eq!(v.to_string(), "{1,NULL}");
1186    }
1187
1188    #[test]
1189    fn test_serialize_deserialize() {
1190        let value = ListValue::from_iter([Some("abcd"), Some(""), None, Some("a")]);
1191        let list_ref = value.as_scalar_ref();
1192        let mut serializer = memcomparable::Serializer::new(vec![]);
1193        serializer.set_reverse(true);
1194        list_ref.memcmp_serialize(&mut serializer).unwrap();
1195        let buf = serializer.into_inner();
1196        let mut deserializer = memcomparable::Deserializer::new(&buf[..]);
1197        deserializer.set_reverse(true);
1198        assert_eq!(
1199            ListValue::memcmp_deserialize(&ListType::new(DataType::Varchar), &mut deserializer)
1200                .unwrap(),
1201            value
1202        );
1203
1204        let mut builder = ListArrayBuilder::with_type(0, DataType::Varchar.list());
1205        builder.append(Some(list_ref));
1206        let array = builder.finish();
1207        let list_ref = array.value_at(0).unwrap();
1208        let mut serializer = memcomparable::Serializer::new(vec![]);
1209        list_ref.memcmp_serialize(&mut serializer).unwrap();
1210        let buf = serializer.into_inner();
1211        let mut deserializer = memcomparable::Deserializer::new(&buf[..]);
1212        assert_eq!(
1213            ListValue::memcmp_deserialize(&ListType::new(DataType::Varchar), &mut deserializer)
1214                .unwrap(),
1215            value
1216        );
1217    }
1218
1219    #[test]
1220    fn test_memcomparable() {
1221        let cases = [
1222            (
1223                ListValue::from_iter([123, 456]),
1224                ListValue::from_iter([123, 789]),
1225            ),
1226            (
1227                ListValue::from_iter([123, 456]),
1228                ListValue::from_iter([123]),
1229            ),
1230            (
1231                ListValue::from_iter([None, Some("")]),
1232                ListValue::from_iter([None, None::<&str>]),
1233            ),
1234            (
1235                ListValue::from_iter([Some(2)]),
1236                ListValue::from_iter([Some(1), None, Some(3)]),
1237            ),
1238        ];
1239
1240        for (lhs, rhs) in cases {
1241            let lhs_serialized = {
1242                let mut serializer = memcomparable::Serializer::new(vec![]);
1243                lhs.as_scalar_ref()
1244                    .memcmp_serialize(&mut serializer)
1245                    .unwrap();
1246                serializer.into_inner()
1247            };
1248            let rhs_serialized = {
1249                let mut serializer = memcomparable::Serializer::new(vec![]);
1250                rhs.as_scalar_ref()
1251                    .memcmp_serialize(&mut serializer)
1252                    .unwrap();
1253                serializer.into_inner()
1254            };
1255            assert_eq!(lhs_serialized.cmp(&rhs_serialized), lhs.cmp(&rhs));
1256        }
1257    }
1258
1259    #[test]
1260    fn test_listref() {
1261        use crate::array::*;
1262        use crate::types;
1263
1264        let arr = ListArray::from_iter([Some(vec![1, 2, 3]), None, Some(vec![4, 5, 6, 7])]);
1265
1266        // get 3rd ListRef from ListArray
1267        let list_ref = arr.value_at(2).unwrap();
1268        assert_eq!(list_ref, ListValue::from_iter([4, 5, 6, 7]).as_scalar_ref());
1269
1270        // Get 2nd value from ListRef
1271        let scalar = list_ref.get(1).unwrap();
1272        assert_eq!(scalar, Some(types::ScalarRefImpl::Int32(5)));
1273    }
1274
1275    #[test]
1276    fn test_from_to_literal() {
1277        #[track_caller]
1278        fn test(typestr: &str, input: &str, output: Option<&str>) {
1279            let datatype: DataType = typestr.parse().unwrap();
1280            let list = ListValue::from_str(input, &datatype).unwrap();
1281            let actual = list.as_scalar_ref().to_text();
1282            let output = output.unwrap_or(input);
1283            assert_eq!(actual, output);
1284        }
1285
1286        #[track_caller]
1287        fn test_err(typestr: &str, input: &str, err: &str) {
1288            let datatype: DataType = typestr.parse().unwrap();
1289            let actual_err = ListValue::from_str(input, &datatype).unwrap_err();
1290            assert_eq!(actual_err, err);
1291        }
1292
1293        test("varchar[]", "{}", None);
1294        test("varchar[]", "{1 2}", Some(r#"{"1 2"}"#));
1295        test("varchar[]", "{🥵,🤡}", None);
1296        test("varchar[]", r#"{aa\\bb}"#, Some(r#"{"aa\\bb"}"#));
1297        test("int[]", "{1,2,3}", None);
1298        test("varchar[]", r#"{"1,2"}"#, None);
1299        test("varchar[]", r#"{1, ""}"#, Some(r#"{1,""}"#));
1300        test("varchar[]", r#"{"\""}"#, None);
1301        test("varchar[]", r#"{\   }"#, Some(r#"{" "}"#));
1302        test("varchar[]", r#"{\\  }"#, Some(r#"{"\\"}"#));
1303        test("varchar[]", "{nulla}", None);
1304        test("varchar[]", "{null a}", Some(r#"{"null a"}"#));
1305        test(
1306            "varchar[]",
1307            r#"{"null", "NULL", null, NuLL}"#,
1308            Some(r#"{"null","NULL",NULL,NULL}"#),
1309        );
1310        test("varchar[][]", "{{1, 2, 3}, null }", Some("{{1,2,3},NULL}"));
1311        test(
1312            "varchar[][][]",
1313            "{{{1, 2, 3}}, {{4, 5, 6}}}",
1314            Some("{{{1,2,3}},{{4,5,6}}}"),
1315        );
1316        test_err("varchar[]", "()", r#"Array value must start with "{""#);
1317        test_err("varchar[]", "{1,", r#"Unexpected end of input."#);
1318        test_err("varchar[]", "{1,}", r#"Unexpected "}" character."#);
1319        test_err("varchar[]", "{1,,3}", r#"Unexpected "," character."#);
1320        test_err("varchar[]", r#"{"a""b"}"#, r#"Unexpected array element."#);
1321        test_err("varchar[]", r#"{}{"#, r#"Junk after closing right brace."#);
1322    }
1323}