From 3e07838ccd2d9068e7126f8ce7939b8a93fb76ae Mon Sep 17 00:00:00 2001 From: drdr xp Date: Tue, 9 Nov 2021 01:26:05 +0800 Subject: [PATCH 01/17] [metasrv] refactor: remove unused proto --- metasrv/proto/meta.proto | 45 +--------------------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/metasrv/proto/meta.proto b/metasrv/proto/meta.proto index 2ed16a08eb15..b8da40f026da 100644 --- a/metasrv/proto/meta.proto +++ b/metasrv/proto/meta.proto @@ -14,53 +14,10 @@ syntax = "proto3"; -// meta data types for Databend meta server package meta; -// TODO(zbr): keep it or remove -message Db { - int64 db_id = 1; - // Every modification has a corresponding unique ver. - int64 ver = 20; - map table_name_to_id = 2; - map tables = 3; -} - -// TODO(zbr): keep it or remove -message Table { - int64 table_id = 1; - // Every modification has a corresponding unique ver. - int64 ver = 20; - - bytes schema = 5; - - map options = 30; - // a func(string, Vec) mapping PartitionBy expr to - // replication group. A DatabendQuery process should consider this to determine - // where to send the read or write operations. - bytes placement_policy = 10; - // repeated ReplicationGroupId ReplicationGroupIds -} - -// A Cmd serves as a raft log entry to commit an atomic operation into meta data -// storage. - -// TODO(zbr): keep it or remove -message CmdCreateDatabase { - string db_name = 20; - Db db = 50; -} - -// TODO(zbr): keep it or remove -message CmdCreateTable { - string db_name = 20; - string table_name = 30; - Table table = 40; -} - -// meta service - message GetReq { string key = 1; } + message GetReply { bool ok = 1; string key = 2; From b8b42e855b4272baa0febe1a0f9431ded4af2f95 Mon Sep 17 00:00:00 2001 From: drdr xp Date: Tue, 9 Nov 2021 14:56:04 +0800 Subject: [PATCH 02/17] [metasrv] refactor: impl KVApi for MetaNode, as it already provides the methods in KVApi --- metasrv/src/executor/kv_handlers.rs | 34 ++----- .../src/meta_service/meta_node_kv_api_impl.rs | 89 +++++++++++++++++++ metasrv/src/meta_service/mod.rs | 1 + metasrv/src/meta_service/raftmeta.rs | 29 ------ metasrv/src/meta_service/raftmeta_test.rs | 1 + 5 files changed, 97 insertions(+), 57 deletions(-) create mode 100644 metasrv/src/meta_service/meta_node_kv_api_impl.rs diff --git a/metasrv/src/executor/kv_handlers.rs b/metasrv/src/executor/kv_handlers.rs index 84e511b6dc90..5faa87febf23 100644 --- a/metasrv/src/executor/kv_handlers.rs +++ b/metasrv/src/executor/kv_handlers.rs @@ -13,15 +13,12 @@ // limitations under the License. // -use common_exception::ErrorCode; +use common_meta_api::KVApi; use common_meta_flight::GetKVAction; use common_meta_flight::MGetKVAction; use common_meta_flight::PrefixListReq; use common_meta_flight::UpsertKVAction; -use common_meta_raft_store::state_machine::AppliedState; -use common_meta_types::Cmd; use common_meta_types::GetKVActionReply; -use common_meta_types::LogEntry; use common_meta_types::MGetKVActionReply; use common_meta_types::PrefixListReply; use common_meta_types::UpsertKVActionReply; @@ -32,48 +29,29 @@ use crate::executor::ActionHandler; #[async_trait::async_trait] impl RequestHandler for ActionHandler { async fn handle(&self, act: UpsertKVAction) -> common_exception::Result { - let cr = LogEntry { - txid: None, - cmd: Cmd::UpsertKV { - key: act.key, - seq: act.seq, - value: act.value, - value_meta: act.value_meta, - }, - }; - let rst = self - .meta_node - .write(cr) + self.meta_node + .upsert_kv(&act.key, act.seq, act.value, act.value_meta) .await - .map_err(|e| ErrorCode::MetaNodeInternalError(e.to_string()))?; - - match rst { - AppliedState::KV(x) => Ok(x), - _ => Err(ErrorCode::MetaNodeInternalError("not a KV result")), - } } } #[async_trait::async_trait] impl RequestHandler for ActionHandler { async fn handle(&self, act: GetKVAction) -> common_exception::Result { - let result = self.meta_node.get_kv(&act.key).await?; - Ok(result) + self.meta_node.get_kv(&act.key).await } } #[async_trait::async_trait] impl RequestHandler for ActionHandler { async fn handle(&self, act: MGetKVAction) -> common_exception::Result { - let result = self.meta_node.mget_kv(&act.keys).await?; - Ok(result) + self.meta_node.mget_kv(&act.keys).await } } #[async_trait::async_trait] impl RequestHandler for ActionHandler { async fn handle(&self, act: PrefixListReq) -> common_exception::Result { - let result = self.meta_node.prefix_list_kv(&(act.0)).await?; - Ok(result) + self.meta_node.prefix_list_kv(&(act.0)).await } } diff --git a/metasrv/src/meta_service/meta_node_kv_api_impl.rs b/metasrv/src/meta_service/meta_node_kv_api_impl.rs new file mode 100644 index 000000000000..35dc91e509ef --- /dev/null +++ b/metasrv/src/meta_service/meta_node_kv_api_impl.rs @@ -0,0 +1,89 @@ +// Copyright 2020 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 async_trait::async_trait; +use common_exception::ErrorCode; +use common_meta_api::KVApi; +use common_meta_raft_store::state_machine::AppliedState; +use common_meta_types::Cmd; +use common_meta_types::GetKVActionReply; +use common_meta_types::KVMeta; +use common_meta_types::LogEntry; +use common_meta_types::MGetKVActionReply; +use common_meta_types::MatchSeq; +use common_meta_types::Operation; +use common_meta_types::PrefixListReply; +use common_meta_types::UpsertKVActionReply; +use common_tracing::tracing; + +use crate::meta_service::MetaNode; + +/// Impl KVApi for MetaNode. +/// +/// Write through raft-log. +/// Read through local state machine, which may not be consistent. +/// E.g. Read is not guaranteed to see a write. +#[async_trait] +impl KVApi for MetaNode { + async fn upsert_kv( + &self, + key: &str, + seq: MatchSeq, + value: Operation>, + value_meta: Option, + ) -> common_exception::Result { + let ent = LogEntry { + txid: None, + cmd: Cmd::UpsertKV { + key: key.to_string(), + seq, + value, + value_meta, + }, + }; + let rst = self + .write(ent) + .await + .map_err(|e| ErrorCode::MetaNodeInternalError(e.to_string()))?; + + match rst { + AppliedState::KV(x) => Ok(x), + _ => Err(ErrorCode::MetaNodeInternalError("not a KV result")), + } + } + + #[tracing::instrument(level = "debug", skip(self))] + async fn get_kv(&self, key: &str) -> common_exception::Result { + // inconsistent get: from local state machine + + let sm = self.sto.state_machine.read().await; + sm.get_kv(key).await + } + + #[tracing::instrument(level = "debug", skip(self))] + async fn mget_kv(&self, keys: &[String]) -> common_exception::Result { + // inconsistent get: from local state machine + + let sm = self.sto.state_machine.read().await; + sm.mget_kv(keys).await + } + + #[tracing::instrument(level = "debug", skip(self))] + async fn prefix_list_kv(&self, prefix: &str) -> common_exception::Result { + // inconsistent get: from local state machine + + let sm = self.sto.state_machine.read().await; + sm.prefix_list_kv(prefix).await + } +} diff --git a/metasrv/src/meta_service/mod.rs b/metasrv/src/meta_service/mod.rs index 2f33a25ee6cf..33dd94c8b096 100644 --- a/metasrv/src/meta_service/mod.rs +++ b/metasrv/src/meta_service/mod.rs @@ -21,6 +21,7 @@ pub use raftmeta::MetaNode; mod message; mod meta_leader; +mod meta_node_kv_api_impl; pub mod meta_service_impl; pub mod network; pub mod raftmeta; diff --git a/metasrv/src/meta_service/raftmeta.rs b/metasrv/src/meta_service/raftmeta.rs index a05a673d6862..8dccdb8b8f9e 100644 --- a/metasrv/src/meta_service/raftmeta.rs +++ b/metasrv/src/meta_service/raftmeta.rs @@ -28,7 +28,6 @@ use common_base::tokio::sync::RwLockReadGuard; use common_base::tokio::task::JoinHandle; use common_exception::prelude::ErrorCode; use common_exception::prelude::ToErrorCode; -use common_meta_api::KVApi; use common_meta_raft_store::config::RaftConfig; use common_meta_raft_store::state_machine::AppliedState; use common_meta_raft_store::state_machine::StateMachine; @@ -530,34 +529,6 @@ impl MetaNode { sm.get_table_by_id(tid) } - #[tracing::instrument(level = "debug", skip(self))] - pub async fn get_kv(&self, key: &str) -> common_exception::Result>>> { - // inconsistent get: from local state machine - - let sm = self.sto.state_machine.read().await; - sm.get_kv(key).await - } - - #[tracing::instrument(level = "debug", skip(self))] - pub async fn mget_kv( - &self, - keys: &[String], - ) -> common_exception::Result>>>> { - // inconsistent get: from local state machine - let sm = self.sto.state_machine.read().await; - sm.mget_kv(keys).await - } - - #[tracing::instrument(level = "debug", skip(self))] - pub async fn prefix_list_kv( - &self, - prefix: &str, - ) -> common_exception::Result>)>> { - // inconsistent get: from local state machine - let sm = self.sto.state_machine.read().await; - sm.prefix_list_kv(prefix).await - } - /// Submit a write request to the known leader. Returns the response after applying the request. #[tracing::instrument(level = "info", skip(self))] pub async fn write(&self, req: LogEntry) -> common_exception::Result { diff --git a/metasrv/src/meta_service/raftmeta_test.rs b/metasrv/src/meta_service/raftmeta_test.rs index 8eae85c3bf52..ce1faf9fae3a 100644 --- a/metasrv/src/meta_service/raftmeta_test.rs +++ b/metasrv/src/meta_service/raftmeta_test.rs @@ -19,6 +19,7 @@ use async_raft::RaftMetrics; use async_raft::State; use common_base::tokio; use common_base::tokio::time::Duration; +use common_meta_api::KVApi; use common_meta_raft_store::state_machine::AppliedState; use common_meta_types::Cmd; use common_meta_types::LogEntry; From d75584be3225fbf5a8c3145881f9c23de09a62d4 Mon Sep 17 00:00:00 2001 From: drdr xp Date: Tue, 9 Nov 2021 15:20:13 +0800 Subject: [PATCH 03/17] [common/meta] refactor: move UpsertKVAction to meta/types --- common/meta/api/src/kv_api.rs | 1 + common/meta/flight/src/flight_action.rs | 13 +------------ common/meta/flight/src/impls/kv_api_impl.rs | 2 +- .../meta/types/src/{kv_reply.rs => kv_message.rs} | 11 +++++++++++ common/meta/types/src/lib.rs | 11 ++++++----- metasrv/src/executor/action_handler.rs | 1 + metasrv/src/executor/kv_handlers.rs | 2 +- 7 files changed, 22 insertions(+), 19 deletions(-) rename common/meta/types/src/{kv_reply.rs => kv_message.rs} (75%) diff --git a/common/meta/api/src/kv_api.rs b/common/meta/api/src/kv_api.rs index c03a9ef974c4..534be8277f67 100644 --- a/common/meta/api/src/kv_api.rs +++ b/common/meta/api/src/kv_api.rs @@ -22,6 +22,7 @@ use common_meta_types::MGetKVActionReply; use common_meta_types::MatchSeq; use common_meta_types::Operation; use common_meta_types::PrefixListReply; +use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; #[async_trait] diff --git a/common/meta/flight/src/flight_action.rs b/common/meta/flight/src/flight_action.rs index f191cde8dce2..d03177b13bfb 100644 --- a/common/meta/flight/src/flight_action.rs +++ b/common/meta/flight/src/flight_action.rs @@ -22,14 +22,12 @@ use common_meta_types::CreateDatabaseReply; use common_meta_types::CreateTableReply; use common_meta_types::DatabaseInfo; use common_meta_types::GetKVActionReply; -use common_meta_types::KVMeta; use common_meta_types::MGetKVActionReply; -use common_meta_types::MatchSeq; use common_meta_types::MetaId; use common_meta_types::MetaVersion; -use common_meta_types::Operation; use common_meta_types::PrefixListReply; use common_meta_types::TableInfo; +use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; use common_meta_types::UpsertTableOptionReply; use common_planners::CreateDatabasePlan; @@ -160,15 +158,6 @@ action_declare!( MetaFlightAction::PrefixListKV ); -// === general-kv: upsert === -#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] -pub struct UpsertKVAction { - pub key: String, - pub seq: MatchSeq, - pub value: Operation>, - pub value_meta: Option, -} - action_declare!( UpsertKVAction, UpsertKVActionReply, diff --git a/common/meta/flight/src/impls/kv_api_impl.rs b/common/meta/flight/src/impls/kv_api_impl.rs index e35a78505f66..dc69e71d7429 100644 --- a/common/meta/flight/src/impls/kv_api_impl.rs +++ b/common/meta/flight/src/impls/kv_api_impl.rs @@ -20,6 +20,7 @@ use common_meta_types::MGetKVActionReply; use common_meta_types::MatchSeq; use common_meta_types::Operation; use common_meta_types::PrefixListReply; +use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; use common_tracing::tracing; @@ -27,7 +28,6 @@ use crate::GetKVAction; use crate::MGetKVAction; use crate::MetaFlightClient; use crate::PrefixListReq; -use crate::UpsertKVAction; #[async_trait::async_trait] impl KVApi for MetaFlightClient { diff --git a/common/meta/types/src/kv_reply.rs b/common/meta/types/src/kv_message.rs similarity index 75% rename from common/meta/types/src/kv_reply.rs rename to common/meta/types/src/kv_message.rs index fb6763200645..61dd2deb03cf 100644 --- a/common/meta/types/src/kv_reply.rs +++ b/common/meta/types/src/kv_message.rs @@ -13,9 +13,20 @@ // limitations under the License. use crate::Change; +use crate::KVMeta; +use crate::MatchSeq; +use crate::Operation; use crate::SeqV; pub type UpsertKVActionReply = Change>; pub type GetKVActionReply = Option>>; pub type MGetKVActionReply = Vec>>>; pub type PrefixListReply = Vec<(String, SeqV>)>; + +#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] +pub struct UpsertKVAction { + pub key: String, + pub seq: MatchSeq, + pub value: Operation>, + pub value_meta: Option, +} diff --git a/common/meta/types/src/lib.rs b/common/meta/types/src/lib.rs index 5a2bbc54d357..e2918acbb40a 100644 --- a/common/meta/types/src/lib.rs +++ b/common/meta/types/src/lib.rs @@ -33,10 +33,11 @@ pub use commit_table_reply::UpsertTableOptionReply; pub use database_info::DatabaseInfo; pub use database_reply::CreateDatabaseReply; pub use errors::ConflictSeq; -pub use kv_reply::GetKVActionReply; -pub use kv_reply::MGetKVActionReply; -pub use kv_reply::PrefixListReply; -pub use kv_reply::UpsertKVActionReply; +pub use kv_message::GetKVActionReply; +pub use kv_message::MGetKVActionReply; +pub use kv_message::PrefixListReply; +pub use kv_message::UpsertKVAction; +pub use kv_message::UpsertKVActionReply; pub use log_entry::LogEntry; pub use match_seq::MatchSeq; pub use match_seq::MatchSeqExt; @@ -68,7 +69,7 @@ mod commit_table_reply; mod database_info; mod database_reply; mod errors; -mod kv_reply; +mod kv_message; mod log_entry; mod match_seq; mod operation; diff --git a/metasrv/src/executor/action_handler.rs b/metasrv/src/executor/action_handler.rs index 20d4f2b69641..351a71468c8b 100644 --- a/metasrv/src/executor/action_handler.rs +++ b/metasrv/src/executor/action_handler.rs @@ -15,6 +15,7 @@ use std::sync::Arc; use common_exception::ErrorCode; +use common_meta_api::KVApi; use common_meta_flight::MetaFlightAction; use common_meta_flight::RequestFor; use serde::Serialize; diff --git a/metasrv/src/executor/kv_handlers.rs b/metasrv/src/executor/kv_handlers.rs index 5faa87febf23..800f63472ebc 100644 --- a/metasrv/src/executor/kv_handlers.rs +++ b/metasrv/src/executor/kv_handlers.rs @@ -17,10 +17,10 @@ use common_meta_api::KVApi; use common_meta_flight::GetKVAction; use common_meta_flight::MGetKVAction; use common_meta_flight::PrefixListReq; -use common_meta_flight::UpsertKVAction; use common_meta_types::GetKVActionReply; use common_meta_types::MGetKVActionReply; use common_meta_types::PrefixListReply; +use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; use crate::executor::action_handler::RequestHandler; From 65929fd252fcda1b470eb88f2a307424d79000d7 Mon Sep 17 00:00:00 2001 From: drdr xp Date: Tue, 9 Nov 2021 16:17:16 +0800 Subject: [PATCH 04/17] [common/meta/api] refactor: upsert_kv use UpsertAction as a arg container --- .../management/src/namespace/namespace_mgr.rs | 18 ++- common/management/src/user/user_mgr.rs | 22 ++- common/management/src/user/user_mgr_test.rs | 122 ++++++++--------- common/meta/api/src/kv_api.rs | 19 +-- common/meta/api/src/kv_api_test_suite.rs | 126 +++++++++++------- common/meta/embedded/src/kv_api_impl.rs | 11 +- common/meta/flight/src/impls/kv_api_impl.rs | 19 +-- .../src/state_machine/sm_kv_api_impl.rs | 17 +-- common/meta/types/src/kv_message.rs | 18 ++- metasrv/src/executor/action_handler.rs | 1 - metasrv/src/executor/kv_handlers.rs | 4 +- .../src/meta_service/meta_node_kv_api_impl.rs | 17 +-- metasrv/tests/flight/metasrv_flight_api.rs | 9 +- 13 files changed, 213 insertions(+), 190 deletions(-) diff --git a/common/management/src/namespace/namespace_mgr.rs b/common/management/src/namespace/namespace_mgr.rs index c63cd39ad62c..24c37d788cce 100644 --- a/common/management/src/namespace/namespace_mgr.rs +++ b/common/management/src/namespace/namespace_mgr.rs @@ -27,6 +27,7 @@ use common_meta_types::MatchSeq; use common_meta_types::NodeInfo; use common_meta_types::Operation; use common_meta_types::SeqV; +use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; use crate::namespace::NamespaceApi; @@ -143,7 +144,9 @@ impl NamespaceApi for NamespaceMgr { self.namespace_prefix, Self::escape_for_key(&node.id)? ); - let upsert_node = self.kv_api.upsert_kv(&node_key, seq, value, meta); + let upsert_node = self + .kv_api + .upsert_kv(UpsertKVAction::new(&node_key, seq, value, meta)); let res = upsert_node.await?.into_add_result()?; @@ -177,9 +180,12 @@ impl NamespaceApi for NamespaceMgr { self.namespace_prefix, Self::escape_for_key(&node_id)? ); - let upsert_node = self - .kv_api - .upsert_kv(&node_key, seq.into(), Operation::Delete, None); + let upsert_node = self.kv_api.upsert_kv(UpsertKVAction::new( + &node_key, + seq.into(), + Operation::Delete, + None, + )); match upsert_node.await? { UpsertKVActionReply { @@ -205,7 +211,9 @@ impl NamespaceApi for NamespaceMgr { Some(exact) => MatchSeq::Exact(exact), }; - let upsert_meta = self.kv_api.upsert_kv(&node_key, seq, Operation::AsIs, meta); + let upsert_meta = + self.kv_api + .upsert_kv(UpsertKVAction::new(&node_key, seq, Operation::AsIs, meta)); match upsert_meta.await? { UpsertKVActionReply { diff --git a/common/management/src/user/user_mgr.rs b/common/management/src/user/user_mgr.rs index 371a02378393..36cee7703c27 100644 --- a/common/management/src/user/user_mgr.rs +++ b/common/management/src/user/user_mgr.rs @@ -26,6 +26,7 @@ use common_meta_types::MatchSeq; use common_meta_types::MatchSeqExt; use common_meta_types::Operation; use common_meta_types::SeqV; +use common_meta_types::UpsertKVAction; use crate::user::user_api::UserInfo; use crate::user::user_api::UserMgrApi; @@ -54,7 +55,12 @@ impl UserMgrApi for UserMgr { let value = serde_json::to_vec(&user_info)?; let kv_api = self.kv_api.clone(); - let upsert_kv = kv_api.upsert_kv(&key, match_seq, Operation::Update(value), None); + let upsert_kv = kv_api.upsert_kv(UpsertKVAction::new( + &key, + match_seq, + Operation::Update(value), + None, + )); let res = upsert_kv.await?.into_add_result()?; match res { AddResult::Ok(v) => Ok(v.seq), @@ -138,7 +144,12 @@ impl UserMgrApi for UserMgr { let kv_api = self.kv_api.clone(); let upsert_kv = async move { kv_api - .upsert_kv(&key, match_seq, Operation::Update(value), None) + .upsert_kv(UpsertKVAction::new( + &key, + match_seq, + Operation::Update(value), + None, + )) .await }; let res = upsert_kv.await?; @@ -156,7 +167,12 @@ impl UserMgrApi for UserMgr { let kv_api = self.kv_api.clone(); let upsert_kv = async move { kv_api - .upsert_kv(&key, seq.into(), Operation::Delete, None) + .upsert_kv(UpsertKVAction::new( + &key, + seq.into(), + Operation::Delete, + None, + )) .await }; let res = upsert_kv.await?; diff --git a/common/management/src/user/user_mgr_test.rs b/common/management/src/user/user_mgr_test.rs index 398ffe61797d..a07a660f1758 100644 --- a/common/management/src/user/user_mgr_test.rs +++ b/common/management/src/user/user_mgr_test.rs @@ -20,12 +20,12 @@ use common_base::tokio; use common_exception::ErrorCode; use common_meta_api::KVApi; use common_meta_types::GetKVActionReply; -use common_meta_types::KVMeta; use common_meta_types::MGetKVActionReply; use common_meta_types::MatchSeq; use common_meta_types::Operation; use common_meta_types::PrefixListReply; use common_meta_types::SeqV; +use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; use mockall::predicate::*; use mockall::*; @@ -41,10 +41,7 @@ mock! { impl KVApi for KV { async fn upsert_kv( &self, - key: &str, - seq: MatchSeq, - value: Operation>, - value_meta: Option + act: UpsertKVAction, ) -> common_exception::Result; async fn get_kv(&self, key: &str) -> common_exception::Result; @@ -86,14 +83,14 @@ mod add { let test_key = test_key.clone(); let mut api = MockKV::new(); api.expect_upsert_kv() - .with( - predicate::function(move |v| v == test_key.as_str()), - predicate::eq(test_seq), - predicate::eq(value.clone()), - predicate::eq(None), - ) + .with(predicate::eq(UpsertKVAction::new( + &test_key, + test_seq, + value.clone(), + None, + ))) .times(1) - .return_once(|_u, _s, _salt, _meta| Ok(UpsertKVActionReply::new(None, None))); + .return_once(|_u| Ok(UpsertKVActionReply::new(None, None))); let api = Arc::new(api); let user_mgr = UserMgr::new(api, "tenant1"); let res = user_mgr.add_user(user_info); @@ -109,14 +106,14 @@ mod add { let test_key = test_key.clone(); let mut api = MockKV::new(); api.expect_upsert_kv() - .with( - predicate::function(move |v| v == test_key.as_str()), - predicate::eq(test_seq), - predicate::eq(value.clone()), - predicate::eq(None), - ) + .with(predicate::eq(UpsertKVAction::new( + &test_key, + test_seq, + value.clone(), + None, + ))) .times(1) - .returning(|_u, _s, _salt, _meta| { + .returning(|_u| { Ok(UpsertKVActionReply::new( Some(SeqV::new(1, vec![])), Some(SeqV::new(1, vec![])), @@ -145,14 +142,14 @@ mod add { { let mut api = MockKV::new(); api.expect_upsert_kv() - .with( - predicate::function(move |v| v == test_key.as_str()), - predicate::eq(test_seq), - predicate::eq(value), - predicate::eq(None), - ) + .with(predicate::eq(UpsertKVAction::new( + &test_key, + test_seq, + value.clone(), + None, + ))) .times(1) - .returning(|_u, _s, _salt, _meta| Ok(UpsertKVActionReply::new(None, None))); + .returning(|_u| Ok(UpsertKVActionReply::new(None, None))); let kv = Arc::new(api); @@ -387,16 +384,14 @@ mod drop { let mut kv = MockKV::new(); let test_key = "__fd_users/tenant1/test"; kv.expect_upsert_kv() - .with( - predicate::function(move |v| v == test_key), - predicate::eq(MatchSeq::Any), - predicate::eq(Operation::Delete), - predicate::eq(None), - ) + .with(predicate::eq(UpsertKVAction::new( + test_key, + MatchSeq::Any, + Operation::Delete, + None, + ))) .times(1) - .returning(|_k, _seq, _none, _meta| { - Ok(UpsertKVActionReply::new(Some(SeqV::new(1, vec![])), None)) - }); + .returning(|_k| Ok(UpsertKVActionReply::new(Some(SeqV::new(1, vec![])), None))); let kv = Arc::new(kv); let user_mgr = UserMgr::new(kv, "tenant1"); let res = user_mgr.drop_user("test".to_string(), None); @@ -410,14 +405,14 @@ mod drop { let mut kv = MockKV::new(); let test_key = "__fd_users/tenant1/test"; kv.expect_upsert_kv() - .with( - predicate::function(move |v| v == test_key), - predicate::eq(MatchSeq::Any), - predicate::eq(Operation::Delete), - predicate::eq(None), - ) + .with(predicate::eq(UpsertKVAction::new( + test_key, + MatchSeq::Any, + Operation::Delete, + None, + ))) .times(1) - .returning(|_k, _seq, _none, _meta| Ok(UpsertKVActionReply::new(None, None))); + .returning(|_k| Ok(UpsertKVActionReply::new(None, None))); let kv = Arc::new(kv); let user_mgr = UserMgr::new(kv, "tenant1"); let res = user_mgr.drop_user("test".to_string(), None); @@ -474,16 +469,14 @@ mod update { let new_value_with_old_salt = serde_json::to_vec(&new_user_info)?; kv.expect_upsert_kv() - .with( - predicate::function(move |v| v == test_key.as_str()), - predicate::eq(MatchSeq::GE(1)), - predicate::eq(Operation::Update(new_value_with_old_salt)), - predicate::eq(None), - ) + .with(predicate::eq(UpsertKVAction::new( + &test_key, + MatchSeq::GE(1), + Operation::Update(new_value_with_old_salt.clone()), + None, + ))) .times(1) - .return_once(|_, _, _, _meta| { - Ok(UpsertKVActionReply::new(None, Some(SeqV::new(0, vec![])))) - }); + .return_once(|_| Ok(UpsertKVActionReply::new(None, Some(SeqV::new(0, vec![]))))); let kv = Arc::new(kv); let user_mgr = UserMgr::new(kv, "tenant1"); @@ -523,16 +516,14 @@ mod update { let mut kv = MockKV::new(); kv.expect_upsert_kv() - .with( - predicate::function(move |v| v == test_key.as_str()), - predicate::eq(MatchSeq::GE(1)), - predicate::eq(Operation::Update(new_value)), - predicate::eq(None), - ) + .with(predicate::eq(UpsertKVAction::new( + &test_key, + MatchSeq::GE(1), + Operation::Update(new_value), + None, + ))) .times(1) - .return_once(|_, _, _, _meta| { - Ok(UpsertKVActionReply::new(None, Some(SeqV::new(0, vec![])))) - }); + .return_once(|_| Ok(UpsertKVActionReply::new(None, Some(SeqV::new(0, vec![]))))); let kv = Arc::new(kv); let user_mgr = UserMgr::new(kv, "tenant1"); @@ -605,14 +596,11 @@ mod update { // upsert should be called kv.expect_upsert_kv() - .with( - predicate::function(move |v| v == test_key.as_str()), - predicate::eq(MatchSeq::GE(1)), - predicate::always(), // a little bit relax here, as we've covered it before - predicate::eq(None), - ) + .with(predicate::function(move |act: &UpsertKVAction| { + act.key == test_key.as_str() && act.seq == MatchSeq::GE(1) + })) .times(1) - .returning(|_u, _s, _salt, _meta| Ok(UpsertKVActionReply::new(None, None))); + .returning(|_| Ok(UpsertKVActionReply::new(None, None))); let kv = Arc::new(kv); let user_mgr = UserMgr::new(kv, "tenant1"); diff --git a/common/meta/api/src/kv_api.rs b/common/meta/api/src/kv_api.rs index 534be8277f67..2a5649e50db5 100644 --- a/common/meta/api/src/kv_api.rs +++ b/common/meta/api/src/kv_api.rs @@ -17,23 +17,15 @@ use std::sync::Arc; use async_trait::async_trait; use common_meta_types::GetKVActionReply; -use common_meta_types::KVMeta; use common_meta_types::MGetKVActionReply; -use common_meta_types::MatchSeq; -use common_meta_types::Operation; use common_meta_types::PrefixListReply; use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; #[async_trait] pub trait KVApi: Send + Sync { - async fn upsert_kv( - &self, - key: &str, - seq: MatchSeq, - value: Operation>, - value_meta: Option, - ) -> common_exception::Result; + async fn upsert_kv(&self, act: UpsertKVAction) + -> common_exception::Result; async fn get_kv(&self, key: &str) -> common_exception::Result; @@ -47,12 +39,9 @@ pub trait KVApi: Send + Sync { impl KVApi for Arc { async fn upsert_kv( &self, - key: &str, - seq: MatchSeq, - value: Operation>, - value_meta: Option, + act: UpsertKVAction, ) -> common_exception::Result { - self.as_ref().upsert_kv(key, seq, value, value_meta).await + self.as_ref().upsert_kv(act).await } async fn get_kv(&self, key: &str) -> common_exception::Result { diff --git a/common/meta/api/src/kv_api_test_suite.rs b/common/meta/api/src/kv_api_test_suite.rs index 2a6f3f1d0530..e68aaa102478 100644 --- a/common/meta/api/src/kv_api_test_suite.rs +++ b/common/meta/api/src/kv_api_test_suite.rs @@ -20,6 +20,7 @@ use common_meta_types::KVMeta; use common_meta_types::MatchSeq; use common_meta_types::Operation; use common_meta_types::SeqV; +use common_meta_types::UpsertKVAction; use common_tracing::tracing; use crate::KVApi; @@ -30,12 +31,12 @@ impl KVApiTestSuite { { // write let res = kv - .upsert_kv( + .upsert_kv(UpsertKVAction::new( "foo", MatchSeq::Any, Operation::Update(b"bar".to_vec()), None, - ) + )) .await?; assert_eq!(None, res.prev); assert_eq!(Some(SeqV::with_meta(1, None, b"bar".to_vec())), res.result); @@ -44,12 +45,12 @@ impl KVApiTestSuite { { // write fails with unmatched seq let res = kv - .upsert_kv( + .upsert_kv(UpsertKVAction::new( "foo", MatchSeq::Exact(2), Operation::Update(b"bar".to_vec()), None, - ) + )) .await?; assert_eq!( ( @@ -64,12 +65,12 @@ impl KVApiTestSuite { { // write done with matching seq let res = kv - .upsert_kv( + .upsert_kv(UpsertKVAction::new( "foo", MatchSeq::Exact(1), Operation::Update(b"wow".to_vec()), None, - ) + )) .await?; assert_eq!( Some(SeqV::with_meta(1, None, b"bar".to_vec())), @@ -89,12 +90,12 @@ impl KVApiTestSuite { pub async fn kv_delete(&self, client: &KV) -> anyhow::Result<()> { let test_key = "test_key"; client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( test_key, MatchSeq::Any, Operation::Update(b"v1".to_vec()), None, - ) + )) .await?; let current = client.get_kv(test_key).await?; @@ -102,14 +103,24 @@ impl KVApiTestSuite { // seq mismatch let wrong_seq = Some(seq + 1); let res = client - .upsert_kv(test_key, wrong_seq.into(), Operation::Delete, None) + .upsert_kv(UpsertKVAction::new( + test_key, + wrong_seq.into(), + Operation::Delete, + None, + )) .await?; assert_eq!(res.prev, res.result); // seq match let res = client - .upsert_kv(test_key, MatchSeq::Exact(seq), Operation::Delete, None) + .upsert_kv(UpsertKVAction::new( + test_key, + MatchSeq::Exact(seq), + Operation::Delete, + None, + )) .await?; assert!(res.result.is_none()); @@ -122,23 +133,33 @@ impl KVApiTestSuite { // key not exist let res = client - .upsert_kv("not exists", MatchSeq::Any, Operation::Delete, None) + .upsert_kv(UpsertKVAction::new( + "not exists", + MatchSeq::Any, + Operation::Delete, + None, + )) .await?; assert_eq!(None, res.prev); assert_eq!(None, res.result); // do not care seq client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( test_key, MatchSeq::Any, Operation::Update(b"v2".to_vec()), None, - ) + )) .await?; let res = client - .upsert_kv(test_key, MatchSeq::Any, Operation::Delete, None) + .upsert_kv(UpsertKVAction::new( + test_key, + MatchSeq::Any, + Operation::Delete, + None, + )) .await?; assert_eq!( (Some(SeqV::with_meta(2, None, b"v2".to_vec())), None), @@ -152,58 +173,58 @@ impl KVApiTestSuite { let test_key = "test_key_for_update"; let r = client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( test_key, MatchSeq::GE(1), Operation::Update(b"v1".to_vec()), None, - ) + )) .await?; assert_eq!((None, None), (r.prev, r.result), "not changed"); let r = client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( test_key, MatchSeq::Any, Operation::Update(b"v1".to_vec()), None, - ) + )) .await?; assert_eq!(Some(SeqV::with_meta(1, None, b"v1".to_vec())), r.result); let seq = r.result.unwrap().seq; // unmatched seq let r = client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( test_key, MatchSeq::Exact(seq + 1), Operation::Update(b"v2".to_vec()), None, - ) + )) .await?; assert_eq!(Some(SeqV::with_meta(1, None, b"v1".to_vec())), r.prev); assert_eq!(Some(SeqV::with_meta(1, None, b"v1".to_vec())), r.result); // matched seq let r = client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( test_key, MatchSeq::Exact(seq), Operation::Update(b"v2".to_vec()), None, - ) + )) .await?; assert_eq!(Some(SeqV::with_meta(1, None, b"v1".to_vec())), r.prev); assert_eq!(Some(SeqV::with_meta(2, None, b"v2".to_vec())), r.result); // blind update let r = client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( test_key, MatchSeq::GE(1), Operation::Update(b"v3".to_vec()), None, - ) + )) .await?; assert_eq!(Some(SeqV::with_meta(2, None, b"v2".to_vec())), r.prev); assert_eq!(Some(SeqV::with_meta(3, None, b"v3".to_vec())), r.result); @@ -228,14 +249,14 @@ impl KVApiTestSuite { .as_secs(); client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( "k1", MatchSeq::Any, Operation::Update(b"v1".to_vec()), Some(KVMeta { expire_at: Some(now + 1), }), - ) + )) .await?; tracing::info!("---get unexpired"); @@ -260,24 +281,24 @@ impl KVApiTestSuite { tracing::info!("--- expired entry act as if it does not exist, an ADD op should apply"); { client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( "k1", MatchSeq::Exact(0), Operation::Update(b"v1".to_vec()), Some(KVMeta { expire_at: Some(now - 1), }), - ) + )) .await?; client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( "k2", MatchSeq::Exact(0), Operation::Update(b"v2".to_vec()), Some(KVMeta { expire_at: Some(now + 2), }), - ) + )) .await?; tracing::info!("--- mget should not return expired"); @@ -307,14 +328,14 @@ impl KVApiTestSuite { tracing::info!("--- update expire"); { client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( "k2", MatchSeq::Exact(3), Operation::Update(b"v2".to_vec()), Some(KVMeta { expire_at: Some(now - 1), }), - ) + )) .await?; let res = client.get_kv(&"k2".to_string()).await?; @@ -333,12 +354,12 @@ impl KVApiTestSuite { .as_secs(); let r = client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( test_key, MatchSeq::Any, Operation::Update(b"v1".to_vec()), None, - ) + )) .await?; assert_eq!(Some(SeqV::with_meta(1, None, b"v1".to_vec())), r.result); let seq = r.result.unwrap().seq; @@ -346,14 +367,14 @@ impl KVApiTestSuite { tracing::info!("--- mismatching seq does nothing"); let r = client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( test_key, MatchSeq::Exact(seq + 1), Operation::AsIs, Some(KVMeta { expire_at: Some(now + 20), }), - ) + )) .await?; assert_eq!(Some(SeqV::with_meta(1, None, b"v1".to_vec())), r.prev); assert_eq!(Some(SeqV::with_meta(1, None, b"v1".to_vec())), r.result); @@ -361,14 +382,14 @@ impl KVApiTestSuite { tracing::info!("--- matching seq only update meta"); let r = client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( test_key, MatchSeq::Exact(seq), Operation::AsIs, Some(KVMeta { expire_at: Some(now + 20), }), - ) + )) .await?; assert_eq!(Some(SeqV::with_meta(1, None, b"v1".to_vec())), r.prev); assert_eq!( @@ -403,12 +424,12 @@ impl KVApiTestSuite { let mut values = vec![]; { client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( "t", MatchSeq::Any, Operation::Update("".as_bytes().to_vec()), None, - ) + )) .await?; for i in 0..9 { @@ -416,16 +437,21 @@ impl KVApiTestSuite { let val = format!("val_{}", i); values.push(val.clone()); client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( &key, MatchSeq::Any, Operation::Update(val.as_bytes().to_vec()), None, - ) + )) .await?; } client - .upsert_kv("v", MatchSeq::Any, Operation::Update(b"".to_vec()), None) + .upsert_kv(UpsertKVAction::new( + "v", + MatchSeq::Any, + Operation::Update(b"".to_vec()), + None, + )) .await?; } @@ -444,10 +470,20 @@ impl KVApiTestSuite { pub async fn kv_mget(&self, client: &KV) -> anyhow::Result<()> { client - .upsert_kv("k1", MatchSeq::Any, Operation::Update(b"v1".to_vec()), None) + .upsert_kv(UpsertKVAction::new( + "k1", + MatchSeq::Any, + Operation::Update(b"v1".to_vec()), + None, + )) .await?; client - .upsert_kv("k2", MatchSeq::Any, Operation::Update(b"v2".to_vec()), None) + .upsert_kv(UpsertKVAction::new( + "k2", + MatchSeq::Any, + Operation::Update(b"v2".to_vec()), + None, + )) .await?; let res = client diff --git a/common/meta/embedded/src/kv_api_impl.rs b/common/meta/embedded/src/kv_api_impl.rs index f584c1beab91..a09477596173 100644 --- a/common/meta/embedded/src/kv_api_impl.rs +++ b/common/meta/embedded/src/kv_api_impl.rs @@ -17,11 +17,9 @@ use common_exception::Result; use common_meta_api::KVApi; pub use common_meta_sled_store::init_temp_sled_db; use common_meta_types::GetKVActionReply; -use common_meta_types::KVMeta; use common_meta_types::MGetKVActionReply; -use common_meta_types::MatchSeq; -use common_meta_types::Operation; use common_meta_types::PrefixListReply; +use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; use crate::MetaEmbedded; @@ -30,13 +28,10 @@ use crate::MetaEmbedded; impl KVApi for MetaEmbedded { async fn upsert_kv( &self, - key: &str, - seq: MatchSeq, - value: Operation>, - value_meta: Option, + act: UpsertKVAction, ) -> common_exception::Result { let sm = self.inner.lock().await; - sm.upsert_kv(key, seq, value, value_meta).await + sm.upsert_kv(act).await } async fn get_kv(&self, key: &str) -> Result { diff --git a/common/meta/flight/src/impls/kv_api_impl.rs b/common/meta/flight/src/impls/kv_api_impl.rs index dc69e71d7429..a0054d53082d 100644 --- a/common/meta/flight/src/impls/kv_api_impl.rs +++ b/common/meta/flight/src/impls/kv_api_impl.rs @@ -15,10 +15,7 @@ use common_exception::Result; use common_meta_api::KVApi; use common_meta_types::GetKVActionReply; -use common_meta_types::KVMeta; use common_meta_types::MGetKVActionReply; -use common_meta_types::MatchSeq; -use common_meta_types::Operation; use common_meta_types::PrefixListReply; use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; @@ -31,21 +28,12 @@ use crate::PrefixListReq; #[async_trait::async_trait] impl KVApi for MetaFlightClient { - #[tracing::instrument(level = "debug", skip(self, value))] + #[tracing::instrument(level = "debug", skip(self, act))] async fn upsert_kv( &self, - key: &str, - seq: MatchSeq, - value: Operation>, - value_meta: Option, + act: UpsertKVAction, ) -> common_exception::Result { - self.do_action(UpsertKVAction { - key: key.to_string(), - seq, - value, - value_meta, - }) - .await + self.do_action(act).await } #[tracing::instrument(level = "debug", skip(self))] @@ -59,7 +47,6 @@ impl KVApi for MetaFlightClient { #[tracing::instrument(level = "debug", skip(self, keys))] async fn mget_kv(&self, keys: &[String]) -> common_exception::Result { let keys = keys.to_vec(); - //keys.iter().map(|k| k.to_string()).collect(); self.do_action(MGetKVAction { keys }).await } diff --git a/common/meta/raft-store/src/state_machine/sm_kv_api_impl.rs b/common/meta/raft-store/src/state_machine/sm_kv_api_impl.rs index bfba800612b8..b6d376a9e82d 100644 --- a/common/meta/raft-store/src/state_machine/sm_kv_api_impl.rs +++ b/common/meta/raft-store/src/state_machine/sm_kv_api_impl.rs @@ -15,11 +15,9 @@ use common_meta_api::KVApi; use common_meta_types::Cmd; use common_meta_types::GetKVActionReply; -use common_meta_types::KVMeta; use common_meta_types::MGetKVActionReply; -use common_meta_types::MatchSeq; -use common_meta_types::Operation; use common_meta_types::SeqV; +use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; use common_tracing::tracing; @@ -30,16 +28,13 @@ use crate::state_machine::StateMachine; impl KVApi for StateMachine { async fn upsert_kv( &self, - key: &str, - seq: MatchSeq, - value: Operation>, - value_meta: Option, + act: UpsertKVAction, ) -> common_exception::Result { let cmd = Cmd::UpsertKV { - key: key.to_string(), - seq, - value, - value_meta, + key: act.key, + seq: act.seq, + value: act.value, + value_meta: act.value_meta, }; let res = self.apply_cmd(&cmd).await?; diff --git a/common/meta/types/src/kv_message.rs b/common/meta/types/src/kv_message.rs index 61dd2deb03cf..35d2534e240d 100644 --- a/common/meta/types/src/kv_message.rs +++ b/common/meta/types/src/kv_message.rs @@ -23,10 +23,26 @@ pub type GetKVActionReply = Option>>; pub type MGetKVActionReply = Vec>>>; pub type PrefixListReply = Vec<(String, SeqV>)>; -#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] +#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq)] pub struct UpsertKVAction { pub key: String, pub seq: MatchSeq, pub value: Operation>, pub value_meta: Option, } + +impl UpsertKVAction { + pub fn new( + key: &str, + seq: MatchSeq, + value: Operation>, + value_meta: Option, + ) -> Self { + Self { + key: key.to_string(), + seq, + value, + value_meta, + } + } +} diff --git a/metasrv/src/executor/action_handler.rs b/metasrv/src/executor/action_handler.rs index 351a71468c8b..20d4f2b69641 100644 --- a/metasrv/src/executor/action_handler.rs +++ b/metasrv/src/executor/action_handler.rs @@ -15,7 +15,6 @@ use std::sync::Arc; use common_exception::ErrorCode; -use common_meta_api::KVApi; use common_meta_flight::MetaFlightAction; use common_meta_flight::RequestFor; use serde::Serialize; diff --git a/metasrv/src/executor/kv_handlers.rs b/metasrv/src/executor/kv_handlers.rs index 800f63472ebc..47114a66286d 100644 --- a/metasrv/src/executor/kv_handlers.rs +++ b/metasrv/src/executor/kv_handlers.rs @@ -29,9 +29,7 @@ use crate::executor::ActionHandler; #[async_trait::async_trait] impl RequestHandler for ActionHandler { async fn handle(&self, act: UpsertKVAction) -> common_exception::Result { - self.meta_node - .upsert_kv(&act.key, act.seq, act.value, act.value_meta) - .await + self.meta_node.upsert_kv(act).await } } diff --git a/metasrv/src/meta_service/meta_node_kv_api_impl.rs b/metasrv/src/meta_service/meta_node_kv_api_impl.rs index 35dc91e509ef..6f4a9d5f68ed 100644 --- a/metasrv/src/meta_service/meta_node_kv_api_impl.rs +++ b/metasrv/src/meta_service/meta_node_kv_api_impl.rs @@ -18,12 +18,10 @@ use common_meta_api::KVApi; use common_meta_raft_store::state_machine::AppliedState; use common_meta_types::Cmd; use common_meta_types::GetKVActionReply; -use common_meta_types::KVMeta; use common_meta_types::LogEntry; use common_meta_types::MGetKVActionReply; -use common_meta_types::MatchSeq; -use common_meta_types::Operation; use common_meta_types::PrefixListReply; +use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; use common_tracing::tracing; @@ -38,18 +36,15 @@ use crate::meta_service::MetaNode; impl KVApi for MetaNode { async fn upsert_kv( &self, - key: &str, - seq: MatchSeq, - value: Operation>, - value_meta: Option, + act: UpsertKVAction, ) -> common_exception::Result { let ent = LogEntry { txid: None, cmd: Cmd::UpsertKV { - key: key.to_string(), - seq, - value, - value_meta, + key: act.key, + seq: act.seq, + value: act.value, + value_meta: act.value_meta, }, }; let rst = self diff --git a/metasrv/tests/flight/metasrv_flight_api.rs b/metasrv/tests/flight/metasrv_flight_api.rs index 49971b39d006..c19a7ffaaeac 100644 --- a/metasrv/tests/flight/metasrv_flight_api.rs +++ b/metasrv/tests/flight/metasrv_flight_api.rs @@ -20,6 +20,7 @@ use common_meta_flight::MetaFlightClient; use common_meta_types::MatchSeq; use common_meta_types::Operation; use common_meta_types::SeqV; +use common_meta_types::UpsertKVAction; use common_meta_types::UpsertKVActionReply; use common_tracing::tracing; use databend_meta::init_meta_ut; @@ -46,12 +47,12 @@ async fn test_restart() -> anyhow::Result<()> { tracing::info!("--- upsert kv"); { let res = client - .upsert_kv( + .upsert_kv(UpsertKVAction::new( "foo", MatchSeq::Any, Operation::Update(b"bar".to_vec()), None, - ) + )) .await; tracing::debug!("set kv res: {:?}", res); @@ -163,12 +164,12 @@ async fn test_join() -> anyhow::Result<()> { let k = format!("join-{}", i); let res = cli - .upsert_kv( + .upsert_kv(UpsertKVAction::new( k.as_str(), MatchSeq::Any, Operation::Update(k.clone().into_bytes()), None, - ) + )) .await; tracing::debug!("set kv res: {:?}", res); From e20c97bd0faa4289b31cd70068a2da696217be64 Mon Sep 17 00:00:00 2001 From: zhihanz Date: Wed, 10 Nov 2021 09:23:49 +0800 Subject: [PATCH 05/17] release *** issue fix --- .github/workflows/databend-release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/databend-release.yml b/.github/workflows/databend-release.yml index f3e29e883373..6b9e9f3a435a 100644 --- a/.github/workflows/databend-release.yml +++ b/.github/workflows/databend-release.yml @@ -142,4 +142,5 @@ jobs: mkdir -p ./target/aarch64-unknown-linux-gnu/release tar xC ./target/x86_64-unknown-linux-gnu/release -f ./databend-${{ steps.get_version.outputs.VERSION }}-x86_64-unknown-linux-gnu.tar.gz tar xC ./target/aarch64-unknown-linux-gnu/release -f ./databend-${{ steps.get_version.outputs.VERSION }}-aarch64-unknown-linux-gnu.tar.gz - HUB= ${{ secrets.DOCKERHUB_NAMESPACE }} TAG=${{ steps.get_version.outputs.VERSION }} make k8s-docker \ No newline at end of file + export TAG=${{ steps.get_version.outputs.VERSION }} + make k8s-docker \ No newline at end of file From d0d41e022ece64000f55e69f8abb970ad8e37147 Mon Sep 17 00:00:00 2001 From: sundyli <543950155@qq.com> Date: Wed, 10 Nov 2021 09:56:52 +0800 Subject: [PATCH 06/17] disable flaky test temporary --- query/src/servers/clickhouse/clickhouse_handler_test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/query/src/servers/clickhouse/clickhouse_handler_test.rs b/query/src/servers/clickhouse/clickhouse_handler_test.rs index c218f3989779..03a3f4976057 100644 --- a/query/src/servers/clickhouse/clickhouse_handler_test.rs +++ b/query/src/servers/clickhouse/clickhouse_handler_test.rs @@ -68,7 +68,7 @@ async fn test_clickhouse_insert_data() -> Result<()> { Ok(()) } -#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +// (todo winter)#[tokio::test(flavor = "multi_thread", worker_threads = 1)] async fn test_clickhouse_insert_to_fuse_table() -> Result<()> { let tmp_dir = TempDir::new()?; let data_path = tmp_dir.path().to_str().unwrap().to_string(); From cffe76690e24ddaf89be600acf858ef64a99e547 Mon Sep 17 00:00:00 2001 From: sundyli <543950155@qq.com> Date: Wed, 10 Nov 2021 10:07:28 +0800 Subject: [PATCH 07/17] Update query/src/servers/clickhouse/clickhouse_handler_test.rs Co-authored-by: Chojan Shang --- query/src/servers/clickhouse/clickhouse_handler_test.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/query/src/servers/clickhouse/clickhouse_handler_test.rs b/query/src/servers/clickhouse/clickhouse_handler_test.rs index 03a3f4976057..4725f5cddb3f 100644 --- a/query/src/servers/clickhouse/clickhouse_handler_test.rs +++ b/query/src/servers/clickhouse/clickhouse_handler_test.rs @@ -68,7 +68,9 @@ async fn test_clickhouse_insert_data() -> Result<()> { Ok(()) } -// (todo winter)#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +// (todo winter) +#[tokio::test(flavor = "multi_thread", worker_threads = 1)] +#[ignore] async fn test_clickhouse_insert_to_fuse_table() -> Result<()> { let tmp_dir = TempDir::new()?; let data_path = tmp_dir.path().to_str().unwrap().to_string(); From cd721e72b85a01105d8af14dba591b947540ea6e Mon Sep 17 00:00:00 2001 From: Li Yazhou Date: Wed, 10 Nov 2021 11:29:21 +0800 Subject: [PATCH 08/17] rename LogFunction to GenericLogFunction, with derived LogFunction and LnFunction --- common/functions/src/scalars/maths/log.rs | 69 +++++++++++++++++----- common/functions/src/scalars/maths/math.rs | 2 + common/functions/src/scalars/maths/mod.rs | 1 + 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/common/functions/src/scalars/maths/log.rs b/common/functions/src/scalars/maths/log.rs index 39e0fc2c4b97..325b023c7693 100644 --- a/common/functions/src/scalars/maths/log.rs +++ b/common/functions/src/scalars/maths/log.rs @@ -27,32 +27,45 @@ use crate::scalars::function_factory::FunctionFeatures; use crate::scalars::Function; #[derive(Clone)] -pub struct LogFunction { - _display_name: String, +pub struct GenericLogFunction { + display_name: String, default_base: f64, + unary: bool, } -impl LogFunction { - pub fn try_create(_display_name: &str) -> Result> { +impl GenericLogFunction { + pub fn try_create( + display_name: &str, + default_base: f64, + unary: bool, + ) -> Result> { Ok(Box::new(Self { - _display_name: _display_name.to_string(), - default_base: E, + display_name: display_name.to_string(), + default_base, + unary, })) } - - pub fn desc() -> FunctionDescription { - FunctionDescription::creator(Box::new(Self::try_create)) - .features(FunctionFeatures::default().deterministic()) - } } -impl Function for LogFunction { +impl Function for GenericLogFunction { fn name(&self) -> &str { - &*self._display_name + &*self.display_name + } + + fn num_arguments(&self) -> usize { + if self.unary { + 1 + } else { + 0 + } } fn variadic_arguments(&self) -> Option<(usize, usize)> { - Some((1, 2)) + if self.unary { + None + } else { + Some((1, 2)) + } } fn return_type(&self, _args: &[DataType]) -> Result { @@ -113,8 +126,34 @@ impl Function for LogFunction { } } -impl fmt::Display for LogFunction { +impl fmt::Display for GenericLogFunction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "LOG") } } + +pub struct LogFunction {} + +impl LogFunction { + pub fn try_create(display_name: &str) -> Result> { + GenericLogFunction::try_create(display_name, E, false) + } + + pub fn desc() -> FunctionDescription { + FunctionDescription::creator(Box::new(Self::try_create)) + .features(FunctionFeatures::default().deterministic()) + } +} + +pub struct LnFunction {} + +impl LnFunction { + pub fn try_create(display_name: &str) -> Result> { + GenericLogFunction::try_create(display_name, E, true) + } + + pub fn desc() -> FunctionDescription { + FunctionDescription::creator(Box::new(Self::try_create)) + .features(FunctionFeatures::default().deterministic()) + } +} diff --git a/common/functions/src/scalars/maths/math.rs b/common/functions/src/scalars/maths/math.rs index 88264882c78d..78628fce4bcc 100644 --- a/common/functions/src/scalars/maths/math.rs +++ b/common/functions/src/scalars/maths/math.rs @@ -16,6 +16,7 @@ use crate::scalars::function_factory::FunctionFactory; use crate::scalars::AbsFunction; use crate::scalars::CRC32Function; use crate::scalars::DegressFunction; +use crate::scalars::LnFunction; use crate::scalars::LogFunction; use crate::scalars::PiFunction; use crate::scalars::RadiansFunction; @@ -38,5 +39,6 @@ impl MathsFunction { factory.register("degrees", DegressFunction::desc()); factory.register("radians", RadiansFunction::desc()); factory.register("log", LogFunction::desc()); + factory.register("ln", LnFunction::desc()); } } diff --git a/common/functions/src/scalars/maths/mod.rs b/common/functions/src/scalars/maths/mod.rs index 141f327d456b..db04da8a0415 100644 --- a/common/functions/src/scalars/maths/mod.rs +++ b/common/functions/src/scalars/maths/mod.rs @@ -24,6 +24,7 @@ pub use abs::AbsFunction; pub use angle::DegressFunction; pub use angle::RadiansFunction; pub use crc32::CRC32Function; +pub use log::LnFunction; pub use log::LogFunction; pub use math::MathsFunction; pub use pi::PiFunction; From 76f1ee51da273e9d9a7b0a313d49d25b0f1068c3 Mon Sep 17 00:00:00 2001 From: Chojan Shang Date: Wed, 10 Nov 2021 11:40:29 +0800 Subject: [PATCH 09/17] [ci] ignore some paths Signed-off-by: Chojan Shang --- .github/workflows/cargo.yml | 10 +++++++++- .github/workflows/databend-build.yml | 10 +++++++++- .github/workflows/databend-docker.yml | 3 +++ .github/workflows/embedded-meta-test.yml | 10 +++++++++- .github/workflows/pr-audit.yml | 4 ++-- .github/workflows/stateless-tests-cluster.yml | 10 +++++++++- .github/workflows/stateless-tests-standalone.yml | 10 +++++++++- .github/workflows/unit-tests.yml | 10 +++++++++- 8 files changed, 59 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cargo.yml b/.github/workflows/cargo.yml index aa2580483ef4..4ff770139b46 100644 --- a/.github/workflows/cargo.yml +++ b/.github/workflows/cargo.yml @@ -1,5 +1,13 @@ name: Cargo -on: [push, pull_request] +on: + push: + paths-ignore: + - 'website/' + - '*.md' + pull_request: + paths-ignore: + - 'website/' + - '*.md' env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/databend-build.yml b/.github/workflows/databend-build.yml index 9a3572f05ee0..9e226a04c573 100644 --- a/.github/workflows/databend-build.yml +++ b/.github/workflows/databend-build.yml @@ -1,5 +1,13 @@ name: Build -on: [push, pull_request] +on: + push: + paths-ignore: + - 'website/' + - '*.md' + pull_request: + paths-ignore: + - 'website/' + - '*.md' env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/databend-docker.yml b/.github/workflows/databend-docker.yml index acf487cb64b7..24cd008f9f31 100644 --- a/.github/workflows/databend-docker.yml +++ b/.github/workflows/databend-docker.yml @@ -2,6 +2,9 @@ name: Push to Dockerhub on: push: branches: main + paths-ignore: + - 'website/' + - '*.md' jobs: build: diff --git a/.github/workflows/embedded-meta-test.yml b/.github/workflows/embedded-meta-test.yml index bed69ec84e4f..df6335156c21 100644 --- a/.github/workflows/embedded-meta-test.yml +++ b/.github/workflows/embedded-meta-test.yml @@ -1,5 +1,13 @@ name: Stateless(Standalone, using embedded meta-store) -on: [push, pull_request] +on: + push: + paths-ignore: + - 'website/' + - '*.md' + pull_request: + paths-ignore: + - 'website/' + - '*.md' env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/pr-audit.yml b/.github/workflows/pr-audit.yml index 91804a418103..5b06aacc5624 100644 --- a/.github/workflows/pr-audit.yml +++ b/.github/workflows/pr-audit.yml @@ -3,10 +3,10 @@ name: Pull Request Security Audit on: push: paths: - - '**/**/Cargo.toml' + - '**/Cargo.lock' pull_request: paths: - - '**/**/Cargo.toml' + - '**/Cargo.lock' jobs: security-audit: diff --git a/.github/workflows/stateless-tests-cluster.yml b/.github/workflows/stateless-tests-cluster.yml index 6fe8906bf4b3..2cb062f67c00 100644 --- a/.github/workflows/stateless-tests-cluster.yml +++ b/.github/workflows/stateless-tests-cluster.yml @@ -1,5 +1,13 @@ name: Stateless(Cluster) -on: [push, pull_request] +on: + push: + paths-ignore: + - 'website/' + - '*.md' + pull_request: + paths-ignore: + - 'website/' + - '*.md' env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/stateless-tests-standalone.yml b/.github/workflows/stateless-tests-standalone.yml index 4978edf3a77e..c453382602dc 100644 --- a/.github/workflows/stateless-tests-standalone.yml +++ b/.github/workflows/stateless-tests-standalone.yml @@ -1,5 +1,13 @@ name: Stateless(Standalone) -on: [push, pull_request] +on: + push: + paths-ignore: + - 'website/' + - '*.md' + pull_request: + paths-ignore: + - 'website/' + - '*.md' env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 0f516d0f0d47..d0996f4efdb5 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -1,5 +1,13 @@ name: Unit Tests -on: [push, pull_request] +on: + push: + paths-ignore: + - 'website/' + - '*.md' + pull_request: + paths-ignore: + - 'website/' + - '*.md' env: CARGO_TERM_COLOR: always From bd54f89b4c968a9eea2c978349d75fde31e419e1 Mon Sep 17 00:00:00 2001 From: BohuTANG Date: Wed, 10 Nov 2021 09:39:42 +0800 Subject: [PATCH 10/17] README: Add logo --- README.md | 2 +- website/databend/docs/assets/favicon.png | Bin 32988 -> 5593 bytes .../databend/docs/images/databend-logo.png | Bin 0 -> 5593 bytes website/databend/src/.icons/logo.svg | 4 +--- .../databend/src/assets/images/favicon.png | Bin 32988 -> 5593 bytes 5 files changed, 2 insertions(+), 4 deletions(-) create mode 100644 website/databend/docs/images/databend-logo.png diff --git a/README.md b/README.md index d7bb2792d411..9c42fdd75c04 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
-

