0
点赞
收藏
分享

微信扫一扫

NOT_FIXED_DEC详解

_刘彦辉 2023-06-16 阅读 31


宏,等于31

来源

There is a “magic” number for precision : NOT_FIXED_DEC.
This means that the precision is not a fixed number.

⬆️摘自:https://bugs.mysql.com/bug.php?id=33544

The number of decimal digits to the right of the decimal point. The default value is the maximum number of decimal digits in the arguments passed to the main function. For example, if the function is passed 1.34, 1.345, and 1.3, the default would be 3, because 1.345 has 3 decimal digits.

For arguments that have no fixed number of decimals, the decimals value is set to 31, which is 1 more than the maximum number of decimals permitted for the DECIMAL, FLOAT, and DOUBLE data types. As of MySQL 5.5.3, this value is available as the constant NOT_FIXED_DEC in the mysql_com.h header file.

A decimals value of 31 is used for arguments in cases such as a FLOAT or DOUBLE column declared without an explicit number of decimals (for example, FLOAT rather than FLOAT(10,3)) and for floating-point constants such as 1345E-3. It is also used for string and other nonnumber arguments that might be converted within the function to numeric form.

The value to which the decimals member is initialized is only a default. It can be changed within the function to reflect the actual calculation performed. The default is determined such that the largest number of decimals of the arguments is used. If the number of decimals is NOT_FIXED_DEC for even one of the arguments, that is the value used for decimals.

⬆️摘自:http://docs.oracle.com/cd/E17952_01/refman-5.5-en/udf-calling.html

上面有一句很重要,说明了NOT_FIXED_DEC为什么取值为31:

the decimals value is set to 31, which is 1 more than the maximum number of decimals permitted for the DECIMAL, FLOAT, and DOUBLE data types

做个实验:

mysql> create table tf (x decimal(33,31));
ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.

Ooops…

The fact that an Item has a not fixed number of decimal digits
is currently stored in Item::decimals as a special value
NOT_FIXED_DEC (31).

We should stop using decimal==NOT_FIXED_DEC for that purposes,
and introduce a new virtual method “bool NOT_FIXED_DEC()” instead.
This should help to avoid bugs like MDEV-4511
when NOT_FIXED_DEC is erroneously treated as “normal”
number of decimals.

Also, there is currently no a way to get the real number of
decimals from an Item if decimals=NOT_FIXED_DEC, which
makes calculating decimal precision and scale hard in
fix_length_and_dec() of some items.

⬆️ 摘自: https://mariadb.atlassian.net/browse/MDEV-6346

用途

先看几个例子,分别执行下面的SQL:

mysql> select 1.3e1;
mysql> select 'hi';

他们的meta结果中,decimal都是NOT_FIXED_DEC。

mysql> select 'hi';
Field   1:  `hi`
Catalog:    `def`
Database:   ``
Table:      ``
Org_table:  ``
Type:       VAR_STRING
Collation:  utf8_general_ci (33)
Length:     6
Max_length: 2
Decimals:   31
Flags:      NOT_NULL


+----+
| hi |
+----+
| hi |
+----+
1 row in set (0.01 sec)

mysql> select 1.3e1;
Field   1:  `1.3e1`
Catalog:    `def`
Database:   ``
Table:      ``
Org_table:  ``
Type:       DOUBLE
Collation:  binary (63)
Length:     5
Max_length: 2
Decimals:   31
Flags:      NOT_NULL BINARY NUM


+-------+
| 1.3e1 |
+-------+
|    13 |
+-------+
1 row in set (0.00 sec)

推论

其实,并不一定必须用31,用-1也是可以的,反正是一个Magic Number,不会直接参与加减运算。
阅读MySQL源码的时候,可能看到类似这样的比较:

if (decimals >= NOT_FIXED_DEC) { ... }

它只是一种防御性编程的写法,实际等价于:

if (decimals == NOT_FIXED_DEC) { ... }


举报

相关推荐

0 条评论