mz_sql/plan/statement/
tcl.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10//! Transaction control language (TCL).
11//!
12//! This module houses the handlers for statements that manipulate the session's transaction,
13//! like `BEGIN` and `COMMIT`.
14
15use mz_sql_parser::ast::TransactionIsolationLevel;
16
17use crate::ast::{
18    CommitStatement, RollbackStatement, SetTransactionStatement, StartTransactionStatement,
19    TransactionAccessMode, TransactionMode,
20};
21use crate::plan::statement::{StatementContext, StatementDesc};
22use crate::plan::{
23    AbortTransactionPlan, CommitTransactionPlan, Plan, PlanError, SetTransactionPlan,
24    StartTransactionPlan, TransactionType,
25};
26
27pub fn describe_start_transaction(
28    _: &StatementContext,
29    _: StartTransactionStatement,
30) -> Result<StatementDesc, PlanError> {
31    Ok(StatementDesc::new(None))
32}
33
34pub fn plan_start_transaction(
35    _: &StatementContext,
36    StartTransactionStatement { modes }: StartTransactionStatement,
37) -> Result<Plan, PlanError> {
38    let (access, isolation_level) = verify_transaction_modes(modes)?;
39    Ok(Plan::StartTransaction(StartTransactionPlan {
40        access,
41        isolation_level,
42    }))
43}
44
45pub fn describe_set_transaction(
46    _: &StatementContext,
47    _: SetTransactionStatement,
48) -> Result<StatementDesc, PlanError> {
49    Ok(StatementDesc::new(None))
50}
51
52pub fn plan_set_transaction(
53    _: &StatementContext,
54    SetTransactionStatement { local, modes }: SetTransactionStatement,
55) -> Result<Plan, PlanError> {
56    Ok(Plan::SetTransaction(SetTransactionPlan { local, modes }))
57}
58
59fn verify_transaction_modes(
60    modes: Vec<TransactionMode>,
61) -> Result<
62    (
63        Option<TransactionAccessMode>,
64        Option<TransactionIsolationLevel>,
65    ),
66    PlanError,
67> {
68    let mut access = None;
69    let mut isolation = None;
70    for mode in modes {
71        match mode {
72            TransactionMode::IsolationLevel(level) => isolation = Some(level),
73            TransactionMode::AccessMode(mode) => {
74                access = Some(mode);
75            }
76        }
77    }
78    Ok((access, isolation))
79}
80
81pub fn describe_rollback(
82    _: &StatementContext,
83    _: RollbackStatement,
84) -> Result<StatementDesc, PlanError> {
85    Ok(StatementDesc::new(None))
86}
87
88pub fn plan_rollback(
89    _: &StatementContext,
90    RollbackStatement { chain }: RollbackStatement,
91) -> Result<Plan, PlanError> {
92    verify_chain(chain)?;
93    Ok(Plan::AbortTransaction(AbortTransactionPlan {
94        transaction_type: TransactionType::Explicit,
95    }))
96}
97
98pub fn describe_commit(
99    _: &StatementContext,
100    _: CommitStatement,
101) -> Result<StatementDesc, PlanError> {
102    Ok(StatementDesc::new(None))
103}
104
105pub fn plan_commit(
106    _: &StatementContext,
107    CommitStatement { chain }: CommitStatement,
108) -> Result<Plan, PlanError> {
109    verify_chain(chain)?;
110    Ok(Plan::CommitTransaction(CommitTransactionPlan {
111        transaction_type: TransactionType::Explicit,
112    }))
113}
114
115fn verify_chain(chain: bool) -> Result<(), PlanError> {
116    if chain {
117        bail_unsupported!("CHAIN");
118    }
119    Ok(())
120}