Coverage Report

Created: 2024-10-13 08:39

/Users/andrewlamb/Software/datafusion/datafusion/expr/src/logical_plan/statement.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
use datafusion_common::DFSchemaRef;
19
use std::cmp::Ordering;
20
use std::fmt::{self, Display};
21
22
/// Various types of Statements.
23
///
24
/// # Transactions:
25
///
26
/// While DataFusion does not offer support transactions, it provides
27
/// [`LogicalPlan`](crate::LogicalPlan) support to assist building
28
/// database systems using DataFusion
29
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
30
pub enum Statement {
31
    // Begin a transaction
32
    TransactionStart(TransactionStart),
33
    // Commit or rollback a transaction
34
    TransactionEnd(TransactionEnd),
35
    /// Set a Variable
36
    SetVariable(SetVariable),
37
}
38
39
impl Statement {
40
    /// Get a reference to the logical plan's schema
41
0
    pub fn schema(&self) -> &DFSchemaRef {
42
0
        match self {
43
0
            Statement::TransactionStart(TransactionStart { schema, .. }) => schema,
44
0
            Statement::TransactionEnd(TransactionEnd { schema, .. }) => schema,
45
0
            Statement::SetVariable(SetVariable { schema, .. }) => schema,
46
        }
47
0
    }
48
49
    /// Return a descriptive string describing the type of this
50
    /// [`Statement`]
51
0
    pub fn name(&self) -> &str {
52
0
        match self {
53
0
            Statement::TransactionStart(_) => "TransactionStart",
54
0
            Statement::TransactionEnd(_) => "TransactionEnd",
55
0
            Statement::SetVariable(_) => "SetVariable",
56
        }
57
0
    }
58
59
    /// Return a `format`able structure with the a human readable
60
    /// description of this LogicalPlan node per node, not including
61
    /// children.
62
    ///
63
    /// See [crate::LogicalPlan::display] for an example
64
0
    pub fn display(&self) -> impl fmt::Display + '_ {
65
        struct Wrapper<'a>(&'a Statement);
66
        impl<'a> Display for Wrapper<'a> {
67
0
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68
0
                match self.0 {
69
                    Statement::TransactionStart(TransactionStart {
70
0
                        access_mode,
71
0
                        isolation_level,
72
0
                        ..
73
0
                    }) => {
74
0
                        write!(f, "TransactionStart: {access_mode:?} {isolation_level:?}")
75
                    }
76
                    Statement::TransactionEnd(TransactionEnd {
77
0
                        conclusion,
78
0
                        chain,
79
0
                        ..
80
0
                    }) => {
81
0
                        write!(f, "TransactionEnd: {conclusion:?} chain:={chain}")
82
                    }
83
                    Statement::SetVariable(SetVariable {
84
0
                        variable, value, ..
85
0
                    }) => {
86
0
                        write!(f, "SetVariable: set {variable:?} to {value:?}")
87
                    }
88
                }
89
0
            }
90
        }
91
0
        Wrapper(self)
92
0
    }
93
}
94
95
/// Indicates if a transaction was committed or aborted
96
#[derive(Clone, PartialEq, Eq, PartialOrd, Hash, Debug)]
97
pub enum TransactionConclusion {
98
    Commit,
99
    Rollback,
100
}
101
102
/// Indicates if this transaction is allowed to write
103
#[derive(Clone, PartialEq, Eq, PartialOrd, Hash, Debug)]
104
pub enum TransactionAccessMode {
105
    ReadOnly,
106
    ReadWrite,
107
}
108
109
/// Indicates ANSI transaction isolation level
110
#[derive(Clone, PartialEq, Eq, PartialOrd, Hash, Debug)]
111
pub enum TransactionIsolationLevel {
112
    ReadUncommitted,
113
    ReadCommitted,
114
    RepeatableRead,
115
    Serializable,
116
}
117
118
/// Indicator that the following statements should be committed or rolled back atomically
119
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
120
pub struct TransactionStart {
121
    /// indicates if transaction is allowed to write
122
    pub access_mode: TransactionAccessMode,
123
    // indicates ANSI isolation level
124
    pub isolation_level: TransactionIsolationLevel,
125
    /// Empty schema
126
    pub schema: DFSchemaRef,
127
}
128
129
// Manual implementation needed because of `schema` field. Comparison excludes this field.
130
impl PartialOrd for TransactionStart {
131
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
132
0
        match self.access_mode.partial_cmp(&other.access_mode) {
133
            Some(Ordering::Equal) => {
134
0
                self.isolation_level.partial_cmp(&other.isolation_level)
135
            }
136
0
            cmp => cmp,
137
        }
138
0
    }
139
}
140
141
/// Indicator that any current transaction should be terminated
142
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
143
pub struct TransactionEnd {
144
    /// whether the transaction committed or aborted
145
    pub conclusion: TransactionConclusion,
146
    /// if specified a new transaction is immediately started with same characteristics
147
    pub chain: bool,
148
    /// Empty schema
149
    pub schema: DFSchemaRef,
150
}
151
152
// Manual implementation needed because of `schema` field. Comparison excludes this field.
153
impl PartialOrd for TransactionEnd {
154
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
155
0
        match self.conclusion.partial_cmp(&other.conclusion) {
156
0
            Some(Ordering::Equal) => self.chain.partial_cmp(&other.chain),
157
0
            cmp => cmp,
158
        }
159
0
    }
160
}
161
162
/// Set a Variable's value -- value in
163
/// [`ConfigOptions`](datafusion_common::config::ConfigOptions)
164
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
165
pub struct SetVariable {
166
    /// The variable name
167
    pub variable: String,
168
    /// The value to set
169
    pub value: String,
170
    /// Dummy schema
171
    pub schema: DFSchemaRef,
172
}
173
174
// Manual implementation needed because of `schema` field. Comparison excludes this field.
175
impl PartialOrd for SetVariable {
176
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
177
0
        match self.variable.partial_cmp(&other.value) {
178
0
            Some(Ordering::Equal) => self.value.partial_cmp(&other.value),
179
0
            cmp => cmp,
180
        }
181
0
    }
182
}