Skip to content

Commit

Permalink
Part2: support interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
TCeason committed Aug 29, 2024
1 parent bc18c19 commit 05bc53a
Show file tree
Hide file tree
Showing 42 changed files with 1,929 additions and 12 deletions.
5 changes: 5 additions & 0 deletions src/common/exception/src/exception_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,11 @@ build_exceptions! {
UnsupportedDictionarySource(3117),
MissingDictionaryOption(3118),
WrongDictionaryFieldExpr(3119),

// Procedure
UnknownProcedure(3130),
ProcedureAlreadyExists(3131),
IllegalProcedureFormat(3132),
}

// Storage errors [3001, 4000].
Expand Down
1 change: 1 addition & 0 deletions src/meta/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pub use util::is_all_db_data_removed;
pub use util::is_db_need_to_be_remove;
pub use util::list_keys;
pub use util::list_u64_value;
pub use util::procedure_has_to_exist;
pub use util::remove_db_from_share;
pub use util::send_txn;
pub use util::serialize_struct;
Expand Down
24 changes: 24 additions & 0 deletions src/meta/api/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use databend_common_meta_app::app_error::ShareHasNoGrantedDatabase;
use databend_common_meta_app::app_error::ShareHasNoGrantedPrivilege;
use databend_common_meta_app::app_error::UnknownDatabase;
use databend_common_meta_app::app_error::UnknownDatabaseId;
use databend_common_meta_app::app_error::UnknownProcedure;
use databend_common_meta_app::app_error::UnknownShare;
use databend_common_meta_app::app_error::UnknownShareAccounts;
use databend_common_meta_app::app_error::UnknownShareEndpoint;
Expand All @@ -31,6 +32,7 @@ use databend_common_meta_app::app_error::UnknownTableId;
use databend_common_meta_app::app_error::VirtualColumnNotFound;
use databend_common_meta_app::app_error::WrongShareObject;
use databend_common_meta_app::primitive::Id;
use databend_common_meta_app::principal::ProcedureNameIdent;
use databend_common_meta_app::schema::database_name_ident::DatabaseNameIdent;
use databend_common_meta_app::schema::database_name_ident::DatabaseNameIdentRaw;
use databend_common_meta_app::schema::DBIdTableName;
Expand Down Expand Up @@ -444,6 +446,28 @@ pub fn db_id_has_to_exist(seq: u64, db_id: u64, msg: impl Display) -> Result<(),
}
}

/// Return OK if a procedure_id or procedure_meta exists by checking the seq.
///
/// Otherwise returns UnknownProcedure error
pub fn procedure_has_to_exist(
seq: u64,
procedure_name_ident: &ProcedureNameIdent,
msg: impl Display,
) -> Result<(), KVAppError> {
if seq == 0 {
debug!(seq = seq, db_name_ident :? =(procedure_name_ident); "procedure does not exist");

Err(KVAppError::AppError(AppError::UnknownProcedure(
UnknownProcedure::new(
procedure_name_ident.procedure_name(),
format!("{}: {}", msg, procedure_name_ident.display()),
),
)))
} else {
Ok(())
}
}

/// Return OK if a `table_name_ident->*` exists by checking the seq.
///
/// Otherwise returns [`AppError::UnknownTable`] error
Expand Down
55 changes: 55 additions & 0 deletions src/meta/app/src/app_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,22 @@ impl DatabaseAlreadyExists {
}
}

#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[error("ProcedureAlreadyExists: `{procedure_name}` while `{context}`")]
pub struct ProcedureAlreadyExists {
procedure_name: String,
context: String,
}

impl ProcedureAlreadyExists {
pub fn new(procedure_name: impl Into<String>, context: impl Into<String>) -> Self {
Self {
procedure_name: procedure_name.into(),
context: context.into(),
}
}
}

#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[error("CreateDatabaseWithDropTime: `{db_name}` with drop_on")]
pub struct CreateDatabaseWithDropTime {
Expand Down Expand Up @@ -387,6 +403,22 @@ impl UnknownDatabase {
}
}

#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
#[error("UnknownProcedure: `{procedure_name}` while `{context}`")]
pub struct UnknownProcedure {
procedure_name: String,
context: String,
}

impl UnknownProcedure {
pub fn new(procedure_name: impl Into<String>, context: impl Into<String>) -> Self {
Self {
procedure_name: procedure_name.into(),
context: context.into(),
}
}
}

