MySQL 源码 - 23|ImplicitCommitParser
的解析方法
源码位置:(版本 = MySQL 8.0.37)
ImplicitCommitParser
解析方法的函数原型如下:
stdx::expected<bool, std::string> ImplicitCommitParser::parse(
std::optional<classic_protocol::session_track::TransactionState>
trx_state)
在函数成员 parse
中,实现了通过解析 SQL 语句中的 token,判断是否需要在事务中隐式提交的逻辑。如果需要隐式提交,则返回 true,否则返回 false。函数接收一个参数,为当前事务的状态 trx_state
。
解析函数的执行逻辑如下:
Step 1|如果当前事务状态 trx_state
为假值,则抛出异常信息的文本。
if (!trx_state) return stdx::unexpected("Expected trx-state to be set.");
Step 2|如果当前事务状态的类型为 _
,即说明不在事务中,不需要提交,直接返回 false。
// no transaction, nothing to commit.
if (trx_state->trx_type() == '_') return false;
Step 3|逐个解析 SQL 语句开头的 token,枚举了 SQL 语句开头的各种关键字组合,并根据关键字组合返回布尔值。具体地:
- 当以
ALTER
开头时,若下一个 token 为EVENT
、FUNCTION
、PROCEDURE
、SERVER
、TABLE
、TABLESPACE
、VIEW
或USER
返回 true,否则返回 false
if (accept(ALTER)) {
if (accept(EVENT_SYM) || //
accept(FUNCTION_SYM) || //
accept(PROCEDURE_SYM) || //
accept(SERVER_SYM) || //
accept(TABLE_SYM) || //
accept(TABLESPACE_SYM) || //
accept(VIEW_SYM) || //
accept(USER) || //
false) {
return true;
}
return false;
}
- 当以
CREATE
或DROP
开头时,若下一个 token 为DATEBASE
、EVENT
、FUNCTION
、INDEX
、PROCEDURE
、ROLE
、SERVER
、SPATIAL
、TABLE
、TABLESPACE
、TRIGGER
、VIEW
、USER
则返回 true,否则返回 false
if (accept(CREATE) || accept(DROP)) {
if (accept(DATABASE) || //
accept(EVENT_SYM) || //
accept(FUNCTION_SYM) || //
accept(INDEX_SYM) || //
accept(PROCEDURE_SYM) || //
accept(ROLE_SYM) || //
accept(SERVER_SYM) || //
accept(SPATIAL_SYM) || //
accept(TABLE_SYM) || //
accept(TABLESPACE_SYM) || //
accept(TRIGGER_SYM) || //
accept(VIEW_SYM) || //
accept(USER) || //
false) {
return true;
}
return false;
}
- 若以
GRANT
、REVOKE
、TRUNCATE
开头,则直接返回 true
if (accept(GRANT) || accept(REVOKE) || accept(TRUNCATE_SYM)) {
return true;
}
- 当以
RENAME
开头时,若下一个 token 为USER
或TABLE
则返回 true,否则返回 false
if (accept(RENAME)) {
if (accept(USER) || accept(TABLE_SYM)) {
return true;
}
return false;
}
- 当以
INSTALL
或UNINSTALL
开头时,若下一个 token 为PLUGIN
则返回 true,否则返回 false
if (accept(INSTALL_SYM) || accept(UNINSTALL_SYM)) {
if (accept(PLUGIN_SYM)) {
return true;
}
return false;
}
- 当以
SET
开头时,若下一个 token 为PASSWORD
则返回 true,否则返回 false
if (accept(SET_SYM)) {
if (accept(PASSWORD)) {
return true;
}
return false;
}
- 当以
BEGIN
开头时,直接返回 true
if (accept(BEGIN_SYM)) {
return true;
}
- 当以
START
开头时,若下一个 token 为TRANSACTION
、REPLICA
或SLAVE
则返回 true,否则返回 false
if (accept(START_SYM)) {
if (accept(TRANSACTION_SYM) || accept(REPLICA_SYM) || accept(SLAVE)) {
return true;
}
return false;
}
- 当以
STOP
开头时,若下一个 token为REPLICA
或SLAVE
则返回 true,否则返回 false
if (accept(STOP_SYM)) {
if (accept(REPLICA_SYM) || accept(SLAVE)) {
return true;
}
return false;
}
- 当以
CHANGE
开头时,若下一个 token 为MASTER
或REPLICATION
则返回 true,否则返回 false
if (accept(CHANGE)) {
if (accept(MASTER_SYM) || accept(REPLICATION)) {
return true;
}
return false;
}
- 当以
LOCK
开头时,若下一个 token 为TABLES
则返回 true,否则返回 false
if (accept(LOCK_SYM)) {
if (accept(TABLES)) {
return true;
}
return false;
}
- 当以
UNLOCK
开头时,若下一个 token 为TABLES
且当前事务中有表正在被锁表时,返回 true,否则返回 false
if (accept(UNLOCK_SYM)) {
if (accept(TABLES)) {
// UNLOCK TABLES only commits if there is a table locked and a transaction
// open.
return trx_state->locked_tables() != '_';
}
return false;
}
- 当以
ANALYZE
开头时,若下一个 token 为TABLE
,则返回 true,否则返回 false
if (accept(ANALYZE_SYM)) {
if (accept(TABLE_SYM)) {
return true;
}
return false;
}
- 当以
CACHE
开头时,若下一个 token 为INDEX
,则返回 true,否则返回 false
if (accept(CACHE_SYM)) {
if (accept(INDEX_SYM)) {
return true;
}
return false;
}
- 当以
CHECK
、OPTIMIZE
或REPAIR
开头时,若下一个 token 为TABLE
,则返回 true,否则返回 false
if (accept(CHECK_SYM) || accept(OPTIMIZE) || accept(REPAIR)) {
if (accept(TABLE_SYM)) {
return true;
}
return false;
}
- 当以
FLUSH
开头时,直接返回 true
if (accept(FLUSH_SYM)) {
return true;
}
- 当以
LOAD
开头时,若之后 3 个 token 依次为INDEX INTO CACHE
时返回 true,否则返回 false
// LOAD INDEX INTO CACHE
if (accept(LOAD)) {
return (accept(INDEX_SYM) && accept(INTO) && accept(CACHE_SYM));
}
- 当以
RESET
开头时,若下一个 token 为PERSIST
则返回 true,否则返回 false
// RESET, except RESET PERSIST
if (accept(RESET_SYM)) {
if (accept(PERSIST_SYM)) {
return false;
}
return true;
}
- 除以上场景外,例如
SELECT
开头的 DQL 语句以及UPDATE
、DELETE
等开头的 DML 语句均返回 false
return false;