深入理解 MySQL 8 C++ 源碼:SELECT MOD(MONTH(NOW()), 2) 的函數執行過程

MySQL 作為最流行的關系型數據庫之一,其內部實現機制一直是開發者探索的熱點。本文將以一條簡單的 SQL 查詢?SELECT MOD(MONTH(NOW()), 2)?為例,深入分析 MySQL 8 源碼中內置函數?MODMONTH?和?NOW?的執行過程,揭示其底層實現邏輯。


一、SQL 語句的解析與表達式樹構建

當 MySQL 接收到 SQL 查詢時,首先會通過?解析器?將文本轉化為內部的表達式樹結構。對于?MOD(MONTH(NOW()), 2),解析過程如下:

  1. NOW()
    被解析為?Item_func_now?類的實例,負責返回當前時間(datetime?類型)。

  2. MONTH(NOW())
    被解析為?Item_func_month?類的實例,接受?NOW()?的結果作為輸入,提取月份值(整數類型)。

  3. MOD(month_value, 2)
    被解析為?Item_func_mod?類的實例,對?MONTH()?的結果和常量?2?進行取模運算。

最終,這三個函數會形成一個嵌套的表達式樹:
Item_func_mod(Item_func_month(Item_func_now()), 2)


二、關鍵源碼文件與類定義
1.?NOW()?函數的實現
  • 聲明文件sql/item_timefunc.h
    類名:Item_func_now(或其派生類?Item_func_now_local/Item_func_now_utc)。
  • 實現文件sql/item_timefunc.cc
    核心方法?Item_func_now::val_datetime()?負責獲取當前時間。
2.?MONTH()?函數的實現
  • 聲明文件sql/item_timefunc.h
    類名:Item_func_month
  • 實現文件sql/item_timefunc.cc
    核心方法?Item_func_month::val_int()?從日期中提取月份:
     
    longlong Item_func_month::val_int() {MYSQL_TIME ltime;if (get_arg0_date(&ltime, TIME_FUZZY_DATE)) return 0;return ltime.month; // 返回月份(1-12)
    }
3.?MOD()?函數的實現
  • 聲明文件sql/item_func.h
    類名:Item_func_mod
  • 實現文件sql/item_func.cc
    核心方法?Item_func_mod::int_op()?處理整數取模運算:
     
    longlong Item_func_mod::int_op() {longlong val1 = args[0]->val_int(); // 計算 MONTH(NOW())longlong val2 = args[1]->val_int(); // 常量 2if (val2 == 0) return 0; // 避免除零錯誤return val1 % val2;
    }

三、執行流程詳解
1.?解析階段
  • 語法解析器(sql/sql_yacc.yy)將 SQL 字符串轉換為表達式樹。
  • 優化器確定表達式類型(例如?Item::INT_RESULT)。
2.?執行階段
  1. 調用?NOW()
    Item_func_now::val_datetime()?獲取當前時間(例如?2023-10-05 12:34:56)。

  2. 調用?MONTH()
    Item_func_month::val_int()?從?NOW()?的結果中提取月份值(例如?10)。

  3. 調用?MOD()
    Item_func_mod::int_op()?對月份值?10?和?2?取模,最終結果為?0


四、源碼定位技巧

由于代碼行號可能隨版本變化,建議通過以下方式快速定位關鍵代碼:

  1. GitHub 搜索
    訪問?MySQL 8.0 源碼倉庫,搜索?Item_func_mod?或?Item_func_month

  2. 本地代碼搜索

     
    # 在 MySQL 源碼根目錄執行:
    grep -rn 'Item_func_mod' sql/
    grep -rn 'Item_func_month' sql/

五、關鍵設計思想
  1. 表達式樹模型
    MySQL 通過嵌套的?Item?類對象(如?Item_func_mod)表示復雜表達式,支持遞歸求值。

  2. 類型推導與優化
    優化器在預處理階段確定表達式的結果類型(如整數、浮點數),避免運行時類型轉換開銷。

  3. 錯誤處理
    內置函數需處理邊界條件(如?MOD?的除零錯誤),返回合理默認值而非拋出異常,確保查詢穩定性。


