1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

MCOL-4188 Fix regression in a union subquery involving a numeric field.

Since we now perform type promotion to wide decimals for aggregations
involving numeric fields, we need to check for wide decimal in
in and out ROWs and call the appropriate setter and getter functions.
This commit is contained in:
Gagan Goel
2020-11-05 18:09:10 -05:00
committed by Roman Nozdrin
parent 3d7f5c6fd1
commit 6fd7916c56
2 changed files with 83 additions and 17 deletions

View File

@ -534,7 +534,11 @@ dec1:
else
val *= (uint64_t) pow((double) 10, (double) diff);
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);
if (out->getColumnWidth(i) == datatypes::MAXDECIMALWIDTH)
out->setInt128Field(val, i);
else
out->setIntField(val, i);
break;
}
@ -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,7 +1099,18 @@ 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);
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])
@ -1100,6 +1127,24 @@ dec4: /* have to pick a scale to use for the double. using 5... */
case CalpontSystemCatalog::UBIGINT:
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
{
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);
@ -1107,6 +1152,7 @@ dec4: /* have to pick a scale to use for the double. using 5... */
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;
}

View File

@ -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;
}