Databend

+

Databend Logo

The Open Source Serverless Data Warehouse for Everyone

diff --git a/website/databend/docs/assets/favicon.png b/website/databend/docs/assets/favicon.png index 5c882f31b4129bc1850061fad4165fdfdd4f350d..ff09aeed8fe7bd54ac4ca6c0958289b7771fe80c 100644 GIT binary patch literal 5593 zcmb_=XEYpM(Eh5?ErRGv5Ryemu=*0cx3Id1UV~Lalofq-qJ@awg_W!pEo#&debv=_ z@4@T$_5bnzz8~h!hda+abLY&t=gbqOt*Jy#!bk!D0LWF8<#q3U?|()_cz;&Hs=nMi z;&;kMo&W$T^?!ylIv4m40H8&x$jj>cX6?eycCdJbG+r%eaPVOj$cf{QlTN%nY&n7Q7Cn09j8CqBNDrophjT?UQ&DL0P<(%C5<{j zsd99LXGhseesOiSZ-Xke?k#*&8ZS2-AAdb}x_+H#>|#hee!3p8us?jAR%%d=3;6n^ ze2xTAf`b590&sEK0Qk7UI7IjWJRlK(5CjB}K|z2=!BD_+!2egkkk~$M(!cB<((IiD zK&vd#PoY54RizFE$pY(-?`uqZ7mOai85orjRvJoUBiEWihjaqy`=Pf(j7E`9D6k;z zBcBOdXA@bgU?{U?zhLfye>g9OF5%IlmBV8C+YU>yidh~RMst)4LCpg?`C)xLED+3{ z00jZ1V)5tu?}>oQatJ7RWxpbph@H?`;v|LYBPSD4=TN;1l9js0{&M6X+FL*w9~haf zgQ1fEDyarTcgSYYSvIs-Wy+`>$5Efj31RtnMWwJzPmP{TEG2JTk_)9WXOz=}&88;B zJRZi;@5hB=0p|(-vV~Es0?ra!l3XLQ%$poK{00ki#yFx;AJaFQwx^^ze>dkz8!iKt zu9S_*us;y{f%n(qlcXC7=~hYHz;9vZ?C}|tb=QZirj;1Y0>g)m)HW)7zSq99b z|7OP$`X7aaCU4;A&E`q3CfznK<$AFcq{!RVsCsr3j?NyCi2|gnSpdPLrOL-oQ^0(8|y+w?`Cr0-itOEwrTnY19PIzCtjet2*6ad$Xqx4$>SekeZ zJyDZ}M|2Jk{;&%BsTGwwEs;sI$}RNa(yJOZ_iOhn#@BEEgH9Ik0JXkH2x)l>eopn} zI>K$xonohV+`729nD8ldqd22HXBi3+CuUUo4U(SL|y3eG&{QNt5Xy}-Ht_xH509)_(;V8%`>Q604zyF61 z%oDYF4-c)W8|%I+fSd)R-xS)H0<_PNUR_cL!3) zJ+{M$iWgCJR$^eQ0S zH|4T8Q=u+T0F1o^{kAAKaf#u(uH(%wy+cI{-=Xy{-Ux7a#?+1&inh^x%;7STN1;>dRfGB_* zH21*7&DK>T(D|3$xP^^$e$vBL z#nZ(N*h`UFa{OrU1?p?-xn_~K-w(8#Fr4M+Twwi$U0`;o9F~14!ICVmp}YCz40W<^ z4M@!uFRLW{Vtn%Tq0GXJHzGJ!PKo0yr4fKyK|%q@sXra~x@@9Fn180y8?Hhu527xk zx_w*jSVj)TOCTzE4MKixR8onMM_rnkfd@p$v+aMBuXc4ENlK=gudv;`)T1FXdPvm8 zq=F_1Y{>f7WU~^jQ+VxVbYlAg%N7O{HF?is4vxG8;BhA0-L9$gCHRdx(`F)mCNHFx zU9*`F{5ze^@w#&<4;0l$D3{PB$W6x%$4F}6lmi*{=P0CqPR~&rmUI1e(_X5d$)Pg5 zHp8odafCt7RSei;Qg|Wk3w;#^YT!tkm5@Z(#%Fc=vBauGN7|zetv~$Ifxfj8C+@q7 zq`xXRa%K5@3fabvmr**Km`ShpUd2Lh&@ygg%NOR^{79kgF-3Y#MN*IbY5qaG(_iTP zumqU3TE)Xe;4MJ`Vb{?@HVebZWB{XR@YK8QrNKRIjA9Hf6?+p5@bdRs$LG0^Z=^em z!e?>+*b?qZVaUC9i12Z-L;C48LiavS{W=^MA6IV4)F5)cY9M2{;XoDB*=*PJ7+r~D zseUZf4|^>#w=zVWxIHk|A^@NGdz5mMOklou+%ZxEl(;^X{IldP_2Rv+KCQ$9xt-R^ z=zwL@DLW#r-On*$U?@nNPe9?1e{Ms_{wE6b%Os@KNqp^FCG<0|_Jo9u1&X`|%~u_4 z^E(vqKt2HnbKNyF3EKKj)ch(>Up>>gx}!dX+}3w#nfe zgwtC6YBved1k1@3DRGwF$-ipWXkuBSyzu@s}arhEP2Uu>dz z-?Ivg!twGZdytpD7_!;o@C*_;kol`RwB}v9f%3zb?(O50C@dwRc;{jvxN|8R(RF%r zXsd-C4}pUCI1s6M1FVsYZpHP%;>>XeKHBpnMu|n;NMCcdmHAq;dLwpOGm-hqu7@>r zUEHM5K-IUe#1?3`u~)Z5J}ilBt;f(H5s{SRT}NS#gk*+!ghXq=4?~Hy9(n=$_)mHD zy*cUZmA|Ni3_=`z-i6E+s^s(|7g(A4F1JEPBcaZWw0{yR>yz@U+tUA;RubGz~U@O3LpL33X@gFp=V z>dd_F&-#}Ap8O0pras}9X4s9%$ z*+uC?eRsd*PnhX~g^}q(j)+O!tJ5l%w~~og)AxBO1GZT30=PcnoW|l{~J`ZD8DEi?AUp= zXmu1O7xML*`Bul^-;$QN;{yCHC6lE-B_GlOky%-787h#<9k2*Z=rAAWk2F=It@A51>x&k%iQ)A!d(V|@-0n4;M=vFz~ime?N^w_*dXDn zz}4gn6Mlpg|!$g41&-NP`K2tw*;W<&LbT{#k279R~O zBERP&^uu+}ELwbzk3R2q?DR&=t>3OV-bU;<|8=geZ)V80SA#vLoMu%YSd$`{tfJy-+Zc%#tZ~E@&$eL7#`IXd~lP` z9qb5wfN*A%%wDa@%^J~gRt4n+B63egj-IAI2SW#VJk=rP6MM5*=gc~hlRfrIOZR}F z4p6Yh5Q7>L&5*v{+b}{&sHayhn_9a=G2yrObGO7bXAamR#Y<7Os z&tRz63ew*YlUZahd?D^$K&F?_%-PS=r0a=(Y)aHAwxr(1BTxMl7|yCEvK!+I0o_H0 zp>`CWYxIDg?ws>OF8$l+KWEj(n-cOq1y}8-F;mm*i(C)jlDkdsvz(4Zkxk_??oCW- z$AJ~8u+Q_H26HH}83c~9`XzNwCO?SV;7Qq_+iG{2J*h;Q8LQmzN75NGp`E4uuRC`R zswzDAh(!CIq=q|Le9VW3J_Qo{kbMpl7VF?PL2^_mJg-((yvQKb9r-Q~!j6$?9zLm* z<9%i(B4?IOi~p)0pF<~9$iaS5g&L?3sxc zEBlIswjbc`;!_bLN)AHbB+q`K9w+Rvu`w_CRC4Z1a2u6%4@UK7oGQ+M(oy#X)7GnR za*X1Rw3kXwfAW{l_&e@q>zvUl3eJ&-KX@=mC4s1KHxl}*&XmZ8kDvDni;oLUDDVff z0{H)T``>>XB&TKjn)RqfNpInG~n6)A0I z-+GiwkI{-%5|>!d*aY0rxF_DC_Cqm?m-}doffUl95tfYR^Ct97?a~Sb=8&?RpU^*5 zGxh%-b}MJ|y;a*`niOY*gF>*^i!PcTL7*CxE7Y&IB_PYWSzspEYiIJ;tnoF%@gB1* zNxm71x>O0u059E=pY>n}Wl)vmF)DjsMHX}5nU1|sw@J?VU9sl}=b41KHW-Q#pU3EV$Tz#T zu!^OjPEAi@qPewXj|VE&A@6O`GLBS<@v;|%s9gb>8-iZIfFev$P?P4oOAl8 zb-fBdvX}Jjw;EQ2-f^|qd0i3<2uY0H({zeHIBl_?G;zvbMY$Hj$uCovEkGEX_0UC9y|pf-(+7_ z-pUnLmUH!#mPZ*s*Tnx7rpI?O6QWKKZenp$wdAS_E+KHyi**7|Ru`13NNJzF8xnHs z+n$x_7anrxWFHnS9q@I#k$84wE(%`fIeahjY0%(YOG@CBt~y&O%K*mbAUsJm*#dKP z$)gK@oecrwqa>>dP6>w6Lu~k0j?pZ(MUq*1&HFD1qMhKIXDMbR&DAjbs%(E|H^pW5EqT{{L|ocB>E9%*}G;S_9s>Py*qW} zmI#Eny(XY@-8~k2`m@Mb%=sv~P>1)~Hot3ip~{ViXAO|ZPG}7LX{)j__;CYP zwSeGP%aOn*jYhJ85U#GxN1V03Kk0_du#eyD}>ixh(S1A~M z@l3g9+`K(g?-!t-;EKluo9K2h47y#v7mUm12{3*9W*ePnp0?M>*HbneA1dKEy|8hr z?7U8bEa?G#HbpiNmd<)yw{bxW1L~R^jZA4wm`)3-74@CECq=Cs!X|2V9xrCqb&83v zX<+RS7zsoNHo-cU2d6Q9%JBlnO)g@U@R}mV4IwDOa3y5|ISSvosOPf1-}w{svblAd zdh8SU?G-VnBw91M?=lr07V*s|#i`p}4ec1VuhJM$S6?koY_Vsd-MFk}yr;%HNc+-tP}6$MTCDmlxL{{i&|ce(%o literal 32988 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 diff --git a/website/databend/docs/images/databend-logo.png b/website/databend/docs/images/databend-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ff09aeed8fe7bd54ac4ca6c0958289b7771fe80c GIT binary patch literal 5593 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 literal 0 HcmV?d00001 diff --git a/website/databend/src/.icons/logo.svg b/website/databend/src/.icons/logo.svg index 5e1af8706d1f..cfb90237b4ee 100644 --- a/website/databend/src/.icons/logo.svg +++ b/website/databend/src/.icons/logo.svg @@ -1,3 +1 @@ - - -


datafuse
datafuse
THE  MODERN  DATA  CLOUD
THE  MODERN  DATA  CLOUD
Viewer does not support full SVG 1.1
\ No newline at end of file +画板 2 \ No newline at end of file diff --git a/website/databend/src/assets/images/favicon.png b/website/databend/src/assets/images/favicon.png index 5c882f31b4129bc1850061fad4165fdfdd4f350d..ff09aeed8fe7bd54ac4ca6c0958289b7771fe80c 100644 GIT binary patch literal 5593 zcmb_=XEYpM(Eh5?ErRGv5Ryemu=*0cx3Id1UV~Lalofq-qJ@awg_W!pEo#&debv=_ z@4@T$_5bnzz8~h!hda+abLY&t=gbqOt*Jy#!bk!D0LWF8<#q3U?|()_cz;&Hs=nMi z;&;kMo&W$T^?!ylIv4m40H8&x$jj>cX6?eycCdJbG+r%eaPVOj$cf{QlTN%nY&n7Q7Cn09j8CqBNDrophjT?UQ&DL0P<(%C5<{j zsd99LXGhseesOiSZ-Xke?k#*&8ZS2-AAdb}x_+H#>|#hee!3p8us?jAR%%d=3;6n^ ze2xTAf`b590&sEK0Qk7UI7IjWJRlK(5CjB}K|z2=!BD_+!2egkkk~$M(!cB<((IiD zK&vd#PoY54RizFE$pY(-?`uqZ7mOai85orjRvJoUBiEWihjaqy`=Pf(j7E`9D6k;z zBcBOdXA@bgU?{U?zhLfye>g9OF5%IlmBV8C+YU>yidh~RMst)4LCpg?`C)xLED+3{ z00jZ1V)5tu?}>oQatJ7RWxpbph@H?`;v|LYBPSD4=TN;1l9js0{&M6X+FL*w9~haf zgQ1fEDyarTcgSYYSvIs-Wy+`>$5Efj31RtnMWwJzPmP{TEG2JTk_)9WXOz=}&88;B zJRZi;@5hB=0p|(-vV~Es0?ra!l3XLQ%$poK{00ki#yFx;AJaFQwx^^ze>dkz8!iKt zu9S_*us;y{f%n(qlcXC7=~hYHz;9vZ?C}|tb=QZirj;1Y0>g)m)HW)7zSq99b z|7OP$`X7aaCU4;A&E`q3CfznK<$AFcq{!RVsCsr3j?NyCi2|gnSpdPLrOL-oQ^0(8|y+w?`Cr0-itOEwrTnY19PIzCtjet2*6ad$Xqx4$>SekeZ zJyDZ}M|2Jk{;&%BsTGwwEs;sI$}RNa(yJOZ_iOhn#@BEEgH9Ik0JXkH2x)l>eopn} zI>K$xonohV+`729nD8ldqd22HXBi3+CuUUo4U(SL|y3eG&{QNt5Xy}-Ht_xH509)_(;V8%`>Q604zyF61 z%oDYF4-c)W8|%I+fSd)R-xS)H0<_PNUR_cL!3) zJ+{M$iWgCJR$^eQ0S zH|4T8Q=u+T0F1o^{kAAKaf#u(uH(%wy+cI{-=Xy{-Ux7a#?+1&inh^x%;7STN1;>dRfGB_* zH21*7&DK>T(D|3$xP^^$e$vBL z#nZ(N*h`UFa{OrU1?p?-xn_~K-w(8#Fr4M+Twwi$U0`;o9F~14!ICVmp}YCz40W<^ z4M@!uFRLW{Vtn%Tq0GXJHzGJ!PKo0yr4fKyK|%q@sXra~x@@9Fn180y8?Hhu527xk zx_w*jSVj)TOCTzE4MKixR8onMM_rnkfd@p$v+aMBuXc4ENlK=gudv;`)T1FXdPvm8 zq=F_1Y{>f7WU~^jQ+VxVbYlAg%N7O{HF?is4vxG8;BhA0-L9$gCHRdx(`F)mCNHFx zU9*`F{5ze^@w#&<4;0l$D3{PB$W6x%$4F}6lmi*{=P0CqPR~&rmUI1e(_X5d$)Pg5 zHp8odafCt7RSei;Qg|Wk3w;#^YT!tkm5@Z(#%Fc=vBauGN7|zetv~$Ifxfj8C+@q7 zq`xXRa%K5@3fabvmr**Km`ShpUd2Lh&@ygg%NOR^{79kgF-3Y#MN*IbY5qaG(_iTP zumqU3TE)Xe;4MJ`Vb{?@HVebZWB{XR@YK8QrNKRIjA9Hf6?+p5@bdRs$LG0^Z=^em z!e?>+*b?qZVaUC9i12Z-L;C48LiavS{W=^MA6IV4)F5)cY9M2{;XoDB*=*PJ7+r~D zseUZf4|^>#w=zVWxIHk|A^@NGdz5mMOklou+%ZxEl(;^X{IldP_2Rv+KCQ$9xt-R^ z=zwL@DLW#r-On*$U?@nNPe9?1e{Ms_{wE6b%Os@KNqp^FCG<0|_Jo9u1&X`|%~u_4 z^E(vqKt2HnbKNyF3EKKj)ch(>Up>>gx}!dX+}3w#nfe zgwtC6YBved1k1@3DRGwF$-ipWXkuBSyzu@s}arhEP2Uu>dz z-?Ivg!twGZdytpD7_!;o@C*_;kol`RwB}v9f%3zb?(O50C@dwRc;{jvxN|8R(RF%r zXsd-C4}pUCI1s6M1FVsYZpHP%;>>XeKHBpnMu|n;NMCcdmHAq;dLwpOGm-hqu7@>r zUEHM5K-IUe#1?3`u~)Z5J}ilBt;f(H5s{SRT}NS#gk*+!ghXq=4?~Hy9(n=$_)mHD zy*cUZmA|Ni3_=`z-i6E+s^s(|7g(A4F1JEPBcaZWw0{yR>yz@U+tUA;RubGz~U@O3LpL33X@gFp=V z>dd_F&-#}Ap8O0pras}9X4s9%$ z*+uC?eRsd*PnhX~g^}q(j)+O!tJ5l%w~~og)AxBO1GZT30=PcnoW|l{~J`ZD8DEi?AUp= zXmu1O7xML*`Bul^-;$QN;{yCHC6lE-B_GlOky%-787h#<9k2*Z=rAAWk2F=It@A51>x&k%iQ)A!d(V|@-0n4;M=vFz~ime?N^w_*dXDn zz}4gn6Mlpg|!$g41&-NP`K2tw*;W<&LbT{#k279R~O zBERP&^uu+}ELwbzk3R2q?DR&=t>3OV-bU;<|8=geZ)V80SA#vLoMu%YSd$`{tfJy-+Zc%#tZ~E@&$eL7#`IXd~lP` z9qb5wfN*A%%wDa@%^J~gRt4n+B63egj-IAI2SW#VJk=rP6MM5*=gc~hlRfrIOZR}F z4p6Yh5Q7>L&5*v{+b}{&sHayhn_9a=G2yrObGO7bXAamR#Y<7Os z&tRz63ew*YlUZahd?D^$K&F?_%-PS=r0a=(Y)aHAwxr(1BTxMl7|yCEvK!+I0o_H0 zp>`CWYxIDg?ws>OF8$l+KWEj(n-cOq1y}8-F;mm*i(C)jlDkdsvz(4Zkxk_??oCW- z$AJ~8u+Q_H26HH}83c~9`XzNwCO?SV;7Qq_+iG{2J*h;Q8LQmzN75NGp`E4uuRC`R zswzDAh(!CIq=q|Le9VW3J_Qo{kbMpl7VF?PL2^_mJg-((yvQKb9r-Q~!j6$?9zLm* z<9%i(B4?IOi~p)0pF<~9$iaS5g&L?3sxc zEBlIswjbc`;!_bLN)AHbB+q`K9w+Rvu`w_CRC4Z1a2u6%4@UK7oGQ+M(oy#X)7GnR za*X1Rw3kXwfAW{l_&e@q>zvUl3eJ&-KX@=mC4s1KHxl}*&XmZ8kDvDni;oLUDDVff z0{H)T``>>XB&TKjn)RqfNpInG~n6)A0I z-+GiwkI{-%5|>!d*aY0rxF_DC_Cqm?m-}doffUl95tfYR^Ct97?a~Sb=8&?RpU^*5 zGxh%-b}MJ|y;a*`niOY*gF>*^i!PcTL7*CxE7Y&IB_PYWSzspEYiIJ;tnoF%@gB1* zNxm71x>O0u059E=pY>n}Wl)vmF)DjsMHX}5nU1|sw@J?VU9sl}=b41KHW-Q#pU3EV$Tz#T zu!^OjPEAi@qPewXj|VE&A@6O`GLBS<@v;|%s9gb>8-iZIfFev$P?P4oOAl8 zb-fBdvX}Jjw;EQ2-f^|qd0i3<2uY0H({zeHIBl_?G;zvbMY$Hj$uCovEkGEX_0UC9y|pf-(+7_ z-pUnLmUH!#mPZ*s*Tnx7rpI?O6QWKKZenp$wdAS_E+KHyi**7|Ru`13NNJzF8xnHs z+n$x_7anrxWFHnS9q@I#k$84wE(%`fIeahjY0%(YOG@CBt~y&O%K*mbAUsJm*#dKP z$)gK@oecrwqa>>dP6>w6Lu~k0j?pZ(MUq*1&HFD1qMhKIXDMbR&DAjbs%(E|H^pW5EqT{{L|ocB>E9%*}G;S_9s>Py*qW} zmI#Eny(XY@-8~k2`m@Mb%=sv~P>1)~Hot3ip~{ViXAO|ZPG}7LX{)j__;CYP zwSeGP%aOn*jYhJ85U#GxN1V03Kk0_du#eyD}>ixh(S1A~M z@l3g9+`K(g?-!t-;EKluo9K2h47y#v7mUm12{3*9W*ePnp0?M>*HbneA1dKEy|8hr z?7U8bEa?G#HbpiNmd<)yw{bxW1L~R^jZA4wm`)3-74@CECq=Cs!X|2V9xrCqb&83v zX<+RS7zsoNHo-cU2d6Q9%JBlnO)g@U@R}mV4IwDOa3y5|ISSvosOPf1-}w{svblAd zdh8SU?G-VnBw91M?=lr07V*s|#i`p}4ec1VuhJM$S6?koY_Vsd-MFk}yr;%HNc+-tP}6$MTCDmlxL{{i&|ce(%o literal 32988 zcmeHPYjjlA6~1=SiVF}>D6g42cS2C=4?$C9Sp^b8CiA#+U-QTekPt$kZ7e>hMQqVT zyR450B=g7v3oAN}ESt@cN|S{Dle(^?4C%-qQfl6boJ4HqXjGf9R? zh>2&``sSY3-uvu*9{0TNVVGN(X-s}T15b`w4o@4yFdTQyKZju+gRq4Qula9dm7Pz;xcE;+;ntKZ>o?Y?CFj%wo+4~$@ely=F z>ye+nG`HZ#FRU1j9^)_#rZv*92A;@!IN3UH+f%hOjP%+1S8si>&?S3&+@jRO3+W+x zf>#{g@?RR|6>Q$UUGN2a+=7^v9^*tvv#xyiPmJ_-Px)@-J)CUJn@jfftgU>$$Vi{9 zfAzK(iv`(3BvBxukRD!N32}PMYK-#MmF@bO>24ceGYjK zCmZu7$X>Fhvc_qo&(^=D;@37_QiuR~bi30-@%jno)hMr^Y*&@&Eg^!NPfL$+5~M*} z8R_jx=^o@goNUY+FL_A*)*8E!K3hN4pO!zZ|Fr$n{x5yskA3r0?f>)3_t+&@5mD@G ziCml>e!)(7L8&&rZzlWuZ{;)ZKAiW&k=_S)9wQGt@kVMqd4xQ)`yG%{_Z8O6SBBD4Gs`uI!ef*X7a>T)1QlWtTct=J(h-U!iLq|Jjy*Vd>6CWmzPWqmYP>qLjcm52RUN_VXQst;aAEJ^s&D|A(sTwiZ@alXaV) zCIw}wfpM7TM^$y(rkeiduqs&^x(FNXguWx58W4y5iz%YYQ&E4mv4@x&0FjQ=fH=1C z%9Pdr>+(G5^{6Ct80~wC8d55R9)Ipnr_^q=dPtk1URKUa>TG-j}VuM*4}?pAC0Bj$>;U z#@Ok`-`KyH!m%rsNbG)N{YOR8o=t;K zEzzETnUb0dvV76nzoq>YRQarnD@%%S$WOmyHieoqe2<_Cwu+RP~9QP zss739|Eb^KxHph){ePn8ze5T%!vI?TwEVMK|EKkTV%L8%Z0tKF$K?-sm*{LJA*mE~Z6f(@w&wmzO34V?+t8~TEawy&J%{EoH!+|U=dTMl+xxyEjeYiv&m zOE_k=M!GHcoFLyDYx$Jl)U*Ijv^YRMV6xp4U@s{Ti2jWsr|7Lmi2h*6DF+?}RkWYY zSFu$KONuWp*;1*;+m&F|;P{OpyMGJZo-n$fT@JpzArK%Qk4HlwP(oa8`D2|L;!k5( za=b&?^hZ73DJUN$$0IM75`0IGAL;3kgDrR_R{thgQDpq~>JK^{==Uy$CC58Fo8Hso zoucPday;^KDuKg#{7BDHO}+bBST8a)T-CtB_+U}=$_F<~K3kuts)dGVA-a$i5s?v(^M+g&p1_BWFLrjUA+Yr*olW*>Bi z;&1Bm?b60m(0>w_?AIXqHxY+_^C3Ncq-VDBt@~O}E^BBfIeS|*ENhIBrF&b$Bgxg{ zvz2cOcb;TnE!G_E)`0D2aik}t^B?J%z5Mo*gUV;1Em8R+8U9-QMBCpIjz_J~zV-7k zc=p8{j$iNpM{0kjaCYSnbD|g6gT0qbq4v)a?1A1(Y*fA8zl^v1+z`1H=OuT;nGXcI zP5WBmMyi3|c+1!2q*L3Ddu3bybUx{xFjqfeeG}Tp zfqo6>X6s|W)6ZgWu( z2kq||riDwMe>_~#GV2l7hPk{b{|m#A#w95q=T}8%reV*l+8DZ>7vwKJFo#xTiNO7A z#NqJGU$rB2yGxL+Vi*E=_O2}7KPTTEoactS(J%~YV0<6T+y3(Gbo?<-JkNhF3vln3 z+eO?w-|Yq-5ASN3i5Q6w<`y@+`kj=xj%e=fjx zp>D}bT%u=8`ExbrrgOFDF67o-BDwqiLvm`*C)ne$xemuFu$vf{cqc))c=3kvkK+qd zwEMgn?iDdN^}{!hU5VKziN@a{2jXr8?n48>Jp0D^*T>IWntHW!cksSUm|lsjeK?gjqz7iJR^x^2IJpv0RPy3aSq2F z{0hfbSC>T8J2k!1+Gq6n$8~&|uYYW6yn4wL?gFT1xx?*qxEeCuGzR>!9Og&cX5zSA zAICF<+>+BwW{(wry{wa;p))YI!ub{AjP@S1)^#ixEB?v)=_Csh98cT z<^VXrXvRrGuyTRm+vHLJf)HHb4sM@^euTrfWxh=={k|3ley6V-hhT$#4rL=;iy9y$ zxOX6U6}TtX=?6E$<}Kr$Zdt@QKcs=QC4-2;!;7Mf>*ghbjkt@~iwl2|_I$wKUvrw|y>OZ=d+|e;w`i5kClnKeQW{Cb$V)s^#NN)-y)@t<=`gEK(E`6=lk=vw_+^9-&>Mrs| z{f+XC^srCwut0ub9twBcbPl11_RQnHKCUCdeA#V|B-SL$hczY#>V`UETBCeuPwOoQ z`Yu~q`Yy9|v7#mQiGob%;k%w`In7_r#y%O{mU>mrh~AJPE));uyanf2-v*tc9X75$ zZXYiH266`02lBX<{zDp?)#Y5cUCM-hD8G0q^fCH-V2J&U>5YCa)Lx$RThIr}2hT7Y z<45va_FrCPZRxdHn|o~wLy7q#rKj=K0@MQ30@MQ30@MQ30@MQ30@MQ30@MQ30@MQ3 t0@MQ30@MQ30@MQ30@MQ30@MQ30@MQ30@MQ30@MQ30@MQ30^eK<{2%!;$BO^} From 932944936e2041ba57256d255d661acd121f6d9c Mon Sep 17 00:00:00 2001 From: Li Yazhou Date: Wed, 10 Nov 2021 11:55:52 +0800 Subject: [PATCH 11/17] add tests for ln --- common/functions/src/scalars/maths/log.rs | 2 +- .../functions/tests/it/scalars/maths/log.rs | 24 +++++++++++++++++++ .../0_stateless/02_0014_function_maths.result | 1 + .../0_stateless/02_0014_function_maths.sql | 2 ++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/common/functions/src/scalars/maths/log.rs b/common/functions/src/scalars/maths/log.rs index 325b023c7693..3d4913454722 100644 --- a/common/functions/src/scalars/maths/log.rs +++ b/common/functions/src/scalars/maths/log.rs @@ -128,7 +128,7 @@ impl Function for GenericLogFunction { impl fmt::Display for GenericLogFunction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "LOG") + write!(f, "{}", self.display_name.to_uppercase()) } } diff --git a/common/functions/tests/it/scalars/maths/log.rs b/common/functions/tests/it/scalars/maths/log.rs index c7cf46cf1858..f80575024519 100644 --- a/common/functions/tests/it/scalars/maths/log.rs +++ b/common/functions/tests/it/scalars/maths/log.rs @@ -96,6 +96,30 @@ fn test_log_function() -> Result<()> { expect: Series::new([None, None, Some(1_f64)]).into(), error: "", }, + Test { + name: "ln on series", + display: "LN", + args: vec![DataColumnWithField::new( + Series::new([Some(E), None]).into(), + DataField::new("num", DataType::Int32, false), + )], + input_rows: 1, + func: LnFunction::try_create("ln")?, + expect: Series::new([Some(1_f64), None]).into(), + error: "", + }, + Test { + name: "ln on literal", + display: "LN", + args: vec![DataColumnWithField::new( + Series::new([E]).into(), + DataField::new("num", DataType::Int32, false), + )], + input_rows: 1, + func: LnFunction::try_create("ln")?, + expect: DataColumn::Constant(1_f64.into(), 1), + error: "", + }, ]; for t in tests { let func = t.func; diff --git a/tests/suites/0_stateless/02_0014_function_maths.result b/tests/suites/0_stateless/02_0014_function_maths.result index 98a08cfc867f..56b03b0aa017 100644 --- a/tests/suites/0_stateless/02_0014_function_maths.result +++ b/tests/suites/0_stateless/02_0014_function_maths.result @@ -12,3 +12,4 @@ NULL NULL NULL 2 +NULL \ No newline at end of file diff --git a/tests/suites/0_stateless/02_0014_function_maths.sql b/tests/suites/0_stateless/02_0014_function_maths.sql index d0ed77bbb83c..e28bd3511a5c 100644 --- a/tests/suites/0_stateless/02_0014_function_maths.sql +++ b/tests/suites/0_stateless/02_0014_function_maths.sql @@ -16,5 +16,7 @@ SELECT log(NULL, NULL); -- {ErrorCode 10} SELECT log(1, NULL); SELECT log(NULL, 1); -- {ErrorCode 10} SELECT log('10', 100); +SELECT ln(NULL); +SELECT ln(1, 2); -- {ErrorCode 28} DROP TABLE math_sample_numbers; From b19352fc9876872d66aacdea4e7917ca85a5a6ea Mon Sep 17 00:00:00 2001 From: Li Yazhou Date: Wed, 10 Nov 2021 12:01:58 +0800 Subject: [PATCH 12/17] add log10(), log2() with tests --- common/functions/src/scalars/maths/log.rs | 26 +++++++++++++++++ common/functions/src/scalars/maths/math.rs | 4 +++ common/functions/src/scalars/maths/mod.rs | 2 ++ .../functions/tests/it/scalars/maths/log.rs | 28 +++++++++++++++++-- .../0_stateless/02_0014_function_maths.result | 5 +++- .../0_stateless/02_0014_function_maths.sql | 3 ++ 6 files changed, 65 insertions(+), 3 deletions(-) diff --git a/common/functions/src/scalars/maths/log.rs b/common/functions/src/scalars/maths/log.rs index 3d4913454722..8bb13c8abd08 100644 --- a/common/functions/src/scalars/maths/log.rs +++ b/common/functions/src/scalars/maths/log.rs @@ -157,3 +157,29 @@ impl LnFunction { .features(FunctionFeatures::default().deterministic()) } } + +pub struct Log10Function {} + +impl Log10Function { + pub fn try_create(display_name: &str) -> Result> { + GenericLogFunction::try_create(display_name, 10_f64, true) + } + + pub fn desc() -> FunctionDescription { + FunctionDescription::creator(Box::new(Self::try_create)) + .features(FunctionFeatures::default().deterministic()) + } +} + +pub struct Log2Function {} + +impl Log2Function { + pub fn try_create(display_name: &str) -> Result> { + GenericLogFunction::try_create(display_name, 2_f64, true) + } + + pub fn desc() -> FunctionDescription { + FunctionDescription::creator(Box::new(Self::try_create)) + .features(FunctionFeatures::default().deterministic()) + } +} diff --git a/common/functions/src/scalars/maths/math.rs b/common/functions/src/scalars/maths/math.rs index 78628fce4bcc..0933a93a99ea 100644 --- a/common/functions/src/scalars/maths/math.rs +++ b/common/functions/src/scalars/maths/math.rs @@ -17,6 +17,8 @@ use crate::scalars::AbsFunction; use crate::scalars::CRC32Function; use crate::scalars::DegressFunction; use crate::scalars::LnFunction; +use crate::scalars::Log10Function; +use crate::scalars::Log2Function; use crate::scalars::LogFunction; use crate::scalars::PiFunction; use crate::scalars::RadiansFunction; @@ -39,6 +41,8 @@ impl MathsFunction { factory.register("degrees", DegressFunction::desc()); factory.register("radians", RadiansFunction::desc()); factory.register("log", LogFunction::desc()); + factory.register("log10", Log10Function::desc()); + factory.register("log2", Log2Function::desc()); factory.register("ln", LnFunction::desc()); } } diff --git a/common/functions/src/scalars/maths/mod.rs b/common/functions/src/scalars/maths/mod.rs index db04da8a0415..beaf82839249 100644 --- a/common/functions/src/scalars/maths/mod.rs +++ b/common/functions/src/scalars/maths/mod.rs @@ -25,6 +25,8 @@ pub use angle::DegressFunction; pub use angle::RadiansFunction; pub use crc32::CRC32Function; pub use log::LnFunction; +pub use log::Log10Function; +pub use log::Log2Function; pub use log::LogFunction; pub use math::MathsFunction; pub use pi::PiFunction; diff --git a/common/functions/tests/it/scalars/maths/log.rs b/common/functions/tests/it/scalars/maths/log.rs index f80575024519..2b90ebca5337 100644 --- a/common/functions/tests/it/scalars/maths/log.rs +++ b/common/functions/tests/it/scalars/maths/log.rs @@ -101,7 +101,7 @@ fn test_log_function() -> Result<()> { display: "LN", args: vec![DataColumnWithField::new( Series::new([Some(E), None]).into(), - DataField::new("num", DataType::Int32, false), + DataField::new("num", DataType::Float64, false), )], input_rows: 1, func: LnFunction::try_create("ln")?, @@ -113,13 +113,37 @@ fn test_log_function() -> Result<()> { display: "LN", args: vec![DataColumnWithField::new( Series::new([E]).into(), - DataField::new("num", DataType::Int32, false), + DataField::new("num", DataType::Float64, false), )], input_rows: 1, func: LnFunction::try_create("ln")?, expect: DataColumn::Constant(1_f64.into(), 1), error: "", }, + Test { + name: "log2 on literal", + display: "LOG2", + args: vec![DataColumnWithField::new( + Series::new([2_f64]).into(), + DataField::new("num", DataType::Float64, false), + )], + input_rows: 1, + func: Log2Function::try_create("log2")?, + expect: DataColumn::Constant(1_f64.into(), 1), + error: "", + }, + Test { + name: "log10 on literal", + display: "LOG10", + args: vec![DataColumnWithField::new( + Series::new([10_f64]).into(), + DataField::new("num", DataType::Float64, false), + )], + input_rows: 1, + func: Log10Function::try_create("log10")?, + expect: DataColumn::Constant(1_f64.into(), 1), + error: "", + }, ]; for t in tests { let func = t.func; diff --git a/tests/suites/0_stateless/02_0014_function_maths.result b/tests/suites/0_stateless/02_0014_function_maths.result index 56b03b0aa017..4c4c47cdbb3b 100644 --- a/tests/suites/0_stateless/02_0014_function_maths.result +++ b/tests/suites/0_stateless/02_0014_function_maths.result @@ -12,4 +12,7 @@ NULL NULL NULL 2 -NULL \ No newline at end of file +NULL +NULL +2 +1 diff --git a/tests/suites/0_stateless/02_0014_function_maths.sql b/tests/suites/0_stateless/02_0014_function_maths.sql index e28bd3511a5c..77f031db3686 100644 --- a/tests/suites/0_stateless/02_0014_function_maths.sql +++ b/tests/suites/0_stateless/02_0014_function_maths.sql @@ -18,5 +18,8 @@ SELECT log(NULL, 1); -- {ErrorCode 10} SELECT log('10', 100); SELECT ln(NULL); SELECT ln(1, 2); -- {ErrorCode 28} +SELECT log10(NULL); +SELECT log10(100); +SELECT log2(2); DROP TABLE math_sample_numbers; From 2530cbf951bcdfc5837e708634ef4e3fbe668430 Mon Sep 17 00:00:00 2001 From: BohuTANG Date: Wed, 10 Nov 2021 12:05:30 +0800 Subject: [PATCH 13/17] Update logo.svg --- website/databend/src/.icons/logo.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/databend/src/.icons/logo.svg b/website/databend/src/.icons/logo.svg index cfb90237b4ee..c70768b5f6f9 100644 --- a/website/databend/src/.icons/logo.svg +++ b/website/databend/src/.icons/logo.svg @@ -1 +1 @@ -画板 2 \ No newline at end of file +Databend Logo From 2691a2da7912a1bea6173c12e19f9e4336054a49 Mon Sep 17 00:00:00 2001 From: drdr xp Date: Tue, 9 Nov 2021 20:46:49 +0800 Subject: [PATCH 14/17] [metasrv] refactor: remove kv handler. ActionHandler calls directly --- metasrv/src/executor/action_handler.rs | 11 ++++-- metasrv/src/executor/kv_handlers.rs | 55 -------------------------- metasrv/src/executor/mod.rs | 1 - 3 files changed, 7 insertions(+), 60 deletions(-) delete mode 100644 metasrv/src/executor/kv_handlers.rs diff --git a/metasrv/src/executor/action_handler.rs b/metasrv/src/executor/action_handler.rs index 20d4f2b69641..c718ee3f9cbd 100644 --- a/metasrv/src/executor/action_handler.rs +++ b/metasrv/src/executor/action_handler.rs @@ -15,6 +15,7 @@ use std::sync::Arc; use common_exception::ErrorCode; +use common_meta_api::KVApi; use common_meta_flight::MetaFlightAction; use common_meta_flight::RequestFor; use serde::Serialize; @@ -55,10 +56,12 @@ impl ActionHandler { // To keep the code IDE-friendly, we manually expand the enum variants and dispatch them one by one match action { - MetaFlightAction::UpsertKV(a) => s.serialize(self.handle(a).await?), - MetaFlightAction::GetKV(a) => s.serialize(self.handle(a).await?), - MetaFlightAction::MGetKV(a) => s.serialize(self.handle(a).await?), - MetaFlightAction::PrefixListKV(a) => s.serialize(self.handle(a).await?), + MetaFlightAction::UpsertKV(a) => s.serialize(self.meta_node.upsert_kv(a).await?), + MetaFlightAction::GetKV(a) => s.serialize(self.meta_node.get_kv(&a.key).await?), + MetaFlightAction::MGetKV(a) => s.serialize(self.meta_node.mget_kv(&a.keys).await?), + MetaFlightAction::PrefixListKV(a) => { + s.serialize(self.meta_node.prefix_list_kv(&a.0).await?) + } // database MetaFlightAction::CreateDatabase(a) => s.serialize(self.handle(a).await?), diff --git a/metasrv/src/executor/kv_handlers.rs b/metasrv/src/executor/kv_handlers.rs deleted file mode 100644 index 47114a66286d..000000000000 --- a/metasrv/src/executor/kv_handlers.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2020 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 common_meta_api::KVApi; -use common_meta_flight::GetKVAction; -use common_meta_flight::MGetKVAction; -use common_meta_flight::PrefixListReq; -use common_meta_types::GetKVActionReply; -use common_meta_types::MGetKVActionReply; -use common_meta_types::PrefixListReply; -use common_meta_types::UpsertKVAction; -use common_meta_types::UpsertKVActionReply; - -use crate::executor::action_handler::RequestHandler; -use crate::executor::ActionHandler; - -#[async_trait::async_trait] -impl RequestHandler for ActionHandler { - async fn handle(&self, act: UpsertKVAction) -> common_exception::Result { - self.meta_node.upsert_kv(act).await - } -} - -#[async_trait::async_trait] -impl RequestHandler for ActionHandler { - async fn handle(&self, act: GetKVAction) -> common_exception::Result { - self.meta_node.get_kv(&act.key).await - } -} - -#[async_trait::async_trait] -impl RequestHandler for ActionHandler { - async fn handle(&self, act: MGetKVAction) -> common_exception::Result { - self.meta_node.mget_kv(&act.keys).await - } -} - -#[async_trait::async_trait] -impl RequestHandler for ActionHandler { - async fn handle(&self, act: PrefixListReq) -> common_exception::Result { - self.meta_node.prefix_list_kv(&(act.0)).await - } -} diff --git a/metasrv/src/executor/mod.rs b/metasrv/src/executor/mod.rs index 218dacd73a79..7a624182cbda 100644 --- a/metasrv/src/executor/mod.rs +++ b/metasrv/src/executor/mod.rs @@ -13,7 +13,6 @@ // limitations under the License. mod action_handler; -mod kv_handlers; mod meta_handlers; pub use action_handler::ActionHandler; From 0f13a37e45c9e05cb4507644def07d80e60e7e56 Mon Sep 17 00:00:00 2001 From: drdr xp Date: Tue, 9 Nov 2021 21:16:10 +0800 Subject: [PATCH 15/17] [metasrv] refactor: use derive_more to impl Into for actions --- Cargo.lock | 1 + common/meta/flight/Cargo.toml | 1 + common/meta/flight/src/flight_action.rs | 112 +++++++++--------------- 3 files changed, 43 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 30f78b1e70c1..22c15ea4154d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1423,6 +1423,7 @@ dependencies = [ "common-meta-types", "common-planners", "common-tracing", + "derive_more", "futures", "hyper", "jwt-simple", diff --git a/common/meta/flight/Cargo.toml b/common/meta/flight/Cargo.toml index 12072f111486..251ddfd111ae 100644 --- a/common/meta/flight/Cargo.toml +++ b/common/meta/flight/Cargo.toml @@ -24,6 +24,7 @@ common-tracing = {path = "../../tracing"} # Crates.io dependencies async-trait = "0.1" +derive_more = "0.99.16" futures = "0.3" jwt-simple = "0.10.7" log = "0.4" diff --git a/common/meta/flight/src/flight_action.rs b/common/meta/flight/src/flight_action.rs index d03177b13bfb..c877fd9c971c 100644 --- a/common/meta/flight/src/flight_action.rs +++ b/common/meta/flight/src/flight_action.rs @@ -43,23 +43,8 @@ pub trait RequestFor { type Reply; } -#[macro_export] -macro_rules! action_declare { - ($req:ident, $reply:ty, $enum_ctor:expr) => { - impl RequestFor for $req { - type Reply = $reply; - } - - impl From<$req> for MetaFlightAction { - fn from(act: $req) -> Self { - $enum_ctor(act) - } - } - }; -} - // Action wrapper for do_action. -#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] +#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, derive_more::From)] pub enum MetaFlightAction { // database meta CreateDatabase(CreateDatabaseAction), @@ -129,15 +114,6 @@ impl RequestFor for GetKVAction { type Reply = GetKVActionReply; } -// Explicitly defined the converter for MetaDoAction -// It's implementations' choice, that they gonna using enum MetaDoAction as wrapper. -// This can be simplified by using macro (see code below) -impl From for MetaFlightAction { - fn from(act: GetKVAction) -> Self { - MetaFlightAction::GetKV(act) - } -} - // - MGetKV // Again, impl chooses to wrap it up @@ -147,22 +123,20 @@ pub struct MGetKVAction { } // here we use a macro to simplify the declarations -action_declare!(MGetKVAction, MGetKVActionReply, MetaFlightAction::MGetKV); +impl RequestFor for MGetKVAction { + type Reply = MGetKVActionReply; +} // - prefix list #[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] pub struct PrefixListReq(pub String); -action_declare!( - PrefixListReq, - PrefixListReply, - MetaFlightAction::PrefixListKV -); - -action_declare!( - UpsertKVAction, - UpsertKVActionReply, - MetaFlightAction::UpsertKV -); +impl RequestFor for PrefixListReq { + type Reply = PrefixListReply; +} + +impl RequestFor for UpsertKVAction { + type Reply = UpsertKVActionReply; +} // == database actions == // - create database @@ -170,28 +144,26 @@ action_declare!( pub struct CreateDatabaseAction { pub plan: CreateDatabasePlan, } -action_declare!( - CreateDatabaseAction, - CreateDatabaseReply, - MetaFlightAction::CreateDatabase -); +impl RequestFor for CreateDatabaseAction { + type Reply = CreateDatabaseReply; +} // - get database #[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] pub struct GetDatabaseAction { pub db: String, } -action_declare!( - GetDatabaseAction, - DatabaseInfo, - MetaFlightAction::GetDatabase -); +impl RequestFor for GetDatabaseAction { + type Reply = DatabaseInfo; +} #[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] pub struct DropDatabaseAction { pub plan: DropDatabasePlan, } -action_declare!(DropDatabaseAction, (), MetaFlightAction::DropDatabase); +impl RequestFor for DropDatabaseAction { + type Reply = (); +} // == table actions == // - create table @@ -199,18 +171,18 @@ action_declare!(DropDatabaseAction, (), MetaFlightAction::DropDatabase); pub struct CreateTableAction { pub plan: CreateTablePlan, } -action_declare!( - CreateTableAction, - CreateTableReply, - MetaFlightAction::CreateTable -); +impl RequestFor for CreateTableAction { + type Reply = CreateTableReply; +} // - drop table #[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] pub struct DropTableAction { pub plan: DropTablePlan, } -action_declare!(DropTableAction, (), MetaFlightAction::DropTable); +impl RequestFor for DropTableAction { + type Reply = (); +} // - get table #[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq)] @@ -219,13 +191,17 @@ pub struct GetTableAction { pub table: String, } -action_declare!(GetTableAction, TableInfo, MetaFlightAction::GetTable); +impl RequestFor for GetTableAction { + type Reply = TableInfo; +} #[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq)] pub struct GetTableExtReq { pub tbl_id: MetaId, } -action_declare!(GetTableExtReq, TableInfo, MetaFlightAction::GetTableExt); +impl RequestFor for GetTableExtReq { + type Reply = TableInfo; +} #[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq)] pub struct UpsertTableOptionReq { @@ -234,11 +210,9 @@ pub struct UpsertTableOptionReq { pub option_key: String, pub option_value: String, } -action_declare!( - UpsertTableOptionReq, - UpsertTableOptionReply, - MetaFlightAction::CommitTable -); +impl RequestFor for UpsertTableOptionReq { + type Reply = UpsertTableOptionReply; +} // - get tables #[derive(serde::Serialize, serde::Deserialize, Clone, Debug, Eq, PartialEq)] @@ -246,19 +220,15 @@ pub struct GetTablesAction { pub db: String, } -action_declare!( - GetTablesAction, - Vec>, - MetaFlightAction::GetTables -); +impl RequestFor for GetTablesAction { + type Reply = Vec>; +} // -get databases #[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq)] pub struct GetDatabasesAction; -action_declare!( - GetDatabasesAction, - Vec>, - MetaFlightAction::GetDatabases -); +impl RequestFor for GetDatabasesAction { + type Reply = Vec>; +} From d7407fc2a6277ff474338877b5a0bb7a2e68b318 Mon Sep 17 00:00:00 2001 From: drdr xp Date: Wed, 10 Nov 2021 13:28:16 +0800 Subject: [PATCH 16/17] [metasrv] refactor: move write_to_local_leader() to MetaLeader --- metasrv/src/meta_service/message.rs | 3 + metasrv/src/meta_service/meta_leader.rs | 56 ++++++++++----- metasrv/src/meta_service/meta_service_impl.rs | 22 ++++-- .../meta_service/meta_service_impl_test.rs | 13 +++- metasrv/src/meta_service/raftmeta.rs | 69 +++---------------- metasrv/src/meta_service/raftmeta_test.rs | 30 +++++--- 6 files changed, 96 insertions(+), 97 deletions(-) diff --git a/metasrv/src/meta_service/message.rs b/metasrv/src/meta_service/message.rs index 8f7f48bce023..02d4a31412b3 100644 --- a/metasrv/src/meta_service/message.rs +++ b/metasrv/src/meta_service/message.rs @@ -35,6 +35,7 @@ pub struct JoinRequest { #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, derive_more::TryInto)] pub enum AdminRequestInner { Join(JoinRequest), + Write(LogEntry), } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] @@ -52,8 +53,10 @@ impl AdminRequest { } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, derive_more::TryInto)] +#[allow(clippy::large_enum_variant)] pub enum AdminResponse { Join(()), + AppliedState(AppliedState), } impl tonic::IntoRequest for AdminRequest { diff --git a/metasrv/src/meta_service/meta_leader.rs b/metasrv/src/meta_service/meta_leader.rs index 494dce70c907..eb15a0eaffbc 100644 --- a/metasrv/src/meta_service/meta_leader.rs +++ b/metasrv/src/meta_service/meta_leader.rs @@ -15,7 +15,10 @@ use std::collections::BTreeSet; use async_raft::error::ResponseError; +use async_raft::raft::ClientWriteRequest; use async_raft::ChangeConfigError; +use async_raft::ClientWriteError; +use common_meta_raft_store::state_machine::AppliedState; use common_meta_types::Cmd; use common_meta_types::LogEntry; use common_meta_types::Node; @@ -25,7 +28,6 @@ use common_tracing::tracing; use crate::errors::ForwardToLeader; use crate::errors::InvalidMembership; use crate::errors::MetaError; -use crate::errors::RetryableError; use crate::meta_service::message::AdminRequest; use crate::meta_service::message::AdminResponse; use crate::meta_service::AdminRequestInner; @@ -52,6 +54,10 @@ impl<'a> MetaLeader<'a> { self.join(join_req).await?; Ok(AdminResponse::Join(())) } + AdminRequestInner::Write(entry) => { + let res = self.write(entry).await?; + Ok(AdminResponse::AppliedState(res)) + } } } @@ -85,23 +91,7 @@ impl<'a> MetaLeader<'a> { }, }; - let res = self - .meta_node - .write_to_local_leader(ent.clone()) - .await - .map_err(|e| MetaError::UnknownError(e.to_string()))?; - match res { - Ok(_applied_state) => {} - Err(retryable_error) => { - // TODO(xp): remove retryable error. - let leader_id = match retryable_error { - RetryableError::ForwardToLeader { leader } => leader, - }; - return Err(MetaError::ForwardToLeader(ForwardToLeader { - leader: Some(leader_id), - })); - } - } + self.write(ent.clone()).await?; self.change_membership(membership).await } @@ -138,4 +128,34 @@ impl<'a> MetaLeader<'a> { _ => Err(MetaError::UnknownError("uncovered error".to_string())), } } + + /// Write a log through local raft node and return the states before and after applying the log. + /// + /// If the raft node is not a leader, it returns MetaError::ForwardToLeader. + /// If the leadership is lost during writing the log, it returns an UnknownError. + /// TODO(xp): elaborate the UnknownError, e.g. LeaderLostError + #[tracing::instrument(level = "debug", skip(self))] + pub async fn write(&self, entry: LogEntry) -> Result { + let write_rst = self + .meta_node + .raft + .client_write(ClientWriteRequest::new(entry)) + .await; + + tracing::debug!("raft.client_write rst: {:?}", write_rst); + + match write_rst { + Ok(resp) => Ok(resp.data), + Err(cli_write_err) => match cli_write_err { + // fatal error + ClientWriteError::RaftError(raft_err) => { + Err(MetaError::UnknownError(raft_err.to_string())) + } + // retryable error + ClientWriteError::ForwardToLeader(_, leader) => { + Err(MetaError::ForwardToLeader(ForwardToLeader { leader })) + } + }, + } + } } diff --git a/metasrv/src/meta_service/meta_service_impl.rs b/metasrv/src/meta_service/meta_service_impl.rs index dde9cf912e79..1a4a41614f59 100644 --- a/metasrv/src/meta_service/meta_service_impl.rs +++ b/metasrv/src/meta_service/meta_service_impl.rs @@ -21,6 +21,7 @@ use std::sync::Arc; use common_meta_types::LogEntry; use common_tracing::tracing; +use crate::errors::MetaError; use crate::meta_service::message::AdminRequest; use crate::meta_service::MetaNode; use crate::proto::meta_service_server::MetaService; @@ -53,14 +54,21 @@ impl MetaService for MetaServiceImpl { let mes = request.into_inner(); let req: LogEntry = mes.try_into()?; - let rst = self - .meta_node - .write_to_local_leader(req) - .await - .map_err(|e| tonic::Status::internal(e.to_string()))?; + let leader = self.meta_node.as_leader().await; - let raft_mes = rst.into(); - Ok(tonic::Response::new(raft_mes)) + let leader = match leader { + Ok(x) => x, + Err(err) => { + let err: MetaError = err.into(); + let raft_reply = Err::<(), _>(err).into(); + return Ok(tonic::Response::new(raft_reply)); + } + }; + + let rst = leader.write(req).await; + + let raft_reply = rst.into(); + Ok(tonic::Response::new(raft_reply)) } #[tracing::instrument(level = "info", skip(self))] diff --git a/metasrv/src/meta_service/meta_service_impl_test.rs b/metasrv/src/meta_service/meta_service_impl_test.rs index 2be6170159d3..203f5bcf2f8b 100644 --- a/metasrv/src/meta_service/meta_service_impl_test.rs +++ b/metasrv/src/meta_service/meta_service_impl_test.rs @@ -25,6 +25,8 @@ use common_tracing::tracing; use log::info; use pretty_assertions::assert_eq; +use crate::errors::ForwardToLeader; +use crate::errors::MetaError; use crate::errors::RetryableError; use crate::meta_service::MetaNode; use crate::proto::meta_service_client::MetaServiceClient; @@ -165,12 +167,17 @@ async fn test_meta_cluster_write_on_non_leader() -> anyhow::Result<()> { }; let raft_mes = client.write(req).await?.into_inner(); - let rst: Result = raft_mes.into(); + let rst: Result = raft_mes.into(); + println!("{:?}", rst); + assert!(rst.is_err()); let err = rst.unwrap_err(); match err { - RetryableError::ForwardToLeader { leader } => { - assert_eq!(leader, 0); + MetaError::ForwardToLeader(ForwardToLeader { leader }) => { + assert_eq!(leader, Some(0)); + } + _ => { + panic!("expect ForwardToLeader") } } diff --git a/metasrv/src/meta_service/raftmeta.rs b/metasrv/src/meta_service/raftmeta.rs index 8dccdb8b8f9e..506e7cf13907 100644 --- a/metasrv/src/meta_service/raftmeta.rs +++ b/metasrv/src/meta_service/raftmeta.rs @@ -16,8 +16,6 @@ use std::collections::BTreeSet; use std::sync::Arc; use async_raft::config::Config; -use async_raft::raft::ClientWriteRequest; -use async_raft::ClientWriteError; use async_raft::Raft; use async_raft::RaftMetrics; use async_raft::SnapshotPolicy; @@ -46,10 +44,10 @@ use common_tracing::tracing::Instrument; use crate::errors::ConnectionError; use crate::errors::ForwardToLeader; use crate::errors::MetaError; -use crate::errors::RetryableError; use crate::meta_service::message::AdminRequest; use crate::meta_service::message::AdminResponse; use crate::meta_service::meta_leader::MetaLeader; +use crate::meta_service::AdminRequestInner; use crate::meta_service::MetaServiceImpl; use crate::meta_service::Network; use crate::proto::meta_service_client::MetaServiceClient; @@ -532,31 +530,16 @@ impl MetaNode { /// Submit a write request to the known leader. Returns the response after applying the request. #[tracing::instrument(level = "info", skip(self))] pub async fn write(&self, req: LogEntry) -> common_exception::Result { - let mut curr_leader = self.get_leader().await; - loop { - let rst = if curr_leader == self.sto.id { - self.write_to_local_leader(req.clone()).await? - } else { - // forward to leader - - let addr = self.sto.get_node_addr(&curr_leader).await?; - - // TODO: retry - let mut client = MetaServiceClient::connect(format!("http://{}", addr)) - .await - .map_err(|e| ErrorCode::CannotConnectNode(e.to_string()))?; - let resp = client.write(req.clone()).await?; - let rst: Result = resp.into_inner().into(); - rst - }; - - match rst { - Ok(resp) => return Ok(resp), - Err(write_err) => match write_err { - RetryableError::ForwardToLeader { leader } => curr_leader = leader, - }, - } - } + let res = self + .handle_admin_req(AdminRequest { + forward_to_leader: true, + req: AdminRequestInner::Write(req.clone()), + }) + .await?; + + let res: AppliedState = res.try_into().expect("expect AppliedState"); + + Ok(res) } /// Try to get the leader from the latest metrics of the local raft node. @@ -616,34 +599,4 @@ impl MetaNode { let res: Result = raft_mes.into(); res } - - /// Write a meta log through local raft node. - /// It works only when this node is the leader, - /// otherwise it returns ClientWriteError::ForwardToLeader error indicating the latest leader. - #[tracing::instrument(level = "info", skip(self))] - pub async fn write_to_local_leader( - &self, - req: LogEntry, - ) -> common_exception::Result> { - let write_rst = self.raft.client_write(ClientWriteRequest::new(req)).await; - - tracing::debug!("raft.client_write rst: {:?}", write_rst); - - match write_rst { - Ok(resp) => Ok(Ok(resp.data)), - Err(cli_write_err) => match cli_write_err { - // fatal error - ClientWriteError::RaftError(raft_err) => { - Err(ErrorCode::MetaServiceError(raft_err.to_string())) - } - // retryable error - ClientWriteError::ForwardToLeader(_, leader) => match leader { - Some(id) => Ok(Err(RetryableError::ForwardToLeader { leader: id })), - None => Err(ErrorCode::MetaServiceUnavailable( - "no leader to write".to_string(), - )), - }, - }, - } - } } diff --git a/metasrv/src/meta_service/raftmeta_test.rs b/metasrv/src/meta_service/raftmeta_test.rs index ce1faf9fae3a..7cccb6b4f5c9 100644 --- a/metasrv/src/meta_service/raftmeta_test.rs +++ b/metasrv/src/meta_service/raftmeta_test.rs @@ -32,8 +32,10 @@ use maplit::btreeset; use pretty_assertions::assert_eq; use crate::configs; -use crate::errors::RetryableError; +use crate::errors::ForwardToLeader; +use crate::errors::MetaError; use crate::meta_service::message::AdminRequest; +use crate::meta_service::meta_leader::MetaLeader; use crate::meta_service::AdminRequestInner; use crate::meta_service::JoinRequest; use crate::meta_service::MetaNode; @@ -136,8 +138,9 @@ async fn test_meta_node_write_to_local_leader() -> anyhow::Result<()> { let key = "t-non-leader-write"; for id in 0u64..4 { let mn = &all[id as usize]; - let rst = mn - .write_to_local_leader(LogEntry { + let maybe_leader = MetaLeader::new(mn); + let rst = maybe_leader + .write(LogEntry { txid: None, cmd: Cmd::UpsertKV { key: key.to_string(), @@ -148,16 +151,17 @@ async fn test_meta_node_write_to_local_leader() -> anyhow::Result<()> { }) .await; - let rst = rst?; - if id == leader_id { assert!(rst.is_ok()); } else { assert!(rst.is_err()); let e = rst.unwrap_err(); match e { - RetryableError::ForwardToLeader { leader } => { - assert_eq!(leader_id, leader); + MetaError::ForwardToLeader(ForwardToLeader { leader }) => { + assert_eq!(Some(leader_id), leader); + } + _ => { + panic!("expect ForwardToLeader") } } } @@ -559,7 +563,9 @@ async fn test_meta_node_restart_single_node() -> anyhow::Result<()> { let leader = tc.meta_nodes.pop().unwrap(); leader - .write_to_local_leader(LogEntry { + .as_leader() + .await? + .write(LogEntry { txid: None, cmd: Cmd::UpsertKV { key: "foo".to_string(), @@ -568,7 +574,7 @@ async fn test_meta_node_restart_single_node() -> anyhow::Result<()> { value_meta: None, }, }) - .await??; + .await?; log_cnt += 1; want_hs = leader.sto.raft_state.read_hard_state()?; @@ -752,7 +758,9 @@ async fn assert_upsert_kv_synced(meta_nodes: Vec>, key: &str) -> a tracing::info!("leader: last_applied={}", last_applied); { leader - .write_to_local_leader(LogEntry { + .as_leader() + .await? + .write(LogEntry { txid: None, cmd: Cmd::UpsertKV { key: key.to_string(), @@ -761,7 +769,7 @@ async fn assert_upsert_kv_synced(meta_nodes: Vec>, key: &str) -> a value_meta: None, }, }) - .await??; + .await?; } assert_applied_index(meta_nodes.clone(), last_applied + 1).await?; From d8c307c2ded9c99648c46aa5cd013eb8e5e6bb37 Mon Sep 17 00:00:00 2001 From: Sunli Date: Wed, 10 Nov 2021 17:00:45 +0800 Subject: [PATCH 17/17] Bump poem from `1.0.21` to `1.0.23`. --- Cargo.lock | 4 ++-- common/base/Cargo.toml | 2 +- common/base/src/http_shutdown_handlers.rs | 10 +++++----- metasrv/Cargo.toml | 2 +- metasrv/src/api/http_service.rs | 6 +++--- query/Cargo.toml | 2 +- query/src/api/http_service.rs | 6 +++--- query/src/common/service/http_shutdown_handles.rs | 10 +++++----- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22c15ea4154d..cae12bff8554 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4847,9 +4847,9 @@ dependencies = [ [[package]] name = "poem" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a70978aaae37dc18bbd43e5ed31cfd665a79a07bba612477eb808520eb5b1dde" +checksum = "ab3fde11180e1e5c1585b90776c410b200dd9a157300c9e7dd16b25a6b1ea1dd" dependencies = [ "async-trait", "base64 0.13.0", diff --git a/common/base/Cargo.toml b/common/base/Cargo.toml index 456f1fd730ce..5c5ace452eec 100644 --- a/common/base/Cargo.toml +++ b/common/base/Cargo.toml @@ -25,7 +25,7 @@ pprof = { version = "0.5", features = ["flamegraph", "protobuf"] } tokio = { version = "1.13.0", features = ["macros", "rt", "rt-multi-thread", "sync", "fs", "signal"] } uuid = { version = "0.8", features = ["serde", "v4"] } serde = { version = "1.0", features = ["derive"] } -poem = { version = "1.0.21", features = ["tls"] } +poem = { version = "1.0.23", features = ["rustls"] } [dev-dependencies] diff --git a/common/base/src/http_shutdown_handlers.rs b/common/base/src/http_shutdown_handlers.rs index 5624e08f221e..626fc0873bbc 100644 --- a/common/base/src/http_shutdown_handlers.rs +++ b/common/base/src/http_shutdown_handlers.rs @@ -20,9 +20,10 @@ use common_tracing::tracing; use futures::FutureExt; use poem::listener::Acceptor; use poem::listener::AcceptorExt; +use poem::listener::IntoTlsConfigStream; use poem::listener::Listener; +use poem::listener::RustlsConfig; use poem::listener::TcpListener; -use poem::listener::TlsConfig; use poem::Endpoint; use tokio::sync::oneshot; use tokio::task::JoinHandle; @@ -45,7 +46,7 @@ impl HttpShutdownHandler { pub async fn start_service( &mut self, listening: String, - tls_config: Option, + tls_config: Option, ep: impl Endpoint + 'static, ) -> Result { assert!(self.join_handle.is_none()); @@ -65,13 +66,12 @@ impl HttpShutdownHandler { if let Some(tls_config) = tls_config { acceptor = acceptor - .tls(tls_config) - .map_err(|err| { + .rustls(tls_config.into_stream().map_err(|err| { ErrorCode::TLSConfigurationFailure(format!( "Cannot build TLS config for http service, cause {}", err )) - })? + })?) .boxed(); } diff --git a/metasrv/Cargo.toml b/metasrv/Cargo.toml index ceac5495191f..15dade74291a 100644 --- a/metasrv/Cargo.toml +++ b/metasrv/Cargo.toml @@ -69,7 +69,7 @@ tonic = { version = "0.6.0", features = ["tls"]} sha2 = "0.9.8" uuid = { version = "0.8", features = ["serde", "v4"] } -poem = { version = "1.0.21", features = ["tls"] } +poem = { version = "1.0.23", features = ["rustls"] } [dev-dependencies] common-meta-api = {path = "../common/meta/api" } diff --git a/metasrv/src/api/http_service.rs b/metasrv/src/api/http_service.rs index 03ad29c36c7e..fb083bb18045 100644 --- a/metasrv/src/api/http_service.rs +++ b/metasrv/src/api/http_service.rs @@ -17,7 +17,7 @@ use common_base::HttpShutdownHandler; use common_base::Stoppable; use common_exception::Result; use poem::get; -use poem::listener::TlsConfig; +use poem::listener::RustlsConfig; use poem::Endpoint; use poem::EndpointExt; use poem::Route; @@ -52,12 +52,12 @@ impl HttpService { .data(self.cfg.clone()) } - fn build_tls(config: &Config) -> Result { + fn build_tls(config: &Config) -> Result { let conf = config.clone(); let tls_cert = conf.admin_tls_server_cert; let tls_key = conf.admin_tls_server_key; - let cfg = TlsConfig::new() + let cfg = RustlsConfig::new() .cert(std::fs::read(tls_cert.as_str())?) .key(std::fs::read(tls_key.as_str())?); Ok(cfg) diff --git a/query/Cargo.toml b/query/Cargo.toml index a81dc41f2497..0233c67ac760 100644 --- a/query/Cargo.toml +++ b/query/Cargo.toml @@ -56,7 +56,7 @@ sqlparser = { git = "https://github.com/datafuse-extras/sqlparser-rs", rev = "ec ahash = "0.7.6" async-compat = "0.2.1" async-trait = "0.1" -poem = { version = "1.0.21", features = ["tls"] } +poem = { version = "1.0.23", features = ["rustls"] } bumpalo = "3.8.0" byteorder = "1" bytes = "1" diff --git a/query/src/api/http_service.rs b/query/src/api/http_service.rs index f79501681c5b..b8d091b42150 100644 --- a/query/src/api/http_service.rs +++ b/query/src/api/http_service.rs @@ -17,7 +17,7 @@ use std::path::Path; use common_exception::Result; use poem::get; -use poem::listener::TlsConfig; +use poem::listener::RustlsConfig; use poem::Endpoint; use poem::EndpointExt; use poem::Route; @@ -61,8 +61,8 @@ impl HttpService { .data(self.sessions.get_conf().clone()) } - fn build_tls(config: &Config) -> Result { - let mut cfg = TlsConfig::new() + fn build_tls(config: &Config) -> Result { + let mut cfg = RustlsConfig::new() .cert(std::fs::read(&config.query.api_tls_server_cert.as_str())?) .key(std::fs::read(&config.query.api_tls_server_key.as_str())?); if Path::new(&config.query.api_tls_server_root_ca_cert).exists() { diff --git a/query/src/common/service/http_shutdown_handles.rs b/query/src/common/service/http_shutdown_handles.rs index d42c65e97063..f3c1c2ec1be8 100644 --- a/query/src/common/service/http_shutdown_handles.rs +++ b/query/src/common/service/http_shutdown_handles.rs @@ -21,9 +21,10 @@ use common_exception::Result; use futures::FutureExt; use poem::listener::Acceptor; use poem::listener::AcceptorExt; +use poem::listener::IntoTlsConfigStream; use poem::listener::Listener; +use poem::listener::RustlsConfig; use poem::listener::TcpListener; -use poem::listener::TlsConfig; use poem::Endpoint; pub struct HttpShutdownHandler { @@ -44,7 +45,7 @@ impl HttpShutdownHandler { pub async fn start_service( &mut self, listening: SocketAddr, - tls_config: Option, + tls_config: Option, ep: impl Endpoint + 'static, ) -> Result { assert!(self.join_handle.is_none()); @@ -64,13 +65,12 @@ impl HttpShutdownHandler { if let Some(tls_config) = tls_config { acceptor = acceptor - .tls(tls_config) - .map_err(|err| { + .rustls(tls_config.into_stream().map_err(|err| { ErrorCode::TLSConfigurationFailure(format!( "Cannot build TLS config for http service, cause {}", err )) - })? + })?) .boxed(); }