mysql源码:
void Item_func_div::result_precision()
{
uint precision= min(args[0]->decimal_precision() +
args[1]->decimals + prec_increment,
DECIMAL_MAX_PRECISION);
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
if (result_type() == INT_RESULT)
unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
else
unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
unsigned_flag);
}
void Item_func_div::fix_length_and_dec()
{
DBUG_ENTER(“Item_func_div::fix_length_and_dec”);
prec_increment= current_thd->variables.div_precincrement;
Item_num_op::fix_length_and_dec();
switch(hybrid_type) {
case REAL_RESULT:
{
decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
set_if_smaller(decimals, NOT_FIXED_DEC);
uint tmp=float_length(decimals);
if (decimals == NOT_FIXED_DEC)
max_length= tmp;
else
{
max_length=args[0]->max_length - args[0]->decimals + decimals;
set_if_smaller(max_length,tmp);
}
break;
}
case INT_RESULT:
hybrid_type= DECIMAL_RESULT;
DBUG_PRINT(“info”, (“Type changed: DECIMAL_RESULT”));
result_precision();
break;
case DECIMAL_RESULT:
result_precision();
break;
default:
DBUG_ASSERT(0);
}
maybe_null= 1; // devision by zero
DBUG_VOID_RETURN;
}
通过分析以上代码,发现mysql的除法操作结果又三种类型,real_result、 int_result 、decimal_result
prec_increment= current_thd->variables.div_precincrement;
结果的精度precision:
uint precision= min(args[0]->decimal_precision() +
args[1]->decimals + prec_increment,
DECIMAL_MAX_PRECISION);
结果精度scale:
decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
猜测:prec_increment 是为了处理类似字符串这种类型的操作设定的。