use mz_sql_parser::ast::TransactionIsolationLevel;
use crate::ast::{
CommitStatement, RollbackStatement, SetTransactionStatement, StartTransactionStatement,
TransactionAccessMode, TransactionMode,
};
use crate::plan::statement::{StatementContext, StatementDesc};
use crate::plan::{
AbortTransactionPlan, CommitTransactionPlan, Plan, PlanError, SetTransactionPlan,
StartTransactionPlan, TransactionType,
};
pub fn describe_start_transaction(
_: &StatementContext,
_: StartTransactionStatement,
) -> Result<StatementDesc, PlanError> {
Ok(StatementDesc::new(None))
}
pub fn plan_start_transaction(
_: &StatementContext,
StartTransactionStatement { modes }: StartTransactionStatement,
) -> Result<Plan, PlanError> {
let (access, isolation_level) = verify_transaction_modes(modes)?;
Ok(Plan::StartTransaction(StartTransactionPlan {
access,
isolation_level,
}))
}
pub fn describe_set_transaction(
_: &StatementContext,
_: SetTransactionStatement,
) -> Result<StatementDesc, PlanError> {
Ok(StatementDesc::new(None))
}
pub fn plan_set_transaction(
_: &StatementContext,
SetTransactionStatement { local, modes }: SetTransactionStatement,
) -> Result<Plan, PlanError> {
Ok(Plan::SetTransaction(SetTransactionPlan { local, modes }))
}
fn verify_transaction_modes(
modes: Vec<TransactionMode>,
) -> Result<
(
Option<TransactionAccessMode>,
Option<TransactionIsolationLevel>,
),
PlanError,
> {
let mut access = None;
let mut isolation = None;
for mode in modes {
match mode {
TransactionMode::IsolationLevel(level) => isolation = Some(level),
TransactionMode::AccessMode(mode) => {
access = Some(mode);
}
}
}
Ok((access, isolation))
}
pub fn describe_rollback(
_: &StatementContext,
_: RollbackStatement,
) -> Result<StatementDesc, PlanError> {
Ok(StatementDesc::new(None))
}
pub fn plan_rollback(
_: &StatementContext,
RollbackStatement { chain }: RollbackStatement,
) -> Result<Plan, PlanError> {
verify_chain(chain)?;
Ok(Plan::AbortTransaction(AbortTransactionPlan {
transaction_type: TransactionType::Explicit,
}))
}
pub fn describe_commit(
_: &StatementContext,
_: CommitStatement,
) -> Result<StatementDesc, PlanError> {
Ok(StatementDesc::new(None))
}
pub fn plan_commit(
_: &StatementContext,
CommitStatement { chain }: CommitStatement,
) -> Result<Plan, PlanError> {
verify_chain(chain)?;
Ok(Plan::CommitTransaction(CommitTransactionPlan {
transaction_type: TransactionType::Explicit,
}))
}
fn verify_chain(chain: bool) -> Result<(), PlanError> {
if chain {
bail_unsupported!("CHAIN");
}
Ok(())
}