介绍
这篇文章主要为大家展示了“MySQL隐式转换的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“MySQL隐式转换的示例分析”这篇文章吧。
<强>一、问题描述强>
root@mysqldb 二二12:,[xucl]祝辞,show create table t1 \ G * * * * * * * * * * * * * * * * * * * * * * * * * * *,1只row * * * * * * * * * * * * * * * * * * * * * * * * * * * ,表:t1 Create 表:,Create TABLE  t1, ( ,“id”varchar (255), DEFAULT NULL ),引擎=InnoDB DEFAULT CHARSET=utf8 1,row set 拷贝;(0.00,sec) , root@mysqldb 22:19: [xucl]祝辞,select *,得到t1; +--------------------+ |,id , | +--------------------+ |,204027026112927605 | |,204027026112927603 | |,2040270261129276 | |,2040270261129275 | |,100,| |,101,| +--------------------+ 6,rows set 拷贝;(0.00,sec)
奇怪的现象:
root@mysqldb 22:19:, [xucl]祝辞,select *,得到t1 where id=204027026112927603; +--------------------+ |,id , | +--------------------+ |,204027026112927605 | |,204027026112927603 | +--------------------+ 2,rows set 拷贝;(0.00,sec) 640年?wx_fmt=jpeg
什么鬼,明明查的是204027026112927603,为什么204027026112927605也出来了
<强>二、源码解释强>
堆栈调用关系如下所示:
其中加入::exec()是执行的入口,Arg_comparator: compare_real()是进行等值判断的函数,其定义如下
int Arg_comparator: compare_real () { ,/* ,Fix yet  another manifestation  of 错误# 2338只& # 39;挥发性# 39;will 指导 用,gcc  flush double  values out of 80 - bit Intel FPU registers 之前 performing 从而比较。 ,*/,volatile double  val1, val2; ,val1=(*)→val_real (); ,if (! (*)→null_value) ,{ ,val2=(* b)→val_real (); ,if (! (* b)→null_value) ,{ ,if (set_null) ,老板→null_value=https://www.yisu.com/zixun/0; 如果(val1null_value=1; 返回1; }
比较步骤如下图所示,逐行读取t1表的id列放入val1,而常量204027026112927603存在于缓存中,类型为两类型(2.0402702611292762 e + 17),所以到这里传值给val2后val2=2.0402702611292762 e + 17。
当扫描到第一行时,204027026112927605转成双的值为2.0402702611292762 e17等式成立,判定为符合条件的行,继续往下扫描,同理204027026112927603也同样符合
如何检测字符串类型的数字转成双类型是否溢出呢?这里经过测试,当数字超过16位以后,转成两类型就已经不准确了,例如20402702611292711会表示成20402702611292712(如图中val1)
MySQL字符串转成双的定义函数如下:
{ ,char 缓冲区(DTOA_BUFF_SIZE); ,double res; ,DBUG_ASSERT(最终获得!=,NULL ,,, ((str !=, NULL ,,, *最终获得!=,NULL), | | ,,,(str ==, NULL ,,, *最终获得==,NULL)),,, error 才能;!=,NULL); ,res=my_strtod_int (str,,,,错误,,但,,sizeof (buf)); ,return (* error ==, 0), ?, res :, (res & lt;, 0, ?, -DBL_MAX :, DBL_MAX); }
真正转换函数my_strtod_int位置在时差。c(太复杂了,简单贴个注释吧)
/* ,strtod for  IEEE - arithmetic 机器。 , ,却;能够strtod returns  a nearest machine number 用,input 小数 ,string (一、sets errno 用EOVERFLOW)只Ties 断开连接;broken by 从而IEEE 人 规则。 , ,Inspired loosely  by William D只克林杰# 39;s paper “请;用Read 浮动 ,Point Numbers Accurately" [Proc只ACM SIGPLAN & # 39; 90年,页只92 - 101]。 , ,修改: , ,1只only 我方表示歉意require IEEE (not IEEE double-extended)。 ,2只get 我方表示歉意by with floating-point arithmetic a case 拷贝 ,Clinger missed ——, when 我们# 39;re computing d * 10 ^ n null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null nullMySQL隐式转换的示例分析