From 03fc85519ebda6512927ddea85f0f6cb1f0220d8 Mon Sep 17 00:00:00 2001 From: Andy Lok <andylokandy@hotmail.com> Date: Tue, 14 May 2024 13:08:53 +0800 Subject: [PATCH] refactor: remove databend-common-meta-app from databend-common-ast (#15509) * refactor: remove databend-common-meta-app from databend-common-ast * fix --------- Co-authored-by: Bohu <overred.shuttler@gmail.com> Co-authored-by: sundyli <543950155@qq.com> --- Cargo.lock | 3 +- src/meta/app/Cargo.toml | 1 + src/meta/app/src/principal/file_format.rs | 200 ++++++------ .../app/src/principal/principal_identity.rs | 16 +- src/meta/app/src/principal/user_auth.rs | 14 +- src/meta/app/src/principal/user_identity.rs | 6 + src/meta/app/src/principal/user_info.rs | 23 +- src/meta/app/src/principal/user_privilege.rs | 47 ++- src/meta/app/src/principal/user_stage.rs | 89 +++--- src/meta/app/src/schema/catalog.rs | 12 +- src/meta/app/src/schema/create_option.rs | 14 + src/meta/app/src/share/share.rs | 31 +- src/meta/app/src/share/share_name_ident.rs | 14 + .../src/stage_from_to_protobuf_impl.rs | 6 +- src/query/ast/Cargo.toml | 1 - src/query/ast/src/ast/escape.rs | 40 +++ src/query/ast/src/ast/format/ast_format.rs | 18 +- src/query/ast/src/ast/format/syntax/ddl.rs | 2 +- src/query/ast/src/ast/mod.rs | 1 + src/query/ast/src/ast/statements/catalog.rs | 2 +- .../ast/src/ast/statements/connection.rs | 3 +- src/query/ast/src/ast/statements/copy.rs | 44 --- src/query/ast/src/ast/statements/data_mask.rs | 3 +- src/query/ast/src/ast/statements/database.rs | 14 +- .../ast/src/ast/statements/dynamic_table.rs | 3 +- src/query/ast/src/ast/statements/index.rs | 4 +- src/query/ast/src/ast/statements/mod.rs | 2 + .../ast/src/ast/statements/network_policy.rs | 4 +- .../ast/src/ast/statements/password_policy.rs | 4 +- src/query/ast/src/ast/statements/principal.rs | 299 ++++++++++++++++++ src/query/ast/src/ast/statements/sequence.rs | 3 +- src/query/ast/src/ast/statements/share.rs | 14 +- src/query/ast/src/ast/statements/stage.rs | 3 +- src/query/ast/src/ast/statements/statement.rs | 9 +- src/query/ast/src/ast/statements/stream.rs | 3 +- src/query/ast/src/ast/statements/table.rs | 3 +- src/query/ast/src/ast/statements/udf.rs | 3 +- src/query/ast/src/ast/statements/user.rs | 41 +-- src/query/ast/src/ast/statements/view.rs | 3 +- .../ast/src/ast/statements/virtual_column.rs | 3 +- src/query/ast/src/ast/visitors/visitor.rs | 4 - src/query/ast/src/ast/visitors/visitor_mut.rs | 4 - src/query/ast/src/parser/statement.rs | 27 +- src/query/ast/tests/it/testdata/statement.txt | 99 +++++- .../formats/tests/it/output_format_tcsv.rs | 13 +- src/query/sql/src/planner/binder/binder.rs | 10 +- .../sql/src/planner/binder/copy_into_table.rs | 40 ++- .../sql/src/planner/binder/ddl/account.rs | 41 +-- .../sql/src/planner/binder/ddl/catalog.rs | 2 +- .../sql/src/planner/binder/ddl/connection.rs | 2 +- .../sql/src/planner/binder/ddl/data_mask.rs | 2 +- .../sql/src/planner/binder/ddl/database.rs | 8 +- .../src/planner/binder/ddl/dynamic_table.rs | 2 +- src/query/sql/src/planner/binder/ddl/index.rs | 4 +- .../src/planner/binder/ddl/network_policy.rs | 2 +- .../src/planner/binder/ddl/password_policy.rs | 2 +- .../sql/src/planner/binder/ddl/sequence.rs | 2 +- src/query/sql/src/planner/binder/ddl/share.rs | 12 +- src/query/sql/src/planner/binder/ddl/stage.rs | 9 +- .../sql/src/planner/binder/ddl/stream.rs | 2 +- src/query/sql/src/planner/binder/ddl/table.rs | 2 +- src/query/sql/src/planner/binder/ddl/view.rs | 2 +- .../src/planner/binder/ddl/virtual_column.rs | 2 +- src/query/sql/src/planner/binder/insert.rs | 7 +- src/query/sql/src/planner/binder/replace.rs | 7 +- src/query/sql/src/planner/binder/udf.rs | 2 +- src/query/users/tests/it/password_policy.rs | 2 +- src/tests/sqlsmith/Cargo.toml | 1 - src/tests/sqlsmith/src/sql_gen/ddl.rs | 2 +- 69 files changed, 904 insertions(+), 415 deletions(-) create mode 100644 src/query/ast/src/ast/escape.rs create mode 100644 src/query/ast/src/ast/statements/principal.rs diff --git a/Cargo.lock b/Cargo.lock index 499cdcf0568e1..1f93ae6edb19f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2971,7 +2971,6 @@ dependencies = [ "databend-common-base", "databend-common-exception", "databend-common-io", - "databend-common-meta-app", "derive-visitor", "enum-as-inner 0.5.1", "ethnum 1.5.0 (git+https://github.com/ariesdevil/ethnum-rs?rev=4cb05f1)", @@ -3521,6 +3520,7 @@ dependencies = [ "chrono", "chrono-tz", "cron", + "databend-common-ast", "databend-common-building", "databend-common-exception", "databend-common-expression", @@ -5068,7 +5068,6 @@ dependencies = [ "databend-common-formats", "databend-common-functions", "databend-common-io", - "databend-common-meta-app", "databend-common-sql", "databend-driver", "databend-sql", diff --git a/src/meta/app/Cargo.toml b/src/meta/app/Cargo.toml index e446654f4dff4..11acc637262fb 100644 --- a/src/meta/app/Cargo.toml +++ b/src/meta/app/Cargo.toml @@ -14,6 +14,7 @@ test = true storage-hdfs = [] [dependencies] +databend-common-ast = { path = "../../query/ast" } databend-common-exception = { path = "../../common/exception" } databend-common-expression = { path = "../../query/expression" } databend-common-io = { path = "../../common/io" } diff --git a/src/meta/app/src/principal/file_format.rs b/src/meta/app/src/principal/file_format.rs index d56fd0df0e500..326c1b956320e 100644 --- a/src/meta/app/src/principal/file_format.rs +++ b/src/meta/app/src/principal/file_format.rs @@ -18,6 +18,8 @@ use std::fmt::Display; use std::fmt::Formatter; use std::str::FromStr; +use databend_common_ast::ast::FileFormatOptions; +use databend_common_ast::ast::FileFormatValue; use databend_common_exception::ErrorCode; use databend_common_exception::Result; use databend_common_io::constants::NULL_BYTES_ESCAPE; @@ -46,63 +48,6 @@ const NULL_IF: &str = "null_if"; const OPT_EMPTY_FIELD_AS: &str = "empty_field_as"; const OPT_BINARY_FORMAT: &str = "binary_format"; -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct FileFormatOptionsAst { - pub options: BTreeMap<String, String>, -} - -impl FileFormatOptionsAst { - pub fn new(options: BTreeMap<String, String>) -> Self { - FileFormatOptionsAst { options } - } - - fn take_string(&mut self, key: &str, default: String) -> String { - self.options.remove(key).unwrap_or(default) - } - - fn take_type(&mut self) -> Result<StageFileFormatType> { - match (self.options.remove("type"), self.options.remove("format")) { - (Some(t), None) | (None, Some(t)) => { - StageFileFormatType::from_str(&t).map_err(ErrorCode::IllegalFileFormat) - } - (Some(_), Some(_)) => Err(ErrorCode::IllegalFileFormat( - "Invalid FILE_FORMAT options: both TYPE and FORMAT option are present. \ - Please only use the TYPE to specify the file format type. The FORMAT option is deprecated.", - )), - (None, None) => Err(ErrorCode::IllegalFileFormat( - "Invalid FILE_FORMAT options: FILE_FORMAT must include at least one of the TYPE or NAME option. \ - Currently, neither is specified.", - )), - } - } - - fn take_compression(&mut self) -> Result<StageFileCompression> { - match self.options.remove("compression") { - Some(c) => StageFileCompression::from_str(&c).map_err(ErrorCode::IllegalFileFormat), - None => Ok(StageFileCompression::None), - } - } - - fn take_u64(&mut self, key: &str, default: u64) -> Result<u64> { - match self.options.remove(key) { - Some(v) => Ok(u64::from_str(&v)?), - None => Ok(default), - } - } - - fn take_bool(&mut self, key: &str, default: bool) -> Result<bool> { - match self.options.remove(key) { - Some(v) => Ok(bool::from_str(&v.to_lowercase()).map_err(|_| { - ErrorCode::IllegalFileFormat(format!( - "Invalid boolean value {} for option {}.", - v, key - )) - })?), - None => Ok(default), - } - } -} - /// File format parameters after checking and parsing. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(tag = "type")] @@ -159,28 +104,27 @@ impl FileFormatParams { } } - pub fn try_from_ast(ast: FileFormatOptionsAst, old: bool) -> Result<Self> { - let mut ast = ast; - let typ = ast.take_type()?; + pub fn try_from_reader(mut reader: FileFormatOptionsReader, old: bool) -> Result<Self> { + let typ = reader.take_type()?; let params = match typ { StageFileFormatType::Xml => { let default = XmlFileFormatParams::default(); - let row_tag = ast.take_string(OPT_ROW_TAG, default.row_tag); - let compression = ast.take_compression()?; + let row_tag = reader.take_string(OPT_ROW_TAG, default.row_tag); + let compression = reader.take_compression()?; FileFormatParams::Xml(XmlFileFormatParams { compression, row_tag, }) } StageFileFormatType::Json => { - let compression = ast.take_compression()?; + let compression = reader.take_compression()?; FileFormatParams::Json(JsonFileFormatParams { compression }) } StageFileFormatType::NdJson => { - let compression = ast.take_compression()?; - let missing_field_as = ast.options.remove(MISSING_FIELD_AS); - let null_field_as = ast.options.remove(NULL_FIELD_AS); - let null_if = ast.options.remove(NULL_IF); + let compression = reader.take_compression()?; + let missing_field_as = reader.options.remove(MISSING_FIELD_AS); + let null_field_as = reader.options.remove(NULL_FIELD_AS); + let null_if = reader.options.remove(NULL_IF); let null_if = match null_if { None => { vec![] @@ -201,39 +145,40 @@ impl FileFormatParams { )?) } StageFileFormatType::Parquet => { - let missing_field_as = ast.options.remove(MISSING_FIELD_AS); + let missing_field_as = reader.options.remove(MISSING_FIELD_AS); FileFormatParams::Parquet(ParquetFileFormatParams::try_create( missing_field_as.as_deref(), )?) } StageFileFormatType::Csv => { let default = CsvFileFormatParams::default(); - let compression = ast.take_compression()?; - let headers = ast.take_u64(OPT_SKIP_HEADER, default.headers)?; - let field_delimiter = ast.take_string(OPT_FIELD_DELIMITER, default.field_delimiter); + let compression = reader.take_compression()?; + let headers = reader.take_u64(OPT_SKIP_HEADER, default.headers)?; + let field_delimiter = + reader.take_string(OPT_FIELD_DELIMITER, default.field_delimiter); let record_delimiter = - ast.take_string(OPT_RECORDE_DELIMITER, default.record_delimiter); - let nan_display = ast.take_string(OPT_NAN_DISPLAY, default.nan_display); - let escape = ast.take_string(OPT_ESCAPE, default.escape); - let quote = ast.take_string(OPT_QUOTE, default.quote); - let null_display = ast.take_string(OPT_NULL_DISPLAY, default.null_display); - let empty_field_as = ast + reader.take_string(OPT_RECORDE_DELIMITER, default.record_delimiter); + let nan_display = reader.take_string(OPT_NAN_DISPLAY, default.nan_display); + let escape = reader.take_string(OPT_ESCAPE, default.escape); + let quote = reader.take_string(OPT_QUOTE, default.quote); + let null_display = reader.take_string(OPT_NULL_DISPLAY, default.null_display); + let empty_field_as = reader .options .remove(OPT_EMPTY_FIELD_AS) .map(|s| EmptyFieldAs::from_str(&s)) .transpose()? .unwrap_or_default(); - let binary_format = ast + let binary_format = reader .options .remove(OPT_BINARY_FORMAT) .map(|s| BinaryFormat::from_str(&s)) .transpose()? .unwrap_or_default(); - let error_on_column_count_mismatch = ast.take_bool( + let error_on_column_count_mismatch = reader.take_bool( OPT_ERROR_ON_COLUMN_COUNT_MISMATCH, default.error_on_column_count_mismatch, )?; - let output_header = ast.take_bool(OPT_OUTPUT_HEADER, default.output_header)?; + let output_header = reader.take_bool(OPT_OUTPUT_HEADER, default.output_header)?; FileFormatParams::Csv(CsvFileFormatParams { compression, headers, @@ -252,14 +197,15 @@ impl FileFormatParams { } StageFileFormatType::Tsv => { let default = TsvFileFormatParams::default(); - let compression = ast.take_compression()?; - let headers = ast.take_u64(OPT_SKIP_HEADER, default.headers)?; - let field_delimiter = ast.take_string(OPT_FIELD_DELIMITER, default.field_delimiter); + let compression = reader.take_compression()?; + let headers = reader.take_u64(OPT_SKIP_HEADER, default.headers)?; + let field_delimiter = + reader.take_string(OPT_FIELD_DELIMITER, default.field_delimiter); let record_delimiter = - ast.take_string(OPT_RECORDE_DELIMITER, default.record_delimiter); - let nan_display = ast.take_string(OPT_NAN_DISPLAY, default.nan_display); - let escape = ast.take_string(OPT_ESCAPE, default.escape); - let quote = ast.take_string(OPT_QUOTE, default.quote); + reader.take_string(OPT_RECORDE_DELIMITER, default.record_delimiter); + let nan_display = reader.take_string(OPT_NAN_DISPLAY, default.nan_display); + let escape = reader.take_string(OPT_ESCAPE, default.escape); + let quote = reader.take_string(OPT_QUOTE, default.quote); FileFormatParams::Tsv(TsvFileFormatParams { compression, headers, @@ -285,12 +231,12 @@ impl FileFormatParams { params.get_type().to_string() )) })?; - if ast.options.is_empty() { + if reader.options.is_empty() { Ok(params) } else { Err(ErrorCode::IllegalFileFormat(format!( "Unsupported options for {:?}: {:?}", - typ, ast.options + typ, reader.options ))) } } @@ -342,11 +288,79 @@ impl Default for FileFormatParams { } } -impl TryFrom<FileFormatOptionsAst> for FileFormatParams { - type Error = ErrorCode; +pub struct FileFormatOptionsReader { + pub options: BTreeMap<String, String>, +} + +impl FileFormatOptionsReader { + pub fn from_ast(options: &FileFormatOptions) -> Self { + let options = options + .options + .iter() + .map(|(k, v)| { + let v = match v { + FileFormatValue::Keyword(v) => v.clone(), + FileFormatValue::Bool(v) => v.to_string(), + FileFormatValue::U64(v) => v.to_string(), + FileFormatValue::String(v) => v.clone(), + FileFormatValue::StringList(v) => serde_json::to_string(&v).unwrap(), + }; + + (k.clone(), v) + }) + .collect(); + + FileFormatOptionsReader { options } + } - fn try_from(ast: FileFormatOptionsAst) -> Result<Self> { - FileFormatParams::try_from_ast(ast, false) + pub fn from_map(options: BTreeMap<String, String>) -> Self { + FileFormatOptionsReader { options } + } + + fn take_string(&mut self, key: &str, default: String) -> String { + self.options.remove(key).unwrap_or(default) + } + + fn take_type(&mut self) -> Result<StageFileFormatType> { + match (self.options.remove("type"), self.options.remove("format")) { + (Some(t), None) | (None, Some(t)) => { + StageFileFormatType::from_str(&t).map_err(ErrorCode::IllegalFileFormat) + } + (Some(_), Some(_)) => Err(ErrorCode::IllegalFileFormat( + "Invalid FILE_FORMAT options: both TYPE and FORMAT option are present. \ + Please only use the TYPE to specify the file format type. The FORMAT option is deprecated.", + )), + (None, None) => Err(ErrorCode::IllegalFileFormat( + "Invalid FILE_FORMAT options: FILE_FORMAT must include at least one of the TYPE or NAME option. \ + Currently, neither is specified.", + )), + } + } + + fn take_compression(&mut self) -> Result<StageFileCompression> { + match self.options.remove("compression") { + Some(c) => StageFileCompression::from_str(&c).map_err(ErrorCode::IllegalFileFormat), + None => Ok(StageFileCompression::None), + } + } + + fn take_u64(&mut self, key: &str, default: u64) -> Result<u64> { + match self.options.remove(key) { + Some(v) => Ok(u64::from_str(&v)?), + None => Ok(default), + } + } + + fn take_bool(&mut self, key: &str, default: bool) -> Result<bool> { + match self.options.remove(key) { + Some(v) => Ok(bool::from_str(&v.to_lowercase()).map_err(|_| { + ErrorCode::IllegalFileFormat(format!( + "Invalid boolean value {} for option {}.", + v, key + )) + })?), + None => Ok(default), + } } } diff --git a/src/meta/app/src/principal/principal_identity.rs b/src/meta/app/src/principal/principal_identity.rs index c420ef525909b..33db0cff38660 100644 --- a/src/meta/app/src/principal/principal_identity.rs +++ b/src/meta/app/src/principal/principal_identity.rs @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::fmt; - use crate::principal::UserIdentity; #[derive(Clone, Debug, Eq, PartialEq)] @@ -32,11 +30,15 @@ impl PrincipalIdentity { } } -impl fmt::Display for PrincipalIdentity { - fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> { - match self { - PrincipalIdentity::User(u) => write!(f, " USER {}", u.display()), - PrincipalIdentity::Role(r) => write!(f, " ROLE '{r}'"), +impl From<databend_common_ast::ast::PrincipalIdentity> for PrincipalIdentity { + fn from(p: databend_common_ast::ast::PrincipalIdentity) -> Self { + match p { + databend_common_ast::ast::PrincipalIdentity::User(user) => { + PrincipalIdentity::User(user.into()) + } + databend_common_ast::ast::PrincipalIdentity::Role(name) => { + PrincipalIdentity::Role(name) + } } } } diff --git a/src/meta/app/src/principal/user_auth.rs b/src/meta/app/src/principal/user_auth.rs index f94562c06c36e..60b4dddcfd2e9 100644 --- a/src/meta/app/src/principal/user_auth.rs +++ b/src/meta/app/src/principal/user_auth.rs @@ -32,8 +32,9 @@ pub enum AuthType { JWT, } -impl std::str::FromStr for AuthType { +impl FromStr for AuthType { type Err = ErrorCode; + fn from_str(s: &str) -> Result<Self> { match s { SHA256_PASSWORD_STR => Ok(AuthType::Sha256Password), @@ -79,6 +80,17 @@ impl AuthType { } } +impl From<databend_common_ast::ast::AuthType> for AuthType { + fn from(t: databend_common_ast::ast::AuthType) -> Self { + match t { + databend_common_ast::ast::AuthType::NoPassword => AuthType::NoPassword, + databend_common_ast::ast::AuthType::Sha256Password => AuthType::Sha256Password, + databend_common_ast::ast::AuthType::DoubleSha1Password => AuthType::DoubleSha1Password, + databend_common_ast::ast::AuthType::JWT => AuthType::JWT, + } + } +} + #[derive( serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Default, )] diff --git a/src/meta/app/src/principal/user_identity.rs b/src/meta/app/src/principal/user_identity.rs index 62df0fdc48275..87ce5b342d8c6 100644 --- a/src/meta/app/src/principal/user_identity.rs +++ b/src/meta/app/src/principal/user_identity.rs @@ -85,3 +85,9 @@ impl KeyCodec for UserIdentity { Self::parse(&s) } } + +impl From<databend_common_ast::ast::UserIdentity> for UserIdentity { + fn from(user: databend_common_ast::ast::UserIdentity) -> Self { + UserIdentity::new(user.username, user.hostname) + } +} diff --git a/src/meta/app/src/principal/user_info.rs b/src/meta/app/src/principal/user_info.rs index 5951620a568bf..e3358c69c7c6c 100644 --- a/src/meta/app/src/principal/user_info.rs +++ b/src/meta/app/src/principal/user_info.rs @@ -17,6 +17,7 @@ use std::convert::TryFrom; use chrono::DateTime; use chrono::Utc; +use databend_common_ast::ast::UserOptionItem; use databend_common_exception::ErrorCode; use databend_common_exception::Result; use enumflags2::bitflags; @@ -158,13 +159,9 @@ impl TryFrom<Vec<u8>> for UserInfo { #[serde(default)] pub struct UserOption { flags: BitFlags<UserOptionFlag>, - default_role: Option<String>, - network_policy: Option<String>, - password_policy: Option<String>, - disabled: Option<bool>, } @@ -272,6 +269,24 @@ impl UserOption { pub fn has_option_flag(&self, flag: UserOptionFlag) -> bool { self.flags.contains(flag) } + + pub fn apply(&mut self, alter: &UserOptionItem) { + match alter { + UserOptionItem::TenantSetting(enabled) => { + if *enabled { + self.flags.insert(UserOptionFlag::TenantSetting); + } else { + self.flags.remove(UserOptionFlag::TenantSetting); + } + } + UserOptionItem::DefaultRole(v) => self.default_role = Some(v.clone()), + UserOptionItem::SetNetworkPolicy(v) => self.network_policy = Some(v.clone()), + UserOptionItem::UnsetNetworkPolicy => self.network_policy = None, + UserOptionItem::SetPasswordPolicy(v) => self.password_policy = Some(v.clone()), + UserOptionItem::UnsetPasswordPolicy => self.password_policy = None, + UserOptionItem::Disabled(v) => self.disabled = Some(*v), + } + } } #[bitflags] diff --git a/src/meta/app/src/principal/user_privilege.rs b/src/meta/app/src/principal/user_privilege.rs index 22c55372226c2..4f7374fabef32 100644 --- a/src/meta/app/src/principal/user_privilege.rs +++ b/src/meta/app/src/principal/user_privilege.rs @@ -13,6 +13,7 @@ // limitations under the License. use std::fmt; +use std::fmt::Display; use std::ops; use enumflags2::bitflags; @@ -104,8 +105,8 @@ const ALL_PRIVILEGES: BitFlags<UserPrivilegeType> = make_bitflags!( } ); -impl std::fmt::Display for UserPrivilegeType { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { +impl Display for UserPrivilegeType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", match self { UserPrivilegeType::Usage => "USAGE", UserPrivilegeType::Create => "CREATE", @@ -132,6 +133,44 @@ impl std::fmt::Display for UserPrivilegeType { } } +impl From<databend_common_ast::ast::UserPrivilegeType> for UserPrivilegeType { + fn from(t: databend_common_ast::ast::UserPrivilegeType) -> Self { + match t { + databend_common_ast::ast::UserPrivilegeType::Usage => UserPrivilegeType::Usage, + databend_common_ast::ast::UserPrivilegeType::Select => UserPrivilegeType::Select, + databend_common_ast::ast::UserPrivilegeType::Insert => UserPrivilegeType::Insert, + databend_common_ast::ast::UserPrivilegeType::Update => UserPrivilegeType::Update, + databend_common_ast::ast::UserPrivilegeType::Delete => UserPrivilegeType::Delete, + databend_common_ast::ast::UserPrivilegeType::Create => UserPrivilegeType::Create, + databend_common_ast::ast::UserPrivilegeType::Drop => UserPrivilegeType::Drop, + databend_common_ast::ast::UserPrivilegeType::Alter => UserPrivilegeType::Alter, + databend_common_ast::ast::UserPrivilegeType::Super => UserPrivilegeType::Super, + databend_common_ast::ast::UserPrivilegeType::CreateUser => { + UserPrivilegeType::CreateUser + } + databend_common_ast::ast::UserPrivilegeType::CreateRole => { + UserPrivilegeType::CreateRole + } + databend_common_ast::ast::UserPrivilegeType::Grant => UserPrivilegeType::Grant, + databend_common_ast::ast::UserPrivilegeType::CreateStage => { + UserPrivilegeType::CreateStage + } + databend_common_ast::ast::UserPrivilegeType::DropRole => UserPrivilegeType::DropRole, + databend_common_ast::ast::UserPrivilegeType::DropUser => UserPrivilegeType::DropUser, + databend_common_ast::ast::UserPrivilegeType::CreateDataMask => { + UserPrivilegeType::CreateDataMask + } + databend_common_ast::ast::UserPrivilegeType::Ownership => UserPrivilegeType::Ownership, + databend_common_ast::ast::UserPrivilegeType::Read => UserPrivilegeType::Read, + databend_common_ast::ast::UserPrivilegeType::Write => UserPrivilegeType::Write, + databend_common_ast::ast::UserPrivilegeType::CreateDatabase => { + UserPrivilegeType::CreateDatabase + } + databend_common_ast::ast::UserPrivilegeType::Set => UserPrivilegeType::Set, + } + } +} + #[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Default, Debug, Eq, PartialEq)] pub struct UserPrivilegeSet { privileges: BitFlags<UserPrivilegeType>, @@ -223,8 +262,8 @@ impl UserPrivilegeSet { } } -impl std::fmt::Display for UserPrivilegeSet { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { +impl Display for UserPrivilegeSet { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "{}", diff --git a/src/meta/app/src/principal/user_stage.rs b/src/meta/app/src/principal/user_stage.rs index 04a5e7106b561..c63ea941138c7 100644 --- a/src/meta/app/src/principal/user_stage.rs +++ b/src/meta/app/src/principal/user_stage.rs @@ -405,32 +405,9 @@ impl Default for OnErrorMode { } } -impl Display for OnErrorMode { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - OnErrorMode::Continue => { - write!(f, "continue") - } - OnErrorMode::SkipFileNum(n) => { - if *n <= 1 { - write!(f, "skipfile") - } else { - write!(f, "skipfile_{}", n) - } - } - OnErrorMode::AbortNum(n) => { - if *n <= 1 { - write!(f, "abort") - } else { - write!(f, "abort_{}", n) - } - } - } - } -} - impl FromStr for OnErrorMode { type Err = String; + fn from_str(s: &str) -> std::result::Result<Self, String> { match s.to_uppercase().as_str() { "" | "ABORT" => Ok(OnErrorMode::AbortNum(1)), @@ -470,6 +447,40 @@ impl FromStr for OnErrorMode { } } +impl Display for OnErrorMode { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + OnErrorMode::Continue => { + write!(f, "continue") + } + OnErrorMode::SkipFileNum(n) => { + if *n <= 1 { + write!(f, "skipfile") + } else { + write!(f, "skipfile_{}", n) + } + } + OnErrorMode::AbortNum(n) => { + if *n <= 1 { + write!(f, "abort") + } else { + write!(f, "abort_{}", n) + } + } + } + } +} + +impl From<databend_common_ast::ast::OnErrorMode> for OnErrorMode { + fn from(opt: databend_common_ast::ast::OnErrorMode) -> Self { + match opt { + databend_common_ast::ast::OnErrorMode::Continue => OnErrorMode::Continue, + databend_common_ast::ast::OnErrorMode::SkipFileNum(n) => OnErrorMode::SkipFileNum(n), + databend_common_ast::ast::OnErrorMode::AbortNum(n) => OnErrorMode::AbortNum(n), + } + } +} + #[derive(serde::Serialize, serde::Deserialize, Clone, Default, Debug, Eq, PartialEq)] #[serde(default)] pub struct CopyOptions { @@ -487,21 +498,6 @@ pub struct CopyOptions { pub detailed_output: bool, } -impl Display for CopyOptions { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "OnErrorMode {}", self.on_error)?; - write!(f, "SizeLimit {}", self.size_limit)?; - write!(f, "MaxFiles {}", self.max_files)?; - write!(f, "SplitSize {}", self.split_size)?; - write!(f, "Purge {}", self.purge)?; - write!(f, "DisableVariantCheck {}", self.disable_variant_check)?; - write!(f, "ReturnFailedOnly {}", self.return_failed_only)?; - write!(f, "MaxFileSize {}", self.max_file_size)?; - write!(f, "Single {}", self.single)?; - write!(f, "DetailedOutput {}", self.detailed_output) - } -} - impl CopyOptions { pub fn apply(&mut self, opts: &BTreeMap<String, String>, ignore_unknown: bool) -> Result<()> { if opts.is_empty() { @@ -573,6 +569,21 @@ impl CopyOptions { } } +impl Display for CopyOptions { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "OnErrorMode {}", self.on_error)?; + write!(f, "SizeLimit {}", self.size_limit)?; + write!(f, "MaxFiles {}", self.max_files)?; + write!(f, "SplitSize {}", self.split_size)?; + write!(f, "Purge {}", self.purge)?; + write!(f, "DisableVariantCheck {}", self.disable_variant_check)?; + write!(f, "ReturnFailedOnly {}", self.return_failed_only)?; + write!(f, "MaxFileSize {}", self.max_file_size)?; + write!(f, "Single {}", self.single)?; + write!(f, "DetailedOutput {}", self.detailed_output) + } +} + #[derive(serde::Serialize, serde::Deserialize, Default, Clone, Debug, Eq, PartialEq)] #[serde(default)] pub struct StageInfo { diff --git a/src/meta/app/src/schema/catalog.rs b/src/meta/app/src/schema/catalog.rs index f89ae08301b2d..1d99a10b58f7c 100644 --- a/src/meta/app/src/schema/catalog.rs +++ b/src/meta/app/src/schema/catalog.rs @@ -31,12 +31,12 @@ pub enum CatalogType { Iceberg = 3, } -impl Display for CatalogType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - CatalogType::Default => write!(f, "DEFAULT"), - CatalogType::Hive => write!(f, "HIVE"), - CatalogType::Iceberg => write!(f, "ICEBERG"), +impl From<databend_common_ast::ast::CatalogType> for CatalogType { + fn from(catalog_type: databend_common_ast::ast::CatalogType) -> Self { + match catalog_type { + databend_common_ast::ast::CatalogType::Default => CatalogType::Default, + databend_common_ast::ast::CatalogType::Hive => CatalogType::Hive, + databend_common_ast::ast::CatalogType::Iceberg => CatalogType::Iceberg, } } } diff --git a/src/meta/app/src/schema/create_option.rs b/src/meta/app/src/schema/create_option.rs index dc853ba9fc70e..9c1144c0cce21 100644 --- a/src/meta/app/src/schema/create_option.rs +++ b/src/meta/app/src/schema/create_option.rs @@ -21,6 +21,20 @@ pub enum CreateOption { CreateOrReplace, } +impl From<databend_common_ast::ast::CreateOption> for CreateOption { + fn from(create_option: databend_common_ast::ast::CreateOption) -> Self { + match create_option { + databend_common_ast::ast::CreateOption::Create => CreateOption::Create, + databend_common_ast::ast::CreateOption::CreateIfNotExists => { + CreateOption::CreateIfNotExists + } + databend_common_ast::ast::CreateOption::CreateOrReplace => { + CreateOption::CreateOrReplace + } + } + } +} + impl From<CreateOption> for MatchSeq { /// Convert `CreateOption` to `MatchSeq`. /// diff --git a/src/meta/app/src/share/share.rs b/src/meta/app/src/share/share.rs index e096c5ae4040d..e80eb4bc382fc 100644 --- a/src/meta/app/src/share/share.rs +++ b/src/meta/app/src/share/share.rs @@ -140,6 +140,19 @@ impl Display for ShareGrantObjectName { } } +impl From<databend_common_ast::ast::ShareGrantObjectName> for ShareGrantObjectName { + fn from(obj: databend_common_ast::ast::ShareGrantObjectName) -> Self { + match obj { + databend_common_ast::ast::ShareGrantObjectName::Database(db_name) => { + ShareGrantObjectName::Database(db_name.name) + } + databend_common_ast::ast::ShareGrantObjectName::Table(db_name, table_name) => { + ShareGrantObjectName::Table(db_name.name, table_name.name) + } + } + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub enum ShareGrantObjectSeqAndId { // db_meta_seq, db_id, DatabaseMeta @@ -475,12 +488,18 @@ pub enum ShareGrantObjectPrivilege { Select = 1 << 2, } -impl Display for ShareGrantObjectPrivilege { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match *self { - ShareGrantObjectPrivilege::Usage => write!(f, "USAGE"), - ShareGrantObjectPrivilege::ReferenceUsage => write!(f, "REFERENCE_USAGE"), - ShareGrantObjectPrivilege::Select => write!(f, "SELECT"), +impl From<databend_common_ast::ast::ShareGrantObjectPrivilege> for ShareGrantObjectPrivilege { + fn from(privilege: databend_common_ast::ast::ShareGrantObjectPrivilege) -> Self { + match privilege { + databend_common_ast::ast::ShareGrantObjectPrivilege::Usage => { + ShareGrantObjectPrivilege::Usage + } + databend_common_ast::ast::ShareGrantObjectPrivilege::ReferenceUsage => { + ShareGrantObjectPrivilege::ReferenceUsage + } + databend_common_ast::ast::ShareGrantObjectPrivilege::Select => { + ShareGrantObjectPrivilege::Select + } } } } diff --git a/src/meta/app/src/share/share_name_ident.rs b/src/meta/app/src/share/share_name_ident.rs index 69ebffb1687ca..bbfc74855a067 100644 --- a/src/meta/app/src/share/share_name_ident.rs +++ b/src/meta/app/src/share/share_name_ident.rs @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +use databend_common_exception::Result; + +use crate::tenant::Tenant; use crate::tenant_key::ident::TIdent; use crate::tenant_key::raw::TIdentRaw; @@ -20,6 +23,8 @@ pub type ShareNameIdent = TIdent<Resource>; /// Share name as value. pub type ShareNameIdentRaw = TIdentRaw<Resource>; +use anyerror::func_name; +use databend_common_exception::ErrorCode; pub use kvapi_impl::Resource; impl TIdent<Resource> { @@ -34,6 +39,15 @@ impl TIdentRaw<Resource> { } } +impl TryFrom<databend_common_ast::ast::ShareNameIdent> for ShareNameIdent { + type Error = ErrorCode; + + fn try_from(ident: databend_common_ast::ast::ShareNameIdent) -> Result<Self> { + let tenant = Tenant::new_or_err(ident.tenant.name, func_name!())?; + Ok(ShareNameIdent::new(tenant, ident.share)) + } +} + mod kvapi_impl { use databend_common_meta_kvapi::kvapi; diff --git a/src/meta/proto-conv/src/stage_from_to_protobuf_impl.rs b/src/meta/proto-conv/src/stage_from_to_protobuf_impl.rs index 14c5f1f185801..eb94ad24040e3 100644 --- a/src/meta/proto-conv/src/stage_from_to_protobuf_impl.rs +++ b/src/meta/proto-conv/src/stage_from_to_protobuf_impl.rs @@ -21,10 +21,10 @@ use chrono::DateTime; use chrono::Utc; use databend_common_meta_app as mt; use databend_common_protos::pb; +use mt::principal::FileFormatOptionsReader; use num::FromPrimitive; use crate::reader_check_msg; -use crate::stage_from_to_protobuf_impl::mt::principal::FileFormatOptionsAst; use crate::FromToProto; use crate::FromToProtoEnum; use crate::Incompatible; @@ -185,8 +185,8 @@ impl FromToProto for mt::principal::StageInfo { }, (None, Some(p)) => { let options = mt::principal::FileFormatOptions::from_pb(p)?; - let options = FileFormatOptionsAst{options: options.to_map()}; - mt::principal::FileFormatParams::try_from_ast(options, true).map_err(|e| Incompatible { + let reader = FileFormatOptionsReader::from_map(options.to_map()); + mt::principal::FileFormatParams::try_from_reader(reader, true).map_err(|e| Incompatible { reason: format!("fail to convert StageInfo.file_format_options to StageInfo.file_format_params: {e:?}"), })? }, diff --git a/src/query/ast/Cargo.toml b/src/query/ast/Cargo.toml index 87d419d9a2257..c97d92fb42189 100644 --- a/src/query/ast/Cargo.toml +++ b/src/query/ast/Cargo.toml @@ -19,7 +19,6 @@ ignored = ["geos"] databend-common-base = { path = "../../common/base" } databend-common-exception = { path = "../../common/exception" } databend-common-io = { path = "../../common/io" } -databend-common-meta-app = { path = "../../meta/app" } # Crates.io dependencies derive-visitor = { workspace = true } diff --git a/src/query/ast/src/ast/escape.rs b/src/query/ast/src/ast/escape.rs new file mode 100644 index 0000000000000..e08f99be53cc2 --- /dev/null +++ b/src/query/ast/src/ast/escape.rs @@ -0,0 +1,40 @@ +// Copyright 2021 Datafuse Labs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/// Escape only the specified `chars` in a string. +pub(crate) fn escape_specified(key: &str, chars: &[u8]) -> String { + let mut new_key = Vec::with_capacity(key.len()); + + for char in key.as_bytes() { + if chars.contains(char) { + new_key.push(b'%'); + new_key.push(hex(*char / 16)); + new_key.push(hex(*char % 16)); + } else { + new_key.push(*char); + } + } + + // Safe unwrap(): there are no invalid utf char in it. + String::from_utf8(new_key).unwrap() +} + +// Encode 4bit number to [0-9a-f] +fn hex(num: u8) -> u8 { + match num { + 0..=9 => b'0' + num, + 10..=15 => b'a' + (num - 10), + unreachable => unreachable!("Unreachable branch num = {}", unreachable), + } +} diff --git a/src/query/ast/src/ast/format/ast_format.rs b/src/query/ast/src/ast/format/ast_format.rs index 8721b328e4c96..e90b81906ba54 100644 --- a/src/query/ast/src/ast/format/ast_format.rs +++ b/src/query/ast/src/ast/format/ast_format.rs @@ -18,8 +18,6 @@ use std::fmt::Display; use databend_common_exception::Result; use databend_common_exception::Span; -use databend_common_meta_app::principal::PrincipalIdentity; -use databend_common_meta_app::principal::UserIdentity; use itertools::Itertools; use crate::ast::*; @@ -2000,11 +1998,11 @@ impl<'ast> Visitor<'ast> for AstFormatVisitor { fn visit_create_user(&mut self, stmt: &'ast CreateUserStmt) { let mut children = Vec::new(); - let user_name = format!("User {}", stmt.user.display()); + let user_name = format!("User {}", stmt.user); let user_format_ctx = AstFormatContext::new(user_name); children.push(FormatTreeNode::new(user_format_ctx)); if let Some(auth_type) = &stmt.auth_option.auth_type { - let auth_type_name = format!("AuthType {}", auth_type.to_str()); + let auth_type_name = format!("AuthType {}", auth_type); let auth_type_format_ctx = AstFormatContext::new(auth_type_name); children.push(FormatTreeNode::new(auth_type_format_ctx)); } @@ -2039,13 +2037,13 @@ impl<'ast> Visitor<'ast> for AstFormatVisitor { fn visit_alter_user(&mut self, stmt: &'ast AlterUserStmt) { let mut children = Vec::new(); if let Some(user) = &stmt.user { - let user_name = format!("User {}", user.display()); + let user_name = format!("User {}", user); let user_format_ctx = AstFormatContext::new(user_name); children.push(FormatTreeNode::new(user_format_ctx)); } if let Some(auth_option) = &stmt.auth_option { if let Some(auth_type) = &auth_option.auth_type { - let auth_type_name = format!("AuthType {}", auth_type.to_str()); + let auth_type_name = format!("AuthType {}", auth_type); let auth_type_format_ctx = AstFormatContext::new(auth_type_name); children.push(FormatTreeNode::new(auth_type_format_ctx)); } @@ -2079,7 +2077,7 @@ impl<'ast> Visitor<'ast> for AstFormatVisitor { } fn visit_drop_user(&mut self, _if_exists: bool, user: &'ast UserIdentity) { - let user_name = format!("User {}", user.display()); + let user_name = format!("User {}", user); let user_format_ctx = AstFormatContext::new(user_name); let child = FormatTreeNode::new(user_format_ctx); @@ -2144,7 +2142,7 @@ impl<'ast> Visitor<'ast> for AstFormatVisitor { } }; let principal_name = match &grant.principal { - PrincipalIdentity::User(user) => format!("User {}", user.display()), + PrincipalIdentity::User(user) => format!("User {}", user), PrincipalIdentity::Role(role) => format!("Role {}", role), }; let principal_format_ctx = AstFormatContext::new(principal_name); @@ -2160,7 +2158,7 @@ impl<'ast> Visitor<'ast> for AstFormatVisitor { let mut children = Vec::new(); if let Some(principal) = &principal { let principal_name = match principal { - PrincipalIdentity::User(user) => format!("User {}", user.display()), + PrincipalIdentity::User(user) => format!("User {}", user), PrincipalIdentity::Role(role) => format!("Role {}", role), }; let principal_format_ctx = AstFormatContext::new(principal_name); @@ -2198,7 +2196,7 @@ impl<'ast> Visitor<'ast> for AstFormatVisitor { } }; let principal_name = match &revoke.principal { - PrincipalIdentity::User(user) => format!("User {}", user.display()), + PrincipalIdentity::User(user) => format!("User {}", user), PrincipalIdentity::Role(role) => format!("Role {}", role), }; let principal_format_ctx = AstFormatContext::new(principal_name); diff --git a/src/query/ast/src/ast/format/syntax/ddl.rs b/src/query/ast/src/ast/format/syntax/ddl.rs index 1b057ff717b14..d6094f54e4708 100644 --- a/src/query/ast/src/ast/format/syntax/ddl.rs +++ b/src/query/ast/src/ast/format/syntax/ddl.rs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use databend_common_meta_app::schema::CreateOption; use pretty::RcDoc; use super::expr::pretty_expr; @@ -25,6 +24,7 @@ use crate::ast::AddColumnOption; use crate::ast::AlterTableAction; use crate::ast::AlterTableStmt; use crate::ast::AlterViewStmt; +use crate::ast::CreateOption; use crate::ast::CreateStreamStmt; use crate::ast::CreateTableSource; use crate::ast::CreateTableStmt; diff --git a/src/query/ast/src/ast/mod.rs b/src/query/ast/src/ast/mod.rs index f06ebc5addbb2..40c5f5182253c 100644 --- a/src/query/ast/src/ast/mod.rs +++ b/src/query/ast/src/ast/mod.rs @@ -14,6 +14,7 @@ #[allow(clippy::module_inception)] mod common; +mod escape; mod expr; mod format; mod query; diff --git a/src/query/ast/src/ast/statements/catalog.rs b/src/query/ast/src/ast/statements/catalog.rs index 5bbed5c8e123e..d7101f19d884a 100644 --- a/src/query/ast/src/ast/statements/catalog.rs +++ b/src/query/ast/src/ast/statements/catalog.rs @@ -16,11 +16,11 @@ use std::collections::BTreeMap; use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CatalogType; use derive_visitor::Drive; use derive_visitor::DriveMut; use crate::ast::write_comma_separated_string_map; +use crate::ast::CatalogType; use crate::ast::Identifier; use crate::ast::ShowLimit; diff --git a/src/query/ast/src/ast/statements/connection.rs b/src/query/ast/src/ast/statements/connection.rs index 985a3e8fedbc8..299cc0c21bd7d 100644 --- a/src/query/ast/src/ast/statements/connection.rs +++ b/src/query/ast/src/ast/statements/connection.rs @@ -16,10 +16,10 @@ use std::collections::BTreeMap; use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; +use crate::ast::CreateOption; use crate::ast::Identifier; #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] @@ -29,7 +29,6 @@ pub struct CreateConnectionStmt { pub storage_type: String, #[drive(skip)] pub storage_params: BTreeMap<String, String>, - #[drive(skip)] pub create_option: CreateOption, } diff --git a/src/query/ast/src/ast/statements/copy.rs b/src/query/ast/src/ast/statements/copy.rs index 9370d252343d4..d61ba041bda06 100644 --- a/src/query/ast/src/ast/statements/copy.rs +++ b/src/query/ast/src/ast/statements/copy.rs @@ -19,15 +19,10 @@ use std::fmt::Formatter; use std::io::Error; use std::io::ErrorKind; use std::io::Result; -use std::str::FromStr; use databend_common_base::base::mask_string; use databend_common_exception::ErrorCode; use databend_common_io::escape_string_with_quote; -use databend_common_meta_app::principal::CopyOptions; -use databend_common_meta_app::principal::FileFormatOptionsAst; -use databend_common_meta_app::principal::OnErrorMode; -use databend_common_meta_app::principal::COPY_MAX_FILES_PER_COMMIT; use derive_visitor::Drive; use derive_visitor::DriveMut; use itertools::Itertools; @@ -105,36 +100,6 @@ impl CopyIntoTableStmt { CopyIntoTableOption::OnError(v) => self.on_error = v, } } - - pub fn apply_to_copy_option( - &self, - copy_options: &mut CopyOptions, - ) -> databend_common_exception::Result<()> { - copy_options.on_error = - OnErrorMode::from_str(&self.on_error).map_err(ErrorCode::SyntaxException)?; - - if self.size_limit != 0 { - copy_options.size_limit = self.size_limit; - } - - copy_options.split_size = self.split_size; - copy_options.purge = self.purge; - copy_options.disable_variant_check = self.disable_variant_check; - copy_options.return_failed_only = self.return_failed_only; - - if self.max_files != 0 { - copy_options.max_files = self.max_files; - } - - if !(copy_options.purge && self.force) && copy_options.max_files > COPY_MAX_FILES_PER_COMMIT - { - return Err(ErrorCode::InvalidArgument(format!( - "max_files {} is too large, max_files should be less than {COPY_MAX_FILES_PER_COMMIT}", - copy_options.max_files - ))); - } - Ok(()) - } } impl Display for CopyIntoTableStmt { @@ -513,15 +478,6 @@ impl FileFormatOptions { pub fn is_empty(&self) -> bool { self.options.is_empty() } - - pub fn to_meta_ast(&self) -> FileFormatOptionsAst { - let options = self - .options - .iter() - .map(|(k, v)| (k.clone(), v.to_meta_value())) - .collect(); - FileFormatOptionsAst { options } - } } impl Display for FileFormatOptions { diff --git a/src/query/ast/src/ast/statements/data_mask.rs b/src/query/ast/src/ast/statements/data_mask.rs index d6a12c3a4a259..b629e95d0a316 100644 --- a/src/query/ast/src/ast/statements/data_mask.rs +++ b/src/query/ast/src/ast/statements/data_mask.rs @@ -15,10 +15,10 @@ use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; +use crate::ast::CreateOption; use crate::ast::Expr; use crate::ast::TypeName; @@ -40,7 +40,6 @@ pub struct DataMaskPolicy { #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreateDatamaskPolicyStmt { - #[drive(skip)] pub create_option: CreateOption, #[drive(skip)] pub name: String, diff --git a/src/query/ast/src/ast/statements/database.rs b/src/query/ast/src/ast/statements/database.rs index c3a5f1a180e1e..3556aabe91585 100644 --- a/src/query/ast/src/ast/statements/database.rs +++ b/src/query/ast/src/ast/statements/database.rs @@ -15,16 +15,15 @@ use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; -use databend_common_meta_app::share::share_name_ident::ShareNameIdent; -use databend_common_meta_app::KeyWithTenant; use derive_visitor::Drive; use derive_visitor::DriveMut; use crate::ast::statements::show::ShowLimit; use crate::ast::write_dot_separated_list; +use crate::ast::CreateOption; use crate::ast::DatabaseRef; use crate::ast::Identifier; +use crate::ast::ShareNameIdent; #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct ShowDatabasesStmt { @@ -69,12 +68,10 @@ impl Display for ShowCreateDatabaseStmt { #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct CreateDatabaseStmt { - #[drive(skip)] pub create_option: CreateOption, pub database: DatabaseRef, pub engine: Option<DatabaseEngine>, pub options: Vec<SQLProperty>, - #[drive(skip)] pub from_share: Option<ShareNameIdent>, } @@ -95,12 +92,7 @@ impl Display for CreateDatabaseStmt { write!(f, " ENGINE = {engine}")?; } if let Some(from_share) = &self.from_share { - write!( - f, - " FROM SHARE {}.{}", - from_share.tenant_name(), - from_share.name() - )?; + write!(f, " FROM SHARE {from_share}",)?; } // TODO(leiysky): display rest information diff --git a/src/query/ast/src/ast/statements/dynamic_table.rs b/src/query/ast/src/ast/statements/dynamic_table.rs index 0b3c863ecfdb9..8fa93f61d28d5 100644 --- a/src/query/ast/src/ast/statements/dynamic_table.rs +++ b/src/query/ast/src/ast/statements/dynamic_table.rs @@ -16,13 +16,13 @@ use std::collections::BTreeMap; use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; use crate::ast::write_comma_separated_list; use crate::ast::write_dot_separated_list; use crate::ast::write_space_separated_string_map; +use crate::ast::CreateOption; use crate::ast::CreateTableSource; use crate::ast::Expr; use crate::ast::Identifier; @@ -92,7 +92,6 @@ impl Display for InitializeMode { #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreateDynamicTableStmt { - #[drive(skip)] pub create_option: CreateOption, #[drive(skip)] pub transient: bool, diff --git a/src/query/ast/src/ast/statements/index.rs b/src/query/ast/src/ast/statements/index.rs index 3a248f7cee982..25f41bb7fb989 100644 --- a/src/query/ast/src/ast/statements/index.rs +++ b/src/query/ast/src/ast/statements/index.rs @@ -16,20 +16,19 @@ use std::collections::BTreeMap; use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; use crate::ast::write_comma_separated_list; use crate::ast::write_dot_separated_list; use crate::ast::write_space_separated_string_map; +use crate::ast::CreateOption; use crate::ast::Identifier; use crate::ast::Query; #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreateIndexStmt { pub index_type: TableIndexType, - #[drive(skip)] pub create_option: CreateOption, pub index_name: Identifier, @@ -116,7 +115,6 @@ impl Display for RefreshIndexStmt { #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreateInvertedIndexStmt { - #[drive(skip)] pub create_option: CreateOption, pub index_name: Identifier, diff --git a/src/query/ast/src/ast/statements/mod.rs b/src/query/ast/src/ast/statements/mod.rs index 5e5b81625e50f..b1e7c8ae756a1 100644 --- a/src/query/ast/src/ast/statements/mod.rs +++ b/src/query/ast/src/ast/statements/mod.rs @@ -34,6 +34,7 @@ mod notification; mod password_policy; mod pipe; mod presign; +mod principal; mod priority; mod procedure; mod replace; @@ -75,6 +76,7 @@ pub use notification::*; pub use password_policy::*; pub use pipe::*; pub use presign::*; +pub use principal::*; pub use priority::*; pub use procedure::*; pub use replace::*; diff --git a/src/query/ast/src/ast/statements/network_policy.rs b/src/query/ast/src/ast/statements/network_policy.rs index 3e0dbc3db8a3a..209581759f996 100644 --- a/src/query/ast/src/ast/statements/network_policy.rs +++ b/src/query/ast/src/ast/statements/network_policy.rs @@ -15,13 +15,13 @@ use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; +use crate::ast::CreateOption; + #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct CreateNetworkPolicyStmt { - #[drive(skip)] pub create_option: CreateOption, #[drive(skip)] pub name: String, diff --git a/src/query/ast/src/ast/statements/password_policy.rs b/src/query/ast/src/ast/statements/password_policy.rs index 9d64e082aebb4..8ffcf6680fa9b 100644 --- a/src/query/ast/src/ast/statements/password_policy.rs +++ b/src/query/ast/src/ast/statements/password_policy.rs @@ -15,13 +15,13 @@ use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; +use crate::ast::CreateOption; + #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreatePasswordPolicyStmt { - #[drive(skip)] pub create_option: CreateOption, #[drive(skip)] pub name: String, diff --git a/src/query/ast/src/ast/statements/principal.rs b/src/query/ast/src/ast/statements/principal.rs new file mode 100644 index 0000000000000..ea5464cef6a39 --- /dev/null +++ b/src/query/ast/src/ast/statements/principal.rs @@ -0,0 +1,299 @@ +// Copyright 2021 Datafuse Labs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::fmt::Display; +use std::fmt::Formatter; + +use derive_visitor::Drive; +use derive_visitor::DriveMut; + +use crate::ast::escape::escape_specified; +use crate::ast::Identifier; + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub struct ShareNameIdent { + pub tenant: Identifier, + pub share: Identifier, +} + +impl Display for ShareNameIdent { + fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { + write!(f, "{}.{}", self.tenant, self.share) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub struct UserIdentity { + #[drive(skip)] + pub username: String, + #[drive(skip)] + pub hostname: String, +} + +impl UserIdentity { + const ESCAPE_CHARS: [u8; 2] = [b'\'', b'@']; +} + +impl Display for UserIdentity { + fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { + write!( + f, + "'{}'@'{}'", + escape_specified(&self.username, &Self::ESCAPE_CHARS), + escape_specified(&self.hostname, &Self::ESCAPE_CHARS), + ) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub enum PrincipalIdentity { + User(UserIdentity), + Role(#[drive(skip)] String), +} + +impl Display for PrincipalIdentity { + fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { + match self { + PrincipalIdentity::User(u) => write!(f, " USER {u}"), + PrincipalIdentity::Role(r) => write!(f, " ROLE '{r}'"), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub enum CreateOption { + Create, + CreateIfNotExists, + CreateOrReplace, +} + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub enum AuthType { + NoPassword, + Sha256Password, + DoubleSha1Password, + JWT, +} + +impl Display for AuthType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", match self { + AuthType::NoPassword => "no_password", + AuthType::Sha256Password => "sha256_password", + AuthType::DoubleSha1Password => "double_sha1_password", + AuthType::JWT => "jwt", + }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub enum CatalogType { + Default, + Hive, + Iceberg, +} + +impl Display for CatalogType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + CatalogType::Default => write!(f, "DEFAULT"), + CatalogType::Hive => write!(f, "HIVE"), + CatalogType::Iceberg => write!(f, "ICEBERG"), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub enum UserPrivilegeType { + // UsagePrivilege is a synonym for “no privileges”, if object is udf, means can use this udf + Usage, + // Privilege to select rows from tables in a database. + Select, + // Privilege to insert into tables in a database. + Insert, + // Privilege to update rows in a table + Update, + // Privilege to delete rows in a table + Delete, + // Privilege to create databases or tables. + Create, + // Privilege to drop databases or tables. + Drop, + // Privilege to alter databases or tables. + Alter, + // Privilege to Kill query, Set global configs, etc. + Super, + // Privilege to Create User. + CreateUser, + // Privilege to Create Role. + CreateRole, + // Privilege to Grant/Revoke privileges to users or roles + Grant, + // Privilege to Create Stage. + CreateStage, + // Privilege to Drop role. + DropRole, + // Privilege to Drop user. + DropUser, + // Privilege to Create/Drop DataMask. + CreateDataMask, + // Privilege to Own a databend object such as database/table. + Ownership, + // Privilege to Read stage + Read, + // Privilege to Write stage + Write, + // Privilege to Create database + CreateDatabase, + // Discard Privilege Type + Set, +} + +impl Display for UserPrivilegeType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", match self { + UserPrivilegeType::Usage => "USAGE", + UserPrivilegeType::Create => "CREATE", + UserPrivilegeType::Update => "UPDATE", + UserPrivilegeType::Select => "SELECT", + UserPrivilegeType::Insert => "INSERT", + UserPrivilegeType::Delete => "DELETE", + UserPrivilegeType::Drop => "DROP", + UserPrivilegeType::Alter => "ALTER", + UserPrivilegeType::Super => "SUPER", + UserPrivilegeType::CreateUser => "CREATE USER", + UserPrivilegeType::DropUser => "DROP USER", + UserPrivilegeType::CreateRole => "CREATE ROLE", + UserPrivilegeType::DropRole => "DROP ROLE", + UserPrivilegeType::CreateStage => "CREATE STAGE", + UserPrivilegeType::Grant => "GRANT", + UserPrivilegeType::Set => "SET", + UserPrivilegeType::CreateDataMask => "CREATE DATAMASK", + UserPrivilegeType::Ownership => "OWNERSHIP", + UserPrivilegeType::Read => "Read", + UserPrivilegeType::Write => "Write", + UserPrivilegeType::CreateDatabase => "CREATE DATABASE", + }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub enum ShareGrantObjectName { + // database name + Database(Identifier), + // database name, table name + Table(Identifier, Identifier), +} + +impl Display for ShareGrantObjectName { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + ShareGrantObjectName::Database(db) => { + write!(f, "DATABASE {db}") + } + ShareGrantObjectName::Table(db, table) => { + write!(f, "TABLE {db}.{table}") + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub enum ShareGrantObjectPrivilege { + // For DATABASE or SCHEMA + Usage, + // For DATABASE + ReferenceUsage, + // For TABLE or VIEW + Select, +} + +impl Display for ShareGrantObjectPrivilege { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match *self { + ShareGrantObjectPrivilege::Usage => write!(f, "USAGE"), + ShareGrantObjectPrivilege::ReferenceUsage => write!(f, "REFERENCE_USAGE"), + ShareGrantObjectPrivilege::Select => write!(f, "SELECT"), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub struct CopyOptions { + pub on_error: OnErrorMode, + #[drive(skip)] + pub size_limit: usize, + #[drive(skip)] + pub max_files: usize, + #[drive(skip)] + pub split_size: usize, + #[drive(skip)] + pub purge: bool, + #[drive(skip)] + pub disable_variant_check: bool, + #[drive(skip)] + pub return_failed_only: bool, + #[drive(skip)] + pub max_file_size: usize, + #[drive(skip)] + pub single: bool, + #[drive(skip)] + pub detailed_output: bool, +} + +impl Display for CopyOptions { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "OnErrorMode {}", self.on_error)?; + write!(f, "SizeLimit {}", self.size_limit)?; + write!(f, "MaxFiles {}", self.max_files)?; + write!(f, "SplitSize {}", self.split_size)?; + write!(f, "Purge {}", self.purge)?; + write!(f, "DisableVariantCheck {}", self.disable_variant_check)?; + write!(f, "ReturnFailedOnly {}", self.return_failed_only)?; + write!(f, "MaxFileSize {}", self.max_file_size)?; + write!(f, "Single {}", self.single)?; + write!(f, "DetailedOutput {}", self.detailed_output) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] +pub enum OnErrorMode { + Continue, + SkipFileNum(#[drive(skip)] u64), + AbortNum(#[drive(skip)] u64), +} + +impl Display for OnErrorMode { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + OnErrorMode::Continue => { + write!(f, "continue") + } + OnErrorMode::SkipFileNum(n) => { + if *n <= 1 { + write!(f, "skipfile") + } else { + write!(f, "skipfile_{}", n) + } + } + OnErrorMode::AbortNum(n) => { + if *n <= 1 { + write!(f, "abort") + } else { + write!(f, "abort_{}", n) + } + } + } + } +} diff --git a/src/query/ast/src/ast/statements/sequence.rs b/src/query/ast/src/ast/statements/sequence.rs index 4ab21543e6bca..fe83fa3933bea 100644 --- a/src/query/ast/src/ast/statements/sequence.rs +++ b/src/query/ast/src/ast/statements/sequence.rs @@ -15,15 +15,14 @@ use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; +use crate::ast::CreateOption; use crate::ast::Identifier; #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreateSequenceStmt { - #[drive(skip)] pub create_option: CreateOption, pub sequence: Identifier, #[drive(skip)] diff --git a/src/query/ast/src/ast/statements/share.rs b/src/query/ast/src/ast/statements/share.rs index 97cce82e92d93..c9ff82e728f7a 100644 --- a/src/query/ast/src/ast/statements/share.rs +++ b/src/query/ast/src/ast/statements/share.rs @@ -16,20 +16,19 @@ use std::collections::BTreeMap; use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; -use databend_common_meta_app::share::ShareGrantObjectName; -use databend_common_meta_app::share::ShareGrantObjectPrivilege; use derive_visitor::Drive; use derive_visitor::DriveMut; use itertools::Itertools; -use super::UriLocation; use crate::ast::write_comma_separated_string_map; +use crate::ast::CreateOption; use crate::ast::Identifier; +use crate::ast::ShareGrantObjectName; +use crate::ast::ShareGrantObjectPrivilege; +use crate::ast::UriLocation; #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct CreateShareEndpointStmt { - #[drive(skip)] pub create_option: CreateOption, pub endpoint: Identifier, pub url: UriLocation, @@ -107,9 +106,7 @@ impl Display for DropShareStmt { #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct GrantShareObjectStmt { pub share: Identifier, - #[drive(skip)] pub object: ShareGrantObjectName, - #[drive(skip)] pub privilege: ShareGrantObjectPrivilege, } @@ -128,9 +125,7 @@ impl Display for GrantShareObjectStmt { #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct RevokeShareObjectStmt { pub share: Identifier, - #[drive(skip)] pub object: ShareGrantObjectName, - #[drive(skip)] pub privilege: ShareGrantObjectPrivilege, } @@ -230,7 +225,6 @@ impl Display for DropShareEndpointStmt { #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct ShowObjectGrantPrivilegesStmt { - #[drive(skip)] pub object: ShareGrantObjectName, } diff --git a/src/query/ast/src/ast/statements/stage.rs b/src/query/ast/src/ast/statements/stage.rs index 02f525d0085e9..f44d1a3a09bdd 100644 --- a/src/query/ast/src/ast/statements/stage.rs +++ b/src/query/ast/src/ast/statements/stage.rs @@ -17,18 +17,17 @@ use std::default::Default; use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; use crate::ast::write_comma_separated_string_list; use crate::ast::write_comma_separated_string_map; +use crate::ast::CreateOption; use crate::ast::FileFormatOptions; use crate::ast::UriLocation; #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct CreateStageStmt { - #[drive(skip)] pub create_option: CreateOption, #[drive(skip)] pub stage_name: String, diff --git a/src/query/ast/src/ast/statements/statement.rs b/src/query/ast/src/ast/statements/statement.rs index 6b2554d8ad20e..571dd471abe55 100644 --- a/src/query/ast/src/ast/statements/statement.rs +++ b/src/query/ast/src/ast/statements/statement.rs @@ -16,9 +16,6 @@ use std::fmt::Display; use std::fmt::Formatter; use databend_common_io::escape_string_with_quote; -use databend_common_meta_app::principal::PrincipalIdentity; -use databend_common_meta_app::principal::UserIdentity; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; use itertools::Itertools; @@ -28,6 +25,7 @@ use super::*; use crate::ast::statements::connection::CreateConnectionStmt; use crate::ast::statements::pipe::CreatePipeStmt; use crate::ast::statements::task::CreateTaskStmt; +use crate::ast::CreateOption; use crate::ast::Expr; use crate::ast::Identifier; use crate::ast::Query; @@ -186,7 +184,6 @@ pub enum Statement { DropUser { #[drive(skip)] if_exists: bool, - #[drive(skip)] user: UserIdentity, }, ShowRoles, @@ -204,7 +201,6 @@ pub enum Statement { }, Grant(GrantStmt), ShowGrants { - #[drive(skip)] principal: Option<PrincipalIdentity>, }, Revoke(RevokeStmt), @@ -251,7 +247,6 @@ pub enum Statement { // UserDefinedFileFormat CreateFileFormat { - #[drive(skip)] create_option: CreateOption, #[drive(skip)] name: String, @@ -587,7 +582,7 @@ impl Display for Statement { if *if_exists { write!(f, " IF EXISTS")?; } - write!(f, " {}", user.display())?; + write!(f, " {}", user)?; } Statement::CreateRole { if_not_exists, diff --git a/src/query/ast/src/ast/statements/stream.rs b/src/query/ast/src/ast/statements/stream.rs index 66fafeee06248..3ceacda3c3731 100644 --- a/src/query/ast/src/ast/statements/stream.rs +++ b/src/query/ast/src/ast/statements/stream.rs @@ -15,18 +15,17 @@ use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; use crate::ast::write_dot_separated_list; +use crate::ast::CreateOption; use crate::ast::Identifier; use crate::ast::ShowLimit; use crate::ast::TimeTravelPoint; #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreateStreamStmt { - #[drive(skip)] pub create_option: CreateOption, pub catalog: Option<Identifier>, pub database: Option<Identifier>, diff --git a/src/query/ast/src/ast/statements/table.rs b/src/query/ast/src/ast/statements/table.rs index 75dbc9970cb90..e979aa449d66b 100644 --- a/src/query/ast/src/ast/statements/table.rs +++ b/src/query/ast/src/ast/statements/table.rs @@ -17,7 +17,6 @@ use std::fmt::Display; use std::fmt::Formatter; use std::time::Duration; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; @@ -26,6 +25,7 @@ use crate::ast::write_comma_separated_list; use crate::ast::write_comma_separated_string_map; use crate::ast::write_dot_separated_list; use crate::ast::write_space_separated_string_map; +use crate::ast::CreateOption; use crate::ast::Expr; use crate::ast::Identifier; use crate::ast::Query; @@ -132,7 +132,6 @@ impl Display for ShowDropTablesStmt { #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreateTableStmt { - #[drive(skip)] pub create_option: CreateOption, pub catalog: Option<Identifier>, pub database: Option<Identifier>, diff --git a/src/query/ast/src/ast/statements/udf.rs b/src/query/ast/src/ast/statements/udf.rs index 6a1206718341c..ff033ba32c579 100644 --- a/src/query/ast/src/ast/statements/udf.rs +++ b/src/query/ast/src/ast/statements/udf.rs @@ -15,11 +15,11 @@ use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; use crate::ast::write_comma_separated_list; +use crate::ast::CreateOption; use crate::ast::Expr; use crate::ast::Identifier; use crate::ast::TypeName; @@ -102,7 +102,6 @@ impl Display for UDFDefinition { #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreateUDFStmt { - #[drive(skip)] pub create_option: CreateOption, pub udf_name: Identifier, #[drive(skip)] diff --git a/src/query/ast/src/ast/statements/user.rs b/src/query/ast/src/ast/statements/user.rs index 8d291e9d3f24a..be79a6139cebc 100644 --- a/src/query/ast/src/ast/statements/user.rs +++ b/src/query/ast/src/ast/statements/user.rs @@ -15,23 +15,19 @@ use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::principal::AuthType; -use databend_common_meta_app::principal::PrincipalIdentity; -use databend_common_meta_app::principal::UserIdentity; -use databend_common_meta_app::principal::UserOption; -use databend_common_meta_app::principal::UserOptionFlag; -use databend_common_meta_app::principal::UserPrivilegeType; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; use crate::ast::write_comma_separated_list; +use crate::ast::AuthType; +use crate::ast::CreateOption; +use crate::ast::PrincipalIdentity; +use crate::ast::UserIdentity; +use crate::ast::UserPrivilegeType; #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct CreateUserStmt { - #[drive(skip)] pub create_option: CreateOption, - #[drive(skip)] pub user: UserIdentity, pub auth_option: AuthOption, pub user_options: Vec<UserOptionItem>, @@ -47,7 +43,7 @@ impl Display for CreateUserStmt { if let CreateOption::CreateIfNotExists = self.create_option { write!(f, " IF NOT EXISTS")?; } - write!(f, " {} IDENTIFIED", self.user.display())?; + write!(f, " {} IDENTIFIED", self.user)?; write!(f, " {}", self.auth_option)?; if !self.user_options.is_empty() { write!(f, " WITH ")?; @@ -60,7 +56,6 @@ impl Display for CreateUserStmt { #[derive(Debug, Clone, PartialEq, Eq, Default, Drive, DriveMut)] pub struct AuthOption { - #[drive(skip)] pub auth_type: Option<AuthType>, #[drive(skip)] pub password: Option<String>, @@ -69,7 +64,7 @@ pub struct AuthOption { impl Display for AuthOption { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { if let Some(auth_type) = &self.auth_type { - write!(f, "WITH {} ", auth_type.to_str())?; + write!(f, "WITH {auth_type} ")?; } if let Some(password) = &self.password { write!(f, "BY '{password}'")?; @@ -82,7 +77,6 @@ impl Display for AuthOption { #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct AlterUserStmt { // None means current user - #[drive(skip)] pub user: Option<UserIdentity>, // None means no change to make pub auth_option: Option<AuthOption>, @@ -93,7 +87,7 @@ impl Display for AlterUserStmt { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "ALTER USER")?; if let Some(user) = &self.user { - write!(f, " {}", user.display())?; + write!(f, " {}", user)?; } else { write!(f, " USER()")?; } @@ -112,7 +106,6 @@ impl Display for AlterUserStmt { #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct GrantStmt { pub source: AccountMgrSource, - #[drive(skip)] pub principal: PrincipalIdentity, } @@ -129,7 +122,6 @@ impl Display for GrantStmt { #[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)] pub struct RevokeStmt { pub source: AccountMgrSource, - #[drive(skip)] pub principal: PrincipalIdentity, } @@ -150,7 +142,6 @@ pub enum AccountMgrSource { role: String, }, Privs { - #[drive(skip)] privileges: Vec<UserPrivilegeType>, level: AccountMgrLevel, }, @@ -241,22 +232,6 @@ pub enum UserOptionItem { UnsetPasswordPolicy, } -impl UserOptionItem { - pub fn apply(&self, option: &mut UserOption) { - match self { - Self::TenantSetting(enabled) => { - option.switch_option_flag(UserOptionFlag::TenantSetting, *enabled); - } - Self::DefaultRole(v) => option.set_default_role(Some(v.clone())), - Self::SetNetworkPolicy(v) => option.set_network_policy(Some(v.clone())), - Self::UnsetNetworkPolicy => option.set_network_policy(None), - Self::SetPasswordPolicy(v) => option.set_password_policy(Some(v.clone())), - Self::UnsetPasswordPolicy => option.set_password_policy(None), - Self::Disabled(v) => option.set_disabled(Some(*v)), - } - } -} - impl Display for UserOptionItem { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { match self { diff --git a/src/query/ast/src/ast/statements/view.rs b/src/query/ast/src/ast/statements/view.rs index a1ffbcedde977..35a563772069c 100644 --- a/src/query/ast/src/ast/statements/view.rs +++ b/src/query/ast/src/ast/statements/view.rs @@ -15,19 +15,18 @@ use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; use crate::ast::write_comma_separated_list; use crate::ast::write_dot_separated_list; +use crate::ast::CreateOption; use crate::ast::Identifier; use crate::ast::Query; use crate::ast::ShowLimit; #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreateViewStmt { - #[drive(skip)] pub create_option: CreateOption, pub catalog: Option<Identifier>, pub database: Option<Identifier>, diff --git a/src/query/ast/src/ast/statements/virtual_column.rs b/src/query/ast/src/ast/statements/virtual_column.rs index 9f53a5471aa69..c5f4da64546a4 100644 --- a/src/query/ast/src/ast/statements/virtual_column.rs +++ b/src/query/ast/src/ast/statements/virtual_column.rs @@ -15,19 +15,18 @@ use std::fmt::Display; use std::fmt::Formatter; -use databend_common_meta_app::schema::CreateOption; use derive_visitor::Drive; use derive_visitor::DriveMut; use crate::ast::write_comma_separated_list; use crate::ast::write_dot_separated_list; +use crate::ast::CreateOption; use crate::ast::Expr; use crate::ast::Identifier; use crate::ast::ShowLimit; #[derive(Debug, Clone, PartialEq, Drive, DriveMut)] pub struct CreateVirtualColumnStmt { - #[drive(skip)] pub create_option: CreateOption, pub catalog: Option<Identifier>, pub database: Option<Identifier>, diff --git a/src/query/ast/src/ast/visitors/visitor.rs b/src/query/ast/src/ast/visitors/visitor.rs index 12a20c0aedf07..879f2243b8d76 100644 --- a/src/query/ast/src/ast/visitors/visitor.rs +++ b/src/query/ast/src/ast/visitors/visitor.rs @@ -13,11 +13,7 @@ // limitations under the License. use databend_common_exception::Span; -use databend_common_meta_app::principal::PrincipalIdentity; -use databend_common_meta_app::principal::UserIdentity; -use databend_common_meta_app::schema::CreateOption; -use crate::ast::visitors::walk_window_definition; use crate::ast::*; #[deprecated = "Use derive_visitor::Visitor instead"] diff --git a/src/query/ast/src/ast/visitors/visitor_mut.rs b/src/query/ast/src/ast/visitors/visitor_mut.rs index 1adfd9b2b7426..989873f9eaa43 100644 --- a/src/query/ast/src/ast/visitors/visitor_mut.rs +++ b/src/query/ast/src/ast/visitors/visitor_mut.rs @@ -13,11 +13,7 @@ // limitations under the License. use databend_common_exception::Span; -use databend_common_meta_app::principal::PrincipalIdentity; -use databend_common_meta_app::principal::UserIdentity; -use databend_common_meta_app::schema::CreateOption; -use crate::ast::visitors::walk_column_id_mut; use crate::ast::*; #[deprecated = "Use derive_visitor::VisitorMut instead"] diff --git a/src/query/ast/src/parser/statement.rs b/src/query/ast/src/parser/statement.rs index d0eadc68fc43c..90a741c913a05 100644 --- a/src/query/ast/src/parser/statement.rs +++ b/src/query/ast/src/parser/statement.rs @@ -15,17 +15,6 @@ use std::collections::BTreeMap; use std::time::Duration; -use databend_common_meta_app::principal::AuthType; -use databend_common_meta_app::principal::PrincipalIdentity; -use databend_common_meta_app::principal::UserIdentity; -use databend_common_meta_app::principal::UserPrivilegeType; -use databend_common_meta_app::schema::CatalogType; -use databend_common_meta_app::schema::CreateOption; -use databend_common_meta_app::share::share_name_ident::ShareNameIdent; -use databend_common_meta_app::share::ShareGrantObjectName; -use databend_common_meta_app::share::ShareGrantObjectPrivilege; -use databend_common_meta_app::tenant::Tenant; -use minitrace::func_name; use nom::branch::alt; use nom::combinator::consumed; use nom::combinator::map; @@ -2868,7 +2857,7 @@ pub fn grant_share_object_name(i: Input) -> IResult<ShareGrantObjectName> { rule! { DATABASE ~ #ident }, - |(_, database)| ShareGrantObjectName::Database(database.to_string()), + |(_, database)| ShareGrantObjectName::Database(database), ); // `db01`.'tb1' or `db01`.`tb1` or `db01`.tb1 @@ -2876,9 +2865,7 @@ pub fn grant_share_object_name(i: Input) -> IResult<ShareGrantObjectName> { rule! { TABLE ~ #ident ~ "." ~ #ident }, - |(_, database, _, table)| { - ShareGrantObjectName::Table(database.to_string(), table.to_string()) - }, + |(_, database, _, table)| ShareGrantObjectName::Table(database, table), ); rule!( @@ -3762,16 +3749,12 @@ pub fn create_database_option(i: Input) -> IResult<CreateDatabaseOption> { |(_, _, option)| CreateDatabaseOption::DatabaseEngine(option), ); - let share_from = map_res( + let share_from = map( rule! { FROM ~ SHARE ~ #ident ~ "." ~ #ident }, - |(_, _, tenant, _, share_name)| { - Tenant::new_or_err(tenant.to_string(), func_name!()) - .map_err(|_e| nom::Err::Error(ErrorKind::Other("tenant can not be empty string"))) - .map(|tenant| { - CreateDatabaseOption::FromShare(ShareNameIdent::new(tenant, share_name)) - }) + |(_, _, tenant, _, share)| { + CreateDatabaseOption::FromShare(ShareNameIdent { tenant, share }) }, ); diff --git a/src/query/ast/tests/it/testdata/statement.txt b/src/query/ast/tests/it/testdata/statement.txt index dc9869740e8f8..0cc598f106137 100644 --- a/src/query/ast/tests/it/testdata/statement.txt +++ b/src/query/ast/tests/it/testdata/statement.txt @@ -2566,10 +2566,22 @@ CreateDatabase( options: [], from_share: Some( ShareNameIdent { - tenant: Tenant { - tenant: "a", + tenant: Identifier { + span: Some( + 29..30, + ), + name: "a", + quote: None, + is_hole: false, + }, + share: Identifier { + span: Some( + 31..32, + ), + name: "s", + quote: None, + is_hole: false, }, - name: "s", }, ), }, @@ -14220,7 +14232,14 @@ GrantShareObject( is_hole: false, }, object: Database( - "db1", + Identifier { + span: Some( + 24..27, + ), + name: "db1", + quote: None, + is_hole: false, + }, ), privilege: Usage, }, @@ -14243,8 +14262,22 @@ GrantShareObject( is_hole: false, }, object: Table( - "db1", - "tb1", + Identifier { + span: Some( + 22..25, + ), + name: "db1", + quote: None, + is_hole: false, + }, + Identifier { + span: Some( + 26..29, + ), + name: "tb1", + quote: None, + is_hole: false, + }, ), privilege: Select, }, @@ -14464,7 +14497,14 @@ RevokeShareObject( is_hole: false, }, object: Database( - "db1", + Identifier { + span: Some( + 25..28, + ), + name: "db1", + quote: None, + is_hole: false, + }, ), privilege: Usage, }, @@ -14487,8 +14527,22 @@ RevokeShareObject( is_hole: false, }, object: Table( - "db1", - "tb1", + Identifier { + span: Some( + 23..26, + ), + name: "db1", + quote: None, + is_hole: false, + }, + Identifier { + span: Some( + 27..30, + ), + name: "tb1", + quote: None, + is_hole: false, + }, ), privilege: Select, }, @@ -14668,8 +14722,22 @@ SHOW GRANTS ON TABLE db1.tb1 ShowObjectGrantPrivileges( ShowObjectGrantPrivilegesStmt { object: Table( - "db1", - "tb1", + Identifier { + span: Some( + 21..24, + ), + name: "db1", + quote: None, + is_hole: false, + }, + Identifier { + span: Some( + 25..28, + ), + name: "tb1", + quote: None, + is_hole: false, + }, ), }, ) @@ -14683,7 +14751,14 @@ SHOW GRANTS ON DATABASE db ShowObjectGrantPrivileges( ShowObjectGrantPrivilegesStmt { object: Database( - "db", + Identifier { + span: Some( + 24..26, + ), + name: "db", + quote: None, + is_hole: false, + }, ), }, ) diff --git a/src/query/formats/tests/it/output_format_tcsv.rs b/src/query/formats/tests/it/output_format_tcsv.rs index 0ac8f672ee3c4..f712b64604e4f 100644 --- a/src/query/formats/tests/it/output_format_tcsv.rs +++ b/src/query/formats/tests/it/output_format_tcsv.rs @@ -21,7 +21,7 @@ use databend_common_expression::FromData; use databend_common_expression::TableDataType; use databend_common_expression::TableField; use databend_common_formats::FileFormatOptionsExt; -use databend_common_meta_app::principal::FileFormatOptionsAst; +use databend_common_meta_app::principal::FileFormatOptionsReader; use databend_common_meta_app::principal::FileFormatParams; use databend_common_meta_app::tenant::Tenant; use databend_common_settings::Settings; @@ -69,8 +69,10 @@ fn test_data_block(is_nullable: bool) -> Result<()> { options.insert("field_delimiter".to_string(), "$".to_string()); options.insert("record_delimiter".to_string(), "\r\n".to_string()); - let params = - FileFormatParams::try_from_ast(FileFormatOptionsAst::new(options.clone()), false)?; + let params = FileFormatParams::try_from_reader( + FileFormatOptionsReader::from_map(options.clone()), + false, + )?; let mut options = FileFormatOptionsExt::create_from_settings(&settings, false)?; let mut output_format = options.get_output_format(schema, params)?; let buffer = output_format.serialize_block(&block)?; @@ -131,7 +133,10 @@ fn test_field_delimiter_with_ascii_control_code() -> Result<()> { options.insert("type".to_string(), "csv".to_string()); options.insert("field_delimiter".to_string(), "\x01".to_string()); options.insert("record_delimiter".to_string(), "\r\n".to_string()); - let params = FileFormatParams::try_from_ast(FileFormatOptionsAst::new(options.clone()), false)?; + let params = FileFormatParams::try_from_reader( + FileFormatOptionsReader::from_map(options.clone()), + false, + )?; let mut options = FileFormatOptionsExt::create_from_settings(&settings, false)?; let mut output_format = options.get_output_format(schema, params)?; let buffer = output_format.serialize_block(&block)?; diff --git a/src/query/sql/src/planner/binder/binder.rs b/src/query/sql/src/planner/binder/binder.rs index cf3d1d0c6c8e0..4e71659644431 100644 --- a/src/query/sql/src/planner/binder/binder.rs +++ b/src/query/sql/src/planner/binder/binder.rs @@ -34,6 +34,8 @@ use databend_common_expression::types::DataType; use databend_common_expression::ConstantFolder; use databend_common_expression::Expr; use databend_common_functions::BUILTIN_FUNCTIONS; +use databend_common_meta_app::principal::FileFormatOptionsReader; +use databend_common_meta_app::principal::FileFormatParams; use databend_common_meta_app::principal::StageFileFormatType; use indexmap::IndexMap; use log::warn; @@ -339,7 +341,7 @@ impl<'a> Binder { Statement::CreateUser(stmt) => self.bind_create_user(stmt).await?, Statement::DropUser { if_exists, user } => Plan::DropUser(Box::new(DropUserPlan { if_exists: *if_exists, - user: user.clone(), + user: user.clone().into(), })), Statement::ShowUsers => self.bind_rewrite_to_query(bind_context, "SELECT name, hostname, auth_type, is_configured, default_role, disabled FROM system.users ORDER BY name", RewriteKind::ShowUsers).await?, Statement::AlterUser(stmt) => self.bind_alter_user(stmt).await?, @@ -444,7 +446,7 @@ impl<'a> Binder { // Permissions Statement::Grant(stmt) => self.bind_grant(stmt).await?, Statement::ShowGrants { principal } => Plan::ShowGrants(Box::new(ShowGrantsPlan { - principal: principal.clone(), + principal: principal.clone().map(Into::into), })), Statement::Revoke(stmt) => self.bind_revoke(stmt).await?, @@ -456,9 +458,9 @@ impl<'a> Binder { ))); } Plan::CreateFileFormat(Box::new(CreateFileFormatPlan { - create_option: *create_option, + create_option: create_option.clone().into(), name: name.clone(), - file_format_params: file_format_options.to_meta_ast().try_into()?, + file_format_params: FileFormatParams::try_from_reader( FileFormatOptionsReader::from_ast(file_format_options), false)?, })) } Statement::DropFileFormat { diff --git a/src/query/sql/src/planner/binder/copy_into_table.rs b/src/query/sql/src/planner/binder/copy_into_table.rs index 9b24d6b555a12..bb4d916c8a5ce 100644 --- a/src/query/sql/src/planner/binder/copy_into_table.rs +++ b/src/query/sql/src/planner/binder/copy_into_table.rs @@ -50,10 +50,12 @@ use databend_common_expression::Evaluator; use databend_common_expression::Scalar; use databend_common_functions::BUILTIN_FUNCTIONS; use databend_common_meta_app::principal::EmptyFieldAs; -use databend_common_meta_app::principal::FileFormatOptionsAst; +use databend_common_meta_app::principal::FileFormatOptionsReader; use databend_common_meta_app::principal::FileFormatParams; use databend_common_meta_app::principal::NullAs; +use databend_common_meta_app::principal::OnErrorMode; use databend_common_meta_app::principal::StageInfo; +use databend_common_meta_app::principal::COPY_MAX_FILES_PER_COMMIT; use databend_common_storage::StageFilesInfo; use databend_common_users::UserApiProvider; use derive_visitor::Drive; @@ -239,10 +241,10 @@ impl<'a> Binder { resolve_stage_location(self.ctx.as_ref(), &attachment.location[1..]).await?; if let Some(ref options) = attachment.file_format_options { - let mut params = FileFormatOptionsAst { - options: options.clone(), - } - .try_into()?; + let mut params = FileFormatParams::try_from_reader( + FileFormatOptionsReader::from_map(options.clone()), + false, + )?; if let FileFormatParams::Csv(ref mut fmt) = &mut params { // TODO: remove this after 1. the old server is no longer supported 2. Driver add the option "EmptyFieldAs=FieldDefault" // CSV attachment is mainly used in Drivers for insert. @@ -459,7 +461,33 @@ impl<'a> Binder { if !stmt.file_format.is_empty() { stage.file_format_params = self.try_resolve_file_format(&stmt.file_format).await?; } - stmt.apply_to_copy_option(&mut stage.copy_options) + + stage.copy_options.on_error = + OnErrorMode::from_str(&stmt.on_error).map_err(ErrorCode::SyntaxException)?; + + if stmt.size_limit != 0 { + stage.copy_options.size_limit = stmt.size_limit; + } + + stage.copy_options.split_size = stmt.split_size; + stage.copy_options.purge = stmt.purge; + stage.copy_options.disable_variant_check = stmt.disable_variant_check; + stage.copy_options.return_failed_only = stmt.return_failed_only; + + if stmt.max_files != 0 { + stage.copy_options.max_files = stmt.max_files; + } + + if !(stage.copy_options.purge && stmt.force) + && stage.copy_options.max_files > COPY_MAX_FILES_PER_COMMIT + { + return Err(ErrorCode::InvalidArgument(format!( + "max_files {} is too large, max_files should be less than {COPY_MAX_FILES_PER_COMMIT}", + stage.copy_options.max_files + ))); + } + + Ok(()) } #[async_backtrace::framed] diff --git a/src/query/sql/src/planner/binder/ddl/account.rs b/src/query/sql/src/planner/binder/ddl/account.rs index ce9707df89be4..c27840765ae16 100644 --- a/src/query/sql/src/planner/binder/ddl/account.rs +++ b/src/query/sql/src/planner/binder/ddl/account.rs @@ -49,7 +49,7 @@ impl Binder { match source { AccountMgrSource::Role { role } => { let plan = GrantRolePlan { - principal: principal.clone(), + principal: principal.clone().into(), role: role.clone(), }; Ok(Plan::GrantRole(Box::new(plan))) @@ -59,8 +59,8 @@ impl Binder { // Now in this case all is always true. let grant_object = self.convert_to_grant_object(level).await?; let priv_types = grant_object.available_privileges(false); - let plan = GrantPrivilegePlan { - principal: principal.clone(), + let plan: GrantPrivilegePlan = GrantPrivilegePlan { + principal: principal.clone().into(), on: grant_object, priv_types, }; @@ -70,10 +70,10 @@ impl Binder { let grant_object = self.convert_to_grant_object(level).await?; let mut priv_types = UserPrivilegeSet::empty(); for x in privileges { - priv_types.set_privilege(*x); + priv_types.set_privilege(x.clone().into()); } let plan = GrantPrivilegePlan { - principal: principal.clone(), + principal: principal.clone().into(), on: grant_object, priv_types, }; @@ -92,7 +92,7 @@ impl Binder { match source { AccountMgrSource::Role { role } => { let plan = RevokeRolePlan { - principal: principal.clone(), + principal: principal.clone().into(), role: role.clone(), }; Ok(Plan::RevokeRole(Box::new(plan))) @@ -103,7 +103,8 @@ impl Binder { let grant_object = self.convert_to_revoke_grant_object(level).await?; // Note if old version `grant all on db.*/db.t to user`, the user will contains ownership privilege. // revoke all need to revoke it. - let priv_types = match principal { + let principal: PrincipalIdentity = principal.clone().into(); + let priv_types = match &principal { PrincipalIdentity::User(_) => grant_object[0].available_privileges(true), PrincipalIdentity::Role(_) => grant_object[0].available_privileges(false), }; @@ -118,10 +119,10 @@ impl Binder { let grant_object = self.convert_to_revoke_grant_object(level).await?; let mut priv_types = UserPrivilegeSet::empty(); for x in privileges { - priv_types.set_privilege(*x); + priv_types.set_privilege(x.clone().into()); } let plan = RevokePrivilegePlan { - principal: principal.clone(), + principal: principal.clone().into(), on: grant_object, priv_types, }; @@ -243,7 +244,7 @@ impl Binder { } let mut user_option = UserOption::default(); for option in user_options { - option.apply(&mut user_option); + user_option.apply(option); } UserApiProvider::instance() .verify_password( @@ -256,9 +257,12 @@ impl Binder { .await?; let plan = CreateUserPlan { - create_option: *create_option, - user: user.clone(), - auth_info: AuthInfo::create2(&auth_option.auth_type, &auth_option.password)?, + create_option: create_option.clone().into(), + user: user.clone().into(), + auth_info: AuthInfo::create2( + &auth_option.auth_type.clone().map(Into::into), + &auth_option.password, + )?, user_option, password_update_on: Some(Utc::now()), }; @@ -280,20 +284,21 @@ impl Binder { self.ctx.get_current_user()? } else { UserApiProvider::instance() - .get_user(&self.ctx.get_tenant(), user.clone().unwrap()) + .get_user(&self.ctx.get_tenant(), user.clone().unwrap().into()) .await? }; let mut user_option = user_info.option.clone(); for option in user_options { - option.apply(&mut user_option); + user_option.apply(option); } // None means no change to make let new_auth_info = if let Some(auth_option) = &auth_option { - let auth_info = user_info - .auth_info - .alter2(&auth_option.auth_type, &auth_option.password)?; + let auth_info = user_info.auth_info.alter2( + &auth_option.auth_type.clone().map(Into::into), + &auth_option.password, + )?; // verify the password if changed UserApiProvider::instance() .verify_password( diff --git a/src/query/sql/src/planner/binder/ddl/catalog.rs b/src/query/sql/src/planner/binder/ddl/catalog.rs index bb68a5b2a1c45..9ecfa6aa301a7 100644 --- a/src/query/sql/src/planner/binder/ddl/catalog.rs +++ b/src/query/sql/src/planner/binder/ddl/catalog.rs @@ -104,7 +104,7 @@ impl Binder { let tenant = self.ctx.get_tenant(); let meta = self - .try_create_meta_from_options(&self.ctx, *catalog_type, options) + .try_create_meta_from_options(&self.ctx, catalog_type.clone().into(), options) .await?; Ok(Plan::CreateCatalog(Box::new(CreateCatalogPlan { diff --git a/src/query/sql/src/planner/binder/ddl/connection.rs b/src/query/sql/src/planner/binder/ddl/connection.rs index c9e7c84e50be9..1b27823ebdc57 100644 --- a/src/query/sql/src/planner/binder/ddl/connection.rs +++ b/src/query/sql/src/planner/binder/ddl/connection.rs @@ -36,7 +36,7 @@ impl Binder { ); parse_storage_params_from_uri(&mut location, None, "when CREATE CONNECTION").await?; Ok(Plan::CreateConnection(Box::new(CreateConnectionPlan { - create_option: stmt.create_option, + create_option: stmt.create_option.clone().into(), name: stmt.name.to_string(), storage_type: stmt.storage_type.clone(), storage_params: stmt.storage_params.clone(), diff --git a/src/query/sql/src/planner/binder/ddl/data_mask.rs b/src/query/sql/src/planner/binder/ddl/data_mask.rs index 54722bf6928ee..0b3c78d17b908 100644 --- a/src/query/sql/src/planner/binder/ddl/data_mask.rs +++ b/src/query/sql/src/planner/binder/ddl/data_mask.rs @@ -46,7 +46,7 @@ impl Binder { let tenant = self.ctx.get_tenant(); let plan = CreateDatamaskPolicyPlan { - create_option: *create_option, + create_option: create_option.clone().into(), tenant, name: name.to_string(), policy: policy.clone(), diff --git a/src/query/sql/src/planner/binder/ddl/database.rs b/src/query/sql/src/planner/binder/ddl/database.rs index 464a10a002369..9211e5b20c6e1 100644 --- a/src/query/sql/src/planner/binder/ddl/database.rs +++ b/src/query/sql/src/planner/binder/ddl/database.rs @@ -229,10 +229,14 @@ impl Binder { } else { engine }; - let meta = self.database_meta(engine, options, from_share)?; + let meta = self.database_meta( + engine, + options, + &from_share.clone().map(TryInto::try_into).transpose()?, + )?; Ok(Plan::CreateDatabase(Box::new(CreateDatabasePlan { - create_option: *create_option, + create_option: create_option.clone().into(), tenant, catalog, database, diff --git a/src/query/sql/src/planner/binder/ddl/dynamic_table.rs b/src/query/sql/src/planner/binder/ddl/dynamic_table.rs index a684453442222..7781a89240a8a 100644 --- a/src/query/sql/src/planner/binder/ddl/dynamic_table.rs +++ b/src/query/sql/src/planner/binder/ddl/dynamic_table.rs @@ -178,7 +178,7 @@ impl Binder { }; let plan = CreateDynamicTablePlan { - create_option: *create_option, + create_option: create_option.clone().into(), tenant: self.ctx.get_tenant(), catalog: catalog_name.clone(), database: database.clone(), diff --git a/src/query/sql/src/planner/binder/ddl/index.rs b/src/query/sql/src/planner/binder/ddl/index.rs index 6929cc764bc3d..8e87c7fb660de 100644 --- a/src/query/sql/src/planner/binder/ddl/index.rs +++ b/src/query/sql/src/planner/binder/ddl/index.rs @@ -215,7 +215,7 @@ impl Binder { Self::rewrite_query_with_database(&mut query, table_entry.database()); let plan = CreateIndexPlan { - create_option: *create_option, + create_option: create_option.clone().into(), index_type: *index_type, index_name, original_query: original_query.to_string(), @@ -414,7 +414,7 @@ impl Binder { let index_name = self.normalize_object_identifier(index_name); let plan = CreateTableIndexPlan { - create_option: *create_option, + create_option: create_option.clone().into(), catalog, index_name, column_ids, diff --git a/src/query/sql/src/planner/binder/ddl/network_policy.rs b/src/query/sql/src/planner/binder/ddl/network_policy.rs index 439fd8a25580e..61bf3affaa565 100644 --- a/src/query/sql/src/planner/binder/ddl/network_policy.rs +++ b/src/query/sql/src/planner/binder/ddl/network_policy.rs @@ -61,7 +61,7 @@ impl Binder { let tenant = self.ctx.get_tenant(); let plan = CreateNetworkPolicyPlan { - create_option: *create_option, + create_option: create_option.clone().into(), tenant, name: name.to_string(), allowed_ip_list: allowed_ip_list.clone(), diff --git a/src/query/sql/src/planner/binder/ddl/password_policy.rs b/src/query/sql/src/planner/binder/ddl/password_policy.rs index b1545533cb0d8..0c78eb8551c5b 100644 --- a/src/query/sql/src/planner/binder/ddl/password_policy.rs +++ b/src/query/sql/src/planner/binder/ddl/password_policy.rs @@ -40,7 +40,7 @@ impl Binder { let tenant = self.ctx.get_tenant(); let plan = CreatePasswordPolicyPlan { - create_option: *create_option, + create_option: create_option.clone().into(), tenant, name: name.to_string(), set_options: set_options.clone(), diff --git a/src/query/sql/src/planner/binder/ddl/sequence.rs b/src/query/sql/src/planner/binder/ddl/sequence.rs index ee63c90f6f925..167d0f9174a3c 100644 --- a/src/query/sql/src/planner/binder/ddl/sequence.rs +++ b/src/query/sql/src/planner/binder/ddl/sequence.rs @@ -38,7 +38,7 @@ impl Binder { let sequence = self.normalize_object_identifier(sequence); let plan = CreateSequencePlan { - create_option: *create_option, + create_option: create_option.clone().into(), ident: SequenceIdent::new(tenant, sequence), comment: comment.clone(), }; diff --git a/src/query/sql/src/planner/binder/ddl/share.rs b/src/query/sql/src/planner/binder/ddl/share.rs index 7741b556be5be..c4c45420d467b 100644 --- a/src/query/sql/src/planner/binder/ddl/share.rs +++ b/src/query/sql/src/planner/binder/ddl/share.rs @@ -59,7 +59,7 @@ impl Binder { }; let plan = CreateShareEndpointPlan { - create_option: *create_option, + create_option: create_option.clone().into(), endpoint: ShareEndpointIdent::new(self.ctx.get_tenant(), endpoint), tenant, url: format!("{}://{}{}", url.protocol, url.name, url.path), @@ -151,8 +151,8 @@ impl Binder { let plan = GrantShareObjectPlan { share, - object: object.clone(), - privilege: *privilege, + object: object.clone().into(), + privilege: privilege.clone().into(), }; Ok(Plan::GrantShareObject(Box::new(plan))) } @@ -172,8 +172,8 @@ impl Binder { let plan = RevokeShareObjectPlan { share, - object: object.clone(), - privilege: *privilege, + object: object.clone().into(), + privilege: privilege.clone().into(), }; Ok(Plan::RevokeShareObject(Box::new(plan))) } @@ -230,7 +230,7 @@ impl Binder { let ShowObjectGrantPrivilegesStmt { object } = stmt; let plan = ShowObjectGrantPrivilegesPlan { - object: object.clone(), + object: object.clone().into(), }; Ok(Plan::ShowObjectGrantPrivileges(Box::new(plan))) } diff --git a/src/query/sql/src/planner/binder/ddl/stage.rs b/src/query/sql/src/planner/binder/ddl/stage.rs index 04e73a26d2ece..1a331973d871f 100644 --- a/src/query/sql/src/planner/binder/ddl/stage.rs +++ b/src/query/sql/src/planner/binder/ddl/stage.rs @@ -19,6 +19,7 @@ use databend_common_ast::ast::FileFormatOptions; use databend_common_ast::ast::UriLocation; use databend_common_exception::ErrorCode; use databend_common_exception::Result; +use databend_common_meta_app::principal::FileFormatOptionsReader; use databend_common_meta_app::principal::FileFormatParams; use databend_common_meta_app::principal::OnErrorMode; use databend_common_meta_app::principal::StageInfo; @@ -115,7 +116,7 @@ impl Binder { } Ok(Plan::CreateStage(Box::new(CreateStagePlan { - create_option: *create_option, + create_option: create_option.clone().into(), tenant: self.ctx.get_tenant(), stage_info, }))) @@ -126,11 +127,11 @@ impl Binder { &self, options: &FileFormatOptions, ) -> Result<FileFormatParams> { - let options = options.to_meta_ast(); - if let Some(name) = options.options.get("format_name") { + let reader = FileFormatOptionsReader::from_ast(options); + if let Some(name) = reader.options.get("format_name") { self.ctx.get_file_format(name).await } else { - FileFormatParams::try_from(options) + FileFormatParams::try_from_reader(reader, false) } } } diff --git a/src/query/sql/src/planner/binder/ddl/stream.rs b/src/query/sql/src/planner/binder/ddl/stream.rs index f5ee318fa5ad4..01cc43347995b 100644 --- a/src/query/sql/src/planner/binder/ddl/stream.rs +++ b/src/query/sql/src/planner/binder/ddl/stream.rs @@ -67,7 +67,7 @@ impl Binder { }; let plan = CreateStreamPlan { - create_option: *create_option, + create_option: create_option.clone().into(), tenant, catalog, database, diff --git a/src/query/sql/src/planner/binder/ddl/table.rs b/src/query/sql/src/planner/binder/ddl/table.rs index a8a571368e482..117be9bb7e987 100644 --- a/src/query/sql/src/planner/binder/ddl/table.rs +++ b/src/query/sql/src/planner/binder/ddl/table.rs @@ -635,7 +635,7 @@ impl Binder { }; let plan = CreateTablePlan { - create_option: *create_option, + create_option: create_option.clone().into(), tenant: self.ctx.get_tenant(), catalog: catalog.clone(), database: database.clone(), diff --git a/src/query/sql/src/planner/binder/ddl/view.rs b/src/query/sql/src/planner/binder/ddl/view.rs index 572fab6b9c847..8579a68ea3a7a 100644 --- a/src/query/sql/src/planner/binder/ddl/view.rs +++ b/src/query/sql/src/planner/binder/ddl/view.rs @@ -66,7 +66,7 @@ impl Binder { let subquery = format!("{}", query); let plan = CreateViewPlan { - create_option: *create_option, + create_option: create_option.clone().into(), tenant, catalog, database, diff --git a/src/query/sql/src/planner/binder/ddl/virtual_column.rs b/src/query/sql/src/planner/binder/ddl/virtual_column.rs index 60e1c4eab8078..f843888fa130f 100644 --- a/src/query/sql/src/planner/binder/ddl/virtual_column.rs +++ b/src/query/sql/src/planner/binder/ddl/virtual_column.rs @@ -73,7 +73,7 @@ impl Binder { Ok(Plan::CreateVirtualColumn(Box::new( CreateVirtualColumnPlan { - create_option: *create_option, + create_option: create_option.clone().into(), catalog, database, table, diff --git a/src/query/sql/src/planner/binder/insert.rs b/src/query/sql/src/planner/binder/insert.rs index 1d4aab56996b0..afe25bd84747c 100644 --- a/src/query/sql/src/planner/binder/insert.rs +++ b/src/query/sql/src/planner/binder/insert.rs @@ -23,6 +23,8 @@ use databend_common_exception::ErrorCode; use databend_common_exception::Result; use databend_common_expression::TableSchema; use databend_common_expression::TableSchemaRefExt; +use databend_common_meta_app::principal::FileFormatOptionsReader; +use databend_common_meta_app::principal::FileFormatParams; use databend_common_meta_app::principal::OnErrorMode; use crate::binder::Binder; @@ -117,7 +119,10 @@ impl Binder { on_error_mode, start, } => { - let params = settings.to_meta_ast().try_into()?; + let params = FileFormatParams::try_from_reader( + FileFormatOptionsReader::from_ast(&settings), + false, + )?; Ok(InsertInputSource::StreamingWithFileFormat { format: params, start, diff --git a/src/query/sql/src/planner/binder/replace.rs b/src/query/sql/src/planner/binder/replace.rs index f378c6a41612b..699a6bfbbc740 100644 --- a/src/query/sql/src/planner/binder/replace.rs +++ b/src/query/sql/src/planner/binder/replace.rs @@ -20,6 +20,8 @@ use databend_common_ast::ast::ReplaceStmt; use databend_common_ast::ast::Statement; use databend_common_exception::ErrorCode; use databend_common_exception::Result; +use databend_common_meta_app::principal::FileFormatOptionsReader; +use databend_common_meta_app::principal::FileFormatParams; use databend_common_meta_app::principal::OnErrorMode; use crate::binder::Binder; @@ -102,7 +104,10 @@ impl Binder { on_error_mode, start, } => { - let params = settings.to_meta_ast().try_into()?; + let params = FileFormatParams::try_from_reader( + FileFormatOptionsReader::from_ast(&settings), + false, + )?; Ok(InsertInputSource::StreamingWithFileFormat { format: params, start, diff --git a/src/query/sql/src/planner/binder/udf.rs b/src/query/sql/src/planner/binder/udf.rs index 416b52ea91569..5124aef88b69e 100644 --- a/src/query/sql/src/planner/binder/udf.rs +++ b/src/query/sql/src/planner/binder/udf.rs @@ -182,7 +182,7 @@ impl Binder { .bind_udf_definition(&stmt.udf_name, &stmt.description, &stmt.definition) .await?; Ok(Plan::CreateUDF(Box::new(CreateUDFPlan { - create_option: stmt.create_option, + create_option: stmt.create_option.clone().into(), udf, }))) } diff --git a/src/query/users/tests/it/password_policy.rs b/src/query/users/tests/it/password_policy.rs index 715a598958f40..e552963ce82b5 100644 --- a/src/query/users/tests/it/password_policy.rs +++ b/src/query/users/tests/it/password_policy.rs @@ -16,11 +16,11 @@ use chrono::Duration; use chrono::TimeZone; use chrono::Utc; use databend_common_ast::ast::AuthOption; +use databend_common_ast::ast::AuthType; use databend_common_base::base::tokio; use databend_common_exception::Result; use databend_common_grpc::RpcClientConf; use databend_common_meta_app::principal::AuthInfo; -use databend_common_meta_app::principal::AuthType; use databend_common_meta_app::principal::PasswordPolicy; use databend_common_meta_app::principal::UserIdentity; use databend_common_meta_app::principal::UserInfo; diff --git a/src/tests/sqlsmith/Cargo.toml b/src/tests/sqlsmith/Cargo.toml index b64691443ff1c..06f4e8823b909 100644 --- a/src/tests/sqlsmith/Cargo.toml +++ b/src/tests/sqlsmith/Cargo.toml @@ -28,7 +28,6 @@ databend-common-expression = { path = "../../query/expression" } databend-common-formats = { path = "../../query/formats" } databend-common-functions = { path = "../../query/functions" } databend-common-io = { path = "../../common/io" } -databend-common-meta-app = { path = "../../meta/app" } databend-common-sql = { path = "../../query/sql" } [[bin]] diff --git a/src/tests/sqlsmith/src/sql_gen/ddl.rs b/src/tests/sqlsmith/src/sql_gen/ddl.rs index 54da93aeaf698..cdcedb78e0b0f 100644 --- a/src/tests/sqlsmith/src/sql_gen/ddl.rs +++ b/src/tests/sqlsmith/src/sql_gen/ddl.rs @@ -16,6 +16,7 @@ use std::collections::BTreeMap; use databend_common_ast::ast::ColumnDefinition; use databend_common_ast::ast::ColumnExpr; +use databend_common_ast::ast::CreateOption; use databend_common_ast::ast::CreateTableSource; use databend_common_ast::ast::CreateTableStmt; use databend_common_ast::ast::DropTableStmt; @@ -24,7 +25,6 @@ use databend_common_ast::ast::Expr; use databend_common_ast::ast::Identifier; use databend_common_ast::ast::Literal; use databend_common_ast::ast::TypeName; -use databend_common_meta_app::schema::CreateOption; use rand::distributions::Alphanumeric; use rand::Rng;