MySQL 源码|25 - 句法解析:StartTransactionParser 解析器

MySQL 源码 - 25|StartTransactionParser 解析器

源码位置:(版本 = MySQL 8.0.37)

前置文档:MySQL 源码|SQLParser 类及其子类

StartTransactionParser 解析器

StartTransactionParser 解析器主要解析 START TRANSACTION 语句、BEGIN WORK 语句和 BEGIN 语句。、

StartTransactionParser 解析方法的函数原型如下:

stdx::expected<std::variant<std::monostate, StartTransaction>, std::string>
StartTransactionParser::parse()

这个函数的返回值为将 std::variant<std::monostate, StartTransaction> 作为预期值的 stdx::expected 类型。

START TRANSACTION 开头

当 SQL 以 START 开头时,若下一个 token 不是 TRANSACTION,则返回预期值为空空结果 {}

若 SQL 以 START TRANSACTION 开头,则执行如下逻辑:

Step 1|尝试解析 WITH CONSISTENT SNAPSHOTREAD ONLYREAD WRITE,如果匹配不到则返回不满足预期的字符串。

stdx::expected<std::variant<std::monostate, StartTransaction::AccessMode, bool>,
               std::string>
StartTransactionParser::transaction_characteristics() {
  if (accept(WITH)) {
    if (accept(CONSISTENT_SYM)) {
      if (accept(SNAPSHOT_SYM)) {
        return true;
      }
      return stdx::make_unexpected(
          "after WITH CONSISTENT only SNAPSHOT is allowed.");
    }
    return stdx::make_unexpected("after WITH only CONSISTENT is allowed.");
  }

  if (accept(READ_SYM)) {
    if (accept(ONLY_SYM)) {
      return StartTransaction::AccessMode::ReadOnly;
    }
    if (accept(WRITE_SYM)) {
      return StartTransaction::AccessMode::ReadWrite;
    }
    return stdx::make_unexpected("after READ only ONLY|WRITE are allowed.");
  }

  return {};
}

Step 2|不断解析每个逗号之间的 token,直至无法匹配跳出循环或匹配结果异常返回不满足预期的字符串。

      do {
        auto trx_characteristics_res = transaction_characteristics();
        if (!trx_characteristics_res) {
          return stdx::make_unexpected(
              "You have an error in your SQL syntax; " +
              trx_characteristics_res.error());
        }

        auto trx_characteristics = *trx_characteristics_res;

        if (std::holds_alternative<std::monostate>(trx_characteristics)) {
          // no match.
          break;
        }

        if (std::holds_alternative<bool>(trx_characteristics)) {
          with_consistent_snapshot = true;
        }

        if (std::holds_alternative<StartTransaction::AccessMode>(
                trx_characteristics)) {
          if (access_mode) {
            return stdx::make_unexpected(
                "You have an error in your SQL syntax; START TRANSACTION only "
                "allows one access mode");
          }

          access_mode =
              std::get<StartTransaction::AccessMode>(trx_characteristics);
        }

        if (!accept(',')) break;
      } while (true);

Step 3|如果在匹配完成后,SQL 语句已经结束,则返回预期值为 {std::in_place, StartTransaction{access_mode, with_consistent_snapshot}} 的结果,否则返回不满足预期的字符串。

      if (accept(END_OF_INPUT)) {
        return {std::in_place,
                StartTransaction{access_mode, with_consistent_snapshot}};
      }

      return stdx::make_unexpected(
          "You have an error in your SQL syntax; unexpected input near " +
          to_string(token()));
BEGIN 开头

当 SQL 以 BEGIN 开头时:

  • 若下一个 token 为 WORK,且 WORK 之后 SQL 已经结束,则返回 {std::in_place, StartTransaction{}}
  • 若下一个 token 为 WORK,但 WORK 之后 SQL 没有结束,则返回不满足预期的字符串
  • BEGIN 之后 SQL 已经结束,则返回 {std::in_place, StartTransaction{}}
  • 否则返回不满足预期的字符串
其他 token 开头

当 SQL 不以 STARTBEGIN 开头时,返回预期值为空结果 {}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值