六、總結

通過分析?SELECT MOD(MONTH(NOW()), 2)?的執行過程,我們可以深入理解 MySQL 的以下機制:

  • 內置函數的實現:通過?Item_func_*?類封裝邏輯。
  • 表達式求值:遞歸調用?val_int()?或?val_datetime()?方法。
  • 源碼結構:時間函數在?item_timefunc.*,數學函數在?item_func.*

掌握這些底層細節,不僅能幫助開發者調試復雜 SQL,還能為貢獻 MySQL 源碼或定制內置函數奠定基礎。

##MOD函數?gdb調試堆棧

#0  Item_func_mod::int_op (this=0x746cd800e280) at /home/yym/mysql8/mysql-8.1.0/sql/item_func.cc:2616
#1  0x00005591538eda46 in Item_func_numhybrid::val_int (this=0x746cd800e280) at /home/yym/mysql8/mysql-8.1.0/sql/item_func.cc:1740
#2  0x00005591538600cb in Item::send (this=0x746cd800e280, protocol=0x746cd80052c0, buffer=0x746de10f5e20) at /home/yym/mysql8/mysql-8.1.0/sql/item.cc:7483
#3  0x00005591532bf8a0 in THD::send_result_set_row (this=0x746cd8001050, row_items=...) at /home/yym/mysql8/mysql-8.1.0/sql/sql_class.cc:2881
#4  0x0000559153b1ce85 in Query_result_send::send_data (this=0x746cd8010498, thd=0x746cd8001050, items=...) at /home/yym/mysql8/mysql-8.1.0/sql/query_result.cc:102
#5  0x0000559153513ef0 in Query_expression::ExecuteIteratorQuery (this=0x746cd800db40, thd=0x746cd8001050) at /home/yym/mysql8/mysql-8.1.0/sql/sql_union.cc:1785
#6  0x0000559153514181 in Query_expression::execute (this=0x746cd800db40, thd=0x746cd8001050) at /home/yym/mysql8/mysql-8.1.0/sql/sql_union.cc:1823
#7  0x0000559153454cf6 in Sql_cmd_dml::execute_inner (this=0x746cd8010460, thd=0x746cd8001050) at /home/yym/mysql8/mysql-8.1.0/sql/sql_select.cc:1022
#8  0x0000559153454067 in Sql_cmd_dml::execute (this=0x746cd8010460, thd=0x746cd8001050) at /home/yym/mysql8/mysql-8.1.0/sql/sql_select.cc:793
#9  0x00005591533c6841 in mysql_execute_command (thd=0x746cd8001050, first_level=true) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:4797
#10 0x00005591533c8cb3 in dispatch_sql_command (thd=0x746cd8001050, parser_state=0x746de10f79f0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:5447
#11 0x00005591533be0d7 in dispatch_command (thd=0x746cd8001050, com_data=0x746de10f8340, command=COM_QUERY) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:2112
#12 0x00005591533bbf77 in do_command (thd=0x746cd8001050) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:1459
#13 0x0000559153613835 in handle_connection (arg=0x559198b65f80) at /home/yym/mysql8/mysql-8.1.0/sql/conn_handler/connection_handler_per_thread.cc:303
#14 0x0000559155552bdc in pfs_spawn_thread (arg=0x559198b3ec30) at /home/yym/mysql8/mysql-8.1.0/storage/perfschema/pfs.cc:3043
#15 0x0000746df0e94ac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#16 0x0000746df0f26850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

?##MONTH函數 gdb調試堆棧

