国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

解析MySQL隱式轉換問題

2024-07-24 12:41:40
字體:
來源:轉載
供稿:網友

一、問題描述

root@mysqldb 22:12: [xucl]> show create table t1/G*************************** 1. row *************************** Table: t1Create Table: CREATE TABLE `t1` ( `id` varchar(255) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec) root@mysqldb 22:19: [xucl]> select * from t1;+--------------------+| id   |+--------------------+| 204027026112927605 || 204027026112927603 || 2040270261129276 || 2040270261129275 || 100  || 101  |+--------------------+6 rows in set (0.00 sec)

奇怪的現象:

root@mysqldb 22:19: [xucl]> select * from t1 where id=204027026112927603;+--------------------+| id   |+--------------------+| 204027026112927605 || 204027026112927603 |+--------------------+2 rows in set (0.00 sec)640?wx_fmt=jpeg

什么鬼,明明查的是204027026112927603,為什么204027026112927605也出來了

二、源碼解釋

堆棧調用關系如下所示:

其中JOIN::exec()是執行的入口,Arg_comparator::compare_real()是進行等值判斷的函數,其定義如下

int Arg_comparator::compare_real(){ /* Fix yet another manifestation of Bug#2338. 'Volatile' will instruct gcc to flush double values out of 80-bit Intel FPU registers before performing the comparison. */ volatile double val1, val2; val1= (*a)->val_real(); if (!(*a)->null_value) { val2= (*b)->val_real(); if (!(*b)->null_value) { if (set_null) owner->null_value= 0; if (val1 < val2) return -1; if (val1 == val2) return 0; return 1; } } if (set_null) owner->null_value= 1; return -1;}

比較步驟如下圖所示,逐行讀取t1表的id列放入val1,而常量204027026112927603存在于cache中,類型為double類型(2.0402702611292762E+17),所以到這里傳值給val2后val2=2.0402702611292762E+17。

當掃描到第一行時,204027026112927605轉成doule的值為2.0402702611292762e17,等式成立,判定為符合條件的行,繼續往下掃描,同理204027026112927603也同樣符合

如何檢測string類型的數字轉成doule類型是否溢出呢?這里經過測試,當數字超過16位以后,轉成double類型就已經不準確了,例如20402702611292711會表示成20402702611292712(如圖中val1)

MySQL string轉成double的定義函數如下:

{ char buf[DTOA_BUFF_SIZE]; double res; DBUG_ASSERT(end != NULL && ((str != NULL && *end != NULL) ||    (str == NULL && *end == NULL)) &&  error != NULL); res= my_strtod_int(str, end, error, buf, sizeof(buf)); return (*error == 0) ? res : (res < 0 ? -DBL_MAX : DBL_MAX);}

真正轉換函數my_strtod_int位置在dtoa.c(太復雜了,簡單貼個注釋吧)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 高州市| 抚顺市| 松原市| 延川县| 彭水| 铜陵市| 宁乡县| 遂昌县| 教育| 兴国县| 云安县| 资溪县| 湖北省| 琼海市| 娄烦县| 沁阳市| 鞍山市| 嘉义市| 正阳县| 柳江县| 苏州市| 崇明县| 五华县| 浪卡子县| 东乌珠穆沁旗| 云阳县| 曲沃县| 天峻县| 怀化市| 长岛县| 尼勒克县| 宽城| 尚义县| 英山县| 常熟市| 湖北省| 安义县| 雅江县| 临桂县| 宣城市| 鹰潭市|