diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9c0c1d8f5b1a5af810ed3ddfa6e83a00df76da29..cb6ff7b599cdad01da54e4e47f65e80c18149aa1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,7 @@ + variables: GIT_SUBMODULE_STRATEGY: none + SBROAD_DEV_IMAGE: docker-public.binary.picodata.io/sbroad-builder:0.5.0 stages: - build @@ -14,7 +16,7 @@ cache: default: tags: - picodata - image: docker-public.binary.picodata.io/picodata/picodata/sbroad/sbroad-builder:0.4.1 + image: ${SBROAD_DEV_IMAGE} build: stage: build script: diff --git a/Makefile b/Makefile index 15b4fb546609e02dcf66d2709c307631852b7d23..7331543e632c7bf3c3722df6936e0727b8e2730b 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ else SRC_LIB = libsbroad.dylib endif endif +IMAGE_NAME = docker-public.binary.picodata.io/sbroad-builder:0.5.0 bench: make clean @@ -60,3 +61,7 @@ test_integration: make run_integration test_all: test bench_check test_integration + +update_ci_image: + docker build -f ci/Dockerfile -t $(IMAGE_NAME) . + docker push $(IMAGE_NAME) diff --git a/src/api/calculate_bucket_id.rs b/src/api/calculate_bucket_id.rs index 028647a14f393bc3188bf354d2831d1c6155f4ab..ebbe9e54f33dcd692ea327b790b4544e879fdc3d 100644 --- a/src/api/calculate_bucket_id.rs +++ b/src/api/calculate_bucket_id.rs @@ -12,7 +12,7 @@ use crate::api::COORDINATOR_ENGINE; use crate::executor::engine::Coordinator; use crate::ir::value::Value; -#[derive(Debug, Default, Serialize, PartialEq)] +#[derive(Debug, Default, Serialize, PartialEq, Eq)] /// Tuple with space name and `key:value` map of values pub struct ArgsMap { /// A key:value `HashMap` with key String and custom type Value @@ -40,7 +40,7 @@ impl<'de> Deserialize<'de> for ArgsMap { } } -#[derive(Debug, Default, Serialize, PartialEq, Clone)] +#[derive(Clone, Debug, Default, Serialize, PartialEq, Eq)] /// Tuple with space name and vec of values pub struct ArgsTuple { /// Vec of custom type Value @@ -95,11 +95,11 @@ impl TryFrom<FunctionArgs> for Args { return Ok(Self::Map(args)); } - return Err(QueryPlannerError::CustomError(format!( + Err(QueryPlannerError::CustomError(format!( "Parsing args {:?} error, \ expected string, tuple with a space name, or map with a space name as an argument", &value - ))); + ))) } } diff --git a/src/api/helper.rs b/src/api/helper.rs index f05716f195ef127d2862ab9dbc554f5cfa2928b5..ba6276fadf6974b0f60aa8766146af679192212d 100644 --- a/src/api/helper.rs +++ b/src/api/helper.rs @@ -28,11 +28,11 @@ where 0 } Err(e) => { - return tarantool::set_error!( + tarantool::set_error!( TarantoolErrorCode::ProcC, "Failed to get configuration: {}", e.to_string() - ); + ) } } }); diff --git a/src/api/invalidate_cached_schema.rs b/src/api/invalidate_cached_schema.rs index 6a67b945bc0077e3334f433ef3bedb190dc3de61..06175a46cc7bd6a7d4f30eb03648f1e586c06079 100644 --- a/src/api/invalidate_cached_schema.rs +++ b/src/api/invalidate_cached_schema.rs @@ -23,11 +23,11 @@ pub extern "C" fn invalidate_coordinator_cache(ctx: FunctionCtx, _: FunctionArgs 0 } Err(e) => { - return tarantool::set_error!( + tarantool::set_error!( TarantoolErrorCode::ProcC, "Failed to borrow the runtime while clearing cached configuration on router: {}", e.to_string() - ); + ) } }) } @@ -43,11 +43,11 @@ pub extern "C" fn invalidate_segment_cache(ctx: FunctionCtx, _: FunctionArgs) -> 0 } Err(e) => { - return tarantool::set_error!( + tarantool::set_error!( TarantoolErrorCode::ProcC, "Failed to borrow the runtime while clearing cached configuration on a storage: {}", e.to_string() - ); + ) } }) } diff --git a/src/errors.rs b/src/errors.rs index 8914f6237d99e1d7d52fad51f7904c23b76f167c..06a73258191a37d83a35e644d09cb66c47057916 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -44,7 +44,7 @@ const UNSUPPORTED_TYPE_IR_VALUE: &str = "unsupported type ir value"; const VALUE_OUT_OF_RANGE_ERROR: &str = "value out of range"; const TYPE_NOT_IMPLEMENTED: &str = "type is not implemented"; -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize)] pub enum QueryPlannerError { BucketIdError, CustomError(String), diff --git a/src/executor/bucket.rs b/src/executor/bucket.rs index 73cc7dddc867c6c918eca1e4ad4e3f85017bd9ff..3e2aab94ae6907460237a766071ccb1916d67e97 100644 --- a/src/executor/bucket.rs +++ b/src/executor/bucket.rs @@ -13,7 +13,7 @@ use crate::ir::transformation::redistribution::MotionPolicy; use crate::ir::value::Value; /// Buckets are used to determine which nodes to send the query to. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum Buckets { // We don't want to keep thousands of buckets in memory // so we use a special enum to represent all the buckets diff --git a/src/executor/engine/cartridge/backend/sql/ir.rs b/src/executor/engine/cartridge/backend/sql/ir.rs index a79b248ea8191555f2c95bb44f1b2dc69cf398a5..42eca870770d08d52390cf8a946151ef4f8531f4 100644 --- a/src/executor/engine/cartridge/backend/sql/ir.rs +++ b/src/executor/engine/cartridge/backend/sql/ir.rs @@ -15,7 +15,7 @@ use crate::ir::Node; use super::tree::SyntaxData; -#[derive(Debug, PartialEq, Serialize, tlua::Push)] +#[derive(Debug, PartialEq, Eq, Serialize, tlua::Push)] pub struct PatternWithParams { pub pattern: String, pub params: Vec<Value>, diff --git a/src/executor/engine/cartridge/backend/sql/tree.rs b/src/executor/engine/cartridge/backend/sql/tree.rs index 8a312f847ec3f1341367a5f21157cefe2f50d242..c08d604b65e842d43e4f6efe075c7e6c838dc639 100644 --- a/src/executor/engine/cartridge/backend/sql/tree.rs +++ b/src/executor/engine/cartridge/backend/sql/tree.rs @@ -14,7 +14,7 @@ use crate::ir::operator::{Bool, Relational}; use crate::ir::Node; /// Payload of the syntax tree node. -#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] +#[derive(Clone, Deserialize, Debug, PartialEq, Eq, Serialize)] pub enum SyntaxData { /// "as alias_name" Alias(String), @@ -39,7 +39,7 @@ pub enum SyntaxData { } /// A syntax tree node. -#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] +#[derive(Clone, Deserialize, Debug, PartialEq, Eq, Serialize)] pub struct SyntaxNode { /// Payload pub(crate) data: SyntaxData, @@ -145,7 +145,7 @@ impl SyntaxNode { } /// Storage for the syntax nodes. -#[derive(Deserialize, Serialize, PartialEq, Debug)] +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct SyntaxNodes { pub(crate) arena: Vec<SyntaxNode>, map: HashMap<usize, usize, RandomState>, @@ -161,7 +161,7 @@ impl SyntaxNodes { children, alias, .. } = rel { - let right_id = *children.get(0).ok_or_else(|| { + let right_id = *children.first().ok_or_else(|| { QueryPlannerError::CustomError("Sub-query has no children.".into()) })?; let mut children: Vec<usize> = vec![ @@ -480,7 +480,7 @@ impl<'p> SyntaxPlan<'p> { condition, .. } => { - let left_id = *children.get(0).ok_or_else(|| { + let left_id = *children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Inner join doesn't have a left child.".into(), ) @@ -505,7 +505,7 @@ impl<'p> SyntaxPlan<'p> { Relational::Projection { children, output, .. } => { - let left_id = *children.get(0).ok_or_else(|| { + let left_id = *children.first().ok_or_else(|| { QueryPlannerError::CustomError("Projection has no children.".into()) })?; // We don't need the row node itself, only its children. @@ -535,7 +535,7 @@ impl<'p> SyntaxPlan<'p> { Relational::Selection { children, filter, .. } => { - let left_id = *children.get(0).ok_or_else(|| { + let left_id = *children.first().ok_or_else(|| { QueryPlannerError::CustomError("Selection has no children.".into()) })?; let sn = SyntaxNode::new_pointer( @@ -546,7 +546,7 @@ impl<'p> SyntaxPlan<'p> { Ok(self.nodes.push_syntax_node(sn)) } Relational::Except { children, .. } | Relational::UnionAll { children, .. } => { - let left_id = *children.get(0).ok_or_else(|| { + let left_id = *children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Union/except doesn't have a left child.".into(), ) diff --git a/src/executor/engine/cartridge/config.rs b/src/executor/engine/cartridge/config.rs index 3a5df8ad32f48c3ae52a459d4585ac6f73c99d61..a262c6ce8d1fc6d2d387cb72b4610812573582a7 100644 --- a/src/executor/engine/cartridge/config.rs +++ b/src/executor/engine/cartridge/config.rs @@ -18,7 +18,7 @@ use tarantool::log::{say, SayLevel}; /// /// Information based on tarantool cartridge schema. Cache knows nothing about bucket distribution in the cluster, /// as it is managed by Tarantool's vshard module. -#[derive(Debug, Clone, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct RouterConfiguration { /// Execute response waiting timeout in seconds. waiting_timeout: u64, diff --git a/src/executor/engine/mock.rs b/src/executor/engine/mock.rs index 2d48379f261aa101c836708d573c50a4e66218fb..aa7f621a0b7efe06fa7f24b0d627d31fecb68a96 100644 --- a/src/executor/engine/mock.rs +++ b/src/executor/engine/mock.rs @@ -209,7 +209,7 @@ impl ProducerResult { "Metadata mismatch. Producer results can't be extended", ))); } - self.rows.extend(result.rows.clone()); + self.rows.extend(result.rows); Ok(()) } } diff --git a/src/executor/ir.rs b/src/executor/ir.rs index cc21dbf7bdbf67ebb019b8d744b52ab4bab49dd0..27f66e94595a7956530d22f3a7ebbebd19f723b4 100644 --- a/src/executor/ir.rs +++ b/src/executor/ir.rs @@ -149,7 +149,7 @@ impl ExecutionPlan { ))); } - let child_id = children.get(0).ok_or_else(|| { + let child_id = children.first().ok_or_else(|| { QueryPlannerError::CustomError("Failed to get the first motion child".to_string()) })?; @@ -182,7 +182,7 @@ impl ExecutionPlan { ))); } - let child_id = children.get(0).ok_or_else(|| { + let child_id = children.first().ok_or_else(|| { QueryPlannerError::CustomError("Could not find subquery child".to_string()) })?; diff --git a/src/executor/vtable.rs b/src/executor/vtable.rs index f3220765c5c9ccead24d706fad9ea4ec8455f35e..5d75a5a841465ab740c2be93ad2b1d5ca544633b 100644 --- a/src/executor/vtable.rs +++ b/src/executor/vtable.rs @@ -18,7 +18,7 @@ struct ShardingRecord(ShardingKey, usize); /// Result tuple storage, created by the executor. All tuples /// have a distribution key. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct VirtualTable { /// List of the columns. columns: Vec<Column>, diff --git a/src/frontend/sql.rs b/src/frontend/sql.rs index b6f8ee3a8a7b084bffa4cda9d3fc73a3d5d7d7e1..57c29518344ec2455c3baef36760669d227fec23 100644 --- a/src/frontend/sql.rs +++ b/src/frontend/sql.rs @@ -112,7 +112,7 @@ impl Ast for AbstractSyntaxTree { let node = self.nodes.get_node(*id)?; match &node.rule { Type::Scan => { - let ast_child_id = node.children.get(0).ok_or_else(|| { + let ast_child_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Could not find child id in scan node".to_string(), ) @@ -148,7 +148,7 @@ impl Ast for AbstractSyntaxTree { } } Type::SubQuery => { - let ast_child_id = node.children.get(0).ok_or_else(|| { + let ast_child_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Child node id is not found among sub-query children.".into(), ) @@ -214,10 +214,10 @@ impl Ast for AbstractSyntaxTree { // Reference to the join node. if let (Some(plan_left_id), Some(plan_right_id)) = - (plan_rel_list.get(0), plan_rel_list.get(1)) + (plan_rel_list.first(), plan_rel_list.get(1)) { if let (Some(ast_scan_id), Some(ast_col_name_id)) = - (node.children.get(0), node.children.get(1)) + (node.children.first(), node.children.get(1)) { let ast_scan = self.nodes.get_node(*ast_scan_id)?; if let Type::ScanName = ast_scan.rule { @@ -277,7 +277,7 @@ impl Ast for AbstractSyntaxTree { )); } } else if let (Some(ast_col_name_id), None) = - (node.children.get(0), node.children.get(1)) + (node.children.first(), node.children.get(1)) { // Determine the referred side of the join (left or right). let col_name = get_column_name(*ast_col_name_id)?; @@ -317,10 +317,10 @@ impl Ast for AbstractSyntaxTree { // Reference to a single child node. } else if let (Some(plan_rel_id), None) = - (plan_rel_list.get(0), plan_rel_list.get(1)) + (plan_rel_list.first(), plan_rel_list.get(1)) { let col_name: String = if let (Some(ast_scan_id), Some(ast_col_id)) = - (node.children.get(0), node.children.get(1)) + (node.children.first(), node.children.get(1)) { // Get column name. let col_name = get_column_name(*ast_col_id)?; @@ -349,7 +349,7 @@ impl Ast for AbstractSyntaxTree { }; col_name } else if let (Some(ast_col_id), None) = - (node.children.get(0), node.children.get(1)) + (node.children.first(), node.children.get(1)) { // Get the column name. get_column_name(*ast_col_id)? @@ -367,7 +367,7 @@ impl Ast for AbstractSyntaxTree { false, true, )?; - let ref_id = *ref_list.get(0).ok_or_else(|| { + let ref_id = *ref_list.first().ok_or_else(|| { QueryPlannerError::CustomError("Referred column is not found.".into()) })?; map.add(*id, ref_id); @@ -405,7 +405,7 @@ impl Ast for AbstractSyntaxTree { "Sub-queries in projections are not implemented yet.".into(), )); } - let plan_rel_id = *plan_rel_list.get(0).ok_or_else(|| { + let plan_rel_id = *plan_rel_list.first().ok_or_else(|| { QueryPlannerError::CustomError( "Referred relational node is not found.".into(), ) @@ -414,7 +414,7 @@ impl Ast for AbstractSyntaxTree { map.add(*id, plan_asterisk_id); } Type::Alias => { - let ast_ref_id = node.children.get(0).ok_or_else(|| { + let ast_ref_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Reference node id is not found among alias children.".into(), ) @@ -439,7 +439,7 @@ impl Ast for AbstractSyntaxTree { map.add(*id, plan_alias_id); } Type::Column => { - let ast_child_id = node.children.get(0).ok_or_else(|| { + let ast_child_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError("Column has no children.".into()) })?; let plan_child_id = map.get(*ast_child_id)?; @@ -453,7 +453,7 @@ impl Ast for AbstractSyntaxTree { // reference-to-row logic in AST code, we should unwrap it back. let plan_id = if rows.get(&plan_child_id).is_some() { let plan_inner_expr = plan.get_expression_node(plan_child_id)?; - *plan_inner_expr.get_row_list()?.get(0).ok_or_else(|| { + *plan_inner_expr.get_row_list()?.first().ok_or_else(|| { QueryPlannerError::CustomError("Row is empty.".into()) })? } else { @@ -474,7 +474,7 @@ impl Ast for AbstractSyntaxTree { | Type::LtEq | Type::NotEq | Type::NotIn => { - let ast_left_id = node.children.get(0).ok_or_else(|| { + let ast_left_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Left node id is not found among comparison children.".into(), ) @@ -491,7 +491,7 @@ impl Ast for AbstractSyntaxTree { map.add(*id, cond_id); } Type::IsNull | Type::IsNotNull => { - let ast_child_id = node.children.get(0).ok_or_else(|| { + let ast_child_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError(format!("{:?} has no children.", &node.rule)) })?; let plan_child_id = plan.as_row(map.get(*ast_child_id)?, &mut rows)?; @@ -501,7 +501,7 @@ impl Ast for AbstractSyntaxTree { } Type::Between => { // left BETWEEN center AND right - let ast_left_id = node.children.get(0).ok_or_else(|| { + let ast_left_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Left node id is not found among between children.".into(), ) @@ -526,14 +526,14 @@ impl Ast for AbstractSyntaxTree { map.add(*id, and_id); } Type::Condition => { - let ast_child_id = node.children.get(0).ok_or_else(|| { + let ast_child_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError("Condition has no children.".into()) })?; let plan_child_id = map.get(*ast_child_id)?; map.add(*id, plan_child_id); } Type::InnerJoin => { - let ast_left_id = node.children.get(0).ok_or_else(|| { + let ast_left_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Left node id is not found among join children.".into(), ) @@ -555,7 +555,7 @@ impl Ast for AbstractSyntaxTree { map.add(*id, plan_join_id); } Type::Selection => { - let ast_child_id = node.children.get(0).ok_or_else(|| { + let ast_child_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Child node id is not found among selection children.".into(), ) @@ -571,7 +571,7 @@ impl Ast for AbstractSyntaxTree { map.add(*id, plan_selection_id); } Type::Projection => { - let ast_child_id = node.children.get(0).ok_or_else(|| { + let ast_child_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Child node id is not found among projection children.".into(), ) @@ -583,7 +583,7 @@ impl Ast for AbstractSyntaxTree { match ast_column.rule { Type::Column => { let ast_alias_id = - *ast_column.children.get(0).ok_or_else(|| { + *ast_column.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Alias node id is not found among column children." .into(), @@ -619,7 +619,7 @@ impl Ast for AbstractSyntaxTree { map.add(*id, projection_id); } Type::Except => { - let ast_left_id = node.children.get(0).ok_or_else(|| { + let ast_left_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Left node id is not found among except children.".into(), ) @@ -635,7 +635,7 @@ impl Ast for AbstractSyntaxTree { map.add(*id, plan_except_id); } Type::UnionAll => { - let ast_left_id = node.children.get(0).ok_or_else(|| { + let ast_left_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Left node id is not found among union all children.".into(), ) @@ -651,7 +651,7 @@ impl Ast for AbstractSyntaxTree { map.add(*id, plan_union_all_id); } Type::ValuesRow => { - let ast_child_id = node.children.get(0).ok_or_else(|| { + let ast_child_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError("Values row has no children.".into()) })?; let plan_child_id = map.get(*ast_child_id)?; @@ -668,7 +668,7 @@ impl Ast for AbstractSyntaxTree { map.add(*id, plan_values_id); } Type::Insert => { - let ast_table_id = node.children.get(0).ok_or_else(|| { + let ast_table_id = node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Table node id is not found among insert children.".into(), ) diff --git a/src/frontend/sql/ast.rs b/src/frontend/sql/ast.rs index 7f54017ad87dc42c15e0cd381f300f5033a4f740..9c84363a76c70b6948b05abe7dcb3a0631e52223 100644 --- a/src/frontend/sql/ast.rs +++ b/src/frontend/sql/ast.rs @@ -22,7 +22,7 @@ pub(super) struct ParseTree; /// A list of current rules from the actual grammar. /// When new tokens are added to the grammar they /// should be also added in the current list. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub enum Type { Alias, AliasName, @@ -133,7 +133,7 @@ impl Type { } /// Parse node is a wrapper over the pest pair. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct ParseNode { pub(in crate::frontend::sql) children: Vec<usize>, pub(in crate::frontend::sql) rule: Type, @@ -153,7 +153,7 @@ impl ParseNode { /// A storage arena of the parse nodes /// (a node position in the arena vector acts like a reference). -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct ParseNodes { pub(crate) arena: Vec<ParseNode>, } @@ -257,7 +257,7 @@ impl<'n> StackParseNode<'n> { } /// AST is a tree build on the top of the parse nodes arena. -#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct AbstractSyntaxTree { pub(in crate::frontend::sql) nodes: ParseNodes, pub(in crate::frontend::sql) top: Option<usize>, @@ -336,7 +336,7 @@ impl AbstractSyntaxTree { ) })?; let child = self.nodes.get_node(child_id)?; - let mut node_id = *child.children.get(0).ok_or_else(|| { + let mut node_id = *child.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Selection node doesn't contain any children.".into(), ) @@ -348,7 +348,7 @@ impl AbstractSyntaxTree { let top_id = self.get_top()?; if selects.contains(&top_id) { let top = self.nodes.get_node(top_id)?; - let child_id = *top.children.get(0).ok_or_else(|| { + let child_id = *top.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Selection node doesn't contain any children.".into(), ) @@ -376,7 +376,7 @@ impl AbstractSyntaxTree { } // Check that the first child is `Projection`. - let proj_id: usize = *children.get(0).ok_or(QueryPlannerError::ValueOutOfRange)?; + let proj_id: usize = *children.first().ok_or(QueryPlannerError::ValueOutOfRange)?; let proj = self .nodes .arena @@ -432,7 +432,7 @@ impl AbstractSyntaxTree { selection.children.insert(0, scan_id); // Check that the first child is `Projection`. - let proj_id: usize = *children.get(0).ok_or(QueryPlannerError::ValueOutOfRange)?; + let proj_id: usize = *children.first().ok_or(QueryPlannerError::ValueOutOfRange)?; let proj = self .nodes .arena @@ -498,7 +498,7 @@ impl AbstractSyntaxTree { join.children.insert(0, scan_id); // Check that the first child is `Projection`. - let proj_id: usize = *children.get(0).ok_or(QueryPlannerError::ValueOutOfRange)?; + let proj_id: usize = *children.first().ok_or(QueryPlannerError::ValueOutOfRange)?; let proj = self .nodes .arena @@ -578,7 +578,7 @@ impl AbstractSyntaxTree { selection.children.insert(0, join_id); // Check that the first child is `Projection`. - let proj_id: usize = *children.get(0).ok_or(QueryPlannerError::ValueOutOfRange)?; + let proj_id: usize = *children.first().ok_or(QueryPlannerError::ValueOutOfRange)?; let proj = self .nodes .arena @@ -614,7 +614,7 @@ impl AbstractSyntaxTree { for child_id in &node.children { let child = self.nodes.get_node(*child_id)?; if let Type::Column = child.rule { - let col_child_id = *child.children.get(0).ok_or_else(|| { + let col_child_id = *child.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "Column doesn't have any children".into(), ) @@ -626,11 +626,11 @@ impl AbstractSyntaxTree { } Type::Reference => { let col_name_id: usize = if let (Some(_), Some(col_name_id)) = - (col_child.children.get(0), col_child.children.get(1)) + (col_child.children.first(), col_child.children.get(1)) { *col_name_id } else if let (Some(col_name_id), None) = - (col_child.children.get(0), col_child.children.get(1)) + (col_child.children.first(), col_child.children.get(1)) { *col_name_id } else { @@ -666,7 +666,7 @@ impl AbstractSyntaxTree { "Parsed node is not a column.".into(), )); } - let child_id = *node.children.get(0).ok_or_else(|| { + let child_id = *node.children.first().ok_or_else(|| { QueryPlannerError::CustomError("Column doesn't have any children".into()) })?; let child = self.nodes.get_node(child_id)?; @@ -701,7 +701,7 @@ impl AbstractSyntaxTree { let rel_node = self.nodes.get_node(*node_id)?; match rel_node.rule { Type::Projection => { - let rel_id = rel_node.children.get(0).ok_or_else(|| { + let rel_id = rel_node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "AST projection doesn't have any children.".into(), ) @@ -719,7 +719,7 @@ impl AbstractSyntaxTree { } } Type::Selection => { - let rel_id = rel_node.children.get(0).ok_or_else(|| { + let rel_id = rel_node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "AST selection doesn't have any children.".into(), ) @@ -740,7 +740,7 @@ impl AbstractSyntaxTree { } } Type::InnerJoin => { - let left_id = rel_node.children.get(0).ok_or_else(|| { + let left_id = rel_node.children.first().ok_or_else(|| { QueryPlannerError::CustomError( "AST inner join doesn't have a left child.".into(), ) diff --git a/src/ir.rs b/src/ir.rs index c156abd89f73d40fd8be2c4ab2bda53a68d6565d..014795116a04a1385e1c63cc1881e9e08282c63c 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -34,7 +34,7 @@ pub mod value; /// /// Enum was chosen as we don't want to mess with dynamic /// dispatching and its performance penalties. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub enum Node { Expression(Expression), Relational(Relational), @@ -42,7 +42,7 @@ pub enum Node { } /// Plan nodes storage. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct Nodes { /// We don't want to mess with the borrow checker and RefCell/Rc, /// so all nodes are stored in the single arena ("nodes" array). @@ -88,7 +88,7 @@ impl Nodes { } /// Logical plan tree structure. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct Plan { /// Append only arena for the plan nodes. pub(crate) nodes: Nodes, @@ -441,7 +441,7 @@ impl Plan { let child_ids = targets.as_ref().ok_or_else(|| { QueryPlannerError::CustomError("Node refs to scan node, not alias".into()) })?; - let column_index_in_list = child_ids.get(0).ok_or_else(|| { + let column_index_in_list = child_ids.first().ok_or_else(|| { QueryPlannerError::CustomError("Invalid child index in target".into()) })?; let col_idx_in_rel = diff --git a/src/ir/distribution.rs b/src/ir/distribution.rs index 4d42d080b3f2ab32b9ade71232148696d1c480c6..c1eeb142e900f19d0c76083b43c6a87c754ef6c4 100644 --- a/src/ir/distribution.rs +++ b/src/ir/distribution.rs @@ -33,7 +33,7 @@ impl Key { } /// Tuple distribution in the cluster. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub enum Distribution { /// A tuple can be located on any data node. /// Example: projection removes the segment key columns. diff --git a/src/ir/expression.rs b/src/ir/expression.rs index 2a693b49aa7aa8df00271a65c917a21154ff7def..8580e523bff9e99528e3c0324c9842fd9a357dc5 100644 --- a/src/ir/expression.rs +++ b/src/ir/expression.rs @@ -30,7 +30,7 @@ use super::{operator, Node, Nodes, Plan}; /// and should not be changed. It ensures that we always know the /// name of any column in the tuple and therefore simplifies AST /// deserialization. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub enum Expression { /// Expression name. /// @@ -423,7 +423,7 @@ impl Plan { .. } => { let sel_child_id = if let (Some(sel_child_id), None) = - (sel_child_ids.get(0), sel_child_ids.get(1)) + (sel_child_ids.first(), sel_child_ids.get(1)) { *sel_child_id } else { @@ -504,7 +504,7 @@ impl Plan { } result.reserve(col_names.len()); - let target_child: usize = if let Some(target) = targets.get(0) { + let target_child: usize = if let Some(target) = targets.first() { *target } else { return Err(QueryPlannerError::CustomError("Target is empty".into())); @@ -721,7 +721,7 @@ impl Plan { "Reference node has no targets".into(), )) } - Some(positions) => match (positions.get(0), positions.get(1)) { + Some(positions) => match (positions.first(), positions.get(1)) { (Some(first), None) => { let child_id = children.get(*first).ok_or_else(|| { QueryPlannerError::CustomError( diff --git a/src/ir/operator.rs b/src/ir/operator.rs index b12a32177a976e9bdacc962ce26693f8c7979f53..dad8c6faec7d3d2a2b4c7078f302df33a5560a1d 100644 --- a/src/ir/operator.rs +++ b/src/ir/operator.rs @@ -125,7 +125,7 @@ impl Display for Unary { /// /// Transforms input tuple(s) into the output one using the /// relation algebra logic. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub enum Relational { Except { /// Contains exactly two elements: left and right node indexes @@ -649,7 +649,7 @@ impl Plan { }; children.push(chid_id); } - if let (Some(left_id), Some(right_id)) = (children.get(0), children.get(1)) { + if let (Some(left_id), Some(right_id)) = (children.first(), children.get(1)) { let output = self.add_row_for_join(*left_id, *right_id)?; let join = Relational::InnerJoin { children: vec![*left_id, *right_id], @@ -1073,10 +1073,10 @@ impl Plan { }; match self.get_relation_node(rel_id)? { Relational::Selection { .. } | Relational::Projection { .. } => { - Ok(children.get(0) != Some(&sq_id)) + Ok(children.first() != Some(&sq_id)) } Relational::InnerJoin { .. } => { - Ok(children.get(0) != Some(&sq_id) && children.get(1) != Some(&sq_id)) + Ok(children.first() != Some(&sq_id) && children.get(1) != Some(&sq_id)) } _ => Ok(false), } diff --git a/src/ir/relation.rs b/src/ir/relation.rs index 5c418a73cead06b07c3f36a10de5b29055d0cd49..f658b707c7c22ad05337a3518e884d0369d40db5 100644 --- a/src/ir/relation.rs +++ b/src/ir/relation.rs @@ -168,7 +168,7 @@ impl Column { /// Table is a tuple storage in the cluster. /// /// Tables are tuple storages in the cluster. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct Table { /// List of the columns. pub columns: Vec<Column>, diff --git a/src/ir/transformation/equality_propagation.rs b/src/ir/transformation/equality_propagation.rs index 66e192f6fab9bc07e880b430a4090fc13239e48d..f55c1d70e7045f69808e90cb8c0a487ccba5feba 100644 --- a/src/ir/transformation/equality_propagation.rs +++ b/src/ir/transformation/equality_propagation.rs @@ -477,7 +477,7 @@ impl Plan { Ok(EqClassExpr::EqClassRef(EqClassRef::from_ref(expr)?)) } Expression::Row { list, .. } => { - if let (Some(col_id), None) = (list.get(0), list.get(1)) { + if let (Some(col_id), None) = (list.first(), list.get(1)) { self.try_to_eq_class_expr(*col_id) } else { // We don't support more than a single column in a row. diff --git a/src/ir/transformation/merge_tuples.rs b/src/ir/transformation/merge_tuples.rs index 35d208ff2f607d3860434e7793f29f35bb3cf5b4..d4aca891031cec50d4d2e694cd7a0f27cc581317 100644 --- a/src/ir/transformation/merge_tuples.rs +++ b/src/ir/transformation/merge_tuples.rs @@ -258,6 +258,7 @@ impl Plan { /// # Errors /// - Failed to build an expression subtree for some chain. /// - The plan is invalid (some bugs). + #[allow(clippy::type_complexity)] pub fn expr_tree_modify_and_chains( &mut self, expr_id: usize, diff --git a/src/ir/transformation/redistribution.rs b/src/ir/transformation/redistribution.rs index f1b3010fd2915519dafe15e42ca6934c199ac0b2..0925d9e17c5ae793276f0a97519daf132b47604a 100644 --- a/src/ir/transformation/redistribution.rs +++ b/src/ir/transformation/redistribution.rs @@ -61,7 +61,7 @@ impl From<&Key> for MotionKey { } /// Determinate what portion of data to move between data nodes in cluster. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub enum MotionPolicy { /// Move all data. Full, @@ -72,7 +72,7 @@ pub enum MotionPolicy { } /// Determine what portion of data to generate during motion. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub enum DataGeneration { /// Nothing to generate. None, @@ -541,7 +541,7 @@ impl Plan { let mut inner_keys: Vec<Key> = Vec::new(); let children = self.get_join_children(join_id)?; - let outer_child = *children.get(0).ok_or_else(|| { + let outer_child = *children.first().ok_or_else(|| { QueryPlannerError::CustomError("Join node doesn't have an outer child.".into()) })?; let inner_child = *children.get(1).ok_or_else(|| { @@ -769,7 +769,8 @@ impl Plan { children, .. } => { - let child: usize = if let (Some(child), None) = (children.get(0), children.get(1)) { + let child: usize = if let (Some(child), None) = (children.first(), children.get(1)) + { *child } else { return Err(QueryPlannerError::CustomError( @@ -881,7 +882,7 @@ impl Plan { match self.get_relation_node(rel_id)? { Relational::Except { children, .. } => { if let (Some(left), Some(right), None) = - (children.get(0), children.get(1), children.get(2)) + (children.first(), children.get(1), children.get(2)) { let left_output_id = self.get_relation_node(*left)?.output(); let right_output_id = self.get_relation_node(*right)?.output(); diff --git a/src/ir/value.rs b/src/ir/value.rs index f7ca38b112d8e8a2ef2531bf41d7e7368941ca4c..8d00c93be859b4c93a7eb13620aa337aaa300dcc 100644 --- a/src/ir/value.rs +++ b/src/ir/value.rs @@ -15,7 +15,7 @@ use crate::ir::value::double::Double; /// SQL uses three-valued logic. We need to implement /// it to compare values with each other. -#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] pub enum Trivalent { False, True, @@ -148,7 +148,7 @@ impl Value { /// The result uses three-valued logic. #[must_use] pub fn eq(&self, other: &Value) -> Trivalent { - match &*self { + match self { Value::Boolean(s) => match other { Value::Boolean(o) => (s == o).into(), Value::Null => Trivalent::Unknown,