#0  Item_func_now::get_date (this=0x746cec01b6d0, res=0x746de13fbbd0) at /home/yym/mysql8/mysql-8.1.0/sql/item_timefunc.cc:2108
#1  0x00005591539bcb6d in Item_func::get_arg0_date (this=0x746cec01b7c8, ltime=0x746de13fbbd0, fuzzy_date=1) at /home/yym/mysql8/mysql-8.1.0/sql/item_func.h:510
#2  0x00005591539b1ea2 in Item_func_month::val_int (this=0x746cec01b7c8) at /home/yym/mysql8/mysql-8.1.0/sql/item_timefunc.cc:1268
#3  0x00005591538f1fe0 in Item_func_mod::int_op (this=0x746cec01b990) at /home/yym/mysql8/mysql-8.1.0/sql/item_func.cc:2585
#4  0x00005591538eda46 in Item_func_numhybrid::val_int (this=0x746cec01b990) at /home/yym/mysql8/mysql-8.1.0/sql/item_func.cc:1740
#5  0x00005591538600cb in Item::send (this=0x746cec01b990, protocol=0x746cec012d80, buffer=0x746de13fbe20) at /home/yym/mysql8/mysql-8.1.0/sql/item.cc:7483
#6  0x00005591532bf8a0 in THD::send_result_set_row (this=0x746cec000b90, row_items=...) at /home/yym/mysql8/mysql-8.1.0/sql/sql_class.cc:2881
#7  0x0000559153b1ce85 in Query_result_send::send_data (this=0x746cec01dba8, thd=0x746cec000b90, items=...) at /home/yym/mysql8/mysql-8.1.0/sql/query_result.cc:102
#8  0x0000559153513ef0 in Query_expression::ExecuteIteratorQuery (this=0x746cec01b250, thd=0x746cec000b90) at /home/yym/mysql8/mysql-8.1.0/sql/sql_union.cc:1785
#9  0x0000559153514181 in Query_expression::execute (this=0x746cec01b250, thd=0x746cec000b90) at /home/yym/mysql8/mysql-8.1.0/sql/sql_union.cc:1823
#10 0x0000559153454cf6 in Sql_cmd_dml::execute_inner (this=0x746cec01db70, thd=0x746cec000b90) at /home/yym/mysql8/mysql-8.1.0/sql/sql_select.cc:1022
#11 0x0000559153454067 in Sql_cmd_dml::execute (this=0x746cec01db70, thd=0x746cec000b90) at /home/yym/mysql8/mysql-8.1.0/sql/sql_select.cc:793
#12 0x00005591533c6841 in mysql_execute_command (thd=0x746cec000b90, first_level=true) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:4797
#13 0x00005591533c8cb3 in dispatch_sql_command (thd=0x746cec000b90, parser_state=0x746de13fd9f0) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:5447
#14 0x00005591533be0d7 in dispatch_command (thd=0x746cec000b90, com_data=0x746de13fe340, command=COM_QUERY) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:2112
#15 0x00005591533bbf77 in do_command (thd=0x746cec000b90) at /home/yym/mysql8/mysql-8.1.0/sql/sql_parse.cc:1459
#16 0x0000559153613835 in handle_connection (arg=0x559198b68010) at /home/yym/mysql8/mysql-8.1.0/sql/conn_handler/connection_handler_per_thread.cc:303
#17 0x0000559155552bdc in pfs_spawn_thread (arg=0x559198b689e0) at /home/yym/mysql8/mysql-8.1.0/storage/perfschema/pfs.cc:3043
#18 0x0000746df0e94ac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#19 0x0000746df0f26850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/70358.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70358.shtml
英文地址,請注明出處:http://en.pswp.cn/web/70358.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RNN中遠距離時間步梯度消失問題及解決辦法

RNN中遠距離時間步梯度消失問題及解決辦法 RNN 遠距離時間步梯度消失問題LSTM如何解決遠距離時間步梯度消失問題 RNN 遠距離時間步梯度消失問題 經典的RNN結構如下圖所示&#xff1a; 假設我們的時間序列只有三段&#xff0c; S 0 S_{0} S0? 為給定值&#xff0c;神經元沒有…

Tomcat理論(Ⅰ)

