From af62abf63537e854e6dc4a2962b81ce1d0ce91d6 Mon Sep 17 00:00:00 2001 From: EmirVildanov <reddog201030@gmail.com> Date: Tue, 4 Jun 2024 15:23:28 +0300 Subject: [PATCH] feat: mock param and transaction settings --- sbroad-core/src/frontend/sql.rs | 61 +++++++++++++++++++++++- sbroad-core/src/frontend/sql/ir/tests.rs | 32 +++++++++++++ sbroad-core/src/frontend/sql/query.pest | 30 +++++++++++- sbroad-core/src/ir/ddl.rs | 34 +++++++++++++ 4 files changed, 155 insertions(+), 2 deletions(-) diff --git a/sbroad-core/src/frontend/sql.rs b/sbroad-core/src/frontend/sql.rs index add50594b..642a38b2a 100644 --- a/sbroad-core/src/frontend/sql.rs +++ b/sbroad-core/src/frontend/sql.rs @@ -26,7 +26,7 @@ use crate::frontend::sql::ast::{ }; use crate::frontend::sql::ir::Translation; use crate::frontend::Ast; -use crate::ir::ddl::{ColumnDef, Ddl}; +use crate::ir::ddl::{ColumnDef, Ddl, SetParamScopeType, SetParamValue}; use crate::ir::ddl::{Language, ParamDef}; use crate::ir::expression::cast::Type as CastType; use crate::ir::expression::{ @@ -789,6 +789,53 @@ fn parse_create_table(ast: &AbstractSyntaxTree, node: &ParseNode) -> Result<Ddl, Ok(create_sharded_table) } +fn parse_set_param(ast: &AbstractSyntaxTree, node: &ParseNode) -> Result<Ddl, SbroadError> { + let mut scope_type = SetParamScopeType::Session; + let mut param_value = None; + for child_id in &node.children { + let child_node = ast.nodes.get_node(*child_id)?; + match child_node.rule { + Rule::SetScope => { + let set_scope_child_id = child_node + .children + .first() + .expect("SetScope must have child."); + let set_scope_child = ast.nodes.get_node(*set_scope_child_id)?; + match set_scope_child.rule { + Rule::ScopeSession => {} + Rule::ScopeLocal => scope_type = SetParamScopeType::Local, + _ => panic!("Unexpected rule met under SetScope."), + } + } + Rule::ConfParam => { + let conf_param_child_id = child_node + .children + .first() + .expect("ConfParam must have child."); + let conf_param_child = ast.nodes.get_node(*conf_param_child_id)?; + match conf_param_child.rule { + Rule::NamedParam => { + let param_name_id = conf_param_child + .children + .first() + .expect("Param name expected under NamedParam."); + let param_name = parse_identifier(ast, *param_name_id)?; + param_value = Some(SetParamValue::NamedParam { name: param_name }); + } + Rule::TimeZoneParam => param_value = Some(SetParamValue::TimeZone), + _ => panic!("Unexpected rule met under ConfParam."), + } + } + _ => panic!("Unexpected rule met under SetParam."), + } + } + Ok(Ddl::SetParam { + scope_type, + param_value: param_value.unwrap(), + timeout: get_default_timeout(), + }) +} + fn parse_select_full( ast: &AbstractSyntaxTree, node_id: usize, @@ -3476,6 +3523,18 @@ impl AbstractSyntaxTree { let plan_id = plan.nodes.push(Node::Acl(create_role)); map.add(id, plan_id); } + Rule::SetParam => { + let set_param_node = parse_set_param(self, node)?; + let plan_id = plan.nodes.push(Node::Ddl(set_param_node)); + map.add(id, plan_id); + } + Rule::SetTransaction => { + let set_transaction_node = Ddl::SetTransaction { + timeout: get_default_timeout(), + }; + let plan_id = plan.nodes.push(Node::Ddl(set_transaction_node)); + map.add(id, plan_id); + } _ => {} } } diff --git a/sbroad-core/src/frontend/sql/ir/tests.rs b/sbroad-core/src/frontend/sql/ir/tests.rs index 95b34689d..e9273244e 100644 --- a/sbroad-core/src/frontend/sql/ir/tests.rs +++ b/sbroad-core/src/frontend/sql/ir/tests.rs @@ -3556,6 +3556,38 @@ fn front_count_no_params() { ); } +#[test] +fn front_mock_set_param_transaction() { + let queries_to_check = vec![ + r#"set session default_param = default"#, + r#"set session stringparam = 'value'"#, + r#"set session identparam to ident"#, + r#"set local intparam to -3"#, + r#"set local doubleparam = -42.5"#, + r#"set doubleparam = -42.5"#, + r#"set local time zone local"#, + r#"set time zone -3"#, + r#"set time zone 'value'"#, + r#"set transaction snapshot 'snapshot-string'"#, + r#"set transaction read write"#, + r#"set transaction read only"#, + r#"set transaction deferrable"#, + r#"set transaction not deferrable"#, + r#"set transaction isolation level serializable"#, + r#"set transaction isolation level repeatable read"#, + r#"set transaction isolation level read commited"#, + r#"set transaction isolation level read uncommited"#, + r#"set session characteristics as transaction read only"#, + r#"set session characteristics as transaction isolation level read commited"#, + ]; + + let metadata = &RouterConfigurationMock::new(); + for query in queries_to_check { + let plan = AbstractSyntaxTree::transform_into_plan(query, metadata); + assert!(plan.is_ok()) + } +} + #[cfg(test)] mod cte; #[cfg(test)] diff --git a/sbroad-core/src/frontend/sql/query.pest b/sbroad-core/src/frontend/sql/query.pest index 4d4e3d3f0..014ed49ef 100644 --- a/sbroad-core/src/frontend/sql/query.pest +++ b/sbroad-core/src/frontend/sql/query.pest @@ -55,7 +55,8 @@ ACL = _{ DropRole | DropUser | CreateRole | CreateUser | AlterUser | GrantPrivil PrivilegeUsage = { ^"usage" } PrivilegeWrite = { ^"write" } -DDL = _{ CreateTable | DropTable | CreateIndex | DropIndex | CreateProc | DropProc | RenameProc } +DDL = _{ CreateTable | DropTable | CreateIndex | DropIndex + | CreateProc | DropProc | RenameProc | SetParam | SetTransaction } CreateTable = { ^"create" ~ ^"table" ~ NewTable ~ "(" ~ Columns ~ ("," ~ PrimaryKey)? ~ ")" ~ @@ -121,6 +122,33 @@ DDL = _{ CreateTable | DropTable | CreateIndex | DropIndex | CreateProc | DropPr DropIndex = { ^"drop" ~ ^"index" ~ Identifier ~ TimeoutOption? } + SetParam = { ^"set" ~ SetScope? ~ ConfParam } + SetScope = { ScopeSession | ScopeLocal } + ScopeSession = { ^"session" } + ScopeLocal = { ^"local" } + ConfParam = { NamedParam | TimeZoneParam } + NamedParam = { Identifier ~ (^"to" | "=") ~ NamedParamValue } + NamedParamValue = { ParamValueDefault | SingleQuotedString | Identifier | Double | Decimal | Integer } + TimeZoneParam = { ^"time" ~ ^"zone" ~ TimeZoneParamValue } + TimeZoneParamValue = { NamedParamValue | ParamValueLocal } + ParamValueLocal = { ^"local" } + ParamValueDefault = { ^"default" } + + SetTransaction = { ^"set" ~ (SetTransactionSubRule | SetSessionCharacteristics) } + SetTransactionSubRule = { ^"transaction" ~ (TransactionMode | TransactionSnapshot) } + SetSessionCharacteristics = { ^"session" ~ ^"characteristics" ~ ^"as" ~ ^"transaction" ~ TransactionMode } + TransactionMode = { IsolationLevel | ReadWrite | ReadOnly | Deferrable } + IsolationLevel = { ^"isolation" ~ ^"level" ~ ConcreteIsolationLevel } + ConcreteIsolationLevel = _{ Serializable | RepeatableRead | ReadCommited | ReadUncommited } + Serializable = { ^"serializable" } + RepeatableRead = { ^"repeatable" ~ ^"read" } + ReadCommited = { ^"read" ~ ^"commited" } + ReadUncommited = { ^"read" ~ ^"uncommited" } + ReadWrite = { ^"read" ~ ^"write" } + ReadOnly = { ^"read" ~ ^"only" } + Deferrable = { NotFlag? ~ ^"deferrable" } + TransactionSnapshot = { ^"snapshot" ~ SingleQuotedString } + Block = { CallProc ~ DqlOption? } CallProc = { ^"call" ~ Identifier ~ "(" ~ ProcValues ~ ")" } ProcValues = { ProcValue? ~ ("," ~ ProcValue)* } diff --git a/sbroad-core/src/ir/ddl.rs b/sbroad-core/src/ir/ddl.rs index 5eb1635e0..f692c2853 100644 --- a/sbroad-core/src/ir/ddl.rs +++ b/sbroad-core/src/ir/ddl.rs @@ -38,6 +38,29 @@ pub enum Language { SQL, } +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +pub enum SetParamScopeType { + Local, + Session, +} + +// TODO: Fill with actual values. +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +pub enum SetParamValue { + NamedParam { name: SmolStr }, + TimeZone, +} + +impl SetParamValue { + #[must_use] + pub fn param_name(&self) -> SmolStr { + match self { + SetParamValue::NamedParam { name } => name.clone(), + SetParamValue::TimeZone => SmolStr::from("TimeZone"), + } + } +} + #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub enum Ddl { CreateTable { @@ -98,6 +121,15 @@ pub enum Ddl { name: SmolStr, timeout: Decimal, }, + SetParam { + scope_type: SetParamScopeType, + param_value: SetParamValue, + timeout: Decimal, + }, + // TODO: Fill with actual values. + SetTransaction { + timeout: Decimal, + }, } impl Ddl { @@ -111,6 +143,8 @@ impl Ddl { | Ddl::DropTable { ref timeout, .. } | Ddl::CreateIndex { ref timeout, .. } | Ddl::DropIndex { ref timeout, .. } + | Ddl::SetParam { ref timeout, .. } + | Ddl::SetTransaction { ref timeout, .. } | Ddl::CreateProc { ref timeout, .. } | Ddl::DropProc { ref timeout, .. } | Ddl::RenameRoutine { ref timeout, .. } => timeout, -- GitLab