Coverage Report

Created: 2024-10-13 08:39

/Users/andrewlamb/Software/datafusion/datafusion/common/src/unnest.rs
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
//! [`UnnestOptions`] for unnesting structured types
19
20
/// Options for unnesting a column that contains a list type,
21
/// replicating values in the other, non nested rows.
22
///
23
/// Conceptually this operation is like joining each row with all the
24
/// values in the list column.
25
///
26
/// If `preserve_nulls` is false, nulls and empty lists
27
/// from the input column are not carried through to the output. This
28
/// is the default behavior for other systems such as ClickHouse and
29
/// DuckDB
30
///
31
/// If `preserve_nulls` is true (the default), nulls from the input
32
/// column are carried through to the output.
33
///
34
/// # Examples
35
///
36
/// ## `Unnest(c1)`, preserve_nulls: false
37
/// ```text
38
///      ┌─────────┐ ┌─────┐                ┌─────────┐ ┌─────┐
39
///      │ {1, 2}  │ │  A  │   Unnest       │    1    │ │  A  │
40
///      ├─────────┤ ├─────┤                ├─────────┤ ├─────┤
41
///      │  null   │ │  B  │                │    2    │ │  A  │
42
///      ├─────────┤ ├─────┤ ────────────▶  ├─────────┤ ├─────┤
43
///      │   {}    │ │  D  │                │    3    │ │  E  │
44
///      ├─────────┤ ├─────┤                └─────────┘ └─────┘
45
///      │   {3}   │ │  E  │                    c1        c2
46
///      └─────────┘ └─────┘
47
///        c1         c2
48
/// ```
49
///
50
/// ## `Unnest(c1)`, preserve_nulls: true
51
/// ```text
52
///      ┌─────────┐ ┌─────┐                ┌─────────┐ ┌─────┐
53
///      │ {1, 2}  │ │  A  │   Unnest       │    1    │ │  A  │
54
///      ├─────────┤ ├─────┤                ├─────────┤ ├─────┤
55
///      │  null   │ │  B  │                │    2    │ │  A  │
56
///      ├─────────┤ ├─────┤ ────────────▶  ├─────────┤ ├─────┤
57
///      │   {}    │ │  D  │                │  null   │ │  B  │
58
///      ├─────────┤ ├─────┤                ├─────────┤ ├─────┤
59
///      │   {3}   │ │  E  │                │    3    │ │  E  │
60
///      └─────────┘ └─────┘                └─────────┘ └─────┘
61
///        c1         c2                        c1        c2
62
/// ```
63
#[derive(Debug, Clone, PartialEq, PartialOrd, Hash, Eq)]
64
pub struct UnnestOptions {
65
    /// Should nulls in the input be preserved? Defaults to true
66
    pub preserve_nulls: bool,
67
}
68
69
impl Default for UnnestOptions {
70
0
    fn default() -> Self {
71
0
        Self {
72
0
            // default to true to maintain backwards compatible behavior
73
0
            preserve_nulls: true,
74
0
        }
75
0
    }
76
}
77
78
impl UnnestOptions {
79
    /// Create a new [`UnnestOptions`] with default values
80
0
    pub fn new() -> Self {
81
0
        Default::default()
82
0
    }
83
84
    /// Set the behavior with nulls in the input as described on
85
    /// [`Self`]
86
0
    pub fn with_preserve_nulls(mut self, preserve_nulls: bool) -> Self {
87
0
        self.preserve_nulls = preserve_nulls;
88
0
        self
89
0
    }
90
}