## Coverage Report

#### Created: 2025-11-22 06:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /Users/andrewlamb/Software/datafusion/datafusion/expr/src/execution_props.rs

    Line
    Count
    Source
    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 crate::var_provider::{VarProvider, VarType};
    19
    use chrono::{DateTime, TimeZone, Utc};
    20
    use datafusion_common::alias::AliasGenerator;
    21
    use datafusion_common::config::ConfigOptions;
    22
    use datafusion_common::HashMap;
    23
    use std::sync::Arc;
    24
    25
    /// Holds per-query execution properties and data (such as statement
    26
    /// starting timestamps).
    27
    ///
    28
    /// An [`ExecutionProps`] is created each time a `LogicalPlan` is
    29
    /// prepared for execution (optimized). If the same plan is optimized
    30
    /// multiple times, a new `ExecutionProps` is created each time.
    31
    ///
    32
    /// It is important that this structure be cheap to create as it is
    33
    /// done so during predicate pruning and expression simplification
    34
    #[derive(Clone, Debug)]
    35
    pub struct ExecutionProps {
    36
        pub query_execution_start_time: DateTime<Utc>,
    37
        /// Alias generator used by subquery optimizer rules
    38
        pub alias_generator: Arc<AliasGenerator>,
    39
        /// Snapshot of config options when the query started
    40
        pub config_options: Option<Arc<ConfigOptions>>,
    41
        /// Providers for scalar variables
    42
        pub var_providers: Option<HashMap<VarType, Arc<dyn VarProvider + Send + Sync>>>,
    43
    }
    44
    45
    impl Default for ExecutionProps {
    46
    0
        fn default() -> Self {
    47
    0
            Self::new()
    48
    0
        }
    49
    }
    50
    51
    impl ExecutionProps {
    52
        /// Creates a new execution props
    53
    0
        pub fn new() -> Self {
    54
    0
            ExecutionProps {
    55
    0
                // Set this to a fixed sentinel to make it obvious if this is
    56
    0
                // not being updated / propagated correctly
    57
    0
                query_execution_start_time: Utc.timestamp_nanos(0),
    58
    0
                alias_generator: Arc::new(AliasGenerator::new()),
    59
    0
                config_options: None,
    60
    0
                var_providers: None,
    61
    0
            }
    62
    0
        }
    63
    64
        /// Set the query execution start time to use
    65
    0
        pub fn with_query_execution_start_time(
    66
    0
            mut self,
    67
    0
            query_execution_start_time: DateTime<Utc>,
    68
    0
        ) -> Self {
    69
    0
            self.query_execution_start_time = query_execution_start_time;
    70
    0
            self
    71
    0
        }
    72
    73
        #[deprecated(since = "50.0.0", note = "Use mark_start_execution instead")]
    74
    0
        pub fn start_execution(&mut self) -> &Self {
    75
    0
            let default_config = Arc::new(ConfigOptions::default());
    76
    0
            self.mark_start_execution(default_config)
    77
    0
        }
    78
    79
        /// Marks the execution of query started timestamp.
    80
        /// This also instantiates a new alias generator.
    81
    0
        pub fn mark_start_execution(&mut self, config_options: Arc<ConfigOptions>) -> &Self {
    82
    0
            self.query_execution_start_time = Utc::now();
    83
    0
            self.alias_generator = Arc::new(AliasGenerator::new());
    84
    0
            self.config_options = Some(config_options);
    85
    0
            &*self
    86
    0
        }
    87
    88
        /// Registers a variable provider, returning the existing
    89
        /// provider, if any
    90
    0
        pub fn add_var_provider(
    91
    0
            &mut self,
    92
    0
            var_type: VarType,
    93
    0
            provider: Arc<dyn VarProvider + Send + Sync>,
    94
    0
        ) -> Option<Arc<dyn VarProvider + Send + Sync>> {
    95
    0
            let mut var_providers = self.var_providers.take().unwrap_or_default();
    96
    97
    0
            let old_provider = var_providers.insert(var_type, provider);
    98
    99
    0
            self.var_providers = Some(var_providers);
    100
    101
    0
            old_provider
    102
    0
        }
    103
    104
        /// Returns the provider for the `var_type`, if any
    105
        #[expect(clippy::needless_pass_by_value)]
    106
    0
        pub fn get_var_provider(
    107
    0
            &self,
    108
    0
            var_type: VarType,
    109
    0
        ) -> Option<Arc<dyn VarProvider + Send + Sync>> {
    110
    0
            self.var_providers
    111
    0
                .as_ref()
    112
    0
                .and_then(|var_providers| var_providers.get(&var_type).cloned())
    113
    0
        }
    114
    115
        /// Returns the configuration properties for this execution
    116
        /// if the execution has started
    117
    0
        pub fn config_options(&self) -> Option<&Arc<ConfigOptions>> {
    118
    0
            self.config_options.as_ref()
    119
    0
        }
    120
    }
    121
    122
    #[cfg(test)]
    123
    mod test {
    124
        use super::*;
    125
        #[test]
    126
        fn debug() {
    127
            let props = ExecutionProps::new();
    128
            assert_eq!("ExecutionProps { query_execution_start_time: 1970-01-01T00:00:00Z, alias_generator: AliasGenerator { next_id: 1 }, config_options: None, var_providers: None }", format!("{props:?}"));
    129
        }
    130
    }