目錄 服務器流程圖一覽 一、JavaWeb前奏(了解) 1. C/S結構 2. B/S結構 3. 靜態網頁&動態網頁 4.常見的網頁 5.Web服務器 知名服務器&#xff1a; ?編輯 二、Tomcat安裝&#xff08;熟練&#xff09; 1.Tomcat概述 2.Tomcat的作用 3.Tomcat安裝 4.Tomcat測試 3.…

如何使用 DeepSeek R1 構建開源 ChatGPT Operator 替代方案

開源大型語言模型&#xff08;LLMs&#xff09;的興起使得創建 AI 驅動的工具比以往任何時候都更容易&#xff0c;這些工具可以與 OpenAI 的 ChatGPT Operator 等專有解決方案相媲美。在這些開源模型中&#xff0c;DeepSeek R1 以其強大的推理能力、自由的可訪問性和適應性而脫…

使用Docker Desktop部署GitLab

1. 環境準備 確保Windows 10/11系統支持虛擬化技術&#xff08;需在BIOS中開啟Intel VT-x/AMD-V&#xff09;內存建議≥8GB&#xff0c;存儲空間≥100GB 2. 安裝Docker Desktop 訪問Docker官網下載安裝包安裝時勾選"Use WSL 2 instead of Hyper-V"&#xff08;推薦…

【復習】Java集合

集合概念 集合與數組 數組是固定長度&#xff1b;集合是動態長度的數據結構&#xff0c;需要動態增加或刪除元素 數組可以包含基本數據類型和對象&#xff1b;集合只能包含對象 數組可以直接訪問元素&#xff1b;集合需要通過迭代器訪問元素 線程安全的集合&#xff1f; …

vue3 文件類型傳Form Data數據格式給后端

在 Vue 3 中&#xff0c;如果你想將文件&#xff08;例如上傳的 Excel 文件&#xff09;以 FormData 格式發送到后端&#xff0c;可以通過以下步驟實現。這種方式通常用于處理文件上傳&#xff0c;因為它可以將文件和其他數據一起發送到服務器。 首先&#xff0c;創建一個 Vue…

使用 INFINI Console 配置集群監控 Webhook 通知指南

在集群管理中&#xff0c;監控關鍵指標如CPU、內存、磁盤、JVM等是至關重要的。對于Easysearch及ES生態系統&#xff0c;還需要關注集群本身的指標&#xff0c;例如搜索延遲、集群狀態、節點移除等。INFINI Console不僅提供了默認的監控指標&#xff0c;還支持用戶自定義監控項…

WPF的頁面設計和實用功能實現

目錄 一、TextBlock和TextBox 1. 在TextBlock中實時顯示當前時間 二、ListView 1.ListView顯示數據 三、ComboBox 1. ComboBox和CheckBox組合實現下拉框多選 四、Button 1. 設計Button按鈕的邊框為圓角&#xff0c;并對指針懸停時的顏色進行設置 一、TextBlock和TextBox…

二級公共基礎之數據結構與算法篇(八)排序技術

目錄 前言 一、交換類排序 1.冒泡排序法 1. 冒泡排序的思想 2. 冒泡排序的實現步驟 3. 示例 4. 冒泡排序的特點 2.快速排序 1. 快速排序的核心思想 2. 快速排序的實現步驟 3. 示例代碼(C語言) 4. 快速排序的特點 二、插入類排序 1. 簡單插入排序 1.簡單插入排…

記錄一次 ALG 的處理過程

前幾天朋友找我幫忙&#xff0c;說碰到很大困難了&#xff0c;實際上&#xff0c;不過如此 現象是這樣的&#xff1a; FreeSWITCH mod_unimrcp 工作不正常 FS 和 mrcp-server 兩邊同時抓包&#xff0c;看到的是&#xff1a; sip 流程正常 FS TCP 連接到 mccp-server 失敗&…

【Linux網絡編程】IP協議格式,解包步驟

目錄 解析步驟 1.版本字段&#xff08;大小&#xff1a;4比特位&#xff09; 2.首部長度&#xff08;大小&#xff1a;4比特位&#xff09;&#xff08;單位&#xff1a;4字節&#xff09; &#x1f35c;細節解釋&#xff1a; 3.服務類型&#xff08;大小&#xff1a;8比特…

