sqlparser/ast/helpers/
stmt_data_loading.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13//! AST types specific to loading and unloading syntax, like one available in Snowflake which
14//! contains: STAGE ddl operations, PUT upload or COPY INTO
15//! See [this page](https://docs.snowflake.com/en/sql-reference/commands-data-loading) for more details.
16
17#[cfg(not(feature = "std"))]
18use alloc::string::String;
19#[cfg(not(feature = "std"))]
20use alloc::vec::Vec;
21use core::fmt;
22use core::fmt::Formatter;
23
24#[cfg(feature = "serde")]
25use serde::{Deserialize, Serialize};
26
27use crate::ast::Ident;
28#[cfg(feature = "visitor")]
29use sqlparser_derive::{Visit, VisitMut};
30
31#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
34pub struct StageParamsObject {
35    pub url: Option<String>,
36    pub encryption: DataLoadingOptions,
37    pub endpoint: Option<String>,
38    pub storage_integration: Option<String>,
39    pub credentials: DataLoadingOptions,
40}
41
42#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
43#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
44#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
45pub struct DataLoadingOptions {
46    pub options: Vec<DataLoadingOption>,
47}
48
49#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
50#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
51#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
52pub enum DataLoadingOptionType {
53    STRING,
54    BOOLEAN,
55    ENUM,
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
59#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
60#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
61pub struct DataLoadingOption {
62    pub option_name: String,
63    pub option_type: DataLoadingOptionType,
64    pub value: String,
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
68#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
69#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
70pub struct StageLoadSelectItem {
71    pub alias: Option<Ident>,
72    pub file_col_num: i32,
73    pub element: Option<Ident>,
74    pub item_as: Option<Ident>,
75}
76
77impl fmt::Display for StageParamsObject {
78    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79        let url = &self.url.as_ref();
80        let storage_integration = &self.storage_integration.as_ref();
81        let endpoint = &self.endpoint.as_ref();
82
83        if url.is_some() {
84            write!(f, " URL='{}'", url.unwrap())?;
85        }
86        if storage_integration.is_some() {
87            write!(f, " STORAGE_INTEGRATION={}", storage_integration.unwrap())?;
88        }
89        if endpoint.is_some() {
90            write!(f, " ENDPOINT='{}'", endpoint.unwrap())?;
91        }
92        if !self.credentials.options.is_empty() {
93            write!(f, " CREDENTIALS=({})", self.credentials)?;
94        }
95        if !self.encryption.options.is_empty() {
96            write!(f, " ENCRYPTION=({})", self.encryption)?;
97        }
98
99        Ok(())
100    }
101}
102
103impl fmt::Display for DataLoadingOptions {
104    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
105        if !self.options.is_empty() {
106            for option in &self.options {
107                write!(f, "{}", option)?;
108                if !option.eq(self.options.last().unwrap()) {
109                    write!(f, " ")?;
110                }
111            }
112        }
113        Ok(())
114    }
115}
116
117impl fmt::Display for DataLoadingOption {
118    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
119        match self.option_type {
120            DataLoadingOptionType::STRING => {
121                write!(f, "{}='{}'", self.option_name, self.value)?;
122            }
123            DataLoadingOptionType::ENUM => {
124                // single quote is omitted
125                write!(f, "{}={}", self.option_name, self.value)?;
126            }
127            DataLoadingOptionType::BOOLEAN => {
128                // single quote is omitted
129                write!(f, "{}={}", self.option_name, self.value)?;
130            }
131        }
132        Ok(())
133    }
134}
135
136impl fmt::Display for StageLoadSelectItem {
137    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138        if self.alias.is_some() {
139            write!(f, "{}.", self.alias.as_ref().unwrap())?;
140        }
141        write!(f, "${}", self.file_col_num)?;
142        if self.element.is_some() {
143            write!(f, ":{}", self.element.as_ref().unwrap())?;
144        }
145        if self.item_as.is_some() {
146            write!(f, " AS {}", self.item_as.as_ref().unwrap())?;
147        }
148        Ok(())
149    }
150}