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;