#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
#[error("UnknownCatalog: `{catalog_name}` while `{context}`")]
pub struct UnknownCatalog {
Expand Down Expand Up @@ -1244,6 +1276,13 @@ pub enum AppError {

#[error(transparent)]
UnknownDictionary(#[from] UnknownDictionary),

// Procedure
#[error(transparent)]
UnknownProcedure(#[from] UnknownProcedure),

#[error(transparent)]
ProcedureAlreadyExists(#[from] ProcedureAlreadyExists),
}

impl AppError {
Expand Down Expand Up @@ -1296,6 +1335,18 @@ impl AppErrorMessage for UnknownDatabase {
}
}

impl AppErrorMessage for UnknownProcedure {
fn message(&self) -> String {
format!("Unknown procedure '{}'", self.procedure_name)
}
}

impl AppErrorMessage for ProcedureAlreadyExists {
fn message(&self) -> String {
format!("Procedure '{}' already exists", self.procedure_name)
}
}

impl AppErrorMessage for DatabaseAlreadyExists {
fn message(&self) -> String {
format!("Database '{}' already exists", self.db_name)
Expand Down Expand Up @@ -1805,6 +1856,10 @@ impl From<AppError> for ErrorCode {
ErrorCode::DictionaryAlreadyExists(err.message())
}
AppError::UnknownDictionary(err) => ErrorCode::UnknownDictionary(err.message()),
AppError::UnknownProcedure(err) => ErrorCode::UnknownProcedure(err.message()),
AppError::ProcedureAlreadyExists(err) => {
ErrorCode::ProcedureAlreadyExists(err.message())
}
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions src/meta/app/src/id_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub(crate) const ID_GEN_SHARE_ENDPOINT: &str = "share_endpoint_id";
pub(crate) const ID_GEN_DATA_MASK: &str = "data_mask";
pub(crate) const ID_GEN_BACKGROUND_JOB: &str = "background_job";

pub(crate) const ID_GEN_PROCEDURE: &str = "procedure_id";

/// Key for resource id generator
///
/// This is a special key for an application to generate unique id with kvapi::KVApi.
Expand Down Expand Up @@ -103,6 +105,13 @@ impl IdGenerator {
resource: ID_GEN_CATALOG.to_string(),
}
}

/// Create a key for generating procedure id with kvapi::KVApi
pub fn procedure_id() -> Self {
Self {
resource: ID_GEN_PROCEDURE.to_string(),
}
}
}

impl kvapi::KeyCodec for IdGenerator {
Expand Down Expand Up @@ -217,6 +226,16 @@ mod t {
assert_eq!(g1, g2);
}

// Procedure id generator
{
let g = IdGenerator::procedure_id();
let k = g.to_string_key();
assert_eq!("__fd_id_gen/procedure_id", k);

let t2 = IdGenerator::from_str_key(&k)?;
assert_eq!(g, t2);
}

Ok(())
}

Expand Down
18 changes: 18 additions & 0 deletions src/meta/app/src/principal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub mod client_session_ident;
pub mod connection_ident;
pub mod network_policy_ident;
pub mod password_policy_ident;
pub mod procedur_name_ident;
pub mod procedure;
pub mod procedure_id_ident;
pub mod stage_file_ident;
pub mod tenant_ownership_object_ident;
pub mod tenant_user_ident;
Expand All @@ -60,6 +63,21 @@ pub use ownership_object::OwnershipObject;
pub use password_policy::PasswordPolicy;
pub use password_policy_ident::PasswordPolicyIdent;
pub use principal_identity::PrincipalIdentity;
pub use procedur_name_ident::ProcedureNameIdent;
pub use procedure::CreateProcedureReply;
pub use procedure::CreateProcedureReq;
pub use procedure::DropProcedureReply;
pub use procedure::DropProcedureReq;
pub use procedure::GetProcedureReply;
pub use procedure::GetProcedureReq;
pub use procedure::ListProcedureReq;
pub use procedure::ProcedureId;
pub use procedure::ProcedureIdList;
pub use procedure::ProcedureIdToName;
pub use procedure::ProcedureInfoFilter;
pub use procedure::ProcedureMeta;
pub use procedure::RenameProcedureReply;
pub use procedure::RenameProcedureReq;
pub use role_ident::RoleIdent;
pub use role_ident::RoleIdentRaw;
pub use role_info::RoleInfo;
Expand Down
82 changes: 82 additions & 0 deletions src/meta/app/src/principal/procedur_name_ident.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// 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 crate::tenant_key::ident::TIdent;
use crate::tenant_key::raw::TIdentRaw;

pub type ProcedureNameIdent = TIdent<Resource>;
pub type ProcedureNameIdentRaw = TIdentRaw<Resource>;

pub use kvapi_impl::Resource;

impl ProcedureNameIdent {
pub fn procedure_name(&self) -> &str {
self.name()
}
}

impl ProcedureNameIdentRaw {
pub fn procedure_name(&self) -> &str {
self.name()
}
}

mod kvapi_impl {

use databend_common_meta_kvapi::kvapi;
use databend_common_meta_kvapi::kvapi::Key;

use crate::primitive::Id;
use crate::principal::ProcedureId;
use crate::principal::ProcedureNameIdent;
use crate::tenant_key::resource::TenantResource;

pub struct Resource;
impl TenantResource for Resource {
const PREFIX: &'static str = "__fd_procedure";
const TYPE: &'static str = "ProcedureNameIdent";
const HAS_TENANT: bool = true;
type ValueType = Id<ProcedureId>;
}

impl kvapi::Value for Id<ProcedureId> {
type KeyType = ProcedureNameIdent;
fn dependency_keys(&self, _key: &Self::KeyType) -> impl IntoIterator<Item = String> {
[self.inner().to_string_key()]
}
}

// // Use these error types to replace usage of ErrorCode if possible.
// impl From<ExistError<Resource>> for ErrorCode {
// impl From<UnknownError<Resource>> for ErrorCode {
}

#[cfg(test)]
mod tests {
use databend_common_meta_kvapi::kvapi::Key;

use super::ProcedureNameIdent;
use crate::tenant::Tenant;

#[test]
fn test_ident() {
let tenant = Tenant::new_literal("test");
let ident = ProcedureNameIdent::new(tenant, "test1");

let key = ident.to_string_key();
assert_eq!(key, "__fd_procedure/test/test1");

assert_eq!(ident, ProcedureNameIdent::from_str_key(&key).unwrap());
}
}
Loading

0 comments on commit 05bc53a

Please sign in to comment.