diff --git a/dbcon/joblist/tupleunion.cpp b/dbcon/joblist/tupleunion.cpp index 914bd850d..4344109f1 100644 --- a/dbcon/joblist/tupleunion.cpp +++ b/dbcon/joblist/tupleunion.cpp @@ -534,7 +534,11 @@ dec1: else val *= (uint64_t) pow((double) 10, (double) diff); - out->setIntField(val, i); + if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH) + out->setInt128Field(val, i); + else + out->setIntField(val, i); + break; } @@ -661,7 +665,11 @@ dec2: else val *= (uint64_t) pow((double) 10, (double) diff); - out->setIntField(val, i); + if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH) + out->setInt128Field(val, i); + else + out->setIntField(val, i); + break; } @@ -979,7 +987,7 @@ dec2: case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { -dec3: /* have to pick a scale to use for the double. using 5... */ +dec3: /* have to pick a scale to use for the double. using 5... */ uint32_t scale = 5; uint64_t ival = (uint64_t) (double) (val * pow((double) 10, (double) scale)); int diff = out->getScale(i) - scale; @@ -989,7 +997,11 @@ dec3: /* have to pick a scale to use for the double. using 5... */ else ival *= (uint64_t) pow((double) 10, (double) diff); - out->setIntField((int64_t) val, i); + if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH) + out->setInt128Field(ival, i); + else + out->setIntField(ival, i); + break; } @@ -1066,7 +1078,11 @@ dec4: /* have to pick a scale to use for the double. using 5... */ else ival *= (uint64_t) pow((double) 10, (double) diff); - out->setIntField((int64_t) val, i); + if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH) + out->setInt128Field(ival, i); + else + out->setIntField(ival, i); + break; } @@ -1083,8 +1099,19 @@ dec4: /* have to pick a scale to use for the double. using 5... */ case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { - int64_t val = in.getIntField(i); - uint32_t scale = in.getScale(i); + int64_t val; + int128_t val128; + bool isInputWide = false; + + if (in.getColumnWidth(i) == datatypes::MAXDECIMALWIDTH) + { + in.getInt128Field(i, val128); + isInputWide = true; + } + else + val = in.getIntField(i); + + uint32_t scale = in.getScale(i); switch (out->getColTypes()[i]) { @@ -1101,12 +1128,31 @@ dec4: /* have to pick a scale to use for the double. using 5... */ case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { - if (out->getScale(i) == scale) - out->setIntField(val, i); - else if (out->getScale(i) > scale) - out->setIntField(IDB_pow[out->getScale(i) - scale]*val, i); - else // should not happen, the output's scale is the largest - throw logic_error("TupleUnion::normalize(): incorrect scale setting"); + if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH) + { + if (out->getScale(i) == scale) + out->setInt128Field(isInputWide ? val128 : val, i); + else if (out->getScale(i) > scale) + { + int128_t divisor = 1; + datatypes::getScaleDivisor(divisor, out->getScale(i) - scale); + int128_t temp = isInputWide ? divisor*val128 : divisor*val; + out->setInt128Field(temp, i); + } + else // should not happen, the output's scale is the largest + throw logic_error("TupleUnion::normalize(): incorrect scale setting"); + } + // If output type is narrow decimal, input type + // has to be narrow decimal as well. + else + { + if (out->getScale(i) == scale) + out->setIntField(val, i); + else if (out->getScale(i) > scale) + out->setIntField(IDB_pow[out->getScale(i) - scale]*val, i); + else // should not happen, the output's scale is the largest + throw logic_error("TupleUnion::normalize(): incorrect scale setting"); + } break; } diff --git a/utils/dataconvert/dataconvert.cpp b/utils/dataconvert/dataconvert.cpp index 7c416c141..12a766976 100644 --- a/utils/dataconvert/dataconvert.cpp +++ b/utils/dataconvert/dataconvert.cpp @@ -3160,6 +3160,9 @@ DataConvert::joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd &unione unionedType.colDataType = datatypes::SystemCatalog::DECIMAL; } + if (type.precision > unionedType.precision) + unionedType.precision = type.precision; + unionedType.scale = (type.scale > unionedType.scale) ? type.scale : unionedType.scale; break; @@ -3390,7 +3393,6 @@ DataConvert::joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd &unione case datatypes::SystemCatalog::MEDINT: case datatypes::SystemCatalog::INT: case datatypes::SystemCatalog::BIGINT: - case datatypes::SystemCatalog::DECIMAL: case datatypes::SystemCatalog::FLOAT: case datatypes::SystemCatalog::DOUBLE: case datatypes::SystemCatalog::UTINYINT: @@ -3398,7 +3400,6 @@ DataConvert::joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd &unione case datatypes::SystemCatalog::UMEDINT: case datatypes::SystemCatalog::UINT: case datatypes::SystemCatalog::UBIGINT: - case datatypes::SystemCatalog::UDECIMAL: case datatypes::SystemCatalog::UFLOAT: case datatypes::SystemCatalog::UDOUBLE: unionedType.colDataType = datatypes::SystemCatalog::DOUBLE; @@ -3406,6 +3407,16 @@ DataConvert::joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd &unione unionedType.colWidth = sizeof(double); break; + case datatypes::SystemCatalog::DECIMAL: + case datatypes::SystemCatalog::UDECIMAL: + if (unionedType.colWidth != datatypes::MAXDECIMALWIDTH) + { + unionedType.colDataType = datatypes::SystemCatalog::DOUBLE; + unionedType.scale = 0; + unionedType.colWidth = sizeof(double); + } + break; + default: break; } @@ -3446,7 +3457,6 @@ DataConvert::joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd &unione case datatypes::SystemCatalog::MEDINT: case datatypes::SystemCatalog::INT: case datatypes::SystemCatalog::BIGINT: - case datatypes::SystemCatalog::DECIMAL: case datatypes::SystemCatalog::FLOAT: case datatypes::SystemCatalog::DOUBLE: case datatypes::SystemCatalog::UTINYINT: @@ -3454,7 +3464,6 @@ DataConvert::joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd &unione case datatypes::SystemCatalog::UMEDINT: case datatypes::SystemCatalog::UINT: case datatypes::SystemCatalog::UBIGINT: - case datatypes::SystemCatalog::UDECIMAL: case datatypes::SystemCatalog::UFLOAT: case datatypes::SystemCatalog::UDOUBLE: case datatypes::SystemCatalog::LONGDOUBLE: @@ -3464,6 +3473,17 @@ DataConvert::joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd &unione unionedType.precision = -1; break; + case datatypes::SystemCatalog::DECIMAL: + case datatypes::SystemCatalog::UDECIMAL: + if (unionedType.colWidth != datatypes::MAXDECIMALWIDTH) + { + unionedType.colDataType = datatypes::SystemCatalog::LONGDOUBLE; + unionedType.scale = (type.scale > unionedType.scale) ? type.scale : unionedType.scale; + unionedType.colWidth = sizeof(long double); + unionedType.precision = -1; + } + break; + default: break; }