mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 16:43:03 +01:00
Fixup some issues with numeric & decimal datatypes
This commit is contained in:
parent
cd78c265d3
commit
a46a3df0fb
@ -24,6 +24,9 @@ When incomplete type definition is used (i.e. `CHAR` instead `CHAR(n)`) in left
|
||||
will take place for all `CHAR` columns, not only default `CHAR(1)`.
|
||||
When incomplete type definiton is used in right side of the statement (TO part) firebird engine will define missing
|
||||
details about that type automatically based on source column.
|
||||
From this statement POV there is no difference between NUMERIC and DECIMAL datatypes. Changing bind of any NUMERIC
|
||||
does not affect appropriate underlying integer type. On contrary, changing bind of integer datatype also affects
|
||||
appropriate NUMERICs.
|
||||
|
||||
Special `TO` part format `LEGACY` is used when datatype, missing in previous FB version, should be represented in
|
||||
a way, understandable by old client software (may be with some data losses). The following coercions are done for
|
||||
|
@ -7449,7 +7449,7 @@ void LiteralNode::genNegZero(DsqlCompilerScratch* dsqlScratch, int prec)
|
||||
|
||||
GEN_descriptor(dsqlScratch, &desc, true);
|
||||
|
||||
const USHORT len = static_cast<SSHORT>(s - buf);
|
||||
const USHORT len = static_cast<USHORT>(s - buf);
|
||||
dsqlScratch->appendUShort(len);
|
||||
if (len)
|
||||
dsqlScratch->appendBytes(desc.dsc_address, len);
|
||||
|
@ -199,6 +199,8 @@ ValueExprNode* MAKE_constant(const char* str, dsql_constant_type numeric_flag, S
|
||||
{
|
||||
literal->litDesc.dsc_dtype = numeric_flag == CONSTANT_DOUBLE ? dtype_double :
|
||||
numeric_flag == CONSTANT_DECIMAL ? dtype_dec128 : dtype_int128;
|
||||
if (numeric_flag == CONSTANT_NUM128)
|
||||
literal->litDesc.dsc_sub_type = dsc_num_type_decimal;
|
||||
literal->litDesc.dsc_scale = scale;
|
||||
size_t l = strlen(str);
|
||||
if (l > MAX_SSHORT)
|
||||
|
@ -137,28 +137,25 @@ bool CoercionRule::operator==(const CoercionRule& rule) const
|
||||
|
||||
bool CoercionRule::match(const dsc* d) const
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
// check for exact match (taking flags into an account)
|
||||
if ((!found) &&
|
||||
(d->dsc_dtype == fromDsc.dsc_dtype) &&
|
||||
if ((d->dsc_dtype == fromDsc.dsc_dtype) &&
|
||||
((d->dsc_length == fromDsc.dsc_length) || (!(fromMask & FLD_has_len))) &&
|
||||
((d->getCharSet() == fromDsc.getCharSet()) || (!(fromMask & FLD_has_chset))) &&
|
||||
((d->getSubType() == fromDsc.getSubType()) || (!(fromMask & FLD_has_sub))) &&
|
||||
((d->dsc_scale == fromDsc.dsc_scale) || (!(fromMask & FLD_has_scale))))
|
||||
{
|
||||
found = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// check for inexact datatype match when FLD_has_len is not set
|
||||
if ((!found) && (!(fromMask & FLD_has_len)))
|
||||
if (!(fromMask & FLD_has_len))
|
||||
{
|
||||
switch(fromDsc.dsc_dtype)
|
||||
{
|
||||
case dtype_dec64:
|
||||
case dtype_dec128:
|
||||
if (d->dsc_dtype == dtype_dec64 || d->dsc_dtype == dtype_dec128)
|
||||
found = true;
|
||||
return true;
|
||||
break;
|
||||
|
||||
case dtype_short:
|
||||
@ -166,12 +163,19 @@ bool CoercionRule::match(const dsc* d) const
|
||||
case dtype_int64:
|
||||
case dtype_int128:
|
||||
if (d->isExact() && (fromMask & FLD_has_sub) && (d->dsc_sub_type != dsc_num_type_none))
|
||||
found = true;
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
// ignore minor decimal/numeric difference
|
||||
if (fromDsc.isExact() && (fromMask & FLD_has_sub) &&
|
||||
(fromDsc.dsc_dtype == d->dsc_dtype) && (d->dsc_sub_type != dsc_num_type_none))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CoercionRule::coerce(dsc* d) const
|
||||
|
Loading…
Reference in New Issue
Block a user