From 129d5b5a0ffa2f6f3d8d7686db4e4cbac454b56b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 20 Oct 2020 15:35:36 +0400 Subject: [PATCH] MCOL-4174 Review/refactor frontend/connector code --- datatypes/mcs_datatype.cpp | 1766 ++++++++++++ datatypes/mcs_datatype.h | 2510 +++++++++++++++++ datatypes/mcs_decimal.cpp | 126 +- datatypes/mcs_decimal.h | 481 +++- dbcon/ddlpackageproc/createindexprocessor.cpp | 8 +- dbcon/ddlpackageproc/ddlindexpopulator.h | 2 +- dbcon/ddlpackageproc/ddlpackageprocessor.cpp | 232 +- dbcon/ddlpackageproc/ddlpackageprocessor.h | 6 - dbcon/dmlpackageproc/dmlpackageprocessor.cpp | 1 - dbcon/execplan/arithmeticoperator.h | 4 +- dbcon/execplan/calpontsystemcatalog.cpp | 55 +- dbcon/execplan/calpontsystemcatalog.h | 190 +- dbcon/execplan/functioncolumn.h | 2 +- dbcon/execplan/treenode.h | 289 +- dbcon/joblist/batchprimitiveprocessor-jl.cpp | 2 +- dbcon/joblist/columncommand-jl.cpp | 2 +- dbcon/joblist/crossenginestep.cpp | 5 +- dbcon/joblist/groupconcat.cpp | 6 +- dbcon/joblist/jlf_common.cpp | 2 +- dbcon/joblist/jlf_execplantojoblist.cpp | 15 +- dbcon/joblist/jlf_tuplejoblist.cpp | 2 +- dbcon/joblist/lbidlist.cpp | 11 +- dbcon/joblist/pseudocc-jl.cpp | 8 +- dbcon/joblist/rowestimator.cpp | 16 +- dbcon/joblist/tuple-bps.cpp | 8 +- dbcon/joblist/tupleaggregatestep.cpp | 6 +- dbcon/joblist/tuplehashjoin.cpp | 2 +- dbcon/mysql/CMakeLists.txt | 1 + dbcon/mysql/ha_mcs_datatype.h | 1301 +++++++++ dbcon/mysql/ha_mcs_ddl.cpp | 158 +- dbcon/mysql/ha_mcs_dml.cpp | 1082 +------ dbcon/mysql/ha_mcs_execplan.cpp | 104 +- dbcon/mysql/ha_mcs_impl.cpp | 441 +-- dbcon/mysql/ha_mcs_partition.cpp | 1139 +------- dbcon/mysql/is_columnstore_extents.cpp | 9 +- primitives/primproc/columncommand.cpp | 2 +- primitives/primproc/filtercommand.cpp | 8 +- primitives/primproc/pseudocc.cpp | 4 +- tests/dataconvert-tests.cpp | 105 +- tests/mcs_decimal-tests.cpp | 118 +- tests/rowgroup-tests.cpp | 3 +- tools/editem/editem.cpp | 13 +- utils/cloudio/CMakeLists.txt | 2 +- utils/common/emptyvaluemanip.cpp | 3 +- utils/common/widedecimalutils.h | 42 - utils/dataconvert/dataconvert.cpp | 1193 ++++---- utils/dataconvert/dataconvert.h | 16 +- utils/funcexp/func_round.cpp | 14 +- utils/funcexp/func_truncate.cpp | 14 +- utils/joiner/tuplejoiner.cpp | 19 +- utils/regr/moda.cpp | 2 +- utils/rowgroup/rowaggregation.cpp | 12 +- utils/rowgroup/rowgroup.cpp | 17 +- utils/rowgroup/rowgroup.h | 12 +- utils/udfsdk/mcsv1_udaf.cpp | 2 +- utils/windowfunction/windowfunctiontype.cpp | 2 +- versioning/BRM/CMakeLists.txt | 3 +- versioning/BRM/dbrm.cpp | 5 +- versioning/BRM/extentmap.cpp | 1 - writeengine/bulk/we_brmreporter.cpp | 9 +- writeengine/bulk/we_bulkloadbuffer.cpp | 1 - writeengine/bulk/we_bulkloadbuffer.h | 1 - writeengine/bulk/we_colextinf.cpp | 1 - writeengine/bulk/we_colextinf.h | 1 - writeengine/server/CMakeLists.txt | 3 +- writeengine/server/we_ddlcommandproc.cpp | 28 +- writeengine/server/we_ddlcommon.h | 233 -- writeengine/server/we_dmlcommandproc.cpp | 22 +- writeengine/wrapper/we_colop.cpp | 1 - writeengine/wrapper/writeengine.cpp | 5 +- 70 files changed, 6982 insertions(+), 4927 deletions(-) create mode 100644 datatypes/mcs_datatype.cpp create mode 100644 datatypes/mcs_datatype.h create mode 100644 dbcon/mysql/ha_mcs_datatype.h diff --git a/datatypes/mcs_datatype.cpp b/datatypes/mcs_datatype.cpp new file mode 100644 index 000000000..82c87ade9 --- /dev/null +++ b/datatypes/mcs_datatype.cpp @@ -0,0 +1,1766 @@ +/* + Copyright (C) 2020 MariaDB Corporation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include +#include +#include +#ifdef _MSC_VER +#include +#else +#include +#endif +#include +#include +#include +#include +#ifdef _MSC_VER +#include +#else +#include +#endif +#include +#include +using namespace std; + +#include + + +#include "dataconvert.h" +using namespace dataconvert; + +#include "simplecolumn.h" +#include "simplecolumn_int.h" +#include "simplecolumn_uint.h" +#include "simplecolumn_decimal.h" + +#include "rowgroup.h" +#include "ddlpkg.h" +#include "dbrm.h" +#include "we_typeext.h" +#include "joblisttypes.h" + +namespace datatypes +{ + +int128_t SystemCatalog::TypeAttributesStd::decimal128FromString(const std::string& value) const +{ + int128_t result = 0; + bool pushWarning = false; + bool noRoundup = false; + dataconvert::number_int_value(value, + SystemCatalog::DECIMAL, + *this, + pushWarning, + noRoundup, + result); + return result; +} + + +const string & TypeHandlerSInt8::name() const +{ + static const string xname= "TINYINT"; + return xname; +} + + +const string & TypeHandlerUInt8::name() const +{ + static const string xname= "UTINYINT"; + return xname; +} + + +const string & TypeHandlerSInt16::name() const +{ + static const string xname= "SMALLINT"; + return xname; +} + + +const string & TypeHandlerUInt16::name() const +{ + static const string xname= "USMALLINT"; + return xname; +} + + +const string & TypeHandlerSInt24::name() const +{ + static const string xname= "MEDINT"; + return xname; +} + + +const string & TypeHandlerUInt24::name() const +{ + static const string xname= "UMEDINT"; + return xname; +} + + +const string & TypeHandlerSInt32::name() const +{ + static const string xname= "INT"; + return xname; +} + + +const string & TypeHandlerUInt32::name() const +{ + static const string xname= "UINT"; + return xname; +} + + +const string & TypeHandlerSInt64::name() const +{ + static const string xname= "BIGINT"; + return xname; +} + + +const string & TypeHandlerUInt64::name() const +{ + static const string xname= "UBIGINT"; + return xname; +} + + +const string & TypeHandlerSFloat::name() const +{ + static const string xname= "FLOAT"; + return xname; +} + + +const string & TypeHandlerUFloat::name() const +{ + static const string xname= "UFLOAT"; + return xname; +} + + +const string & TypeHandlerSDouble::name() const +{ + static const string xname= "DOUBLE"; + return xname; +} + + +const string & TypeHandlerUDouble::name() const +{ + static const string xname= "UDOUBLE"; + return xname; +} + + +const string & TypeHandlerSLongDouble::name() const +{ + static const string xname= "LONGDOUBLE"; + return xname; +} + + +const string & TypeHandlerSDecimal64::name() const +{ + static const string xname= "DECIMAL"; + return xname; +} + + +const string & TypeHandlerUDecimal64::name() const +{ + static const string xname= "UDECIMAL"; + return xname; +} + + +const string & TypeHandlerSDecimal128::name() const +{ + static const string xname= "DECIMAL"; + return xname; +} + + +const string & TypeHandlerUDecimal128::name() const +{ + static const string xname= "UDECIMAL"; + return xname; +} + + +const string & TypeHandlerDate::name() const +{ + static const string xname= "DATE"; + return xname; +} + + +const string & TypeHandlerDatetime::name() const +{ + static const string xname= "DATETIME"; + return xname; +} + + +const string & TypeHandlerTime::name() const +{ + static const string xname= "TIME"; + return xname; +} + + +const string & TypeHandlerTimestamp::name() const +{ + static const string xname= "TIMESTAMP"; + return xname; +} + + +const string & TypeHandlerChar::name() const +{ + static const string xname= "CHAR"; + return xname; +} + + +const string & TypeHandlerVarchar::name() const +{ + static const string xname= "VARCHAR"; + return xname; +} + + +const string & TypeHandlerVarbinary::name() const +{ + static const string xname= "VARBINARY"; + return xname; +} + + +const string & TypeHandlerBlob::name() const +{ + static const string xname= "BLOB"; + return xname; +} + + +const string & TypeHandlerClob::name() const +{ + static const string xname= "CLOB"; + return xname; +} + + +const string & TypeHandlerText::name() const +{ + static const string xname= "TEXT"; + return xname; +} + + +const string & TypeHandlerBit::name() const +{ + static const string xname= "BIT"; + return xname; +} + + +TypeHandlerBit mcs_type_handler_bit; + +TypeHandlerSInt8 mcs_type_handler_sint8; +TypeHandlerSInt16 mcs_type_handler_sint16; +TypeHandlerSInt24 mcs_type_handler_sint24; +TypeHandlerSInt32 mcs_type_handler_sint32; +TypeHandlerSInt64 mcs_type_handler_sint64; + +TypeHandlerUInt8 mcs_type_handler_uint8; +TypeHandlerUInt16 mcs_type_handler_uint16; +TypeHandlerUInt24 mcs_type_handler_uint24; +TypeHandlerUInt32 mcs_type_handler_uint32; +TypeHandlerUInt64 mcs_type_handler_uint64; + +TypeHandlerSFloat mcs_type_handler_sfloat; +TypeHandlerSDouble mcs_type_handler_sdouble; +TypeHandlerSLongDouble mcs_type_handler_slongdouble; + +TypeHandlerUFloat mcs_type_handler_ufloat; +TypeHandlerUDouble mcs_type_handler_udouble; + +TypeHandlerSDecimal64 mcs_type_handler_sdecimal64; +TypeHandlerUDecimal64 mcs_type_handler_udecimal64; + +TypeHandlerSDecimal128 mcs_type_handler_sdecimal128; +TypeHandlerUDecimal128 mcs_type_handler_udecimal128; + +TypeHandlerDate mcs_type_handler_date; +TypeHandlerTime mcs_type_handler_time; +TypeHandlerDatetime mcs_type_handler_datetime; +TypeHandlerTimestamp mcs_type_handler_timestamp; + + +TypeHandlerChar mcs_type_handler_char; +TypeHandlerVarchar mcs_type_handler_varchar; +TypeHandlerText mcs_type_handler_text; +TypeHandlerClob mcs_type_handler_clob; +TypeHandlerVarbinary mcs_type_handler_varbinary; +TypeHandlerBlob mcs_type_handler_blob; + + +const TypeHandler * +TypeHandler::find(SystemCatalog::ColDataType typeCode, + const SystemCatalog::TypeAttributesStd &ct) +{ + switch (typeCode) { + case SystemCatalog::BIT: return &mcs_type_handler_bit; + case SystemCatalog::TINYINT: return &mcs_type_handler_sint8; + case SystemCatalog::SMALLINT: return &mcs_type_handler_sint16; + case SystemCatalog::MEDINT: return &mcs_type_handler_sint24; + case SystemCatalog::INT: return &mcs_type_handler_sint32; + case SystemCatalog::BIGINT: return &mcs_type_handler_sint64; + case SystemCatalog::UTINYINT: return &mcs_type_handler_uint8; + case SystemCatalog::USMALLINT: return &mcs_type_handler_uint16; + case SystemCatalog::UMEDINT: return &mcs_type_handler_uint24; + case SystemCatalog::UINT: return &mcs_type_handler_uint32; + case SystemCatalog::UBIGINT: return &mcs_type_handler_uint64; + case SystemCatalog::FLOAT: return &mcs_type_handler_sfloat; + case SystemCatalog::DOUBLE: return &mcs_type_handler_sdouble; + case SystemCatalog::LONGDOUBLE: return &mcs_type_handler_slongdouble; + case SystemCatalog::UFLOAT: return &mcs_type_handler_ufloat; + case SystemCatalog::UDOUBLE: return &mcs_type_handler_udouble; + + case SystemCatalog::DECIMAL: + if (ct.colWidth < datatypes::MAXDECIMALWIDTH) + return &mcs_type_handler_sdecimal64; + else + return &mcs_type_handler_sdecimal128; + + case SystemCatalog::UDECIMAL: + if (ct.colWidth < datatypes::MAXDECIMALWIDTH) + return &mcs_type_handler_udecimal64; + else + return &mcs_type_handler_udecimal128; + + case SystemCatalog::TIME: return &mcs_type_handler_time; + case SystemCatalog::DATE: return &mcs_type_handler_date; + case SystemCatalog::DATETIME: return &mcs_type_handler_datetime; + case SystemCatalog::TIMESTAMP: return &mcs_type_handler_timestamp; + case SystemCatalog::CHAR: return &mcs_type_handler_char; + case SystemCatalog::VARCHAR: return &mcs_type_handler_varchar; + case SystemCatalog::TEXT: return &mcs_type_handler_text; + case SystemCatalog::CLOB: return &mcs_type_handler_clob; + case SystemCatalog::VARBINARY: return &mcs_type_handler_varbinary; + case SystemCatalog::BLOB: return &mcs_type_handler_blob; + + case SystemCatalog::NUM_OF_COL_DATA_TYPE: + case SystemCatalog::STRINT: + case SystemCatalog::UNDEFINED: + case SystemCatalog::BINARY: + break; + } + return NULL; +} + + +const TypeHandler * +SystemCatalog::TypeHolderStd::typeHandler() const +{ + return TypeHandler::find(colDataType, *this); +} + + +boost::any +SystemCatalog::TypeHolderStd::getNullValueForType() const +{ + const TypeHandler *h= typeHandler(); + if (!h) + { + throw std::runtime_error("getNullValueForType: unkown column data type"); + return boost::any(); + } + return h->getNullValueForType(*this); +} + + +const TypeHandler * +TypeHandler::find_by_ddltype(const ddlpackage::ColumnType &ct) +{ + switch (ct.fType) { + case ddlpackage::DDL_CHAR: return &mcs_type_handler_char; + case ddlpackage::DDL_VARCHAR: return &mcs_type_handler_varchar; + case ddlpackage::DDL_VARBINARY: return &mcs_type_handler_varbinary; + case ddlpackage::DDL_BIT: return &mcs_type_handler_bit; + + case ddlpackage::DDL_REAL: + case ddlpackage::DDL_DECIMAL: + case ddlpackage::DDL_NUMERIC: + case ddlpackage::DDL_NUMBER: + + if (ct.fLength < datatypes::MAXDECIMALWIDTH) + return &mcs_type_handler_sdecimal64; + return &mcs_type_handler_sdecimal128; + + case ddlpackage::DDL_FLOAT: return &mcs_type_handler_sfloat; + case ddlpackage::DDL_DOUBLE: return &mcs_type_handler_sdouble; + + case ddlpackage::DDL_INT: + case ddlpackage::DDL_INTEGER: return &mcs_type_handler_sint32; + + case ddlpackage::DDL_BIGINT: return &mcs_type_handler_sint64; + case ddlpackage::DDL_MEDINT: return &mcs_type_handler_sint24; + case ddlpackage::DDL_SMALLINT: return &mcs_type_handler_sint16; + case ddlpackage::DDL_TINYINT: return &mcs_type_handler_sint8; + + case ddlpackage::DDL_DATE: return &mcs_type_handler_date; + case ddlpackage::DDL_DATETIME: return &mcs_type_handler_datetime; + case ddlpackage::DDL_TIME: return &mcs_type_handler_time; + case ddlpackage::DDL_TIMESTAMP: return &mcs_type_handler_timestamp; + + case ddlpackage::DDL_CLOB: return &mcs_type_handler_clob; + case ddlpackage::DDL_BLOB: return &mcs_type_handler_blob; + case ddlpackage::DDL_TEXT: return &mcs_type_handler_text; + + case ddlpackage::DDL_UNSIGNED_TINYINT: return &mcs_type_handler_uint8; + case ddlpackage::DDL_UNSIGNED_SMALLINT: return &mcs_type_handler_uint16; + case ddlpackage::DDL_UNSIGNED_MEDINT: return &mcs_type_handler_uint24; + case ddlpackage::DDL_UNSIGNED_INT: return &mcs_type_handler_uint32; + case ddlpackage::DDL_UNSIGNED_BIGINT: return &mcs_type_handler_uint64; + + case ddlpackage::DDL_UNSIGNED_DECIMAL: + case ddlpackage::DDL_UNSIGNED_NUMERIC: + + if (ct.fLength < datatypes::MAXDECIMALWIDTH) + return &mcs_type_handler_udecimal64; + return &mcs_type_handler_udecimal128; + + case ddlpackage::DDL_UNSIGNED_FLOAT: return &mcs_type_handler_ufloat; + case ddlpackage::DDL_UNSIGNED_DOUBLE: return &mcs_type_handler_udouble; + + case ddlpackage::DDL_BINARY: //return &mcs_type_handler_binary; + case ddlpackage::DDL_INVALID_DATATYPE: + break; + } + return NULL; +} + + +/****************************************************************************/ + + +int TypeHandlerDate::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int64_t intColVal = row.getUintField<4>(pos); + return f->store_date(intColVal); +} + + +int TypeHandlerDatetime::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int64_t intColVal = row.getUintField<8>(pos); + return f->store_datetime(intColVal); +} + + +int TypeHandlerTime::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int64_t intColVal = row.getUintField<8>(pos); + return f->store_time(intColVal); +} + + +int TypeHandlerTimestamp::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int64_t intColVal = row.getUintField<8>(pos); + return f->store_timestamp(intColVal); +} + + +int TypeHandlerStr::storeValueToFieldCharVarchar(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int64_t intColVal; + switch (f->colWidth()) + { + case 1: + intColVal = row.getUintField<1>(pos); + return f->store_string((const char*)(&intColVal), strlen((char*)(&intColVal))); + + case 2: + intColVal = row.getUintField<2>(pos); + return f->store_string((char*)(&intColVal), strlen((char*)(&intColVal))); + + case 4: + intColVal = row.getUintField<4>(pos); + return f->store_string((char*)(&intColVal), strlen((char*)(&intColVal))); + + case 8: + { + //make sure we don't send strlen off into the weeds... + intColVal = row.getUintField<8>(pos); + char tmp[256]; + memcpy(tmp, &intColVal, 8); + tmp[8] = 0; + return f->store_string(tmp, strlen(tmp)); + } + default: + return f->store_string((const char*)row.getStringPointer(pos), row.getStringLength(pos)); + } +} + + +int TypeHandlerVarbinary::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + uint32_t l; + const uint8_t* p = row.getVarBinaryField(l, pos); + return f->store_varbinary((const char *) p, l); +} + + +int TypeHandlerSInt64::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int64_t val = row.getIntField<8>(pos); + return f->store_xlonglong(val); +} + + +int TypeHandlerUInt64::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + uint64_t val = row.getUintField<8>(pos); + return f->store_xlonglong(static_cast(val)); +} + + +int TypeHandlerInt::storeValueToFieldSInt32(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int64_t val = row.getIntField<4>(pos); + return f->store_xlonglong(val); +} + + +int TypeHandlerInt::storeValueToFieldUInt32(rowgroup::Row &row, int pos, + StoreField *f) const +{ + uint64_t val = row.getUintField<4>(pos); + return f->store_xlonglong(static_cast(val)); +} + + +int TypeHandlerSInt16::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int64_t val = row.getIntField<2>(pos); + return f->store_xlonglong(val); +} + + +int TypeHandlerUInt16::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + uint64_t val = row.getUintField<2>(pos); + return f->store_xlonglong(static_cast(val)); +} + + +int TypeHandlerSInt8::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int64_t val = row.getIntField<1>(pos); + return f->store_xlonglong(val); +} + + +int TypeHandlerUInt8::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + uint64_t val = row.getUintField<1>(pos); + return f->store_xlonglong(static_cast(val)); +} + + +/* + In this case, we're trying to load a double output column with float data. This is the + case when you do sum(floatcol), e.g. +*/ +int TypeHandlerReal::storeValueToFieldXFloat(rowgroup::Row &row, int pos, + StoreField *f) const +{ + float dl = row.getFloatField(pos); + return f->store_float(dl); +} + + +int TypeHandlerReal::storeValueToFieldXDouble(rowgroup::Row &row, int pos, + StoreField *f) const +{ + double dl = row.getDoubleField(pos); + return f->store_double(dl); +} + + +int TypeHandlerSLongDouble::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + long double dl = row.getLongDoubleField(pos); + return f->store_long_double(dl); +} + + +int TypeHandlerXDecimal::storeValueToField64(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int64_t val = row.getIntField(pos); + return f->store_decimal64(val); +} + + +int TypeHandlerXDecimal::storeValueToField128(rowgroup::Row &row, int pos, + StoreField *f) const +{ + int128_t* dec= row.getBinaryField(pos); + return f->store_decimal128(*dec); +} + + +int TypeHandlerStr::storeValueToFieldBlobText(rowgroup::Row &row, int pos, + StoreField *f) const +{ + return f->store_lob((const char*) row.getVarBinaryField(pos), + row.getVarBinaryLength(pos)); +} + + +/* +int TypeHandlerBinary::storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const +{ + Field_varstring* f2 = static_cast(f); + // WIP MCOL-641 Binary representation could contain \0. + char* binaryString = row.getBinaryField(pos); + return f2->store(binaryString, colType.colWidth, f2->charset()); +} +*/ + +/* + Default behaviour: treat as int64 + int64_t intColVal = row.getUintField<8>(pos); + storeNumericField(f, intColVal, colType); +*/ + + +/****************************************************************************/ + +string TypeHandlerDate::format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + return DataConvert::dateToString(v.toSInt64()); +} + + +string TypeHandlerDatetime::format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + return DataConvert::datetimeToString(v.toSInt64()); +} + +string TypeHandlerTimestamp::format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + return DataConvert::timestampToString(v.toSInt64(), v.tzname()); +} + + +string TypeHandlerTime::format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + return DataConvert::timeToString(v.toSInt64()); +} + + +string TypeHandlerChar::format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + // swap again to retain the string byte order + ostringstream oss; + uint64_t tmp = uint64ToStr(v.toSInt64()); + oss << (char*)(&tmp); + return oss.str(); +} + + +string TypeHandlerVarchar::format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + // swap again to retain the string byte order + ostringstream oss; + uint64_t tmp = uint64ToStr(v.toSInt64()); + oss << (char*)(&tmp); + return oss.str(); +} + + +string TypeHandlerInt::formatSInt64(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + ostringstream oss; + oss << v.toSInt64(); + return oss.str(); +} + + +string TypeHandlerInt::formatUInt64(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + ostringstream oss; + oss << static_cast(v.toSInt64()); + return oss.str(); +} + + +string TypeHandlerVarbinary::format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + return "N/A"; +} + + +string +TypeHandlerXDecimal::format64(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + idbassert(isValidXDecimal64(attr)); + ostringstream oss; + if (attr.scale > 0) + { + double d = ((double)(v.toSInt64()) / (double)pow((double)10, attr.scale)); + oss << setprecision(attr.scale) << fixed << d; + } + else + oss << v.toSInt64(); + return oss.str(); +} + + +string +TypeHandlerXDecimal::format128(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) + const +{ + idbassert(isValidXDecimal128(attr)); + ostringstream oss; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; + int128_t tmp= v.toSInt128(); + DataConvert::decimalToString(&tmp, (unsigned) attr.scale, buf, (uint8_t) sizeof(buf), code()); + oss << buf; + return oss.str(); +} + + +/****************************************************************************/ + +string TypeHandler::formatPartitionInfoSInt64( + const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &pi) const +{ + ostringstream output; + if (pi.isEmptyOrNullSInt64()) + output << setw(30) << "Empty/Null" + << setw(30) << "Empty/Null"; + else + output << setw(30) << format(SimpleValueSInt64(pi.min), attr) + << setw(30) << format(SimpleValueSInt64(pi.max), attr); + return output.str(); +} + + +string TypeHandler::formatPartitionInfoUInt64( + const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &pi) const +{ + ostringstream output; + if (pi.isEmptyOrNullUInt64()) + output << setw(30) << "Empty/Null" + << setw(30) << "Empty/Null"; + else + output << setw(30) << format(SimpleValueSInt64(pi.min), attr) + << setw(30) << format(SimpleValueSInt64(pi.max), attr); + return output.str(); +} + + + +string +TypeHandlerXDecimal::formatPartitionInfo128( + const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &pi) const +{ + ostringstream output; + if (pi.isEmptyOrNullSInt128()) + output << setw(datatypes::Decimal::MAXLENGTH16BYTES) << "Empty/Null" + << setw(datatypes::Decimal::MAXLENGTH16BYTES) << "Empty/Null"; + else + output << setw(datatypes::Decimal::MAXLENGTH16BYTES) << format(SimpleValueSInt128(pi.int128Min), attr) + << setw(datatypes::Decimal::MAXLENGTH16BYTES) << format(SimpleValueSInt128(pi.int128Max), attr); + return output.str(); +} + + +string +TypeHandlerStr::formatPartitionInfoSmallCharVarchar( + const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &pi) const +{ + ostringstream output; + int64_t maxLimit = numeric_limits::max(); + int64_t minLimit = numeric_limits::min(); + maxLimit = uint64ToStr(maxLimit); + minLimit = uint64ToStr(minLimit); + if (pi.min == maxLimit && pi.max == minLimit) + output << setw(30) << "Empty/Null" + << setw(30) << "Empty/Null"; + else + output << setw(30) << format(SimpleValueSInt64(pi.min), attr) + << setw(30) << format(SimpleValueSInt64(pi.max), attr); + return output.str(); +} + + +string +TypeHandlerChar::formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &pi) const +{ + // char column order swap for compare in subsequent loop + if (attr.colWidth <= 8) + return formatPartitionInfoSmallCharVarchar(attr, pi); + return formatPartitionInfoSInt64(attr, pi); +} + + +string +TypeHandlerVarchar::formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &pi) const +{ + // varchar column order swap for compare in subsequent loop + if (attr.colWidth <= 7) + return formatPartitionInfoSmallCharVarchar(attr, pi); + return formatPartitionInfoSInt64(attr, pi); +} + + +/****************************************************************************/ + +execplan::SimpleColumn * +TypeHandlerSInt8::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + if (ct.scale == 0) + return new execplan::SimpleColumn_INT<1>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); + ct.colDataType = SystemCatalog::DECIMAL; + return new execplan::SimpleColumn_Decimal<1>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerSInt16::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + if (ct.scale == 0) + return new execplan::SimpleColumn_INT<2>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); + ct.colDataType = SystemCatalog::DECIMAL; + return new execplan::SimpleColumn_Decimal<2>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerSInt24::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + if (ct.scale == 0) + return new execplan::SimpleColumn_INT<4>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); + ct.colDataType = SystemCatalog::DECIMAL; + return new execplan::SimpleColumn_Decimal<4>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerSInt32::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + if (ct.scale == 0) + return new execplan::SimpleColumn_INT<4>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); + ct.colDataType = SystemCatalog::DECIMAL; + return new execplan::SimpleColumn_Decimal<4>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerSInt64::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + if (ct.scale == 0) + return new execplan::SimpleColumn_INT<8>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); + ct.colDataType = SystemCatalog::DECIMAL; + return new execplan::SimpleColumn_Decimal<8>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerUInt8::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + // QQ: why scale is not checked (unlike SInt1)? + return new execplan::SimpleColumn_UINT<1>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerUInt16::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + return new execplan::SimpleColumn_UINT<2>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerUInt24::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + return new execplan::SimpleColumn_UINT<4>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerUInt32::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + return new execplan::SimpleColumn_UINT<4>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerUInt64::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + return new execplan::SimpleColumn_UINT<8>(name.db(), name.table(), name.column(), prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerReal::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + // QQ + return new execplan::SimpleColumn(name.db(), name.table(), name.column(), + prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerXDecimal::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + // QQ + return new execplan::SimpleColumn(name.db(), name.table(), name.column(), + prm.columnStore(), prm.sessionid()); +} + + +execplan::SimpleColumn * +TypeHandlerStr::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + // QQ + return new execplan::SimpleColumn(name.db(), name.table(), name.column(), + prm.columnStore(), prm.sessionid()); +} + + + +execplan::SimpleColumn * +TypeHandlerTemporal::newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) const +{ + // QQ + return new execplan::SimpleColumn(name.db(), name.table(), name.column(), + prm.columnStore(), prm.sessionid()); +} + + +/****************************************************************************/ + +class SimpleConverter: public boost::any +{ + bool &initPushWarning() + { + m_pushWarning= false; + return m_pushWarning; + } + bool m_pushWarning; +public: + SimpleConverter(const SessionParam &sp, + SystemCatalog::ColDataType typeCode, + const SystemCatalog::TypeAttributesStd &attr, + const char *str) + :boost::any(DataConvert::convertColumnData(typeCode, attr, + str, initPushWarning(), + sp.tzname(), + false, true, false)) + { } + round_style_t roundStyle() const + { + return m_pushWarning ? round_style_t::POS : round_style_t::NONE; + } + round_style_t roundStyle(const char *str) const + { + return m_pushWarning ? roundStyleDetect(str) : round_style_t::NONE; + } + static round_style_t roundStyleDetect(const char *str) + { + // get rid of leading white spaces and parentheses + string data(str); + size_t fpos = data.find_first_of(" \t()"); + while (string::npos != fpos) + { + data.erase(fpos, 1); + fpos = data.find_first_of(" \t()"); + } + return (data[0] == '-') ? round_style_t::NEG : round_style_t::POS; + } + int64_t to_sint64() const { return boost::any_cast(*this); } + uint64_t to_uint64() const { return boost::any_cast(*this); } + uint32_t to_uint32() const { return boost::any_cast(*this); } + int128_t to_sint128() const { return boost::any_cast(*this); } +}; + + +class SimpleConverterSNumeric: public SimpleConverter +{ +public: + SimpleConverterSNumeric(const SessionParam &sp, + SystemCatalog::ColDataType typeCode, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, + round_style_t &rf) + :SimpleConverter(sp, typeCode, attr, str) + { + rf = roundStyle(str); + } +}; + + +template +SimpleValue +toSimpleValueSInt(const SessionParam &sp, + SystemCatalog::ColDataType typeCode, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) +{ + idbassert(attr.colWidth <= SystemCatalog::EIGHT_BYTE); + SimpleConverterSNumeric anyVal(sp, typeCode, attr, str, rf); + return SimpleValueSInt64(static_cast(boost::any_cast(anyVal))); +} + + +SimpleValue +TypeHandlerSInt8::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + return toSimpleValueSInt(sp, SystemCatalog::TINYINT, attr, str, rf); +} + + +SimpleValue +TypeHandlerSInt16::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + return toSimpleValueSInt(sp, SystemCatalog::SMALLINT, attr, str, rf); +} + + +SimpleValue +TypeHandlerSInt24::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + return toSimpleValueSInt(sp, SystemCatalog::MEDINT, attr, str, rf); +} + + +SimpleValue +TypeHandlerSInt32::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + return toSimpleValueSInt(sp, SystemCatalog::INT, attr, str, rf); +} + + +SimpleValue +TypeHandlerSInt64::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + return toSimpleValueSInt(sp, SystemCatalog::BIGINT, attr, str, rf); +} + + +template +SimpleValue toSimpleValueUInt(const SessionParam &sp, + SystemCatalog::ColDataType typeCode, + const SystemCatalog::TypeAttributesStd &attr, + const char *str) +{ + idbassert(attr.colWidth <= SystemCatalog::EIGHT_BYTE); + SimpleConverter anyVal(sp, typeCode, attr, str); + return SimpleValueSInt64(static_cast(boost::any_cast(anyVal))); +} + + +SimpleValue +TypeHandlerUInt8::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + return toSimpleValueUInt(sp, SystemCatalog::UTINYINT, attr, str); +} + + +SimpleValue +TypeHandlerUInt16::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + return toSimpleValueUInt(sp, SystemCatalog::USMALLINT, attr, str); +} + + +SimpleValue +TypeHandlerUInt24::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + return toSimpleValueUInt(sp, SystemCatalog::UMEDINT, attr, str); +} + + +SimpleValue +TypeHandlerUInt32::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + return toSimpleValueUInt(sp, SystemCatalog::UINT, attr, str); +} + + +SimpleValue +TypeHandlerUInt64::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + return toSimpleValueUInt(sp, SystemCatalog::UBIGINT, attr, str); +} + + +SimpleValue +TypeHandlerDate::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + idbassert(attr.colWidth <= SystemCatalog::EIGHT_BYTE); + SimpleConverter anyVal(sp, SystemCatalog::DATE, attr, str); + return SimpleValueSInt64(static_cast(anyVal.to_uint32())); +} + + +SimpleValue +TypeHandlerDatetime::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + idbassert(attr.colWidth <= SystemCatalog::EIGHT_BYTE); + SimpleConverter anyVal(sp, SystemCatalog::DATETIME, attr, str); + return SimpleValueSInt64(static_cast(anyVal.to_uint64())); +} + + +SimpleValue +TypeHandlerTimestamp::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + idbassert(attr.colWidth <= SystemCatalog::EIGHT_BYTE); + SimpleConverter anyVal(sp, SystemCatalog::TIMESTAMP, attr, str); + return SimpleValueTimestamp(anyVal.to_uint64(), sp.tzname()); +} + + +SimpleValue +TypeHandlerTime::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + idbassert(attr.colWidth <= SystemCatalog::EIGHT_BYTE); + SimpleConverter anyVal(sp, SystemCatalog::TIME, attr, str); + return SimpleValueSInt64(anyVal.to_sint64()); +} + + +SimpleValue +TypeHandlerXDecimal::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + if (attr.colWidth <= SystemCatalog::EIGHT_BYTE) + { + SimpleConverterSNumeric anyVal(sp, code(), attr, str, rf); + int64_t v; + if (attr.colWidth == SystemCatalog::ONE_BYTE) + v = boost::any_cast(anyVal); + else if (attr.colWidth == SystemCatalog::TWO_BYTE) + v = boost::any_cast(anyVal); + else if (attr.colWidth == SystemCatalog::FOUR_BYTE) + v = boost::any_cast(anyVal); + else if (attr.colWidth == SystemCatalog::EIGHT_BYTE) + v = anyVal.to_sint64(); + else + { + idbassert(0); + v = 0; + } + return SimpleValueSInt64(v); + } + else + { + idbassert(attr.colWidth == datatypes::MAXDECIMALWIDTH); + SimpleConverterSNumeric anyVal(sp, code(), attr, str, rf); + return SimpleValueSInt128(anyVal.to_sint128()); + } +} + + +SimpleValue +TypeHandlerStr::toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const +{ + SimpleConverter anyVal(sp, code(), attr, str); + rf= anyVal.roundStyle(); + string i = boost::any_cast(anyVal); + // bug 1932, pad nulls up to the size of v + i.resize(sizeof(int64_t), 0); + return SimpleValueSInt64(static_cast(uint64ToStr(*((uint64_t*) i.data())))); +} + + +/****************************************************************************/ + +MinMaxPartitionInfo::MinMaxPartitionInfo(const BRM::EMEntry &entry) + :m_status(entry.status == BRM::EXTENTOUTOFSERVICE ? ET_DISABLED : 0) +{ } + + +MinMaxPartitionInfo +TypeHandler::getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const +{ + int32_t seqNum; + MinMaxPartitionInfo partInfo(entry); + *state = em.getExtentMaxMin(entry.range.start, partInfo.max, partInfo.min, seqNum); + return partInfo; +} + + +MinMaxPartitionInfo +TypeHandlerXDecimal::getExtentPartitionInfo64(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const +{ + int32_t seqNum; + MinMaxPartitionInfo partInfo(entry); + *state = em.getExtentMaxMin(entry.range.start, partInfo.max, partInfo.min, seqNum); + return partInfo; +} + + +MinMaxPartitionInfo +TypeHandlerXDecimal::getExtentPartitionInfo128(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const +{ + int32_t seqNum; + MinMaxPartitionInfo partInfo(entry); + *state = em.getExtentMaxMin(entry.range.start, partInfo.int128Max, partInfo.int128Min, seqNum); + return partInfo; +} + + +MinMaxPartitionInfo +TypeHandlerChar::getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const +{ + int32_t seqNum; + MinMaxPartitionInfo partInfo(entry); + *state = em.getExtentMaxMin(entry.range.start, partInfo.max, partInfo.min, seqNum); + // char column order swap + if (attr.colWidth <= 8) + { + partInfo.max = uint64ToStr(partInfo.max); + partInfo.min = uint64ToStr(partInfo.min); + } + return partInfo; +} + + +MinMaxPartitionInfo +TypeHandlerVarchar::getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const +{ + int32_t seqNum; + MinMaxPartitionInfo partInfo(entry); + *state = em.getExtentMaxMin(entry.range.start, partInfo.max, partInfo.min, seqNum); + // char column order swap + if (attr.colWidth <= 7) + { + partInfo.max = uint64ToStr(partInfo.max); + partInfo.min = uint64ToStr(partInfo.min); + } + return partInfo; +} + + +/****************************************************************************/ + + +string TypeHandler::PrintPartitionValueSInt64( + const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const +{ + if (!partInfo.isSuitableSInt64(startVal, rfMin, endVal, rfMax)) + return ""; + + ostringstream oss; + if (partInfo.min > partInfo.max) + oss << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; + else + oss << setw(30) << format(SimpleValueSInt64(partInfo.min), attr) + << setw(30) << format(SimpleValueSInt64(partInfo.max), attr); + return oss.str(); +} + + +string TypeHandler::PrintPartitionValueUInt64( + const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const +{ + if (!partInfo.isSuitableUInt64(startVal, rfMin, endVal, rfMax)) + return ""; + + ostringstream oss; + if (static_cast(partInfo.min) > static_cast(partInfo.max)) + oss << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; + else + oss << setw(30) << format(SimpleValueSInt64(partInfo.min), attr) + << setw(30) << format(SimpleValueSInt64(partInfo.max), attr); + return oss.str(); +} + + +string TypeHandlerXDecimal::PrintPartitionValue128( + const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const +{ + if (!partInfo.isSuitableSInt128(startVal, rfMin, endVal, rfMax)) + return ""; + + ostringstream oss; + if (partInfo.int128Min > partInfo.int128Max) + oss << setw(datatypes::Decimal::MAXLENGTH16BYTES) << "Empty/Null" + << setw(datatypes::Decimal::MAXLENGTH16BYTES) << "Empty/Null"; + else + oss << setw(datatypes::Decimal::MAXLENGTH16BYTES) << format(SimpleValueSInt128(partInfo.int128Min), attr) + << setw(datatypes::Decimal::MAXLENGTH16BYTES) << format(SimpleValueSInt128(partInfo.int128Max), attr); + return oss.str(); +} + +/****************************************************************************/ + + +boost::any +TypeHandlerSInt8::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + char tinyintvalue = joblist::TINYINTNULL; + boost::any value = tinyintvalue; + return value; +} + + +boost::any +TypeHandlerUInt8::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint8_t utinyintvalue = joblist::UTINYINTNULL; + boost::any value = utinyintvalue; + return value; +} + + +boost::any +TypeHandlerSInt16::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + short smallintvalue = joblist::SMALLINTNULL; + boost::any value = smallintvalue; + return value; +} + + +boost::any +TypeHandlerUInt16::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint16_t usmallintvalue = joblist::USMALLINTNULL; + boost::any value = usmallintvalue; + return value; +} + + +boost::any +TypeHandlerSInt24::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + int intvalue = joblist::INTNULL; + boost::any value = intvalue; + return value; +} + + +boost::any +TypeHandlerSInt32::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + int intvalue = joblist::INTNULL; + boost::any value = intvalue; + return value; +} + + +boost::any +TypeHandlerUInt24::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint32_t uintvalue = joblist::UINTNULL; + boost::any value = uintvalue; + return value; +} + + +boost::any +TypeHandlerUInt32::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint32_t uintvalue = joblist::UINTNULL; + boost::any value = uintvalue; + return value; +} + + +boost::any +TypeHandlerSInt64::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + long long bigint = joblist::BIGINTNULL; + boost::any value = bigint; + return value; +} + + +boost::any +TypeHandlerUInt64::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint64_t ubigint = joblist::UBIGINTNULL; + boost::any value = ubigint; + return value; +} + + +boost::any +TypeHandlerXDecimal::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + if (LIKELY(attr.colWidth == 16)) + { + int128_t val; + datatypes::Decimal::setWideDecimalNullValue(val); + boost::any value = val; + return value; + } + if (attr.colWidth == SystemCatalog::EIGHT_BYTE) + { + long long eightbyte = joblist::BIGINTNULL; + boost::any value = eightbyte; + return value; + } + if (attr.colWidth == SystemCatalog::FOUR_BYTE) + { + int intvalue = joblist::INTNULL; + boost::any value = intvalue; + return value; + } + if (attr.colWidth == SystemCatalog::TWO_BYTE) + { + short smallintvalue = joblist::SMALLINTNULL; + boost::any value = smallintvalue; + return value; + } + if (attr.colWidth == SystemCatalog::ONE_BYTE) + { + char tinyintvalue = joblist::TINYINTNULL; + boost::any value = tinyintvalue; + return value; + } + WriteEngine::Token nullToken; + boost::any value = nullToken; + return value; +} + + +boost::any +TypeHandlerSFloat::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint32_t jlfloatnull = joblist::FLOATNULL; + float* fp = reinterpret_cast(&jlfloatnull); + boost::any value = *fp; + return value; +} + + +boost::any +TypeHandlerUFloat::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint32_t jlfloatnull = joblist::FLOATNULL; + float* fp = reinterpret_cast(&jlfloatnull); + boost::any value = *fp; + return value; +} + + +boost::any +TypeHandlerSDouble::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint64_t jldoublenull = joblist::DOUBLENULL; + double* dp = reinterpret_cast(&jldoublenull); + boost::any value = *dp; + return value; +} + + +boost::any +TypeHandlerUDouble::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint64_t jldoublenull = joblist::DOUBLENULL; + double* dp = reinterpret_cast(&jldoublenull); + boost::any value = *dp; + return value; +} + + +boost::any +TypeHandlerDate::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint32_t d = joblist::DATENULL; + boost::any value = d; + return value; +} + + +boost::any +TypeHandlerDatetime::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint64_t d = joblist::DATETIMENULL; + boost::any value = d; + return value; +} + + +boost::any +TypeHandlerTime::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + int64_t d = joblist::TIMENULL; + boost::any value = d; + return value; +} + + +boost::any +TypeHandlerTimestamp::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + uint64_t d = joblist::TIMESTAMPNULL; + boost::any value = d; + return value; +} + + +boost::any +TypeHandlerChar::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + switch (attr.colWidth) + { + case 1: + { + //charnull = joblist::CHAR1NULL; + std::string charnull = "\376"; + boost::any value = charnull; + return value; + } + case 2: + { + //charnull = joblist::CHAR2NULL; + std::string charnull = "\377\376"; + boost::any value = charnull; + return value; + } + case 3: + case 4: + { + //charnull = joblist::CHAR4NULL; + std::string charnull = "\377\377\377\376"; + boost::any value = charnull; + return value; + } + case 5: + case 6: + case 7: + case 8: + { + //charnull = joblist::CHAR8NULL; + std::string charnull = "\377\377\377\377\377\377\377\376"; + boost::any value = charnull; + return value; + } + } + WriteEngine::Token nullToken; + boost::any value = nullToken; + return value; +} + + +boost::any +TypeHandlerStr::getNullValueForTypeVarcharText(const SystemCatalog::TypeAttributesStd &attr) const +{ + switch (attr.colWidth) + { + case 1: + { + //charnull = joblist::CHAR2NULL; + std::string charnull = "\377\376"; + boost::any value = charnull; + return value; + } + case 2: + case 3: + { + //charnull = joblist::CHAR4NULL; + std::string charnull = "\377\377\377\376"; + boost::any value = charnull; + return value; + } + case 4: + case 5: + case 6: + case 7: + { + //charnull = joblist::CHAR8NULL; + std::string charnull = "\377\377\377\377\377\377\377\376"; + boost::any value = charnull; + return value; + } + } + WriteEngine::Token nullToken; + boost::any value = nullToken; + return value; +} + + +boost::any +TypeHandlerBlob::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + WriteEngine::Token nullToken; + boost::any value = nullToken; + return value; +} + + +boost::any +TypeHandlerVarbinary::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + WriteEngine::Token nullToken; + boost::any value = nullToken; + return value; +} + +/****************************************************************************/ + +} // end of namespace datatypes + + +// vim:ts=2 sw=2: diff --git a/datatypes/mcs_datatype.h b/datatypes/mcs_datatype.h new file mode 100644 index 000000000..1e161b7ae --- /dev/null +++ b/datatypes/mcs_datatype.h @@ -0,0 +1,2510 @@ +/* + Copyright (C) 2020 MariaDB Corporation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ +#ifndef MCS_DATATYPE_H_INCLUDED +#define MCS_DATATYPE_H_INCLUDED + +#include +#include +#include +#include "exceptclasses.h" +#include "mcs_decimal.h" + + +#ifdef _MSC_VER +typedef int mcs_sint32_t; +#else +typedef int32_t mcs_sint32_t; +#endif + + +using int128_t = __int128; +using uint128_t = unsigned __int128; + + +// Because including my_sys.h in a Columnstore header causes too many conflicts +struct charset_info_st; +typedef const struct charset_info_st CHARSET_INFO; + + +#ifdef _MSC_VER +#define __attribute__(x) +#endif + +namespace +{ +const int64_t MIN_TINYINT __attribute__ ((unused)) = std::numeric_limits::min() + 2; // -126; +const int64_t MAX_TINYINT __attribute__ ((unused)) = std::numeric_limits::max(); // 127; +const int64_t MIN_SMALLINT __attribute__ ((unused)) = std::numeric_limits::min() + 2; // -32766; +const int64_t MAX_SMALLINT __attribute__ ((unused)) = std::numeric_limits::max(); // 32767; +const int64_t MIN_MEDINT __attribute__ ((unused)) = -(1ULL << 23); // -8388608; +const int64_t MAX_MEDINT __attribute__ ((unused)) = (1ULL << 23) - 1; // 8388607; +const int64_t MIN_INT __attribute__ ((unused)) = std::numeric_limits::min() + 2; // -2147483646; +const int64_t MAX_INT __attribute__ ((unused)) = std::numeric_limits::max(); // 2147483647; +const int64_t MIN_BIGINT __attribute__ ((unused)) = std::numeric_limits::min() + 2; // -9223372036854775806LL; +const int64_t MAX_BIGINT __attribute__ ((unused)) = std::numeric_limits::max(); // 9223372036854775807 + +const uint64_t MIN_UINT __attribute__ ((unused)) = 0; +const uint64_t MIN_UTINYINT __attribute__ ((unused)) = 0; +const uint64_t MIN_USMALLINT __attribute__ ((unused)) = 0; +const uint64_t MIN_UMEDINT __attribute__ ((unused)) = 0; +const uint64_t MIN_UBIGINT __attribute__ ((unused)) = 0; +const uint64_t MAX_UINT __attribute__ ((unused)) = std::numeric_limits::max() - 2; // 4294967293 +const uint64_t MAX_UTINYINT __attribute__ ((unused)) = std::numeric_limits::max() - 2; // 253; +const uint64_t MAX_USMALLINT __attribute__ ((unused)) = std::numeric_limits::max() - 2; // 65533; +const uint64_t MAX_UMEDINT __attribute__ ((unused)) = (1ULL << 24) - 1; // 16777215 +const uint64_t MAX_UBIGINT __attribute__ ((unused)) = std::numeric_limits::max() - 2; // 18446744073709551613 + +const float MAX_FLOAT __attribute__ ((unused)) = std::numeric_limits::max(); // 3.402823466385289e+38 +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(); +} + + +using namespace std; // e.g. string + + +namespace ddlpackage +{ + struct ColumnType; +}; + + +namespace BRM +{ + struct EMEntry; + class DBRM; +}; + + +namespace rowgroup +{ + struct Row; +}; + + +namespace execplan +{ + struct SimpleColumn; +}; + + + +namespace datatypes +{ + +class SystemCatalog +{ +public: + + /** the set of Calpont column widths + * + */ + enum ColWidth { ONE_BIT, ONE_BYTE, TWO_BYTE, THREE_BYTE, FOUR_BYTE, FIVE_BYTE, SIX_BYTE, SEVEN_BYTE, EIGHT_BYTE }; + + + /** the set of Calpont column data types + * + */ + enum ColDataType + { + BIT, /*!< BIT type */ + TINYINT, /*!< TINYINT type */ + CHAR, /*!< CHAR type */ + SMALLINT, /*!< SMALLINT type */ + DECIMAL, /*!< DECIMAL type */ + MEDINT, /*!< MEDINT type */ + INT, /*!< INT type */ + FLOAT, /*!< FLOAT type */ + DATE, /*!< DATE type */ + BIGINT, /*!< BIGINT type */ + DOUBLE, /*!< DOUBLE type */ + DATETIME, /*!< DATETIME type */ + VARCHAR, /*!< VARCHAR type */ + VARBINARY, /*!< VARBINARY type */ + CLOB, /*!< CLOB type */ + BLOB, /*!< BLOB type */ + UTINYINT, /*!< Unsigned TINYINT type */ + USMALLINT, /*!< Unsigned SMALLINT type */ + UDECIMAL, /*!< Unsigned DECIMAL type */ + UMEDINT, /*!< Unsigned MEDINT type */ + UINT, /*!< Unsigned INT type */ + UFLOAT, /*!< Unsigned FLOAT type */ + UBIGINT, /*!< Unsigned BIGINT type */ + UDOUBLE, /*!< Unsigned DOUBLE type */ + TEXT, /*!< TEXT type */ + TIME, /*!< TIME type */ + TIMESTAMP, /*!< TIMESTAMP type */ + NUM_OF_COL_DATA_TYPE, /* NEW TYPES ABOVE HERE */ + LONGDOUBLE, /* @bug3241, dev and variance calculation only */ + STRINT, /* @bug3532, string as int for fast comparison */ + UNDEFINED, /*!< Undefined - used in UDAF API */ + BINARY, /*!< BINARY type */ + }; + + class TypeAttributesStd + { + public: + int32_t colWidth; + int32_t scale; //number after decimal points + int32_t precision; + TypeAttributesStd() + :colWidth(0), + scale(0), + precision(-1) + {} + /** + @brief Convenience method to get int128 from a std::string. + */ + int128_t decimal128FromString(const std::string& value) const; + + /** + @brief The method sets the legacy scale and precision of a wide decimal + column which is the result of an arithmetic operation. + */ + inline void setDecimalScalePrecisionLegacy(unsigned int p, unsigned int s) + { + scale = s; + + if (s == 0) + precision = p - 1; + else + precision = p - s; + } + + /** + @brief The method sets the scale and precision of a wide decimal + column which is the result of an arithmetic operation. + */ + inline void setDecimalScalePrecision(unsigned int p, unsigned int s) + { + colWidth = (p > INT64MAXPRECISION) ? + MAXDECIMALWIDTH : MAXLEGACYWIDTH; + + precision = (p > INT128MAXPRECISION) ? + INT128MAXPRECISION : p; + + scale = s; + } + + /** + @brief The method sets the scale and precision of a wide decimal + column which is the result of an arithmetic operation, based on a heuristic. + */ + inline void setDecimalScalePrecisionHeuristic(unsigned int p, unsigned int s) + { + unsigned int diff = 0; + + if (p > INT128MAXPRECISION) + { + precision = INT128MAXPRECISION; + diff = p - INT128MAXPRECISION; + } + else + { + precision = p; + } + + scale = s; + + if (diff != 0) + { + scale = s - (int)(diff * (38.0/65.0)); + + if (scale < 0) + scale = 0; + } + } + + }; + + class TypeHolderStd: public TypeAttributesStd + { + public: + ColDataType colDataType; + TypeHolderStd() + :colDataType(MEDINT) + { } + const class TypeHandler *typeHandler() const; + boost::any getNullValueForType() const; + + /** + @brief The method detects whether decimal type is wide + using csc colType. + */ + constexpr inline bool isWideDecimalType() const + { + return (colDataType == DECIMAL || + colDataType == UDECIMAL) && + colWidth == MAXDECIMALWIDTH; + } + }; + +}; + + +/** + @brief The method detects whether decimal type is wide + using datatype and width. +*/ +static constexpr inline bool isWideDecimalType(const datatypes::SystemCatalog::ColDataType &dt, + const int32_t width) +{ + return width == MAXDECIMALWIDTH && + (dt == SystemCatalog::DECIMAL || + dt == SystemCatalog::UDECIMAL); +} + + +/** convenience function to determine if column type is a char + * type + */ +inline bool isCharType(const datatypes::SystemCatalog::ColDataType type) +{ + return (datatypes::SystemCatalog::VARCHAR == type || + datatypes::SystemCatalog::CHAR == type || + datatypes::SystemCatalog::BLOB == type || + datatypes::SystemCatalog::TEXT == type); +} + +/** convenience function to determine if column type is a + * numeric type + */ +inline bool isNumeric(const datatypes::SystemCatalog::ColDataType type) +{ + switch (type) + { + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::SMALLINT: + case datatypes::SystemCatalog::MEDINT: + case datatypes::SystemCatalog::INT: + case datatypes::SystemCatalog::BIGINT: + case datatypes::SystemCatalog::FLOAT: + case datatypes::SystemCatalog::DOUBLE: + case datatypes::SystemCatalog::DECIMAL: + case datatypes::SystemCatalog::UTINYINT: + case datatypes::SystemCatalog::USMALLINT: + case datatypes::SystemCatalog::UMEDINT: + case datatypes::SystemCatalog::UINT: + case datatypes::SystemCatalog::UBIGINT: + case datatypes::SystemCatalog::UFLOAT: + case datatypes::SystemCatalog::UDOUBLE: + case datatypes::SystemCatalog::UDECIMAL: + return true; + + default: + return false; + } +} + +inline bool isDecimal(const datatypes::SystemCatalog::ColDataType type) +{ + return (type == datatypes::SystemCatalog::DECIMAL || + type == datatypes::SystemCatalog::UDECIMAL); +} + +/** convenience function to determine if column type is an + * unsigned type + */ +inline bool isUnsigned(const datatypes::SystemCatalog::ColDataType type) +{ + switch (type) + { + case datatypes::SystemCatalog::UTINYINT: + case datatypes::SystemCatalog::USMALLINT: + case datatypes::SystemCatalog::UMEDINT: + case datatypes::SystemCatalog::UINT: + case datatypes::SystemCatalog::UBIGINT: + return true; + + default: + return false; + } +} + +inline bool isSignedInteger(const datatypes::SystemCatalog::ColDataType type) +{ + switch (type) + { + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::SMALLINT: + case datatypes::SystemCatalog::MEDINT: + case datatypes::SystemCatalog::INT: + case datatypes::SystemCatalog::BIGINT: + return true; + + default: + return false; + } +} + + +/** + @brief Returns true if all arguments have a DECIMAL/UDECIMAL type +*/ +static inline bool isDecimalOperands(const SystemCatalog::ColDataType resultDataType, + const SystemCatalog::ColDataType leftColDataType, + const SystemCatalog::ColDataType rightColDataType) +{ + return ((resultDataType == SystemCatalog::DECIMAL || + resultDataType == SystemCatalog::UDECIMAL) && + (leftColDataType == SystemCatalog::DECIMAL || + leftColDataType == SystemCatalog::UDECIMAL) && + (rightColDataType == SystemCatalog::DECIMAL || + rightColDataType == SystemCatalog::UDECIMAL)); +} + +} // end of namespace datatypes + + + + +namespace datatypes +{ + +static constexpr int128_t minInt128 = int128_t(0x8000000000000000LL) << 64; +static constexpr int128_t maxInt128 = (int128_t(0x7FFFFFFFFFFFFFFFLL) << 64) + 0xFFFFFFFFFFFFFFFFLL; + +class ConstString +{ + const char *m_str; + size_t m_length; +public: + ConstString(const char *str, size_t length) + :m_str(str), m_length(length) + { } + const char *str() const { return m_str; } + const size_t length() const { return m_length; } + const char *end() const { return m_str + m_length; } + void bin2hex(char *o) + { + static const char hexdig[] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + const char *e= end(); + for (const char *s= m_str; s < e; s++) + { + *o++ = hexdig[*s >> 4]; + *o++ = hexdig[*s & 0xf]; + } + } +}; + + +enum class round_style_t: uint8_t +{ + NONE= 0, + POS= 0x01, + NEG= 0x80 +}; + + +class SessionParam +{ + const char *m_tzname; +public: + SessionParam(const char *tzname) + :m_tzname(tzname) + { } + const char *tzname() const + { + return m_tzname; + } +}; + + +class SimpleValue +{ + int64_t m_sint64; + int128_t m_sint128; + const char *m_tzname; +public: + SimpleValue(const int64_t sint64, + const int128_t &sint128, + const char *tzname) + :m_sint64(sint64), m_sint128(sint128), m_tzname(tzname) + { } + SimpleValue() + :m_sint64(0), m_sint128(0), m_tzname(0) + { } + int64_t toSInt64() const { return m_sint64; } + uint64_t toUInt64() const { return static_cast(m_sint64); } + int128_t toSInt128() const { return m_sint128; } + const char *tzname() const { return m_tzname; } +}; + + +class SimpleValueSInt64: public SimpleValue +{ +public: + SimpleValueSInt64(int64_t value) + :SimpleValue(value, 0, NULL) + { } +}; + + +class SimpleValueUInt64: public SimpleValue +{ +public: + SimpleValueUInt64(uint64_t value) + :SimpleValue(static_cast(value), 0, NULL) + { } +}; + + +class SimpleValueSInt128: public SimpleValue +{ +public: + SimpleValueSInt128(int128_t value) + :SimpleValue(0, value, NULL) + { } +}; + + +class SimpleValueTimestamp: public SimpleValue +{ +public: + SimpleValueTimestamp(uint64_t value, const char *tzname) + :SimpleValue(static_cast(value), 0, tzname) + { } +}; + + +class MinMaxInfo +{ +public: + int64_t min; + int64_t max; + union + { + int128_t int128Min; + int64_t min_; + }; + union + { + int128_t int128Max; + int64_t max_; + }; + MinMaxInfo() + :min((uint64_t)0x8000000000000001ULL), + max((uint64_t) - 0x8000000000000001LL) + { + int128Min = datatypes::minInt128; + int128Max = datatypes::maxInt128; + }; + bool isEmptyOrNullSInt64() const + { + return min == std::numeric_limits::max() && + max == std::numeric_limits::min(); + } + bool isEmptyOrNullUInt64() const + { + return static_cast(min) == std::numeric_limits::max() && + static_cast(max) == std::numeric_limits::min(); + } + bool isEmptyOrNullSInt128() const + { + return int128Min == datatypes::maxInt128 && + int128Max == datatypes::minInt128; + } + void widenSInt64(const MinMaxInfo &partInfo) + { + min = partInfo.min < min ? partInfo.min : min; + max = partInfo.max > max ? partInfo.max : max; + } + void widenUInt64(const MinMaxInfo &partInfo) + { + min = static_cast(partInfo.min < static_cast(min) ? partInfo.min : min); + max = static_cast(partInfo.max > static_cast(max) ? partInfo.max : max); + } + void widenSInt128(const MinMaxInfo &partInfo) + { + int128Min = partInfo.int128Min < int128Min ? partInfo.int128Min : int128Min; + int128Max = partInfo.int128Max > int128Max ? partInfo.int128Max : int128Max; + } + static MinMaxInfo widenSInt64(const MinMaxInfo &a, + const MinMaxInfo &b) + { + MinMaxInfo tmp= a; + tmp.widenSInt64(b); + return tmp; + } + static MinMaxInfo widenUInt64(const MinMaxInfo &a, + const MinMaxInfo &b) + { + MinMaxInfo tmp(a); + tmp.widenUInt64(b); + return tmp; + } + static MinMaxInfo widenSInt128(const MinMaxInfo &a, + const MinMaxInfo &b) + { + MinMaxInfo tmp= a; + tmp.widenSInt128(b); + return tmp; + } +}; + + +class MinMaxPartitionInfo: public MinMaxInfo +{ + enum status_flag_t : uint64_t + { + ET_DISABLED = 0x0002, + CPINVALID = 0x0004 + }; + uint64_t m_status; +public: + MinMaxPartitionInfo() + :m_status(0) + { }; + MinMaxPartitionInfo(const BRM::EMEntry &entry); + void set_invalid() { m_status|= CPINVALID; } + const bool is_invalid() const { return m_status & CPINVALID; } + const bool is_disabled() const { return m_status & ET_DISABLED; } + + bool isSuitableSInt64(const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const + { + if (min >= startVal.toSInt64() && + max <= endVal.toSInt64() && + !(min == std::numeric_limits::max() && + max == std::numeric_limits::min())) + { + if (rfMin == round_style_t::POS && min == startVal.toSInt64()) + return false; + + if (rfMax == round_style_t::NEG && max == endVal.toSInt64()) + return false; + + return true; + } + return false; + } + bool isSuitableUInt64(const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const + { + if (static_cast(min) >= startVal.toUInt64() && + static_cast(max) <= endVal.toUInt64() && + !(static_cast(min) == std::numeric_limits::max() && + max == 0)) + { + if (rfMin == round_style_t::POS && min == startVal.toSInt64()) + return false; + + if (rfMax == round_style_t::NEG && max == endVal.toSInt64()) + return false; + return true; + } + return false; + } + bool isSuitableSInt128(const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const + { + if (int128Min >= startVal.toSInt128() && + int128Max <= endVal.toSInt128() && + !(int128Min == datatypes::maxInt128 && + int128Max == datatypes::minInt128)) + { + if (rfMin == round_style_t::POS && int128Min == startVal.toSInt128()) + return false; + + if (rfMax == round_style_t::NEG && int128Max == endVal.toSInt128()) + return false; + + return true; + } + return false; + } +}; + + +class ColBatchWriter +{ + FILE *m_filePtr; + char m_delimiter; + char m_enclosed_by; + bool m_utf8; +public: + ColBatchWriter(FILE *f, + char delimiter, + char enclosed_by, + bool utf8) + :m_filePtr(f), + m_delimiter(delimiter), + m_enclosed_by(enclosed_by), + m_utf8(utf8) + { } + FILE *filePtr() const { return m_filePtr; } + char delimiter() const { return m_delimiter; } + char enclosed_by() const { return m_enclosed_by; } + bool utf8() const { return m_utf8; } +}; + + +class SimpleColumnParam +{ + uint32_t m_sessionid; + bool m_columnStore; +public: + SimpleColumnParam(uint32_t sessionid, bool columnStore) + :m_sessionid(sessionid), + m_columnStore(columnStore) + { } + uint32_t sessionid() const { return m_sessionid; } + bool columnStore() const { return m_columnStore; } + void columnStore(bool value) { m_columnStore= value; } +}; + + +class DatabaseQualifiedColumnName +{ + std::string m_db; + std::string m_table; + std::string m_column; +public: + DatabaseQualifiedColumnName(const std::string &db, + const std::string &table, + const std::string &column) + :m_db(db), + m_table(table), + m_column(column) + { } + const std::string &db() const { return m_db; } + const std::string &table() const { return m_table; } + const std::string &column() const { return m_column; } +}; + + +class StoreField +{ +public: + virtual int32_t colWidth() const = 0; + virtual int32_t precision() const = 0; + virtual int store_date(int64_t val) = 0; + virtual int store_datetime(int64_t val) = 0; + virtual int store_time(int64_t val) = 0; + virtual int store_timestamp(int64_t val) = 0; + virtual int store_string(const char *str, size_t length) = 0; + virtual int store_varbinary(const char *str, size_t length) = 0; + virtual int store_xlonglong(int64_t val) = 0; + virtual int store_float(float val) = 0; + virtual int store_double(double val) = 0; + virtual int store_long_double(long double val) = 0; + virtual int store_decimal64(int64_t val) = 0; + virtual int store_decimal128(const int128_t &val) = 0; + virtual int store_lob(const char *str, size_t length) = 0; +}; + + +class WriteBatchField +{ +public: + virtual size_t ColWriteBatchDate(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchDatetime(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchTime(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchTimestamp(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchChar(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchVarchar(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchSInt64(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchUInt64(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchSInt32(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchUInt32(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchSInt16(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchUInt16(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchSInt8(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchUInt8(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchXFloat(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchXDouble(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchSLongDouble(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchXDecimal(const unsigned char *buf, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchVarbinary(const unsigned char *buf0, bool nullVal, ColBatchWriter &ci) = 0; + virtual size_t ColWriteBatchBlob(const unsigned char *buf0, bool nullVal, ColBatchWriter &ci) = 0; +}; + + +class TypeHandler +{ +public: + using code_t = datatypes::SystemCatalog::ColDataType; +protected: + std::string formatPartitionInfoSInt64(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const; + std::string formatPartitionInfoUInt64(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const; + + std::string PrintPartitionValueSInt64(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const; + + std::string PrintPartitionValueUInt64(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const; + +public: + static const TypeHandler *find(SystemCatalog::ColDataType typeCode, + const SystemCatalog::TypeAttributesStd &attr); + static const TypeHandler *find_by_ddltype(const ddlpackage::ColumnType &ct); + virtual ~TypeHandler() { } + virtual const string & name() const= 0; + virtual const string print(const SystemCatalog::TypeAttributesStd &attr) const + { + return name(); + } + virtual code_t code() const= 0; + virtual bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const + { + return false; + } + virtual uint8_t PartitionValueCharLength(const SystemCatalog::TypeAttributesStd &attr) + const + { + return 30; + } + virtual size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const= 0; + virtual int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const= 0; + + virtual std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const = 0; + + virtual std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const= 0; + virtual execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const= 0; + virtual SimpleValue getMinValueSimple() const + { + return SimpleValue(std::numeric_limits::min(), + std::numeric_limits::min(), + 0); + } + virtual SimpleValue getMaxValueSimple() const + { + return SimpleValue(std::numeric_limits::max(), + std::numeric_limits::max(), + 0); + } + virtual SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const= 0; + virtual MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &a, + const MinMaxInfo &b) const + { + return MinMaxInfo::widenSInt64(a, b); + } + virtual MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const; + virtual string PrintPartitionValue(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const + { + return PrintPartitionValueSInt64(attr, partInfo, + startVal, rfMin, + endVal, rfMax); + } + virtual bool isSuitablePartition(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &part, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const + { + return part.isSuitableSInt64(startVal, rfMin, endVal, rfMax); + } + virtual boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const = 0; +}; + + +// QQ: perhaps not needed yet +class TypeHandlerBit: public TypeHandler +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::BIT; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + idbassert(0); // QQ + return 0; + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + idbassert(0); // QQ + return 1; + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return "0"; // QQ + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) const override + { + idbassert(0); + return "Error"; + } + + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override + { + idbassert(0); + return NULL; + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override + { + idbassert(0); + return SimpleValue(); + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override + { + //TODO: How to communicate with write engine? + return boost::any(); + } +}; + + +class TypeHandlerInt: public TypeHandler +{ +protected: + int storeValueToFieldSInt32(rowgroup::Row &row, int pos, + StoreField *f) const; + int storeValueToFieldUInt32(rowgroup::Row &row, int pos, + StoreField *f) const; + std::string formatSInt64(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const; + std::string formatUInt64(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const; + +}; + + +class TypeHandlerSInt8: public TypeHandlerInt +{ +public: + const string &name() const override; + code_t code() const override + { + return SystemCatalog::TINYINT; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchSInt8(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return formatSInt64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoSInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue getMinValueSimple() const override + { + return SimpleValueSInt64(std::numeric_limits::min()); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueSInt64(std::numeric_limits::max()); + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerSInt16: public TypeHandlerInt +{ +public: + const string &name() const override; + code_t code() const override + { + return SystemCatalog::SMALLINT; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchSInt16(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return formatSInt64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoSInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue getMinValueSimple() const override + { + return SimpleValueSInt64(std::numeric_limits::min()); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueSInt64(std::numeric_limits::max()); + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerSInt24: public TypeHandlerInt +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::MEDINT; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchSInt32(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldSInt32(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return formatSInt64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoSInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue getMinValueSimple() const override + { + return SimpleValueSInt64(MIN_MEDINT); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueSInt64(MAX_MEDINT); + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerSInt32: public TypeHandlerInt +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::INT; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchSInt32(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldSInt32(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return formatSInt64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoSInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue getMinValueSimple() const override + { + return SimpleValueSInt64(std::numeric_limits::min()); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueSInt64(std::numeric_limits::max()); + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerSInt64: public TypeHandlerInt +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::BIGINT; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchSInt64(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return formatSInt64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoSInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue getMinValueSimple() const override + { + return SimpleValueSInt64(std::numeric_limits::min()); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueSInt64(std::numeric_limits::max()); + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerUInt8: public TypeHandlerInt +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::UTINYINT; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchUInt8(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return formatUInt64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoUInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + + SimpleValue getMinValueSimple() const override + { + return SimpleValueUInt64(0); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueUInt64(std::numeric_limits::max()); + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &a, + const MinMaxInfo &b) const override + { + return MinMaxInfo::widenUInt64(a, b); + } + string PrintPartitionValue(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return PrintPartitionValueUInt64(attr, partInfo, + startVal, rfMin, + endVal, rfMax); + } + bool isSuitablePartition(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &part, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return part.isSuitableUInt64(startVal, rfMin, endVal, rfMax); + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerUInt16: public TypeHandlerInt +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::USMALLINT; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchUInt16(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return formatUInt64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoUInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue getMinValueSimple() const override + { + return SimpleValueUInt64(0); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueUInt64(std::numeric_limits::max()); + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &a, + const MinMaxInfo &b) const override + { + return MinMaxInfo::widenUInt64(a, b); + } + string PrintPartitionValue(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return PrintPartitionValueUInt64(attr, partInfo, + startVal, rfMin, + endVal, rfMax); + } + bool isSuitablePartition(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &part, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return part.isSuitableUInt64(startVal, rfMin, endVal, rfMax); + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerUInt24: public TypeHandlerInt +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::UMEDINT; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchUInt32(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldUInt32(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return formatUInt64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoUInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue getMinValueSimple() const override + { + return SimpleValueUInt64(0); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueUInt64(MAX_UMEDINT); + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &a, + const MinMaxInfo &b) const override + { + return MinMaxInfo::widenUInt64(a, b); + } + string PrintPartitionValue(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return PrintPartitionValueUInt64(attr, partInfo, + startVal, rfMin, + endVal, rfMax); + } + bool isSuitablePartition(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &part, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return part.isSuitableUInt64(startVal, rfMin, endVal, rfMax); + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerUInt32: public TypeHandlerInt +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::UINT; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchUInt32(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldUInt32(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return formatUInt64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoUInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue getMinValueSimple() const override + { + return SimpleValueUInt64(0); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueUInt64(std::numeric_limits::max()); + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &a, + const MinMaxInfo &b) const override + { + return MinMaxInfo::widenUInt64(a, b); + } + string PrintPartitionValue(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return PrintPartitionValueUInt64(attr, partInfo, + startVal, rfMin, + endVal, rfMax); + } + bool isSuitablePartition(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &part, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return part.isSuitableUInt64(startVal, rfMin, endVal, rfMax); + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerUInt64: public TypeHandlerInt +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::BIGINT; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchUInt64(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return formatUInt64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoUInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue getMinValueSimple() const override + { + return SimpleValueUInt64(0); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueUInt64(std::numeric_limits::max()); + } + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &a, + const MinMaxInfo &b) const override + { + return MinMaxInfo::widenUInt64(a, b); + } + string PrintPartitionValue(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return PrintPartitionValueUInt64(attr, partInfo, + startVal, rfMin, + endVal, rfMax); + } + bool isSuitablePartition(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &part, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return part.isSuitableUInt64(startVal, rfMin, endVal, rfMax); + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerXDecimal: public TypeHandler +{ +protected: + + static bool isValidXDecimal64(const SystemCatalog::TypeAttributesStd &attr) + { + return attr.colWidth <= 8; + } + static bool isValidXDecimal128(const SystemCatalog::TypeAttributesStd &attr) + { + return attr.colWidth == 16; + } + int storeValueToField64(rowgroup::Row &row, int pos, + StoreField *f) const; + int storeValueToField128(rowgroup::Row &row, int pos, + StoreField *f) const; + + std::string format64(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const; + std::string format128(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const; + std::string formatPartitionInfo128(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const; + + MinMaxPartitionInfo getExtentPartitionInfo64(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const; + MinMaxPartitionInfo getExtentPartitionInfo128(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const; + string PrintPartitionValue128(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const; + +public: + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchXDecimal(buf, nullVal, writer); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerSDecimal64: public TypeHandlerXDecimal +{ +public: + const string &name() const override; + code_t code() const override + { + return SystemCatalog::DECIMAL; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + uint8_t PartitionValueCharLength(const SystemCatalog::TypeAttributesStd &attr) + const override + { + return 30; + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToField64(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return format64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) const override + { + return formatPartitionInfoSInt64(attr, i); + } + SimpleValue getMinValueSimple() const override + { + return SimpleValueSInt64(std::numeric_limits::min()); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueSInt64(std::numeric_limits::max()); + } + MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &a, + const MinMaxInfo &b) const override + { + return MinMaxInfo::widenSInt64(a, b); + } + MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const override + { + return getExtentPartitionInfo64(attr, em, entry, state); + } + string PrintPartitionValue(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return PrintPartitionValueSInt64(attr, partInfo, + startVal, rfMin, + endVal, rfMax); + } + bool isSuitablePartition(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &part, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return part.isSuitableSInt64(startVal, rfMin, endVal, rfMax); + } +}; + + +class TypeHandlerUDecimal64: public TypeHandlerXDecimal +{ +public: + const string &name() const override; + code_t code() const override + { + return SystemCatalog::UDECIMAL; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + uint8_t PartitionValueCharLength(const SystemCatalog::TypeAttributesStd &attr) + const override + { + return 30; + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToField64(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return format64(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) const override + { + return formatPartitionInfoSInt64(attr, i); + } + SimpleValue getMinValueSimple() const override + { + return SimpleValueUInt64(0); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueUInt64(std::numeric_limits::max()); + } + MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &a, + const MinMaxInfo &b) const override + { + return MinMaxInfo::widenSInt64(a, b); + } + MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const override + { + return getExtentPartitionInfo64(attr, em, entry, state); + } + string PrintPartitionValue(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return PrintPartitionValueSInt64(attr, partInfo, + startVal, rfMin, + endVal, rfMax); + } + bool isSuitablePartition(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &part, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return part.isSuitableSInt64(startVal, rfMin, endVal, rfMax); + } +}; + + +class TypeHandlerSDecimal128: public TypeHandlerXDecimal +{ +public: + const string &name() const override; + code_t code() const override + { + return SystemCatalog::DECIMAL; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + uint8_t PartitionValueCharLength(const SystemCatalog::TypeAttributesStd &attr) + const override + { + return Decimal::MAXLENGTH16BYTES; + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToField128(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return format128(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) const override + { + return formatPartitionInfo128(attr, i); + } + SimpleValue getMinValueSimple() const override + { + return SimpleValue(std::numeric_limits::min(), + datatypes::minInt128, + 0); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValue(std::numeric_limits::max(), + datatypes::maxInt128, + 0); + } + MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &a, + const MinMaxInfo &b) const override + { + return MinMaxInfo::widenSInt128(a, b); + } + MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const override + { + return getExtentPartitionInfo128(attr, em, entry, state); + } + string PrintPartitionValue(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return PrintPartitionValue128(attr, partInfo, startVal, rfMin, endVal, rfMax); + } + bool isSuitablePartition(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &part, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return part.isSuitableSInt128(startVal, rfMin, endVal, rfMax); + } +}; + + +class TypeHandlerUDecimal128: public TypeHandlerXDecimal +{ +public: + const string &name() const override; + code_t code() const override + { + return SystemCatalog::UDECIMAL; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + uint8_t PartitionValueCharLength(const SystemCatalog::TypeAttributesStd &attr) + const override + { + return Decimal::MAXLENGTH16BYTES; + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToField128(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return format128(v, attr); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) const override + { + return formatPartitionInfo128(attr, i); + } + SimpleValue getMinValueSimple() const override + { + return SimpleValueSInt128(0); + } + SimpleValue getMaxValueSimple() const override + { + return SimpleValueSInt128(-1); + } + MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &a, + const MinMaxInfo &b) const override + { + return MinMaxInfo::widenSInt128(a, b); + } + MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const override + { + return getExtentPartitionInfo128(attr, em, entry, state); + } + string PrintPartitionValue(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &partInfo, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return PrintPartitionValue128(attr, partInfo, startVal, rfMin, endVal, rfMax); + } + bool isSuitablePartition(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxPartitionInfo &part, + const SimpleValue &startVal, + round_style_t rfMin, + const SimpleValue &endVal, + round_style_t rfMax) const override + { + return part.isSuitableSInt128(startVal, rfMin, endVal, rfMax); + } +}; + + +class TypeHandlerReal: public TypeHandler +{ +public: + int storeValueToFieldXFloat(rowgroup::Row &row, int pos, + StoreField *f) const; + int storeValueToFieldXDouble(rowgroup::Row &row, int pos, + StoreField *f) const; + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override + { + return SimpleValue(); // QQ: real types were not handled in IDB_format() + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return "0"; // QQ + } +}; + + +class TypeHandlerSFloat: public TypeHandlerReal +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::FLOAT; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchXFloat(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldXFloat(row, pos, f); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoSInt64(attr, i); + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerSDouble: public TypeHandlerReal +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::DOUBLE; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchXDouble(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldXDouble(row, pos, f); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoSInt64(attr, i); + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerUFloat: public TypeHandlerReal +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::UFLOAT; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchXFloat(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldXFloat(row, pos, f); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoSInt64(attr, i); + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerUDouble: public TypeHandlerReal +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::UDOUBLE; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchXDouble(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldXDouble(row, pos, f); + } + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoSInt64(attr, i); + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerSLongDouble: public TypeHandlerReal +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::LONGDOUBLE; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchSLongDouble(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + idbassert(0); + return "Error"; + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override + { + // QQ: DDLPackageProcessor::getNullValueForType() did not handle LONGDOUBLE + return boost::any(); + } +}; + + +class TypeHandlerTemporal: public TypeHandler +{ +public: + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + return formatPartitionInfoSInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; +}; + + +class TypeHandlerDate: public TypeHandlerTemporal +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::DATE; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchDate(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override; + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerDatetime: public TypeHandlerTemporal +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::DATETIME; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchDatetime(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override; + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerTime: public TypeHandlerTemporal +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::TIME; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchTime(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override; + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerTimestamp: public TypeHandlerTemporal +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::TIMESTAMP; + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return true; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchTimestamp(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override; + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerStr: public TypeHandler +{ +protected: + std::string formatPartitionInfoSmallCharVarchar( + const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const; + boost::any getNullValueForTypeVarcharText(const SystemCatalog::TypeAttributesStd &attr) + const; +public: + int storeValueToFieldCharVarchar(rowgroup::Row &row, int pos, + StoreField *f) const; + int storeValueToFieldBlobText(rowgroup::Row &row, int pos, + StoreField *f) const; + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override + { + // QQ: Check with Roman if this correct: + return formatPartitionInfoSInt64(attr, i); + } + execplan::SimpleColumn *newSimpleColumn(const DatabaseQualifiedColumnName &name, + SystemCatalog::TypeHolderStd &ct, + const SimpleColumnParam &prm) + const override; + SimpleValue toSimpleValue(const SessionParam &sp, + const SystemCatalog::TypeAttributesStd &attr, + const char *str, round_style_t & rf) const override; +}; + + +class TypeHandlerChar: public TypeHandlerStr +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::CHAR; + } + const string print(const SystemCatalog::TypeAttributesStd &attr) const override + { + ostringstream oss; + oss << name () << "(" << attr.colWidth << ")"; + return oss.str(); + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return attr.colWidth <= 8; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchChar(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldCharVarchar(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override; + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override; + MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerVarchar: public TypeHandlerStr +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::VARCHAR; + } + const string print(const SystemCatalog::TypeAttributesStd &attr) const override + { + ostringstream oss; + oss << name () << "(" << attr.colWidth << ")"; + return oss.str(); + } + bool CP_type(const SystemCatalog::TypeAttributesStd &attr) const override + { + return attr.colWidth <= 7; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchVarchar(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldCharVarchar(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override; + std::string formatPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + const MinMaxInfo &i) + const override; + MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr, + BRM::DBRM &em, + const BRM::EMEntry &entry, + int *state) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override + { + return getNullValueForTypeVarcharText(attr); + } +}; + + +class TypeHandlerVarbinary: public TypeHandlerStr +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::VARBINARY; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchVarbinary(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override; + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override; + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerBlob: public TypeHandlerStr +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::BLOB; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchBlob(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldBlobText(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return "0"; // QQ + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override; +}; + + +class TypeHandlerText: public TypeHandlerStr +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::TEXT; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + return field->ColWriteBatchBlob(buf, nullVal, writer); + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + return storeValueToFieldBlobText(row, pos, f); + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return "0"; // QQ + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override + { + return getNullValueForTypeVarcharText(attr); + } +}; + + +class TypeHandlerClob: public TypeHandlerStr +{ + const string &name() const override; + code_t code() const override + { + return SystemCatalog::CLOB; + } + size_t ColWriteBatch(WriteBatchField *field, + const unsigned char *buf, + bool nullVal, + ColBatchWriter & writer) const override + { + idbassert(0); // QQ + return 0; + } + int storeValueToField(rowgroup::Row &row, int pos, + StoreField *f) const override + { + idbassert(0); // QQ + return 1; + } + std::string format(const SimpleValue &v, + const SystemCatalog::TypeAttributesStd &attr) const override + { + return "0"; // QQ + } + boost::any getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) + const override + { + return boost::any(); // QQ + } +}; + + +}// end of namespace datatypes + +#endif //MCS_DATATYPE_H_INCLUDED + +// vim:ts=2 sw=2: diff --git a/datatypes/mcs_decimal.cpp b/datatypes/mcs_decimal.cpp index 4b7c4e7c6..f66cc68ef 100644 --- a/datatypes/mcs_decimal.cpp +++ b/datatypes/mcs_decimal.cpp @@ -18,9 +18,10 @@ #include #include +#include "utils/common/branchpred.h" #include "mcs_decimal.h" -#include "treenode.h" #include "exceptclasses.h" +#include "dataconvert.h" namespace datatypes { @@ -48,16 +49,16 @@ namespace datatypes template - void addSubtractExecute(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, - execplan::IDB_Decimal& result, + void addSubtractExecute(const VDecimal& l, + const VDecimal& r, + VDecimal& result, BinaryOperation op, OpOverflowCheck opOverflowCheck, MultiplicationOverflowCheck mulOverflowCheck) { - int128_t lValue = Decimal::isWideDecimalType(l.precision) + int128_t lValue = Decimal::isWideDecimalTypeByPrecision(l.precision) ? l.s128Value : l.value; - int128_t rValue = Decimal::isWideDecimalType(r.precision) + int128_t rValue = Decimal::isWideDecimalTypeByPrecision(r.precision) ? r.s128Value : r.value; if (result.scale == l.scale && result.scale == r.scale) @@ -108,15 +109,15 @@ namespace datatypes template - void divisionExecute(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, - execplan::IDB_Decimal& result, + void divisionExecute(const VDecimal& l, + const VDecimal& r, + VDecimal& result, OpOverflowCheck opOverflowCheck, MultiplicationOverflowCheck mulOverflowCheck) { - int128_t lValue = Decimal::isWideDecimalType(l.precision) + int128_t lValue = Decimal::isWideDecimalTypeByPrecision(l.precision) ? l.s128Value : l.value; - int128_t rValue = Decimal::isWideDecimalType(r.precision) + int128_t rValue = Decimal::isWideDecimalTypeByPrecision(r.precision) ? r.s128Value : r.value; opOverflowCheck(lValue, rValue); @@ -147,15 +148,15 @@ namespace datatypes template - void multiplicationExecute(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, - execplan::IDB_Decimal& result, + void multiplicationExecute(const VDecimal& l, + const VDecimal& r, + VDecimal& result, OpOverflowCheck opOverflowCheck, MultiplicationOverflowCheck mulOverflowCheck) { - int128_t lValue = Decimal::isWideDecimalType(l.precision) + int128_t lValue = Decimal::isWideDecimalTypeByPrecision(l.precision) ? l.s128Value : l.value; - int128_t rValue = Decimal::isWideDecimalType(r.precision) + int128_t rValue = Decimal::isWideDecimalTypeByPrecision(r.precision) ? r.s128Value : r.value; if (lValue == 0 || rValue == 0) @@ -194,36 +195,21 @@ namespace datatypes } } - std::string Decimal::toString(execplan::IDB_Decimal& value) + std::string Decimal::toString(VDecimal& value) { - char buf[utils::MAXLENGTH16BYTES]; + char buf[Decimal::MAXLENGTH16BYTES]; dataconvert::DataConvert::decimalToString(&value.s128Value, - value.scale, buf, sizeof(buf), - execplan::CalpontSystemCatalog::DECIMAL); + value.scale, buf, (uint8_t) sizeof(buf), + datatypes::SystemCatalog::DECIMAL); return std::string(buf); } - std::string Decimal::toString(const execplan::IDB_Decimal& value) + std::string Decimal::toString(const VDecimal& value) { - return toString(const_cast(value)); + return toString(const_cast(value)); } - // Compare perf with f(string&, ColTypeAlias&, int128_t&) - int128_t Decimal::int128FromString(const std::string& value, - ColTypeAlias& colType) - { - int128_t result = 0; - bool pushWarning = false; - bool noRoundup = false; - dataconvert::number_int_value(value, - colType, - pushWarning, - noRoundup, - result); - return result; - } - - int Decimal::compare(const execplan::IDB_Decimal& l, const execplan::IDB_Decimal& r) + int Decimal::compare(const VDecimal& l, const VDecimal& r) { int128_t divisorL, divisorR; getScaleDivisor(divisorL, l.scale); @@ -270,8 +256,8 @@ namespace datatypes // no overflow check template<> - void Decimal::addition(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::addition(const VDecimal& l, + const VDecimal& r, VDecimal& result) { std::plus add; NoOverflowCheck noOverflowCheck; @@ -280,8 +266,8 @@ namespace datatypes // with overflow check template<> - void Decimal::addition(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::addition(const VDecimal& l, + const VDecimal& r, VDecimal& result) { std::plus add; AdditionOverflowCheck overflowCheck; @@ -291,8 +277,8 @@ namespace datatypes // no overflow check template<> - void Decimal::addition(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::addition(const VDecimal& l, + const VDecimal& r, VDecimal& result) { if (result.scale == l.scale && result.scale == r.scale) { @@ -321,8 +307,8 @@ namespace datatypes // with overflow check template<> - void Decimal::addition(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::addition(const VDecimal& l, + const VDecimal& r, VDecimal& result) { AdditionOverflowCheck additionOverflowCheck; MultiplicationOverflowCheck mulOverflowCheck; @@ -356,8 +342,8 @@ namespace datatypes // no overflow check template<> - void Decimal::subtraction(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::subtraction(const VDecimal& l, + const VDecimal& r, VDecimal& result) { std::minus subtract; NoOverflowCheck noOverflowCheck; @@ -366,8 +352,8 @@ namespace datatypes // with overflow check template<> - void Decimal::subtraction(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::subtraction(const VDecimal& l, + const VDecimal& r, VDecimal& result) { std::minus subtract; SubtractionOverflowCheck overflowCheck; @@ -377,8 +363,8 @@ namespace datatypes // no overflow check template<> - void Decimal::subtraction(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::subtraction(const VDecimal& l, + const VDecimal& r, VDecimal& result) { if (result.scale == l.scale && result.scale == r.scale) { @@ -407,8 +393,8 @@ namespace datatypes // with overflow check template<> - void Decimal::subtraction(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::subtraction(const VDecimal& l, + const VDecimal& r, VDecimal& result) { SubtractionOverflowCheck subtractionOverflowCheck; MultiplicationOverflowCheck mulOverflowCheck; @@ -442,8 +428,8 @@ namespace datatypes // no overflow check template<> - void Decimal::division(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::division(const VDecimal& l, + const VDecimal& r, VDecimal& result) { NoOverflowCheck noOverflowCheck; divisionExecute(l, r, result, noOverflowCheck, noOverflowCheck); @@ -451,8 +437,8 @@ namespace datatypes // With overflow check template<> - void Decimal::division(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::division(const VDecimal& l, + const VDecimal& r, VDecimal& result) { DivisionOverflowCheck overflowCheck; MultiplicationOverflowCheck mulOverflowCheck; @@ -462,8 +448,8 @@ namespace datatypes // no overflow check // We rely on the zero check from ArithmeticOperator::execute template<> - void Decimal::division(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::division(const VDecimal& l, + const VDecimal& r, VDecimal& result) { if (result.scale >= l.scale - r.scale) result.value = (int64_t)(( (l.value > 0 && r.value > 0) || (l.value < 0 && r.value < 0) ? @@ -477,8 +463,8 @@ namespace datatypes // With overflow check template<> - void Decimal::division(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::division(const VDecimal& l, + const VDecimal& r, VDecimal& result) { DivisionOverflowCheck divisionOverflowCheck; @@ -497,8 +483,8 @@ namespace datatypes // no overflow check template<> - void Decimal::multiplication(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::multiplication(const VDecimal& l, + const VDecimal& r, VDecimal& result) { MultiplicationNoOverflowCheck noOverflowCheck; multiplicationExecute(l, r, result, noOverflowCheck, noOverflowCheck); @@ -506,8 +492,8 @@ namespace datatypes // With overflow check template<> - void Decimal::multiplication(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::multiplication(const VDecimal& l, + const VDecimal& r, VDecimal& result) { MultiplicationOverflowCheck mulOverflowCheck; multiplicationExecute(l, r, result, mulOverflowCheck, mulOverflowCheck); @@ -515,8 +501,8 @@ namespace datatypes // no overflow check template<> - void Decimal::multiplication(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::multiplication(const VDecimal& l, + const VDecimal& r, VDecimal& result) { if (result.scale >= l.scale + r.scale) result.value = l.value * r.value * mcs_pow_10[result.scale - (l.scale + r.scale)]; @@ -528,8 +514,8 @@ namespace datatypes // With overflow check template<> - void Decimal::multiplication(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, execplan::IDB_Decimal& result) + void Decimal::multiplication(const VDecimal& l, + const VDecimal& r, VDecimal& result) { MultiplicationOverflowCheck mulOverflowCheck; diff --git a/datatypes/mcs_decimal.h b/datatypes/mcs_decimal.h index 178dce1ba..dcef8b947 100644 --- a/datatypes/mcs_decimal.h +++ b/datatypes/mcs_decimal.h @@ -20,17 +20,16 @@ #include #include - -#include "calpontsystemcatalog.h" +#include +#include "exceptclasses.h" +#include "widedecimalutils.h" using int128_t = __int128; using uint128_t = unsigned __int128; -using ColTypeAlias = execplan::CalpontSystemCatalog::ColType; -using ColDataTypeAlias = execplan::CalpontSystemCatalog::ColDataType; -namespace execplan +namespace datatypes { - struct IDB_Decimal; + struct VDecimal; } // A class by Fabio Fernandes pulled off of stackoverflow @@ -81,8 +80,6 @@ constexpr uint8_t INT128MAXPRECISION = 38U; constexpr uint8_t MAXLEGACYWIDTH = 8U; constexpr uint8_t MAXSCALEINC4AVG = 4U; constexpr int8_t IGNOREPRECISION = -1; -constexpr uint8_t MAXLENGTH16BYTES = 42; -constexpr uint8_t MAXLENGTH8BYTES = 23; @@ -175,154 +172,109 @@ class Decimal Decimal() { }; ~Decimal() { }; + static constexpr uint8_t MAXLENGTH16BYTES = 42; + static constexpr uint8_t MAXLENGTH8BYTES = 23; + + static inline bool isWideDecimalNullValue(const int128_t& val) + { + const uint64_t* ptr = reinterpret_cast(&val); + return (ptr[0] == utils::BINARYNULLVALUELOW && ptr[1] == utils::BINARYNULLVALUEHIGH); + } + + static inline bool isWideDecimalEmptyValue(const int128_t& val) + { + const uint64_t* ptr = reinterpret_cast(&val); + return (ptr[0] == utils::BINARYEMPTYVALUELOW && ptr[1] == utils::BINARYEMPTYVALUEHIGH); + } + + static inline void setWideDecimalNullValue(int128_t& val) + { + uint64_t* ptr = reinterpret_cast(&val); + ptr[0] = utils::BINARYNULLVALUELOW; + ptr[1] = utils::BINARYNULLVALUEHIGH; + } + + static inline void setWideDecimalEmptyValue(int128_t& val) + { + uint64_t* ptr = reinterpret_cast(&val); + ptr[0] = utils::BINARYEMPTYVALUELOW; + ptr[1] = utils::BINARYEMPTYVALUEHIGH; + } + + static inline void setWideDecimalNullValue(int128_t* val) + { + uint64_t* ptr = reinterpret_cast(val); + ptr[0] = utils::BINARYNULLVALUELOW; + ptr[1] = utils::BINARYNULLVALUEHIGH; + } + + static inline void setWideDecimalEmptyValue(int128_t* val) + { + uint64_t* ptr = reinterpret_cast(val); + ptr[0] = utils::BINARYEMPTYVALUELOW; + ptr[1] = utils::BINARYEMPTYVALUEHIGH; + } + + static constexpr int128_t minInt128 = int128_t(0x8000000000000000LL) << 64; static constexpr int128_t maxInt128 = (int128_t(0x7FFFFFFFFFFFFFFFLL) << 64) + 0xFFFFFFFFFFFFFFFFLL; /** - @brief Compares two IDB_Decimal taking scale into account. + @brief Compares two VDecimal taking scale into account. */ - static int compare(const execplan::IDB_Decimal& l, const execplan::IDB_Decimal& r); + static int compare(const VDecimal& l, const VDecimal& r); /** @brief Addition template that supports overflow check and two internal representations of decimal. */ template - static void addition(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, - execplan::IDB_Decimal& result); + static void addition(const VDecimal& l, + const VDecimal& r, + VDecimal& result); /** @brief Subtraction template that supports overflow check and two internal representations of decimal. */ template - static void subtraction(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, - execplan::IDB_Decimal& result); + static void subtraction(const VDecimal& l, + const VDecimal& r, + VDecimal& result); /** @brief Division template that supports overflow check and two internal representations of decimal. */ template - static void division(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, - execplan::IDB_Decimal& result); + static void division(const VDecimal& l, + const VDecimal& r, + VDecimal& result); /** @brief Multiplication template that supports overflow check and two internal representations of decimal. */ template - static void multiplication(const execplan::IDB_Decimal& l, - const execplan::IDB_Decimal& r, - execplan::IDB_Decimal& result); + static void multiplication(const VDecimal& l, + const VDecimal& r, + VDecimal& result); /** @brief Convenience method to put decimal into a std::string. */ - static std::string toString(execplan::IDB_Decimal& value); - static std::string toString(const execplan::IDB_Decimal& value); - - /** - @brief Convenience method to get int128 from a std::string. - */ - static int128_t int128FromString(const std::string& value, ColTypeAlias& colType); - - /** - @brief The method detects whether decimal type is wide - using csc colType. - */ - static constexpr inline bool isWideDecimalType(const ColTypeAlias& ct) - { - return ((ct.colDataType == execplan::CalpontSystemCatalog::DECIMAL || - ct.colDataType == execplan::CalpontSystemCatalog::UDECIMAL) && - ct.colWidth == MAXDECIMALWIDTH); - } + static std::string toString(VDecimal& value); + static std::string toString(const VDecimal& value); /** @brief The method detects whether decimal type is wide using precision. */ - static constexpr inline bool isWideDecimalType(const int32_t precision) + static constexpr inline bool isWideDecimalTypeByPrecision(const int32_t precision) { return precision > INT64MAXPRECISION && precision <= INT128MAXPRECISION; } - /** - @brief The method detects whether decimal type is wide - using datatype and width. - */ - static constexpr inline bool isWideDecimalType(const ColDataTypeAlias dt, - const int32_t width) - { - return (width == MAXDECIMALWIDTH && - (dt == execplan::CalpontSystemCatalog::DECIMAL || - dt == execplan::CalpontSystemCatalog::UDECIMAL)); - } - - /** - @brief The method sets the legacy scale and precision of a wide decimal - column which is the result of an arithmetic operation. - */ - static inline void setDecimalScalePrecisionLegacy(ColTypeAlias& ct, - unsigned int precision, unsigned int scale) - { - ct.scale = scale; - - if (ct.scale == 0) - ct.precision = precision - 1; - else - ct.precision = precision - scale; - } - - /** - @brief The method sets the scale and precision of a wide decimal - column which is the result of an arithmetic operation. - */ - static inline void setDecimalScalePrecision(ColTypeAlias& ct, - unsigned int precision, unsigned int scale) - { - ct.colWidth = (precision > INT64MAXPRECISION) - ? MAXDECIMALWIDTH : MAXLEGACYWIDTH; - - ct.precision = (precision > INT128MAXPRECISION) - ? INT128MAXPRECISION : precision; - - ct.scale = scale; - } - - /** - @brief The method sets the scale and precision of a wide decimal - column which is the result of an arithmetic operation, based on a heuristic. - */ - static inline void setDecimalScalePrecisionHeuristic(ColTypeAlias& ct, - unsigned int precision, unsigned int scale) - { - unsigned int diff = 0; - - if (precision > INT128MAXPRECISION) - { - ct.precision = INT128MAXPRECISION; - diff = precision - INT128MAXPRECISION; - } - else - { - ct.precision = precision; - } - - ct.scale = scale; - - if (diff != 0) - { - ct.scale = scale - (int)(diff * (38.0/65.0)); - - if (ct.scale < 0) - ct.scale = 0; - } - } - /** @brief The method converts a __float128 value to an int64_t. */ @@ -470,21 +422,6 @@ class Decimal scale += (scaleAvailable >= MAXSCALEINC4AVG) ? MAXSCALEINC4AVG : scaleAvailable; precision += (precisionAvailable >= MAXSCALEINC4AVG) ? MAXSCALEINC4AVG : precisionAvailable; } - - /** - @brief Returns true if all arguments have a DECIMAL/UDECIMAL type - */ - static inline bool isDecimalOperands(const ColDataTypeAlias resultDataType, - const ColDataTypeAlias leftColDataType, - const ColDataTypeAlias rightColDataType) - { - return ((resultDataType == execplan::CalpontSystemCatalog::DECIMAL || - resultDataType == execplan::CalpontSystemCatalog::UDECIMAL) && - (leftColDataType == execplan::CalpontSystemCatalog::DECIMAL || - leftColDataType == execplan::CalpontSystemCatalog::UDECIMAL) && - (rightColDataType == execplan::CalpontSystemCatalog::DECIMAL || - rightColDataType == execplan::CalpontSystemCatalog::UDECIMAL)); - } }; /** @@ -627,5 +564,291 @@ struct NoOverflowCheck { } }; + +/** + * @brief VDecimal type + * + */ +struct VDecimal +{ + VDecimal(): s128Value(0), value(0), scale(0), precision(0) + { + } + + VDecimal(int64_t val, int8_t s, uint8_t p, const int128_t &val128 = 0) : + s128Value(val128), + value(val), + scale(s), + precision(p) + { + } + + int decimalComp(const VDecimal& d) const + { + lldiv_t d1 = lldiv(value, static_cast(mcs_pow_10[scale])); + lldiv_t d2 = lldiv(d.value, static_cast(mcs_pow_10[d.scale])); + + int ret = 0; + + if (d1.quot > d2.quot) + { + ret = 1; + } + else if (d1.quot < d2.quot) + { + ret = -1; + } + else + { + // rem carries the value's sign, but needs to be normalized. + int64_t s = scale - d.scale; + + if (s < 0) + { + if ((d1.rem * static_cast(mcs_pow_10[-s])) > d2.rem) + ret = 1; + else if ((d1.rem * static_cast(mcs_pow_10[-s])) < d2.rem) + ret = -1; + } + else + { + if (d1.rem > (d2.rem * static_cast(mcs_pow_10[s]))) + ret = 1; + else if (d1.rem < (d2.rem * static_cast(mcs_pow_10[s]))) + ret = -1; + } + } + + return ret; + } + + bool operator==(const VDecimal& rhs) const + { + if (precision > datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return s128Value == rhs.s128Value; + else + return (datatypes::Decimal::compare(*this, rhs) == 0); + } + else if (precision > datatypes::INT64MAXPRECISION && + rhs.precision <= datatypes::INT64MAXPRECISION) + { + const_cast(rhs).s128Value = rhs.value; + + if (scale == rhs.scale) + return s128Value == rhs.s128Value; + else + return (datatypes::Decimal::compare(*this, rhs) == 0); + } + else if (precision <= datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return (int128_t) value == rhs.s128Value; + else + return (datatypes::Decimal::compare(VDecimal(0, scale, precision, (int128_t) value), rhs) == 0); + } + else + { + if (scale == rhs.scale) + return value == rhs.value; + else + return (decimalComp(rhs) == 0); + } + } + + bool operator>(const VDecimal& rhs) const + { + if (precision > datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return s128Value > rhs.s128Value; + else + return (datatypes::Decimal::compare(*this, rhs) > 0); + } + else if (precision > datatypes::INT64MAXPRECISION && + rhs.precision <= datatypes::INT64MAXPRECISION) + { + VDecimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); + + if (scale == rhstmp.scale) + return s128Value > rhstmp.s128Value; + else + return (datatypes::Decimal::compare(*this, rhstmp) > 0); + } + else if (precision <= datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return (int128_t) value > rhs.s128Value; + else + return (datatypes::Decimal::compare(VDecimal(0, scale, precision, (int128_t) value), rhs) > 0); + } + else + { + if (scale == rhs.scale) + return value > rhs.value; + else + return (decimalComp(rhs) > 0); + } + } + + bool operator<(const VDecimal& rhs) const + { + if (precision > datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return s128Value < rhs.s128Value; + else + return (datatypes::Decimal::compare(*this, rhs) < 0); + } + else if (precision > datatypes::INT64MAXPRECISION && + rhs.precision <= datatypes::INT64MAXPRECISION) + { + VDecimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); + + if (scale == rhstmp.scale) + return s128Value < rhstmp.s128Value; + else + return (datatypes::Decimal::compare(*this, rhstmp) < 0); + } + else if (precision <= datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return (int128_t) value < rhs.s128Value; + else + return (datatypes::Decimal::compare(VDecimal(0, scale, precision, (int128_t) value), rhs) < 0); + } + else + { + if (scale == rhs.scale) + return value < rhs.value; + else + return (decimalComp(rhs) < 0); + } + } + + bool operator>=(const VDecimal& rhs) const + { + if (precision > datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return s128Value >= rhs.s128Value; + else + return (datatypes::Decimal::compare(*this, rhs) >= 0); + } + else if (precision > datatypes::INT64MAXPRECISION && + rhs.precision <= datatypes::INT64MAXPRECISION) + { + VDecimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); + + if (scale == rhstmp.scale) + return s128Value >= rhstmp.s128Value; + else + return (datatypes::Decimal::compare(*this, rhstmp) >= 0); + } + else if (precision <= datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return (int128_t) value >= rhs.s128Value; + else + return (datatypes::Decimal::compare(VDecimal(0, scale, precision, (int128_t) value), rhs) >= 0); + } + else + { + if (scale == rhs.scale) + return value >= rhs.value; + else + return (decimalComp(rhs) >= 0); + } + } + + bool operator<=(const VDecimal& rhs) const + { + if (precision > datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return s128Value <= rhs.s128Value; + else + return (datatypes::Decimal::compare(*this, rhs) <= 0); + } + else if (precision > datatypes::INT64MAXPRECISION && + rhs.precision <= datatypes::INT64MAXPRECISION) + { + VDecimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); + + if (scale == rhstmp.scale) + return s128Value <= rhstmp.s128Value; + else + return (datatypes::Decimal::compare(*this, rhstmp) <= 0); + } + else if (precision <= datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return (int128_t) value <= rhs.s128Value; + else + return (datatypes::Decimal::compare(VDecimal(0, scale, precision, (int128_t) value), rhs) <= 0); + } + else + { + if (scale == rhs.scale) + return value <= rhs.value; + else + return (decimalComp(rhs) <= 0); + } + } + + bool operator!=(const VDecimal& rhs) const + { + if (precision > datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return s128Value != rhs.s128Value; + else + return (datatypes::Decimal::compare(*this, rhs) != 0); + } + else if (precision > datatypes::INT64MAXPRECISION && + rhs.precision <= datatypes::INT64MAXPRECISION) + { + VDecimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); + + if (scale == rhstmp.scale) + return s128Value != rhstmp.s128Value; + else + return (datatypes::Decimal::compare(*this, rhstmp) != 0); + } + else if (precision <= datatypes::INT64MAXPRECISION && + rhs.precision > datatypes::INT64MAXPRECISION) + { + if (scale == rhs.scale) + return (int128_t) value != rhs.s128Value; + else + return (datatypes::Decimal::compare(VDecimal(0, scale, precision, (int128_t) value), rhs) != 0); + } + else + { + if (scale == rhs.scale) + return value != rhs.value; + else + return (decimalComp(rhs) != 0); + } + } + + int128_t s128Value; + int64_t value; + int8_t scale; // 0~38 + uint8_t precision; // 1~38 +}; + } //end of namespace #endif diff --git a/dbcon/ddlpackageproc/createindexprocessor.cpp b/dbcon/ddlpackageproc/createindexprocessor.cpp index 30b8eeaf7..92787f02f 100644 --- a/dbcon/ddlpackageproc/createindexprocessor.cpp +++ b/dbcon/ddlpackageproc/createindexprocessor.cpp @@ -220,12 +220,12 @@ CreateIndexProcessor::DDLResult CreateIndexProcessor::processPackage(ddlpackage: } else if (CONSTRAINTPRIM_COL == column.tableColName.column) { - colTuple.data = getNullValueForType(column.colType); + colTuple.data =column.colType.getNullValueForType(); isNull = true; } else if (CONSTRAINTTEXT_COL == column.tableColName.column) { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); isNull = true; } else if (INDEXNAME_COL == column.tableColName.column) @@ -235,7 +235,7 @@ CreateIndexProcessor::DDLResult CreateIndexProcessor::processPackage(ddlpackage: } else { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); isNull = true; } @@ -336,7 +336,7 @@ CreateIndexProcessor::DDLResult CreateIndexProcessor::processPackage(ddlpackage: } else { - colTupleCol.data = getNullValueForType(column.colType); + colTupleCol.data = column.colType.getNullValueForType(); isNull = true; } diff --git a/dbcon/ddlpackageproc/ddlindexpopulator.h b/dbcon/ddlpackageproc/ddlindexpopulator.h index de623aa76..71910c32d 100644 --- a/dbcon/ddlpackageproc/ddlindexpopulator.h +++ b/dbcon/ddlpackageproc/ddlindexpopulator.h @@ -291,7 +291,7 @@ private: : DDLPackageProcessor(), fType(ctype) {} boost::any operator()(execplan::CalpontSystemCatalog::ColType& ctype) { - return getNullValueForType(fType); + return ctype.getNullValueForType(); } const execplan::CalpontSystemCatalog::ColType& fType; }; diff --git a/dbcon/ddlpackageproc/ddlpackageprocessor.cpp b/dbcon/ddlpackageproc/ddlpackageprocessor.cpp index 97712bf38..0f21db9cb 100644 --- a/dbcon/ddlpackageproc/ddlpackageprocessor.cpp +++ b/dbcon/ddlpackageproc/ddlpackageprocessor.cpp @@ -27,6 +27,7 @@ using namespace std; #include "ddlpackageprocessor.h" +#include "mcs_datatype.h" #include "dataconvert.h" using namespace dataconvert; #include "calpontselectexecutionplan.h" @@ -390,237 +391,6 @@ char DDLPackageProcessor::getConstraintCode(ddlpackage::DDL_CONSTRAINTS type) return constraint_type; } -boost::any -DDLPackageProcessor::getNullValueForType(const execplan::CalpontSystemCatalog::ColType& colType) -{ - boost::any value; - - switch (colType.colDataType) - { - case execplan::CalpontSystemCatalog::BIT: - break; - - case execplan::CalpontSystemCatalog::TINYINT: - { - char tinyintvalue = joblist::TINYINTNULL; - value = tinyintvalue; - - } - break; - - case execplan::CalpontSystemCatalog::SMALLINT: - { - short smallintvalue = joblist::SMALLINTNULL; - value = smallintvalue; - } - break; - - case execplan::CalpontSystemCatalog::MEDINT: - case execplan::CalpontSystemCatalog::INT: - { - int intvalue = joblist::INTNULL; - value = intvalue; - } - break; - - case execplan::CalpontSystemCatalog::BIGINT: - { - long long bigint = joblist::BIGINTNULL; - value = bigint; - } - break; - - case execplan::CalpontSystemCatalog::DECIMAL: - case execplan::CalpontSystemCatalog::UDECIMAL: - { - if (colType.colWidth <= 4) - { - short smallintvalue = joblist::SMALLINTNULL; - value = smallintvalue; - } - else if (colType.colWidth <= 9) - { - int intvalue = joblist::INTNULL; - value = intvalue; - } - else if (colType.colWidth <= 18) - { - long long eightbyte = joblist::BIGINTNULL; - value = eightbyte; - } - else - { - WriteEngine::Token nullToken; - value = nullToken; - } - } - break; - - case execplan::CalpontSystemCatalog::FLOAT: - case execplan::CalpontSystemCatalog::UFLOAT: - { - uint32_t jlfloatnull = joblist::FLOATNULL; - float* fp = reinterpret_cast(&jlfloatnull); - value = *fp; - } - break; - - case execplan::CalpontSystemCatalog::DOUBLE: - case execplan::CalpontSystemCatalog::UDOUBLE: - { - uint64_t jldoublenull = joblist::DOUBLENULL; - double* dp = reinterpret_cast(&jldoublenull); - value = *dp; - } - break; - - case execplan::CalpontSystemCatalog::DATE: - { - int d = joblist::DATENULL; - value = d; - } - break; - - case execplan::CalpontSystemCatalog::DATETIME: - { - long long d = joblist::DATETIMENULL; - value = d; - } - break; - - case execplan::CalpontSystemCatalog::TIME: - { - long long d = joblist::TIMENULL; - value = d; - } - break; - - case execplan::CalpontSystemCatalog::TIMESTAMP: - { - long long d = joblist::TIMESTAMPNULL; - value = d; - } - break; - - case execplan::CalpontSystemCatalog::CHAR: - { - std::string charnull; - - if (colType.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE) - { - //charnull = joblist::CHAR1NULL; - charnull = "\376"; - value = charnull; - } - else if (colType.colWidth == execplan::CalpontSystemCatalog::TWO_BYTE) - { - //charnull = joblist::CHAR2NULL; - charnull = "\377\376"; - value = charnull; - } - else if (colType.colWidth <= execplan::CalpontSystemCatalog::FOUR_BYTE) - { - //charnull = joblist::CHAR4NULL; - charnull = "\377\377\377\376"; - value = charnull; - } - else - { - WriteEngine::Token nullToken; - value = nullToken; - } - - } - break; - - case execplan::CalpontSystemCatalog::VARCHAR: - { - std::string charnull; - - if (colType.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE) - { - //charnull = joblist::CHAR2NULL; - charnull = "\377\376"; - value = charnull; - } - else if (colType.colWidth < execplan::CalpontSystemCatalog::FOUR_BYTE) - { - //charnull = joblist::CHAR4NULL; - charnull = "\377\377\377\376"; - value = charnull; - } - else - { - WriteEngine::Token nullToken; - value = nullToken; - } - - } - break; - - case execplan::CalpontSystemCatalog::VARBINARY: - { - std::string charnull; - - if (colType.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE) - { - //charnull = joblist::CHAR2NULL; - charnull = "\377\376"; - value = charnull; - } - else if (colType.colWidth < execplan::CalpontSystemCatalog::FOUR_BYTE) - { - //charnull = joblist::CHAR4NULL; - charnull = "\377\377\377\376"; - value = charnull; - } - else - { - WriteEngine::Token nullToken; - value = nullToken; - } - - } - break; - - case execplan::CalpontSystemCatalog::UTINYINT: - { - uint8_t utinyintvalue = joblist::UTINYINTNULL; - value = utinyintvalue; - - } - break; - - case execplan::CalpontSystemCatalog::USMALLINT: - { - uint16_t usmallintvalue = joblist::USMALLINTNULL; - value = usmallintvalue; - } - break; - - case execplan::CalpontSystemCatalog::UMEDINT: - case execplan::CalpontSystemCatalog::UINT: - { - uint32_t uintvalue = joblist::UINTNULL; - value = uintvalue; - } - break; - - case execplan::CalpontSystemCatalog::UBIGINT: - { - uint64_t ubigint = joblist::UBIGINTNULL; - value = ubigint; - } - break; - - default: - throw std::runtime_error("getNullValueForType: unkown column data type"); - break; - - } - - return value; -} bool DDLPackageProcessor::isIndexConstraint(ddlpackage::DDL_CONSTRAINTS type) { diff --git a/dbcon/ddlpackageproc/ddlpackageprocessor.h b/dbcon/ddlpackageproc/ddlpackageprocessor.h index 5714d5cd6..84d50d805 100644 --- a/dbcon/ddlpackageproc/ddlpackageprocessor.h +++ b/dbcon/ddlpackageproc/ddlpackageprocessor.h @@ -418,12 +418,6 @@ protected: */ execplan::CalpontSystemCatalog::ColDataType convertDataType(int dataType); - /** @brief get the null representation for the given column type - * - * @param colType the column type - */ - boost::any getNullValueForType(const execplan::CalpontSystemCatalog::ColType& colType); - /** @brief return a tokenized value for the supplied data value * * @param result the result of the operation diff --git a/dbcon/dmlpackageproc/dmlpackageprocessor.cpp b/dbcon/dmlpackageproc/dmlpackageprocessor.cpp index ad5bd1df0..c268f238a 100644 --- a/dbcon/dmlpackageproc/dmlpackageprocessor.cpp +++ b/dbcon/dmlpackageproc/dmlpackageprocessor.cpp @@ -52,7 +52,6 @@ using namespace joblist; using namespace messageqcpp; #include "tablelockdata.h" #include "exceptclasses.h" -#include "widedecimalutils.h" namespace { diff --git a/dbcon/execplan/arithmeticoperator.h b/dbcon/execplan/arithmeticoperator.h index 416daeea4..96c7ad75c 100644 --- a/dbcon/execplan/arithmeticoperator.h +++ b/dbcon/execplan/arithmeticoperator.h @@ -400,8 +400,8 @@ inline void ArithmeticOperator::execute(IDB_Decimal& result, IDB_Decimal op1, ID case OP_DIV: if (fOperationType.colWidth == datatypes::MAXDECIMALWIDTH) { - if ((datatypes::Decimal::isWideDecimalType(op2.precision) && op2.s128Value == 0) - || (!datatypes::Decimal::isWideDecimalType(op2.precision) && op2.value == 0)) + if ((datatypes::Decimal::isWideDecimalTypeByPrecision(op2.precision) && op2.s128Value == 0) + || (!datatypes::Decimal::isWideDecimalTypeByPrecision(op2.precision) && op2.value == 0)) { isNull = true; break; diff --git a/dbcon/execplan/calpontsystemcatalog.cpp b/dbcon/execplan/calpontsystemcatalog.cpp index 02c72c573..133b5f76e 100644 --- a/dbcon/execplan/calpontsystemcatalog.cpp +++ b/dbcon/execplan/calpontsystemcatalog.cpp @@ -31,6 +31,7 @@ using namespace std; #include "messagequeue.h" #include "calpontsystemcatalog.h" +#include "dataconvert.h" #include "ddlpkg.h" #include "expressionparser.h" #include "calpontselectexecutionplan.h" @@ -6091,13 +6092,9 @@ void CalpontSystemCatalog::checkSysCatVer() } CalpontSystemCatalog::ColType::ColType() : - colWidth(0), constraintType(NO_CONSTRAINT), - colDataType(MEDINT), defaultValue(""), colPosition(-1), - scale(0), - precision(-1), compressionType(NO_COMPRESSION), columnOID(0), autoincrement(0), @@ -6108,15 +6105,12 @@ CalpontSystemCatalog::ColType::ColType() : } CalpontSystemCatalog::ColType::ColType(const ColType& rhs) + :TypeHolderStd(rhs) { - colWidth = rhs.colWidth; constraintType = rhs.constraintType; - colDataType = rhs.colDataType; ddn = rhs.ddn; defaultValue = rhs.defaultValue; colPosition = rhs.colPosition; - scale = rhs.scale; - precision = rhs.precision; compressionType = rhs.compressionType; columnOID = rhs.columnOID; autoincrement = rhs.autoincrement; @@ -6125,26 +6119,6 @@ CalpontSystemCatalog::ColType::ColType(const ColType& rhs) cs = rhs.cs; } -CalpontSystemCatalog::ColType& CalpontSystemCatalog::ColType::operator=(const ColType& rhs) -{ - colWidth = rhs.colWidth; - constraintType = rhs.constraintType; - colDataType = rhs.colDataType; - ddn = rhs.ddn; - defaultValue = rhs.defaultValue; - colPosition = rhs.colPosition; - scale = rhs.scale; - precision = rhs.precision; - compressionType = rhs.compressionType; - columnOID = rhs.columnOID; - autoincrement = rhs.autoincrement; - nextvalue = rhs.nextvalue; - charsetNumber = rhs.charsetNumber; - cs = rhs.cs; - - return *this; -} - CHARSET_INFO* CalpontSystemCatalog::ColType::getCharset() { if (!cs) @@ -6170,6 +6144,31 @@ const string CalpontSystemCatalog::ColType::toString() const return output.str(); } + +boost::any +CalpontSystemCatalog::ColType::convertColumnData(const std::string& dataOrig, + bool& bSaturate, + const std::string& timeZone, + bool nulFlag, + bool noRoundup, + bool isUpdate) const +{ + return dataconvert::DataConvert::convertColumnData(colDataType, *this, + dataOrig, bSaturate, timeZone, + nulFlag, noRoundup, isUpdate); +} + + +CalpontSystemCatalog::ColType CalpontSystemCatalog::ColType::convertUnionColType(vector& types) +{ + idbassert(types.size()); + CalpontSystemCatalog::ColType unionedType = types[0]; + for (uint64_t i = 1; i < types.size(); i++) + dataconvert::DataConvert::joinColTypeForUnion(unionedType, types[i]); + return unionedType; +} + + //format a session id that includes the module id //we want the top bit clear to use as a syscat flag, then we want 7 bits of module id, then 24 bits of thread id /*static*/ diff --git a/dbcon/execplan/calpontsystemcatalog.h b/dbcon/execplan/calpontsystemcatalog.h index 2efd7cef1..29113afc8 100644 --- a/dbcon/execplan/calpontsystemcatalog.h +++ b/dbcon/execplan/calpontsystemcatalog.h @@ -44,54 +44,13 @@ #include "bytestream.h" #include "joblisttypes.h" #include "stdexcept" -#include "widedecimalutils.h" #undef min #undef max -// Because including my_sys.h in a Columnstore header causes too many conflicts -struct charset_info_st; -typedef const struct charset_info_st CHARSET_INFO; +#include "mcs_datatype.h" -#ifdef _MSC_VER -#define __attribute__(x) -#endif - -namespace -{ -const int64_t MIN_TINYINT __attribute__ ((unused)) = std::numeric_limits::min() + 2; //-126; -const int64_t MAX_TINYINT __attribute__ ((unused)) = std::numeric_limits::max(); //127; -const int64_t MIN_SMALLINT __attribute__ ((unused)) = std::numeric_limits::min() + 2; //-32766; -const int64_t MAX_SMALLINT __attribute__ ((unused)) = std::numeric_limits::max(); //32767; -const int64_t MIN_MEDINT __attribute__ ((unused)) = -(1ULL << 23); //-8388608; -const int64_t MAX_MEDINT __attribute__ ((unused)) = (1ULL << 23) - 1; //8388607; -const int64_t MIN_INT __attribute__ ((unused)) = std::numeric_limits::min() + 2; //-2147483646; -const int64_t MAX_INT __attribute__ ((unused)) = std::numeric_limits::max(); //2147483647; -const int64_t MIN_BIGINT __attribute__ ((unused)) = std::numeric_limits::min() + 2; //-9223372036854775806LL; -const int64_t MAX_BIGINT __attribute__ ((unused)) = std::numeric_limits::max(); //9223372036854775807 - -const uint64_t MIN_UINT __attribute__ ((unused)) = 0; -const uint64_t MIN_UTINYINT __attribute__ ((unused)) = 0; -const uint64_t MIN_USMALLINT __attribute__ ((unused)) = 0; -const uint64_t MIN_UMEDINT __attribute__ ((unused)) = 0; -const uint64_t MIN_UBIGINT __attribute__ ((unused)) = 0; -const uint64_t MAX_UINT __attribute__ ((unused)) = std::numeric_limits::max() - 2; //4294967293 -const uint64_t MAX_UTINYINT __attribute__ ((unused)) = std::numeric_limits::max() - 2; //253; -const uint64_t MAX_USMALLINT __attribute__ ((unused)) = std::numeric_limits::max() - 2; //65533; -const uint64_t MAX_UMEDINT __attribute__ ((unused)) = (1ULL << 24) - 1; //16777215 -const uint64_t MAX_UBIGINT __attribute__ ((unused)) = std::numeric_limits::max() - 2; //18446744073709551613 - -const float MAX_FLOAT __attribute__ ((unused)) = std::numeric_limits::max(); //3.402823466385289e+38 -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(); -} class ExecPlanTest; namespace messageqcpp @@ -99,6 +58,7 @@ namespace messageqcpp class MessageQueueClient; } + // This is now set in the Columnstore.xml file // Use, e.g., 0x500 for uid 500 so it is easy to spot in ipcs list //const int32_t BRM_UID = 0x0; @@ -117,7 +77,7 @@ const int32_t IDB_VTABLE_ID = CNX_VTABLE_ID; * * This object encapsulates the system catalog stored in the engine */ -class CalpontSystemCatalog +class CalpontSystemCatalog: public datatypes::SystemCatalog { public: @@ -131,50 +91,6 @@ public: */ enum Identity { EC = 0, FE }; - /** the set of Calpont column widths - * - */ - enum ColWidth { ONE_BIT, ONE_BYTE, TWO_BYTE, THREE_BYTE, FOUR_BYTE, FIVE_BYTE, SIX_BYTE, SEVEN_BYTE, EIGHT_BYTE }; - - /** the set of Calpont column data types - * - */ - enum ColDataType - { - BIT, /*!< BIT type */ - TINYINT, /*!< TINYINT type */ - CHAR, /*!< CHAR type */ - SMALLINT, /*!< SMALLINT type */ - DECIMAL, /*!< DECIMAL type */ - MEDINT, /*!< MEDINT type */ - INT, /*!< INT type */ - FLOAT, /*!< FLOAT type */ - DATE, /*!< DATE type */ - BIGINT, /*!< BIGINT type */ - DOUBLE, /*!< DOUBLE type */ - DATETIME, /*!< DATETIME type */ - VARCHAR, /*!< VARCHAR type */ - VARBINARY, /*!< VARBINARY type */ - CLOB, /*!< CLOB type */ - BLOB, /*!< BLOB type */ - UTINYINT, /*!< Unsigned TINYINT type */ - USMALLINT, /*!< Unsigned SMALLINT type */ - UDECIMAL, /*!< Unsigned DECIMAL type */ - UMEDINT, /*!< Unsigned MEDINT type */ - UINT, /*!< Unsigned INT type */ - UFLOAT, /*!< Unsigned FLOAT type */ - UBIGINT, /*!< Unsigned BIGINT type */ - UDOUBLE, /*!< Unsigned DOUBLE type */ - TEXT, /*!< TEXT type */ - TIME, /*!< TIME type */ - TIMESTAMP, /*!< TIMESTAMP type */ - NUM_OF_COL_DATA_TYPE, /* NEW TYPES ABOVE HERE */ - LONGDOUBLE, /* @bug3241, dev and variance calculation only */ - STRINT, /* @bug3532, string as int for fast comparison */ - UNDEFINED, /*!< Undefined - used in UDAF API */ - BINARY, /*!< BINARY type */ - }; - /** the set of column constraint types * */ @@ -280,21 +196,18 @@ public: */ typedef std::vector DictOIDList; + /** the structure returned by colType * * defaultValue is only meaningful when constraintType == DEFAULT_CONSTRAINT */ - struct ColType + struct ColType: public datatypes::SystemCatalog::TypeHolderStd { ColType(); - int32_t colWidth; ConstraintType constraintType; - ColDataType colDataType; DictOID ddn; std::string defaultValue; int32_t colPosition; // temporally put here. may need to have ColInfo struct later - int32_t scale; //number after decimal points - int32_t precision; int32_t compressionType; OID columnOID; bool autoincrement; //set to true if SYSCOLUMN autoincrement is �y� @@ -329,6 +242,13 @@ public: b >> charsetNumber; } + boost::any convertColumnData(const std::string& dataOrig, + bool& bSaturate, + const std::string& timeZone, + bool nulFlag = false, + bool noRoundup = false, + bool isUpdate = false) const; + const std::string toString() const; //Put these here so udf doesn't need to link libexecplan @@ -364,6 +284,8 @@ public: return !(*this == t); } + static ColType convertUnionColType(std::vector&); + }; /** the structure of a table infomation @@ -964,91 +886,9 @@ const CalpontSystemCatalog::TableAliasName make_aliastable(const std::string& s, const CalpontSystemCatalog::TableAliasName make_aliasview(const std::string& s, const std::string& t, const std::string& a, const std::string& v, const bool fisColumnStore = true, int lower_case_table_names=0); -/** convenience function to determine if column type is a char - * type - */ -inline bool isCharType(const execplan::CalpontSystemCatalog::ColDataType type) -{ - return (execplan::CalpontSystemCatalog::VARCHAR == type || - execplan::CalpontSystemCatalog::CHAR == type || - execplan::CalpontSystemCatalog::BLOB == type || - execplan::CalpontSystemCatalog::TEXT == type); -} - -/** convenience function to determine if column type is a - * numeric type - */ -inline bool isNumeric(const execplan::CalpontSystemCatalog::ColDataType type) -{ - switch (type) - { - case execplan::CalpontSystemCatalog::TINYINT: - case execplan::CalpontSystemCatalog::SMALLINT: - case execplan::CalpontSystemCatalog::MEDINT: - case execplan::CalpontSystemCatalog::INT: - case execplan::CalpontSystemCatalog::BIGINT: - case execplan::CalpontSystemCatalog::FLOAT: - case execplan::CalpontSystemCatalog::DOUBLE: - case execplan::CalpontSystemCatalog::DECIMAL: - case execplan::CalpontSystemCatalog::UTINYINT: - case execplan::CalpontSystemCatalog::USMALLINT: - case execplan::CalpontSystemCatalog::UMEDINT: - case execplan::CalpontSystemCatalog::UINT: - case execplan::CalpontSystemCatalog::UBIGINT: - case execplan::CalpontSystemCatalog::UFLOAT: - case execplan::CalpontSystemCatalog::UDOUBLE: - case execplan::CalpontSystemCatalog::UDECIMAL: - return true; - - default: - return false; - } -} - -inline bool isDecimal(const execplan::CalpontSystemCatalog::ColDataType type) -{ - return (type == execplan::CalpontSystemCatalog::DECIMAL || - type == execplan::CalpontSystemCatalog::UDECIMAL); -} - -/** convenience function to determine if column type is an - * unsigned type - */ -inline bool isUnsigned(const execplan::CalpontSystemCatalog::ColDataType type) -{ - switch (type) - { - case execplan::CalpontSystemCatalog::UTINYINT: - case execplan::CalpontSystemCatalog::USMALLINT: - case execplan::CalpontSystemCatalog::UMEDINT: - case execplan::CalpontSystemCatalog::UINT: - case execplan::CalpontSystemCatalog::UBIGINT: - return true; - - default: - return false; - } -} - -inline bool isSignedInteger(const execplan::CalpontSystemCatalog::ColDataType type) -{ - switch (type) - { - case execplan::CalpontSystemCatalog::TINYINT: - case execplan::CalpontSystemCatalog::SMALLINT: - case execplan::CalpontSystemCatalog::MEDINT: - case execplan::CalpontSystemCatalog::INT: - case execplan::CalpontSystemCatalog::BIGINT: - return true; - - default: - return false; - } -} - inline bool isNull(int128_t val, const execplan::CalpontSystemCatalog::ColType& ct) { - return utils::isWideDecimalNullValue(val); + return datatypes::Decimal::isWideDecimalNullValue(val); } inline bool isNull(int64_t val, const execplan::CalpontSystemCatalog::ColType& ct) diff --git a/dbcon/execplan/functioncolumn.h b/dbcon/execplan/functioncolumn.h index 874e7ef67..cda618b85 100644 --- a/dbcon/execplan/functioncolumn.h +++ b/dbcon/execplan/functioncolumn.h @@ -253,7 +253,7 @@ public: if (LIKELY(fResultType.colWidth == datatypes::MAXDECIMALWIDTH)) { decimal.s128Value = - (datatypes::Decimal::isWideDecimalType(decimal.precision)) ? + (datatypes::Decimal::isWideDecimalTypeByPrecision(decimal.precision)) ? decimal.s128Value : decimal.value; int128_t scaleMultiplier; diff --git a/dbcon/execplan/treenode.h b/dbcon/execplan/treenode.h index b23024990..ad35f1768 100644 --- a/dbcon/execplan/treenode.h +++ b/dbcon/execplan/treenode.h @@ -57,290 +57,13 @@ namespace execplan typedef execplan::CalpontSystemCatalog::ColType Type; -/** - * @brief IDB_Decimal type - * - */ -struct IDB_Decimal +class IDB_Decimal: public datatypes::VDecimal { - IDB_Decimal(): s128Value(0), value(0), scale(0), precision(0) - { - } - - IDB_Decimal(int64_t val, int8_t s, uint8_t p, int128_t val128 = 0) : - s128Value(val128), - value(val), - scale(s), - precision(p) - { - } - - int decimalComp(const IDB_Decimal& d) const - { - lldiv_t d1 = lldiv(value, IDB_pow[scale]); - lldiv_t d2 = lldiv(d.value, IDB_pow[d.scale]); - - int ret = 0; - - if (d1.quot > d2.quot) - { - ret = 1; - } - else if (d1.quot < d2.quot) - { - ret = -1; - } - else - { - // rem carries the value's sign, but needs to be normalized. - int64_t s = scale - d.scale; - - if (s < 0) - { - if ((d1.rem * IDB_pow[-s]) > d2.rem) - ret = 1; - else if ((d1.rem * IDB_pow[-s]) < d2.rem) - ret = -1; - } - else - { - if (d1.rem > (d2.rem * IDB_pow[s])) - ret = 1; - else if (d1.rem < (d2.rem * IDB_pow[s])) - ret = -1; - } - } - - return ret; - } - - bool operator==(const IDB_Decimal& rhs) const - { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value == rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) == 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - const_cast(rhs).s128Value = rhs.value; - - if (scale == rhs.scale) - return s128Value == rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) == 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value == rhs.s128Value; - else - return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) == 0); - } - else - { - if (scale == rhs.scale) - return value == rhs.value; - else - return (decimalComp(rhs) == 0); - } - } - - bool operator>(const IDB_Decimal& rhs) const - { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value > rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) > 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - IDB_Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); - - if (scale == rhstmp.scale) - return s128Value > rhstmp.s128Value; - else - return (datatypes::Decimal::compare(*this, rhstmp) > 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value > rhs.s128Value; - else - return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) > 0); - } - else - { - if (scale == rhs.scale) - return value > rhs.value; - else - return (decimalComp(rhs) > 0); - } - } - - bool operator<(const IDB_Decimal& rhs) const - { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value < rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) < 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - IDB_Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); - - if (scale == rhstmp.scale) - return s128Value < rhstmp.s128Value; - else - return (datatypes::Decimal::compare(*this, rhstmp) < 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value < rhs.s128Value; - else - return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) < 0); - } - else - { - if (scale == rhs.scale) - return value < rhs.value; - else - return (decimalComp(rhs) < 0); - } - } - - bool operator>=(const IDB_Decimal& rhs) const - { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value >= rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) >= 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - IDB_Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); - - if (scale == rhstmp.scale) - return s128Value >= rhstmp.s128Value; - else - return (datatypes::Decimal::compare(*this, rhstmp) >= 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value >= rhs.s128Value; - else - return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) >= 0); - } - else - { - if (scale == rhs.scale) - return value >= rhs.value; - else - return (decimalComp(rhs) >= 0); - } - } - - bool operator<=(const IDB_Decimal& rhs) const - { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value <= rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) <= 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - IDB_Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); - - if (scale == rhstmp.scale) - return s128Value <= rhstmp.s128Value; - else - return (datatypes::Decimal::compare(*this, rhstmp) <= 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value <= rhs.s128Value; - else - return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) <= 0); - } - else - { - if (scale == rhs.scale) - return value <= rhs.value; - else - return (decimalComp(rhs) <= 0); - } - } - - bool operator!=(const IDB_Decimal& rhs) const - { - if (precision > datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return s128Value != rhs.s128Value; - else - return (datatypes::Decimal::compare(*this, rhs) != 0); - } - else if (precision > datatypes::INT64MAXPRECISION && - rhs.precision <= datatypes::INT64MAXPRECISION) - { - IDB_Decimal rhstmp(0, rhs.scale, rhs.precision, (int128_t) rhs.value); - - if (scale == rhstmp.scale) - return s128Value != rhstmp.s128Value; - else - return (datatypes::Decimal::compare(*this, rhstmp) != 0); - } - else if (precision <= datatypes::INT64MAXPRECISION && - rhs.precision > datatypes::INT64MAXPRECISION) - { - if (scale == rhs.scale) - return (int128_t) value != rhs.s128Value; - else - return (datatypes::Decimal::compare(IDB_Decimal(0, scale, precision, (int128_t) value), rhs) != 0); - } - else - { - if (scale == rhs.scale) - return value != rhs.value; - else - return (decimalComp(rhs) != 0); - } - } - - int128_t s128Value; - int64_t value; - int8_t scale; // 0~38 - uint8_t precision; // 1~38 +public: + using datatypes::VDecimal::VDecimal; }; + + typedef IDB_Decimal CNX_Decimal; /** @@ -900,7 +623,7 @@ inline const std::string& TreeNode::getStrVal(const std::string& timeZone) case CalpontSystemCatalog::UDECIMAL: { if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH) - dataconvert::DataConvert::decimalToString(&fResult.decimalVal.s128Value, fResult.decimalVal.scale, tmp, utils::MAXLENGTH16BYTES, fResultType.colDataType); + dataconvert::DataConvert::decimalToString(&fResult.decimalVal.s128Value, fResult.decimalVal.scale, tmp, datatypes::Decimal::MAXLENGTH16BYTES, fResultType.colDataType); else dataconvert::DataConvert::decimalToString(fResult.decimalVal.value, fResult.decimalVal.scale, tmp, 22, fResultType.colDataType); fResult.strVal = std::string(tmp); diff --git a/dbcon/joblist/batchprimitiveprocessor-jl.cpp b/dbcon/joblist/batchprimitiveprocessor-jl.cpp index 2a874c4e2..929252d56 100644 --- a/dbcon/joblist/batchprimitiveprocessor-jl.cpp +++ b/dbcon/joblist/batchprimitiveprocessor-jl.cpp @@ -773,7 +773,7 @@ void BatchPrimitiveProcessorJL::getRowGroupData(ByteStream& in, vector* if (UNLIKELY(*hasWideColumn)) { idbassert(colType.colWidth > utils::MAXLEGACYWIDTH); - if (LIKELY(datatypes::Decimal::isWideDecimalType(colType))) + if (LIKELY(colType.isWideDecimalType())) { in >> tmp128; *min = tmp128; diff --git a/dbcon/joblist/columncommand-jl.cpp b/dbcon/joblist/columncommand-jl.cpp index b8ef18f5d..66b3acb2e 100644 --- a/dbcon/joblist/columncommand-jl.cpp +++ b/dbcon/joblist/columncommand-jl.cpp @@ -288,7 +288,7 @@ string ColumnCommandJL::toString() if (isDict()) ret << " (tokens)"; - else if (execplan::isCharType(colType.colDataType)) + else if (datatypes::isCharType(colType.colDataType)) ret << " (is char)"; return ret.str(); diff --git a/dbcon/joblist/crossenginestep.cpp b/dbcon/joblist/crossenginestep.cpp index 455906c0f..bbdefce0e 100644 --- a/dbcon/joblist/crossenginestep.cpp +++ b/dbcon/joblist/crossenginestep.cpp @@ -46,9 +46,6 @@ using namespace execplan; #include "rowgroup.h" using namespace rowgroup; -#include "dataconvert.h" -using namespace dataconvert; - #include "querytele.h" using namespace querytele; @@ -247,7 +244,7 @@ int64_t CrossEngineStep::convertValueNum( // bool nulFlag, // bool noRoundup ) bool pushWarning = false; - boost::any anyVal = DataConvert::convertColumnData(ct, str, pushWarning, fTimeZone, false, true, false); + boost::any anyVal = ct.convertColumnData(str, pushWarning, fTimeZone, false, true, false); // Out of range values are treated as NULL as discussed during design review. if (pushWarning) diff --git a/dbcon/joblist/groupconcat.cpp b/dbcon/joblist/groupconcat.cpp index 78fdf24c2..b5ba3390f 100644 --- a/dbcon/joblist/groupconcat.cpp +++ b/dbcon/joblist/groupconcat.cpp @@ -381,7 +381,7 @@ void GroupConcatAgUM::applyMapping(const boost::shared_array& mapping, cons { fRow.setLongDoubleField(row.getLongDoubleField(mapping[i]), i); } - else if (datatypes::Decimal::isWideDecimalType(fRow.getColType(i), fRow.getColumnWidth(i))) + else if (datatypes::isWideDecimalType(fRow.getColType(i), fRow.getColumnWidth(i))) { row.copyBinaryField(fRow, i, mapping[i]); } @@ -460,12 +460,12 @@ void GroupConcator::outputRow(std::ostringstream& oss, const rowgroup::Row& row) if (LIKELY(row.getColumnWidth(*i) == datatypes::MAXDECIMALWIDTH)) { - char buf[utils::MAXLENGTH16BYTES]; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; int128_t* dec = row.getBinaryField(*i); dataconvert::DataConvert::decimalToString(dec, static_cast(scale), buf, - sizeof(buf), types[*i]); + (uint8_t) sizeof(buf), types[*i]); oss << fixed << buf; } else diff --git a/dbcon/joblist/jlf_common.cpp b/dbcon/joblist/jlf_common.cpp index c07ab056e..794ed4c07 100644 --- a/dbcon/joblist/jlf_common.cpp +++ b/dbcon/joblist/jlf_common.cpp @@ -333,7 +333,7 @@ string extractTableAlias(const SSC& sc) //------------------------------------------------------------------------------ CalpontSystemCatalog::OID isDictCol(const CalpontSystemCatalog::ColType& colType) { - if (datatypes::Decimal::isWideDecimalType(colType) || + if (colType.isWideDecimalType() || colType.colDataType == CalpontSystemCatalog::BINARY) return 0; if (colType.colWidth > 8) return colType.ddn.dictOID; diff --git a/dbcon/joblist/jlf_execplantojoblist.cpp b/dbcon/joblist/jlf_execplantojoblist.cpp index a184fbe24..42bbf8904 100644 --- a/dbcon/joblist/jlf_execplantojoblist.cpp +++ b/dbcon/joblist/jlf_execplantojoblist.cpp @@ -65,9 +65,6 @@ namespace ba = boost::algorithm; #include "simplescalarfilter.h" using namespace execplan; -#include "dataconvert.h" -using namespace dataconvert; - #include "configcpp.h" using namespace config; @@ -135,7 +132,7 @@ void valueNullNum(const CalpontSystemCatalog::ColType& ct, const string& timeZon { T& n = val; bool pushWarning = false; - boost::any anyVal = DataConvert::convertColumnData(ct, "", pushWarning, timeZone, true, false, false); + boost::any anyVal = ct.convertColumnData("", pushWarning, timeZone, true, false, false); switch (ct.colDataType) { @@ -324,7 +321,7 @@ void convertValueNum(const string& str, const CalpontSystemCatalog::ColType& ct, v = 0; rf = 0; bool pushWarning = false; - boost::any anyVal = DataConvert::convertColumnData(ct, str, pushWarning, timeZone, false, true, false); + boost::any anyVal = ct.convertColumnData(str, pushWarning, timeZone, false, true, false); switch (ct.colDataType) { @@ -1896,7 +1893,7 @@ const JobStepVector doSimpleFilter(SimpleFilter* sf, JobInfo& jobInfo) // WIP MCOL-641 width check must be a f() not a literal // make a template from convertValueNum to avoid extra if // this condition doesn't support UDECIMAL - if (datatypes::Decimal::isWideDecimalType(ct)) + if (ct.isWideDecimalType()) convertValueNum(constval, ct, isNull, rf, jobInfo.timeZone, value128); else convertValueNum(constval, ct, isNull, rf, jobInfo.timeZone, value); @@ -1933,7 +1930,7 @@ const JobStepVector doSimpleFilter(SimpleFilter* sf, JobInfo& jobInfo) if (sc->isColumnStore()) { - if (datatypes::Decimal::isWideDecimalType(ct)) + if (ct.isWideDecimalType()) pcs->addFilter(cop, value128, rf); else pcs->addFilter(cop, value, rf); @@ -3011,7 +3008,7 @@ const JobStepVector doConstantFilter(const ConstantFilter* cf, JobInfo& jobInfo) uint8_t rf = 0; bool isNull = ConstantColumn::NULLDATA == cc->type(); - if (datatypes::Decimal::isWideDecimalType(ct)) + if (ct.isWideDecimalType()) convertValueNum(constval, ct, isNull, rf, jobInfo.timeZone, value128); else convertValueNum(constval, ct, isNull, rf, jobInfo.timeZone, value); @@ -3031,7 +3028,7 @@ const JobStepVector doConstantFilter(const ConstantFilter* cf, JobInfo& jobInfo) if (ConstantColumn::NULLDATA == cc->type() && (opeq == *sop || opne == *sop)) cop = COMPARE_NIL; - if (datatypes::Decimal::isWideDecimalType(ct)) + if (ct.isWideDecimalType()) pcs->addFilter(cop, value128, rf); else pcs->addFilter(cop, value, rf); diff --git a/dbcon/joblist/jlf_tuplejoblist.cpp b/dbcon/joblist/jlf_tuplejoblist.cpp index 5f7ea2dff..ddab457cc 100644 --- a/dbcon/joblist/jlf_tuplejoblist.cpp +++ b/dbcon/joblist/jlf_tuplejoblist.cpp @@ -4072,7 +4072,7 @@ SJSTEP unionQueries(JobStepVector& queries, uint64_t distinctUnionNum, JobInfo& // get unioned column types for (uint64_t j = 0; j < colCount; ++j) { - CalpontSystemCatalog::ColType colType = DataConvert::convertUnionColType(queryColTypes[j]); + CalpontSystemCatalog::ColType colType = CalpontSystemCatalog::ColType::convertUnionColType(queryColTypes[j]); types.push_back(colType.colDataType); csNums.push_back(colType.charsetNumber); scale.push_back(colType.scale); diff --git a/dbcon/joblist/lbidlist.cpp b/dbcon/joblist/lbidlist.cpp index 79d053d9a..4f2affc89 100644 --- a/dbcon/joblist/lbidlist.cpp +++ b/dbcon/joblist/lbidlist.cpp @@ -28,7 +28,6 @@ #include "brm.h" #include "brmtypes.h" #include "dataconvert.h" -#include "widedecimalutils.h" #include "mcs_decimal.h" #define IS_VERBOSE (fDebug >= 4) @@ -415,7 +414,7 @@ void LBIDList::UpdateMinMax(T min, T max, int64_t lbid, CalpontSystemCatalog::Co if (mmp->isValid == BRM::CP_INVALID) { - if (execplan::isCharType(type)) + if (datatypes::isCharType(type)) { if (order_swap(min) < order_swap(mmp->min) || mmp->min == numeric_limits::max()) @@ -425,7 +424,7 @@ void LBIDList::UpdateMinMax(T min, T max, int64_t lbid, CalpontSystemCatalog::Co mmp->max == numeric_limits::min()) mmp->max = max; } - else if (execplan::isUnsigned(type)) + else if (datatypes::isUnsigned(type)) { if (typeid(T) == typeid(__int128)) { @@ -757,8 +756,8 @@ bool LBIDList::CasualPartitionPredicate(const BRM::EMCasualPartition_t& cpRange, bool scan = true; int64_t value = 0; __int128 bigValue = 0; - bool bIsUnsigned = execplan::isUnsigned(ct.colDataType); - bool bIsChar = execplan::isCharType(ct.colDataType); + bool bIsUnsigned = datatypes::isUnsigned(ct.colDataType); + bool bIsChar = datatypes::isCharType(ct.colDataType); for (int i = 0; i < NOPS; i++) { @@ -859,7 +858,7 @@ bool LBIDList::CasualPartitionPredicate(const BRM::EMCasualPartition_t& cpRange, // Should we also check for empty here? // TODO MCOL-641 - if (datatypes::Decimal::isWideDecimalType(ct)) + if (ct.isWideDecimalType()) { if (isNull(bigValue, ct)) continue; diff --git a/dbcon/joblist/pseudocc-jl.cpp b/dbcon/joblist/pseudocc-jl.cpp index 94e7cb574..7a48fb096 100644 --- a/dbcon/joblist/pseudocc-jl.cpp +++ b/dbcon/joblist/pseudocc-jl.cpp @@ -46,7 +46,7 @@ void PseudoCCJL::runCommand(ByteStream& bs) const { if (function == PSEUDO_EXTENTMAX) { - if (!datatypes::Decimal::isWideDecimalType(colType)) + if (!colType.isWideDecimalType()) { int64_t max = extents[currentExtentIndex].partition.cprange.hiVal; int64_t min = extents[currentExtentIndex].partition.cprange.loVal; @@ -66,14 +66,14 @@ void PseudoCCJL::runCommand(ByteStream& bs) const else { int128_t int128Null; - utils::setWideDecimalNullValue(int128Null); + datatypes::Decimal::setWideDecimalNullValue(int128Null); bs << (uint128_t) int128Null; } } } else if (function == PSEUDO_EXTENTMIN) { - if (!datatypes::Decimal::isWideDecimalType(colType)) + if (!colType.isWideDecimalType()) { int64_t max = extents[currentExtentIndex].partition.cprange.hiVal; int64_t min = extents[currentExtentIndex].partition.cprange.loVal; @@ -93,7 +93,7 @@ void PseudoCCJL::runCommand(ByteStream& bs) const else { int128_t int128Null; - utils::setWideDecimalNullValue(int128Null); + datatypes::Decimal::setWideDecimalNullValue(int128Null); bs << (uint128_t) int128Null; } } diff --git a/dbcon/joblist/rowestimator.cpp b/dbcon/joblist/rowestimator.cpp index c28e00781..95ae57140 100644 --- a/dbcon/joblist/rowestimator.cpp +++ b/dbcon/joblist/rowestimator.cpp @@ -224,7 +224,7 @@ float RowEstimator::estimateOpFactor(const T& min, const T& max, const T& value, case COMPARE_NGE: if (cpStatus == BRM::CP_VALID) { - if (!datatypes::Decimal::isWideDecimalType(ct)) + if (!ct.isWideDecimalType()) factor = (1.0 * value - min) / (max - min + 1); else factor = ((__float128) value - min) / (max - min + 1); @@ -236,7 +236,7 @@ float RowEstimator::estimateOpFactor(const T& min, const T& max, const T& value, case COMPARE_NGT: if (cpStatus == BRM::CP_VALID) { - if (!datatypes::Decimal::isWideDecimalType(ct)) + if (!ct.isWideDecimalType()) factor = (1.0 * value - min + 1) / (max - min + 1); else factor = ((__float128) value - min + 1) / (max - min + 1); @@ -248,7 +248,7 @@ float RowEstimator::estimateOpFactor(const T& min, const T& max, const T& value, case COMPARE_NLE: if (cpStatus == BRM::CP_VALID) { - if (!datatypes::Decimal::isWideDecimalType(ct)) + if (!ct.isWideDecimalType()) factor = (1.0 * max - value) / (1.0 * max - min + 1); else factor = ((__float128) max - value) / (max - min + 1); @@ -261,7 +261,7 @@ float RowEstimator::estimateOpFactor(const T& min, const T& max, const T& value, if (cpStatus == BRM::CP_VALID) { // TODO: Best way to convert to floating point arithmetic? - if (!datatypes::Decimal::isWideDecimalType(ct)) + if (!ct.isWideDecimalType()) factor = (1.0 * max - value + 1) / (max - min + 1); else factor = ((__float128) max - value + 1) / (max - min + 1); @@ -299,7 +299,7 @@ float RowEstimator::estimateRowReturnFactor(const BRM::EMEntry& emEntry, const uint8_t BOP, const uint32_t& rowsInExtent) { - bool bIsUnsigned = execplan::isUnsigned(ct.colDataType); + bool bIsUnsigned = datatypes::isUnsigned(ct.colDataType); float factor = 1.0; float tempFactor = 1.0; @@ -308,7 +308,7 @@ float RowEstimator::estimateRowReturnFactor(const BRM::EMEntry& emEntry, uint32_t distinctValuesEstimate; // Adjust values based on column type and estimate the - if (!datatypes::Decimal::isWideDecimalType(ct)) + if (!ct.isWideDecimalType()) { adjustedMin = adjustValue(ct, emEntry.partition.cprange.loVal); adjustedMax = adjustValue(ct, emEntry.partition.cprange.hiVal); @@ -460,7 +460,7 @@ float RowEstimator::estimateRowReturnFactor(const BRM::EMEntry& emEntry, // Get the factor for the individual operation. if (bIsUnsigned) { - if (!datatypes::Decimal::isWideDecimalType(ct)) + if (!ct.isWideDecimalType()) { tempFactor = estimateOpFactor( adjustedMin, adjustedMax, adjustValue(ct, value), op, lcf, @@ -475,7 +475,7 @@ float RowEstimator::estimateRowReturnFactor(const BRM::EMEntry& emEntry, } else { - if (!datatypes::Decimal::isWideDecimalType(ct)) + if (!ct.isWideDecimalType()) { tempFactor = estimateOpFactor( adjustedMin, adjustedMax, adjustValue(ct, value), op, lcf, diff --git a/dbcon/joblist/tuple-bps.cpp b/dbcon/joblist/tuple-bps.cpp index dcdc2f5f1..44162ba6e 100644 --- a/dbcon/joblist/tuple-bps.cpp +++ b/dbcon/joblist/tuple-bps.cpp @@ -1693,11 +1693,11 @@ bool TupleBPS::processPseudoColFilters(uint32_t extentIndex, boost::shared_ptrresultType(); - if (datatypes::Decimal::isWideDecimalType(colType)) + if (colType.isWideDecimalType()) { *scaleIter = colType.scale; *precisionIter = colType.precision; @@ -776,7 +776,7 @@ void TupleAggregateStep::configDeliveredRowGroup(const JobInfo& jobInfo) { const auto& colType = jobInfo.nonConstDelCols[i]->resultType(); - if (datatypes::Decimal::isWideDecimalType(colType)) + if (colType.isWideDecimalType()) { *scaleIter = colType.scale; *precisionIter = colType.precision; diff --git a/dbcon/joblist/tuplehashjoin.cpp b/dbcon/joblist/tuplehashjoin.cpp index 35639814a..6b616c083 100644 --- a/dbcon/joblist/tuplehashjoin.cpp +++ b/dbcon/joblist/tuplehashjoin.cpp @@ -487,7 +487,7 @@ void TupleHashJoinStep::forwardCPData() continue; bool isSmallSideWideDecimal = - datatypes::Decimal::isWideDecimalType(smallRGs[i].getColType(idx), smallRGs[i].getColumnWidth(idx)); + datatypes::isWideDecimalType(smallRGs[i].getColType(idx), smallRGs[i].getColumnWidth(idx)); largeBPS->addCPPredicates(largeRG.getOIDs()[joiners[i]->getLargeKeyColumns()[col]], joiners[i]->getCPData()[col], !joiners[i]->discreteCPValues()[col], diff --git a/dbcon/mysql/CMakeLists.txt b/dbcon/mysql/CMakeLists.txt index 491a59323..7274ed525 100644 --- a/dbcon/mysql/CMakeLists.txt +++ b/dbcon/mysql/CMakeLists.txt @@ -7,6 +7,7 @@ include_directories( ${ENGINE_COMMON_INCLUDES} SET ( libcalmysql_SRCS + ../../datatypes/mcs_datatype.cpp ha_mcs_sysvars.cpp ha_mcs_client_udfs.cpp ha_mcs_opt_rewrites.cpp diff --git a/dbcon/mysql/ha_mcs_datatype.h b/dbcon/mysql/ha_mcs_datatype.h new file mode 100644 index 000000000..56ffd7cba --- /dev/null +++ b/dbcon/mysql/ha_mcs_datatype.h @@ -0,0 +1,1301 @@ +/* + Copyright (C) 2020 MariaDB Corporation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ +#ifndef HA_MCS_DATATYPE_H_INCLUDED +#define HA_MCS_DATATYPE_H_INCLUDED + +/* + Interface classes for MariaDB data types (e.g. Field) for TypeHandler. + These classes are needed to avoid TypeHandler dependency on + MariaDB header files. +*/ + + +namespace datatypes { + +class StoreFieldMariaDB: public StoreField +{ + Field *m_field; + const CalpontSystemCatalog::ColType &m_type; +public: + StoreFieldMariaDB(Field *f, CalpontSystemCatalog::ColType &type) + :m_field(f), m_type(type) + { } + const CalpontSystemCatalog::ColType &type() const { return m_type; } + int32_t colWidth() const override { return m_type.colWidth; } + int32_t precision() const override { return m_type.precision; } + + int store_date(int64_t val) override + { + char tmp[256]; + DataConvert::dateToString(val, tmp, sizeof(tmp)-1); + return store_string(tmp, strlen(tmp)); + } + + int store_datetime(int64_t val) override + { + char tmp[256]; + DataConvert::datetimeToString(val, tmp, sizeof(tmp)-1, m_type.precision); + return store_string(tmp, strlen(tmp)); + } + + int store_time(int64_t val) override + { + char tmp[256]; + DataConvert::timeToString(val, tmp, sizeof(tmp)-1, m_type.precision); + return store_string(tmp, strlen(tmp)); + } + + int store_timestamp(int64_t val) override + { + char tmp[256]; + DataConvert::timestampToString(val, tmp, sizeof(tmp), + current_thd->variables.time_zone->get_name()->ptr(), + m_type.precision); + return store_string(tmp, strlen(tmp)); + } + + int store_string(const char *str, size_t length) override + { + return m_field->store(str, length, m_field->charset()); + } + int store_varbinary(const char *str, size_t length) override + { + if (get_varbin_always_hex(current_thd)) + { + size_t ll = length * 2; + boost::scoped_array sca(new char[ll]); + ConstString(str, length).bin2hex(sca.get()); + return m_field->store_binary(sca.get(), ll); + } + return m_field->store_binary(str, length); + } + + int store_xlonglong(int64_t val) override + { + idbassert(dynamic_cast(m_field)); + return m_field->store(val, static_cast(m_field)->unsigned_flag); + } + + int store_float(float dl) override + { + if (dl == std::numeric_limits::infinity()) + { + m_field->set_null(); + return 1; + } + + // bug 3485, reserve enough space for the longest float value + // -3.402823466E+38 to -1.175494351E-38, 0, and + // 1.175494351E-38 to 3.402823466E+38. + m_field->field_length = 40; + return m_field->store(dl); + } + + int store_double(double dl) override + { + if (dl == std::numeric_limits::infinity()) + { + m_field->set_null(); + return 1; + } + + if (m_field->type() == MYSQL_TYPE_NEWDECIMAL) + { + char buf[310]; + // reserve enough space for the longest double value + // -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and + // 2.2250738585072014E-308 to 1.7976931348623157E+308. + snprintf(buf, 310, "%.18g", dl); + return m_field->store(buf, strlen(buf), m_field->charset()); + } + + // The server converts dl=-0 to dl=0 in (*f)->store(). + // This happens in the call to truncate_double(). + // This is an unexpected behaviour, so we directly store the + // double value using the lower level float8store() function. + // TODO Remove this when (*f)->store() handles this properly. + m_field->field_length = 310; + if (dl == 0) + { + float8store(m_field->ptr,dl); + return 0; + } + return m_field->store(dl); + } + + int store_long_double(long double dl) override + { + if (dl == std::numeric_limits::infinity()) + { + m_field->set_null(); + return 1; + } + + if (m_field->type() == MYSQL_TYPE_NEWDECIMAL) + { + char buf[310]; + snprintf(buf, 310, "%.20Lg", dl); + return m_field->store(buf, strlen(buf), m_field->charset()); + } + + // reserve enough space for the longest double value + // -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and + // 2.2250738585072014E-308 to 1.7976931348623157E+308. + m_field->field_length = 310; + return m_field->store(static_cast(dl)); + } + + int store_decimal64(int64_t val) override + { + // @bug4388 stick to InfiniDB's scale in case mysql gives wrong scale due + // to create vtable limitation. + //if (f2->dec < m_type.scale) + // f2->dec = m_type.scale; + + // WIP MCOL-641 + // This is too much + char buf[256]; + dataconvert::DataConvert::decimalToString(val, (unsigned)m_type.scale, + buf, sizeof(buf), m_type.colDataType); + return m_field->store(buf, strlen(buf), m_field->charset()); + } + + int store_decimal128(const int128_t &val) override + { + // We won't have more than [+-][0][.] + up to 38 digits + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; + dataconvert::DataConvert::decimalToString((int128_t*) &val, + (unsigned) m_type.scale, + buf, (uint8_t) sizeof(buf), + m_type.colDataType); + return m_field->store(buf, strlen(buf), m_field->charset()); + } + + int store_lob(const char *str, size_t length) override + { + idbassert(dynamic_cast(m_field)); + Field_blob* f2 = static_cast(m_field); + f2->set_ptr(length, (uchar*) str); + return 0; + } + +}; + + +/*******************************************************************************/ + +class WriteBatchFieldMariaDB: public WriteBatchField +{ +public: + Field *m_field; + const CalpontSystemCatalog::ColType &m_type; + WriteBatchFieldMariaDB(Field *field, const CalpontSystemCatalog::ColType type) + :m_field(field), m_type(type) + { } + size_t ColWriteBatchDate(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + // QQ: OLD DATE is not handled + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + { + fprintf(ci.filePtr(), "%c", ci.delimiter()); + } + else + { + const uchar* tmp1 = buf; + uint32_t tmp = (tmp1[2] << 16) + (tmp1[1] << 8) + tmp1[0]; + int day = tmp & 0x0000001fl; + int month = (tmp >> 5) & 0x0000000fl; + int year = tmp >> 9; + fprintf(ci.filePtr(), "%04d-%02d-%02d%c", year, month, day, ci.delimiter()); + } + return 3; + } + size_t ColWriteBatchDatetime(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + { + fprintf(ci.filePtr(), "%c", ci.delimiter()); + + if (m_field->real_type() == MYSQL_TYPE_DATETIME2) + return m_field->pack_length(); + else + return 8; + } + + if (m_field->real_type() == MYSQL_TYPE_DATETIME2) + { + // mariadb 10.1 compatibility -- MYSQL_TYPE_DATETIME2 introduced in mysql 5.6 + MYSQL_TIME ltime; + longlong tmp = my_datetime_packed_from_binary(buf, m_field->decimals()); + TIME_from_longlong_datetime_packed(<ime, tmp); + + if (!ltime.second_part) + { + fprintf(ci.filePtr(), "%04d-%02d-%02d %02d:%02d:%02d%c", + ltime.year, ltime.month, ltime.day, + ltime.hour, ltime.minute, ltime.second, ci.delimiter()); + } + else + { + fprintf(ci.filePtr(), "%04d-%02d-%02d %02d:%02d:%02d.%ld%c", + ltime.year, ltime.month, ltime.day, + ltime.hour, ltime.minute, ltime.second, + ltime.second_part, ci.delimiter()); + } + + return m_field->pack_length(); + } + + // Old DATETIME + long long value = *((long long*) buf); + long datePart = (long) (value / 1000000ll); + int day = datePart % 100; + int month = (datePart / 100) % 100; + int year = datePart / 10000; + fprintf(ci.filePtr(), "%04d-%02d-%02d ", year, month, day); + + long timePart = (long) (value - (long long) datePart * 1000000ll); + int second = timePart % 100; + int min = (timePart / 100) % 100; + int hour = timePart / 10000; + fprintf(ci.filePtr(), "%02d:%02d:%02d%c", hour, min, second, ci.delimiter()); + return 8; + } + size_t ColWriteBatchTime(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + // QQ: why old TIME is not handled? + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + { + fprintf(ci.filePtr(), "%c", ci.delimiter()); + return m_field->pack_length(); + } + + MYSQL_TIME ltime; + longlong tmp = my_time_packed_from_binary(buf, m_field->decimals()); + TIME_from_longlong_time_packed(<ime, tmp); + + if (ltime.neg) + fprintf(ci.filePtr(), "-"); + + if (!ltime.second_part) + { + fprintf(ci.filePtr(), "%02d:%02d:%02d%c", + ltime.hour, ltime.minute, ltime.second, ci.delimiter()); + } + else + { + fprintf(ci.filePtr(), "%02d:%02d:%02d.%ld%c", + ltime.hour, ltime.minute, ltime.second, + ltime.second_part, ci.delimiter()); + } + + return m_field->pack_length(); + } + + size_t ColWriteBatchTimestamp(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + // QQ: old TIMESTAMP is not handled + + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + { + fprintf(ci.filePtr(), "%c", ci.delimiter()); + return m_field->pack_length(); + } + + struct timeval tm; + my_timestamp_from_binary(&tm, buf, m_field->decimals()); + + MySQLTime time; + gmtSecToMySQLTime(tm.tv_sec, time, current_thd->variables.time_zone->get_name()->ptr()); + + if (!tm.tv_usec) + { + fprintf(ci.filePtr(), "%04d-%02d-%02d %02d:%02d:%02d%c", + time.year, time.month, time.day, + time.hour, time.minute, time.second, ci.delimiter()); + } + else + { + fprintf(ci.filePtr(), "%04d-%02d-%02d %02d:%02d:%02d.%ld%c", + time.year, time.month, time.day, + time.hour, time.minute, time.second, + tm.tv_usec, ci.delimiter()); + } + return m_field->pack_length(); + } + + size_t ColWriteBatchChar(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + { + fprintf(ci.filePtr(), "%c", ci.delimiter()); + } + else + { + if (current_thd->variables.sql_mode & MODE_PAD_CHAR_TO_FULL_LENGTH) + { + std::string escape; + // Pad to the full length of the field + if (ci.utf8()) + escape.assign((char*)buf, m_type.colWidth * 3); + else + escape.assign((char*)buf, m_type.colWidth); + + boost::replace_all(escape, "\\", "\\\\"); + + fprintf(ci.filePtr(), "%c%.*s%c%c", + ci.enclosed_by(), + (int)escape.length(), escape.c_str(), + ci.enclosed_by(), ci.delimiter()); + } + else + { + std::string escape; + // Get the actual data length + bitmap_set_bit(m_field->table->read_set, m_field->field_index); + String attribute; + m_field->val_str(&attribute); + + escape.assign((char*)buf, attribute.length()); + boost::replace_all(escape, "\\", "\\\\"); + + fprintf(ci.filePtr(), "%c%.*s%c%c", + ci.enclosed_by(), + (int)escape.length(), escape.c_str(), + ci.enclosed_by(), ci.delimiter()); + } + } + + if (ci.utf8()) + return m_type.colWidth * 3; + else + return m_type.colWidth; + } + + size_t ColWriteBatchVarchar(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + const uchar *buf0= buf; + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + { + fprintf(ci.filePtr(), "%c", ci.delimiter()); + + if (!ci.utf8()) + { + if (m_type.colWidth < 256) + { + buf++; + } + else + { + buf = buf + 2 ; + } + } + else //utf8 + { + if (m_type.colWidth < 86) + { + buf++; + } + else + { + buf = buf + 2 ; + } + } + } + else + { + int dataLength = 0; + + if (!ci.utf8()) + { + if (m_type.colWidth < 256) + { + dataLength = *(uint8_t*) buf; + buf++; + } + else + { + dataLength = *(uint16_t*) buf; + buf = buf + 2 ; + } + std::string escape; + escape.assign((char*)buf, dataLength); + boost::replace_all(escape, "\\", "\\\\"); + fprintf(ci.filePtr(), "%c%.*s%c%c", + ci.enclosed_by(), + (int)escape.length(), escape.c_str(), + ci.enclosed_by(), ci.delimiter()); + } + else //utf8 + { + if (m_type.colWidth < 86) + { + dataLength = *(uint8_t*) buf; + buf++; + } + else + { + dataLength = *(uint16_t*) buf; + buf = buf + 2 ; + } + + std::string escape; + escape.assign((char*)buf, dataLength); + boost::replace_all(escape, "\\", "\\\\"); + + fprintf(ci.filePtr(), "%c%.*s%c%c", + ci.enclosed_by(), + (int)escape.length(), escape.c_str(), + ci.enclosed_by(), ci.delimiter()); + } + } + if (ci.utf8()) + buf += (m_type.colWidth * 3); + else + buf += m_type.colWidth; + return buf - buf0; + } + + size_t ColWriteBatchSInt64(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + fprintf(ci.filePtr(), "%lld%c", *((long long*)buf), ci.delimiter()); + return 8; + } + + size_t ColWriteBatchUInt64(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + fprintf(ci.filePtr(), "%llu%c", *((long long unsigned*)buf), ci.delimiter()); + return 8; + } + + + size_t ColWriteBatchSInt32(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + fprintf(ci.filePtr(), "%d%c", *((int32_t*)buf), ci.delimiter()); + return 4; + } + + size_t ColWriteBatchUInt32(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + fprintf(ci.filePtr(), "%u%c", *((uint32_t*)buf), ci.delimiter()); + return 4; + } + + size_t ColWriteBatchSInt16(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + fprintf(ci.filePtr(), "%d%c", *((int16_t*)buf), ci.delimiter()); + return 2; + } + + size_t ColWriteBatchUInt16(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + fprintf(ci.filePtr(), "%u%c", *((uint16_t*)buf), ci.delimiter()); + return 2; + } + + size_t ColWriteBatchSInt8(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + fprintf(ci.filePtr(), "%d%c", *((int8_t*)buf), ci.delimiter()); + return 1; + } + + size_t ColWriteBatchUInt8(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + fprintf(ci.filePtr(), "%u%c", *((uint8_t*)buf), ci.delimiter()); + return 1; + } + + + size_t ColWriteBatchXFloat(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + { + float val = *((float*)buf); + + if ((fabs(val) > (1.0 / IDB_pow[4])) && (fabs(val) < (float) IDB_pow[6])) + { + fprintf(ci.filePtr(), "%.7f%c", val, ci.delimiter()); + } + else + { + fprintf(ci.filePtr(), "%e%c", val, ci.delimiter()); + } + + //fprintf(ci.filePtr(), "%.7g|", *((float*)buf2)); + //printf("%.7f|", *((float*)buf2)); + } + + return 4; + } + + + size_t ColWriteBatchXDouble(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + { + fprintf(ci.filePtr(), "%.15g%c", *((double*)buf), ci.delimiter()); + //printf("%.15g|", *((double*)buf)); + } + + return 8; + } + + + size_t ColWriteBatchSLongDouble(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + fprintf(ci.filePtr(), "%c", ci.delimiter()); + else + fprintf(ci.filePtr(), "%.15Lg%c", *((long double*)buf), ci.delimiter()); + return sizeof(long double); + } + + + size_t ColWriteBatchXDecimal(const uchar *buf, bool nullVal, ColBatchWriter &ci) override + { + uint bytesBefore = 1; + uint totalBytes = 9; + + switch (m_type.precision) + { + case 18: + case 17: + case 16: + { + totalBytes = 8; + break; + } + + case 15: + case 14: + { + totalBytes = 7; + break; + } + + case 13: + case 12: + { + totalBytes = 6; + break; + } + + case 11: + { + totalBytes = 5; + break; + } + + case 10: + { + totalBytes = 5; + break; + } + + case 9: + case 8: + case 7: + { + totalBytes = 4; + break; + } + + case 6: + case 5: + { + totalBytes = 3; + break; + } + + case 4: + case 3: + { + totalBytes = 2; + break; + } + + case 2: + case 1: + { + totalBytes = 1; + break; + } + + default: + break; + } + + switch (m_type.scale) + { + case 0: + { + bytesBefore = totalBytes; + break; + } + + case 1: //1 byte for digits after decimal point + { + if ((m_type.precision != 16) && (m_type.precision != 14) + && (m_type.precision != 12) && (m_type.precision != 10) + && (m_type.precision != 7) && (m_type.precision != 5) + && (m_type.precision != 3) && (m_type.precision != 1)) + totalBytes++; + + bytesBefore = totalBytes - 1; + break; + } + + case 2: //1 byte for digits after decimal point + { + if ((m_type.precision == 18) || (m_type.precision == 9)) + totalBytes++; + + bytesBefore = totalBytes - 1; + break; + } + + case 3: //2 bytes for digits after decimal point + { + if ((m_type.precision != 16) && (m_type.precision != 14) + && (m_type.precision != 12) && (m_type.precision != 7) + && (m_type.precision != 5) && (m_type.precision != 3)) + totalBytes++; + + bytesBefore = totalBytes - 2; + break; + } + + case 4: + { + if ((m_type.precision == 18) || (m_type.precision == 11) + || (m_type.precision == 9)) + totalBytes++; + + bytesBefore = totalBytes - 2; + break; + + } + + case 5: + { + if ((m_type.precision != 16) && (m_type.precision != 14) + && (m_type.precision != 7) && (m_type.precision != 5)) + totalBytes++; + + bytesBefore = totalBytes - 3; + break; + } + + case 6: + { + if ((m_type.precision == 18) || (m_type.precision == 13) + || (m_type.precision == 11) || (m_type.precision == 9)) + totalBytes++; + + bytesBefore = totalBytes - 3; + break; + } + + case 7: + { + if ((m_type.precision != 16) && (m_type.precision != 7)) + totalBytes++; + + bytesBefore = totalBytes - 4; + break; + } + + case 8: + { + if ((m_type.precision == 18) || (m_type.precision == 15) + || (m_type.precision == 13) || (m_type.precision == 11) + || (m_type.precision == 9)) + totalBytes++; + + bytesBefore = totalBytes - 4;; + break; + } + + case 9: + { + bytesBefore = totalBytes - 4;; + break; + } + + case 10: + { + if ((m_type.precision != 16) && (m_type.precision != 14) + && (m_type.precision != 12) && (m_type.precision != 10)) + totalBytes++; + + bytesBefore = totalBytes - 5;; + break; + } + + case 11: + { + if (m_type.precision == 18) + totalBytes++; + + bytesBefore = totalBytes - 5; + break; + } + + case 12: + { + if ((m_type.precision != 16) && (m_type.precision != 14) + && (m_type.precision != 12)) + totalBytes++; + + bytesBefore = totalBytes - 6; + break; + } + + case 13: + { + if (m_type.precision == 18) + totalBytes++; + + bytesBefore = totalBytes - 6; + break; + } + + case 14: + { + if ((m_type.precision != 16) && (m_type.precision != 14)) + totalBytes++; + + bytesBefore = totalBytes - 7; + break; + } + + case 15: + { + if (m_type.precision == 18) + totalBytes++; + + bytesBefore = totalBytes - 7; + break; + } + + case 16: + { + if (m_type.precision != 16) + totalBytes++; + + bytesBefore = totalBytes - 8; + break; + } + + case 17: + { + if (m_type.precision == 18) + totalBytes++; + + bytesBefore = totalBytes - 8; + break; + } + + case 18: + { + bytesBefore = totalBytes - 8; + break; + } + + default: + break; + } + + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + { + fprintf(ci.filePtr(), "%c", ci.delimiter()); + //printf("|"); + } + else + { + uint32_t mask [5] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF}; + char neg = '-'; + + if (m_type.scale == 0) + { + const uchar* tmpBuf = buf; + //test flag bit for sign + bool posNum = tmpBuf[0] & (0x80); + uchar tmpChr = tmpBuf[0]; + tmpChr ^= 0x80; //flip the bit + int32_t tmp1 = tmpChr; + + if (totalBytes > 4) + { + for (uint i = 1; i < (totalBytes - 4); i++) + { + tmp1 = (tmp1 << 8) + tmpBuf[i]; + } + + if (( tmp1 != 0 ) && (tmp1 != -1)) + { + if (!posNum) + { + tmp1 = mask[totalBytes - 4] - tmp1; + + if (tmp1 != 0) + { + fprintf(ci.filePtr(), "%c", neg); + //printf("%c", neg); + } + } + + if (tmp1 != 0) + { + fprintf(ci.filePtr(), "%d", tmp1); + ////printf("%d", tmp1); + } + } + + int32_t tmp2 = tmpBuf[totalBytes - 4]; + + for (uint i = (totalBytes - 3); i < totalBytes; i++) + { + tmp2 = (tmp2 << 8) + tmpBuf[i]; + } + + if ( tmp1 != 0 ) + { + if (!posNum) + { + tmp2 = mask[4] - tmp2; + + if (tmp1 == -1) + { + fprintf(ci.filePtr(), "%c", neg); + fprintf(ci.filePtr(), "%d%c", tmp2, ci.delimiter()); + ////printf("%c", neg); + //////printf( "%d|", tmp2); + } + else + { + fprintf(ci.filePtr(), "%09u%c", tmp2, ci.delimiter()); + ////printf("%09u|", tmp2); + } + } + else + { + fprintf(ci.filePtr(), "%09u%c", tmp2, ci.delimiter()); + //printf("%09u|", tmp2); + } + } + else + { + if (!posNum) + { + tmp2 = mask[4] - tmp2; + fprintf(ci.filePtr(), "%c", neg); + //printf("%c", neg); + } + + fprintf(ci.filePtr(), "%d%c", tmp2, ci.delimiter()); + //printf("%d|", tmp2); + } + } + else + { + for (uint i = 1; i < totalBytes; i++) + { + tmp1 = (tmp1 << 8) + tmpBuf[i]; + } + + if (!posNum) + { + tmp1 = mask[totalBytes] - tmp1; + fprintf(ci.filePtr(), "%c", neg); + //printf("%c", neg); + } + + fprintf(ci.filePtr(), "%d%c", tmp1, ci.delimiter()); + //printf("%d|", tmp1); + } + } + else + { + const uchar* tmpBuf = buf; + //test flag bit for sign + bool posNum = tmpBuf[0] & (0x80); + uchar tmpChr = tmpBuf[0]; + tmpChr ^= 0x80; //flip the bit + int32_t tmp1 = tmpChr; + + //fetch the digits before decimal point + if (bytesBefore == 0) + { + if (!posNum) + { + fprintf(ci.filePtr(), "%c", neg); + //printf("%c", neg); + } + + fprintf(ci.filePtr(), "0."); + //printf("0."); + } + else if (bytesBefore > 4) + { + for (uint i = 1; i < (bytesBefore - 4); i++) + { + tmp1 = (tmp1 << 8) + tmpBuf[i]; + } + + if (!posNum) + { + tmp1 = mask[bytesBefore - 4] - tmp1; + } + + if (( tmp1 != 0 ) && (tmp1 != -1)) + { + if (!posNum) + { + fprintf(ci.filePtr(), "%c", neg); + //printf("%c", neg); + } + + fprintf(ci.filePtr(), "%d", tmp1); + //printf("%d", tmp1); + } + + tmpBuf += (bytesBefore - 4); + int32_t tmp2 = *((int32_t*)tmpBuf); + tmp2 = ntohl(tmp2); + + if ( tmp1 != 0 ) + { + if (!posNum) + { + tmp2 = mask[4] - tmp2; + } + + if (tmp1 == -1) + { + fprintf(ci.filePtr(), "%c", neg); + fprintf(ci.filePtr(), "%d.", tmp2); + //printf("%c", neg); + //printf("%d.", tmp2); + } + else + { + fprintf(ci.filePtr(), "%09u.", tmp2); + //printf("%09u.", tmp2); + } + } + else + { + if (!posNum) + { + tmp2 = mask[4] - tmp2; + fprintf(ci.filePtr(), "%c", neg); + //printf("%c", neg); + } + + fprintf(ci.filePtr(), "%d.", tmp2); + //printf("%d.", tmp2); + } + } + else + { + for (uint i = 1; i < bytesBefore; i++) + { + tmp1 = (tmp1 << 8) + tmpBuf[i]; + } + + if (!posNum) + { + tmp1 = mask[bytesBefore] - tmp1; + fprintf(ci.filePtr(), "%c", neg); + //printf("%c", neg); + } + + fprintf(ci.filePtr(), "%d.", tmp1); + //printf("%d.", tmp1); + } + + //fetch the digits after decimal point + int32_t tmp2 = 0; + + if (bytesBefore > 4) + tmpBuf += 4; + else + tmpBuf += bytesBefore; + + tmp2 = tmpBuf[0]; + + if ((totalBytes - bytesBefore) < 5) + { + for (uint j = 1; j < (totalBytes - bytesBefore); j++) + { + tmp2 = (tmp2 << 8) + tmpBuf[j]; + } + + int8_t digits = m_type.scale - 9; //9 digits is a 4 bytes chunk + + if ( digits <= 0 ) + digits = m_type.scale; + + if (!posNum) + { + tmp2 = mask[totalBytes - bytesBefore] - tmp2; + } + + fprintf(ci.filePtr(), "%0*u%c", digits, tmp2, ci.delimiter()); + //printf("%0*u|", digits, tmp2); + } + else + { + for (uint j = 1; j < 4; j++) + { + tmp2 = (tmp2 << 8) + tmpBuf[j]; + } + + if (!posNum) + { + tmp2 = mask[4] - tmp2; + } + + fprintf(ci.filePtr(), "%09u", tmp2); + //printf("%09u", tmp2); + + tmpBuf += 4; + int32_t tmp3 = tmpBuf[0]; + + for (uint j = 1; j < (totalBytes - bytesBefore - 4); j++) + { + tmp3 = (tmp3 << 8) + tmpBuf[j]; + } + + int8_t digits = m_type.scale - 9; //9 digits is a 4 bytes chunk + + if ( digits < 0 ) + digits = m_type.scale; + + if (!posNum) + { + tmp3 = mask[totalBytes - bytesBefore - 4] - tmp3; + } + + fprintf(ci.filePtr(), "%0*u%c", digits, tmp3, ci.delimiter()); + //printf("%0*u|", digits, tmp3); + } + } + } + + return totalBytes; + } + + + size_t ColWriteBatchVarbinary(const uchar *buf0, bool nullVal, ColBatchWriter &ci) override + { + const uchar *buf= buf0; + if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) + { + fprintf(ci.filePtr(), "%c", ci.delimiter()); + + if (!ci.utf8()) + { + if (m_type.colWidth < 256) + { + buf++; + } + else + { + buf = buf + 2; + } + } + else //utf8 + { + if (m_type.colWidth < 86) + { + buf++; + } + else + { + buf = buf + 2 ; + } + } + } + else + { + int dataLength = 0; + + if (!ci.utf8()) + { + if (m_type.colWidth < 256) + { + dataLength = *(int8_t*) buf; + buf++; + } + else + { + dataLength = *(int16_t*) buf; + buf = buf + 2 ; + } + + const uchar* tmpBuf = buf; + + for (int32_t i = 0; i < dataLength; i++) + { + fprintf(ci.filePtr(), "%02x", *(uint8_t*)tmpBuf); + tmpBuf++; + } + + fprintf(ci.filePtr(), "%c", ci.delimiter()); + } + else //utf8 + { + if (m_type.colWidth < 86) + { + dataLength = *(int8_t*) buf; + buf++; + } + else + { + dataLength = *(uint16_t*) buf; + buf = buf + 2 ; + } + + if ( dataLength > m_type.colWidth) + dataLength = m_type.colWidth; + + const uchar* tmpBuf = buf; + + for (int32_t i = 0; i < dataLength; i++) + { + fprintf(ci.filePtr(), "%02x", *(uint8_t*)tmpBuf); + tmpBuf++; + } + + fprintf(ci.filePtr(), "%c", ci.delimiter()); + } + } + + if (ci.utf8()) + buf += (m_type.colWidth * 3); // QQ: why? It is varbinary! + else + buf += m_type.colWidth; + + return buf - buf0; + } + + + size_t ColWriteBatchBlob(const uchar *buf0, bool nullVal, ColBatchWriter &ci) override + { + const uchar *buf= buf0; + // MCOL-4005 Note that we don't handle nulls as a special + // case here as we do for other datatypes, the below works + // as expected for nulls. + uint32_t dataLength = 0; + uintptr_t* dataptr; + uchar* ucharptr; + uint colWidthInBytes = (ci.utf8() ? + m_type.colWidth * 3: m_type.colWidth); + + if (colWidthInBytes < 256) + { + dataLength = *(uint8_t*) buf; + buf++; + } + else if (colWidthInBytes < 65536) + { + dataLength = *(uint16_t*) buf; + buf += 2; + } + else if (colWidthInBytes < 16777216) + { + dataLength = *(uint16_t*) buf; + dataLength |= ((int) buf[2]) << 16; + buf += 3; + } + else + { + dataLength = *(uint32_t*) buf; + buf += 4; + } + + // buf contains pointer to blob, for example: + // (gdb) p (char*)*(uintptr_t*)buf + // $43 = 0x7f68500c58f8 "hello world" + + dataptr = (uintptr_t*)buf; + ucharptr = (uchar*)*dataptr; + buf += sizeof(uintptr_t); + + if (m_type.colDataType == CalpontSystemCatalog::BLOB) + { + for (uint32_t i = 0; i < dataLength; i++) + { + fprintf(ci.filePtr(), "%02x", *(uint8_t*)ucharptr); + ucharptr++; + } + + fprintf(ci.filePtr(), "%c", ci.delimiter()); + } + else + { + // TEXT Column + std::string escape; + escape.assign((char*)ucharptr, dataLength); + boost::replace_all(escape, "\\", "\\\\"); + fprintf(ci.filePtr(), "%c%.*s%c%c", + ci.enclosed_by(), + (int)escape.length(), escape.c_str(), + ci.enclosed_by(), ci.delimiter()); + } + + return buf - buf0; + } + +}; + +} // end of namespace datatypes + +#endif + +// vim:ts=2 sw=2: diff --git a/dbcon/mysql/ha_mcs_ddl.cpp b/dbcon/mysql/ha_mcs_ddl.cpp index 32daf2c48..e1eca830f 100644 --- a/dbcon/mysql/ha_mcs_ddl.cpp +++ b/dbcon/mysql/ha_mcs_ddl.cpp @@ -61,9 +61,6 @@ using namespace ddlpackage; #include "ddlpackageprocessor.h" using namespace ddlpackageprocessor; -#include "dataconvert.h" -using namespace dataconvert; - #include "bytestream.h" using namespace messageqcpp; @@ -133,135 +130,16 @@ static void decode_file_path(const char *path, char *decoded_dbname, decode_objectname(decoded_tbname, tbname_start, FN_REFLEN); } -uint32_t convertDataType(int dataType) + +CalpontSystemCatalog::ColDataType convertDataType(const ddlpackage::ColumnType &ct) { - uint32_t calpontDataType; - - switch (dataType) - { - case ddlpackage::DDL_CHAR: - calpontDataType = CalpontSystemCatalog::CHAR; - break; - - case ddlpackage::DDL_VARCHAR: - calpontDataType = CalpontSystemCatalog::VARCHAR; - break; - - case ddlpackage::DDL_VARBINARY: - calpontDataType = CalpontSystemCatalog::VARBINARY; - break; - - case ddlpackage::DDL_BIT: - calpontDataType = CalpontSystemCatalog::BIT; - break; - - case ddlpackage::DDL_REAL: - case ddlpackage::DDL_DECIMAL: - case ddlpackage::DDL_NUMERIC: - case ddlpackage::DDL_NUMBER: - calpontDataType = CalpontSystemCatalog::DECIMAL; - break; - - case ddlpackage::DDL_FLOAT: - calpontDataType = CalpontSystemCatalog::FLOAT; - break; - - case ddlpackage::DDL_DOUBLE: - calpontDataType = CalpontSystemCatalog::DOUBLE; - break; - - case ddlpackage::DDL_INT: - case ddlpackage::DDL_INTEGER: - calpontDataType = CalpontSystemCatalog::INT; - break; - - case ddlpackage::DDL_BIGINT: - calpontDataType = CalpontSystemCatalog::BIGINT; - break; - - case ddlpackage::DDL_MEDINT: - calpontDataType = CalpontSystemCatalog::MEDINT; - break; - - case ddlpackage::DDL_SMALLINT: - calpontDataType = CalpontSystemCatalog::SMALLINT; - break; - - case ddlpackage::DDL_TINYINT: - calpontDataType = CalpontSystemCatalog::TINYINT; - break; - - case ddlpackage::DDL_DATE: - calpontDataType = CalpontSystemCatalog::DATE; - break; - - case ddlpackage::DDL_DATETIME: - calpontDataType = CalpontSystemCatalog::DATETIME; - break; - - case ddlpackage::DDL_TIME: - calpontDataType = CalpontSystemCatalog::TIME; - break; - - case ddlpackage::DDL_TIMESTAMP: - calpontDataType = CalpontSystemCatalog::TIMESTAMP; - break; - - case ddlpackage::DDL_CLOB: - calpontDataType = CalpontSystemCatalog::CLOB; - break; - - case ddlpackage::DDL_BLOB: - calpontDataType = CalpontSystemCatalog::BLOB; - break; - - case ddlpackage::DDL_TEXT: - calpontDataType = CalpontSystemCatalog::TEXT; - break; - - case ddlpackage::DDL_UNSIGNED_TINYINT: - calpontDataType = CalpontSystemCatalog::UTINYINT; - break; - - case ddlpackage::DDL_UNSIGNED_SMALLINT: - calpontDataType = CalpontSystemCatalog::USMALLINT; - break; - - case ddlpackage::DDL_UNSIGNED_MEDINT: - calpontDataType = CalpontSystemCatalog::UMEDINT; - break; - - case ddlpackage::DDL_UNSIGNED_INT: - calpontDataType = CalpontSystemCatalog::UINT; - break; - - case ddlpackage::DDL_UNSIGNED_BIGINT: - calpontDataType = CalpontSystemCatalog::UBIGINT; - break; - - case ddlpackage::DDL_UNSIGNED_DECIMAL: - case ddlpackage::DDL_UNSIGNED_NUMERIC: - calpontDataType = CalpontSystemCatalog::UDECIMAL; - break; - - case ddlpackage::DDL_UNSIGNED_FLOAT: - calpontDataType = CalpontSystemCatalog::UFLOAT; - break; - - case ddlpackage::DDL_UNSIGNED_DOUBLE: - calpontDataType = CalpontSystemCatalog::UDOUBLE; - break; - - case ddlpackage::DDL_BINARY: - calpontDataType = CalpontSystemCatalog::BINARY; - break; - - default: - throw runtime_error("Unsupported datatype!"); - - } - - return calpontDataType; + const datatypes::TypeHandler *h= datatypes::TypeHandler::find_by_ddltype(ct); + if (!h) + { + throw runtime_error("Unsupported datatype!"); + return CalpontSystemCatalog::UNDEFINED; + } + return h->code(); } @@ -1007,10 +885,10 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl if (!createTable->fTableDef->fColumns[i]->fDefaultValue->fNull) { //validate the default value, if out of range, just error out - uint32_t dataType; + CalpontSystemCatalog::ColDataType dataType; dataType = convertDataType(createTable->fTableDef->fColumns[i]->fType->fType); CalpontSystemCatalog::ColType colType; - colType.colDataType = (CalpontSystemCatalog::ColDataType) dataType; + colType.colDataType = dataType; colType.colWidth = createTable->fTableDef->fColumns[i]->fType->fLength; colType.precision = createTable->fTableDef->fColumns[i]->fType->fPrecision; colType.scale = createTable->fTableDef->fColumns[i]->fType->fScale; @@ -1019,7 +897,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl try { - convertedVal = DataConvert::convertColumnData(colType, createTable->fTableDef->fColumns[i]->fDefaultValue->fValue, pushWarning, thd->variables.time_zone->get_name()->ptr(), false, false, false); + convertedVal = colType.convertColumnData(createTable->fTableDef->fColumns[i]->fDefaultValue->fValue, pushWarning, thd->variables.time_zone->get_name()->ptr(), false, false, false); } catch (std::exception&) { @@ -1383,10 +1261,10 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl } //validate the default value, if out of range, just error out - uint32_t dataType; + CalpontSystemCatalog::ColDataType dataType; dataType = convertDataType(addColumnPtr->fColumnDef->fType->fType); CalpontSystemCatalog::ColType colType; - colType.colDataType = (CalpontSystemCatalog::ColDataType) dataType; + colType.colDataType = dataType; colType.colWidth = addColumnPtr->fColumnDef->fType->fLength; colType.precision = addColumnPtr->fColumnDef->fType->fPrecision; colType.scale = addColumnPtr->fColumnDef->fType->fScale; @@ -1395,7 +1273,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl try { - convertedVal = DataConvert::convertColumnData(colType, addColumnPtr->fColumnDef->fDefaultValue->fValue, pushWarning, thd->variables.time_zone->get_name()->ptr(), false, false, false); + convertedVal = colType.convertColumnData(addColumnPtr->fColumnDef->fDefaultValue->fValue, pushWarning, thd->variables.time_zone->get_name()->ptr(), false, false, false); } catch (std::exception&) { @@ -1737,10 +1615,10 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl } //validate the default value, if out of range, just error out - uint32_t dataType; + CalpontSystemCatalog::ColDataType dataType; dataType = convertDataType(addColumnsPtr->fColumns[0]->fType->fType); CalpontSystemCatalog::ColType colType; - colType.colDataType = (CalpontSystemCatalog::ColDataType) dataType; + colType.colDataType = dataType; colType.colWidth = addColumnsPtr->fColumns[0]->fType->fLength; colType.precision = addColumnsPtr->fColumns[0]->fType->fPrecision; colType.scale = addColumnsPtr->fColumns[0]->fType->fScale; @@ -1749,7 +1627,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl try { - convertedVal = DataConvert::convertColumnData(colType, addColumnsPtr->fColumns[0]->fDefaultValue->fValue, pushWarning, thd->variables.time_zone->get_name()->ptr(), false, false, false); + convertedVal = colType.convertColumnData(addColumnsPtr->fColumns[0]->fDefaultValue->fValue, pushWarning, thd->variables.time_zone->get_name()->ptr(), false, false, false); } catch (std::exception&) { diff --git a/dbcon/mysql/ha_mcs_dml.cpp b/dbcon/mysql/ha_mcs_dml.cpp index 06d1129fe..88d9997f9 100644 --- a/dbcon/mysql/ha_mcs_dml.cpp +++ b/dbcon/mysql/ha_mcs_dml.cpp @@ -75,6 +75,8 @@ using namespace joblist; #include "dbrm.h" +#include "ha_mcs_datatype.h" + namespace { #define BATCH_INSERT_GROUP_ROWS_FOR_CACHE 100000 @@ -669,6 +671,7 @@ int ha_mcs_impl_write_row_(const uchar* buf, TABLE* table, cal_connection_info& } } + int ha_mcs_impl_write_batch_row_(const uchar* buf, TABLE* table, cal_impl_if::cal_connection_info& ci) { ByteStream rowData; @@ -681,7 +684,6 @@ int ha_mcs_impl_write_batch_row_(const uchar* buf, TABLE* table, cal_impl_if::ca uint16_t colpos = 0; buf = buf + ci.headerLength; // Number of bytes used for null bits. //@Bug 6122 if all columns have not null constraint, there is no information in the header - std::string escape; char nullBits = *bufHdr++; if (!ci.useXbit) @@ -730,1078 +732,16 @@ int ha_mcs_impl_write_batch_row_(const uchar* buf, TABLE* table, cal_impl_if::ca nullVal = false; } - switch (ci.columnTypes[colpos].colDataType) + const CalpontSystemCatalog::ColType &colType= ci.columnTypes[colpos]; + const datatypes::TypeHandler *h= colType.typeHandler(); + if (h) // QQ: error reporting { - case CalpontSystemCatalog::DATE: //date fetch - { - - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - { - fprintf(ci.filePtr, "%c", ci.delimiter); - } - else - { - const uchar* tmp1 = buf; - uint32_t tmp = (tmp1[2] << 16) + (tmp1[1] << 8) + tmp1[0]; - - int day = tmp & 0x0000001fl; - int month = (tmp >> 5) & 0x0000000fl; - int year = tmp >> 9; - fprintf(ci.filePtr, "%04d-%02d-%02d%c", year, month, day, ci.delimiter); - } - - buf += 3; - break; - } - - case CalpontSystemCatalog::DATETIME: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - { - fprintf(ci.filePtr, "%c", ci.delimiter); - - if (table->field[colpos]->real_type() == MYSQL_TYPE_DATETIME2) - buf += table->field[colpos]->pack_length(); - else - buf += 8; - } - else - { - if (table->field[colpos]->real_type() == MYSQL_TYPE_DATETIME2) - { - // mariadb 10.1 compatibility -- MYSQL_TYPE_DATETIME2 introduced in mysql 5.6 - MYSQL_TIME ltime; - const uchar* pos = buf; - longlong tmp = my_datetime_packed_from_binary(pos, table->field[colpos]->decimals()); - TIME_from_longlong_datetime_packed(<ime, tmp); - - if (!ltime.second_part) - { - fprintf(ci.filePtr, "%04d-%02d-%02d %02d:%02d:%02d%c", - ltime.year, ltime.month, ltime.day, - ltime.hour, ltime.minute, ltime.second, ci.delimiter); - } - else - { - fprintf(ci.filePtr, "%04d-%02d-%02d %02d:%02d:%02d.%ld%c", - ltime.year, ltime.month, ltime.day, - ltime.hour, ltime.minute, ltime.second, - ltime.second_part, ci.delimiter); - } - - buf += table->field[colpos]->pack_length(); - } - else - { - long long value = *((long long*) buf); - long datePart = (long) (value / 1000000ll); - int day = datePart % 100; - int month = (datePart / 100) % 100; - int year = datePart / 10000; - fprintf(ci.filePtr, "%04d-%02d-%02d ", year, month, day); - - long timePart = (long) (value - (long long) datePart * 1000000ll); - int second = timePart % 100; - int min = (timePart / 100) % 100; - int hour = timePart / 10000; - fprintf(ci.filePtr, "%02d:%02d:%02d%c", hour, min, second, ci.delimiter); - buf += 8; - } - } - - break; - } - - case CalpontSystemCatalog::TIME: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - { - fprintf(ci.filePtr, "%c", ci.delimiter); - - buf += table->field[colpos]->pack_length(); - } - else - { - MYSQL_TIME ltime; - const uchar* pos = buf; - longlong tmp = my_time_packed_from_binary(pos, table->field[colpos]->decimals()); - TIME_from_longlong_time_packed(<ime, tmp); - - if (ltime.neg) - { - fprintf(ci.filePtr, "-"); - } - - if (!ltime.second_part) - { - fprintf(ci.filePtr, "%02d:%02d:%02d%c", - ltime.hour, ltime.minute, ltime.second, ci.delimiter); - } - else - { - fprintf(ci.filePtr, "%02d:%02d:%02d.%ld%c", - ltime.hour, ltime.minute, ltime.second, - ltime.second_part, ci.delimiter); - } - - buf += table->field[colpos]->pack_length(); - } - - break; - } - - case CalpontSystemCatalog::TIMESTAMP: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - { - fprintf(ci.filePtr, "%c", ci.delimiter); - } - else - { - const uchar* pos = buf; - struct timeval tm; - my_timestamp_from_binary(&tm, pos, table->field[colpos]->decimals()); - - MySQLTime time; - gmtSecToMySQLTime(tm.tv_sec, time, current_thd->variables.time_zone->get_name()->ptr()); - - if (!tm.tv_usec) - { - fprintf(ci.filePtr, "%04d-%02d-%02d %02d:%02d:%02d%c", - time.year, time.month, time.day, - time.hour, time.minute, time.second, ci.delimiter); - } - else - { - fprintf(ci.filePtr, "%04d-%02d-%02d %02d:%02d:%02d.%ld%c", - time.year, time.month, time.day, - time.hour, time.minute, time.second, - tm.tv_usec, ci.delimiter); - } - } - - buf += table->field[colpos]->pack_length(); - - break; - } - - case CalpontSystemCatalog::CHAR: - { - Field* field = table->field[colpos]; - - uint32_t colWidthInBytes = - ci.columnTypes[colpos].colWidth * field->charset()->mbmaxlen; - - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - { - fprintf(ci.filePtr, "%c", ci.delimiter); - } - else - { - if (current_thd->variables.sql_mode & MODE_PAD_CHAR_TO_FULL_LENGTH) - { - // Pad to the full length of the field - escape.assign((char*)buf, colWidthInBytes); - - boost::replace_all(escape, "\\", "\\\\"); - - fprintf(ci.filePtr, "%c%.*s%c%c", ci.enclosed_by, (int)escape.length(), - escape.c_str(), ci.enclosed_by, ci.delimiter); - } - else - { - // Get the actual data length - Field* field = table->field[colpos]; - bitmap_set_bit(table->read_set, field->field_index); - String attribute; - field->val_str(&attribute); - - escape.assign((char*)buf, attribute.length()); - boost::replace_all(escape, "\\", "\\\\"); - - fprintf(ci.filePtr, "%c%.*s%c%c", ci.enclosed_by, (int)escape.length(), - escape.c_str(), ci.enclosed_by, ci.delimiter); - } - } - - buf += colWidthInBytes; - - break; - } - - case CalpontSystemCatalog::VARCHAR: - { - Field* field = table->field[colpos]; - - uint32_t colWidthInBytes = - ci.columnTypes[colpos].colWidth * field->charset()->mbmaxlen; - - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - { - fprintf(ci.filePtr, "%c", ci.delimiter); - - if (colWidthInBytes < 256) - { - buf++; - } - else - { - buf = buf + 2 ; - } - } - else - { - // Maximum number of bytes allowed for a VARCHAR - // field is 65532, so the max length fits in 2 bytes. - // dataLength is length in bytes, not length in chars - uint16_t dataLength = 0; - - if (colWidthInBytes < 256) - { - dataLength = *(uint8_t*) buf; - buf++; - } - else - { - dataLength = *(uint16_t*) buf; - buf = buf + 2 ; - } - - escape.assign((char*)buf, dataLength); - boost::replace_all(escape, "\\", "\\\\"); - fprintf(ci.filePtr, "%c%.*s%c%c", ci.enclosed_by, (int)escape.length(), escape.c_str(), ci.enclosed_by, ci.delimiter); - } - - buf += colWidthInBytes; - - break; - } - - case CalpontSystemCatalog::BIGINT: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - fprintf(ci.filePtr, "%c", ci.delimiter); - else - fprintf(ci.filePtr, "%lld%c", *((long long*)buf), ci.delimiter); - - buf += 8; - break; - } - - case CalpontSystemCatalog::UBIGINT: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - fprintf(ci.filePtr, "%c", ci.delimiter); - else - fprintf(ci.filePtr, "%llu%c", *((long long unsigned*)buf), ci.delimiter); - - buf += 8; - break; - } - - case CalpontSystemCatalog::INT: - case CalpontSystemCatalog::MEDINT: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - fprintf(ci.filePtr, "%c", ci.delimiter); - else - fprintf(ci.filePtr, "%d%c", *((int32_t*)buf), ci.delimiter); - - buf += 4; - break; - } - - case CalpontSystemCatalog::UINT: - case CalpontSystemCatalog::UMEDINT: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - fprintf(ci.filePtr, "%c", ci.delimiter); - else - { - fprintf(ci.filePtr, "%u%c", *((uint32_t*)buf), ci.delimiter); - //printf("%u|", *((uint32_t*)buf)); - //cout << *((uint32_t*)buf) << endl; - } - - buf += 4; - break; - } - - case CalpontSystemCatalog::SMALLINT: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - fprintf(ci.filePtr, "%c", ci.delimiter); - else - fprintf(ci.filePtr, "%d%c", *((int16_t*)buf), ci.delimiter); - - buf += 2; - break; - } - - case CalpontSystemCatalog::USMALLINT: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - fprintf(ci.filePtr, "%c", ci.delimiter); - else - fprintf(ci.filePtr, "%u%c", *((uint16_t*)buf), ci.delimiter); - - buf += 2; - break; - } - - case CalpontSystemCatalog::TINYINT: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - fprintf(ci.filePtr, "%c", ci.delimiter); - else - fprintf(ci.filePtr, "%d%c", *((int8_t*)buf), ci.delimiter); - - buf += 1; - break; - } - - case CalpontSystemCatalog::UTINYINT: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - fprintf(ci.filePtr, "%c", ci.delimiter); - else - fprintf(ci.filePtr, "%u%c", *((uint8_t*)buf), ci.delimiter); - - buf += 1; - break; - } - - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::UFLOAT: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - fprintf(ci.filePtr, "%c", ci.delimiter); - else - { - float val = *((float*)buf); - - if ((fabs(val) > (1.0 / IDB_pow[4])) && (fabs(val) < (float) IDB_pow[6])) - { - fprintf(ci.filePtr, "%.7f%c", val, ci.delimiter); - } - else - { - fprintf(ci.filePtr, "%e%c", val, ci.delimiter); - } - - - //fprintf(ci.filePtr, "%.7g|", *((float*)buf)); - //printf("%.7f|", *((float*)buf)); - } - - buf += 4; - break; - } - - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UDOUBLE: - { - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - fprintf(ci.filePtr, "%c", ci.delimiter); - else - { - fprintf(ci.filePtr, "%.15g%c", *((double*)buf), ci.delimiter); - //printf("%.15g|", *((double*)buf)); - } - - buf += 8; - 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: - { - uint bytesBefore = 1; - uint totalBytes = 9; - - switch (ci.columnTypes[colpos].precision) - { - case 18: - case 17: - case 16: - { - totalBytes = 8; - break; - } - - case 15: - case 14: - { - totalBytes = 7; - break; - } - - case 13: - case 12: - { - totalBytes = 6; - break; - } - - case 11: - { - totalBytes = 5; - break; - } - - case 10: - { - totalBytes = 5; - break; - } - - case 9: - case 8: - case 7: - { - totalBytes = 4; - break; - } - - case 6: - case 5: - { - totalBytes = 3; - break; - } - - case 4: - case 3: - { - totalBytes = 2; - break; - } - - case 2: - case 1: - { - totalBytes = 1; - break; - } - - default: - break; - } - - switch (ci.columnTypes[colpos].scale) - { - case 0: - { - bytesBefore = totalBytes; - break; - } - - case 1: //1 byte for digits after decimal point - { - if ((ci.columnTypes[colpos].precision != 16) && (ci.columnTypes[colpos].precision != 14) - && (ci.columnTypes[colpos].precision != 12) && (ci.columnTypes[colpos].precision != 10) - && (ci.columnTypes[colpos].precision != 7) && (ci.columnTypes[colpos].precision != 5) - && (ci.columnTypes[colpos].precision != 3) && (ci.columnTypes[colpos].precision != 1)) - totalBytes++; - - bytesBefore = totalBytes - 1; - break; - } - - case 2: //1 byte for digits after decimal point - { - if ((ci.columnTypes[colpos].precision == 18) || (ci.columnTypes[colpos].precision == 9)) - totalBytes++; - - bytesBefore = totalBytes - 1; - break; - } - - case 3: //2 bytes for digits after decimal point - { - if ((ci.columnTypes[colpos].precision != 16) && (ci.columnTypes[colpos].precision != 14) - && (ci.columnTypes[colpos].precision != 12) && (ci.columnTypes[colpos].precision != 7) - && (ci.columnTypes[colpos].precision != 5) && (ci.columnTypes[colpos].precision != 3)) - totalBytes++; - - bytesBefore = totalBytes - 2; - break; - } - - case 4: - { - if ((ci.columnTypes[colpos].precision == 18) || (ci.columnTypes[colpos].precision == 11) - || (ci.columnTypes[colpos].precision == 9)) - totalBytes++; - - bytesBefore = totalBytes - 2; - break; - - } - - case 5: - { - if ((ci.columnTypes[colpos].precision != 16) && (ci.columnTypes[colpos].precision != 14) - && (ci.columnTypes[colpos].precision != 7) && (ci.columnTypes[colpos].precision != 5)) - totalBytes++; - - bytesBefore = totalBytes - 3; - break; - } - - case 6: - { - if ((ci.columnTypes[colpos].precision == 18) || (ci.columnTypes[colpos].precision == 13) - || (ci.columnTypes[colpos].precision == 11) || (ci.columnTypes[colpos].precision == 9)) - totalBytes++; - - bytesBefore = totalBytes - 3; - break; - } - - case 7: - { - if ((ci.columnTypes[colpos].precision != 16) && (ci.columnTypes[colpos].precision != 7)) - totalBytes++; - - bytesBefore = totalBytes - 4; - break; - } - - case 8: - { - if ((ci.columnTypes[colpos].precision == 18) || (ci.columnTypes[colpos].precision == 15) - || (ci.columnTypes[colpos].precision == 13) || (ci.columnTypes[colpos].precision == 11) - || (ci.columnTypes[colpos].precision == 9)) - totalBytes++; - - bytesBefore = totalBytes - 4;; - break; - } - - case 9: - { - bytesBefore = totalBytes - 4;; - break; - } - - case 10: - { - if ((ci.columnTypes[colpos].precision != 16) && (ci.columnTypes[colpos].precision != 14) - && (ci.columnTypes[colpos].precision != 12) && (ci.columnTypes[colpos].precision != 10)) - totalBytes++; - - bytesBefore = totalBytes - 5;; - break; - } - - case 11: - { - if (ci.columnTypes[colpos].precision == 18) - totalBytes++; - - bytesBefore = totalBytes - 5; - break; - } - - case 12: - { - if ((ci.columnTypes[colpos].precision != 16) && (ci.columnTypes[colpos].precision != 14) - && (ci.columnTypes[colpos].precision != 12)) - totalBytes++; - - bytesBefore = totalBytes - 6; - break; - } - - case 13: - { - if (ci.columnTypes[colpos].precision == 18) - totalBytes++; - - bytesBefore = totalBytes - 6; - break; - } - - case 14: - { - if ((ci.columnTypes[colpos].precision != 16) && (ci.columnTypes[colpos].precision != 14)) - totalBytes++; - - bytesBefore = totalBytes - 7; - break; - } - - case 15: - { - if (ci.columnTypes[colpos].precision == 18) - totalBytes++; - - bytesBefore = totalBytes - 7; - break; - } - - case 16: - { - if (ci.columnTypes[colpos].precision != 16) - totalBytes++; - - bytesBefore = totalBytes - 8; - break; - } - - case 17: - { - if (ci.columnTypes[colpos].precision == 18) - totalBytes++; - - bytesBefore = totalBytes - 8; - break; - } - - case 18: - { - bytesBefore = totalBytes - 8; - break; - } - - default: - break; - } - - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - { - fprintf(ci.filePtr, "%c", ci.delimiter); - //printf("|"); - } - else - { - uint32_t mask [5] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF}; - char neg = '-'; - - if (ci.columnTypes[colpos].scale == 0) - { - const uchar* tmpBuf = buf; - //test flag bit for sign - bool posNum = tmpBuf[0] & (0x80); - uchar tmpChr = tmpBuf[0]; - tmpChr ^= 0x80; //flip the bit - int32_t tmp1 = tmpChr; - - if (totalBytes > 4) - { - for (uint i = 1; i < (totalBytes - 4); i++) - { - tmp1 = (tmp1 << 8) + tmpBuf[i]; - } - - if (( tmp1 != 0 ) && (tmp1 != -1)) - { - if (!posNum) - { - tmp1 = mask[totalBytes - 4] - tmp1; - - if (tmp1 != 0) - { - fprintf(ci.filePtr, "%c", neg); - //printf("%c", neg); - } - } - - if (tmp1 != 0) - { - fprintf(ci.filePtr, "%d", tmp1); - ////printf("%d", tmp1); - } - } - - int32_t tmp2 = tmpBuf[totalBytes - 4]; - - for (uint i = (totalBytes - 3); i < totalBytes; i++) - { - tmp2 = (tmp2 << 8) + tmpBuf[i]; - } - - if ( tmp1 != 0 ) - { - if (!posNum) - { - tmp2 = mask[4] - tmp2; - - if (tmp1 == -1) - { - fprintf(ci.filePtr, "%c", neg); - fprintf(ci.filePtr, "%d%c", tmp2, ci.delimiter); - ////printf("%c", neg); - //////printf( "%d|", tmp2); - } - else - { - fprintf(ci.filePtr, "%09u%c", tmp2, ci.delimiter); - ////printf("%09u|", tmp2); - } - } - else - { - fprintf(ci.filePtr, "%09u%c", tmp2, ci.delimiter); - //printf("%09u|", tmp2); - } - } - else - { - if (!posNum) - { - tmp2 = mask[4] - tmp2; - fprintf(ci.filePtr, "%c", neg); - //printf("%c", neg); - } - - fprintf(ci.filePtr, "%d%c", tmp2, ci.delimiter); - //printf("%d|", tmp2); - } - } - else - { - for (uint i = 1; i < totalBytes; i++) - { - tmp1 = (tmp1 << 8) + tmpBuf[i]; - } - - if (!posNum) - { - tmp1 = mask[totalBytes] - tmp1; - fprintf(ci.filePtr, "%c", neg); - //printf("%c", neg); - } - - fprintf(ci.filePtr, "%d%c", tmp1, ci.delimiter); - //printf("%d|", tmp1); - } - } - else - { - const uchar* tmpBuf = buf; - //test flag bit for sign - bool posNum = tmpBuf[0] & (0x80); - uchar tmpChr = tmpBuf[0]; - tmpChr ^= 0x80; //flip the bit - int32_t tmp1 = tmpChr; - - //fetch the digits before decimal point - if (bytesBefore == 0) - { - if (!posNum) - { - fprintf(ci.filePtr, "%c", neg); - //printf("%c", neg); - } - - fprintf(ci.filePtr, "0."); - //printf("0."); - } - else if (bytesBefore > 4) - { - for (uint i = 1; i < (bytesBefore - 4); i++) - { - tmp1 = (tmp1 << 8) + tmpBuf[i]; - } - - if (!posNum) - { - tmp1 = mask[bytesBefore - 4] - tmp1; - } - - if (( tmp1 != 0 ) && (tmp1 != -1)) - { - if (!posNum) - { - fprintf(ci.filePtr, "%c", neg); - //printf("%c", neg); - } - - fprintf(ci.filePtr, "%d", tmp1); - //printf("%d", tmp1); - } - - tmpBuf += (bytesBefore - 4); - int32_t tmp2 = *((int32_t*)tmpBuf); - tmp2 = ntohl(tmp2); - - if ( tmp1 != 0 ) - { - if (!posNum) - { - tmp2 = mask[4] - tmp2; - } - - if (tmp1 == -1) - { - fprintf(ci.filePtr, "%c", neg); - fprintf(ci.filePtr, "%d.", tmp2); - //printf("%c", neg); - //printf("%d.", tmp2); - } - else - { - fprintf(ci.filePtr, "%09u.", tmp2); - //printf("%09u.", tmp2); - } - } - else - { - if (!posNum) - { - tmp2 = mask[4] - tmp2; - fprintf(ci.filePtr, "%c", neg); - //printf("%c", neg); - } - - fprintf(ci.filePtr, "%d.", tmp2); - //printf("%d.", tmp2); - } - } - else - { - for (uint i = 1; i < bytesBefore; i++) - { - tmp1 = (tmp1 << 8) + tmpBuf[i]; - } - - if (!posNum) - { - tmp1 = mask[bytesBefore] - tmp1; - fprintf(ci.filePtr, "%c", neg); - //printf("%c", neg); - } - - fprintf(ci.filePtr, "%d.", tmp1); - //printf("%d.", tmp1); - } - - //fetch the digits after decimal point - int32_t tmp2 = 0; - - if (bytesBefore > 4) - tmpBuf += 4; - else - tmpBuf += bytesBefore; - - tmp2 = tmpBuf[0]; - - if ((totalBytes - bytesBefore) < 5) - { - for (uint j = 1; j < (totalBytes - bytesBefore); j++) - { - tmp2 = (tmp2 << 8) + tmpBuf[j]; - } - - int8_t digits = ci.columnTypes[colpos].scale - 9; //9 digits is a 4 bytes chunk - - if ( digits <= 0 ) - digits = ci.columnTypes[colpos].scale; - - if (!posNum) - { - tmp2 = mask[totalBytes - bytesBefore] - tmp2; - } - - fprintf(ci.filePtr, "%0*u%c", digits, tmp2, ci.delimiter); - //printf("%0*u|", digits, tmp2); - } - else - { - for (uint j = 1; j < 4; j++) - { - tmp2 = (tmp2 << 8) + tmpBuf[j]; - } - - if (!posNum) - { - tmp2 = mask[4] - tmp2; - } - - fprintf(ci.filePtr, "%09u", tmp2); - //printf("%09u", tmp2); - - tmpBuf += 4; - int32_t tmp3 = tmpBuf[0]; - - for (uint j = 1; j < (totalBytes - bytesBefore - 4); j++) - { - tmp3 = (tmp3 << 8) + tmpBuf[j]; - } - - int8_t digits = ci.columnTypes[colpos].scale - 9; //9 digits is a 4 bytes chunk - - if ( digits < 0 ) - digits = ci.columnTypes[colpos].scale; - - if (!posNum) - { - tmp3 = mask[totalBytes - bytesBefore - 4] - tmp3; - } - - fprintf(ci.filePtr, "%0*u%c", digits, tmp3, ci.delimiter); - //printf("%0*u|", digits, tmp3); - } - } - } - - buf += totalBytes; - break; - } - - case CalpontSystemCatalog::VARBINARY: - { - // For a VARBINARY field, ci.columnTypes[colpos].colWidth == colWidthInBytes - if (nullVal && (ci.columnTypes[colpos].constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT)) - { - fprintf(ci.filePtr, "%c", ci.delimiter); - - if (ci.columnTypes[colpos].colWidth < 256) - { - buf++; - } - else - { - buf = buf + 2; - } - } - else - { - // Maximum number of bytes allowed for a VARBINARY - // field is 65532, so the max length fits in 2 bytes. - // dataLength is length in bytes, not length in chars - uint16_t dataLength = 0; - - if (ci.columnTypes[colpos].colWidth < 256) - { - dataLength = *(uint8_t*) buf; - buf++; - } - else - { - dataLength = *(uint16_t*) buf; - buf = buf + 2 ; - } - - const uchar* tmpBuf = buf; - - for (int32_t i = 0; i < dataLength; i++) - { - fprintf(ci.filePtr, "%02x", *(uint8_t*)tmpBuf); - tmpBuf++; - } - - fprintf(ci.filePtr, "%c", ci.delimiter); - } - - buf += ci.columnTypes[colpos].colWidth; - - break; - } - - case CalpontSystemCatalog::BLOB: - case CalpontSystemCatalog::TEXT: - { - // MCOL-4005 Note that we don't handle nulls as a special - // case here as we do for other datatypes, the below works - // as expected for nulls. - // dataLength is length in bytes, not length in chars - uint32_t dataLength = 0; - uintptr_t* dataptr; - uchar* ucharptr; - - bool isBlob = - ci.columnTypes[colpos].colDataType == CalpontSystemCatalog::BLOB; - - Field* field = table->field[colpos]; - - uint32_t colWidthInBytes = isBlob ? ci.columnTypes[colpos].colWidth : - ci.columnTypes[colpos].colWidth * field->charset()->mbmaxlen; - - if (!isBlob && field->char_length() == 65535) - { - // Special case for TEXT field without default length, - // such as: - // CREATE TABLE mcol4364 (a TEXT); - // Here, char_length() represents the number of bytes, - // not number of characters. - dataLength = *(uint16_t*) buf; - buf += 2; - } - else if (colWidthInBytes < 256) - { - dataLength = *(uint8_t*) buf; - buf++; - } - else if (colWidthInBytes < 65536) - { - dataLength = *(uint16_t*) buf; - buf += 2; - } - else if (colWidthInBytes < 16777216) - { - dataLength = *(uint16_t*) buf; - dataLength |= ((int) buf[2]) << 16; - buf += 3; - } - else - { - dataLength = *(uint32_t*) buf; - buf += 4; - } - - // buf contains pointer to blob, for example: - // (gdb) p (char*)*(uintptr_t*)buf - // $43 = 0x7f68500c58f8 "hello world" - - dataptr = (uintptr_t*)buf; - ucharptr = (uchar*)*dataptr; - buf += sizeof(uintptr_t); - - if (isBlob) - { - for (uint32_t i = 0; i < dataLength; i++) - { - fprintf(ci.filePtr, "%02x", *(uint8_t*)ucharptr); - ucharptr++; - } - - fprintf(ci.filePtr, "%c", ci.delimiter); - } - else - { - // TEXT Column - escape.assign((char*)ucharptr, dataLength); - boost::replace_all(escape, "\\", "\\\\"); - fprintf(ci.filePtr, "%c%.*s%c%c", ci.enclosed_by, (int)escape.length(), escape.c_str(), ci.enclosed_by, ci.delimiter); - } - - break; - - } - - default: // treat as int64 - { - break; - } + datatypes::ColBatchWriter writer(ci.filePtr, ci.delimiter, + ci.enclosed_by, ci.utf8); + datatypes::WriteBatchFieldMariaDB field(table->field[colpos], colType); + idbassert(table == table->field[colpos]->table); + buf+= h->ColWriteBatch(&field, buf, nullVal, writer); } - colpos++; } } diff --git a/dbcon/mysql/ha_mcs_execplan.cpp b/dbcon/mysql/ha_mcs_execplan.cpp index 666bb467a..a5daf7048 100755 --- a/dbcon/mysql/ha_mcs_execplan.cpp +++ b/dbcon/mysql/ha_mcs_execplan.cpp @@ -3111,7 +3111,7 @@ CalpontSystemCatalog::ColType colType_MysqlToIDB (const Item* item) unsigned int precision = idp->decimal_precision(); unsigned int scale = idp->decimal_scale(); - datatypes::Decimal::setDecimalScalePrecision(ct, precision, scale); + ct.setDecimalScalePrecision(precision, scale); break; } @@ -3608,7 +3608,7 @@ ArithmeticColumn* buildArithmeticColumn( const CalpontSystemCatalog::ColType& rightColType = pt->right()->data()->resultType(); // Only tinker with the type if all columns involved are decimal - if (datatypes::Decimal::isDecimalOperands(mysqlType.colDataType, + if (datatypes::isDecimalOperands(mysqlType.colDataType, leftColType.colDataType, rightColType.colDataType)) { int32_t leftColWidth = leftColType.colWidth; @@ -3632,7 +3632,7 @@ ArithmeticColumn* buildArithmeticColumn( unsigned int precision = idp->decimal_precision(); unsigned int scale = idp->decimal_scale(); - datatypes::Decimal::setDecimalScalePrecisionHeuristic(mysqlType, precision, scale); + mysqlType.setDecimalScalePrecisionHeuristic(precision, scale); if (mysqlType.scale < scale1) mysqlType.scale = scale1; @@ -4087,7 +4087,7 @@ ReturnedColumn* buildFunctionColumn( { for (size_t i = 0; i < funcParms.size(); i++) { - if (datatypes::Decimal::isWideDecimalType(funcParms[i]->data()->resultType())) + if (funcParms[i]->data()->resultType().isWideDecimalType()) { fc->resultType().colWidth = datatypes::MAXDECIMALWIDTH; break; @@ -4475,18 +4475,18 @@ SimpleColumn* buildSimpleColumn(Item_field* ifp, gp_walk_info& gwi) return buildSimpleColFromDerivedTable(gwi, ifp); CalpontSystemCatalog::ColType ct; - bool columnStore = true; + datatypes::SimpleColumnParam prm(gwi.sessionid, true); try { // check foreign engine if (ifp->cached_table && ifp->cached_table->table) - columnStore = isMCSTable(ifp->cached_table->table); + prm.columnStore(isMCSTable(ifp->cached_table->table)); // @bug4509. ifp->cached_table could be null for myisam sometimes else if (ifp->field && ifp->field->table) - columnStore = isMCSTable(ifp->field->table); + prm.columnStore(isMCSTable(ifp->field->table)); - if (columnStore) + if (prm.columnStore()) { ct = gwi.csc->colType( gwi.csc->lookupOID(make_tcn(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str))); @@ -4503,75 +4503,12 @@ SimpleColumn* buildSimpleColumn(Item_field* ifp, gp_walk_info& gwi) return NULL; } - SimpleColumn* sc = NULL; + const datatypes::DatabaseQualifiedColumnName name(ifp->db_name.str, + bestTableName(ifp), + ifp->field_name.str); + const datatypes::TypeHandler *h= ct.typeHandler(); + SimpleColumn *sc = h->newSimpleColumn(name, ct, prm); - switch (ct.colDataType) - { - case CalpontSystemCatalog::TINYINT: - if (ct.scale == 0) - sc = new SimpleColumn_INT<1>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - else - { - sc = new SimpleColumn_Decimal<1>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - ct.colDataType = CalpontSystemCatalog::DECIMAL; - } - - break; - - case CalpontSystemCatalog::SMALLINT: - if (ct.scale == 0) - sc = new SimpleColumn_INT<2>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - else - { - sc = new SimpleColumn_Decimal<2>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - ct.colDataType = CalpontSystemCatalog::DECIMAL; - } - - break; - - case CalpontSystemCatalog::INT: - case CalpontSystemCatalog::MEDINT: - if (ct.scale == 0) - sc = new SimpleColumn_INT<4>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - else - { - sc = new SimpleColumn_Decimal<4>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - ct.colDataType = CalpontSystemCatalog::DECIMAL; - } - - break; - - case CalpontSystemCatalog::BIGINT: - if (ct.scale == 0) - sc = new SimpleColumn_INT<8>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - else - { - sc = new SimpleColumn_Decimal<8>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - ct.colDataType = CalpontSystemCatalog::DECIMAL; - } - - break; - - case CalpontSystemCatalog::UTINYINT: - sc = new SimpleColumn_UINT<1>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - break; - - case CalpontSystemCatalog::USMALLINT: - sc = new SimpleColumn_UINT<2>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - break; - - case CalpontSystemCatalog::UINT: - case CalpontSystemCatalog::UMEDINT: - sc = new SimpleColumn_UINT<4>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - break; - - case CalpontSystemCatalog::UBIGINT: - sc = new SimpleColumn_UINT<8>(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - break; - - default: - sc = new SimpleColumn(ifp->db_name.str, bestTableName(ifp), ifp->field_name.str, columnStore, gwi.sessionid); - } sc->resultType(ct); sc->charsetNumber(ifp->collation.collation->number); string tbname(ifp->table_name.str); @@ -4588,10 +4525,10 @@ SimpleColumn* buildSimpleColumn(Item_field* ifp, gp_walk_info& gwi) sc->viewName(getViewName(ifp->cached_table), lower_case_table_names); sc->alias(ifp->name.str); - sc->isColumnStore(columnStore); + sc->isColumnStore(prm.columnStore()); sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); - if (!columnStore && ifp->field) + if (!prm.columnStore() && ifp->field) sc->oid(ifp->field->field_index + 1); // ExeMgr requires offset started from 1 if (ifp->depended_from) @@ -4983,7 +4920,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) isp->sum_func() == Item_sum::SUM_DISTINCT_FUNC) { CalpontSystemCatalog::ColType ct = parm->resultType(); - if (datatypes::Decimal::isWideDecimalType(ct)) + if (ct.isWideDecimalType()) { uint32_t precision = ct.precision; uint32_t scale = ct.scale; @@ -5051,7 +4988,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) else if (bIsConst && hasDecimalConst && isAvg) { CalpontSystemCatalog::ColType ct = parm->resultType(); - if (datatypes::Decimal::isWideDecimalType(constValPrecision)) + if (datatypes::Decimal::isWideDecimalTypeByPrecision(constValPrecision)) { ct.precision = constValPrecision; ct.scale = constValScale; @@ -5065,8 +5002,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) } // adjust decimal result type according to internalDecimalScale - bool isWideDecimal = - datatypes::Decimal::isWideDecimalType(ac->resultType()); + bool isWideDecimal = ac->resultType().isWideDecimalType(); // This must be also valid for UDECIMAL if (!isWideDecimal && gwi.internalDecimalScale >= 0 && ac->resultType().colDataType == CalpontSystemCatalog::DECIMAL) @@ -7413,7 +7349,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, gwi.returnedCols[i]->hasAggregate(true); } - gwi.returnedCols[i]->resultType(dataconvert::DataConvert::convertUnionColType(coltypes)); + gwi.returnedCols[i]->resultType(CalpontSystemCatalog::ColType::convertUnionColType(coltypes)); } } @@ -9163,7 +9099,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro gwi.returnedCols[i]->hasAggregate(true); } - gwi.returnedCols[i]->resultType(dataconvert::DataConvert::convertUnionColType(coltypes)); + gwi.returnedCols[i]->resultType(CalpontSystemCatalog::ColType::convertUnionColType(coltypes)); } } diff --git a/dbcon/mysql/ha_mcs_impl.cpp b/dbcon/mysql/ha_mcs_impl.cpp index 2724d2ba1..e94f19595 100644 --- a/dbcon/mysql/ha_mcs_impl.cpp +++ b/dbcon/mysql/ha_mcs_impl.cpp @@ -138,6 +138,8 @@ using namespace funcexp; #include "columnstoreversion.h" #include "ha_mcs_sysvars.h" +#include "ha_mcs_datatype.h" + namespace cal_impl_if { extern bool nonConstFunc(Item_func* ifp); @@ -249,108 +251,6 @@ void force_close_fep_conn(THD *thd, cal_connection_info* ci, bool check_prev_rc ci->cal_conn_hndl = 0; } -void storeNumericField(Field** f, int64_t value, CalpontSystemCatalog::ColType& ct) -{ - // unset null bit first - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - // For unsigned, use the ColType returned in the row rather than the - // unsigned_flag set by mysql. This is because mysql gets it wrong for SUM() - // Hopefully, in all other cases we get it right. - switch ((*f)->type()) - { - case MYSQL_TYPE_NEWDECIMAL: - { - // @bug4388 stick to InfiniDB's scale in case mysql gives wrong scale due - // to create vtable limitation. - //if (f2->dec < ct.scale) - // f2->dec = ct.scale; - - // WIP MCOL-641 - // This is too much - char buf[256]; - dataconvert::DataConvert::decimalToString(value, (unsigned)ct.scale, buf, 256, ct.colDataType); - (*f)->store(buf, strlen(buf), (*f)->charset()); - break; - } - - case MYSQL_TYPE_TINY: //TINYINT type - { - Field_tiny* f2 = (Field_tiny*)*f; - longlong int_val = (longlong)value; - (*f)->store(int_val, f2->unsigned_flag); - break; - } - - case MYSQL_TYPE_SHORT: //SMALLINT type - { - Field_short* f2 = (Field_short*)*f; - longlong int_val = (longlong)value; - (*f)->store(int_val, f2->unsigned_flag); - break; - } - - case MYSQL_TYPE_INT24: //MEDINT type - { - Field_medium* f2 = (Field_medium*)*f; - longlong int_val = (longlong)value; - (*f)->store(int_val, f2->unsigned_flag); - break; - } - - case MYSQL_TYPE_LONG: //INT type - { - Field_long* f2 = (Field_long*)*f; - longlong int_val = (longlong)value; - (*f)->store(int_val, f2->unsigned_flag); - break; - } - - case MYSQL_TYPE_LONGLONG: //BIGINT type - { - Field_longlong* f2 = (Field_longlong*)*f; - longlong int_val = (longlong)value; - (*f)->store(int_val, f2->unsigned_flag); - break; - } - - case MYSQL_TYPE_FLOAT: // FLOAT type - { - float float_val = *(float*)(&value); - (*f)->store(float_val); - break; - } - - case MYSQL_TYPE_DOUBLE: // DOUBLE type - { - double double_val = *(double*)(&value); - (*f)->store(double_val); - break; - } - - case MYSQL_TYPE_VARCHAR: - { - char tmp[25]; - if (ct.colDataType == CalpontSystemCatalog::DECIMAL) - dataconvert::DataConvert::decimalToString(value, (unsigned)ct.scale, tmp, 25, ct.colDataType); - else - snprintf(tmp, 25, "%lld", (long long)value); - - (*f)->store(tmp, strlen(tmp), (*f)->charset()); - break; - } - - default: - { - Field_longlong* f2 = (Field_longlong*)*f; - longlong int_val = (longlong)value; - (*f)->store(int_val, f2->unsigned_flag); - break; - } - } -} - // // @bug 2244. Log exception related to lost connection to ExeMgr. // Log exception error from calls to sm::tpl_scan_fetch in fetchNextRow() @@ -391,19 +291,6 @@ void tpl_scan_fetch_LogException( cal_table_info& ti, cal_connection_info* ci, s sesID << "; " << connHndl << "; rowsReturned: " << rowsRet << endl; } -const char hexdig[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', }; - -int vbin2hex(const uint8_t* p, const unsigned l, char* o) -{ - for (unsigned i = 0; i < l; i++, p++) - { - *o++ = hexdig[*p >> 4]; - *o++ = hexdig[*p & 0xf]; - } - - return 0; -} - // Table Map is used by both cond_push and table mode processing // Entries made by cond_push don't have csep though. // When @@ -421,6 +308,7 @@ bool onlyOneTableinTM(cal_impl_if::cal_connection_info* ci) return true; } + int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool handler_flag = false) { int rc = HA_ERR_END_OF_FILE; @@ -473,9 +361,6 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h } std::vector& colTypes = ti.tpl_scan_ctx->ctp; - int64_t intColVal = 0; - uint64_t uintColVal = 0; - char tmp[256]; RowGroup* rowGroup = ti.tpl_scan_ctx->rowGroup; @@ -548,319 +433,25 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h colType.colDataType == CalpontSystemCatalog::VARCHAR || colType.colDataType == CalpontSystemCatalog::VARBINARY) { - (*f)->store(tmp, 0, (*f)->charset()); + (*f)->store("", 0, (*f)->charset()); } continue; } - // fetch and store data - switch (colType.colDataType) + const datatypes::TypeHandler *h= colType.typeHandler(); + if (!h) { - case CalpontSystemCatalog::DATE: - { - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - intColVal = row.getUintField<4>(s); - DataConvert::dateToString(intColVal, tmp, 255); - (*f)->store(tmp, strlen(tmp), (*f)->charset()); - break; - } - - case CalpontSystemCatalog::DATETIME: - { - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - intColVal = row.getUintField<8>(s); - DataConvert::datetimeToString(intColVal, tmp, 255, colType.precision); - (*f)->store(tmp, strlen(tmp), (*f)->charset()); - break; - } - - case CalpontSystemCatalog::TIME: - { - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - intColVal = row.getUintField<8>(s); - DataConvert::timeToString(intColVal, tmp, 255, colType.precision); - (*f)->store(tmp, strlen(tmp), (*f)->charset()); - break; - } - - case CalpontSystemCatalog::TIMESTAMP: - { - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - intColVal = row.getUintField<8>(s); - DataConvert::timestampToString(intColVal, tmp, 255, current_thd->variables.time_zone->get_name()->ptr(), colType.precision); - (*f)->store(tmp, strlen(tmp), (*f)->charset()); - break; - } - - case CalpontSystemCatalog::CHAR: - case CalpontSystemCatalog::VARCHAR: - { - switch (colType.colWidth) - { - case 1: - intColVal = row.getUintField<1>(s); - (*f)->store((char*)(&intColVal), strlen((char*)(&intColVal)), (*f)->charset()); - break; - - case 2: - intColVal = row.getUintField<2>(s); - (*f)->store((char*)(&intColVal), strlen((char*)(&intColVal)), (*f)->charset()); - break; - - case 4: - intColVal = row.getUintField<4>(s); - (*f)->store((char*)(&intColVal), strlen((char*)(&intColVal)), (*f)->charset()); - break; - - case 8: - //make sure we don't send strlen off into the weeds... - intColVal = row.getUintField<8>(s); - memcpy(tmp, &intColVal, 8); - tmp[8] = 0; - (*f)->store(tmp, strlen(tmp), (*f)->charset()); - break; - - default: - (*f)->store((const char*)row.getStringPointer(s), row.getStringLength(s), (*f)->charset()); - } - - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - break; - } - - case CalpontSystemCatalog::VARBINARY: - { - if (get_varbin_always_hex(current_thd)) - { - uint32_t l; - const uint8_t* p = row.getVarBinaryField(l, s); - uint32_t ll = l * 2; - boost::scoped_array sca(new char[ll]); - vbin2hex(p, l, sca.get()); - (*f)->store(sca.get(), ll, (*f)->charset()); - } - else - (*f)->store((const char*)row.getVarBinaryField(s), row.getVarBinaryLength(s), (*f)->charset()); - - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - break; - } - - case CalpontSystemCatalog::BIGINT: - { - intColVal = row.getIntField<8>(s); - storeNumericField(f, intColVal, colType); - break; - } - - case CalpontSystemCatalog::UBIGINT: - { - uintColVal = row.getUintField<8>(s); - storeNumericField(f, uintColVal, colType); - break; - } - - case CalpontSystemCatalog::INT: - case CalpontSystemCatalog::MEDINT: - { - intColVal = row.getIntField<4>(s); - storeNumericField(f, intColVal, colType); - break; - } - - case CalpontSystemCatalog::UINT: - case CalpontSystemCatalog::UMEDINT: - { - uintColVal = row.getUintField<4>(s); - storeNumericField(f, uintColVal, colType); - break; - } - - case CalpontSystemCatalog::SMALLINT: - { - intColVal = row.getIntField<2>(s); - storeNumericField(f, intColVal, colType); - break; - } - - case CalpontSystemCatalog::USMALLINT: - { - uintColVal = row.getUintField<2>(s); - storeNumericField(f, uintColVal, colType); - break; - } - - case CalpontSystemCatalog::TINYINT: - { - intColVal = row.getIntField<1>(s); - storeNumericField(f, intColVal, colType); - break; - } - - case CalpontSystemCatalog::UTINYINT: - { - uintColVal = row.getUintField<1>(s); - storeNumericField(f, uintColVal, colType); - break; - } - - //In this case, we're trying to load a double output column with float data. This is the - // case when you do sum(floatcol), e.g. - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::UFLOAT: - { - float dl = row.getFloatField(s); - - if (dl == std::numeric_limits::infinity()) - continue; - - // bug 3485, reserve enough space for the longest float value - // -3.402823466E+38 to -1.175494351E-38, 0, and - // 1.175494351E-38 to 3.402823466E+38. - (*f)->field_length = 40; - (*f)->store(dl); - - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - break; - } - - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UDOUBLE: - { - double dl = row.getDoubleField(s); - - if (dl == std::numeric_limits::infinity()) - continue; - - if ((*f)->type() == MYSQL_TYPE_NEWDECIMAL) - { - char buf[310]; - // reserve enough space for the longest double value - // -1.7976931348623157E+308 to -2.2250738585072014E-308, 0, and - // 2.2250738585072014E-308 to 1.7976931348623157E+308. - snprintf(buf, 310, "%.18g", dl); - (*f)->store(buf, strlen(buf), (*f)->charset()); - } - else - { - // The server converts dl=-0 to dl=0 in (*f)->store(). - // This happens in the call to truncate_double(). - // This is an unexpected behaviour, so we directly store the - // double value using the lower level float8store() function. - // TODO Remove this when (*f)->store() handles this properly. - (*f)->field_length = 310; - if (dl == 0) - float8store((*f)->ptr,dl); - else - (*f)->store(dl); - } - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - break; - } - - case CalpontSystemCatalog::LONGDOUBLE: - { - long double dl = row.getLongDoubleField(s); - if (dl == std::numeric_limits::infinity()) - { - continue; - } - - if ((*f)->type() == MYSQL_TYPE_NEWDECIMAL) - { - char buf[310]; - snprintf(buf, 310, "%.20Lg", dl); - (*f)->store(buf, strlen(buf), (*f)->charset()); - } - else - { - // 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; - (*f)->store(static_cast(dl)); - } - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - break; - } - - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::UDECIMAL: - { - if (LIKELY(colType.colWidth == datatypes::MAXDECIMALWIDTH)) - { - // unset null bit first - // Might be redundant - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - int128_t* dec; - // We won't have more than [+-][0][.] + up to 38 digits - char buf[utils::MAXLENGTH16BYTES]; - - dec = row.getBinaryField(s); - dataconvert::DataConvert::decimalToString(dec, - (unsigned)colType.scale, buf, - sizeof(buf), colType.colDataType); - - Field_new_decimal* f2 = (Field_new_decimal*)*f; - f2->store(buf, strlen(buf), f2->charset()); - } - else - { - intColVal = row.getIntField(s); - storeNumericField(f, intColVal, colType); - } - break; - } - - case CalpontSystemCatalog::BLOB: - case CalpontSystemCatalog::TEXT: - { - Field_blob* f2 = (Field_blob*)*f; - f2->set_ptr(row.getVarBinaryLength(s), (unsigned char*)row.getVarBinaryField(s)); - - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - break; - } - case CalpontSystemCatalog::BINARY: - { - Field_varstring* f2 = (Field_varstring*)*f; - // WIP MCOL-641 Binary representation could contain \0. - char* binaryString = row.getBinaryField(s); - f2->store(binaryString, colType.colWidth, f2->charset()); - - if ((*f)->null_ptr) - *(*f)->null_ptr &= ~(*f)->null_bit; - - break; - } - default: // treat as int64 - { - intColVal = row.getUintField<8>(s); - storeNumericField(f, intColVal, colType); - break; - } + idbassert(0); + (*f)->reset(); + (*f)->set_null(); + } + else + { + // fetch and store data + (*f)->set_notnull(); + datatypes::StoreFieldMariaDB mf(*f, colType); + h->storeValueToField(row, s, &mf); } } diff --git a/dbcon/mysql/ha_mcs_partition.cpp b/dbcon/mysql/ha_mcs_partition.cpp index 17ba58992..c057eecdf 100644 --- a/dbcon/mysql/ha_mcs_partition.cpp +++ b/dbcon/mysql/ha_mcs_partition.cpp @@ -65,12 +65,31 @@ using namespace logging; #include using namespace boost; -#include "mcs_decimal.h" namespace { -const uint8_t ROUND_POS = 0x01; -const uint8_t ROUND_NEG = 0x80; + +datatypes::SimpleValue getStartVal(const datatypes::SessionParam &sp, + const CalpontSystemCatalog::ColType &ct, + const char *val, + datatypes::round_style_t & rfMin) +{ + const datatypes::TypeHandler *h= ct.typeHandler(); + return val ? h->toSimpleValue(sp, ct, val, rfMin) : + h->getMinValueSimple(); +} + + +datatypes::SimpleValue getEndVal(const datatypes::SessionParam &sp, + const CalpontSystemCatalog::ColType &ct, + const char *val, + datatypes::round_style_t & rfMax) +{ + const datatypes::TypeHandler *h= ct.typeHandler(); + return val ? h->toSimpleValue(sp, ct, val, rfMax) : + h->getMaxValueSimple(); +} + //convenience fcn inline uint32_t tid2sid(const uint32_t tid) @@ -101,375 +120,27 @@ void push_warnings(THD* thd, string& warnings) } } + string name(CalpontSystemCatalog::ColType& ct) { - switch (ct.colDataType) - { - case CalpontSystemCatalog::INT: - return "INT"; - - case CalpontSystemCatalog::TINYINT: - return "TINYINT"; - - case CalpontSystemCatalog::MEDINT: - return "MEDINT"; - - case CalpontSystemCatalog::SMALLINT: - return "SMALLINT"; - - case CalpontSystemCatalog::BIGINT: - return "BIGINT"; - - case CalpontSystemCatalog::DATE: - return "DATE"; - - case CalpontSystemCatalog::DATETIME: - return "DATETIME"; - - case CalpontSystemCatalog::TIME: - return "TIME"; - - case CalpontSystemCatalog::TIMESTAMP: - return "TIMESTAMP"; - - case CalpontSystemCatalog::DECIMAL: - return "DECIMAL"; - - case CalpontSystemCatalog::CHAR: - { - ostringstream oss; - oss << "CHAR(" << ct.colWidth << ")"; - return oss.str(); - } - - case CalpontSystemCatalog::VARCHAR: - { - ostringstream oss; - oss << "VARCHAR(" << ct.colWidth << ")"; - return oss.str(); - } - - case CalpontSystemCatalog::FLOAT: - return "FLOAT"; - - case CalpontSystemCatalog::DOUBLE: - return "DOUBLE"; - - case CalpontSystemCatalog::BIT: - return "BIT"; - - case CalpontSystemCatalog::VARBINARY: - return "VARBINARY"; - - case CalpontSystemCatalog::BLOB: - return "BLOB"; - - case CalpontSystemCatalog::TEXT: - return "TEXT"; - - case CalpontSystemCatalog::CLOB: - return "CLOB"; - - case CalpontSystemCatalog::UINT: - return "UINT"; - - case CalpontSystemCatalog::UTINYINT: - return "UTINYINT"; - - case CalpontSystemCatalog::UMEDINT: - return "UMEDINT"; - - case CalpontSystemCatalog::USMALLINT: - return "USMALLINT"; - - case CalpontSystemCatalog::UBIGINT: - return "UBIGINT"; - - case CalpontSystemCatalog::UDECIMAL: - return "UDECIMAL"; - - case CalpontSystemCatalog::UFLOAT: - return "UFLOAT"; - - case CalpontSystemCatalog::UDOUBLE: - return "UDOUBLE"; - - case CalpontSystemCatalog::LONGDOUBLE: - return "LONGDOUBLE"; - - default: - return "Unknown Type"; - } + const datatypes::TypeHandler *h= ct.typeHandler(); + if (!h) + return "Unknown Type"; + return h->print(ct); } + bool CP_type(CalpontSystemCatalog::ColType& ct) { - if (ct.colDataType == CalpontSystemCatalog::INT || - ct.colDataType == CalpontSystemCatalog::TINYINT || - ct.colDataType == CalpontSystemCatalog::MEDINT || - ct.colDataType == CalpontSystemCatalog::SMALLINT || - ct.colDataType == CalpontSystemCatalog::BIGINT || - ct.colDataType == CalpontSystemCatalog::DATE || - ct.colDataType == CalpontSystemCatalog::DATETIME || - ct.colDataType == CalpontSystemCatalog::TIME || - ct.colDataType == CalpontSystemCatalog::TIMESTAMP || - ct.colDataType == CalpontSystemCatalog::DECIMAL || - ct.colDataType == CalpontSystemCatalog::UTINYINT || - ct.colDataType == CalpontSystemCatalog::USMALLINT || - ct.colDataType == CalpontSystemCatalog::UMEDINT || - ct.colDataType == CalpontSystemCatalog::UINT || - ct.colDataType == CalpontSystemCatalog::UBIGINT || - ct.colDataType == CalpontSystemCatalog::UDECIMAL || - (ct.colDataType == CalpontSystemCatalog::CHAR && ct.colWidth <= 8) || - (ct.colDataType == CalpontSystemCatalog::VARCHAR && ct.colWidth <= 7)) - { - return true; - } - - return false; + const datatypes::TypeHandler *h= ct.typeHandler(); + if (!h) + return false; + return h->CP_type(ct); } -const uint64_t ET_DISABLED = 0x0002; -const uint64_t CPINVALID = 0x0004; -struct PartitionInfo -{ - int64_t min; - int64_t max; - union - { - int128_t int128Min; - int64_t min_; - }; - union - { - int128_t int128Max; - int64_t max_; - }; - uint64_t status; - PartitionInfo(): min((uint64_t)0x8000000000000001ULL), - max((uint64_t) - 0x8000000000000001LL), - status(0) - { - int128Min = datatypes::Decimal::minInt128; - int128Max = datatypes::Decimal::maxInt128; - }; -}; +typedef map PartitionMap; -typedef map PartitionMap; - -template -const string format(T v, CalpontSystemCatalog::ColType& ct) -{ - ostringstream oss; - - switch (ct.colDataType) - { - case CalpontSystemCatalog::DATE: - oss << DataConvert::dateToString(v); - break; - - case CalpontSystemCatalog::DATETIME: - oss << DataConvert::datetimeToString(v); - break; - - case CalpontSystemCatalog::TIMESTAMP: - oss << DataConvert::timestampToString(v, current_thd->variables.time_zone->get_name()->ptr()); - break; - - case CalpontSystemCatalog::TIME: - oss << DataConvert::timeToString(v); - break; - - case CalpontSystemCatalog::CHAR: - case CalpontSystemCatalog::VARCHAR: - { - // swap again to retain the string byte order - uint64_t tmp = uint64ToStr(v); - oss << (char*)(&tmp); - break; - } - - case CalpontSystemCatalog::TINYINT: - case CalpontSystemCatalog::SMALLINT: - case CalpontSystemCatalog::MEDINT: - case CalpontSystemCatalog::INT: - case CalpontSystemCatalog::BIGINT: - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::UDECIMAL: - { - if (ct.colWidth <= 8) - { - if (ct.scale > 0) - { - double d = ((double)(v) / (double)pow((double)10, ct.scale)); - oss << setprecision(ct.scale) << fixed << d; - } - else - { - oss << (int64_t) v; - } - } - else - { - char buf[datatypes::MAXLENGTH16BYTES]; - DataConvert::decimalToString((int128_t*)&v, (unsigned)ct.scale, buf, sizeof(buf), ct.colDataType); - oss << buf; - } - - break; - } - - case CalpontSystemCatalog::UTINYINT: - case CalpontSystemCatalog::USMALLINT: - case CalpontSystemCatalog::UMEDINT: - case CalpontSystemCatalog::UINT: - case CalpontSystemCatalog::UBIGINT: - oss << static_cast(v); - break; - - case CalpontSystemCatalog::VARBINARY: - oss << "N/A"; - break; - - default: - oss << (int64_t) v; - break; - } - - return oss.str(); -} - -template -T IDB_format(char* str, CalpontSystemCatalog::ColType& ct, uint8_t& rf) -{ - T v = 0; - bool pushWarning = false; - rf = 0; - boost::any anyVal = DataConvert::convertColumnData(ct, str, pushWarning, current_thd->variables.time_zone->get_name()->ptr(), false, true, false); - - switch (ct.colDataType) - { - case CalpontSystemCatalog::BIT: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::TINYINT: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::UTINYINT: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::SMALLINT: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::USMALLINT: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::MEDINT: - case CalpontSystemCatalog::INT: -#ifdef _MSC_VER - v = boost::any_cast(anyVal); -#else - v = boost::any_cast(anyVal); -#endif - break; - - case CalpontSystemCatalog::UMEDINT: - case CalpontSystemCatalog::UINT: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::BIGINT: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::UBIGINT: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::CHAR: - case CalpontSystemCatalog::VARCHAR: - case CalpontSystemCatalog::VARBINARY: - case CalpontSystemCatalog::BLOB: - case CalpontSystemCatalog::TEXT: - case CalpontSystemCatalog::CLOB: - { - string i = boost::any_cast(anyVal); - // bug 1932, pad nulls up to the size of v - i.resize(sizeof(v), 0); - v = uint64ToStr(*((uint64_t*) i.data())); - - if (pushWarning) - rf = ROUND_POS; - } - break; - - case CalpontSystemCatalog::DATE: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::TIMESTAMP: - case CalpontSystemCatalog::DATETIME: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::TIME: - v = boost::any_cast(anyVal); - break; - - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::UDECIMAL: - if (ct.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE) - v = boost::any_cast(anyVal); - else if (ct.colWidth == execplan::CalpontSystemCatalog::TWO_BYTE) - v = boost::any_cast(anyVal); - else if (ct.colWidth == execplan::CalpontSystemCatalog::FOUR_BYTE) -#ifdef _MSC_VER - v = boost::any_cast(anyVal); - -#else - v = boost::any_cast(anyVal); -#endif - else if (ct.colWidth == execplan::CalpontSystemCatalog::EIGHT_BYTE) - v = boost::any_cast(anyVal); - else - v = boost::any_cast(anyVal); - - break; - - default: - break; - } - - if ((ct.colDataType == CalpontSystemCatalog::TINYINT || - ct.colDataType == CalpontSystemCatalog::SMALLINT || - ct.colDataType == CalpontSystemCatalog::MEDINT || - ct.colDataType == CalpontSystemCatalog::INT || - ct.colDataType == CalpontSystemCatalog::BIGINT || - ct.colDataType == CalpontSystemCatalog::DECIMAL || - ct.colDataType == CalpontSystemCatalog::UDECIMAL) && - pushWarning) - { - // get rid of leading white spaces and parentheses - string data(str); - size_t fpos = data.find_first_of(" \t()"); - - while (string::npos != fpos) - { - data.erase(fpos, 1); - fpos = data.find_first_of(" \t()"); - } - - rf = (data[0] == '-') ? ROUND_NEG : ROUND_POS; - } - - return v; -} void parsePartitionString(UDF_ARGS* args, @@ -644,6 +315,35 @@ int processPartition ( SqlStatement* stmt) return rc; } + +static void addPartition(const CalpontSystemCatalog::ColType& ct, + DBRM &em, + const BRM::EMEntry &entry, + PartitionMap &partMap, + const LogicalPartition &logicalPartNum) +{ + const datatypes::TypeHandler *h= ct.typeHandler(); + int state; + datatypes::MinMaxPartitionInfo partInfo= h->getExtentPartitionInfo(ct, em, entry, &state); + + PartitionMap::iterator mapit = partMap.find(logicalPartNum); + if (mapit == partMap.end()) + { + if (state != CP_VALID) + partInfo.set_invalid(); + + partMap[logicalPartNum] = partInfo; + } + else + { + if (mapit->second.is_invalid()) + return; + + mapit->second.MinMaxInfo::operator=(h->widenMinMaxInfo(ct, mapit->second, partInfo)); + } +} + + void partitionByValue_common(UDF_ARGS* args, // input string& errMsg, // output CalpontSystemCatalog::TableName& tableName, // output @@ -655,13 +355,7 @@ void partitionByValue_common(UDF_ARGS* args, // input vector entries; vector::iterator iter; PartitionMap partMap; - PartitionMap::iterator mapit; - int32_t seqNum; string schema, table, column; - CalpontSystemCatalog::ColType ct; - int64_t startVal = 0, endVal = 0; - int128_t int128StartVal = 0, int128EndVal = 0; - uint8_t rfMin = 0, rfMax = 0; if (args->arg_count == 5) { @@ -709,7 +403,12 @@ void partitionByValue_common(UDF_ARGS* args, // input CalpontSystemCatalog::TableColName tcn = make_tcn(schema, table, column, lower_case_table_names); csc->identity(CalpontSystemCatalog::FE); OID_t oid = csc->lookupOID(tcn); - ct = csc->colType(oid); + CalpontSystemCatalog::ColType ct = csc->colType(oid); + datatypes::SessionParam sp(current_thd->variables.time_zone->get_name()->ptr()); + datatypes::SimpleValue startVal; + datatypes::SimpleValue endVal; + datatypes::round_style_t rfMin = datatypes::round_style_t::NONE; + datatypes::round_style_t rfMax = datatypes::round_style_t::NONE; if (oid == -1) { @@ -731,261 +430,39 @@ void partitionByValue_common(UDF_ARGS* args, // input if (args->arg_count == 4) { - if (!args->args[2]) - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - startVal = 0; - } - else - { - startVal = numeric_limits::min(); - } - } - else - { - if (isUnsigned(ct.colDataType)) - { - int128StartVal = 0; - } - else - { - int128StartVal = datatypes::Decimal::minInt128; - } - } - } - else - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - startVal = IDB_format((char*) args->args[2], ct, rfMin); - else - int128StartVal = IDB_format((char*) args->args[2], ct, rfMin); - } - - if (!args->args[3]) - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - endVal = static_cast(numeric_limits::max()); - } - else - { - endVal = numeric_limits::max(); - } - } - else - { - if (isUnsigned(ct.colDataType)) - { - int128EndVal = -1; - } - else - { - int128EndVal = datatypes::Decimal::maxInt128; - } - } - } - else - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - endVal = IDB_format((char*) args->args[3], ct, rfMax); - else - int128EndVal = IDB_format((char*) args->args[3], ct, rfMax); - } + startVal = getStartVal(sp, ct, args->args[2], rfMin); + endVal = getEndVal(sp, ct, args->args[3], rfMax); } else { - if (!args->args[3]) - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - startVal = 0; - } - else - { - startVal = numeric_limits::min(); - } - } - else - { - if (isUnsigned(ct.colDataType)) - { - int128StartVal = 0; - } - else - { - int128StartVal = datatypes::Decimal::minInt128; - } - } - } - else - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - startVal = IDB_format((char*) args->args[3], ct, rfMin); - else - int128StartVal = IDB_format((char*) args->args[3], ct, rfMin); - } - - if (!args->args[4]) - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - endVal = static_cast(numeric_limits::max()); - } - else - { - endVal = numeric_limits::max(); - } - } - else - { - if (isUnsigned(ct.colDataType)) - { - int128EndVal = -1; - } - else - { - int128EndVal = datatypes::Decimal::maxInt128; - } - } - } - else - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - endVal = IDB_format((char*) args->args[4], ct, rfMax); - else - int128EndVal = IDB_format((char*) args->args[4], ct, rfMax); - } + startVal = getStartVal(sp, ct, args->args[3], rfMin); + endVal = getEndVal(sp, ct, args->args[4], rfMax); } CHECK(em.getExtents(oid, entries, false, false, true)); if (entries.size() > 0) { - LogicalPartition logicalPartNum; for (iter = entries.begin(); iter != entries.end(); ++iter) { - PartitionInfo partInfo; + LogicalPartition logicalPartNum; logicalPartNum.dbroot = (*iter).dbRoot; logicalPartNum.pp = (*iter).partitionNum; logicalPartNum.seg = (*iter).segmentNum; - - if (iter->status == EXTENTOUTOFSERVICE) - partInfo.status |= ET_DISABLED; - - mapit = partMap.find(logicalPartNum); - - int state; - - if (!datatypes::Decimal::isWideDecimalType(ct)) - state = em.getExtentMaxMin(iter->range.start, partInfo.max, partInfo.min, seqNum); - else - state = em.getExtentMaxMin(iter->range.start, partInfo.int128Max, partInfo.int128Min, seqNum); - - // char column order swap - if ((ct.colDataType == CalpontSystemCatalog::CHAR && ct.colWidth <= 8) || - (ct.colDataType == CalpontSystemCatalog::VARCHAR && ct.colWidth <= 7)) - { - partInfo.max = uint64ToStr(partInfo.max); - partInfo.min = uint64ToStr(partInfo.min); - } - - if (mapit == partMap.end()) - { - if (state != CP_VALID) - partInfo.status |= CPINVALID; - - partMap[logicalPartNum] = partInfo; - } - else - { - if (mapit->second.status & CPINVALID) - continue; - - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - mapit->second.min = - (static_cast(partInfo.min) < static_cast(mapit->second.min) ? partInfo.min : mapit->second.min); - mapit->second.max = - (static_cast(partInfo.max) > static_cast(mapit->second.max) ? partInfo.max : mapit->second.max); - } - else - { - mapit->second.min = (partInfo.min < mapit->second.min ? partInfo.min : mapit->second.min); - mapit->second.max = (partInfo.max > mapit->second.max ? partInfo.max : mapit->second.max); - } - } - else - { - mapit->second.int128Min = (partInfo.int128Min < mapit->second.int128Min ? partInfo.int128Min : mapit->second.int128Min); - mapit->second.int128Max = (partInfo.int128Max > mapit->second.int128Max ? partInfo.int128Max : mapit->second.int128Max); - } - } + addPartition(ct, em, *iter, partMap, logicalPartNum); } // check col value range - for (mapit = partMap.begin(); mapit != partMap.end(); ++mapit) + for (PartitionMap::iterator mapit = partMap.begin(); mapit != partMap.end(); ++mapit) { + if (mapit->second.is_invalid()) + continue; + + const datatypes::TypeHandler *h= ct.typeHandler(); // @bug 4595. check empty/null case - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - if (!(mapit->second.status & CPINVALID) && - static_cast(mapit->second.min) >= static_cast(startVal) && - static_cast(mapit->second.max) <= static_cast(endVal) && - !(static_cast(mapit->second.min) == numeric_limits::max() && - static_cast(mapit->second.max == 0))) - { - if (rfMin == ROUND_POS && mapit->second.min == startVal) - continue; - - if (rfMax == ROUND_NEG && mapit->second.max == endVal) - continue; - - partSet.insert(mapit->first); - } - } - else - { - if (!(mapit->second.status & CPINVALID) && mapit->second.min >= startVal && mapit->second.max <= endVal && - !(mapit->second.min == numeric_limits::max() && mapit->second.max == numeric_limits::min())) - { - if (rfMin == ROUND_POS && mapit->second.min == startVal) - continue; - - if (rfMax == ROUND_NEG && mapit->second.max == endVal) - continue; - - partSet.insert(mapit->first); - } - } - } - else - { - if (!(mapit->second.status & CPINVALID) && mapit->second.int128Min >= int128StartVal && mapit->second.int128Max <= int128EndVal && - !(mapit->second.int128Min == datatypes::Decimal::maxInt128 && mapit->second.int128Max == datatypes::Decimal::minInt128)) - { - if (rfMin == ROUND_POS && mapit->second.int128Min == int128StartVal) - continue; - - if (rfMax == ROUND_NEG && mapit->second.int128Max == int128EndVal) - continue; - - partSet.insert(mapit->first); - } - } + if (h->isSuitablePartition(ct, mapit->second, startVal, rfMin, endVal, rfMax)) + partSet.insert(mapit->first); } } } @@ -1135,7 +612,6 @@ extern "C" vector::iterator iter; vector::iterator end; PartitionMap partMap; - int32_t seqNum; string schema, table, column; CalpontSystemCatalog::ColType ct; string errMsg; @@ -1194,54 +670,10 @@ extern "C" for (; iter != end; ++iter) { - PartitionInfo partInfo; logicalPartNum.dbroot = (*iter).dbRoot; logicalPartNum.pp = (*iter).partitionNum; logicalPartNum.seg = (*iter).segmentNum; - - if (iter->status == EXTENTOUTOFSERVICE) - partInfo.status |= ET_DISABLED; - - mapit = partMap.find(logicalPartNum); - - int state = CP_INVALID; - - if (!datatypes::Decimal::isWideDecimalType(ct)) - state = em.getExtentMaxMin(iter->range.start, partInfo.max, partInfo.min, seqNum); - else - state = em.getExtentMaxMin(iter->range.start, partInfo.int128Max, partInfo.int128Min, seqNum); - - // char column order swap for compare - if ((ct.colDataType == CalpontSystemCatalog::CHAR && ct.colWidth <= 8) || - (ct.colDataType == CalpontSystemCatalog::VARCHAR && ct.colWidth <= 7)) - { - partInfo.max = uint64ToStr(partInfo.max); - partInfo.min = uint64ToStr(partInfo.min); - } - - if (mapit == partMap.end()) - { - if (state != CP_VALID) - partInfo.status |= CPINVALID; - - partMap[logicalPartNum] = partInfo; - } - else - { - if (mapit->second.status & CPINVALID) - continue; - - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - mapit->second.min = (partInfo.min < mapit->second.min ? partInfo.min : mapit->second.min); - mapit->second.max = (partInfo.max > mapit->second.max ? partInfo.max : mapit->second.max); - } - else - { - mapit->second.int128Min = (partInfo.int128Min < mapit->second.int128Min ? partInfo.int128Min : mapit->second.int128Min); - mapit->second.int128Max = (partInfo.int128Max > mapit->second.int128Max ? partInfo.int128Max : mapit->second.int128Max); - } - } + addPartition(ct, em, *iter, partMap, logicalPartNum); } } } @@ -1258,35 +690,14 @@ extern "C" return result; } + const datatypes::TypeHandler *h= ct.typeHandler(); + uint8_t valueCharLength= h->PartitionValueCharLength(ct); ostringstream output; output.setf(ios::left, ios::adjustfield); - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - output << setw(10) << "Part#" - << setw(30) << "Min" - << setw(30) << "Max" << "Status"; - } - else - { - output << setw(10) << "Part#" - << setw(datatypes::MAXLENGTH16BYTES) << "Min" - << setw(datatypes::MAXLENGTH16BYTES) << "Max" << "Status"; - } - int64_t maxLimit = numeric_limits::max(); - int64_t minLimit = numeric_limits::min(); - - int128_t int128MaxLimit, int128MinLimit; - int128MaxLimit = datatypes::Decimal::maxInt128; - int128MinLimit = datatypes::Decimal::minInt128; - - // char column order swap for compare in subsequent loop - if ((ct.colDataType == CalpontSystemCatalog::CHAR && ct.colWidth <= 8) || - (ct.colDataType == CalpontSystemCatalog::VARCHAR && ct.colWidth <= 7)) - { - maxLimit = uint64ToStr(maxLimit); - minLimit = uint64ToStr(minLimit); - } + output << setw(10) << "Part#" + << setw(valueCharLength) << "Min" + << setw(valueCharLength) << "Max" << "Status"; PartitionMap::const_iterator partIt; @@ -1296,54 +707,18 @@ extern "C" oss << partIt->first; output << "\n " << setw(10) << oss.str(); - if (partIt->second.status & CPINVALID) + if (partIt->second.is_invalid()) { - if (!datatypes::Decimal::isWideDecimalType(ct)) - output << setw(30) << "N/A" << setw(30) << "N/A"; - else - output << setw(datatypes::MAXLENGTH16BYTES) << "N/A" << setw(datatypes::MAXLENGTH16BYTES) << "N/A"; + output << setw(valueCharLength) << "N/A" + << setw(valueCharLength) << "N/A"; } else { - if ((isUnsigned(ct.colDataType))) - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (static_cast(partIt->second.min) == numeric_limits::max() - && static_cast(partIt->second.max) == numeric_limits::min()) - output << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; - else - output << setw(30) << format(partIt->second.min, ct) << setw(30) << format(partIt->second.max, ct); - } - else - { - if (partIt->second.int128Min == int128MaxLimit - && partIt->second.int128Max == int128MinLimit) - output << setw(datatypes::MAXLENGTH16BYTES) << "Empty/Null" << setw(datatypes::MAXLENGTH16BYTES) << "Empty/Null"; - else - output << setw(datatypes::MAXLENGTH16BYTES) << format(partIt->second.int128Min, ct) << setw(datatypes::MAXLENGTH16BYTES) << format(partIt->second.int128Max, ct); - } - } - else - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (partIt->second.min == maxLimit && partIt->second.max == minLimit) - output << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; - else - output << setw(30) << format(partIt->second.min, ct) << setw(30) << format(partIt->second.max, ct); - } - else - { - if (partIt->second.int128Min == int128MaxLimit && partIt->second.int128Max == int128MinLimit) - output << setw(datatypes::MAXLENGTH16BYTES) << "Empty/Null" << setw(datatypes::MAXLENGTH16BYTES) << "Empty/Null"; - else - output << setw(datatypes::MAXLENGTH16BYTES) << format(partIt->second.int128Min, ct) << setw(datatypes::MAXLENGTH16BYTES) << format(partIt->second.int128Max, ct); - } - } + const datatypes::TypeHandler *h= ct.typeHandler(); + oss << h->formatPartitionInfo(ct, partIt->second); } - if (partIt->second.status & ET_DISABLED) + if (partIt->second.is_disabled()) output << "Disabled"; else output << "Enabled"; @@ -1884,6 +1259,9 @@ extern "C" delete initid->ptr; } + + + #ifdef _MSC_VER __declspec(dllexport) #endif @@ -1897,13 +1275,14 @@ extern "C" vector::iterator end; PartitionMap partMap; PartitionMap::iterator mapit; - int32_t seqNum; string schema, table, column; CalpontSystemCatalog::ColType ct; string errMsg; - int64_t startVal = 0, endVal = 0; - int128_t int128StartVal = 0, int128EndVal = 0; - uint8_t rfMin = 0, rfMax = 0; + datatypes::SessionParam sp(current_thd->variables.time_zone->get_name()->ptr()); + datatypes::SimpleValue startVal; + datatypes::SimpleValue endVal; + datatypes::round_style_t rfMin = datatypes::round_style_t::NONE; + datatypes::round_style_t rfMax = datatypes::round_style_t::NONE; try { @@ -1959,139 +1338,13 @@ extern "C" if (args->arg_count == 4) { - if (!args->args[2]) - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - startVal = 0; - } - else - { - startVal = numeric_limits::min(); - } - } - else - { - if (isUnsigned(ct.colDataType)) - { - int128StartVal = 0; - } - else - { - int128StartVal = datatypes::Decimal::minInt128; - } - } - } - else - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - startVal = IDB_format((char*) args->args[2], ct, rfMin); - else - int128StartVal = IDB_format((char*) args->args[2], ct, rfMin); - } - - if (!args->args[3]) - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - endVal = static_cast(numeric_limits::max()); - } - else - { - endVal = numeric_limits::max(); - } - } - else - { - if (isUnsigned(ct.colDataType)) - { - int128EndVal = -1; - } - else - { - int128EndVal = datatypes::Decimal::maxInt128; - } - } - } - else - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - endVal = IDB_format((char*) args->args[3], ct, rfMax); - else - int128EndVal = IDB_format((char*) args->args[3], ct, rfMax); - } + startVal= getStartVal(sp, ct, args->args[2], rfMin); + endVal= getEndVal(sp, ct, args->args[3], rfMax); } else { - if (!args->args[3]) - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - startVal = 0; - } - else - { - startVal = numeric_limits::min(); - } - } - else - { - if (isUnsigned(ct.colDataType)) - { - int128StartVal = 0; - } - else - { - int128StartVal = datatypes::Decimal::minInt128; - } - } - } - else - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - startVal = IDB_format((char*) args->args[3], ct, rfMin); - else - int128StartVal = IDB_format((char*) args->args[3], ct, rfMin); - } - - if (!args->args[4]) - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - endVal = static_cast(numeric_limits::max()); - } - else - { - endVal = numeric_limits::max(); - } - } - else - { - if (isUnsigned(ct.colDataType)) - { - int128EndVal = -1; - } - else - { - int128EndVal = datatypes::Decimal::maxInt128; - } - } - } - else - { - if (!datatypes::Decimal::isWideDecimalType(ct)) - endVal = IDB_format((char*) args->args[4], ct, rfMax); - else - int128EndVal = IDB_format((char*) args->args[4], ct, rfMax); - } + startVal= getStartVal(sp, ct, args->args[3], rfMin); + endVal= getEndVal(sp, ct, args->args[4], rfMax); } CHECK(em.getExtents(oid, entries, false, false, true)); @@ -2104,64 +1357,10 @@ extern "C" for (; iter != end; ++iter) { - PartitionInfo partInfo; logicalPartNum.dbroot = (*iter).dbRoot; logicalPartNum.pp = (*iter).partitionNum; logicalPartNum.seg = (*iter).segmentNum; - - if (iter->status == EXTENTOUTOFSERVICE) - partInfo.status |= ET_DISABLED; - - mapit = partMap.find(logicalPartNum); - - int state; - - if (!datatypes::Decimal::isWideDecimalType(ct)) - state = em.getExtentMaxMin(iter->range.start, partInfo.max, partInfo.min, seqNum); - else - state = em.getExtentMaxMin(iter->range.start, partInfo.int128Max, partInfo.int128Min, seqNum); - - // char column order swap - if ((ct.colDataType == CalpontSystemCatalog::CHAR && ct.colWidth <= 8) || - (ct.colDataType == CalpontSystemCatalog::VARCHAR && ct.colWidth <= 7)) - { - partInfo.max = uint64ToStr(partInfo.max); - partInfo.min = uint64ToStr(partInfo.min); - } - - if (mapit == partMap.end()) - { - if (state != CP_VALID) - partInfo.status |= CPINVALID; - - partMap[logicalPartNum] = partInfo; - } - else - { - if (mapit->second.status & CPINVALID) - continue; - - if (!datatypes::Decimal::isWideDecimalType(ct)) - { - if (isUnsigned(ct.colDataType)) - { - mapit->second.min = - (static_cast(partInfo.min) < static_cast(mapit->second.min) ? partInfo.min : mapit->second.min); - mapit->second.max = - (static_cast(partInfo.max) > static_cast(mapit->second.max) ? partInfo.max : mapit->second.max); - } - else - { - mapit->second.min = (partInfo.min < mapit->second.min ? partInfo.min : mapit->second.min); - mapit->second.max = (partInfo.max > mapit->second.max ? partInfo.max : mapit->second.max); - } - } - else - { - mapit->second.int128Min = (partInfo.int128Min < mapit->second.int128Min ? partInfo.int128Min : mapit->second.int128Min); - mapit->second.int128Max = (partInfo.int128Max > mapit->second.int128Max ? partInfo.int128Max : mapit->second.int128Max); - } - } + addPartition(ct, em, *iter, partMap, logicalPartNum); } } } @@ -2193,107 +1392,41 @@ extern "C" for (mapit = partMap.begin(); mapit != partMap.end(); ++mapit) { + const datatypes::TypeHandler *h= ct.typeHandler(); + uint8_t valueCharLength= h->PartitionValueCharLength(ct); + if (mapit->second.is_invalid()) + { + output << setw(valueCharLength) << "N/A" + << setw(valueCharLength) << "N/A"; + continue; + } // @bug 4595. check empty/null case - if (!datatypes::Decimal::isWideDecimalType(ct)) + string tmp= h->PrintPartitionValue(ct, mapit->second, + startVal, rfMin, + endVal, rfMax); + if (tmp == "") + continue; + + // print header + if (noPartFound) { - if (!(mapit->second.status & CPINVALID) && mapit->second.min >= startVal && mapit->second.max <= endVal && - !(mapit->second.min == numeric_limits::max() && mapit->second.max == numeric_limits::min())) - { - if (rfMin == ROUND_POS && mapit->second.min == startVal) - continue; - - if (rfMax == ROUND_NEG && mapit->second.max == endVal) - continue; - - // print header - if (noPartFound) - { - output.setf(ios::left, ios::adjustfield); - output << setw(10) << "Part#" - << setw(30) << "Min" - << setw(30) << "Max" << "Status"; - } - - noPartFound = false; - - // print part info - ostringstream oss; - oss << mapit->first; - output << "\n " << setw(10) << oss.str(); - - if (mapit->second.status & CPINVALID) - { - output << setw(30) << "N/A" << setw(30) << "N/A"; - } - else - { - if ((isUnsigned(ct.colDataType))) - { - if (static_cast(mapit->second.min) > static_cast(mapit->second.max)) - output << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; - else - output << setw(30) << format(mapit->second.min, ct) << setw(30) << format(mapit->second.max, ct); - } - else - { - if (mapit->second.min > mapit->second.max) - output << setw(30) << "Empty/Null" << setw(30) << "Empty/Null"; - else - output << setw(30) << format(mapit->second.min, ct) << setw(30) << format(mapit->second.max, ct); - } - } - - if (mapit->second.status & ET_DISABLED) - output << "Disabled"; - else - output << "Enabled"; - } + output.setf(ios::left, ios::adjustfield); + output << setw(10) << "Part#" + << setw(valueCharLength) << "Min" + << setw(valueCharLength) << "Max" << "Status"; + noPartFound = false; } + + // print part info + ostringstream oss; + oss << mapit->first; + output << "\n " << setw(10) << oss.str() << tmp; + + if (mapit->second.is_disabled()) + output << "Disabled"; else - { - if (!(mapit->second.status & CPINVALID) && mapit->second.int128Min >= int128StartVal && mapit->second.int128Max <= int128EndVal && - !(mapit->second.int128Min == datatypes::Decimal::maxInt128 && mapit->second.int128Max == datatypes::Decimal::minInt128)) - { - if (rfMin == ROUND_POS && mapit->second.int128Min == int128StartVal) - continue; + output << "Enabled"; - if (rfMax == ROUND_NEG && mapit->second.int128Max == int128EndVal) - continue; - - // print header - if (noPartFound) - { - output.setf(ios::left, ios::adjustfield); - output << setw(10) << "Part#" - << setw(datatypes::MAXLENGTH16BYTES) << "Min" - << setw(datatypes::MAXLENGTH16BYTES) << "Max" << "Status"; - } - - noPartFound = false; - - // print part info - ostringstream oss; - oss << mapit->first; - output << "\n " << setw(10) << oss.str(); - - if (mapit->second.status & CPINVALID) - { - output << setw(datatypes::MAXLENGTH16BYTES) << "N/A" << setw(datatypes::MAXLENGTH16BYTES) << "N/A"; - } - else - { - if (mapit->second.int128Min > mapit->second.int128Max) - output << setw(datatypes::MAXLENGTH16BYTES) << "Empty/Null" << setw(datatypes::MAXLENGTH16BYTES) << "Empty/Null"; - else - output << setw(datatypes::MAXLENGTH16BYTES) << format(mapit->second.int128Min, ct) << setw(datatypes::MAXLENGTH16BYTES) << format(mapit->second.int128Max, ct); - } - - if (mapit->second.status & ET_DISABLED) - output << "Disabled"; - else - output << "Enabled"; - } - } } if (noPartFound) diff --git a/dbcon/mysql/is_columnstore_extents.cpp b/dbcon/mysql/is_columnstore_extents.cpp index 7f48b0d41..7e6f01165 100644 --- a/dbcon/mysql/is_columnstore_extents.cpp +++ b/dbcon/mysql/is_columnstore_extents.cpp @@ -28,7 +28,6 @@ #include "objectidmanager.h" #include "is_columnstore.h" #include "mcs_decimal.h" -#include "widedecimalutils.h" #include "dataconvert.h" // Required declaration as it isn't in a MairaDB include @@ -114,10 +113,10 @@ static int generate_result(BRM::OID_t oid, BRM::DBRM* emp, TABLE* table, THD* th { table->field[4]->set_notnull(); - char buf[utils::MAXLENGTH16BYTES]; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; dataconvert::DataConvert::decimalToString( &iter->partition.cprange.bigLoVal, - 0, buf, sizeof(buf), execplan::CalpontSystemCatalog::DECIMAL); + 0, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL); table->field[4]->store(buf, strlen(buf), table->field[4]->charset()); } @@ -129,10 +128,10 @@ static int generate_result(BRM::OID_t oid, BRM::DBRM* emp, TABLE* table, THD* th { table->field[5]->set_notnull(); - char buf[utils::MAXLENGTH16BYTES]; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; dataconvert::DataConvert::decimalToString( &iter->partition.cprange.bigHiVal, - 0, buf, sizeof(buf), execplan::CalpontSystemCatalog::DECIMAL); + 0, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL); table->field[5]->store(buf, strlen(buf), table->field[5]->charset()); } } diff --git a/primitives/primproc/columncommand.cpp b/primitives/primproc/columncommand.cpp index 62ac4f66f..fbedc0c6a 100644 --- a/primitives/primproc/columncommand.cpp +++ b/primitives/primproc/columncommand.cpp @@ -288,7 +288,7 @@ void ColumnCommand::issuePrimitive() bpp->lbidForCP = lbid; if (UNLIKELY(utils::isWide(colType.colWidth))) { - if (datatypes::Decimal::isWideDecimalType(colType)) + if (colType.isWideDecimalType()) { bpp->hasWideColumnOut = true; // colWidth is int32 and wideColumnWidthOut's diff --git a/primitives/primproc/filtercommand.cpp b/primitives/primproc/filtercommand.cpp index 5bf5d0b05..ac9f8c79c 100644 --- a/primitives/primproc/filtercommand.cpp +++ b/primitives/primproc/filtercommand.cpp @@ -250,7 +250,7 @@ void FilterCommand::setColTypes(const execplan::CalpontSystemCatalog::ColType& l leftColType = left; rightColType = right; - if (datatypes::Decimal::isWideDecimalType(left) || datatypes::Decimal::isWideDecimalType(right)) + if (left.isWideDecimalType() || right.isWideDecimalType()) hasWideColumns = true; } @@ -280,7 +280,7 @@ void FilterCommand::doFilter() if ((this->*compareFunc)(i, j) == true) { bpp->relRids[bpp->ridCount] = bpp->fFiltCmdRids[0][i]; - if (datatypes::Decimal::isWideDecimalType(leftColType)) + if (leftColType.isWideDecimalType()) bpp->wide128Values[bpp->ridCount] = bpp->fFiltCmdBinaryValues[0][i]; else bpp->values[bpp->ridCount] = bpp->fFiltCmdValues[0][i]; @@ -342,7 +342,7 @@ bool FilterCommand::binaryCompare(uint64_t i, uint64_t j) // not int128_t int128_t leftVal, rightVal; - if (datatypes::Decimal::isWideDecimalType(leftColType)) + if (leftColType.isWideDecimalType()) { if (execplan::isNull(bpp->fFiltCmdBinaryValues[0][i], leftColType)) return false; @@ -355,7 +355,7 @@ bool FilterCommand::binaryCompare(uint64_t i, uint64_t j) leftVal = bpp->fFiltCmdValues[0][i]; } - if (datatypes::Decimal::isWideDecimalType(rightColType)) + if (rightColType.isWideDecimalType()) { if (execplan::isNull(bpp->fFiltCmdBinaryValues[1][j], rightColType)) return false; diff --git a/primitives/primproc/pseudocc.cpp b/primitives/primproc/pseudocc.cpp index 4fb3ba8d8..588723452 100644 --- a/primitives/primproc/pseudocc.cpp +++ b/primitives/primproc/pseudocc.cpp @@ -58,7 +58,7 @@ void PseudoCC::resetCommand(messageqcpp::ByteStream& bs) { if (function == PSEUDO_EXTENTMAX || function == PSEUDO_EXTENTMIN) { - if (!datatypes::Decimal::isWideDecimalType(colType)) + if (!colType.isWideDecimalType()) bs >> valueFromUM; else bs >> bigValueFromUM; @@ -67,7 +67,7 @@ void PseudoCC::resetCommand(messageqcpp::ByteStream& bs) { bs >> valueFromUM; - if (datatypes::Decimal::isWideDecimalType(colType)) + if (colType.isWideDecimalType()) bigValueFromUM = valueFromUM; } diff --git a/tests/dataconvert-tests.cpp b/tests/dataconvert-tests.cpp index 07b191b1a..17c816c98 100644 --- a/tests/dataconvert-tests.cpp +++ b/tests/dataconvert-tests.cpp @@ -20,8 +20,6 @@ using namespace std; #include "gtest/gtest.h" -#include "calpontsystemcatalog.h" -using namespace execplan; #include "dataconvert.h" using namespace dataconvert; #include "joblisttypes.h" @@ -143,7 +141,8 @@ TEST(DataConvertTest, Strtoll128) TEST(DataConvertTest, NumberIntValue) { - CalpontSystemCatalog::ColType ct; + datatypes::SystemCatalog::TypeAttributesStd ct; + int128_t res, valMax; string data; bool noRoundup = false; @@ -153,7 +152,7 @@ TEST(DataConvertTest, NumberIntValue) // tests for signed decimal // behaviour of number_int_value for unsigned decimal // is similar to the signed case. - ct.colDataType = CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::ColDataType typecode = datatypes::SystemCatalog::DECIMAL; // test with decimal(38,0) ct.precision = 38; ct.scale = 0; @@ -161,39 +160,39 @@ TEST(DataConvertTest, NumberIntValue) //data = ""; data = "0"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 0); EXPECT_FALSE(pushWarning); data = "1234"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 1234); EXPECT_FALSE(pushWarning); data = "12.0"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 12); EXPECT_FALSE(pushWarning); data = "12.34"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 12); EXPECT_TRUE(pushWarning); data = "-1234"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, -1234); EXPECT_FALSE(pushWarning); data = "-12.34"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, -12); EXPECT_TRUE(pushWarning); // test max data = "99999999999999999999999999999999999999"; valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -206,7 +205,7 @@ TEST(DataConvertTest, NumberIntValue) valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; valMax = -valMax; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -217,12 +216,12 @@ TEST(DataConvertTest, NumberIntValue) // test rounding data = "12.56"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 13); EXPECT_TRUE(pushWarning); data = "-12.56"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, -13); EXPECT_TRUE(pushWarning); // test saturation @@ -230,7 +229,7 @@ TEST(DataConvertTest, NumberIntValue) // valMax has 38 9's valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -243,7 +242,7 @@ TEST(DataConvertTest, NumberIntValue) valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; valMax = -valMax; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -255,7 +254,7 @@ TEST(DataConvertTest, NumberIntValue) data = "1.23e37"; valMax = ((((((((int128_t)123000000 * 1000000000) + 0) * 1000000000) + 0) * 1000000000 ) + 0) * 100) + 0; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -266,7 +265,7 @@ TEST(DataConvertTest, NumberIntValue) data = "1.23e38"; valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -279,39 +278,39 @@ TEST(DataConvertTest, NumberIntValue) ct.scale = 10; data = "0"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 0); EXPECT_FALSE(pushWarning); data = "1234"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 12340000000000); EXPECT_FALSE(pushWarning); data = "12.0"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 120000000000); EXPECT_FALSE(pushWarning); data = "12.34"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 123400000000); EXPECT_FALSE(pushWarning); data = "-1234"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, -12340000000000); EXPECT_FALSE(pushWarning); data = "-12.34"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, -123400000000); EXPECT_FALSE(pushWarning); // test max data = "9999999999999999999999999999.9999999999"; valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -324,7 +323,7 @@ TEST(DataConvertTest, NumberIntValue) valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; valMax = -valMax; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -335,12 +334,12 @@ TEST(DataConvertTest, NumberIntValue) // test rounding data = "12.11111111119"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 121111111112); EXPECT_TRUE(pushWarning); data = "-12.11111111119"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, -121111111112); EXPECT_TRUE(pushWarning); // test saturation @@ -348,7 +347,7 @@ TEST(DataConvertTest, NumberIntValue) // valMax has 38 9's valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -361,7 +360,7 @@ TEST(DataConvertTest, NumberIntValue) valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; valMax = -valMax; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -373,7 +372,7 @@ TEST(DataConvertTest, NumberIntValue) data = "1.23e9"; valMax = ((((int128_t)123000000 * 1000000000) + 0) * 100); pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -384,7 +383,7 @@ TEST(DataConvertTest, NumberIntValue) data = "1.23e28"; valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -396,13 +395,13 @@ TEST(DataConvertTest, NumberIntValue) ct.scale = 38; data = "0"; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); EXPECT_EQ(res, 0); EXPECT_FALSE(pushWarning); data = "1.234"; valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -413,7 +412,7 @@ TEST(DataConvertTest, NumberIntValue) data = "0.123"; valMax = ((((((((int128_t)123000000 * 1000000000) + 0) * 1000000000) + 0) * 1000000000 ) + 0) * 100) + 0; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -425,7 +424,7 @@ TEST(DataConvertTest, NumberIntValue) valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; valMax = -valMax; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -437,7 +436,7 @@ TEST(DataConvertTest, NumberIntValue) valMax = ((((((((int128_t)123000000 * 1000000000) + 0) * 1000000000) + 0) * 1000000000 ) + 0) * 100) + 0; valMax = -valMax; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -449,7 +448,7 @@ TEST(DataConvertTest, NumberIntValue) data = "0.99999999999999999999999999999999999999"; valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -462,7 +461,7 @@ TEST(DataConvertTest, NumberIntValue) valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; valMax = -valMax; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -474,7 +473,7 @@ TEST(DataConvertTest, NumberIntValue) data = "0.199999999999999999999999999999999999999"; valMax = ((((((((int128_t)200000000 * 1000000000) + 0) * 1000000000) + 0) * 1000000000 ) + 0) * 100) + 0; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -486,7 +485,7 @@ TEST(DataConvertTest, NumberIntValue) valMax = ((((((((int128_t)200000000 * 1000000000) + 0) * 1000000000) + 0) * 1000000000 ) + 0) * 100) + 0; valMax = -valMax; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -499,7 +498,7 @@ TEST(DataConvertTest, NumberIntValue) // valMax has 38 9's valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -512,7 +511,7 @@ TEST(DataConvertTest, NumberIntValue) valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; valMax = -valMax; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -524,7 +523,7 @@ TEST(DataConvertTest, NumberIntValue) data = "123e-4"; valMax = ((((((((int128_t)123000000 * 1000000000) + 0) * 1000000000) + 0) * 1000000000 ) + 0) * 10) + 0; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -535,7 +534,7 @@ TEST(DataConvertTest, NumberIntValue) data = "123e-2"; valMax = ((((((((int128_t)999999999 * 1000000000) + 999999999) * 1000000000) + 999999999) * 1000000000 ) + 999999999) * 100) + 99; pushWarning = false; - number_int_value(data, ct, pushWarning, noRoundup, res); + number_int_value(data, typecode, ct, pushWarning, noRoundup, res); b1 = *(reinterpret_cast(&res)); b2 = *(reinterpret_cast(&res) + 1); b3 = *(reinterpret_cast(&valMax)); @@ -547,8 +546,8 @@ TEST(DataConvertTest, NumberIntValue) TEST(DataConvertTest, DecimalToStringCheckScale0) { - CalpontSystemCatalog::ColType ct; - ct.colDataType = CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::TypeHolderStd ct; + ct.colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; string input, expected; ct.precision = 38; @@ -599,8 +598,8 @@ TEST(DataConvertTest, DecimalToStringCheckScale0) } TEST(DataConvertTest, DecimalToStringCheckScale10) { - CalpontSystemCatalog::ColType ct; - ct.colDataType = CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::TypeHolderStd ct; + ct.colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; string input, expected; ct.precision = 38; @@ -670,8 +669,8 @@ TEST(DataConvertTest, DecimalToStringCheckScale10) TEST(DataConvertTest, DecimalToStringCheckScale38) { - CalpontSystemCatalog::ColType ct; - ct.colDataType = CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::TypeHolderStd ct; + ct.colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; string input, expected; ct.precision = 38; @@ -731,8 +730,8 @@ TEST(DataConvertTest, DecimalToStringCheckScale38) TEST(DataConvertTest, DecimalToStringCheckScale37) { - CalpontSystemCatalog::ColType ct; - ct.colDataType = CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::TypeHolderStd ct; + ct.colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; string expected; ct.precision = 38; diff --git a/tests/mcs_decimal-tests.cpp b/tests/mcs_decimal-tests.cpp index 53a40c533..762db7365 100644 --- a/tests/mcs_decimal-tests.cpp +++ b/tests/mcs_decimal-tests.cpp @@ -21,9 +21,7 @@ #include "treenode.h" #include "mcs_decimal.h" -#include "widedecimalutils.h" #include "dataconvert.h" -#include "calpontsystemcatalog.h" TEST(Decimal, compareCheck) { @@ -86,8 +84,7 @@ TEST(Decimal, compareCheck) TEST(Decimal, additionNoOverflowCheck) { - execplan::CalpontSystemCatalog::ColType ct; - ct.colDataType = execplan::CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; // Addition w/o overflow check execplan::IDB_Decimal l, r, result; @@ -146,7 +143,7 @@ TEST(Decimal, additionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::addition(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000042000000000000000000000042", std::string(buf)); // same precision, L scale > R scale, both negative values @@ -155,7 +152,7 @@ TEST(Decimal, additionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::addition(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-0.00000000000042000000000000000000000042", std::string(buf)); // same precision, L scale > R scale, +- values @@ -164,7 +161,7 @@ TEST(Decimal, additionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::addition(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-0.00000000000041999999999999999999999958", std::string(buf)); // same precision, L scale > R scale, both 0 @@ -189,7 +186,7 @@ TEST(Decimal, additionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::addition(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000004200000000000000000000420", std::string(buf)); // same precision, L scale < R scale, both negative values @@ -198,7 +195,7 @@ TEST(Decimal, additionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::addition(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-0.00000000000004200000000000000000000420", std::string(buf)); // same precision, L scale < R scale, +- values @@ -207,7 +204,7 @@ TEST(Decimal, additionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::addition(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000004199999999999999999999580", std::string(buf)); // same precision, L scale < R scale, both 0 @@ -223,8 +220,7 @@ TEST(Decimal, divisionNoOverflowCheck) { // DIVISION // same precision, same scale, both positive values - execplan::CalpontSystemCatalog::ColType ct; - ct.colDataType = execplan::CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; execplan::IDB_Decimal l, r, result; @@ -241,7 +237,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("9.7674418605", std::string(buf)); // same precision, same scale, both negative values @@ -250,7 +246,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("9.7674418605", std::string(buf)); // same precision, same scale, +- values @@ -259,7 +255,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-1157.8947368421", std::string(buf)); // same precision, same scale, l = 0 @@ -282,7 +278,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("115789473684210526315789.4736842105", std::string(buf)); // same precision, L scale > R scale, both negative values @@ -291,7 +287,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("86363636363636363636363.6363636364", std::string(buf)); // same precision, L scale > R scale, +- values @@ -300,7 +296,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-115789473684210526315789.4736842105", std::string(buf)); // same precision, L scale > R scale, R = 0 @@ -317,7 +313,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("100000000000000000000000.0000000000", std::string(buf)); // same precision, L scale > R scale, both MIN negative values @@ -326,7 +322,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("100000000000000000000000.0000000000", std::string(buf)); // same precision, L scale < R scale, both positive values @@ -343,7 +339,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000000000000001000000000000000", std::string(buf)); // same precision, L scale < R scale, both negative values @@ -352,7 +348,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000000000000000863636363636364", std::string(buf)); // same precision, L scale < R scale, +- values @@ -361,7 +357,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-0.00000000000000000000000863636363636364", std::string(buf)); // same precision, L scale < R scale, R = 0 @@ -379,7 +375,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000000000000001000000000000000", std::string(buf)); // same precision, L scale < R scale, both MIN negative values @@ -388,7 +384,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000000000000001000000000000000", std::string(buf)); // same precision, L scale < R scale, result.scale < (r.scale-l.scale) @@ -406,7 +402,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("1", std::string(buf)); // same precision, L scale < R scale, result.scale < (r.scale-l.scale) @@ -416,7 +412,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("9", std::string(buf)); // same precision, L scale < R scale, result.scale < (r.scale-l.scale) @@ -426,7 +422,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-9", std::string(buf)); // same precision, L scale < R scale, result.scale < (r.scale-l.scale) @@ -445,7 +441,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0", std::string(buf)); // same precision, L scale < R scale, result.scale < (r.scale-l.scale) @@ -455,7 +451,7 @@ TEST(Decimal, divisionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::division(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0", std::string(buf)); } @@ -468,8 +464,7 @@ void doDiv(const execplan::IDB_Decimal& l, TEST(Decimal, divisionWithOverflowCheck) { - execplan::CalpontSystemCatalog::ColType ct; - ct.colDataType = execplan::CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; // Divide min int128 by -1 execplan::IDB_Decimal l, r, result; @@ -508,7 +503,7 @@ TEST(Decimal, divisionWithOverflowCheck) result.s128Value = 0; EXPECT_NO_THROW(doDiv(l, r, result)); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("9223372036854775809", std::string(buf)); } @@ -521,8 +516,7 @@ void doAdd(const execplan::IDB_Decimal& l, TEST(Decimal, additionWithOverflowCheck) { - execplan::CalpontSystemCatalog::ColType ct; - ct.colDataType = execplan::CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; // Add two max ints execplan::IDB_Decimal l, r, result; @@ -561,14 +555,13 @@ TEST(Decimal, additionWithOverflowCheck) result.s128Value = 0; EXPECT_NO_THROW(doAdd(l, r, result)); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-170141183460469231713240559642174554113", std::string(buf)); } TEST(Decimal, subtractionNoOverflowCheck) { - execplan::CalpontSystemCatalog::ColType ct; - ct.colDataType = execplan::CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; // Subtractio w/o overflow check execplan::IDB_Decimal l, r, result; @@ -586,7 +579,7 @@ TEST(Decimal, subtractionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::subtraction(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-0.00000000000000000000000000000000000378", std::string(buf)); // same precision, same scale, both negative values @@ -595,7 +588,7 @@ TEST(Decimal, subtractionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::subtraction(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000000000000000000000000000378", std::string(buf)); // same precision, same scale, +- values @@ -604,7 +597,7 @@ TEST(Decimal, subtractionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::subtraction(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000000000000000000000000000462", std::string(buf)); // same precision, same scale, both 0 @@ -630,7 +623,7 @@ TEST(Decimal, subtractionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::subtraction(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-0.00000000000041999999999999999999999958", std::string(buf)); // same precision, L scale > R scale, both negative values @@ -639,7 +632,7 @@ TEST(Decimal, subtractionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::subtraction(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000041999999999999999999999958", std::string(buf)); // same precision, L scale > R scale, +- values @@ -648,7 +641,7 @@ TEST(Decimal, subtractionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::subtraction(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000042000000000000000000000042", std::string(buf)); // same precision, L scale > R scale, both 0 @@ -673,7 +666,7 @@ TEST(Decimal, subtractionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::subtraction(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000004199999999999999999999580", std::string(buf)); // same precision, L scale < R scale, both negative values @@ -682,7 +675,7 @@ TEST(Decimal, subtractionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::subtraction(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-0.00000000000004199999999999999999999580", std::string(buf)); // same precision, L scale < R scale, +- values @@ -691,7 +684,7 @@ TEST(Decimal, subtractionNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::subtraction(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.00000000000004200000000000000000000420", std::string(buf)); // same precision, L scale < R scale, both 0 @@ -712,8 +705,7 @@ void doSubtract(const execplan::IDB_Decimal& l, TEST(Decimal, subtractionWithOverflowCheck) { - execplan::CalpontSystemCatalog::ColType ct; - ct.colDataType = execplan::CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; // Subtract a max int from a min int execplan::IDB_Decimal l, r, result; @@ -752,7 +744,7 @@ TEST(Decimal, subtractionWithOverflowCheck) result.s128Value = 0; EXPECT_NO_THROW(doSubtract(l, r, result)); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("170141183460469231713240559642174554112", std::string(buf)); } @@ -760,8 +752,7 @@ TEST(Decimal, multiplicationNoOverflowCheck) { // Multiplication // same precision, l.scale + r.scale = result.scale, both positive values - execplan::CalpontSystemCatalog::ColType ct; - ct.colDataType = execplan::CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; execplan::IDB_Decimal l, r, result; @@ -778,7 +769,7 @@ TEST(Decimal, multiplicationNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::multiplication(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.85070591730234615861231965839514664960", std::string(buf)); // same precision, l.scale + r.scale = result.scale, both negative values @@ -788,7 +779,7 @@ TEST(Decimal, multiplicationNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::multiplication(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.85070591730234615861231965839514664960", std::string(buf)); // same precision, l.scale + r.scale = result.scale, +- values @@ -797,7 +788,7 @@ TEST(Decimal, multiplicationNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::multiplication(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-0.85070591730234615861231965839514664960", std::string(buf)); // same precision, l.scale + r.scale = result.scale, l = 0 @@ -822,7 +813,7 @@ TEST(Decimal, multiplicationNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::multiplication(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.66461399789245793645190353014017228800", std::string(buf)); // same precision, l.scale + r.scale < result.scale, both negative values @@ -832,7 +823,7 @@ TEST(Decimal, multiplicationNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::multiplication(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.66461399789245793645190353014017228800", std::string(buf)); // same precision, l.scale + r.scale < result.scale, +- values @@ -841,7 +832,7 @@ TEST(Decimal, multiplicationNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::multiplication(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-0.66461399789245793645190353014017228800", std::string(buf)); // same precision, l.scale + r.scale < result.scale, l = 0 @@ -868,7 +859,7 @@ TEST(Decimal, multiplicationNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::multiplication(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.01524157875323883675019051998750190521", std::string(buf)); // same precision, l.scale + r.scale > result.scale, both negative values @@ -877,7 +868,7 @@ TEST(Decimal, multiplicationNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::multiplication(r, l, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("0.01524157875323883675019051998750190521", std::string(buf)); // same precision, l.scale + r.scale > result.scale, +- values @@ -885,7 +876,7 @@ TEST(Decimal, multiplicationNoOverflowCheck) result.s128Value = 0; datatypes::Decimal::multiplication(l, r, result); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("-0.01524157875323883675019051998750190521", std::string(buf)); // same precision, l.scale + r.scale > result.scale, l = 0 @@ -905,8 +896,7 @@ void doMultiply(const execplan::IDB_Decimal& l, TEST(Decimal, multiplicationWithOverflowCheck) { - execplan::CalpontSystemCatalog::ColType ct; - ct.colDataType = execplan::CalpontSystemCatalog::DECIMAL; + datatypes::SystemCatalog::ColDataType colDataType = datatypes::SystemCatalog::DECIMAL; char buf[42]; execplan::IDB_Decimal l, r, result; // result.scale >= l.scale + r.scale @@ -950,6 +940,6 @@ TEST(Decimal, multiplicationWithOverflowCheck) result.s128Value = 0; EXPECT_NO_THROW(doMultiply(l, r, result)); - dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, ct.colDataType); + dataconvert::DataConvert::decimalToString(&result.s128Value, result.scale, buf, 42, colDataType); EXPECT_EQ("21267647932558653966460912964485513216", std::string(buf)); } diff --git a/tests/rowgroup-tests.cpp b/tests/rowgroup-tests.cpp index d53356d3a..7232d4898 100644 --- a/tests/rowgroup-tests.cpp +++ b/tests/rowgroup-tests.cpp @@ -20,7 +20,6 @@ #include "rowgroup.h" #include "columnwidth.h" -#include "widedecimalutils.h" #include "joblisttypes.h" #include "dataconvert.h" @@ -98,7 +97,7 @@ protected: int128_t nullValue = 0; int128_t bigValue = 0; - utils::setWideDecimalNullValue(nullValue); + datatypes::Decimal::setWideDecimalNullValue(nullValue); bigValue = -static_cast(0xFFFFFFFF)*0xFFFFFFFFFFFFFFFF; sValueVector.push_back(nullValue); diff --git a/tools/editem/editem.cpp b/tools/editem/editem.cpp index 9ed40b2aa..dd39875df 100644 --- a/tools/editem/editem.cpp +++ b/tools/editem/editem.cpp @@ -44,7 +44,6 @@ using namespace config; #include "dataconvert.h" using namespace dataconvert; -#include "widedecimalutils.h" #include "mcs_decimal.h" #include "liboamcpp.h" @@ -192,12 +191,12 @@ const string fmt(T v) } else { - char buf[utils::MAXLENGTH16BYTES]; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; int128_t tmp = v; dataconvert::DataConvert::decimalToString( - &tmp, 0, buf, sizeof(buf), execplan::CalpontSystemCatalog::DECIMAL); + &tmp, 0, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL); oss << buf; } @@ -219,12 +218,12 @@ const string fmt(T v) } else { - char buf[utils::MAXLENGTH16BYTES]; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; int128_t tmp = static_cast(v); dataconvert::DataConvert::decimalToString( - &tmp, 0, buf, sizeof(buf), execplan::CalpontSystemCatalog::DECIMAL); + &tmp, 0, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL); oss << buf; } @@ -248,12 +247,12 @@ const string fmt(T v) } else { - char buf[utils::MAXLENGTH16BYTES]; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; int128_t tmp = v; dataconvert::DataConvert::decimalToString( - &tmp, 0, buf, sizeof(buf), execplan::CalpontSystemCatalog::DECIMAL); + &tmp, 0, buf, (uint8_t) sizeof(buf), datatypes::SystemCatalog::DECIMAL); oss << buf; } diff --git a/utils/cloudio/CMakeLists.txt b/utils/cloudio/CMakeLists.txt index 1e00662e8..f94924b99 100755 --- a/utils/cloudio/CMakeLists.txt +++ b/utils/cloudio/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(${ENGINE_COMMON_INCLUDES} ${ENGINE_SRC_DIR}/storage-manager/include) -set(cloudio_LIB_SRCS SMComm.cpp SMDataFile.cpp SMFileFactory.cpp SMFileSystem.cpp SocketPool.cpp cloud_plugin.cpp) +set(cloudio_LIB_SRCS SMComm.cpp SMDataFile.cpp SMFileFactory.cpp SMFileSystem.cpp SocketPool.cpp cloud_plugin.cpp ../../datatypes/mcs_datatype.cpp) add_library(cloudio SHARED ${cloudio_LIB_SRCS}) diff --git a/utils/common/emptyvaluemanip.cpp b/utils/common/emptyvaluemanip.cpp index fc97d2f14..3300bc690 100644 --- a/utils/common/emptyvaluemanip.cpp +++ b/utils/common/emptyvaluemanip.cpp @@ -15,7 +15,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "widedecimalutils.h" #include "emptyvaluemanip.h" namespace utils @@ -81,7 +80,7 @@ void getEmptyRowValue(const execplan::CalpontSystemCatalog::ColDataType colDataT else if (width <= 8) *(uint64_t*)emptyVal = joblist::BIGINTEMPTYROW; else - setWideDecimalEmptyValue(*(reinterpret_cast(emptyVal))); + datatypes::Decimal::setWideDecimalEmptyValue(*(reinterpret_cast(emptyVal))); break; //case CalpontSystemCatalog::BINARY: diff --git a/utils/common/widedecimalutils.h b/utils/common/widedecimalutils.h index 6efa1b595..b6f1ad5e9 100644 --- a/utils/common/widedecimalutils.h +++ b/utils/common/widedecimalutils.h @@ -29,52 +29,10 @@ namespace utils const uint64_t BINARYNULLVALUEHIGH = 0x8000000000000000ULL; const uint64_t BINARYEMPTYVALUELOW = 1ULL; const uint64_t BINARYEMPTYVALUEHIGH = 0x8000000000000000ULL; - const uint8_t MAXLENGTH16BYTES = 42; - const uint8_t MAXLENGTH8BYTES = 23; const int128_t minInt128 = int128_t(0x8000000000000000LL) << 64; const int128_t maxInt128 = (int128_t(0x7FFFFFFFFFFFFFFFLL) << 64) + 0xFFFFFFFFFFFFFFFFLL; - inline bool isWideDecimalNullValue(const int128_t& val) - { - const uint64_t* ptr = reinterpret_cast(&val); - return (ptr[0] == BINARYNULLVALUELOW && ptr[1] == BINARYNULLVALUEHIGH); - } - - inline bool isWideDecimalEmptyValue(const int128_t& val) - { - const uint64_t* ptr = reinterpret_cast(&val); - return (ptr[0] == BINARYEMPTYVALUELOW && ptr[1] == BINARYEMPTYVALUEHIGH); - } - - inline void setWideDecimalNullValue(int128_t& val) - { - uint64_t* ptr = reinterpret_cast(&val); - ptr[0] = BINARYNULLVALUELOW; - ptr[1] = BINARYNULLVALUEHIGH; - } - - inline void setWideDecimalEmptyValue(int128_t& val) - { - uint64_t* ptr = reinterpret_cast(&val); - ptr[0] = BINARYEMPTYVALUELOW; - ptr[1] = BINARYEMPTYVALUEHIGH; - } - - inline void setWideDecimalNullValue(int128_t* val) - { - uint64_t* ptr = reinterpret_cast(val); - ptr[0] = BINARYNULLVALUELOW; - ptr[1] = BINARYNULLVALUEHIGH; - } - - inline void setWideDecimalEmptyValue(int128_t* val) - { - uint64_t* ptr = reinterpret_cast(val); - ptr[0] = BINARYEMPTYVALUELOW; - ptr[1] = BINARYEMPTYVALUEHIGH; - } - inline void int128Max(int128_t& val) { uint64_t* ptr = reinterpret_cast(&val); diff --git a/utils/dataconvert/dataconvert.cpp b/utils/dataconvert/dataconvert.cpp index b7a0f9985..3651e990f 100644 --- a/utils/dataconvert/dataconvert.cpp +++ b/utils/dataconvert/dataconvert.cpp @@ -34,10 +34,8 @@ using namespace std; #include using namespace boost::algorithm; #include -#include "calpontsystemcatalog.h" #include "calpontselectexecutionplan.h" #include "columnresult.h" -using namespace execplan; #include "joblisttypes.h" @@ -109,7 +107,8 @@ namespace dataconvert template void number_int_value(const string& data, - const CalpontSystemCatalog::ColType& ct, + cscDataType typeCode, + const datatypes::SystemCatalog::TypeAttributesStd& ct, bool& pushwarning, bool noRoundup, T& intVal) @@ -298,9 +297,9 @@ void number_int_value(const string& data, if (frnVal != 0) pushwarning = true; - switch (ct.colDataType) + switch (typeCode) { - case CalpontSystemCatalog::TINYINT: + case datatypes::SystemCatalog::TINYINT: if (intVal < MIN_TINYINT) { intVal = MIN_TINYINT; @@ -314,7 +313,7 @@ void number_int_value(const string& data, break; - case CalpontSystemCatalog::SMALLINT: + case datatypes::SystemCatalog::SMALLINT: if (intVal < MIN_SMALLINT) { intVal = MIN_SMALLINT; @@ -328,7 +327,7 @@ void number_int_value(const string& data, break; - case CalpontSystemCatalog::MEDINT: + case datatypes::SystemCatalog::MEDINT: if (intVal < MIN_MEDINT) { intVal = MIN_MEDINT; @@ -342,7 +341,7 @@ void number_int_value(const string& data, break; - case CalpontSystemCatalog::INT: + case datatypes::SystemCatalog::INT: if (intVal < MIN_INT) { intVal = MIN_INT; @@ -356,7 +355,7 @@ void number_int_value(const string& data, break; - case CalpontSystemCatalog::BIGINT: + case datatypes::SystemCatalog::BIGINT: if (intVal < MIN_BIGINT) { intVal = MIN_BIGINT; @@ -365,8 +364,8 @@ void number_int_value(const string& data, break; - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::UDECIMAL: + case datatypes::SystemCatalog::DECIMAL: + case datatypes::SystemCatalog::UDECIMAL: if (LIKELY(ct.colWidth == 16)) { int128_t tmp; @@ -432,8 +431,8 @@ void number_int_value(const string& data, } // @ bug 3285 make sure the value is in precision range for decimal data type - if ( (ct.colDataType == CalpontSystemCatalog::DECIMAL) || - (ct.colDataType == CalpontSystemCatalog::UDECIMAL) || + if ( (typeCode == datatypes::SystemCatalog::DECIMAL) || + (typeCode == datatypes::SystemCatalog::UDECIMAL) || (ct.scale > 0)) { T rangeUp, rangeLow; @@ -467,20 +466,23 @@ void number_int_value(const string& data, // Explicit template instantiation template void number_int_value(const std::string& data, - const execplan::CalpontSystemCatalog::ColType& ct, + cscDataType typeCode, + const datatypes::SystemCatalog::TypeAttributesStd& ct, bool& pushwarning, bool noRoundup, int64_t& intVal); template void number_int_value(const std::string& data, - const execplan::CalpontSystemCatalog::ColType& ct, + cscDataType typeCode, + const datatypes::SystemCatalog::TypeAttributesStd& ct, bool& pushwarning, bool noRoundup, int128_t& intVal); uint64_t number_uint_value(const string& data, - const CalpontSystemCatalog::ColType& ct, + cscDataType typeCode, + const datatypes::SystemCatalog::TypeAttributesStd& ct, bool& pushwarning, bool noRoundup) { @@ -585,9 +587,9 @@ uint64_t number_uint_value(const string& data, if (frnVal != 0) pushwarning = true; - switch (ct.colDataType) + switch (typeCode) { - case CalpontSystemCatalog::UTINYINT: + case datatypes::SystemCatalog::UTINYINT: if (uintVal > MAX_UTINYINT) { uintVal = MAX_UTINYINT; @@ -596,7 +598,7 @@ uint64_t number_uint_value(const string& data, break; - case CalpontSystemCatalog::USMALLINT: + case datatypes::SystemCatalog::USMALLINT: if (uintVal > MAX_USMALLINT) { uintVal = MAX_USMALLINT; @@ -605,7 +607,7 @@ uint64_t number_uint_value(const string& data, break; - case CalpontSystemCatalog::UMEDINT: + case datatypes::SystemCatalog::UMEDINT: if (uintVal > MAX_UMEDINT) { uintVal = MAX_UMEDINT; @@ -614,7 +616,7 @@ uint64_t number_uint_value(const string& data, break; - case CalpontSystemCatalog::UINT: + case datatypes::SystemCatalog::UINT: if (uintVal > MAX_UINT) { uintVal = MAX_UINT; @@ -623,7 +625,7 @@ uint64_t number_uint_value(const string& data, break; - case CalpontSystemCatalog::UBIGINT: + case datatypes::SystemCatalog::UBIGINT: if (uintVal > MAX_UBIGINT) { uintVal = MAX_UBIGINT; @@ -1338,7 +1340,8 @@ void DataConvert::decimalToString(int128_t* dec, char* original_p = p; size_t written = 0; // Raise exception on NULL and EMPTY value - if (utils::isWideDecimalNullValue(*dec) || utils::isWideDecimalEmptyValue(*dec)) + if (datatypes::Decimal::isWideDecimalNullValue(*dec) || + datatypes::Decimal::isWideDecimalEmptyValue(*dec)) { throw QueryDataExcept("toString() char buffer overflow.", formatErr); } @@ -1370,7 +1373,8 @@ void DataConvert::decimalToString(int128_t* dec, } boost::any -DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, +DataConvert::convertColumnData(cscDataType typeCode, + const datatypes::SystemCatalog::TypeAttributesStd& colType, const std::string& dataOrig, bool& pushWarning, const std::string& timeZone, bool nulFlag, bool noRoundup, bool isUpdate) @@ -1380,14 +1384,13 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, // WIP std::string data( dataOrig ); pushWarning = false; - cscDataType type = colType.colDataType; //if ( !data.empty() ) if (!nulFlag) { - switch (type) + switch (typeCode) { - case CalpontSystemCatalog::BIT: + case datatypes::SystemCatalog::BIT: { unsigned int x = data.find("("); @@ -1405,7 +1408,7 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, int64_t tmp = 0; - number_int_value (data, colType, pushWarning, noRoundup, tmp); + number_int_value (data, typeCode, colType, pushWarning, noRoundup, tmp); if (tmp) { @@ -1423,52 +1426,52 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } break; - case CalpontSystemCatalog::TINYINT: - number_int_value(data, colType, pushWarning, noRoundup, val64); + case datatypes::SystemCatalog::TINYINT: + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); value = (char) val64; break; - case CalpontSystemCatalog::SMALLINT: - number_int_value(data, colType, pushWarning, noRoundup, val64); + case datatypes::SystemCatalog::SMALLINT: + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); value = (short) val64; break; - case CalpontSystemCatalog::MEDINT: - case CalpontSystemCatalog::INT: - number_int_value(data, colType, pushWarning, noRoundup, val64); + case datatypes::SystemCatalog::MEDINT: + case datatypes::SystemCatalog::INT: + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); value = (int) val64; break; - case CalpontSystemCatalog::BIGINT: - number_int_value(data, colType, pushWarning, noRoundup, val64); + case datatypes::SystemCatalog::BIGINT: + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); value = (long long) val64; break; - case CalpontSystemCatalog::DECIMAL: + case datatypes::SystemCatalog::DECIMAL: if (LIKELY(colType.colWidth == 16)) { int128_t val128; - number_int_value(data, colType, pushWarning, noRoundup, val128); + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val128); value = (int128_t) val128; } else if (colType.colWidth == 8) { - number_int_value(data, colType, pushWarning, noRoundup, val64); + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); value = (long long) val64; } else if (colType.colWidth == 4) { - number_int_value(data, colType, pushWarning, noRoundup, val64); + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); value = (int) val64; } else if (colType.colWidth == 2) { - number_int_value(data, colType, pushWarning, noRoundup, val64); + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); value = (short) val64; } else if (colType.colWidth == 1) { - number_int_value(data, colType, pushWarning, noRoundup, val64); + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); value = (char) val64; } //else if (colType.colWidth == 32) @@ -1476,17 +1479,17 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, break; - case CalpontSystemCatalog::UDECIMAL: + case datatypes::SystemCatalog::UDECIMAL: // UDECIMAL numbers may not be negative if (LIKELY(colType.colWidth == 16)) { int128_t val128; - number_int_value(data, colType, pushWarning, noRoundup, val128); + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val128); if (val128 < 0 && - !utils::isWideDecimalNullValue(val128) && - !utils::isWideDecimalEmptyValue(val128)) + !datatypes::Decimal::isWideDecimalNullValue(val128) && + !datatypes::Decimal::isWideDecimalEmptyValue(val128)) { val128 = 0; pushWarning = true; @@ -1496,7 +1499,7 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } else if (colType.colWidth == 8) { - number_int_value(data, colType, pushWarning, noRoundup, val64); + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); long long ival = static_cast(val64); if (ival < 0 && @@ -1511,7 +1514,7 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } else if (colType.colWidth == 4) { - number_int_value(data, colType, pushWarning, noRoundup, val64); + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); int ival = static_cast(val64); if (ival < 0 && @@ -1526,7 +1529,7 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } else if (colType.colWidth == 2) { - number_int_value(data, colType, pushWarning, noRoundup, val64); + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); short ival = (short) val64; if (ival < 0 && @@ -1541,7 +1544,7 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } else if (colType.colWidth == 1) { - number_int_value(data, colType, pushWarning, noRoundup, val64); + number_int_value(data, typeCode, colType, pushWarning, noRoundup, val64); char ival = (char) val64; if (ival < 0 && @@ -1557,8 +1560,8 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, break; - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::UFLOAT: + case datatypes::SystemCatalog::FLOAT: + case datatypes::SystemCatalog::UFLOAT: { string::size_type x = data.find('('); @@ -1615,8 +1618,10 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, floatvalue = 0; } - if (floatvalue < 0.0 && type == CalpontSystemCatalog::UFLOAT && - floatvalue != joblist::FLOATEMPTYROW && floatvalue != joblist::FLOATNULL) + if (floatvalue < 0.0 && + typeCode == datatypes::SystemCatalog::UFLOAT && + floatvalue != joblist::FLOATEMPTYROW && + floatvalue != joblist::FLOATNULL) { value = 0.0; pushWarning = true; @@ -1629,8 +1634,8 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } break; - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UDOUBLE: + case datatypes::SystemCatalog::DOUBLE: + case datatypes::SystemCatalog::UDOUBLE: { string::size_type x = data.find('('); @@ -1669,8 +1674,10 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, else value = doublevalue; - if (doublevalue < 0.0 && type == CalpontSystemCatalog::UDOUBLE && - doublevalue != joblist::DOUBLEEMPTYROW && doublevalue != joblist::DOUBLENULL) + if (doublevalue < 0.0 && + typeCode == datatypes::SystemCatalog::UDOUBLE && + doublevalue != joblist::DOUBLEEMPTYROW && + doublevalue != joblist::DOUBLENULL) { doublevalue = 0.0; pushWarning = true; @@ -1683,26 +1690,26 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } break; - case CalpontSystemCatalog::UTINYINT: - value = (uint8_t)number_uint_value(data, colType, pushWarning, noRoundup); + case datatypes::SystemCatalog::UTINYINT: + value = (uint8_t)number_uint_value(data, typeCode, colType, pushWarning, noRoundup); break; - case CalpontSystemCatalog::USMALLINT: - value = (uint16_t)number_uint_value(data, colType, pushWarning, noRoundup); + case datatypes::SystemCatalog::USMALLINT: + value = (uint16_t)number_uint_value(data, typeCode, colType, pushWarning, noRoundup); break; - case CalpontSystemCatalog::UMEDINT: - case CalpontSystemCatalog::UINT: - value = (uint32_t)number_uint_value(data, colType, pushWarning, noRoundup); + case datatypes::SystemCatalog::UMEDINT: + case datatypes::SystemCatalog::UINT: + value = (uint32_t)number_uint_value(data, typeCode, colType, pushWarning, noRoundup); break; - case CalpontSystemCatalog::UBIGINT: - value = (uint64_t)number_uint_value(data, colType, pushWarning, noRoundup); + case datatypes::SystemCatalog::UBIGINT: + value = (uint64_t)number_uint_value(data, typeCode, colType, pushWarning, noRoundup); break; - case CalpontSystemCatalog::CHAR: - case CalpontSystemCatalog::VARCHAR: - case CalpontSystemCatalog::TEXT: + case datatypes::SystemCatalog::CHAR: + case datatypes::SystemCatalog::VARCHAR: + case datatypes::SystemCatalog::TEXT: { //check data length if ( data.length() > (unsigned int)colType.colWidth ) @@ -1723,7 +1730,7 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } break; - case CalpontSystemCatalog::DATE: + case datatypes::SystemCatalog::DATE: { Date aDay; @@ -1739,7 +1746,7 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } break; - case CalpontSystemCatalog::DATETIME: + case datatypes::SystemCatalog::DATETIME: { DateTime aDatetime; @@ -1755,7 +1762,7 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } break; - case CalpontSystemCatalog::TIME: + case datatypes::SystemCatalog::TIME: { Time aTime; @@ -1768,7 +1775,7 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } break; - case CalpontSystemCatalog::TIMESTAMP: + case datatypes::SystemCatalog::TIMESTAMP: { TimeStamp aTimestamp; @@ -1781,16 +1788,16 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } break; - case CalpontSystemCatalog::BLOB: - case CalpontSystemCatalog::CLOB: + case datatypes::SystemCatalog::BLOB: + case datatypes::SystemCatalog::CLOB: value = data; break; - case CalpontSystemCatalog::VARBINARY: + case datatypes::SystemCatalog::VARBINARY: value = data; break; - case CalpontSystemCatalog::BINARY: + case datatypes::SystemCatalog::BINARY: value = data; break; @@ -1801,241 +1808,11 @@ DataConvert::convertColumnData(const CalpontSystemCatalog::ColType& colType, } else //null { - switch (type) - { - case CalpontSystemCatalog::BIT: - { - //TODO: How to communicate with write engine? - } - break; - - case CalpontSystemCatalog::TINYINT: - { - char tinyintvalue = joblist::TINYINTNULL; - value = tinyintvalue; - } - break; - - case CalpontSystemCatalog::SMALLINT: - { - short smallintvalue = joblist::SMALLINTNULL; - value = smallintvalue; - } - break; - - case CalpontSystemCatalog::MEDINT: - case CalpontSystemCatalog::INT: - { - int intvalue = joblist::INTNULL; - value = intvalue; - } - break; - - case CalpontSystemCatalog::BIGINT: - { - long long bigint = joblist::BIGINTNULL; - value = bigint; - } - break; - - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::UDECIMAL: - { - if (LIKELY(colType.colWidth == 16)) - { - int128_t val; - utils::setWideDecimalNullValue(val); - value = val; - } - else if (colType.colWidth == CalpontSystemCatalog::EIGHT_BYTE) - { - long long eightbyte = joblist::BIGINTNULL; - value = eightbyte; - } - else if (colType.colWidth == CalpontSystemCatalog::FOUR_BYTE) - { - int intvalue = joblist::INTNULL; - value = intvalue; - } - else if (colType.colWidth == CalpontSystemCatalog::TWO_BYTE) - { - short smallintvalue = joblist::SMALLINTNULL; - value = smallintvalue; - } - else if (colType.colWidth == CalpontSystemCatalog::ONE_BYTE) - { - char tinyintvalue = joblist::TINYINTNULL; - value = tinyintvalue; - } - else - { - WriteEngine::Token nullToken; - value = nullToken; - } - } - break; - - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::UFLOAT: - { - uint32_t tmp = joblist::FLOATNULL; - float* floatvalue = (float*)&tmp; - value = *floatvalue; - } - break; - - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UDOUBLE: - { - uint64_t tmp = joblist::DOUBLENULL; - double* doublevalue = (double*)&tmp; - value = *doublevalue; - } - break; - - case CalpontSystemCatalog::DATE: - { - uint32_t d = joblist::DATENULL; - value = d; - } - break; - - case CalpontSystemCatalog::DATETIME: - { - uint64_t d = joblist::DATETIMENULL; - value = d; - } - break; - - case CalpontSystemCatalog::TIMESTAMP: - { - uint64_t d = joblist::TIMESTAMPNULL; - value = d; - } - break; - - case CalpontSystemCatalog::TIME: - { - uint64_t d = joblist::TIMENULL; - value = d; - } - break; - - case CalpontSystemCatalog::CHAR: - { - std::string charnull; - - if (colType.colWidth == 1) - { - //charnull = joblist::CHAR1NULL; - charnull = '\376'; - value = charnull; - } - else if (colType.colWidth == 2) - { - //charnull = joblist::CHAR2NULL; - charnull = "\377\376"; - value = charnull; - } - else if (( colType.colWidth < 5 ) && ( colType.colWidth > 2 )) - { - //charnull = joblist::CHAR4NULL; - charnull = "\377\377\377\376"; - value = charnull; - } - else if (( colType.colWidth < 9 ) && ( colType.colWidth > 4 )) - { - //charnull = joblist::CHAR8NULL; - charnull = "\377\377\377\377\377\377\377\376"; - value = charnull; - } - else - { - WriteEngine::Token nullToken; - value = nullToken; - } - } - break; - - case CalpontSystemCatalog::VARCHAR: - case CalpontSystemCatalog::TEXT: - { - std::string charnull; - - if (colType.colWidth == 1 ) - { - //charnull = joblist::CHAR2NULL; - charnull = "\377\376"; - value = charnull; - } - else if ((colType.colWidth < 4) && (colType.colWidth > 1)) - { - //charnull = joblist::CHAR4NULL; - charnull = "\377\377\377\376"; - value = charnull; - } - else if ((colType.colWidth < 8) && (colType.colWidth > 3)) - { - //charnull = joblist::CHAR8NULL; - charnull = "\377\377\377\377\377\377\377\376"; - value = charnull; - } - else if ( colType.colWidth > 7 ) - { - WriteEngine::Token nullToken; - value = nullToken; - } - } - break; - - case CalpontSystemCatalog::VARBINARY: - case CalpontSystemCatalog::BLOB: - { - WriteEngine::Token nullToken; - value = nullToken; - } - break; - - case CalpontSystemCatalog::BINARY: - { - value = data; - } - break; - - case CalpontSystemCatalog::UTINYINT: - { - uint8_t utinyintvalue = joblist::UTINYINTNULL; - value = utinyintvalue; - } - break; - - case CalpontSystemCatalog::USMALLINT: - { - uint16_t usmallintvalue = joblist::USMALLINTNULL; - value = usmallintvalue; - } - break; - - case CalpontSystemCatalog::UMEDINT: - case CalpontSystemCatalog::UINT: - { - uint32_t uintvalue = joblist::UINTNULL; - value = uintvalue; - } - break; - - case CalpontSystemCatalog::UBIGINT: - { - uint64_t ubigint = joblist::UBIGINTNULL; - value = ubigint; - } - break; - - default: - throw QueryDataExcept("convertColumnData: unknown column data type.", dataTypeErr); - break; - - } + const datatypes::TypeHandler *h= datatypes::TypeHandler::find(typeCode, colType); + if (!h) + throw QueryDataExcept("convertColumnData: unknown column data type.", dataTypeErr); + else + return h->getNullValueForType(colType); } return value; @@ -3349,441 +3126,435 @@ int64_t DataConvert::stringToTime(const string& data) return *(reinterpret_cast(&atime)); } -CalpontSystemCatalog::ColType DataConvert::convertUnionColType(vector& types) + +void +DataConvert::joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd &unionedType, + const datatypes::SystemCatalog::TypeHolderStd &type) { - idbassert(types.size()); - - CalpontSystemCatalog::ColType unionedType = types[0]; - - for (uint64_t i = 1; i < types.size(); i++) + // limited support for VARBINARY, no implicit conversion. + if (type.colDataType == datatypes::SystemCatalog::VARBINARY || + unionedType.colDataType == datatypes::SystemCatalog::VARBINARY) { - // limited support for VARBINARY, no implicit conversion. - if (types[i].colDataType == CalpontSystemCatalog::VARBINARY || - unionedType.colDataType == CalpontSystemCatalog::VARBINARY) + if (type.colDataType != unionedType.colDataType || + type.colWidth != unionedType.colWidth) + throw runtime_error("VARBINARY in UNION must be the same width."); + } + + switch (type.colDataType) + { + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::SMALLINT: + case datatypes::SystemCatalog::MEDINT: + case datatypes::SystemCatalog::INT: + case datatypes::SystemCatalog::BIGINT: + case datatypes::SystemCatalog::DECIMAL: + case datatypes::SystemCatalog::UTINYINT: + case datatypes::SystemCatalog::USMALLINT: + case datatypes::SystemCatalog::UMEDINT: + case datatypes::SystemCatalog::UINT: + case datatypes::SystemCatalog::UBIGINT: + case datatypes::SystemCatalog::UDECIMAL: { - if (types[i].colDataType != unionedType.colDataType || - types[i].colWidth != unionedType.colWidth) - throw runtime_error("VARBINARY in UNION must be the same width."); + switch (unionedType.colDataType) + { + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::SMALLINT: + case datatypes::SystemCatalog::MEDINT: + case datatypes::SystemCatalog::INT: + case datatypes::SystemCatalog::BIGINT: + case datatypes::SystemCatalog::DECIMAL: + case datatypes::SystemCatalog::UTINYINT: + case datatypes::SystemCatalog::USMALLINT: + case datatypes::SystemCatalog::UMEDINT: + case datatypes::SystemCatalog::UINT: + case datatypes::SystemCatalog::UBIGINT: + case datatypes::SystemCatalog::UDECIMAL: + if (type.colWidth > unionedType.colWidth) + { + unionedType.colDataType = type.colDataType; + unionedType.colWidth = type.colWidth; + } + + // If same size and result is signed but source is unsigned... + if (type.colWidth == unionedType.colWidth && !isUnsigned(unionedType.colDataType) && isUnsigned(type.colDataType)) + { + unionedType.colDataType = type.colDataType; + } + + if (type.colDataType == datatypes::SystemCatalog::DECIMAL || type.colDataType == datatypes::SystemCatalog::UDECIMAL) + { + unionedType.colDataType = datatypes::SystemCatalog::DECIMAL; + } + + unionedType.scale = (type.scale > unionedType.scale) ? type.scale : unionedType.scale; + break; + + case datatypes::SystemCatalog::DATE: + unionedType.colDataType = datatypes::SystemCatalog::CHAR; + unionedType.colWidth = 20; + break; + + case datatypes::SystemCatalog::TIME: + case datatypes::SystemCatalog::DATETIME: + case datatypes::SystemCatalog::TIMESTAMP: + unionedType.colDataType = datatypes::SystemCatalog::CHAR; + unionedType.colWidth = 26; + break; + + case datatypes::SystemCatalog::CHAR: + if (unionedType.colWidth < 20) + unionedType.colWidth = 20; + + break; + + case datatypes::SystemCatalog::VARCHAR: + if (unionedType.colWidth < 21) + unionedType.colWidth = 21; + + break; + + case datatypes::SystemCatalog::FLOAT: + case datatypes::SystemCatalog::DOUBLE: + case datatypes::SystemCatalog::UFLOAT: + case datatypes::SystemCatalog::UDOUBLE: + case datatypes::SystemCatalog::LONGDOUBLE: + default: + break; + } + + break; } - switch (types[i].colDataType) + case datatypes::SystemCatalog::DATE: { - 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: + switch (unionedType.colDataType) { - switch (unionedType.colDataType) - { - 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: - if (types[i].colWidth > unionedType.colWidth) - { - unionedType.colDataType = types[i].colDataType; - unionedType.colWidth = types[i].colWidth; - } + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::SMALLINT: + 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: + case datatypes::SystemCatalog::USMALLINT: + 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: + unionedType.colDataType = datatypes::SystemCatalog::CHAR; + unionedType.scale = 0; + unionedType.colWidth = 20; + break; - // If same size and result is signed but source is unsigned... - if (types[i].colWidth == unionedType.colWidth && !isUnsigned(unionedType.colDataType) && isUnsigned(types[i].colDataType)) - { - unionedType.colDataType = types[i].colDataType; - } + case datatypes::SystemCatalog::CHAR: + if (unionedType.colWidth < 10) + unionedType.colWidth = 10; - if (types[i].colDataType == CalpontSystemCatalog::DECIMAL || types[i].colDataType == CalpontSystemCatalog::UDECIMAL) - { - unionedType.colDataType = CalpontSystemCatalog::DECIMAL; - } + break; - unionedType.scale = (types[i].scale > unionedType.scale) ? types[i].scale : unionedType.scale; - break; + case datatypes::SystemCatalog::VARCHAR: + if (unionedType.colWidth < 11) + unionedType.colWidth = 11; - case CalpontSystemCatalog::DATE: - unionedType.colDataType = CalpontSystemCatalog::CHAR; + break; + + case datatypes::SystemCatalog::DATE: + case datatypes::SystemCatalog::DATETIME: + case datatypes::SystemCatalog::TIMESTAMP: + case datatypes::SystemCatalog::TIME: + default: + break; + } + + break; + } + + case datatypes::SystemCatalog::DATETIME: + { + switch (unionedType.colDataType) + { + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::SMALLINT: + 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: + case datatypes::SystemCatalog::USMALLINT: + 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::TIME: + case datatypes::SystemCatalog::LONGDOUBLE: + case datatypes::SystemCatalog::TIMESTAMP: + unionedType.colDataType = datatypes::SystemCatalog::CHAR; + unionedType.scale = 0; + unionedType.colWidth = 26; + break; + + case datatypes::SystemCatalog::DATE: + unionedType.colDataType = datatypes::SystemCatalog::DATETIME; + unionedType.colWidth = type.colWidth; + break; + + case datatypes::SystemCatalog::CHAR: + if (unionedType.colWidth < 26) + unionedType.colWidth = 26; + + break; + + case datatypes::SystemCatalog::VARCHAR: + if (unionedType.colWidth < 27) + unionedType.colWidth = 27; + + break; + + case datatypes::SystemCatalog::DATETIME: + default: + break; + } + + break; + } + + case datatypes::SystemCatalog::TIMESTAMP: + { + switch (unionedType.colDataType) + { + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::SMALLINT: + 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: + case datatypes::SystemCatalog::USMALLINT: + 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::TIME: + case datatypes::SystemCatalog::DATETIME: + unionedType.colDataType = datatypes::SystemCatalog::CHAR; + unionedType.scale = 0; + unionedType.colWidth = 26; + break; + + case datatypes::SystemCatalog::DATE: + unionedType.colDataType = datatypes::SystemCatalog::TIMESTAMP; + unionedType.colWidth = type.colWidth; + break; + + case datatypes::SystemCatalog::CHAR: + if (unionedType.colWidth < 26) + unionedType.colWidth = 26; + + break; + + case datatypes::SystemCatalog::VARCHAR: + if (unionedType.colWidth < 27) + unionedType.colWidth = 27; + + break; + + case datatypes::SystemCatalog::TIMESTAMP: + default: + break; + } + + break; + } + + case datatypes::SystemCatalog::FLOAT: + case datatypes::SystemCatalog::DOUBLE: + case datatypes::SystemCatalog::UFLOAT: + case datatypes::SystemCatalog::UDOUBLE: + { + switch (unionedType.colDataType) + { + case datatypes::SystemCatalog::DATE: + unionedType.colDataType = datatypes::SystemCatalog::CHAR; + unionedType.scale = 0; + unionedType.colWidth = 20; + break; + + case datatypes::SystemCatalog::DATETIME: + case datatypes::SystemCatalog::TIMESTAMP: + unionedType.colDataType = datatypes::SystemCatalog::CHAR; + unionedType.scale = 0; + unionedType.colWidth = 26; + break; + + case datatypes::SystemCatalog::CHAR: + if (unionedType.colWidth < 20) unionedType.colWidth = 20; - break; - case CalpontSystemCatalog::TIME: - case CalpontSystemCatalog::DATETIME: - case CalpontSystemCatalog::TIMESTAMP: - unionedType.colDataType = CalpontSystemCatalog::CHAR; - unionedType.colWidth = 26; - break; + break; - case CalpontSystemCatalog::CHAR: - if (unionedType.colWidth < 20) - unionedType.colWidth = 20; + case datatypes::SystemCatalog::VARCHAR: + if (unionedType.colWidth < 21) + unionedType.colWidth = 21; - break; + break; - case CalpontSystemCatalog::VARCHAR: - if (unionedType.colWidth < 21) - unionedType.colWidth = 21; + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::SMALLINT: + 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: + case datatypes::SystemCatalog::USMALLINT: + 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; + unionedType.scale = 0; + unionedType.colWidth = sizeof(double); + break; - break; - - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UFLOAT: - case CalpontSystemCatalog::UDOUBLE: - case CalpontSystemCatalog::LONGDOUBLE: - default: - break; - } - - break; + default: + break; } - case CalpontSystemCatalog::DATE: + break; + } + + case datatypes::SystemCatalog::LONGDOUBLE: + { + switch (unionedType.colDataType) { - switch (unionedType.colDataType) - { - case CalpontSystemCatalog::TINYINT: - case CalpontSystemCatalog::SMALLINT: - case CalpontSystemCatalog::MEDINT: - case CalpontSystemCatalog::INT: - case CalpontSystemCatalog::BIGINT: - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UTINYINT: - case CalpontSystemCatalog::USMALLINT: - case CalpontSystemCatalog::UMEDINT: - case CalpontSystemCatalog::UINT: - case CalpontSystemCatalog::UBIGINT: - case CalpontSystemCatalog::UDECIMAL: - case CalpontSystemCatalog::UFLOAT: - case CalpontSystemCatalog::UDOUBLE: - case CalpontSystemCatalog::LONGDOUBLE: - unionedType.colDataType = CalpontSystemCatalog::CHAR; - unionedType.scale = 0; + case datatypes::SystemCatalog::DATE: + unionedType.colDataType = datatypes::SystemCatalog::CHAR; + unionedType.scale = 0; + unionedType.colWidth = 20; + break; + + case datatypes::SystemCatalog::DATETIME: + unionedType.colDataType = datatypes::SystemCatalog::CHAR; + unionedType.scale = 0; + unionedType.colWidth = 26; + break; + + case datatypes::SystemCatalog::CHAR: + if (unionedType.colWidth < 20) unionedType.colWidth = 20; - break; - case CalpontSystemCatalog::CHAR: - if (unionedType.colWidth < 10) - unionedType.colWidth = 10; + break; - break; + case datatypes::SystemCatalog::VARCHAR: + if (unionedType.colWidth < 21) + unionedType.colWidth = 21; - case CalpontSystemCatalog::VARCHAR: - if (unionedType.colWidth < 11) - unionedType.colWidth = 11; + break; - break; + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::SMALLINT: + 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: + case datatypes::SystemCatalog::USMALLINT: + 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: + unionedType.colDataType = datatypes::SystemCatalog::LONGDOUBLE; + unionedType.scale = (type.scale > unionedType.scale) ? type.scale : unionedType.scale; + unionedType.colWidth = sizeof(long double); + unionedType.precision = -1; + break; - case CalpontSystemCatalog::DATE: - case CalpontSystemCatalog::DATETIME: - case CalpontSystemCatalog::TIMESTAMP: - case CalpontSystemCatalog::TIME: - default: - break; - } - - break; + default: + break; } - case CalpontSystemCatalog::DATETIME: + break; + } + + case datatypes::SystemCatalog::CHAR: + case datatypes::SystemCatalog::VARCHAR: + { + switch (unionedType.colDataType) { - switch (unionedType.colDataType) - { - case CalpontSystemCatalog::TINYINT: - case CalpontSystemCatalog::SMALLINT: - case CalpontSystemCatalog::MEDINT: - case CalpontSystemCatalog::INT: - case CalpontSystemCatalog::BIGINT: - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UTINYINT: - case CalpontSystemCatalog::USMALLINT: - case CalpontSystemCatalog::UMEDINT: - case CalpontSystemCatalog::UINT: - case CalpontSystemCatalog::UBIGINT: - case CalpontSystemCatalog::UDECIMAL: - case CalpontSystemCatalog::UFLOAT: - case CalpontSystemCatalog::UDOUBLE: - case CalpontSystemCatalog::TIME: - case CalpontSystemCatalog::LONGDOUBLE: - case CalpontSystemCatalog::TIMESTAMP: - unionedType.colDataType = CalpontSystemCatalog::CHAR; - unionedType.scale = 0; - unionedType.colWidth = 26; - break; + case datatypes::SystemCatalog::TINYINT: + case datatypes::SystemCatalog::SMALLINT: + 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: + case datatypes::SystemCatalog::USMALLINT: + 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: + unionedType.scale = 0; + unionedType.colWidth = (type.colWidth > 20) ? type.colWidth : 20; + break; - case CalpontSystemCatalog::DATE: - unionedType.colDataType = CalpontSystemCatalog::DATETIME; - unionedType.colWidth = types[i].colWidth; - break; + case datatypes::SystemCatalog::DATE: + unionedType.colWidth = (type.colWidth > 10) ? type.colWidth : 10; + break; - case CalpontSystemCatalog::CHAR: - if (unionedType.colWidth < 26) - unionedType.colWidth = 26; + case datatypes::SystemCatalog::DATETIME: + case datatypes::SystemCatalog::TIMESTAMP: + unionedType.colWidth = (type.colWidth > 26) ? type.colWidth : 26; + break; - break; + case datatypes::SystemCatalog::CHAR: + case datatypes::SystemCatalog::VARCHAR: - case CalpontSystemCatalog::VARCHAR: - if (unionedType.colWidth < 27) - unionedType.colWidth = 27; + // VARCHAR will fit in CHAR of the same width + if (unionedType.colWidth < type.colWidth) + unionedType.colWidth = type.colWidth; - break; + break; - case CalpontSystemCatalog::DATETIME: - default: - break; - } - - break; + default: + break; } - case CalpontSystemCatalog::TIMESTAMP: - { - switch (unionedType.colDataType) - { - case CalpontSystemCatalog::TINYINT: - case CalpontSystemCatalog::SMALLINT: - case CalpontSystemCatalog::MEDINT: - case CalpontSystemCatalog::INT: - case CalpontSystemCatalog::BIGINT: - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UTINYINT: - case CalpontSystemCatalog::USMALLINT: - case CalpontSystemCatalog::UMEDINT: - case CalpontSystemCatalog::UINT: - case CalpontSystemCatalog::UBIGINT: - case CalpontSystemCatalog::UDECIMAL: - case CalpontSystemCatalog::UFLOAT: - case CalpontSystemCatalog::UDOUBLE: - case CalpontSystemCatalog::TIME: - case CalpontSystemCatalog::DATETIME: - unionedType.colDataType = CalpontSystemCatalog::CHAR; - unionedType.scale = 0; - unionedType.colWidth = 26; - break; + // MariaDB bug 651. Setting to CHAR broke union in subquery + unionedType.colDataType = datatypes::SystemCatalog::VARCHAR; + break; + } - case CalpontSystemCatalog::DATE: - unionedType.colDataType = CalpontSystemCatalog::TIMESTAMP; - unionedType.colWidth = types[i].colWidth; - break; - - case CalpontSystemCatalog::CHAR: - if (unionedType.colWidth < 26) - unionedType.colWidth = 26; - - break; - - case CalpontSystemCatalog::VARCHAR: - if (unionedType.colWidth < 27) - unionedType.colWidth = 27; - - break; - - case CalpontSystemCatalog::TIMESTAMP: - default: - break; - } - - break; - } - - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UFLOAT: - case CalpontSystemCatalog::UDOUBLE: - { - switch (unionedType.colDataType) - { - case CalpontSystemCatalog::DATE: - unionedType.colDataType = CalpontSystemCatalog::CHAR; - unionedType.scale = 0; - unionedType.colWidth = 20; - break; - - case CalpontSystemCatalog::DATETIME: - case CalpontSystemCatalog::TIMESTAMP: - unionedType.colDataType = CalpontSystemCatalog::CHAR; - unionedType.scale = 0; - unionedType.colWidth = 26; - break; - - case CalpontSystemCatalog::CHAR: - if (unionedType.colWidth < 20) - unionedType.colWidth = 20; - - break; - - case CalpontSystemCatalog::VARCHAR: - if (unionedType.colWidth < 21) - unionedType.colWidth = 21; - - break; - - case CalpontSystemCatalog::TINYINT: - case CalpontSystemCatalog::SMALLINT: - case CalpontSystemCatalog::MEDINT: - case CalpontSystemCatalog::INT: - case CalpontSystemCatalog::BIGINT: - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UTINYINT: - case CalpontSystemCatalog::USMALLINT: - case CalpontSystemCatalog::UMEDINT: - case CalpontSystemCatalog::UINT: - case CalpontSystemCatalog::UBIGINT: - case CalpontSystemCatalog::UDECIMAL: - case CalpontSystemCatalog::UFLOAT: - case CalpontSystemCatalog::UDOUBLE: - unionedType.colDataType = CalpontSystemCatalog::DOUBLE; - unionedType.scale = 0; - unionedType.colWidth = sizeof(double); - break; - - default: - break; - } - - break; - } - - case CalpontSystemCatalog::LONGDOUBLE: - { - switch (unionedType.colDataType) - { - case CalpontSystemCatalog::DATE: - unionedType.colDataType = CalpontSystemCatalog::CHAR; - unionedType.scale = 0; - unionedType.colWidth = 20; - break; - - case CalpontSystemCatalog::DATETIME: - unionedType.colDataType = CalpontSystemCatalog::CHAR; - unionedType.scale = 0; - unionedType.colWidth = 26; - break; - - case CalpontSystemCatalog::CHAR: - if (unionedType.colWidth < 20) - unionedType.colWidth = 20; - - break; - - case CalpontSystemCatalog::VARCHAR: - if (unionedType.colWidth < 21) - unionedType.colWidth = 21; - - break; - - case CalpontSystemCatalog::TINYINT: - case CalpontSystemCatalog::SMALLINT: - case CalpontSystemCatalog::MEDINT: - case CalpontSystemCatalog::INT: - case CalpontSystemCatalog::BIGINT: - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UTINYINT: - case CalpontSystemCatalog::USMALLINT: - case CalpontSystemCatalog::UMEDINT: - case CalpontSystemCatalog::UINT: - case CalpontSystemCatalog::UBIGINT: - case CalpontSystemCatalog::UDECIMAL: - case CalpontSystemCatalog::UFLOAT: - case CalpontSystemCatalog::UDOUBLE: - case CalpontSystemCatalog::LONGDOUBLE: - unionedType.colDataType = CalpontSystemCatalog::LONGDOUBLE; - unionedType.scale = (types[i].scale > unionedType.scale) ? types[i].scale : unionedType.scale; - unionedType.colWidth = sizeof(long double); - unionedType.precision = -1; - break; - - default: - break; - } - - break; - } - - case CalpontSystemCatalog::CHAR: - case CalpontSystemCatalog::VARCHAR: - { - switch (unionedType.colDataType) - { - case CalpontSystemCatalog::TINYINT: - case CalpontSystemCatalog::SMALLINT: - case CalpontSystemCatalog::MEDINT: - case CalpontSystemCatalog::INT: - case CalpontSystemCatalog::BIGINT: - case CalpontSystemCatalog::DECIMAL: - case CalpontSystemCatalog::FLOAT: - case CalpontSystemCatalog::DOUBLE: - case CalpontSystemCatalog::UTINYINT: - case CalpontSystemCatalog::USMALLINT: - case CalpontSystemCatalog::UMEDINT: - case CalpontSystemCatalog::UINT: - case CalpontSystemCatalog::UBIGINT: - case CalpontSystemCatalog::UDECIMAL: - case CalpontSystemCatalog::UFLOAT: - case CalpontSystemCatalog::UDOUBLE: - case CalpontSystemCatalog::LONGDOUBLE: - unionedType.scale = 0; - unionedType.colWidth = (types[i].colWidth > 20) ? types[i].colWidth : 20; - break; - - case CalpontSystemCatalog::DATE: - unionedType.colWidth = (types[i].colWidth > 10) ? types[i].colWidth : 10; - break; - - case CalpontSystemCatalog::DATETIME: - case CalpontSystemCatalog::TIMESTAMP: - unionedType.colWidth = (types[i].colWidth > 26) ? types[i].colWidth : 26; - break; - - case CalpontSystemCatalog::CHAR: - case CalpontSystemCatalog::VARCHAR: - - // VARCHAR will fit in CHAR of the same width - if (unionedType.colWidth < types[i].colWidth) - unionedType.colWidth = types[i].colWidth; - - break; - - default: - break; - } - - // MariaDB bug 651. Setting to CHAR broke union in subquery - unionedType.colDataType = CalpontSystemCatalog::VARCHAR; - break; - } - - default: - { - break; - } - } // switch - } // for - - return unionedType; + default: + { + break; + } + } // switch } } // namespace dataconvert diff --git a/utils/dataconvert/dataconvert.h b/utils/dataconvert/dataconvert.h index 2636919e0..4b1dfa96b 100644 --- a/utils/dataconvert/dataconvert.h +++ b/utils/dataconvert/dataconvert.h @@ -47,12 +47,11 @@ #include #endif -#include "calpontsystemcatalog.h" +#include "mcs_datatype.h" #include "columnresult.h" #include "exceptclasses.h" #include "common/branchpred.h" -#include "widedecimalutils.h" // remove this block if the htonll is defined in library #ifdef __linux__ @@ -87,7 +86,7 @@ inline uint64_t uint64ToStr(uint64_t n) return htonll(n); } -using cscDataType = execplan::CalpontSystemCatalog::ColDataType; +using cscDataType = datatypes::SystemCatalog::ColDataType; #if defined(_MSC_VER) && defined(xxxDATACONVERT_DLLEXPORT) #define EXPORT __declspec(dllexport) @@ -883,7 +882,8 @@ uint64_t string_to_ull( const std::string& data, bool& bSaturate ) template void number_int_value(const std::string& data, - const execplan::CalpontSystemCatalog::ColType& ct, + cscDataType typeCode, + const datatypes::SystemCatalog::TypeAttributesStd &ct, bool& pushwarning, bool noRoundup, T& intVal); @@ -901,7 +901,9 @@ public: * @param type the columns data type * @param data the columns string representation of it's data */ - EXPORT static boost::any convertColumnData( const execplan::CalpontSystemCatalog::ColType& colType, + EXPORT static boost::any convertColumnData( + cscDataType typecode, + const datatypes::SystemCatalog::TypeAttributesStd& attr, const std::string& dataOrig, bool& bSaturate, const std::string& timeZone, bool nulFlag = false, bool noRoundup = false, bool isUpdate = false); @@ -1046,7 +1048,6 @@ public: EXPORT static bool isColumnTimeValid( int64_t time ); EXPORT static bool isColumnTimeStampValid( int64_t timeStamp ); - EXPORT static bool isNullData(execplan::ColumnResult* cr, int rownum, execplan::CalpontSystemCatalog::ColType colType); static inline std::string decimalToString(int64_t value, uint8_t scale, cscDataType colDataType); static inline void decimalToString(int64_t value, uint8_t scale, char* buf, unsigned int buflen, cscDataType colDataType); @@ -1083,7 +1084,8 @@ public: EXPORT static int64_t timeToInt(const std::string& time); EXPORT static int64_t stringToTime (const std::string& data); // bug4388, union type conversion - EXPORT static execplan::CalpontSystemCatalog::ColType convertUnionColType(std::vector&); + EXPORT static void joinColTypeForUnion(datatypes::SystemCatalog::TypeHolderStd &unionedType, + const datatypes::SystemCatalog::TypeHolderStd &type); }; inline void DataConvert::dateToString( int datevalue, char* buf, unsigned int buflen) diff --git a/utils/funcexp/func_round.cpp b/utils/funcexp/func_round.cpp index 780b499b0..4e3ad260c 100644 --- a/utils/funcexp/func_round.cpp +++ b/utils/funcexp/func_round.cpp @@ -116,7 +116,7 @@ int64_t Func_round::getIntVal(Row& row, { IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct); - if (!datatypes::Decimal::isWideDecimalType(op_ct)) + if (!op_ct.isWideDecimalType()) { if (x.scale > 0) { @@ -207,7 +207,7 @@ double Func_round::getDoubleVal(Row& row, double d; - if (!datatypes::Decimal::isWideDecimalType(op_ct)) + if (!op_ct.isWideDecimalType()) d = x.value; else d = datatypes::Decimal::getDoubleFromWideDecimal(x.s128Value); @@ -274,7 +274,7 @@ long double Func_round::getLongDoubleVal(Row& row, double d; - if (!datatypes::Decimal::isWideDecimalType(op_ct)) + if (!op_ct.isWideDecimalType()) d = x.value; else d = datatypes::Decimal::getDoubleFromWideDecimal(x.s128Value); @@ -313,7 +313,7 @@ IDB_Decimal Func_round::getDecimalVal(Row& row, int64_t d = 0; decimal = parm[0]->data()->getDecimalVal(row, isNull); - if (!datatypes::Decimal::isWideDecimalType(op_ct)) + if (!op_ct.isWideDecimalType()) { //@Bug 3101 - GCC 4.5.1 optimizes too aggressively here. Mark as volatile. volatile int64_t p = 1; @@ -720,12 +720,12 @@ string Func_round::getStrVal(Row& row, break; } - if (!datatypes::Decimal::isWideDecimalType(op_ct)) + if (!op_ct.isWideDecimalType()) return dataconvert::DataConvert::decimalToString(x.value, x.scale, op_ct.colDataType); else { - char buf[utils::MAXLENGTH16BYTES]; - dataconvert::DataConvert::decimalToString( &x.s128Value, x.scale, buf, utils::MAXLENGTH16BYTES, op_ct.colDataType); + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; + dataconvert::DataConvert::decimalToString( &x.s128Value, x.scale, buf, (uint8_t) sizeof(buf), op_ct.colDataType); return string(buf); } } diff --git a/utils/funcexp/func_truncate.cpp b/utils/funcexp/func_truncate.cpp index d60fa6e70..9ab383774 100644 --- a/utils/funcexp/func_truncate.cpp +++ b/utils/funcexp/func_truncate.cpp @@ -119,7 +119,7 @@ int64_t Func_truncate::getIntVal(Row& row, { IDB_Decimal x = getDecimalVal(row, parm, isNull, op_ct); - if (!datatypes::Decimal::isWideDecimalType(op_ct)) + if (!op_ct.isWideDecimalType()) { if (x.scale > 0) { @@ -230,7 +230,7 @@ double Func_truncate::getDoubleVal(Row& row, double d; - if (!datatypes::Decimal::isWideDecimalType(op_ct)) + if (!op_ct.isWideDecimalType()) d = x.value; else d = datatypes::Decimal::getDoubleFromWideDecimal(x.s128Value); @@ -290,7 +290,7 @@ long double Func_truncate::getLongDoubleVal(Row& row, double d; - if (!datatypes::Decimal::isWideDecimalType(op_ct)) + if (!op_ct.isWideDecimalType()) d = x.value; else d = datatypes::Decimal::getDoubleFromWideDecimal(x.s128Value); @@ -334,7 +334,7 @@ IDB_Decimal Func_truncate::getDecimalVal(Row& row, int64_t d = 0; decimal = parm[0]->data()->getDecimalVal(row, isNull); - if (!datatypes::Decimal::isWideDecimalType(op_ct)) + if (!op_ct.isWideDecimalType()) { //@Bug 3101 - GCC 4.5.1 optimizes too aggressively here. Mark as volatile. volatile int64_t p = 1; @@ -739,12 +739,12 @@ string Func_truncate::getStrVal(Row& row, break; } - if (!datatypes::Decimal::isWideDecimalType(op_ct)) + if (!op_ct.isWideDecimalType()) return dataconvert::DataConvert::decimalToString(x.value, x.scale, op_ct.colDataType); else { - char buf[utils::MAXLENGTH16BYTES]; - dataconvert::DataConvert::decimalToString( &x.s128Value, x.scale, buf, utils::MAXLENGTH16BYTES, op_ct.colDataType); + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; + dataconvert::DataConvert::decimalToString( &x.s128Value, x.scale, buf, (uint8_t) sizeof(buf), op_ct.colDataType); return string(buf); } } diff --git a/utils/joiner/tuplejoiner.cpp b/utils/joiner/tuplejoiner.cpp index ee405dd89..7c6793bf9 100644 --- a/utils/joiner/tuplejoiner.cpp +++ b/utils/joiner/tuplejoiner.cpp @@ -31,7 +31,6 @@ #include "spinlock.h" #include "vlarray.h" -#include "widedecimalutils.h" using namespace std; using namespace rowgroup; @@ -110,7 +109,7 @@ TupleJoiner::TupleJoiner( if (smallRG.isUnsigned(smallKeyColumns[0])) { - if (datatypes::Decimal::isWideDecimalType( + if (datatypes::isWideDecimalType( smallRG.getColType(smallKeyColumns[0]), smallRG.getColumnWidth(smallKeyColumns[0]))) { @@ -125,7 +124,7 @@ TupleJoiner::TupleJoiner( } else { - if (datatypes::Decimal::isWideDecimalType( + if (datatypes::isWideDecimalType( smallRG.getColType(smallKeyColumns[0]), smallRG.getColumnWidth(smallKeyColumns[0]))) { @@ -225,7 +224,7 @@ TupleJoiner::TupleJoiner( discreteValues[i] = false; if (isUnsigned(smallRG.getColTypes()[smallKeyColumns[i]])) { - if (datatypes::Decimal::isWideDecimalType( + if (datatypes::isWideDecimalType( smallRG.getColType(smallKeyColumns[i]), smallRG.getColumnWidth(smallKeyColumns[i]))) { @@ -240,7 +239,7 @@ TupleJoiner::TupleJoiner( } else { - if (datatypes::Decimal::isWideDecimalType( + if (datatypes::isWideDecimalType( smallRG.getColType(smallKeyColumns[i]), smallRG.getColumnWidth(smallKeyColumns[i]))) { @@ -802,7 +801,7 @@ void TupleJoiner::doneInserting() } } } - else if (datatypes::Decimal::isWideDecimalType( + else if (datatypes::isWideDecimalType( smallRow.getColType(smallKeyColumns[col]), smallRow.getColumnWidth(smallKeyColumns[col]))) { @@ -1165,7 +1164,7 @@ void TupleJoiner::updateCPData(const Row& r) } } } - else if (datatypes::Decimal::isWideDecimalType( + else if (datatypes::isWideDecimalType( r.getColType(colIdx), r.getColumnWidth(colIdx))) { @@ -1205,7 +1204,7 @@ void TupleJoiner::updateCPData(const Row& r) } } } - else if (datatypes::Decimal::isWideDecimalType( + else if (datatypes::isWideDecimalType( r.getColType(colIdx), r.getColumnWidth(colIdx))) { @@ -1745,7 +1744,7 @@ boost::shared_ptr TupleJoiner::copyForDiskJoin() ret->discreteValues[i] = false; if (isUnsigned(smallRG.getColTypes()[smallKeyColumns[i]])) { - if (datatypes::Decimal::isWideDecimalType( + if (datatypes::isWideDecimalType( smallRG.getColType(smallKeyColumns[i]), smallRG.getColumnWidth(smallKeyColumns[i]))) { @@ -1760,7 +1759,7 @@ boost::shared_ptr TupleJoiner::copyForDiskJoin() } else { - if (datatypes::Decimal::isWideDecimalType( + if (datatypes::isWideDecimalType( smallRG.getColType(smallKeyColumns[i]), smallRG.getColumnWidth(smallKeyColumns[i]))) { diff --git a/utils/regr/moda.cpp b/utils/regr/moda.cpp index 7bc5b427d..aa095ab53 100644 --- a/utils/regr/moda.cpp +++ b/utils/regr/moda.cpp @@ -158,7 +158,7 @@ mcsv1_UDAF::ReturnCode moda::init(mcsv1Context* context, return mcsv1_UDAF::ERROR; } - if (!(execplan::isNumeric(colTypes[0].dataType))) + if (!(datatypes::isNumeric(colTypes[0].dataType))) { // The error message will be prepended with // "The storage engine for the table doesn't support " diff --git a/utils/rowgroup/rowaggregation.cpp b/utils/rowgroup/rowaggregation.cpp index 04fe593ef..643b934b5 100755 --- a/utils/rowgroup/rowaggregation.cpp +++ b/utils/rowgroup/rowaggregation.cpp @@ -53,7 +53,6 @@ #include "vlarray.h" #include "collation.h" -#include "widedecimalutils.h" //..comment out NDEBUG to enable assertions, uncomment NDEBUG to disable //#define NDEBUG @@ -2752,7 +2751,7 @@ void RowAggregationUM::calculateAvgColumns() uint32_t precision = fRow.getPrecision(colOut); bool isWideDecimal = - datatypes::Decimal::isWideDecimalType(precision); + datatypes::Decimal::isWideDecimalTypeByPrecision(precision); if (LIKELY(!isWideDecimal)) { @@ -3687,12 +3686,12 @@ void RowAggregationUM::doNotNullConstantAggregate(const ConstantAggData& aggData auto width = fRow.getColumnWidth(colOut); if (width == datatypes::MAXDECIMALWIDTH) { - ColTypeAlias colType; + execplan::CalpontSystemCatalog::TypeHolderStd colType; colType.colWidth = width; colType.precision = fRow.getPrecision(i); colType.scale = fRow.getScale(i); colType.colDataType = colDataType; - fRow.setInt128Field(Dec::int128FromString(aggData.fConstValue, colType), colOut); + fRow.setInt128Field(colType.decimal128FromString(aggData.fConstValue), colOut); } else if (width <= datatypes::MAXLEGACYWIDTH) { @@ -3812,13 +3811,12 @@ void RowAggregationUM::doNotNullConstantAggregate(const ConstantAggData& aggData auto width = fRow.getColumnWidth(colOut); if (width == datatypes::MAXDECIMALWIDTH) { - ColTypeAlias colType; + execplan::CalpontSystemCatalog::TypeHolderStd colType; colType.colWidth = width; colType.precision = fRow.getPrecision(i); colType.scale = fRow.getScale(i); colType.colDataType = colDataType; - int128_t constValue = Dec::int128FromString(aggData.fConstValue, - colType); + int128_t constValue = colType.decimal128FromString(aggData.fConstValue); int128_t sum; datatypes::MultiplicationOverflowCheck multOp; diff --git a/utils/rowgroup/rowgroup.cpp b/utils/rowgroup/rowgroup.cpp index 731cf61e5..5b460e27d 100644 --- a/utils/rowgroup/rowgroup.cpp +++ b/utils/rowgroup/rowgroup.cpp @@ -44,7 +44,6 @@ using namespace execplan; #include "rowgroup.h" #include "dataconvert.h" #include "columnwidth.h" -#include "widedecimalutils.h" #include "collation.h" @@ -641,7 +640,7 @@ string Row::toString() const case CalpontSystemCatalog::UDECIMAL: if (colWidths[i] == datatypes::MAXDECIMALWIDTH) { - unsigned int buflen = utils::MAXLENGTH16BYTES; + unsigned int buflen = datatypes::Decimal::MAXLENGTH16BYTES; char *buf = (char*)alloca(buflen); // empty the buffer dataconvert::DataConvert::decimalToString(getBinaryField(i), @@ -851,7 +850,7 @@ void Row::initToNull() break; case 16 : - utils::setWideDecimalNullValue(reinterpret_cast(data[offsets[i]])); + datatypes::Decimal::setWideDecimalNullValue(reinterpret_cast(data[offsets[i]])); break; default: *((int64_t*) &data[offsets[i]]) = static_cast(joblist::BIGINTNULL); @@ -879,7 +878,7 @@ void Row::initToNull() break; case CalpontSystemCatalog::BINARY: { - utils::setWideDecimalNullValue(reinterpret_cast(data[offsets[i]])); + datatypes::Decimal::setWideDecimalNullValue(reinterpret_cast(data[offsets[i]])); } break; @@ -924,7 +923,7 @@ Row::isNullValue_offset( uint32_t offset) const { const int128_t *intPtr = reinterpret_cast(&data[offset]); - return utils::isWideDecimalNullValue (*intPtr); + return datatypes::Decimal::isWideDecimalNullValue (*intPtr); } template<> @@ -933,7 +932,7 @@ Row::isNullValue_offset( uint32_t offset) const { const int128_t *intPtr = reinterpret_cast(&data[offset]); - return utils::isWideDecimalNullValue (*intPtr); + return datatypes::Decimal::isWideDecimalNullValue (*intPtr); } template<> @@ -1203,7 +1202,7 @@ bool Row::equals(const Row& r2, const std::vector& keyCols) const if (getLongDoubleField(col) != r2.getLongDoubleField(col)) return false; } - else if (UNLIKELY(datatypes::Decimal::isWideDecimalType(columnType, colWidths[col]))) + else if (UNLIKELY(datatypes::isWideDecimalType(columnType, colWidths[col]))) { if (*getBinaryField(col) != *r2.getBinaryField(col)) return false; @@ -1262,7 +1261,7 @@ bool Row::equals(const Row& r2, uint32_t lastCol) const if (getLongDoubleField(col) != r2.getLongDoubleField(col)) return false; } - else if (UNLIKELY(datatypes::Decimal::isWideDecimalType(columnType, colWidths[col]))) + else if (UNLIKELY(datatypes::isWideDecimalType(columnType, colWidths[col]))) { if (*getBinaryField(col) != *r2.getBinaryField(col)) return false; @@ -1652,7 +1651,7 @@ void applyMapping(const int* mapping, const Row& in, Row* out) // WIP this doesn't look right b/c we can pushdown colType // Migrate to offset based methods here // code precision 2 width convertor - else if (UNLIKELY(datatypes::Decimal::isWideDecimalType(in.getColTypes()[i], + else if (UNLIKELY(datatypes::isWideDecimalType(in.getColTypes()[i], in.getColumnWidth(i)))) out->setBinaryField_offset(in.getBinaryField(i), 16, out->getOffset(mapping[i])); diff --git a/utils/rowgroup/rowgroup.h b/utils/rowgroup/rowgroup.h index 9064aa8b8..94f72776a 100644 --- a/utils/rowgroup/rowgroup.h +++ b/utils/rowgroup/rowgroup.h @@ -653,12 +653,12 @@ inline uint32_t Row::getCharsetNumber(uint32_t col) const inline bool Row::isCharType(uint32_t colIndex) const { - return execplan::isCharType(types[colIndex]); + return datatypes::isCharType(types[colIndex]); } inline bool Row::isUnsigned(uint32_t colIndex) const { - return execplan::isUnsigned(types[colIndex]); + return datatypes::isUnsigned(types[colIndex]); } inline bool Row::isShortString(uint32_t colIndex) const @@ -1277,7 +1277,7 @@ inline void Row::copyField(Row& out, uint32_t destIndex, uint32_t srcIndex) cons { out.setLongDoubleField(getLongDoubleField(srcIndex), destIndex); } - else if (UNLIKELY(datatypes::Decimal::isWideDecimalType( + else if (UNLIKELY(datatypes::isWideDecimalType( types[srcIndex], colWidths[srcIndex]))) { copyBinaryField(out, destIndex, srcIndex); @@ -1724,12 +1724,12 @@ inline uint64_t RowGroup::getSizeWithStrings() const inline bool RowGroup::isCharType(uint32_t colIndex) const { - return execplan::isCharType(types[colIndex]); + return datatypes::isCharType(types[colIndex]); } inline bool RowGroup::isUnsigned(uint32_t colIndex) const { - return execplan::isUnsigned(types[colIndex]); + return datatypes::isUnsigned(types[colIndex]); } inline bool RowGroup::isShortString(uint32_t colIndex) const @@ -1931,7 +1931,7 @@ inline void copyRow(const Row& in, Row* out, uint32_t colCount) { out->setLongDoubleField(in.getLongDoubleField(i), i); } - else if (UNLIKELY(datatypes::Decimal::isWideDecimalType( + else if (UNLIKELY(datatypes::isWideDecimalType( in.getColType(i), in.getColumnWidth(i)))) { in.copyBinaryField(*out, i, i); diff --git a/utils/udfsdk/mcsv1_udaf.cpp b/utils/udfsdk/mcsv1_udaf.cpp index 2ad8905a8..dea99c125 100755 --- a/utils/udfsdk/mcsv1_udaf.cpp +++ b/utils/udfsdk/mcsv1_udaf.cpp @@ -151,7 +151,7 @@ const std::string mcsv1Context::toString() const std::ostringstream output; output << "mcsv1Context: " << getName() << std::endl; output << " RunFlags=" << fRunFlags << " ContextFlags=" << fContextFlags << std::endl; - output << " UserDataSize=" << fUserDataSize << " ResultType=" << colDataTypeToString(fResultType) << std::endl; + output << " UserDataSize=" << fUserDataSize << " ResultType=" << execplan::colDataTypeToString(fResultType) << std::endl; output << " Resultscale=" << fResultscale << " ResultPrecision=" << fResultPrecision << std::endl; output << " ErrorMsg=" << errorMsg << std::endl; output << " bInterrupted=" << bInterrupted << std::endl; diff --git a/utils/windowfunction/windowfunctiontype.cpp b/utils/windowfunction/windowfunctiontype.cpp index 17aa122a9..738c2bd4e 100644 --- a/utils/windowfunction/windowfunctiontype.cpp +++ b/utils/windowfunction/windowfunctiontype.cpp @@ -793,7 +793,7 @@ void* WindowFunctionType::getNullValueByType(int ct, int pos) break; case 16: - utils::setWideDecimalNullValue(int128Null); + datatypes::Decimal::setWideDecimalNullValue(int128Null); v = &int128Null; break; diff --git a/versioning/BRM/CMakeLists.txt b/versioning/BRM/CMakeLists.txt index 6f39c645d..db6b809b5 100644 --- a/versioning/BRM/CMakeLists.txt +++ b/versioning/BRM/CMakeLists.txt @@ -28,7 +28,8 @@ set(brm_LIB_SRCS transactionnode.cpp undoable.cpp vbbm.cpp - vss.cpp) + vss.cpp + ../../datatypes/mcs_datatype.cpp) add_library(brm SHARED ${brm_LIB_SRCS}) diff --git a/versioning/BRM/dbrm.cpp b/versioning/BRM/dbrm.cpp index bd27c3aec..ad0f96c9f 100644 --- a/versioning/BRM/dbrm.cpp +++ b/versioning/BRM/dbrm.cpp @@ -31,7 +31,6 @@ #include #include "dataconvert.h" -#include "widedecimalutils.h" #include "oamcache.h" #include "rwlock.h" #include "mastersegmenttable.h" @@ -4541,7 +4540,7 @@ void DBRM::invalidateUncommittedExtentLBIDs(execplan::CalpontSystemCatalog::SCN aInfo.isBinaryColumn = isBinaryColumn; if (!isBinaryColumn) { - if (execplan::isUnsigned(colType.colDataType)) + if (datatypes::isUnsigned(colType.colDataType)) { aInfo.max = 0; aInfo.min = numeric_limits::max(); @@ -4554,7 +4553,7 @@ void DBRM::invalidateUncommittedExtentLBIDs(execplan::CalpontSystemCatalog::SCN } else { - if (execplan::isUnsigned(colType.colDataType)) + if (datatypes::isUnsigned(colType.colDataType)) { aInfo.bigMax = 0; aInfo.bigMin = -1; diff --git a/versioning/BRM/extentmap.cpp b/versioning/BRM/extentmap.cpp index 42b452c4f..20fde35c9 100644 --- a/versioning/BRM/extentmap.cpp +++ b/versioning/BRM/extentmap.cpp @@ -55,7 +55,6 @@ namespace bi = boost::interprocess; #include "mastersegmenttable.h" #include "blocksize.h" #include "dataconvert.h" -#include "widedecimalutils.h" #include "mcs_decimal.h" #include "oamcache.h" #include "IDBDataFile.h" diff --git a/writeengine/bulk/we_brmreporter.cpp b/writeengine/bulk/we_brmreporter.cpp index f86490bec..229a8c333 100644 --- a/writeengine/bulk/we_brmreporter.cpp +++ b/writeengine/bulk/we_brmreporter.cpp @@ -34,7 +34,6 @@ #include "we_log.h" #include "cacheutils.h" #include "IDBPolicy.h" -#include "widedecimalutils.h" #include "mcs_decimal.h" #include "dataconvert.h" @@ -301,7 +300,7 @@ void BRMReporter::sendCPToFile( ) { if (fCPInfo.size() > 0) { - char buf[utils::MAXLENGTH16BYTES]; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; std::ostringstream oss; oss << "Writing " << fCPInfo.size() << " CP updates for table " << fTableName << " to report file " << fRptFileName; @@ -309,7 +308,7 @@ void BRMReporter::sendCPToFile( ) for (unsigned int i = 0; i < fCPInfo.size(); i++) { - if (!datatypes::Decimal::isWideDecimalType(fCPInfo[i].type, fCPInfo[i].colWidth)) + if (!datatypes::isWideDecimalType(fCPInfo[i].type, fCPInfo[i].colWidth)) { fRptFile << "CP: " << fCPInfo[i].startLbid << ' ' << fCPInfo[i].max << ' ' << @@ -322,10 +321,10 @@ void BRMReporter::sendCPToFile( ) { std::string bigMin, bigMax; - dataconvert::DataConvert::decimalToString(&fCPInfo[i].bigMin, 0, buf, utils::MAXLENGTH16BYTES, fCPInfo[i].type); + dataconvert::DataConvert::decimalToString(&fCPInfo[i].bigMin, 0, buf, (uint8_t) sizeof(buf), fCPInfo[i].type); bigMin = buf; - dataconvert::DataConvert::decimalToString(&fCPInfo[i].bigMax, 0, buf, utils::MAXLENGTH16BYTES, fCPInfo[i].type); + dataconvert::DataConvert::decimalToString(&fCPInfo[i].bigMax, 0, buf, (uint8_t) sizeof(buf), fCPInfo[i].type); bigMax = buf; fRptFile << "CP: " << fCPInfo[i].startLbid << ' ' << diff --git a/writeengine/bulk/we_bulkloadbuffer.cpp b/writeengine/bulk/we_bulkloadbuffer.cpp index 18e6bae00..250356156 100644 --- a/writeengine/bulk/we_bulkloadbuffer.cpp +++ b/writeengine/bulk/we_bulkloadbuffer.cpp @@ -40,7 +40,6 @@ #include "dataconvert.h" #include "exceptclasses.h" #include "mcs_decimal.h" -#include "widedecimalutils.h" #include "joblisttypes.h" diff --git a/writeengine/bulk/we_bulkloadbuffer.h b/writeengine/bulk/we_bulkloadbuffer.h index bbdb2378d..ffccc2aeb 100644 --- a/writeengine/bulk/we_bulkloadbuffer.h +++ b/writeengine/bulk/we_bulkloadbuffer.h @@ -31,7 +31,6 @@ #include "we_columninfo.h" #include "calpontsystemcatalog.h" #include "dataconvert.h" -#include "widedecimalutils.h" namespace WriteEngine { diff --git a/writeengine/bulk/we_colextinf.cpp b/writeengine/bulk/we_colextinf.cpp index f94433689..a4116df9b 100644 --- a/writeengine/bulk/we_colextinf.cpp +++ b/writeengine/bulk/we_colextinf.cpp @@ -27,7 +27,6 @@ #include "we_colextinf.h" #include "dataconvert.h" -#include "widedecimalutils.h" #include #include diff --git a/writeengine/bulk/we_colextinf.h b/writeengine/bulk/we_colextinf.h index e0e516616..58de88cc2 100644 --- a/writeengine/bulk/we_colextinf.h +++ b/writeengine/bulk/we_colextinf.h @@ -41,7 +41,6 @@ #include "brmtypes.h" #include "we_type.h" #include "dataconvert.h" -#include "widedecimalutils.h" namespace WriteEngine { diff --git a/writeengine/server/CMakeLists.txt b/writeengine/server/CMakeLists.txt index c4128df7e..1165dde47 100644 --- a/writeengine/server/CMakeLists.txt +++ b/writeengine/server/CMakeLists.txt @@ -15,7 +15,8 @@ set(WriteEngineServer_SRCS we_cleartablelockcmd.cpp we_cpifeederthread.cpp we_getfilesizes.cpp - ../../utils/common/crashtrace.cpp) + ../../utils/common/crashtrace.cpp + ../../datatypes/mcs_datatype.cpp) add_executable(WriteEngineServer ${WriteEngineServer_SRCS}) diff --git a/writeengine/server/we_ddlcommandproc.cpp b/writeengine/server/we_ddlcommandproc.cpp index 8356ffc22..d60ff033f 100644 --- a/writeengine/server/we_ddlcommandproc.cpp +++ b/writeengine/server/we_ddlcommandproc.cpp @@ -213,12 +213,12 @@ uint8_t WE_DDLCommandProc::writeSystable(ByteStream& bs, std::string& err) else if (INIT_COL == column.tableColName.column) { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } else if (NEXT_COL == column.tableColName.column) { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } else if (AUTOINC_COL == column.tableColName.column) { @@ -226,7 +226,7 @@ uint8_t WE_DDLCommandProc::writeSystable(ByteStream& bs, std::string& err) } else { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } colStruct.dataOid = column.oid; @@ -588,7 +588,7 @@ uint8_t WE_DDLCommandProc::writeCreateSyscolumn(ByteStream& bs, std::string& err else { tmpStr = ""; - //colTuple.data = getNullValueForType(column.colType); + //colTuple.data = column.colType.getNullValueForType(); } } @@ -629,16 +629,16 @@ uint8_t WE_DDLCommandProc::writeCreateSyscolumn(ByteStream& bs, std::string& err } else { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } } else if (LISTOBJID_COL == column.tableColName.column) { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } else if (TREEOBJID_COL == column.tableColName.column) { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } else if (MINVAL_COL == column.tableColName.column) { @@ -664,7 +664,7 @@ uint8_t WE_DDLCommandProc::writeCreateSyscolumn(ByteStream& bs, std::string& err } else { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } colStruct.dataOid = column.oid; @@ -982,7 +982,7 @@ uint8_t WE_DDLCommandProc::writeSyscolumn(ByteStream& bs, std::string& err) else { tmpStr = ""; - //colTuple.data = getNullValueForType(column.colType); + //colTuple.data = column.colType.getNullValueForType(); } } @@ -1023,16 +1023,16 @@ uint8_t WE_DDLCommandProc::writeSyscolumn(ByteStream& bs, std::string& err) } else { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } } else if (LISTOBJID_COL == column.tableColName.column) { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } else if (TREEOBJID_COL == column.tableColName.column) { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } else if (MINVAL_COL == column.tableColName.column) { @@ -1058,7 +1058,7 @@ uint8_t WE_DDLCommandProc::writeSyscolumn(ByteStream& bs, std::string& err) } else { - colTuple.data = getNullValueForType(column.colType); + colTuple.data = column.colType.getNullValueForType(); } colStruct.dataOid = column.oid; @@ -3646,7 +3646,7 @@ uint8_t WE_DDLCommandProc::fillNewColumn(ByteStream& bs, std::string& err) colType.scale = scale; colType.precision = precision; bool pushWarning = false; - defaultVal.data = DataConvert::convertColumnData(colType, defaultValStr, pushWarning, timeZone, isNULL, false, false); + defaultVal.data = colType.convertColumnData(defaultValStr, pushWarning, timeZone, isNULL, false, false); fWEWrapper.setTransId(txnID); fWEWrapper.setIsInsert(true); fWEWrapper.setBulkFlag(true); diff --git a/writeengine/server/we_ddlcommon.h b/writeengine/server/we_ddlcommon.h index d477880f1..b1741a440 100644 --- a/writeengine/server/we_ddlcommon.h +++ b/writeengine/server/we_ddlcommon.h @@ -143,239 +143,6 @@ inline void getColumnsForTable(uint32_t sessionID, std::string schema, std::str } -inline boost::any getNullValueForType(const execplan::CalpontSystemCatalog::ColType& colType) -{ - boost::any value; - - switch (colType.colDataType) - { - case execplan::CalpontSystemCatalog::BIT: - break; - - case execplan::CalpontSystemCatalog::TINYINT: - { - char tinyintvalue = joblist::TINYINTNULL; - value = tinyintvalue; - - } - break; - - case execplan::CalpontSystemCatalog::UTINYINT: - { - uint8_t tinyintvalue = joblist::UTINYINTNULL; - value = tinyintvalue; - - } - break; - - case execplan::CalpontSystemCatalog::SMALLINT: - { - short smallintvalue = joblist::SMALLINTNULL; - value = smallintvalue; - } - break; - - case execplan::CalpontSystemCatalog::USMALLINT: - { - uint16_t smallintvalue = joblist::USMALLINTNULL; - value = smallintvalue; - } - break; - - case execplan::CalpontSystemCatalog::MEDINT: - case execplan::CalpontSystemCatalog::INT: - { - int intvalue = joblist::INTNULL; - value = intvalue; - } - break; - - case execplan::CalpontSystemCatalog::UMEDINT: - case execplan::CalpontSystemCatalog::UINT: - { - uint32_t intvalue = joblist::UINTNULL; - value = intvalue; - } - break; - - case execplan::CalpontSystemCatalog::BIGINT: - { - long long bigint = joblist::BIGINTNULL; - value = bigint; - } - break; - - case execplan::CalpontSystemCatalog::UBIGINT: - { - uint64_t bigint = joblist::UBIGINTNULL; - value = bigint; - } - break; - - case execplan::CalpontSystemCatalog::DECIMAL: - case execplan::CalpontSystemCatalog::UDECIMAL: - { - if (colType.colWidth <= execplan::CalpontSystemCatalog::FOUR_BYTE) - { - short smallintvalue = joblist::SMALLINTNULL; - value = smallintvalue; - } - else if (colType.colWidth <= 9) - { - int intvalue = joblist::INTNULL; - value = intvalue; - } - else if (colType.colWidth <= 18) - { - long long eightbyte = joblist::BIGINTNULL; - value = eightbyte; - } - else - { - WriteEngine::Token nullToken; - value = nullToken; - } - } - break; - - case execplan::CalpontSystemCatalog::FLOAT: - case execplan::CalpontSystemCatalog::UFLOAT: - { - uint32_t jlfloatnull = joblist::FLOATNULL; - float* fp = reinterpret_cast(&jlfloatnull); - value = *fp; - } - break; - - case execplan::CalpontSystemCatalog::DOUBLE: - case execplan::CalpontSystemCatalog::UDOUBLE: - { - uint64_t jldoublenull = joblist::DOUBLENULL; - double* dp = reinterpret_cast(&jldoublenull); - value = *dp; - } - break; - - case execplan::CalpontSystemCatalog::DATE: - { - int d = joblist::DATENULL; - value = d; - } - break; - - case execplan::CalpontSystemCatalog::DATETIME: - { - long long d = joblist::DATETIMENULL; - value = d; - } - break; - - case execplan::CalpontSystemCatalog::TIME: - { - long long d = joblist::TIMENULL; - value = d; - } - break; - - case execplan::CalpontSystemCatalog::TIMESTAMP: - { - long long d = joblist::TIMESTAMPNULL; - value = d; - } - break; - - case execplan::CalpontSystemCatalog::CHAR: - { - std::string charnull; - - if (colType.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE) - { - //charnull = joblist::CHAR1NULL; - charnull = "\376"; - value = charnull; - } - else if (colType.colWidth == execplan::CalpontSystemCatalog::TWO_BYTE) - { - //charnull = joblist::CHAR2NULL; - charnull = "\377\376"; - value = charnull; - } - else if (colType.colWidth <= execplan::CalpontSystemCatalog::FOUR_BYTE) - { - //charnull = joblist::CHAR4NULL; - charnull = "\377\377\377\376"; - value = charnull; - } - else - { - WriteEngine::Token nullToken; - value = nullToken; - } - - } - break; - - case execplan::CalpontSystemCatalog::VARCHAR: - { - std::string charnull; - - if (colType.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE) - { - //charnull = joblist::CHAR2NULL; - charnull = "\377\376"; - value = charnull; - } - else if (colType.colWidth < execplan::CalpontSystemCatalog::FOUR_BYTE) - { - //charnull = joblist::CHAR4NULL; - charnull = "\377\377\377\376"; - value = charnull; - } - else - { - WriteEngine::Token nullToken; - value = nullToken; - } - - } - break; - - case execplan::CalpontSystemCatalog::BLOB: - case execplan::CalpontSystemCatalog::TEXT: - case execplan::CalpontSystemCatalog::VARBINARY: - { - std::string charnull; - - if (colType.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE) - { - //charnull = joblist::CHAR2NULL; - charnull = "\377\376"; - value = charnull; - } - else if (colType.colWidth < execplan::CalpontSystemCatalog::FOUR_BYTE) - { - //charnull = joblist::CHAR4NULL; - charnull = "\377\377\377\376"; - value = charnull; - } - else - { - WriteEngine::Token nullToken; - value = nullToken; - } - - } - break; - - - default: - throw std::runtime_error("getNullValueForType: unkown column data type"); - break; - - } - - return value; -} inline int convertDataType(int dataType) { diff --git a/writeengine/server/we_dmlcommandproc.cpp b/writeengine/server/we_dmlcommandproc.cpp index 0a17d5128..f9c577dbd 100644 --- a/writeengine/server/we_dmlcommandproc.cpp +++ b/writeengine/server/we_dmlcommandproc.cpp @@ -370,7 +370,7 @@ uint8_t WE_DMLCommandProc::processSingleInsert(messageqcpp::ByteStream& bs, std: try { - datavalue = DataConvert::convertColumnData(colType, indata, pushWarning, insertPkg.get_TimeZone(), isNULL, false, false); + datavalue = colType.convertColumnData(indata, pushWarning, insertPkg.get_TimeZone(), isNULL, false, false); } catch (exception&) { @@ -1245,7 +1245,7 @@ uint8_t WE_DMLCommandProc::processBatchInsert(messageqcpp::ByteStream& bs, std:: try { - datavalue = DataConvert::convertColumnData(colType, indata, pushWarning, insertPkg.get_TimeZone(), isNULL, false, false); + datavalue = colType.convertColumnData(indata, pushWarning, insertPkg.get_TimeZone(), isNULL, false, false); } catch (exception&) { @@ -2996,12 +2996,12 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, if (fetchColColwidths[fetchColPos] == datatypes::MAXDECIMALWIDTH) { int128_t* dec; - char buf[utils::MAXLENGTH16BYTES]; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; dec = row.getBinaryField(fetchColPos); dataconvert::DataConvert::decimalToString(dec, (unsigned)fetchColScales[fetchColPos], buf, - sizeof(buf), fetchColTypes[fetchColPos]); + (uint8_t) sizeof(buf), fetchColTypes[fetchColPos]); value.assign(buf); @@ -3362,12 +3362,12 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, { // WIP MCOL-641 int128_t* dec; - char buf[utils::MAXLENGTH16BYTES]; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; dec = row.getBinaryField(fetchColPos); dataconvert::DataConvert::decimalToString(dec, (unsigned)fetchColScales[fetchColPos], buf, - sizeof(buf), fetchColTypes[fetchColPos]); + (uint8_t) sizeof(buf), fetchColTypes[fetchColPos]); value = buf; @@ -3527,7 +3527,7 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, try { - datavalue = DataConvert::convertColumnData(colType, colType.defaultValue, pushWarn, timeZone, isNull, false, false); + datavalue = colType.convertColumnData(colType.defaultValue, pushWarn, timeZone, isNull, false, false); } catch (exception&) { @@ -3559,7 +3559,7 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, { try { - datavalue = DataConvert::convertColumnData(colType, value, pushWarn, timeZone, isNull, false, false); + datavalue = colType.convertColumnData(value, pushWarn, timeZone, isNull, false, false); } catch (exception&) { @@ -3656,7 +3656,7 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, try { - datavalue = DataConvert::convertColumnData(colType, inData, pushWarn, timeZone, isNull, false, false); + datavalue = colType.convertColumnData(inData, pushWarn, timeZone, isNull, false, false); } catch (exception&) { @@ -3702,7 +3702,7 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, { try { - datavalue = DataConvert::convertColumnData(colType, colType.defaultValue, pushWarn, timeZone, isNull, false, false); + datavalue = colType.convertColumnData(colType.defaultValue, pushWarn, timeZone, isNull, false, false); } catch (exception&) { @@ -3735,7 +3735,7 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, { try { - datavalue = DataConvert::convertColumnData(colType, inData, pushWarn, timeZone, isNull, false, true); + datavalue = colType.convertColumnData(inData, pushWarn, timeZone, isNull, false, true); } catch (exception& ex) { diff --git a/writeengine/wrapper/we_colop.cpp b/writeengine/wrapper/we_colop.cpp index bc9f0666e..3b14b8aae 100644 --- a/writeengine/wrapper/we_colop.cpp +++ b/writeengine/wrapper/we_colop.cpp @@ -40,7 +40,6 @@ using namespace std; using namespace execplan; #include "dataconvert.h" -#include "widedecimalutils.h" #include "IDBDataFile.h" #include "IDBPolicy.h" diff --git a/writeengine/wrapper/writeengine.cpp b/writeengine/wrapper/writeengine.cpp index da4c25bf4..2b5948a92 100644 --- a/writeengine/wrapper/writeengine.cpp +++ b/writeengine/wrapper/writeengine.cpp @@ -58,7 +58,6 @@ using namespace execplan; #include "MonitorProcMem.h" using namespace idbdatafile; #include "dataconvert.h" -#include "widedecimalutils.h" #ifdef _MSC_VER #define isnan _isnan @@ -3898,9 +3897,9 @@ void WriteEngineWrapper::printInputValue(const ColStructList& colStructList, else if (curTuple.data.type() == typeid(int128_t)) { // WIP replace with a single call - char buf[utils::MAXLENGTH16BYTES]; + char buf[datatypes::Decimal::MAXLENGTH16BYTES]; int128_t val = boost::any_cast(curTuple.data); - dataconvert::DataConvert::decimalToString(&val, 0, buf, utils::MAXLENGTH16BYTES, curColStruct.colDataType); + dataconvert::DataConvert::decimalToString(&val, 0, buf, (uint8_t) sizeof(buf), curColStruct.colDataType); curStr.assign(buf); } else if (curTuple.data.type() == typeid(double))