mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:03:02 +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)`.
|
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
|
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.
|
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
|
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
|
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);
|
GEN_descriptor(dsqlScratch, &desc, true);
|
||||||
|
|
||||||
const USHORT len = static_cast<SSHORT>(s - buf);
|
const USHORT len = static_cast<USHORT>(s - buf);
|
||||||
dsqlScratch->appendUShort(len);
|
dsqlScratch->appendUShort(len);
|
||||||
if (len)
|
if (len)
|
||||||
dsqlScratch->appendBytes(desc.dsc_address, 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 :
|
literal->litDesc.dsc_dtype = numeric_flag == CONSTANT_DOUBLE ? dtype_double :
|
||||||
numeric_flag == CONSTANT_DECIMAL ? dtype_dec128 : dtype_int128;
|
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;
|
literal->litDesc.dsc_scale = scale;
|
||||||
size_t l = strlen(str);
|
size_t l = strlen(str);
|
||||||
if (l > MAX_SSHORT)
|
if (l > MAX_SSHORT)
|
||||||
|
@ -137,28 +137,25 @@ bool CoercionRule::operator==(const CoercionRule& rule) const
|
|||||||
|
|
||||||
bool CoercionRule::match(const dsc* d) const
|
bool CoercionRule::match(const dsc* d) const
|
||||||
{
|
{
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
// check for exact match (taking flags into an account)
|
// check for exact match (taking flags into an account)
|
||||||
if ((!found) &&
|
if ((d->dsc_dtype == fromDsc.dsc_dtype) &&
|
||||||
(d->dsc_dtype == fromDsc.dsc_dtype) &&
|
|
||||||
((d->dsc_length == fromDsc.dsc_length) || (!(fromMask & FLD_has_len))) &&
|
((d->dsc_length == fromDsc.dsc_length) || (!(fromMask & FLD_has_len))) &&
|
||||||
((d->getCharSet() == fromDsc.getCharSet()) || (!(fromMask & FLD_has_chset))) &&
|
((d->getCharSet() == fromDsc.getCharSet()) || (!(fromMask & FLD_has_chset))) &&
|
||||||
((d->getSubType() == fromDsc.getSubType()) || (!(fromMask & FLD_has_sub))) &&
|
((d->getSubType() == fromDsc.getSubType()) || (!(fromMask & FLD_has_sub))) &&
|
||||||
((d->dsc_scale == fromDsc.dsc_scale) || (!(fromMask & FLD_has_scale))))
|
((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
|
// 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)
|
switch(fromDsc.dsc_dtype)
|
||||||
{
|
{
|
||||||
case dtype_dec64:
|
case dtype_dec64:
|
||||||
case dtype_dec128:
|
case dtype_dec128:
|
||||||
if (d->dsc_dtype == dtype_dec64 || d->dsc_dtype == dtype_dec128)
|
if (d->dsc_dtype == dtype_dec64 || d->dsc_dtype == dtype_dec128)
|
||||||
found = true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dtype_short:
|
case dtype_short:
|
||||||
@ -166,12 +163,19 @@ bool CoercionRule::match(const dsc* d) const
|
|||||||
case dtype_int64:
|
case dtype_int64:
|
||||||
case dtype_int128:
|
case dtype_int128:
|
||||||
if (d->isExact() && (fromMask & FLD_has_sub) && (d->dsc_sub_type != dsc_num_type_none))
|
if (d->isExact() && (fromMask & FLD_has_sub) && (d->dsc_sub_type != dsc_num_type_none))
|
||||||
found = true;
|
return true;
|
||||||
break;
|
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
|
bool CoercionRule::coerce(dsc* d) const
|
||||||
|
Loading…
Reference in New Issue
Block a user