CSDN文章質量分查詢系統【贈python爬蟲、提分攻略】

CSDN文章質量分查詢系統 https://www.csdn.net/qc 點擊鏈接-----> CSDN文章質量分查詢系統 <------點擊鏈接 點擊鏈接-----> https://www.csdn.net/qc <------點擊鏈接 點擊鏈接-----> CSDN文章質量分查詢系統 <------點擊鏈接 點擊鏈…

HTML應用指南:利用GET請求獲取全國瀘溪河門店位置信息

隨著新零售業態的快速發展,門店位置信息的獲取變得越來越重要。作為新興烘焙品牌之一,瀘溪河自2013年在南京創立以來,一直堅持“健康美味,香飄世界”的企業使命,以匠人精神打造新中式糕點。為了更好地理解和利用這些數據,本篇文章將深入探討GET請求的實際應用,并展示如何…

如何在 React 中測試高階組件?

在 React 中測試高階組件可以采用多種策略&#xff0c;以下是常見的測試方法&#xff1a; 1. 測試高階組件返回的組件 高階組件本身是一個函數&#xff0c;它返回一個新的組件。因此&#xff0c;可以通過測試這個返回的組件來間接測試高階組件的功能。通常使用 Jest 作為測試…

R語言Stan貝葉斯空間條件自回歸CAR模型分析死亡率多維度數據可視化

全文鏈接&#xff1a;https://tecdat.cn/?p40424 在空間數據分析領域&#xff0c;準確的模型和有效的工具對于研究人員至關重要。本文為區域數據的貝葉斯模型分析提供了一套完整的工作流程&#xff0c;基于Stan這一先進的貝葉斯建模平臺構建&#xff0c;幫助客戶為空間分析帶來…

Casbin 權限管理介紹及在 Go 語言中的使用入門

引言 在現代軟件開發過程中&#xff0c;權限管理是一個至關重要的環節&#xff0c;它關系到系統的安全性和用戶體驗。Casbin 是一個強大的訪問控制庫&#xff0c;支持多種訪問控制模型&#xff0c;如 ACL&#xff08;訪問控制列表&#xff09;、RBAC&#xff08;基于角色的訪問…

快速入門——第三方組件element-ui

學習自嗶哩嗶哩上的“劉老師教編程”&#xff0c;具體學習的網站為&#xff1a;10.第三方組件element-ui_嗶哩嗶哩_bilibili&#xff0c;以下是看課后做的筆記&#xff0c;僅供參考。 第一節 組件間的傳值 組件可以有內部Data提供數據&#xff0c;也可由父組件通過prop方式傳…

【算法通關村 Day7】遞歸與二叉樹遍歷

遞歸與二叉樹遍歷青銅挑戰 理解遞歸 遞歸算法是指一個方法在其執行過程中調用自身。它通常用于將一個問題分解為更小的子問題&#xff0c;通過重復調用相同的方法來解決這些子問題&#xff0c;直到達到基準情況&#xff08;終止條件&#xff09;。 遞歸算法通常包括兩個主要…

樸素貝葉斯法

文章目錄 貝葉斯定理樸素貝葉斯法的學習與分類條件獨立假設樸素貝葉斯的后驗概率最大化準則樸素貝葉斯的基本公式 樸素貝葉斯法的參數估計極大似然估計 貝葉斯定理 前置知識&#xff1a;條件概率、全概率、貝葉斯公式 推薦視頻&#xff0c;看完視頻后搜索博客了解先驗概率、后…

《A++ 敏捷開發》- 20 從 AI 到最佳設計

“我們現在推行AIGC&#xff0c;服務端不需要UI交互設計的用AI自動產出代碼&#xff0c;你建議的結對編程、TDD等是否還適用&#xff1f;” 這兩年AI確實很火&#xff0c;是報紙、雜志的熱門話題。例如&#xff0c;HBR雜志從2024年9月至2025年二月份3期&#xff0c;里面有接近一…