diff --git a/dbcon/execplan/aggregatecolumn.cpp b/dbcon/execplan/aggregatecolumn.cpp index c996dad17..bf46fafd5 100644 --- a/dbcon/execplan/aggregatecolumn.cpp +++ b/dbcon/execplan/aggregatecolumn.cpp @@ -498,6 +498,14 @@ void AggregateColumn::evaluate(Row& row, bool& isNull) break; + case CalpontSystemCatalog::LONGDOUBLE: + if (row.equals(LONGDOUBLENULL, fInputIndex)) + isNull = true; + else + fResult.longDoubleVal = row.getLongDoubleField(fInputIndex); + + break; + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: switch (fResultType.colWidth) diff --git a/dbcon/execplan/calpontsystemcatalog.cpp b/dbcon/execplan/calpontsystemcatalog.cpp index 7b75c15a9..0b4fe4fce 100644 --- a/dbcon/execplan/calpontsystemcatalog.cpp +++ b/dbcon/execplan/calpontsystemcatalog.cpp @@ -155,6 +155,10 @@ const string colDataTypeToString(CalpontSystemCatalog::ColDataType cdt) return "double"; break; + case CalpontSystemCatalog::LONGDOUBLE: + return "long double"; + break; + case CalpontSystemCatalog::DATETIME: return "datetime"; break; diff --git a/dbcon/execplan/calpontsystemcatalog.h b/dbcon/execplan/calpontsystemcatalog.h index 7b828a297..e56872b84 100644 --- a/dbcon/execplan/calpontsystemcatalog.h +++ b/dbcon/execplan/calpontsystemcatalog.h @@ -76,6 +76,8 @@ const float MAX_FLOAT __attribute__ ((unused)) = std::numeric_limits::ma const float MIN_FLOAT __attribute__ ((unused)) = -std::numeric_limits::max(); const double MAX_DOUBLE __attribute__ ((unused)) = std::numeric_limits::max(); //1.7976931348623157e+308 const double MIN_DOUBLE __attribute__ ((unused)) = -std::numeric_limits::max(); +const long double MAX_LONGDOUBLE __attribute__ ((unused)) = std::numeric_limits::max(); //1.7976931348623157e+308 +const long double MIN_LONGDOUBLE __attribute__ ((unused)) = -std::numeric_limits::max(); const uint64_t AUTOINCR_SATURATED __attribute__ ((unused)) = std::numeric_limits::max(); diff --git a/dbcon/execplan/constantcolumn.cpp b/dbcon/execplan/constantcolumn.cpp index dd112600e..60d99580d 100644 --- a/dbcon/execplan/constantcolumn.cpp +++ b/dbcon/execplan/constantcolumn.cpp @@ -51,7 +51,7 @@ ConstantColumn::ConstantColumn(const string& sql, TYPE type) : fData(sql) { fResult.strVal = sql; - + if (type == LITERAL && sql.length() < 9) { memcpy(tmp, sql.c_str(), sql.length()); @@ -67,6 +67,7 @@ ConstantColumn::ConstantColumn(const string& sql, TYPE type) : fResult.floatVal = atof(sql.c_str()); fResult.doubleVal = atof(sql.c_str()); + fResult.longDoubleVal = strtold(sql.c_str(), NULL); // decimal for constant should be constructed by the caller and call the decimal constructor fResult.decimalVal.value = fResult.intVal; @@ -105,6 +106,27 @@ ConstantColumn::ConstantColumn(const string& sql, const double val) : fResult.intVal = (int64_t)val; fResult.uintVal = (uint64_t)val; fResult.floatVal = (float)val; + fResult.longDoubleVal = val; + // decimal for constant should be constructed by the caller and call the decimal constructor + fResult.decimalVal.value = fResult.intVal; + fResult.decimalVal.scale = 0; + fResult.decimalVal.precision = 18; + fResultType.colDataType = CalpontSystemCatalog::DOUBLE; + fResultType.colWidth = 8; +} + +ConstantColumn::ConstantColumn(const string& sql, const long double val) : + ReturnedColumn(), + fConstval(sql), + fType(NUM), + fData(sql) +{ + fResult.strVal = sql; + fResult.doubleVal = (double)val; + fResult.intVal = (int64_t)val; + fResult.uintVal = (uint64_t)val; + fResult.floatVal = (float)val; + fResult.longDoubleVal = val; // decimal for constant should be constructed by the caller and call the decimal constructor fResult.decimalVal.value = fResult.intVal; fResult.decimalVal.scale = 0; @@ -124,6 +146,7 @@ ConstantColumn::ConstantColumn(const string& sql, const int64_t val, TYPE type) fResult.uintVal = (uint64_t)fResult.intVal; fResult.floatVal = (float)fResult.intVal; fResult.doubleVal = (double)fResult.intVal; + fResult.longDoubleVal = (long double)fResult.intVal; fResult.decimalVal.value = fResult.intVal; fResult.decimalVal.scale = 0; fResultType.colDataType = CalpontSystemCatalog::BIGINT; @@ -141,6 +164,7 @@ ConstantColumn::ConstantColumn(const string& sql, const uint64_t val, TYPE type) fResult.intVal = (int64_t)fResult.uintVal; fResult.floatVal = (float)fResult.uintVal; fResult.doubleVal = (double)fResult.uintVal; + fResult.longDoubleVal = (long double)fResult.uintVal; fResult.decimalVal.value = fResult.uintVal; fResult.decimalVal.scale = 0; fResultType.colDataType = CalpontSystemCatalog::UBIGINT; @@ -158,6 +182,7 @@ ConstantColumn::ConstantColumn(const string& sql, const IDB_Decimal& val) : fResult.uintVal = strtoull(sql.c_str(), NULL, 0); fResult.floatVal = atof(sql.c_str()); fResult.doubleVal = atof(sql.c_str()); + fResult.longDoubleVal = strtold(sql.c_str(), NULL); fResult.decimalVal = val; fResultType.colDataType = CalpontSystemCatalog::DECIMAL; fResultType.colWidth = 8; @@ -201,6 +226,7 @@ ConstantColumn::ConstantColumn(const int64_t val, TYPE type) : fResult.uintVal = (uint64_t)fResult.intVal; fResult.floatVal = (float)fResult.intVal; fResult.doubleVal = (double)fResult.intVal; + fResult.longDoubleVal = (long double)fResult.intVal; fResult.decimalVal.value = fResult.intVal; fResult.decimalVal.scale = 0; fResultType.colDataType = CalpontSystemCatalog::BIGINT; @@ -220,6 +246,7 @@ ConstantColumn::ConstantColumn(const uint64_t val, TYPE type) : fResult.uintVal = val; fResult.floatVal = (float)fResult.uintVal; fResult.doubleVal = (double)fResult.uintVal; + fResult.longDoubleVal = (long double)fResult.uintVal; fResult.decimalVal.value = fResult.uintVal; fResult.decimalVal.scale = 0; fResultType.colDataType = CalpontSystemCatalog::UBIGINT; @@ -281,13 +308,15 @@ void ConstantColumn::serialize(messageqcpp::ByteStream& b) const b << static_cast(fReturnAll); b << (uint64_t)fResult.intVal; b << fResult.uintVal; - b << (*(uint64_t*)(&fResult.doubleVal)); - b << (*(uint32_t*)(&fResult.floatVal)); + b << fResult.doubleVal; + b << fResult.longDoubleVal; + b << fResult.floatVal; b << (uint8_t)fResult.boolVal; b << fResult.strVal; b << (uint64_t)fResult.decimalVal.value; b << (uint8_t)fResult.decimalVal.scale; b << (uint8_t)fResult.decimalVal.precision; + b << fResult.longDoubleVal; } void ConstantColumn::unserialize(messageqcpp::ByteStream& b) @@ -303,8 +332,9 @@ void ConstantColumn::unserialize(messageqcpp::ByteStream& b) b >> reinterpret_cast< ByteStream::doublebyte&>(fReturnAll); b >> (uint64_t&)fResult.intVal; b >> fResult.uintVal; - b >> (uint64_t&)fResult.doubleVal; - b >> (uint32_t&)fResult.floatVal; + b >> fResult.doubleVal; + b >> fResult.longDoubleVal; + b >> fResult.floatVal; b >> (uint8_t&)fResult.boolVal; b >> fResult.strVal; b >> (uint64_t&)fResult.decimalVal.value; diff --git a/dbcon/execplan/constantcolumn.h b/dbcon/execplan/constantcolumn.h index be0731044..e19abb364 100644 --- a/dbcon/execplan/constantcolumn.h +++ b/dbcon/execplan/constantcolumn.h @@ -200,6 +200,10 @@ public: * ctor */ ConstantColumn(const std::string& sql, const double val); + /** + * ctor + */ + ConstantColumn(const std::string& sql, const long double val); /** * ctor */ diff --git a/dbcon/execplan/simplecolumn.cpp b/dbcon/execplan/simplecolumn.cpp index 1d7780e33..c95f7ac1e 100644 --- a/dbcon/execplan/simplecolumn.cpp +++ b/dbcon/execplan/simplecolumn.cpp @@ -592,6 +592,12 @@ void SimpleColumn::evaluate(Row& row, bool& isNull) break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + fResult.longDoubleVal = row.getLongDoubleField(fInputIndex); + break; + } + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { diff --git a/dbcon/execplan/treenode.h b/dbcon/execplan/treenode.h index d43239563..126d7ee6c 100644 --- a/dbcon/execplan/treenode.h +++ b/dbcon/execplan/treenode.h @@ -249,6 +249,7 @@ struct Result // when converting origIntVal uint64_t dummy; double doubleVal; + long double longDoubleVal; float floatVal; bool boolVal; std::string strVal; @@ -376,6 +377,10 @@ public: { return fResult.doubleVal; } + virtual long double getLongDoubleVal(rowgroup::Row& row, bool& isNull) + { + return fResult.longDoubleVal; + } virtual IDB_Decimal getDecimalVal(rowgroup::Row& row, bool& isNull) { return fResult.decimalVal; @@ -517,6 +522,9 @@ inline bool TreeNode::getBoolVal() case CalpontSystemCatalog::UDOUBLE: return (fResult.doubleVal != 0); + case CalpontSystemCatalog::LONGDOUBLE: + return (fResult.longDoubleVal != 0); + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: return (fResult.decimalVal.value != 0); @@ -646,6 +654,40 @@ inline const std::string& TreeNode::getStrVal() fResult.strVal += tmp; } +// snprintf(tmp, 312, "%e", fResult.doubleVal); +// fResult.strVal = tmp; + } + + break; + } + + case CalpontSystemCatalog::LONGDOUBLE: + { + if ((fabsl(fResult.longDoubleVal) > (1.0 / IDB_pow[13])) && + (fabsl(fResult.longDoubleVal) < (float) IDB_pow[15])) + { + snprintf(tmp, 312, "%Lf", fResult.longDoubleVal); + fResult.strVal = removeTrailing0(tmp, 312); + } + else + { + // MCOL-299 Print scientific with 9 mantissa and no + sign for exponent + int exponent = (int)floorl(log10( fabsl(fResult.longDoubleVal))); // This will round down the exponent + long double base = fResult.longDoubleVal * pow(10, -1.0 * exponent); + + if (isnan(exponent) || isnan(base)) + { + snprintf(tmp, 312, "%Lf", fResult.longDoubleVal); + fResult.strVal = removeTrailing0(tmp, 312); + } + else + { + snprintf(tmp, 312, "%.14Lf", base); + fResult.strVal = removeTrailing0(tmp, 312); + snprintf(tmp, 312, "e%02d", exponent); + fResult.strVal += tmp; + } + // snprintf(tmp, 312, "%e", fResult.doubleVal); // fResult.strVal = tmp; } @@ -736,6 +778,9 @@ inline int64_t TreeNode::getIntVal() case CalpontSystemCatalog::UDOUBLE: return (int64_t)fResult.doubleVal; + case CalpontSystemCatalog::LONGDOUBLE: + return (int64_t)fResult.longDoubleVal; + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { @@ -779,6 +824,9 @@ inline uint64_t TreeNode::getUintVal() case CalpontSystemCatalog::UDOUBLE: return (uint64_t)fResult.doubleVal; + case CalpontSystemCatalog::LONGDOUBLE: + return (uint64_t)fResult.longDoubleVal; + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { @@ -843,6 +891,9 @@ inline float TreeNode::getFloatVal() case CalpontSystemCatalog::UDOUBLE: return (float)fResult.doubleVal; + case CalpontSystemCatalog::LONGDOUBLE: + return (float)fResult.doubleVal; + case CalpontSystemCatalog::DECIMAL: { return (fResult.decimalVal.value / pow((double)10, fResult.decimalVal.scale)); @@ -978,6 +1029,9 @@ inline IDB_Decimal TreeNode::getDecimalVal() case CalpontSystemCatalog::UDOUBLE: throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: non-support conversion from double unsigned"); + case CalpontSystemCatalog::LONGDOUBLE: + throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: non-support conversion from long double"); + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: return fResult.decimalVal; diff --git a/dbcon/execplan/windowfunctioncolumn.cpp b/dbcon/execplan/windowfunctioncolumn.cpp index b1377880f..cad99215a 100644 --- a/dbcon/execplan/windowfunctioncolumn.cpp +++ b/dbcon/execplan/windowfunctioncolumn.cpp @@ -583,6 +583,16 @@ void WindowFunctionColumn::evaluate(Row& row, bool& isNull) break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + if (row.equals(LONGDOUBLENULL, fInputIndex)) + isNull = true; + else + fResult.longDoubleVal = row.getLongDoubleField(fInputIndex); + + break; + } + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { diff --git a/dbcon/joblist/groupconcat.cpp b/dbcon/joblist/groupconcat.cpp index afc91a2ec..f74782d49 100644 --- a/dbcon/joblist/groupconcat.cpp +++ b/dbcon/joblist/groupconcat.cpp @@ -488,6 +488,12 @@ void GroupConcator::outputRow(std::ostringstream& oss, const rowgroup::Row& row) break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + oss << setprecision(15) << row.getLongDoubleField(*i); + break; + } + case CalpontSystemCatalog::FLOAT: case CalpontSystemCatalog::UFLOAT: { @@ -632,6 +638,7 @@ int64_t GroupConcator::lengthEstimate(const rowgroup::Row& row) case CalpontSystemCatalog::UDOUBLE: case CalpontSystemCatalog::FLOAT: case CalpontSystemCatalog::UFLOAT: + case CalpontSystemCatalog::LONGDOUBLE: { fieldLen = 1; // minimum length break; diff --git a/dbcon/joblist/jlf_common.cpp b/dbcon/joblist/jlf_common.cpp index 4b1980d49..9579aad60 100644 --- a/dbcon/joblist/jlf_common.cpp +++ b/dbcon/joblist/jlf_common.cpp @@ -838,6 +838,17 @@ bool compatibleColumnTypes(const CalpontSystemCatalog::ColDataType& dt1, uint32_ break; + case CalpontSystemCatalog::LONGDOUBLE: + if (forJoin && (dt2 != CalpontSystemCatalog::LONGDOUBLE)) + return false; + else if (dt2 != CalpontSystemCatalog::FLOAT && + dt2 != CalpontSystemCatalog::DOUBLE && + dt2 != CalpontSystemCatalog::UFLOAT && + dt2 != CalpontSystemCatalog::UDOUBLE && + dt2 != CalpontSystemCatalog::LONGDOUBLE) return false; + + break; + default: return false; break; diff --git a/dbcon/joblist/joblisttypes.h b/dbcon/joblist/joblisttypes.h index 37d52f9f4..2174f3002 100644 --- a/dbcon/joblist/joblisttypes.h +++ b/dbcon/joblist/joblisttypes.h @@ -25,6 +25,7 @@ #include #include +#include namespace joblist { @@ -51,6 +52,7 @@ const uint32_t FLOATNULL = 0xFFAAAAAA; const uint32_t FLOATEMPTYROW = 0xFFAAAAAB; const uint64_t DOUBLENULL = 0xFFFAAAAAAAAAAAAAULL; const uint64_t DOUBLEEMPTYROW = 0xFFFAAAAAAAAAAAABULL; +const long double LONGDOUBLENULL = nanl(""); const uint32_t DATENULL = 0xFFFFFFFE; const uint32_t DATEEMPTYROW = 0xFFFFFFFF; diff --git a/dbcon/joblist/tupleaggregatestep.cpp b/dbcon/joblist/tupleaggregatestep.cpp index 4c1893115..61768dfd3 100644 --- a/dbcon/joblist/tupleaggregatestep.cpp +++ b/dbcon/joblist/tupleaggregatestep.cpp @@ -266,6 +266,9 @@ inline string colTypeIdString(CalpontSystemCatalog::ColDataType type) case CalpontSystemCatalog::DOUBLE: return string("DOUBLE"); + case CalpontSystemCatalog::LONGDOUBLE: + return string("LONGDOUBLE"); + case CalpontSystemCatalog::DATETIME: return string("DATETIME"); diff --git a/dbcon/joblist/tupleconstantstep.cpp b/dbcon/joblist/tupleconstantstep.cpp index 309bb0058..4e3eb670d 100644 --- a/dbcon/joblist/tupleconstantstep.cpp +++ b/dbcon/joblist/tupleconstantstep.cpp @@ -250,6 +250,12 @@ void TupleConstantStep::constructContanstRow(const JobInfo& jobInfo) break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + fRowConst.setLongDoubleField(c.longDoubleVal, *i); + break; + } + case CalpontSystemCatalog::CHAR: case CalpontSystemCatalog::VARCHAR: case CalpontSystemCatalog::TEXT: diff --git a/dbcon/joblist/tupleunion.cpp b/dbcon/joblist/tupleunion.cpp index d0892e45f..d23a9d4d9 100644 --- a/dbcon/joblist/tupleunion.cpp +++ b/dbcon/joblist/tupleunion.cpp @@ -510,6 +510,22 @@ void TupleUnion::normalize(const Row& in, Row* out) break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + int scale = in.getScale(i); + + if (scale != 0) + { + long double d = in.getIntField(i); + d /= (uint64_t) pow(10.0, scale); + out->setLongDoubleField(d, i); + } + else + out->setLongDoubleField(in.getIntField(i), i); + + break; + } + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { @@ -620,6 +636,22 @@ dec1: break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + int scale = in.getScale(i); + + if (scale != 0) + { + long double d = in.getUintField(i); + d /= (uint64_t) pow(10.0, scale); + out->setLongDoubleField(d, i); + } + else + out->setLongDoubleField(in.getUintField(i), i); + + break; + } + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { @@ -804,6 +836,10 @@ dec2: out->setDoubleField(val, i); break; + case CalpontSystemCatalog::LONGDOUBLE: + out->setLongDoubleField(val, i); + break; + case CalpontSystemCatalog::CHAR: case CalpontSystemCatalog::TEXT: case CalpontSystemCatalog::VARCHAR: @@ -842,6 +878,83 @@ dec3: /* have to pick a scale to use for the double. using 5... */ break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + long double val = in.getLongDoubleField(i); + + switch (out->getColTypes()[i]) + { + case CalpontSystemCatalog::TINYINT: + case CalpontSystemCatalog::SMALLINT: + case CalpontSystemCatalog::MEDINT: + case CalpontSystemCatalog::INT: + case CalpontSystemCatalog::BIGINT: + if (out->getScale(i)) + goto dec4; + + out->setIntField((int64_t) val, i); + break; + + case CalpontSystemCatalog::UTINYINT: + case CalpontSystemCatalog::USMALLINT: + case CalpontSystemCatalog::UMEDINT: + case CalpontSystemCatalog::UINT: + case CalpontSystemCatalog::UBIGINT: + out->setUintField((uint64_t) val, i); + break; + + case CalpontSystemCatalog::FLOAT: + case CalpontSystemCatalog::UFLOAT: + out->setFloatField(val, i); + break; + + case CalpontSystemCatalog::DOUBLE: + case CalpontSystemCatalog::UDOUBLE: + out->setDoubleField(val, i); + break; + + case CalpontSystemCatalog::LONGDOUBLE: + out->setLongDoubleField(val, i); + break; + + case CalpontSystemCatalog::CHAR: + case CalpontSystemCatalog::TEXT: + case CalpontSystemCatalog::VARCHAR: + { + ostringstream os; + os.precision(15); // to match mysql's output + os << val; + out->setStringField(os.str(), i); + break; + } + + case CalpontSystemCatalog::DECIMAL: + case CalpontSystemCatalog::UDECIMAL: + { +dec4: /* 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; + + if (diff < 0) + ival /= (uint64_t) pow((double) 10, (double) - diff); + else + ival *= (uint64_t) pow((double) 10, (double) diff); + + out->setIntField((int64_t) val, i); + break; + } + + default: + ostringstream os; + os << "TupleUnion::normalize(): tried an illegal conversion: floating point to " + << out->getColTypes()[i]; + throw logic_error(os.str()); + } + + break; + } + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { @@ -882,12 +995,20 @@ dec3: /* have to pick a scale to use for the double. using 5... */ } case CalpontSystemCatalog::DOUBLE: + case CalpontSystemCatalog::UDOUBLE: { double dval = ((double) val) / IDB_pow[scale]; out->setDoubleField(dval, i); break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + long double dval = ((long double) val) / IDB_pow[scale]; + out->setLongDoubleField(dval, i); + break; + } + case CalpontSystemCatalog::CHAR: case CalpontSystemCatalog::TEXT: case CalpontSystemCatalog::VARCHAR: diff --git a/dbcon/mysql/ha_calpont_dml.cpp b/dbcon/mysql/ha_calpont_dml.cpp index 43bdc8cd6..3860f6d5e 100644 --- a/dbcon/mysql/ha_calpont_dml.cpp +++ b/dbcon/mysql/ha_calpont_dml.cpp @@ -1173,6 +1173,20 @@ int ha_calpont_impl_write_batch_row_(uchar* buf, TABLE* table, cal_impl_if::cal_ break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr, "%c", ci.delimiter); + else + { + fprintf(ci.filePtr, "%.15Lg%c", *((long double*)buf), ci.delimiter); + //printf("%.15g|", *((double*)buf)); + } + + buf += 8; + break; + } + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 914743a25..83be3c650 100644 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -4499,7 +4499,11 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) isp->sum_func() == Item_sum::AVG_DISTINCT_FUNC) { CalpontSystemCatalog::ColType ct = parm->resultType(); + ct.colDataType = CalpontSystemCatalog::LONGDOUBLE; + ct.scale += 4; +// ct.colWidth = 8; +#if 0 switch (ct.colDataType) { case CalpontSystemCatalog::TINYINT: @@ -4514,13 +4518,9 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) case CalpontSystemCatalog::UMEDINT: case CalpontSystemCatalog::UINT: case CalpontSystemCatalog::UBIGINT: - ct.colDataType = CalpontSystemCatalog::DECIMAL; - ct.colWidth = 8; ct.scale += 4; break; -#if PROMOTE_FLOAT_TO_DOUBLE_ON_SUM - case CalpontSystemCatalog::FLOAT: case CalpontSystemCatalog::UFLOAT: case CalpontSystemCatalog::DOUBLE: @@ -4528,12 +4528,11 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) ct.colDataType = CalpontSystemCatalog::DOUBLE; ct.colWidth = 8; break; -#endif default: break; } - +#endif ac->resultType(ct); } else if (isp->sum_func() == Item_sum::COUNT_FUNC || @@ -4549,7 +4548,9 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) isp->sum_func() == Item_sum::SUM_DISTINCT_FUNC) { CalpontSystemCatalog::ColType ct = parm->resultType(); - + ct.colDataType = CalpontSystemCatalog::LONGDOUBLE; + ct.scale += 4; +#if 0 switch (ct.colDataType) { case CalpontSystemCatalog::TINYINT: @@ -4589,7 +4590,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) default: break; } - +#endif ac->resultType(ct); } else if (isp->sum_func() == Item_sum::STD_FUNC || diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index 3be44d2b8..0a633fe1c 100644 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -703,6 +703,41 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h //break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + double dl = row.getLongDoubleField(s); + + if (dl == std::numeric_limits::infinity()) + continue; + + Field_double* f2 = (Field_double*)*f; + // bug 3483, reserve enough space for the longest double value + // -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and + // 2.2250738585072014E-308 to 1.7976931348623157E+308. + (*f)->field_length = 310; + + //double double_val = *(double*)(&value); + //f2->store(double_val); + if ((f2->decimals() == DECIMAL_NOT_SPECIFIED && row.getScale(s) > 0) + || f2->decimals() < row.getScale(s)) + { + f2->dec = row.getScale(s); + } + + f2->store(dl); + + if ((*f)->null_ptr) + *(*f)->null_ptr &= ~(*f)->null_bit; + + break; + + + //int64_t* icvp = (int64_t*)&dl; + //intColVal = *icvp; + //storeNumericField(f, intColVal, colType); + //break; + } + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { diff --git a/dbcon/mysql/ha_calpont_partition.cpp b/dbcon/mysql/ha_calpont_partition.cpp index 038c668c9..a4eca3212 100644 --- a/dbcon/mysql/ha_calpont_partition.cpp +++ b/dbcon/mysql/ha_calpont_partition.cpp @@ -190,6 +190,9 @@ string name(CalpontSystemCatalog::ColType& ct) case CalpontSystemCatalog::UDOUBLE: return "UDOUBLE"; + case CalpontSystemCatalog::LONGDOUBLE: + return "LONGDOUBLE"; + default: return "Unknown Type"; } diff --git a/utils/dataconvert/dataconvert.cpp b/utils/dataconvert/dataconvert.cpp index 1d196a436..7614385b5 100644 --- a/utils/dataconvert/dataconvert.cpp +++ b/utils/dataconvert/dataconvert.cpp @@ -871,7 +871,7 @@ bool mysql_str_to_datetime( const string& input, DateTime& output, bool& isDate bool mysql_str_to_time( const string& input, Time& output, long decimals ) { - int32_t datesepct = 0; +// int32_t datesepct = 0; uint32_t dtend = 0; bool isNeg = false; @@ -2995,6 +2995,7 @@ CalpontSystemCatalog::ColType DataConvert::convertUnionColType(vector 20) ? types[i].colWidth : 20; break; diff --git a/utils/funcexp/func_between.cpp b/utils/funcexp/func_between.cpp index f23d67826..05ea8be3a 100644 --- a/utils/funcexp/func_between.cpp +++ b/utils/funcexp/func_between.cpp @@ -196,6 +196,24 @@ inline bool getBool(rowgroup::Row& row, numericLE(val, pm[2]->data()->getDoubleVal(row, isNull)); } + case execplan::CalpontSystemCatalog::LONGDOUBLE: + { + long double val = pm[0]->data()->getLongDoubleVal(row, isNull); + + if (notBetween) + { + if (!numericGE(val, pm[1]->data()->getLongDoubleVal(row, isNull)) && !isNull) + return true; + + isNull = false; + return (!numericLE(val, pm[2]->data()->getLongDoubleVal(row, isNull)) && !isNull); + } + + return !isNull && + numericGE(val, pm[1]->data()->getLongDoubleVal(row, isNull)) && + numericLE(val, pm[2]->data()->getLongDoubleVal(row, isNull)); + } + case execplan::CalpontSystemCatalog::DECIMAL: case execplan::CalpontSystemCatalog::UDECIMAL: { diff --git a/utils/funcexp/func_ceil.cpp b/utils/funcexp/func_ceil.cpp index 7c2f7f571..f270ed641 100644 --- a/utils/funcexp/func_ceil.cpp +++ b/utils/funcexp/func_ceil.cpp @@ -123,6 +123,12 @@ int64_t Func_ceil::getIntVal(Row& row, } break; + case CalpontSystemCatalog::LONGDOUBLE: + { + ret = (int64_t) ceill(parm[0]->data()->getLongDoubleVal(row, isNull)); + } + break; + case CalpontSystemCatalog::VARCHAR: case CalpontSystemCatalog::CHAR: case CalpontSystemCatalog::TEXT: diff --git a/utils/funcexp/func_hex.cpp b/utils/funcexp/func_hex.cpp index 83106a9be..9bf35b125 100644 --- a/utils/funcexp/func_hex.cpp +++ b/utils/funcexp/func_hex.cpp @@ -103,6 +103,21 @@ string Func_hex::getStrVal(rowgroup::Row& row, break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + char buf[256]; + long double val = parm[0]->data()->getLongDoubleVal(row, isNull); + +#ifdef _MSC_VER + sprintf(buf, "%llA", val); + +#else + sprintf(buf, "%LA", val); +#endif + retval = buf; + break; + } + case CalpontSystemCatalog::VARBINARY: case CalpontSystemCatalog::BLOB: { diff --git a/utils/funcexp/func_substring_index.cpp b/utils/funcexp/func_substring_index.cpp index cf1395759..7266960d6 100644 --- a/utils/funcexp/func_substring_index.cpp +++ b/utils/funcexp/func_substring_index.cpp @@ -61,7 +61,7 @@ std::string Func_substring_index::getStrVal(rowgroup::Row& row, if (isNull) return ""; - int64_t count = fp[2]->data()->getIntVal(row, isNull); + size_t count = fp[2]->data()->getIntVal(row, isNull); if (isNull) return ""; @@ -71,7 +71,7 @@ std::string Func_substring_index::getStrVal(rowgroup::Row& row, size_t end = strlen(str.c_str()); - if ( count > (int64_t) end ) + if ( count > end ) return str; if (( count < 0 ) && ((count * -1) > end)) @@ -83,7 +83,7 @@ std::string Func_substring_index::getStrVal(rowgroup::Row& row, { int pointer = 0; - for ( int i = 0 ; i < count ; i ++ ) + for ( size_t i = 0 ; i < count ; i ++ ) { string::size_type pos = str.find(delim, pointer); @@ -102,13 +102,13 @@ std::string Func_substring_index::getStrVal(rowgroup::Row& row, int pointer = end; int start = 0; - for ( int i = 0 ; i < count ; i ++ ) + for ( size_t i = 0 ; i < count ; i ++ ) { string::size_type pos = str.rfind(delim, pointer); if (pos != string::npos) { - if ( count > (int64_t) end ) + if ( count > end ) return ""; pointer = pos - 1; diff --git a/utils/funcexp/funcexp.cpp b/utils/funcexp/funcexp.cpp index 53f7da595..9751eabd5 100644 --- a/utils/funcexp/funcexp.cpp +++ b/utils/funcexp/funcexp.cpp @@ -439,6 +439,18 @@ void FuncExp::evaluate(rowgroup::Row& row, std::vector& expressi break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + long double val = expression[i]->getLongDoubleVal(row, isNull); + + if (isNull) + row.setLongDoubleField(LONGDOUBLENULL, expression[i]->outputIndex()); + else + row.setLongDoubleField(val, expression[i]->outputIndex()); + + break; + } + case CalpontSystemCatalog::DECIMAL: case CalpontSystemCatalog::UDECIMAL: { diff --git a/utils/funcexp/functor_str.h b/utils/funcexp/functor_str.h index 8b6c10404..820228848 100644 --- a/utils/funcexp/functor_str.h +++ b/utils/funcexp/functor_str.h @@ -57,6 +57,14 @@ public: return strtod(getStrVal(row, fp, isNull, op_ct).c_str(), NULL); } + double getLongDoubleVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct) + { + return strtold(getStrVal(row, fp, isNull, op_ct).c_str(), NULL); + } + #if 0 std::string getStrVal(rowgroup::Row& row, FunctionParm& fp, @@ -105,12 +113,16 @@ protected: // Bug3788, use the shorter of fixed or scientific notation for floating point values. // [ the default format in treenode.h is fixed-point notation ] char buf[20]; - double floatVal; - int exponent; - double base; + long double floatVal; + int64_t exponent; + long double base; switch (fp->data()->resultType().colDataType) { + case execplan::CalpontSystemCatalog::LONGDOUBLE: + floatVal = fp->data()->getLongDoubleVal(row, isNull); + break; + case execplan::CalpontSystemCatalog::DOUBLE: floatVal = fp->data()->getDoubleVal(row, isNull); break; @@ -125,19 +137,19 @@ protected: break; } - exponent = (int)floor(log10( fabs(floatVal))); + exponent = (int)floor(log10( fabsl(floatVal))); base = floatVal * pow(10, -1.0 * exponent); if (isnan(exponent) || isnan(base)) { - snprintf(buf, 20, "%f", floatVal); + snprintf(buf, 20, "%Lf", floatVal); fFloatStr = execplan::removeTrailing0(buf, 20); } else { - snprintf(buf, 20, "%.5f", base); + snprintf(buf, 20, "%.5Lf", base); fFloatStr = execplan::removeTrailing0(buf, 20); - snprintf(buf, 20, "e%02d", exponent); + snprintf(buf, 20, "e%02ld", exponent); fFloatStr += buf; } diff --git a/utils/joiner/joinpartition.cpp b/utils/joiner/joinpartition.cpp index 962143aac..7d0af1d26 100644 --- a/utils/joiner/joinpartition.cpp +++ b/utils/joiner/joinpartition.cpp @@ -118,7 +118,6 @@ JoinPartition::JoinPartition(const JoinPartition& jp, bool splitMode) : totalBytesWritten(0), maxLargeSize(0), maxSmallSize(0), nextSmallOffset(0), nextLargeOffset(0) { - config::Config* config = config::Config::makeConfig(); boost::posix_time::ptime t; ostringstream os; diff --git a/utils/messageqcpp/bytestream.cpp b/utils/messageqcpp/bytestream.cpp index ec471be8f..edd184ddb 100644 --- a/utils/messageqcpp/bytestream.cpp +++ b/utils/messageqcpp/bytestream.cpp @@ -636,6 +636,18 @@ ByteStream& ByteStream::operator<<(const double d) return *this; } +ByteStream& ByteStream::operator<<(const long double d) +{ + int sz = sizeof(long double); + + if (fBuf == 0 || (fCurInPtr - fBuf + sz > fMaxLen + ISSOverhead)) + growBuf(fMaxLen + BlockSize); + + *((long double*) fCurInPtr) = d; + fCurInPtr += sz; + + return *this; +} ByteStream& ByteStream::operator>>(float& f) { peek(f); @@ -648,6 +660,12 @@ ByteStream& ByteStream::operator>>(double& d) fCurOutPtr += sizeof(double); return *this; } +ByteStream& ByteStream::operator>>(long double& d) +{ + peek(d); + fCurOutPtr += sizeof(long double); + return *this; +} void ByteStream::peek(float& f) const { if (length() < sizeof(float)) @@ -663,6 +681,14 @@ void ByteStream::peek(double& d) const d = *((double*) fCurOutPtr); } +void ByteStream::peek(long double& d) const +{ + if (length() < sizeof(long double)) + throw underflow_error("ByteStream>int64_t: not enough data in stream to fill datatype"); + + d = *((long double*) fCurOutPtr); +} + }//namespace messageqcpp diff --git a/utils/messageqcpp/bytestream.h b/utils/messageqcpp/bytestream.h index f8453843e..4b47c8593 100644 --- a/utils/messageqcpp/bytestream.h +++ b/utils/messageqcpp/bytestream.h @@ -153,6 +153,11 @@ public: * whatever the native byte order is. */ EXPORT ByteStream& operator<<(const double d); + /** + * push a long double onto the end of the stream. The byte + * order is whatever the native byte order is. + */ + EXPORT ByteStream& operator<<(const long double d); /** * push a std::string onto the end of the stream. */ @@ -212,6 +217,11 @@ public: * order is whatever the native byte order is. */ EXPORT ByteStream& operator>>(double& d); + /** + * extract a long double from the front of the stream. The byte + * order is whatever the native byte order is. + */ + EXPORT ByteStream& operator>>(long double& d); /** * extract a std::string from the front of the stream. */ @@ -277,6 +287,11 @@ public: * order is whatever the native byte order is. */ EXPORT void peek(double& f) const; + /** + * Peek at a long double from the front of the stream. The byte + * order is whatever the native byte order is. + */ + EXPORT void peek(long double& f) const; /** * Peek at a std::string from the front of the stream. */ diff --git a/utils/rowgroup/rowgroup.cpp b/utils/rowgroup/rowgroup.cpp index 3411f6fa6..5d5308ba7 100644 --- a/utils/rowgroup/rowgroup.cpp +++ b/utils/rowgroup/rowgroup.cpp @@ -702,6 +702,9 @@ void Row::initToNull() *((uint64_t*) &data[offsets[i]]) = joblist::DOUBLENULL; break; + case CalpontSystemCatalog::LONGDOUBLE: + *((long double*) &data[offsets[i]]) = joblist::LONGDOUBLENULL; + case CalpontSystemCatalog::DATETIME: *((uint64_t*) &data[offsets[i]]) = joblist::DATETIMENULL; break; @@ -804,13 +807,6 @@ void Row::initToNull() *((uint64_t*) &data[offsets[i]]) = joblist::UBIGINTNULL; break; - case CalpontSystemCatalog::LONGDOUBLE: - { - // no NULL value for long double yet, this is a nan. - memset(&data[offsets[i]], 0xFF, getColumnWidth(i)); - break; - } - default: ostringstream os; os << "Row::initToNull(): got bad column type (" << types[i] << @@ -956,7 +952,7 @@ bool Row::isNullValue(uint32_t colIndex) const return (*((uint64_t*) &data[offsets[colIndex]]) == joblist::UBIGINTNULL); case CalpontSystemCatalog::LONGDOUBLE: - // return false; // no NULL value for long double yet + return (*((long double*) &data[offsets[colIndex]]) == joblist::LONGDOUBLENULL); break; default: diff --git a/utils/rowgroup/rowgroup.h b/utils/rowgroup/rowgroup.h index ca05360c2..1c3618735 100644 --- a/utils/rowgroup/rowgroup.h +++ b/utils/rowgroup/rowgroup.h @@ -330,6 +330,7 @@ public: template inline int64_t getIntField(uint32_t colIndex) const; inline int64_t getIntField(uint32_t colIndex) const; template inline bool equals(uint64_t val, uint32_t colIndex) const; + inline bool equals(long double val, uint32_t colIndex) const; inline bool equals(const std::string& val, uint32_t colIndex) const; inline double getDoubleField(uint32_t colIndex) const; @@ -616,6 +617,11 @@ inline bool Row::equals(uint64_t val, uint32_t colIndex) const } } +inline bool Row::equals(long double val, uint32_t colIndex) const +{ + return *((long double*) &data[offsets[colIndex]]) == val; +} + inline bool Row::equals(const std::string& val, uint32_t colIndex) const { if (inStringTable(colIndex)) diff --git a/utils/windowfunction/idborderby.cpp b/utils/windowfunction/idborderby.cpp index db5cdf1c1..f839bc506 100644 --- a/utils/windowfunction/idborderby.cpp +++ b/utils/windowfunction/idborderby.cpp @@ -174,7 +174,6 @@ int DoubleCompare::operator()(IdbCompare* l, Row::Pointer r1, Row::Pointer r2) return ret; } - int FloatCompare::operator()(IdbCompare* l, Row::Pointer r1, Row::Pointer r2) { l->row1().setData(r1); @@ -206,6 +205,37 @@ int FloatCompare::operator()(IdbCompare* l, Row::Pointer r1, Row::Pointer r2) return ret; } +int LongDoubleCompare::operator()(IdbCompare* l, Row::Pointer r1, Row::Pointer r2) +{ + l->row1().setData(r1); + l->row2().setData(r2); + + bool b1 = l->row1().isNullValue(fSpec.fIndex); + bool b2 = l->row2().isNullValue(fSpec.fIndex); + + int ret = 0; + + if (b1 == true || b2 == true) + { + if (b1 == false && b2 == true) + ret = fSpec.fNf; + else if (b1 == true && b2 == false) + ret = -fSpec.fNf; + } + else + { + long double v1 = l->row1().getLongDoubleField(fSpec.fIndex); + long double v2 = l->row2().getLongDoubleField(fSpec.fIndex); + + if (v1 > v2) + ret = fSpec.fAsc; + else if (v1 < v2) + ret = -fSpec.fAsc; + } + + return ret; +} + bool CompareRule::less(Row::Pointer r1, Row::Pointer r2) { @@ -279,6 +309,13 @@ void CompareRule::compileRules(const std::vector& spec, const rowgr break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + Compare* c = new LongDoubleCompare(*i); + fCompares.push_back(c); + break; + } + case CalpontSystemCatalog::DATE: case CalpontSystemCatalog::DATETIME: case CalpontSystemCatalog::TIME: @@ -442,6 +479,12 @@ bool EqualCompData::operator()(Row::Pointer a, Row::Pointer b) break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + eq = (fRow1.getLongDoubleField(*i) == fRow2.getLongDoubleField(*i)); + break; + } + default: { eq = false; diff --git a/utils/windowfunction/idborderby.h b/utils/windowfunction/idborderby.h index a432fdc31..cd31eff30 100644 --- a/utils/windowfunction/idborderby.h +++ b/utils/windowfunction/idborderby.h @@ -119,6 +119,14 @@ public: int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer); }; +class LongDoubleCompare : public Compare +{ +public: + LongDoubleCompare(const IdbSortSpec& spec) : Compare(spec) {} + + int operator()(IdbCompare*, rowgroup::Row::Pointer, rowgroup::Row::Pointer); +}; + class FloatCompare : public Compare { diff --git a/utils/windowfunction/wf_lead_lag.cpp b/utils/windowfunction/wf_lead_lag.cpp index 5160b75bf..961032f2f 100644 --- a/utils/windowfunction/wf_lead_lag.cpp +++ b/utils/windowfunction/wf_lead_lag.cpp @@ -90,6 +90,12 @@ boost::shared_ptr WF_lead_lag::makeFunction(int id, const break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + func.reset(new WF_lead_lag(id, name)); + break; + } + case CalpontSystemCatalog::FLOAT: case CalpontSystemCatalog::UFLOAT: { diff --git a/utils/windowfunction/wf_min_max.cpp b/utils/windowfunction/wf_min_max.cpp index b0c1fe033..8679c743b 100644 --- a/utils/windowfunction/wf_min_max.cpp +++ b/utils/windowfunction/wf_min_max.cpp @@ -96,6 +96,12 @@ boost::shared_ptr WF_min_max::makeFunction(int id, const break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + func.reset(new WF_min_max(id, name)); + break; + } + default: { func.reset(new WF_min_max(id, name)); diff --git a/utils/windowfunction/wf_percentile.cpp b/utils/windowfunction/wf_percentile.cpp index 83d6f57d8..b3e56c17a 100644 --- a/utils/windowfunction/wf_percentile.cpp +++ b/utils/windowfunction/wf_percentile.cpp @@ -102,6 +102,12 @@ boost::shared_ptr WF_percentile::makeFunction(int id, con break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + func.reset(new WF_percentile(id, name)); + break; + } + default: { if (id == WF__PERCENTILE_DISC) @@ -140,6 +146,7 @@ boost::shared_ptr WF_percentile::makeFunction(int id, con case CalpontSystemCatalog::UDOUBLE: case CalpontSystemCatalog::FLOAT: case CalpontSystemCatalog::UFLOAT: + case CalpontSystemCatalog::LONGDOUBLE: { func.reset(new WF_percentile(id, name)); break; diff --git a/utils/windowfunction/wf_stats.cpp b/utils/windowfunction/wf_stats.cpp index 3599271d4..b5af19883 100644 --- a/utils/windowfunction/wf_stats.cpp +++ b/utils/windowfunction/wf_stats.cpp @@ -96,6 +96,12 @@ boost::shared_ptr WF_stats::makeFunction(int id, const st break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + func.reset(new WF_stats(id, name)); + break; + } + default: { string errStr = name + "(" + colType2String[ct] + ")"; diff --git a/utils/windowfunction/wf_sum_avg.cpp b/utils/windowfunction/wf_sum_avg.cpp index 15586da3b..07d671c66 100644 --- a/utils/windowfunction/wf_sum_avg.cpp +++ b/utils/windowfunction/wf_sum_avg.cpp @@ -159,7 +159,7 @@ template boost::shared_ptr WF_sum_avg::makeFunction(int id, const string& name, int ct) { boost::shared_ptr func; - +#if 0 switch (ct) { case CalpontSystemCatalog::TINYINT: @@ -198,6 +198,35 @@ boost::shared_ptr WF_sum_avg::makeFunction(int id, const break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + func.reset(new WF_sum_avg(id, name)); + break; + } +#endif + switch (ct) + { + case CalpontSystemCatalog::TINYINT: + case CalpontSystemCatalog::SMALLINT: + case CalpontSystemCatalog::MEDINT: + case CalpontSystemCatalog::INT: + case CalpontSystemCatalog::BIGINT: + case CalpontSystemCatalog::DECIMAL: + case CalpontSystemCatalog::UTINYINT: + case CalpontSystemCatalog::USMALLINT: + case CalpontSystemCatalog::UMEDINT: + case CalpontSystemCatalog::UINT: + case CalpontSystemCatalog::UBIGINT: + case CalpontSystemCatalog::UDECIMAL: + case CalpontSystemCatalog::DOUBLE: + case CalpontSystemCatalog::UDOUBLE: + case CalpontSystemCatalog::FLOAT: + case CalpontSystemCatalog::UFLOAT: + case CalpontSystemCatalog::LONGDOUBLE: + { + func.reset(new WF_sum_avg(id, name)); + break; + } default: { string errStr = name + "(" + colType2String[ct] + ")"; diff --git a/utils/windowfunction/wf_udaf.cpp b/utils/windowfunction/wf_udaf.cpp index 91ae5f9b2..250f3fc42 100644 --- a/utils/windowfunction/wf_udaf.cpp +++ b/utils/windowfunction/wf_udaf.cpp @@ -398,6 +398,48 @@ bool WF_udaf::dropValues(int64_t b, int64_t e) break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + double valIn; + + if (cc) + { + valIn = cc->getLongDoubleVal(fRow, isNull); + } + else + { + getValue(colIn, valIn); + } + + // Check for distinct, if turned on. + // Currently, distinct only works on the first parameter. + if (k == 0) + { + if (fDistinct) + { + DistinctMap::iterator distinct; + distinct = fDistinctMap.find(valIn); + if (distinct != fDistinctMap.end()) + { + // This is a duplicate: decrement the count + --(*distinct).second; + if ((*distinct).second > 0) // still more of these + { + bSkipIt = true; + continue; + } + else + { + fDistinctMap.erase(distinct); + } + } + } + } + + datum.columnData = valIn; + break; + } + case CalpontSystemCatalog::CHAR: case CalpontSystemCatalog::VARCHAR: case CalpontSystemCatalog::VARBINARY: @@ -971,6 +1013,38 @@ void WF_udaf::operator()(int64_t b, int64_t e, int64_t c) break; } + case CalpontSystemCatalog::LONGDOUBLE: + { + long double valIn; + + if (cc) + { + valIn = cc->getLongDoubleVal(fRow, isNull); + } + else + { + getValue(colIn, valIn); + } + + // Check for distinct, if turned on. + // Currently, distinct only works on the first parameter. + if (k == 0 && fDistinct) + { + std::pair val = make_pair(valIn, 1); + std::pair distinct; + distinct = fDistinctMap.insert(val); + if (distinct.second == false) + { + ++(*distinct.first).second; + bSkipIt = true; + continue; + } + } + + datum.columnData = valIn; + break; + } + case CalpontSystemCatalog::CHAR: case CalpontSystemCatalog::VARCHAR: case CalpontSystemCatalog::VARBINARY: diff --git a/utils/windowfunction/windowfunctiontype.cpp b/utils/windowfunction/windowfunctiontype.cpp index 68015d120..471cdc1ac 100644 --- a/utils/windowfunction/windowfunctiontype.cpp +++ b/utils/windowfunction/windowfunctiontype.cpp @@ -290,6 +290,16 @@ template<> void WindowFunctionType::getValue(uint64_t i, float& t, CDT* c } } +template<> void WindowFunctionType::getValue(uint64_t i, long double& t, CDT* cdt) +{ + t = fRow.getLongDoubleField(i); + + if (cdt) + { + *cdt = execplan::CalpontSystemCatalog::LONGDOUBLE; + } +} + template<> void WindowFunctionType::getValue(uint64_t i, string& t, CDT* cdt) { t = fRow.getStringField(i); @@ -320,6 +330,11 @@ template<> void WindowFunctionType::setValue(uint64_t i, float& t) fRow.setFloatField(t, i); } +template<> void WindowFunctionType::setValue(uint64_t i, long double& t) +{ + fRow.setLongDoubleField(t, i); +} + template<> void WindowFunctionType::setValue(uint64_t i, string& t) { fRow.setStringField(t, i); @@ -406,6 +421,14 @@ void WindowFunctionType::setValue(int ct, int64_t b, int64_t e, int64_t c, T* v) setValue(i, fv); break; } + + case CalpontSystemCatalog::LONGDOUBLE: + { + long double dv = *v; + setValue(i, dv); + break; + } + default: { setValue(i, *v); @@ -523,6 +546,12 @@ void WindowFunctionType::getConstValue(ConstantColumn* cc, double& t, bo t = cc->getDoubleVal(fRow, b); } +template<> +void WindowFunctionType::getConstValue(ConstantColumn* cc, long double& t, bool& b) +{ + t = cc->getLongDoubleVal(fRow, b); +} + template<> void WindowFunctionType::getConstValue(ConstantColumn* cc, float& t, bool& b) { @@ -539,11 +568,13 @@ template void WindowFunctionType::implicit2T(uint64_t, int64_t&, int); template void WindowFunctionType::implicit2T(uint64_t, uint64_t&, int); template void WindowFunctionType::implicit2T(uint64_t, float&, int); template void WindowFunctionType::implicit2T(uint64_t, double&, int); +template void WindowFunctionType::implicit2T(uint64_t, long double&, int); template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, int64_t*); template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, uint64_t*); template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, float*); template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, double*); +template void WindowFunctionType::setValue(int, int64_t, int64_t, int64_t, long double*); void* WindowFunctionType::getNullValueByType(int ct, int pos) { @@ -557,6 +588,7 @@ void* WindowFunctionType::getNullValueByType(int ct, int pos) static uint64_t utinyIntNull = joblist::UTINYINTNULL; static uint64_t floatNull = joblist::FLOATNULL; static uint64_t doubleNull = joblist::DOUBLENULL; + static long double longDoubleNull= joblist::LONGDOUBLENULL; static uint64_t dateNull = joblist::DATENULL; static uint64_t datetimeNull = joblist::DATETIMENULL; static uint64_t timeNull = joblist::TIMENULL; @@ -691,6 +723,9 @@ void* WindowFunctionType::getNullValueByType(int ct, int pos) break; case CalpontSystemCatalog::LONGDOUBLE: + v = &longDoubleNull; + break; + case CalpontSystemCatalog::VARBINARY: default: std::ostringstream oss; diff --git a/utils/windowfunction/windowfunctiontype.h b/utils/windowfunction/windowfunctiontype.h index 5c2f43db0..5388898a0 100644 --- a/utils/windowfunction/windowfunctiontype.h +++ b/utils/windowfunction/windowfunctiontype.h @@ -223,6 +223,10 @@ protected: { return fRow.getDoubleField(i); } + long double getLongDoubleValue(uint64_t i) + { + return fRow.getLongDoubleField(i); + } void setIntValue(int64_t i, int64_t v) { fRow.setIntField(v, i); @@ -231,7 +235,10 @@ protected: { fRow.setDoubleField(v, i); } - + void setLongDoubleValue(int64_t i, long double v) + { + fRow.setLongDoubleField(v, i); + } // for string table rowgroup::Row::Pointer getPointer(joblist::RowPosition& r)