From 5fce19df0a80bafd91c53e9ba84de699f2a0e9ff Mon Sep 17 00:00:00 2001 From: Roman Nozdrin Date: Fri, 15 Jan 2021 16:02:10 +0000 Subject: [PATCH] MCOL-4412 Introduce TypeHandler::getEmptyValueForType to return const ptr for an empty value WE changes for SQL DML and DDL operations Changes for bulk operations Changes for scanning operations Cleanup --- datatypes/mcs_datatype.cpp | 210 ++++++- datatypes/mcs_datatype.h | 564 ++++++++++-------- primitives/primproc/columncommand.cpp | 85 +-- primitives/primproc/columncommand.h | 33 + utils/common/CMakeLists.txt | 3 +- utils/common/emptyvaluemanip.cpp | 110 ---- utils/common/emptyvaluemanip.h | 31 - writeengine/bulk/we_bulkload.cpp | 7 +- writeengine/bulk/we_colbuf.cpp | 8 +- writeengine/bulk/we_colbufcompressed.cpp | 8 +- writeengine/bulk/we_columninfo.cpp | 4 +- writeengine/bulk/we_columninfocompressed.cpp | 2 +- writeengine/server/we_dmlcommandproc.cpp | 3 - writeengine/shared/we_blockop.cpp | 40 +- writeengine/shared/we_blockop.h | 16 +- writeengine/shared/we_bulkrollbackfile.cpp | 3 +- .../shared/we_bulkrollbackfilecompressed.cpp | 3 +- writeengine/shared/we_chunkmanager.cpp | 6 +- writeengine/shared/we_chunkmanager.h | 2 +- writeengine/shared/we_fileop.cpp | 22 +- writeengine/shared/we_fileop.h | 22 +- writeengine/shared/we_type.h | 4 +- writeengine/wrapper/we_colop.cpp | 63 +- writeengine/wrapper/we_colop.h | 4 +- writeengine/wrapper/we_colopcompress.cpp | 2 +- writeengine/wrapper/we_colopcompress.h | 2 +- writeengine/wrapper/writeengine.cpp | 64 +- 27 files changed, 741 insertions(+), 580 deletions(-) delete mode 100644 utils/common/emptyvaluemanip.cpp delete mode 100644 utils/common/emptyvaluemanip.h diff --git a/datatypes/mcs_datatype.cpp b/datatypes/mcs_datatype.cpp index 8fa1b04f1..6f6323491 100644 --- a/datatypes/mcs_datatype.cpp +++ b/datatypes/mcs_datatype.cpp @@ -1750,7 +1750,6 @@ TypeHandlerStr::getNullValueForTypeVarcharText(const SystemCatalog::TypeAttribut return value; } - boost::any TypeHandlerBlob::getNullValueForType(const SystemCatalog::TypeAttributesStd &attr) const { @@ -2083,6 +2082,215 @@ TypeHandlerUDecimal128::convertFromString(const SystemCatalog::TypeAttributesStd } +/****************************************************************************/ +const uint8_t* +getEmptyTypeHandlerSInt8() +{ + const static uint8_t TINYINTEMPTYROW = joblist::TINYINTEMPTYROW; + return &TINYINTEMPTYROW; +} + +const uint8_t* +TypeHandlerSInt8::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerSInt8(); +} + +const uint8_t* +getEmptyTypeHandlerSInt16() +{ + const static uint16_t SMALLINTEMPTYROW = joblist::SMALLINTEMPTYROW; + return reinterpret_cast(&SMALLINTEMPTYROW); +} + +const uint8_t* +TypeHandlerSInt16::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerSInt16(); +} + +const uint8_t* +getEmptyTypeHandlerSInt32() +{ + const static uint32_t INTEMPTYROW = joblist::INTEMPTYROW; + return reinterpret_cast(&INTEMPTYROW); +} + +const uint8_t* +TypeHandlerSInt24::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerSInt32(); +} + +const uint8_t* +TypeHandlerSInt32::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerSInt32(); +} + +const uint8_t* +getEmptyTypeHandlerSInt64() +{ + const static uint64_t BIGINTEMPTYROW = joblist::BIGINTEMPTYROW; + return reinterpret_cast(&BIGINTEMPTYROW); +} + +const uint8_t* +TypeHandlerSInt64::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerSInt64(); +} + +const uint8_t* +TypeHandlerUInt8::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + const static uint8_t UTINYINTEMPTYROW = joblist::UTINYINTEMPTYROW; + return reinterpret_cast(&UTINYINTEMPTYROW); +} + +const uint8_t* +TypeHandlerUInt16::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + const static uint16_t USMALLINTEMPTYROW = joblist::USMALLINTEMPTYROW; + return reinterpret_cast(&USMALLINTEMPTYROW); +} + +const uint8_t* +getEmptyTypeHandlerUInt32() +{ + const static uint32_t UINTEMPTYROW = joblist::UINTEMPTYROW; + return reinterpret_cast(&UINTEMPTYROW); +} + +const uint8_t* +TypeHandlerUInt24::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerUInt32(); +} + +const uint8_t* +TypeHandlerUInt32::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerUInt32(); +} + +const uint8_t* +TypeHandlerUInt64::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + const static uint64_t UBIGINTEMPTYROW = joblist::UBIGINTEMPTYROW; + return reinterpret_cast(&UBIGINTEMPTYROW); +} + +const uint8_t* +getEmptyTypeHandlerFloat(const SystemCatalog::TypeAttributesStd &attr) +{ + const static uint32_t FLOATEMPTYROW = joblist::FLOATEMPTYROW; + return reinterpret_cast(&FLOATEMPTYROW); +} + +const uint8_t* +TypeHandlerUFloat::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerFloat(attr); +} + +const uint8_t* +TypeHandlerSFloat::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerFloat(attr); +} + +const uint8_t* +getEmptyTypeHandlerDouble(const SystemCatalog::TypeAttributesStd &attr) +{ + const static uint64_t DOUBLEEMPTYROW = joblist::DOUBLEEMPTYROW; + return reinterpret_cast(&DOUBLEEMPTYROW); +} + +const uint8_t* +TypeHandlerUDouble::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerDouble(attr); +} + +const uint8_t* +TypeHandlerSDouble::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerDouble(attr); +} + +// returns a ptr to an empty magic value for TypeHandlerStr types +// args +// attr - width, precision and scale +// offset - offset value to reduce width for VARCHAR by 1 +const uint8_t* +getEmptyTypeHandlerStr(const SystemCatalog::TypeAttributesStd &attr, int8_t offset) +{ + const static uint8_t CHAR1EMPTYROW = joblist::CHAR1EMPTYROW; + const static uint16_t CHAR2EMPTYROW = joblist::CHAR2EMPTYROW; + const static uint32_t CHAR4EMPTYROW = joblist::CHAR4EMPTYROW; + const static uint64_t CHAR8EMPTYROW = joblist::CHAR8EMPTYROW; + + if (attr.colWidth == (2 + offset)) + return reinterpret_cast(&CHAR2EMPTYROW); + else if (attr.colWidth >= (3 + offset) && attr.colWidth <= (4 + offset)) + return reinterpret_cast(&CHAR4EMPTYROW); + else if (attr.colWidth >= (5 + offset)) + return reinterpret_cast(&CHAR8EMPTYROW); + + return reinterpret_cast(&CHAR1EMPTYROW); +} + +const uint8_t* +TypeHandlerStr::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerStr(attr, 0); +} + +const uint8_t* +TypeHandlerVarchar::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyTypeHandlerStr(attr, -1); +} + +inline const uint8_t* +getEmptyValueForDecimal64(const SystemCatalog::TypeAttributesStd &attr) +{ + if (attr.colWidth <= 1) + return getEmptyTypeHandlerSInt8(); + else if (attr.colWidth <= 2) + return getEmptyTypeHandlerSInt16(); + else if (attr.colWidth <= 4) + return getEmptyTypeHandlerSInt32(); + else + return getEmptyTypeHandlerSInt64(); +} + +const uint8_t* +TypeHandlerSDecimal64::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyValueForDecimal64(attr); +} + +const uint8_t* +TypeHandlerUDecimal64::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return getEmptyValueForDecimal64(attr); +} + +const uint8_t* +TypeHandlerSDecimal128::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return reinterpret_cast(&datatypes::Decimal128Empty); +} + +const uint8_t* +TypeHandlerUDecimal128::getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const +{ + return reinterpret_cast(&datatypes::Decimal128Empty); +} + + /****************************************************************************/ } // end of namespace datatypes diff --git a/datatypes/mcs_datatype.h b/datatypes/mcs_datatype.h index d996db981..69fc4a5db 100644 --- a/datatypes/mcs_datatype.h +++ b/datatypes/mcs_datatype.h @@ -941,6 +941,9 @@ public: const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const = 0; + virtual const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) + const = 0; + }; @@ -1003,6 +1006,12 @@ class TypeHandlerBit: public TypeHandler const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override + { + idbassert(0); + return nullptr; + } + }; @@ -1074,6 +1083,7 @@ public: const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1130,6 +1140,7 @@ public: const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1188,6 +1199,7 @@ class TypeHandlerSInt24: public TypeHandlerInt const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1246,6 +1258,7 @@ class TypeHandlerSInt32: public TypeHandlerInt const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1301,6 +1314,7 @@ class TypeHandlerSInt64: public TypeHandlerInt const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1383,6 +1397,7 @@ class TypeHandlerUInt8: public TypeHandlerInt const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1464,6 +1479,7 @@ class TypeHandlerUInt16: public TypeHandlerInt const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1548,6 +1564,7 @@ class TypeHandlerUInt24: public TypeHandlerInt const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1632,6 +1649,7 @@ class TypeHandlerUInt32: public TypeHandlerInt const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1713,6 +1731,7 @@ class TypeHandlerUInt64: public TypeHandlerInt const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1853,6 +1872,7 @@ public: const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -1933,6 +1953,7 @@ public: const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -2015,6 +2036,7 @@ public: const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -2093,6 +2115,7 @@ public: const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -2152,6 +2175,7 @@ class TypeHandlerSFloat: public TypeHandlerReal const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -2186,6 +2210,7 @@ class TypeHandlerSDouble: public TypeHandlerReal const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -2220,6 +2245,7 @@ class TypeHandlerUFloat: public TypeHandlerReal const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -2254,6 +2280,7 @@ class TypeHandlerUDouble: public TypeHandlerReal const ConvertFromStringParam& prm, const std::string& str, bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; }; @@ -2294,6 +2321,276 @@ class TypeHandlerSLongDouble: public TypeHandlerReal throw logging::QueryDataExcept("convertColumnData: unknown column data type.", logging::dataTypeErr); return boost::any(); } + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override + { + idbassert(0); + return nullptr; + } +}; + +const uint8_t* getEmptyTypeHandlerStr(const SystemCatalog::TypeAttributesStd &attr, int8_t offset); + +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; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) 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; + boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, + const ConvertFromStringParam& prm, + const std::string& str, + bool& pushWarning) 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); + } + boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, + const ConvertFromStringParam& prm, + const std::string& str, + bool& pushWarning) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override; +}; + + +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; + boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, + const ConvertFromStringParam& prm, + const std::string& str, + bool& pushWarning) 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; + boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, + const ConvertFromStringParam& prm, + const std::string& str, + bool& pushWarning) 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); + } + boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, + const ConvertFromStringParam& prm, + const std::string& str, + bool& pushWarning) const override; +}; + + +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 + } + boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, + const ConvertFromStringParam& prm, + const std::string& str, + bool& pushWarning) const override; }; @@ -2310,6 +2607,10 @@ public: SystemCatalog::TypeHolderStd &ct, const SimpleColumnParam &prm) const override; + const uint8_t* getEmptyValueForType(const SystemCatalog::TypeAttributesStd &attr) const override + { + return getEmptyTypeHandlerStr(attr, 0); + } }; @@ -2448,269 +2749,6 @@ class TypeHandlerTimestamp: public TypeHandlerTemporal bool& pushWarning) 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; - boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, - const ConvertFromStringParam& prm, - const std::string& str, - bool& pushWarning) 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); - } - boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, - const ConvertFromStringParam& prm, - const std::string& str, - bool& pushWarning) const override; -}; - - -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; - boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, - const ConvertFromStringParam& prm, - const std::string& str, - bool& pushWarning) 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; - boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, - const ConvertFromStringParam& prm, - const std::string& str, - bool& pushWarning) 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); - } - boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, - const ConvertFromStringParam& prm, - const std::string& str, - bool& pushWarning) const override; -}; - - -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 - } - boost::any convertFromString(const SystemCatalog::TypeAttributesStd& colType, - const ConvertFromStringParam& prm, - const std::string& str, - bool& pushWarning) const override; -}; - - }// end of namespace datatypes #endif //MCS_DATATYPE_H_INCLUDED diff --git a/primitives/primproc/columncommand.cpp b/primitives/primproc/columncommand.cpp index db563007b..acccf0537 100644 --- a/primitives/primproc/columncommand.cpp +++ b/primitives/primproc/columncommand.cpp @@ -48,8 +48,6 @@ using namespace rowgroup; #include "messageids.h" using namespace logging; -#include "emptyvaluemanip.h" - #ifdef _MSC_VER #define llabs labs #endif @@ -177,65 +175,36 @@ void ColumnCommand::loadData() else if (lastBlockReached && _isScan) { // fill remaining blocks with empty values when col scan - int blockLen = BLOCK_SIZE / colType.colWidth; - ByteStream::hexbyte* hPtr = NULL; - ByteStream::octbyte* oPtr = NULL; - ByteStream::quadbyte* qPtr = NULL; - ByteStream::byte* bPtr = NULL; - ByteStream::doublebyte* dPtr = NULL; + uint32_t blockLen = BLOCK_SIZE / colType.colWidth; + auto attrs = datatypes::SystemCatalog::TypeAttributesStd(colType.colWidth, + 0, + -1); + const auto* typeHandler = datatypes::TypeHandler::find(colType.colDataType, + attrs); + const uint8_t* emptyValue = typeHandler->getEmptyValueForType(attrs); + uint8_t* blockDataPtr = &bpp->blockData[i * BLOCK_SIZE]; - if (colType.colWidth == 1) - bPtr = reinterpret_cast(&bpp->blockData[i * BLOCK_SIZE]); - - //@Bug 1812. Added two bytes column handling - if (colType.colWidth == 2) - dPtr = reinterpret_cast(&bpp->blockData[i * BLOCK_SIZE]); - - if (colType.colWidth == 4) - qPtr = reinterpret_cast(&bpp->blockData[i * BLOCK_SIZE]); - - if (colType.colWidth == 8) - oPtr = reinterpret_cast(&bpp->blockData[i * BLOCK_SIZE]); - - if (colType.colWidth == 16) - hPtr = reinterpret_cast(&bpp->blockData[i * BLOCK_SIZE]); - - - for (int idx = 0; idx < blockLen; idx++) + idbassert(blockDataPtr); + if (colType.colWidth == sizeof(ByteStream::byte)) { - if (bPtr && colType.colWidth == 1) - { - ByteStream::byte b; - utils::getEmptyRowValue(colType.colDataType, colType.colWidth, (uint8_t*)&b); - bPtr[idx] = b; - } - //@Bug 1812. Added two bytes column handling - else if (dPtr && colType.colWidth == 2) - { - ByteStream::doublebyte d; - utils::getEmptyRowValue(colType.colDataType, colType.colWidth, (uint8_t*)&d); - dPtr[idx] = d; - } - else if (qPtr && colType.colWidth == 4) - { - ByteStream::quadbyte q; - utils::getEmptyRowValue(colType.colDataType, colType.colWidth, (uint8_t*)&q); - qPtr[idx] = q; - } - else if (oPtr && colType.colWidth == 8) - { - ByteStream::octbyte o; - utils::getEmptyRowValue(colType.colDataType, colType.colWidth, (uint8_t*)&o); - oPtr[idx] = o; - } - else if (colType.colWidth == 16) - { - ByteStream::hexbyte h; - utils::getEmptyRowValue(colType.colDataType, colType.colWidth, (uint8_t*)&h); - datatypes::TSInt128::storeUnaligned(hPtr + idx, h); - } + fillEmptyBlock(blockDataPtr, emptyValue, blockLen); + } + if (colType.colWidth == sizeof(ByteStream::doublebyte)) + { + fillEmptyBlock(blockDataPtr, emptyValue, blockLen); + } + if (colType.colWidth == sizeof(ByteStream::quadbyte)) + { + fillEmptyBlock(blockDataPtr, emptyValue, blockLen); + } + if (colType.colWidth == sizeof(ByteStream::octbyte)) + { + fillEmptyBlock(blockDataPtr, emptyValue, blockLen); + } + if (colType.colWidth == sizeof(ByteStream::hexbyte)) + { + fillEmptyBlock(blockDataPtr, emptyValue, blockLen); } - }// else if ( (primMsg->LBID + i) == oidLastLbid) diff --git a/primitives/primproc/columncommand.h b/primitives/primproc/columncommand.h index aef33fd43..2f0d22e57 100644 --- a/primitives/primproc/columncommand.h +++ b/primitives/primproc/columncommand.h @@ -129,6 +129,10 @@ private: void makeScanMsg(); void makeStepMsg(); void setLBID(uint64_t rid); + template + inline void fillEmptyBlock(uint8_t* dst, + const uint8_t*emptyValue, + const uint32_t number) const; bool _isScan; @@ -171,6 +175,35 @@ private: friend class RTSCommand; }; +template +inline void ColumnCommand::fillEmptyBlock(uint8_t* dst, + const uint8_t*emptyValue, + const uint32_t number) const +{ + T* typedDst = reinterpret_cast(dst); + const T* typedEmptyValue = reinterpret_cast(emptyValue); + for (uint32_t idx = 0; idx < number; idx = idx + 4) + { + typedDst[idx] = *typedEmptyValue; + typedDst[idx+1] = *typedEmptyValue; + typedDst[idx+2] = *typedEmptyValue; + typedDst[idx+3] = *typedEmptyValue; + } +} + +template<> +inline void ColumnCommand::fillEmptyBlock(uint8_t* dst, + const uint8_t*emptyValue, + const uint32_t number) const +{ + for (uint32_t idx = 0; idx < number; idx++) + { + datatypes::TSInt128::assignPtrPtr(dst + idx * sizeof(messageqcpp::ByteStream::hexbyte), + emptyValue); + } +} + + } #endif diff --git a/utils/common/CMakeLists.txt b/utils/common/CMakeLists.txt index e3dd4607e..c6a0fde01 100644 --- a/utils/common/CMakeLists.txt +++ b/utils/common/CMakeLists.txt @@ -10,8 +10,7 @@ set(common_LIB_SRCS MonitorProcMem.cpp nullvaluemanip.cpp threadnaming.cpp - utils_utf8.cpp - emptyvaluemanip.cpp) + utils_utf8.cpp) add_library(common SHARED ${common_LIB_SRCS}) diff --git a/utils/common/emptyvaluemanip.cpp b/utils/common/emptyvaluemanip.cpp deleted file mode 100644 index 1abb40c33..000000000 --- a/utils/common/emptyvaluemanip.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* 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 "emptyvaluemanip.h" - -namespace utils -{ - -void getEmptyRowValue(const execplan::CalpontSystemCatalog::ColDataType colDataType, - const int width, uint8_t* emptyVal) -{ - switch (colDataType) - { - case execplan::CalpontSystemCatalog::TINYINT: - *(uint8_t*)emptyVal = joblist::TINYINTEMPTYROW; - break; - - case execplan::CalpontSystemCatalog::SMALLINT: - *(uint16_t*)emptyVal = joblist::SMALLINTEMPTYROW; - break; - - case execplan::CalpontSystemCatalog::MEDINT: - case execplan::CalpontSystemCatalog::INT: - *(uint32_t*)emptyVal = joblist::INTEMPTYROW; - break; - - case execplan::CalpontSystemCatalog::BIGINT: - *(uint64_t*)emptyVal = joblist::BIGINTEMPTYROW; - break; - - case execplan::CalpontSystemCatalog::UTINYINT: - *(uint8_t*)emptyVal = joblist::UTINYINTEMPTYROW; - break; - - case execplan::CalpontSystemCatalog::USMALLINT: - *(uint16_t*)emptyVal = joblist::USMALLINTEMPTYROW; - break; - - case execplan::CalpontSystemCatalog::UMEDINT: - case execplan::CalpontSystemCatalog::UINT: - *(uint32_t*)emptyVal = joblist::UINTEMPTYROW; - break; - - case execplan::CalpontSystemCatalog::UBIGINT: - *(uint64_t*)emptyVal = joblist::UBIGINTEMPTYROW; - break; - - case execplan::CalpontSystemCatalog::FLOAT: - case execplan::CalpontSystemCatalog::UFLOAT: - *(uint32_t*)emptyVal = joblist::FLOATEMPTYROW; - break; - - case execplan::CalpontSystemCatalog::DOUBLE: - case execplan::CalpontSystemCatalog::UDOUBLE: - *(uint64_t*)emptyVal = joblist::DOUBLEEMPTYROW; - break; - - case execplan::CalpontSystemCatalog::DECIMAL: - case execplan::CalpontSystemCatalog::UDECIMAL: - if (width <= 1) - *(uint8_t*)emptyVal = joblist::TINYINTEMPTYROW; - else if (width <= 2) - *(uint16_t*)emptyVal = joblist::SMALLINTEMPTYROW; - else if (width <= 4) - *(uint32_t*)emptyVal = joblist::INTEMPTYROW; - else if (width <= 8) - *(uint64_t*)emptyVal = joblist::BIGINTEMPTYROW; - else - datatypes::Decimal::setWideDecimalEmptyValue(*(reinterpret_cast(emptyVal))); - break; - - case execplan::CalpontSystemCatalog::CHAR: - case execplan::CalpontSystemCatalog::VARCHAR: - case execplan::CalpontSystemCatalog::DATE: - case execplan::CalpontSystemCatalog::DATETIME: - case execplan::CalpontSystemCatalog::TIMESTAMP: - case execplan::CalpontSystemCatalog::TIME: - case execplan::CalpontSystemCatalog::VARBINARY: - case execplan::CalpontSystemCatalog::BLOB: - case execplan::CalpontSystemCatalog::TEXT: - default: - *(uint8_t*)emptyVal = joblist::CHAR1EMPTYROW; - int offset = (colDataType == execplan::CalpontSystemCatalog::VARCHAR) ? -1 : 0; - - if (width == (2 + offset)) - *(uint16_t*)emptyVal = joblist::CHAR2EMPTYROW; - else if (width >= (3 + offset) && width <= (4 + offset)) - *(uint32_t*)emptyVal = joblist::CHAR4EMPTYROW; - else if (width >= (5 + offset)) - *(uint64_t*)emptyVal = joblist::CHAR8EMPTYROW; - - break; - } -} - -} // namespace utils diff --git a/utils/common/emptyvaluemanip.h b/utils/common/emptyvaluemanip.h deleted file mode 100644 index 2cf6222de..000000000 --- a/utils/common/emptyvaluemanip.h +++ /dev/null @@ -1,31 +0,0 @@ -/* 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 EMPTY_VALUE_MANIP_H -#define EMPTY_VALUE_MANIP_H - -#include "calpontsystemcatalog.h" - -namespace utils -{ - -void getEmptyRowValue(const execplan::CalpontSystemCatalog::ColDataType colDataType, - const int width, uint8_t* emptyVal); - -} // namespace utils - -#endif // EMPTY_VALUE_MANIP_H diff --git a/writeengine/bulk/we_bulkload.cpp b/writeengine/bulk/we_bulkload.cpp index 0b4c4abb5..6a4f2ae6e 100644 --- a/writeengine/bulk/we_bulkload.cpp +++ b/writeengine/bulk/we_bulkload.cpp @@ -563,10 +563,9 @@ int BulkLoad::preProcess( Job& job, int tableNo, job.jobTableList[tableNo].colList[i].weType = curColStruct.colType; // set width to correct column width job.jobTableList[tableNo].colList[i].width = curColStruct.colWidth; - getEmptyRowValue( - job.jobTableList[tableNo].colList[i].dataType, - job.jobTableList[tableNo].colList[i].width, - (uint8_t*)&job.jobTableList[tableNo].colList[i].emptyVal); + job.jobTableList[tableNo].colList[i].emptyVal = + getEmptyRowValue(job.jobTableList[tableNo].colList[i].dataType, + job.jobTableList[tableNo].colList[i].width); // check HWM for column file rc = BRMWrapper::getInstance()->getDbRootHWMInfo( curJobCol.mapOid, diff --git a/writeengine/bulk/we_colbuf.cpp b/writeengine/bulk/we_colbuf.cpp index caa4f8535..79619c856 100644 --- a/writeengine/bulk/we_colbuf.cpp +++ b/writeengine/bulk/we_colbuf.cpp @@ -115,9 +115,11 @@ int ColumnBuffer::writeToFile(int startOffset, int writeSize, bool fillUpWEmptie { BlockOp blockOp; newBuf = new unsigned char[BYTE_PER_BLOCK]; - uint8_t* emptyVal = (uint8_t*) alloca(fColInfo->column.width); - blockOp.getEmptyRowValue(fColInfo->column.dataType, - fColInfo->column.width, emptyVal); + blockOp.findTypeHandler(fColInfo->column.width, + fColInfo->column.dataType); + const uint8_t* emptyVal = blockOp.getEmptyRowValue(fColInfo->column.dataType, + fColInfo->column.width); + ::memcpy(static_cast(newBuf), static_cast(fBuffer + startOffset), writeSize); blockOp.setEmptyBuf(newBuf + writeSize, BYTE_PER_BLOCK - writeSize, diff --git a/writeengine/bulk/we_colbufcompressed.cpp b/writeengine/bulk/we_colbufcompressed.cpp index 0e359e885..43534dc75 100644 --- a/writeengine/bulk/we_colbufcompressed.cpp +++ b/writeengine/bulk/we_colbufcompressed.cpp @@ -132,7 +132,7 @@ int ColumnBufferCompressed::resetToBeCompressedColBuf( BlockOp::setEmptyBuf( fToBeCompressedBuffer, IDBCompressInterface::UNCOMPRESSED_INBUF_LEN, - (uint8_t*)&fColInfo->column.emptyVal, + fColInfo->column.emptyVal, fColInfo->column.width ); if (fLog->isDebug( DEBUG_2 )) @@ -317,7 +317,7 @@ int ColumnBufferCompressed::writeToFile(int startOffset, int writeSize, // Start over again loading a new to-be-compressed buffer BlockOp::setEmptyBuf( fToBeCompressedBuffer, IDBCompressInterface::UNCOMPRESSED_INBUF_LEN, - (uint8_t*)&fColInfo->column.emptyVal, + fColInfo->column.emptyVal, fColInfo->column.width ); fToBeCompressedCapacity = @@ -628,7 +628,7 @@ int ColumnBufferCompressed::initToBeCompressedBuffer(long long& startFileOffset) new unsigned char[IDBCompressInterface::UNCOMPRESSED_INBUF_LEN]; BlockOp::setEmptyBuf( fToBeCompressedBuffer, IDBCompressInterface::UNCOMPRESSED_INBUF_LEN, - (uint8_t*)&fColInfo->column.emptyVal, + fColInfo->column.emptyVal, fColInfo->column.width ); bNewBuffer = true; } @@ -743,7 +743,7 @@ int ColumnBufferCompressed::initToBeCompressedBuffer(long long& startFileOffset) { BlockOp::setEmptyBuf( fToBeCompressedBuffer, IDBCompressInterface::UNCOMPRESSED_INBUF_LEN, - (uint8_t*)&fColInfo->column.emptyVal, + fColInfo->column.emptyVal, fColInfo->column.width ); } diff --git a/writeengine/bulk/we_columninfo.cpp b/writeengine/bulk/we_columninfo.cpp index 853ef8b65..7b2cd5663 100644 --- a/writeengine/bulk/we_columninfo.cpp +++ b/writeengine/bulk/we_columninfo.cpp @@ -297,6 +297,7 @@ void ColumnInfo::setupDelayedFileCreation( column.mapOid, column.compressionType, dbRoot, partition, segment ); + colOp->findTypeHandler(column.width, column.dataType); } //------------------------------------------------------------------------------ @@ -896,7 +897,7 @@ int ColumnInfo::extendColumnOldExtent( } rc = colOp->expandAbbrevColumnExtent( pFile, dbRootNext, - (uint8_t*)&column.emptyVal, column.width); + column.emptyVal, column.width); if (rc != NO_ERROR) { @@ -1422,6 +1423,7 @@ int ColumnInfo::setupInitialColumnExtent( column.mapOid, column.compressionType, dbRoot, partition, segment ); + colOp->findTypeHandler(column.width, column.dataType); // Open the column file if (!colOp->exists(column.mapOid, dbRoot, partition, segment) ) diff --git a/writeengine/bulk/we_columninfocompressed.cpp b/writeengine/bulk/we_columninfocompressed.cpp index 4fdd7f7be..25af8bc22 100644 --- a/writeengine/bulk/we_columninfocompressed.cpp +++ b/writeengine/bulk/we_columninfocompressed.cpp @@ -540,7 +540,7 @@ int ColumnInfoCompressed::extendColumnOldExtent( int rc = colOp->fillCompColumnExtentEmptyChunks( curCol.dataFile.fid, curCol.colWidth, - (uint8_t*)&column.emptyVal, + column.emptyVal, curCol.dataFile.fDbRoot, curCol.dataFile.fPartition, curCol.dataFile.fSegment, diff --git a/writeengine/server/we_dmlcommandproc.cpp b/writeengine/server/we_dmlcommandproc.cpp index 37d8693a7..f94454ad6 100644 --- a/writeengine/server/we_dmlcommandproc.cpp +++ b/writeengine/server/we_dmlcommandproc.cpp @@ -423,9 +423,6 @@ uint8_t WE_DMLCommandProc::processSingleInsert(messageqcpp::ByteStream& bs, std: // call the write engine to write the rows int error = NO_ERROR; - // MCOL-641 WIP - fWEWrapper.setDebugLevel(WriteEngine::DEBUG_3); - cout << "inserting a row with transaction id " << txnid.id << endl; fWEWrapper.setIsInsert(true); fWEWrapper.setBulkFlag(true); fWEWrapper.setTransId(txnid.id); diff --git a/writeengine/shared/we_blockop.cpp b/writeengine/shared/we_blockop.cpp index 9cb1700eb..ae2f29fff 100644 --- a/writeengine/shared/we_blockop.cpp +++ b/writeengine/shared/we_blockop.cpp @@ -25,6 +25,7 @@ #include #include "joblisttypes.h" +#include "mcs_datatype.h" #include "we_blockop.h" @@ -34,15 +35,13 @@ using namespace execplan; -#include "emptyvaluemanip.h" - namespace WriteEngine { /** * Constructor */ -BlockOp::BlockOp() +BlockOp::BlockOp(): m_typeHandler(nullptr) {} /** @@ -84,11 +83,20 @@ bool BlockOp::calculateRowId( * RETURN: * emptyVal - the value of empty row ***********************************************************/ -// TODO MCOL-641 Add support here -void BlockOp::getEmptyRowValue( - const CalpontSystemCatalog::ColDataType colDataType, const int width, uint8_t* emptyVal ) const +const uint8_t* BlockOp::getEmptyRowValue( + const CalpontSystemCatalog::ColDataType colDataType, + const int width) const { - utils::getEmptyRowValue(colDataType, width, emptyVal); + auto attrs = datatypes::SystemCatalog::TypeAttributesStd(width, 0, -1); + // Bulk operation runtime should have m_typeHandler nullptr calling this + // Non-bulk operations runtime branch + if (m_typeHandler) + return m_typeHandler->getEmptyValueForType(attrs); + + // Bulk operation branch + auto* typeHandler = datatypes::TypeHandler::find(colDataType, + attrs); + return typeHandler->getEmptyValueForType(attrs); } /*********************************************************** @@ -166,7 +174,10 @@ void BlockOp::resetBuf( unsigned char* buf, const int bufSize ) const ***********************************************************/ /* static */ void BlockOp::setEmptyBuf( - unsigned char* buf, const int bufSize, uint8_t* emptyVal, const int width ) + unsigned char* buf, + const int bufSize, + const uint8_t* emptyVal, + const int width ) { const int ARRAY_COUNT = 128; const int NBYTES_IN_ARRAY = width * ARRAY_COUNT; @@ -214,7 +225,7 @@ void BlockOp::setEmptyBuf( * none ***********************************************************/ void BlockOp::writeBufValue( - unsigned char* buf, void* val, const size_t width, const bool clear ) const + unsigned char* buf, const void* val, const size_t width, const bool clear ) const { if ( clear ) memset( buf, 0, width ); @@ -222,5 +233,16 @@ void BlockOp::writeBufValue( memcpy( buf, val, width ); } +void BlockOp::findTypeHandler(const int colWidth, + const execplan::CalpontSystemCatalog::ColDataType colDataType) + +{ + auto attrs = datatypes::SystemCatalog::TypeAttributesStd(colWidth, + 0, + -1); + m_typeHandler = datatypes::TypeHandler::find(colDataType, + attrs); +} + } //end of namespace diff --git a/writeengine/shared/we_blockop.h b/writeengine/shared/we_blockop.h index 10df5a8bb..b9bc870ea 100644 --- a/writeengine/shared/we_blockop.h +++ b/writeengine/shared/we_blockop.h @@ -89,9 +89,9 @@ public: /** * @brief Get an empty row value */ - EXPORT void getEmptyRowValue(const execplan::CalpontSystemCatalog::ColDataType colDataType, - const int width, - uint8_t* emptyVal ) const; + EXPORT const uint8_t* getEmptyRowValue(const execplan::CalpontSystemCatalog::ColDataType colDataType, + const int width) const; + /** * @brief Calculate row id @@ -117,17 +117,23 @@ public: */ EXPORT void static setEmptyBuf( unsigned char* buf, const int bufSize, - uint8_t* emptyVal, const int width ); + const uint8_t* emptyVal, + const int width ); /** * @brief Set a value in a buffer */ EXPORT void writeBufValue( unsigned char* buf, - void* val, + const void* val, const size_t width, const bool clear = false ) const; + EXPORT void findTypeHandler( const int colWidth, + const execplan::CalpontSystemCatalog::ColDataType colDataType); +private: + const datatypes::TypeHandler* m_typeHandler; }; + } //end of namespace #undef EXPORT diff --git a/writeengine/shared/we_bulkrollbackfile.cpp b/writeengine/shared/we_bulkrollbackfile.cpp index ac4cdb4ee..9bf39fa30 100644 --- a/writeengine/shared/we_bulkrollbackfile.cpp +++ b/writeengine/shared/we_bulkrollbackfile.cpp @@ -306,8 +306,7 @@ void BulkRollbackFile::reInitTruncColumnExtent( } // Initialize the remainder of the extent after the HWM block - uint8_t* emptyVal = (uint8_t*) alloca(colWidth); - fDbFile.getEmptyRowValue( colType, colWidth, emptyVal ); + const uint8_t* emptyVal = fDbFile.getEmptyRowValue( colType, colWidth ); int rc = fDbFile.reInitPartialColumnExtent( pFile, startOffset, diff --git a/writeengine/shared/we_bulkrollbackfilecompressed.cpp b/writeengine/shared/we_bulkrollbackfilecompressed.cpp index 4954930af..c149bde71 100644 --- a/writeengine/shared/we_bulkrollbackfilecompressed.cpp +++ b/writeengine/shared/we_bulkrollbackfilecompressed.cpp @@ -374,8 +374,7 @@ void BulkRollbackFileCompressed::reInitTruncColumnExtent( if (nBlocksToInit > 0) { - uint8_t* emptyVal = (uint8_t*) alloca(colWidth); - fDbFile.getEmptyRowValue( colType, colWidth, emptyVal ); + const uint8_t* emptyVal = fDbFile.getEmptyRowValue( colType, colWidth ); rc = fDbFile.reInitPartialColumnExtent( pFile, (chunkPtrs[chunkIndex].first + restoredChunkLen), nBlocksToInit, diff --git a/writeengine/shared/we_chunkmanager.cpp b/writeengine/shared/we_chunkmanager.cpp index a435ce1d4..7dd7f1027 100644 --- a/writeengine/shared/we_chunkmanager.cpp +++ b/writeengine/shared/we_chunkmanager.cpp @@ -821,8 +821,8 @@ int ChunkManager::fetchChunkFromFile(IDBDataFile* pFile, int64_t id, ChunkData*& void ChunkManager::initializeColumnChunk(char* buf, CompFileData* fileData) { int size = UNCOMPRESSED_CHUNK_SIZE; - uint8_t* emptyVal = (uint8_t*) alloca(fileData->fColWidth); - fFileOp->getEmptyRowValue(fileData->fColDataType, fileData->fColWidth, emptyVal); + const uint8_t* emptyVal = fFileOp->getEmptyRowValue(fileData->fColDataType, + fileData->fColWidth); fFileOp->setEmptyBuf((unsigned char*)buf, size, emptyVal, fileData->fColWidth); } @@ -1343,7 +1343,7 @@ inline int ChunkManager::writeHeader_(CompFileData* fileData, int ptrSecSize) // For the specified segment file (pFile), read in an abbreviated/compressed // chunk extent, uncompress, and expand to a full chunk for a full extent. //------------------------------------------------------------------------------ -int ChunkManager::expandAbbrevColumnExtent(IDBDataFile* pFile, uint8_t* emptyVal, int width) +int ChunkManager::expandAbbrevColumnExtent(IDBDataFile* pFile, const uint8_t* emptyVal, int width) { map::iterator i = fFilePtrMap.find(pFile); diff --git a/writeengine/shared/we_chunkmanager.h b/writeengine/shared/we_chunkmanager.h index 6122537e3..d2eaaafac 100644 --- a/writeengine/shared/we_chunkmanager.h +++ b/writeengine/shared/we_chunkmanager.h @@ -214,7 +214,7 @@ public: void cleanUp(const std::map& columOids); // @brief Expand an initial column, not dictionary, extent to a full extent. - int expandAbbrevColumnExtent(IDBDataFile* pFile, uint8_t* emptyVal, int width); + int expandAbbrevColumnExtent(IDBDataFile* pFile, const uint8_t* emptyVal, int width); // @brief Update column extent int updateColumnExtent(IDBDataFile* pFile, int addBlockCount); diff --git a/writeengine/shared/we_fileop.cpp b/writeengine/shared/we_fileop.cpp index 23e285e47..7bfe9a32e 100644 --- a/writeengine/shared/we_fileop.cpp +++ b/writeengine/shared/we_fileop.cpp @@ -161,7 +161,7 @@ int FileOp::createDir( const char* dirName, mode_t mode ) const * ERR_FILE_CREATE if can not create the file ***********************************************************/ int FileOp::createFile( const char* fileName, int numOfBlock, - uint8_t* emptyVal, int width, + const uint8_t* emptyVal, int width, uint16_t dbRoot ) { IDBDataFile* pFile = @@ -228,7 +228,7 @@ int FileOp::createFile(FID fid, uint16_t dbRoot, uint32_t partition, execplan::CalpontSystemCatalog::ColDataType colDataType, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width) { //std::cout << "Creating file oid: " << fid << @@ -569,7 +569,7 @@ bool FileOp::existsOIDDir( FID fid ) const ***********************************************************/ int FileOp::extendFile( OID oid, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width, HWM hwm, BRM::LBID_t startLbid, @@ -875,7 +875,7 @@ int FileOp::extendFile( ***********************************************************/ int FileOp::addExtentExactFile( OID oid, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width, int& allocSize, uint16_t dbRoot, @@ -1045,7 +1045,7 @@ int FileOp::initColumnExtent( IDBDataFile* pFile, uint16_t dbRoot, int nBlocks, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width, bool bNewFile, bool bExpandExtent, @@ -1225,7 +1225,7 @@ int FileOp::initAbbrevCompColumnExtent( IDBDataFile* pFile, uint16_t dbRoot, int nBlocks, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width) { // Reserve disk space for optimized abbreviated extent @@ -1285,7 +1285,7 @@ int FileOp::writeInitialCompColumnChunk( IDBDataFile* pFile, int nBlocksAllocated, int nRows, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width, char* hdrs) { @@ -1366,7 +1366,7 @@ int FileOp::writeInitialCompColumnChunk( ***********************************************************/ int FileOp::fillCompColumnExtentEmptyChunks(OID oid, int colWidth, - uint8_t* emptyVal, + const uint8_t* emptyVal, uint16_t dbRoot, uint32_t partition, uint16_t segment, @@ -1671,7 +1671,7 @@ int FileOp::fillCompColumnExtentEmptyChunks(OID oid, ***********************************************************/ int FileOp::expandAbbrevColumnChunk( IDBDataFile* pFile, - uint8_t* emptyVal, + const uint8_t* emptyVal, int colWidth, const CompChunkPtr& chunkInPtr, CompChunkPtr& chunkOutPtr ) @@ -2036,7 +2036,7 @@ int FileOp::reInitPartialColumnExtent( IDBDataFile* pFile, long long startOffset, int nBlocks, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width ) { int rc = setFileOffset( pFile, startOffset, SEEK_SET ); @@ -2845,7 +2845,7 @@ bool FileOp::isDiskSpaceAvail(const std::string& fileName, int nBlocks) const int FileOp::expandAbbrevColumnExtent( IDBDataFile* pFile, // FILE ptr to file where abbrev extent is to be expanded uint16_t dbRoot, // The DBRoot of the file with the abbreviated extent - uint8_t* emptyVal,// Empty value to be used in expanding the extent + const uint8_t* emptyVal,// Empty value to be used in expanding the extent int width ) // Width of the column (in bytes) { // Based on extent size, see how many blocks to add to fill the extent diff --git a/writeengine/shared/we_fileop.h b/writeengine/shared/we_fileop.h index 0615eaef8..b7f908a14 100644 --- a/writeengine/shared/we_fileop.h +++ b/writeengine/shared/we_fileop.h @@ -92,7 +92,7 @@ public: int& allocSize, uint16_t dbRoot, uint32_t partition, execplan::CalpontSystemCatalog::ColDataType colDataType, - uint8_t* emptyVal, int width = 1 ) ; + const uint8_t* emptyVal, int width = 1 ) ; /** @@ -100,7 +100,7 @@ public: * Changed to public for UT. */ int createFile( const char* fileName, int fileSize, - uint8_t* emptyVal, int width, + const uint8_t* emptyVal, int width, uint16_t dbRoot ); /** @@ -163,7 +163,7 @@ public: EXPORT virtual int expandAbbrevColumnExtent( IDBDataFile* pFile, uint16_t dbRoot, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width ); /** @@ -198,7 +198,7 @@ public: * @param hdrs (in/out) Contents of headers, if file is compressed. * @return returns NO_ERROR if success. */ - EXPORT int extendFile(OID oid, uint8_t* emptyVal, + EXPORT int extendFile(OID oid, const uint8_t* emptyVal, int width, HWM hwm, BRM::LBID_t startLbid, @@ -226,7 +226,7 @@ public: * @param newFile (out) Indicates if a new file was created for the extent * @param hdrs (in/out) Contents of headers, if file is compressed. */ - EXPORT int addExtentExactFile(OID oid, uint8_t* emptyVal, + EXPORT int addExtentExactFile(OID oid, const uint8_t* emptyVal, int width, int& allocSize, uint16_t dbRoot, @@ -253,7 +253,7 @@ public: */ EXPORT int fillCompColumnExtentEmptyChunks(OID oid, int colWidth, - uint8_t* emptyVal, + const uint8_t* emptyVal, uint16_t dbRoot, uint32_t partition, uint16_t segment, @@ -433,7 +433,7 @@ public: EXPORT int reInitPartialColumnExtent( IDBDataFile* pFile, long long startOffset, int nBlocks, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width ); /** @@ -497,7 +497,7 @@ public: int initColumnExtent( IDBDataFile* pFile, uint16_t dbRoot, int nBlocks, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width, bool bNewFile, bool bExpandExtent, @@ -519,7 +519,7 @@ private: FileOp& operator=(const FileOp& rhs); int expandAbbrevColumnChunk( IDBDataFile* pFile, - uint8_t* emptyVal, + const uint8_t* emptyVal, int colWidth, const compress::CompChunkPtr& chunkInPtr, compress::CompChunkPtr& chunkOutPt); @@ -527,7 +527,7 @@ private: int initAbbrevCompColumnExtent( IDBDataFile* pFile, uint16_t dbRoot, int nBlocks, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width); static void initDbRootExtentMutexes(); @@ -536,7 +536,7 @@ private: int writeInitialCompColumnChunk( IDBDataFile* pFile, int nBlocksAllocated, int nRows, - uint8_t* emptyVal, + const uint8_t* emptyVal, int width, char* hdrs); diff --git a/writeengine/shared/we_type.h b/writeengine/shared/we_type.h index dcda94bb4..791b568d7 100644 --- a/writeengine/shared/we_type.h +++ b/writeengine/shared/we_type.h @@ -347,7 +347,7 @@ struct JobColumn /** @brief Job Column Structure */ execplan::CalpontSystemCatalog::ColDataType dataType; /** @brief column data type */ ColType weType; /** @brief write engine data type */ std::string typeName; /** @brief data type name */ - uint128_t emptyVal; /** @brief default empty value */ + const uint8_t* emptyVal; /** @brief default empty value */ int width; /** @brief column width; for a dictionary column, this is "eventually" the token width */ int definedWidth; /** @brief column width as defined in the table, used for non-dictionary strings */ int dctnryWidth; /** @brief dictionary width */ @@ -370,7 +370,7 @@ struct JobColumn /** @brief Job Column Structure */ int128_t fDefaultWideDecimal; /** @brief Wide decimal column default */ std::string fDefaultChr; /** @brief Char column default */ JobColumn() : mapOid(0), dataType(execplan::CalpontSystemCatalog::INT), weType(WR_INT), - typeName("integer"), emptyVal(0), + typeName("integer"), emptyVal(nullptr), width(0), definedWidth(0), dctnryWidth(0), precision(0), scale(0), fNotNull(false), fFldColRelation(BULK_FLDCOL_COLUMN_FIELD), colType(' '), diff --git a/writeengine/wrapper/we_colop.cpp b/writeengine/wrapper/we_colop.cpp index a7f41e5e5..c4ca4944c 100644 --- a/writeengine/wrapper/we_colop.cpp +++ b/writeengine/wrapper/we_colop.cpp @@ -45,7 +45,6 @@ using namespace execplan; using namespace idbdatafile; -#include "emptyvaluemanip.h" #include "mcs_decimal.h" namespace WriteEngine @@ -88,7 +87,6 @@ ColumnOp::~ColumnOp() * NO_ERROR if success * rowIdArray - allocation of the row id left here ***********************************************************/ -// TODO MCOL-641 add support here int ColumnOp::allocRowId(const TxnID& txnid, bool useStartingExtent, Column& column, uint64_t totalRow, RID* rowIdArray, HWM& hwm, bool& newExtent, uint64_t& rowsLeft, HWM& newHwm, bool& newFile, ColStructList& newColStructList, DctnryStructList& newDctnryStructList, std::vector >& dbRootExtentTrackers, @@ -129,9 +127,8 @@ int ColumnOp::allocRowId(const TxnID& txnid, bool useStartingExtent, Column newCol; unsigned char buf[BYTE_PER_BLOCK]; unsigned char* curVal; - uint8_t* emptyVal = (uint8_t*) alloca(column.colWidth); - getEmptyRowValue(column.colDataType, column.colWidth, emptyVal); - + const uint8_t* emptyVal = getEmptyRowValue(column.colDataType, + column.colWidth); if (useStartingExtent) { // ZZ. For insert select, skip the hwm block and start inserting from the next block @@ -191,8 +188,6 @@ int ColumnOp::allocRowId(const TxnID& txnid, bool useStartingExtent, { if (rc == ERR_FILE_EOF) { - uint8_t* emptyVal = (uint8_t*) alloca(column.colWidth); - getEmptyRowValue(column.colDataType, column.colWidth, emptyVal); setEmptyBuf(buf, BYTE_PER_BLOCK, emptyVal, column.colWidth); RETURN_ON_ERROR(saveBlock(column.dataFile.pFile, buf, hwm)); } @@ -290,8 +285,6 @@ int ColumnOp::allocRowId(const TxnID& txnid, bool useStartingExtent, if (newColStructList[i].fCompressionType > 0) { - uint8_t* emptyVal = (uint8_t*) alloca(newColStructList[i].colWidth); - getEmptyRowValue(newColStructList[i].colDataType, newColStructList[i].colWidth, emptyVal); string errorInfo; rc = fileOp.fillCompColumnExtentEmptyChunks(newColStructList[i].dataOid, newColStructList[i].colWidth, emptyVal, dbRoot, partition, segment, newHwm, segFile, errorInfo); @@ -317,8 +310,6 @@ int ColumnOp::allocRowId(const TxnID& txnid, bool useStartingExtent, return rc; } - uint8_t* emptyVal = (uint8_t*) alloca(newColStructList[i].colWidth); - getEmptyRowValue(newColStructList[i].colDataType, newColStructList[i].colWidth, emptyVal); rc = fileOp.expandAbbrevColumnExtent( pFile, dbRoot, emptyVal, newColStructList[i].colWidth); //set hwm for this extent. fileOp.closeFile(pFile); @@ -495,8 +486,6 @@ int ColumnOp::allocRowId(const TxnID& txnid, bool useStartingExtent, { if (rc == ERR_FILE_EOF) { - uint8_t* emptyVal = (uint8_t*) alloca(newCol.colWidth); - getEmptyRowValue(newCol.colDataType, newCol.colWidth, emptyVal); setEmptyBuf(buf, BYTE_PER_BLOCK, emptyVal, newCol.colWidth); RETURN_ON_ERROR(saveBlock(newCol.dataFile.pFile, buf, newHwm)); } @@ -538,8 +527,6 @@ int ColumnOp::allocRowId(const TxnID& txnid, bool useStartingExtent, { if (rc == ERR_FILE_EOF) { - uint8_t* emptyVal = (uint8_t*) alloca(newCol.colWidth); - getEmptyRowValue(newCol.colDataType, newCol.colWidth, emptyVal); setEmptyBuf(buf, BYTE_PER_BLOCK, emptyVal, newCol.colWidth); RETURN_ON_ERROR(saveBlock(newCol.dataFile.pFile, buf, newHwm)); } @@ -652,8 +639,8 @@ int ColumnOp::createColumn(Column& column, int rc, newWidth, allocSize; int compressionType = column.compressionType; setColParam(column, colNo, colWidth, colDataType, colType); - uint8_t* emptyVal = (uint8_t*) alloca(colWidth); - getEmptyRowValue(colDataType, colWidth, emptyVal); + const uint8_t* emptyVal = getEmptyRowValue(colDataType, + colWidth); newWidth = getCorrectRowWidth(colDataType, colWidth); column.dataFile.fid = dataFid; column.dataFile.fDbRoot = dbRoot; @@ -720,10 +707,10 @@ int ColumnOp::fillColumn(const TxnID& txnid, Column& column, Column& refCol, voi config.initConfigCache(); std::vector rootList; config.getRootIdList( rootList ); - uint8_t* emptyVal = (uint8_t*) alloca(column.colWidth); - uint8_t* refEmptyVal = (uint8_t*) alloca(refCol.colWidth); - getEmptyRowValue(column.colDataType, column.colWidth, emptyVal); - getEmptyRowValue(refCol.colDataType, refCol.colWidth, refEmptyVal); + const uint8_t* emptyVal = getEmptyRowValue(column.colDataType, + column.colWidth); + const uint8_t* refEmptyVal = getEmptyRowValue(refCol.colDataType, + refCol.colWidth); //find the dbroots which have rows for refrence column unsigned int i = 0, k = 0; @@ -1335,8 +1322,8 @@ int ColumnOp::extendColumn( bool& newFile, char* hdrs) { - uint8_t* emptyVal = (uint8_t*) alloca(column.colWidth); - getEmptyRowValue(column.colDataType, column.colWidth, emptyVal); + const uint8_t* emptyVal = getEmptyRowValue(column.colDataType, + column.colWidth); int rc = extendFile(column.dataFile.fid, emptyVal, column.colWidth, @@ -1377,8 +1364,8 @@ int ColumnOp::addExtent( int& allocSize, char* hdrs) { - uint8_t* emptyVal = (uint8_t*) alloca(column.colWidth); - getEmptyRowValue(column.colDataType, column.colWidth, emptyVal); + const uint8_t* emptyVal = getEmptyRowValue(column.colDataType, + column.colWidth); int rc = addExtentExactFile(column.dataFile.fid, emptyVal, column.colWidth, @@ -1406,8 +1393,8 @@ int ColumnOp::addExtent( ***********************************************************/ int ColumnOp::expandAbbrevExtent(const Column& column) { - uint8_t* emptyVal = (uint8_t*) alloca(column.colWidth); - getEmptyRowValue(column.colDataType, column.colWidth, emptyVal); + const uint8_t* emptyVal = getEmptyRowValue(column.colDataType, + column.colWidth); int rc = expandAbbrevColumnExtent(column.dataFile.pFile, column.dataFile.fDbRoot, emptyVal, @@ -1463,7 +1450,9 @@ void ColumnOp::initColumn(Column& column) const * RETURN: * true if success, false otherwise ***********************************************************/ -inline bool ColumnOp::isEmptyRow(uint64_t* curVal, uint8_t* emptyVal, const int colWidth) +inline bool ColumnOp::isEmptyRow(uint64_t* curVal, + const uint8_t* emptyVal, + const int colWidth) { // colWidth is either 1, 2, 4, 8, or 16 (Convertor::getCorrectRowWidth) switch(colWidth){ @@ -1482,9 +1471,6 @@ inline bool ColumnOp::isEmptyRow(uint64_t* curVal, uint8_t* emptyVal, const int case 16: return *(uint128_t*)curVal == *(uint128_t*)emptyVal; - //case 32: - // return ((curVal[0] == emptyVal) && (curVal[1] == emptyVal) - // && (curVal[2] == emptyVal) && (curVal[3] == emptyVal)); } return false; @@ -1634,9 +1620,8 @@ int ColumnOp::writeRow(Column& curCol, uint64_t totalRow, const RID* rowIdArray, int dataFbo, dataBio, curDataFbo = -1; unsigned char dataBuf[BYTE_PER_BLOCK]; bool bExit = false, bDataDirty = false; - void* pVal = 0; + const void* pVal = 0; char charTmpBuf[8]; - uint8_t* emptyVal = (uint8_t*) alloca(curCol.colWidth); int rc = NO_ERROR; uint16_t rowsInBlock = BYTE_PER_BLOCK / curCol.colWidth; @@ -1745,8 +1730,8 @@ int ColumnOp::writeRow(Column& curCol, uint64_t totalRow, const RID* rowIdArray, if (bDelete) { - utils::getEmptyRowValue(curCol.colDataType, curCol.colWidth, emptyVal); - pVal = emptyVal; + pVal = getEmptyRowValue(curCol.colDataType, + curCol.colWidth); } // This is the write stuff @@ -1788,10 +1773,9 @@ int ColumnOp::writeRows(Column& curCol, uint64_t totalRow, const RIDList& ridLis int dataFbo, dataBio, curDataFbo = -1; unsigned char dataBuf[BYTE_PER_BLOCK]; bool bExit = false, bDataDirty = false; - void* pVal = 0; + const void* pVal = 0; //void* pOldVal; char charTmpBuf[8]; - uint8_t* emptyVal; int rc = NO_ERROR; while (!bExit) @@ -1894,9 +1878,8 @@ int ColumnOp::writeRows(Column& curCol, uint64_t totalRow, const RIDList& ridLis } else { - emptyVal = (uint8_t*) alloca(curCol.colWidth); - getEmptyRowValue(curCol.colDataType, curCol.colWidth, emptyVal); - pVal = emptyVal; + pVal = getEmptyRowValue(curCol.colDataType, + curCol.colWidth); } writeBufValue(dataBuf + dataBio, pVal, curCol.colWidth); diff --git a/writeengine/wrapper/we_colop.h b/writeengine/wrapper/we_colop.h index 1b2d5dcc7..8735c3c36 100644 --- a/writeengine/wrapper/we_colop.h +++ b/writeengine/wrapper/we_colop.h @@ -220,7 +220,9 @@ public: /** * @brief Check whether it is an empty row */ - EXPORT virtual bool isEmptyRow(uint64_t* curVal, uint8_t* emptyVal, const int colWidth); + EXPORT virtual bool isEmptyRow(uint64_t* curVal, + const uint8_t* emptyVal, + const int colWidth); /** * @brief Check whether it is a valid column diff --git a/writeengine/wrapper/we_colopcompress.cpp b/writeengine/wrapper/we_colopcompress.cpp index 4b06c429d..4337c6026 100644 --- a/writeengine/wrapper/we_colopcompress.cpp +++ b/writeengine/wrapper/we_colopcompress.cpp @@ -191,7 +191,7 @@ int ColumnOpCompress1::flushFile(int rc, std::map& columnOids) int ColumnOpCompress1::expandAbbrevColumnExtent( - IDBDataFile* pFile, uint16_t dbRoot, uint8_t* emptyVal, int width) + IDBDataFile* pFile, uint16_t dbRoot, const uint8_t* emptyVal, int width) { // update the uncompressed initial chunk to full chunk int rc = m_chunkManager->expandAbbrevColumnExtent(pFile, emptyVal, width); diff --git a/writeengine/wrapper/we_colopcompress.h b/writeengine/wrapper/we_colopcompress.h index 5b6635dac..0b865fb1b 100644 --- a/writeengine/wrapper/we_colopcompress.h +++ b/writeengine/wrapper/we_colopcompress.h @@ -111,7 +111,7 @@ public: /** * @brief virtual method in FileOp */ - int expandAbbrevColumnExtent(IDBDataFile* pFile, uint16_t dbRoot, uint8_t* emptyVal, int width); + int expandAbbrevColumnExtent(IDBDataFile* pFile, uint16_t dbRoot, const uint8_t* emptyVal, int width); /** * @brief virtual method in ColumnOp diff --git a/writeengine/wrapper/writeengine.cpp b/writeengine/wrapper/writeengine.cpp index ce82bec28..96fb3a895 100644 --- a/writeengine/wrapper/writeengine.cpp +++ b/writeengine/wrapper/writeengine.cpp @@ -624,6 +624,9 @@ int WriteEngineWrapper::createColumn( int compress_op = op(compressionType); m_colOp[compress_op]->initColumn(curCol); + m_colOp[compress_op]->findTypeHandler(dataWidth, dataType); + + rc = m_colOp[compress_op]->createColumn(curCol, 0, dataWidth, dataType, WriteEngine::WR_CHAR, (FID)dataOid, dbRoot, partition); @@ -708,8 +711,13 @@ int WriteEngineWrapper::fillColumn(const TxnID& txnid, const OID& dataOid, Convertor::convertColType(refColDataType, refColWidth, refColType, isToken); refColOp->setColParam(refCol, 0, refColOp->getCorrectRowWidth(refColDataType, refColWidth), refColDataType, refColType, (FID)refColOID, refCompressionType, dbRoot); - colOpNewCol->setColParam(newCol, 0, newDataWidth, + refColOp->findTypeHandler(refColOp->getCorrectRowWidth(refColDataType, + refColWidth), + refColDataType); + colOpNewCol->setColParam(newCol, 0, newDataWidth, colType.colDataType, newColType, (FID)dataOid, compressionType, dbRoot); + colOpNewCol->findTypeHandler(newDataWidth, colType.colDataType); + int size = sizeof(Token); @@ -761,8 +769,6 @@ int WriteEngineWrapper::deleteRow(const TxnID& txnid, const vector setTransId(txnid); unsigned numExtents = colExtentsStruct.size(); - uint128_t emptyVal; - for (unsigned extent = 0; extent < numExtents; extent++) { colStructList = colExtentsStruct[extent]; @@ -775,9 +781,13 @@ int WriteEngineWrapper::deleteRow(const TxnID& txnid, const vector cscColType = cscColTypeList[i]; Convertor::convertColType(&curColStruct); - m_colOp[op(curColStruct.fCompressionType)]-> - getEmptyRowValue(curColStruct.colDataType, curColStruct.colWidth, (uint8_t*)&emptyVal); - curTuple.data = emptyVal; + const uint8_t* emptyVal = m_colOp[op(curColStruct.fCompressionType)]-> + getEmptyRowValue(curColStruct.colDataType, curColStruct.colWidth); + + if (curColStruct.colWidth == datatypes::MAXDECIMALWIDTH) + curTuple.data = *(int128_t*)emptyVal; + else + curTuple.data = *(int64_t*)emptyVal; curTupleList.push_back(curTuple); colValueList.push_back(curTupleList); @@ -854,6 +864,7 @@ int WriteEngineWrapper::deleteBadRows(const TxnID& txnid, ColStructList& colStru colStructs[i].colDataType, colStructs[i].colType, colStructs[i].dataOid, colStructs[i].fCompressionType, colStructs[i].fColDbRoot, colStructs[i].fColPartition, colStructs[i].fColSegment); + colOp->findTypeHandler(colStructs[i].colWidth, colStructs[i].colDataType); string segFile; rc = colOp->openColumnFile(curCol, segFile, true, IO_BUFF_SIZE); // @bug 5572 HDFS tmp file @@ -1085,6 +1096,8 @@ int WriteEngineWrapper::insertColumnRecs(const TxnID& txnid, colOp->setColParam(curCol, colId, colStructList[i].colWidth, colStructList[i].colDataType, colStructList[i].colType, colStructList[i].dataOid, colStructList[i].fCompressionType, dbRoot, partitionNum, segmentNum); + colOp->findTypeHandler(colStructList[i].colWidth, + colStructList[i].colDataType); rc = colOp->extendColumn(curCol, false, extents[i].startBlkOffset, extents[i].startLbid, extents[i].allocSize, dbRoot, partitionNum, segmentNum, segFile, pFile, newFile); @@ -1314,9 +1327,11 @@ int WriteEngineWrapper::insertColumnRecs(const TxnID& txnid, oldHwm = hwm; //Save this info for rollback //need to pass real dbRoot, partition, and segment to setColParam - colOp->setColParam(curCol, colId, curColStruct.colWidth, curColStruct.colDataType, + colOp->setColParam(curCol, colId, curColStruct.colWidth, curColStruct.colDataType, curColStruct.colType, curColStruct.dataOid, curColStruct.fCompressionType, curColStruct.fColDbRoot, curColStruct.fColPartition, curColStruct.fColSegment); + colOp->findTypeHandler(curColStruct.colWidth, + curColStruct.colDataType); rc = colOp->openColumnFile(curCol, segFile, useTmpSuffix); // @bug 5572 HDFS tmp file if (rc != NO_ERROR) @@ -1377,6 +1392,8 @@ int WriteEngineWrapper::insertColumnRecs(const TxnID& txnid, colStructList[k].fColDbRoot, colStructList[k].fColPartition, colStructList[k].fColSegment); + colOp->findTypeHandler(colStructList[k].colWidth, + colStructList[k].colDataType); rc = colOp->openColumnFile(expandCol, segFile, true); // @bug 5572 HDFS tmp file if (rc == NO_ERROR) @@ -1844,6 +1861,8 @@ int WriteEngineWrapper::insertColumnRecsBinary(const TxnID& txnid, colOp->setColParam(curCol, 0, colStructList[i].colWidth, colStructList[i].colDataType, colStructList[i].colType, colStructList[i].dataOid, colStructList[i].fCompressionType, dbRoot, partitionNum, segmentNum); + colOp->findTypeHandler(colStructList[i].colWidth, + colStructList[i].colDataType); rc = colOp->extendColumn(curCol, false, extents[i].startBlkOffset, extents[i].startLbid, extents[i].allocSize, dbRoot, partitionNum, segmentNum, segFile, pFile, newFile); @@ -2080,6 +2099,8 @@ int WriteEngineWrapper::insertColumnRecsBinary(const TxnID& txnid, colOp->setColParam(curCol, colId, curColStruct.colWidth, curColStruct.colDataType, curColStruct.colType, curColStruct.dataOid, curColStruct.fCompressionType, curColStruct.fColDbRoot, curColStruct.fColPartition, curColStruct.fColSegment); + colOp->findTypeHandler(curColStruct.colWidth, + curColStruct.colDataType); rc = colOp->openColumnFile(curCol, segFile, useTmpSuffix); // @bug 5572 HDFS tmp file if (rc != NO_ERROR) @@ -2144,6 +2165,8 @@ int WriteEngineWrapper::insertColumnRecsBinary(const TxnID& txnid, colStructList[k].fColDbRoot, colStructList[k].fColPartition, colStructList[k].fColSegment); + colOp->findTypeHandler(colStructList[k].colWidth, + colStructList[k].colDataType); rc = colOp->openColumnFile(expandCol, segFile, true); // @bug 5572 HDFS tmp file if (rc == NO_ERROR) @@ -2587,7 +2610,8 @@ int WriteEngineWrapper::insertColumnRec_SYS(const TxnID& txnid, colOp->setColParam(curCol, 0, curColStruct.colWidth, curColStruct.colDataType, curColStruct.colType, curColStruct.dataOid, curColStruct.fCompressionType, dbRoot, partitionNum, segmentNum); - + colOp->findTypeHandler(curColStruct.colWidth, + curColStruct.colDataType); string segFile; rc = colOp->openColumnFile(curCol, segFile, false); // @bug 5572 HDFS tmp file @@ -2698,6 +2722,8 @@ int WriteEngineWrapper::insertColumnRec_SYS(const TxnID& txnid, dbRoot, partitionNum, segmentNum); + colOp->findTypeHandler(colStructList[k].colWidth, + colStructList[k].colDataType); rc = colOp->openColumnFile(expandCol, segFile, false); // @bug 5572 HDFS tmp file if (rc == NO_ERROR) @@ -2942,6 +2968,8 @@ int WriteEngineWrapper::insertColumnRec_SYS(const TxnID& txnid, newColStructList[i].colWidth, newColStructList[i].colDataType, newColStructList[i].colType, newColStructList[i].dataOid, newColStructList[i].fCompressionType, dbRoot, partitionNum, segmentNum); + colOp->findTypeHandler(newColStructList[i].colWidth, + newColStructList[i].colDataType); rc = BRMWrapper::getInstance()->getLastHWM_DBroot( curColLocal.dataFile.fid, dbRoot, partitionNum, segmentNum, oldHwm, @@ -3257,7 +3285,8 @@ int WriteEngineWrapper::insertColumnRec_Single(const TxnID& txnid, colOp->setColParam(curCol, colId, curColStruct.colWidth, curColStruct.colDataType, curColStruct.colType, curColStruct.dataOid, curColStruct.fCompressionType, dbRoot, partitionNum, segmentNum); - + colOp->findTypeHandler(curColStruct.colWidth, + curColStruct.colDataType); string segFile; if (bUseStartExtent) @@ -3392,6 +3421,8 @@ int WriteEngineWrapper::insertColumnRec_Single(const TxnID& txnid, colStructList[k].fColDbRoot, colStructList[k].fColPartition, colStructList[k].fColSegment); + colOp->findTypeHandler(colStructList[k].colWidth, + colStructList[k].colDataType); rc = colOp->openColumnFile(expandCol, segFile, true); // @bug 5572 HDFS tmp file if (rc == NO_ERROR) @@ -4363,7 +4394,8 @@ int WriteEngineWrapper::writeColumnRecords(const TxnID& txnid, curColStruct.colDataType, curColStruct.colType, curColStruct.dataOid, curColStruct.fCompressionType, curColStruct.fColDbRoot, curColStruct.fColPartition, curColStruct.fColSegment); - + colOp->findTypeHandler(curColStruct.colWidth, + curColStruct.colDataType); ColExtsInfo aColExtsInfo = aTbaleMetaData->getColExtsInfo(curColStruct.dataOid); ColExtsInfo::iterator it = aColExtsInfo.begin(); @@ -4543,6 +4575,8 @@ int WriteEngineWrapper::writeColumnRec(const TxnID& txnid, colStructList[i].colDataType, colStructList[i].colType, colStructList[i].dataOid, colStructList[i].fCompressionType, colStructList[i].fColDbRoot, colStructList[i].fColPartition, colStructList[i].fColSegment); + colOp->findTypeHandler(colStructList[i].colWidth, + colStructList[i].colDataType); ColExtsInfo aColExtsInfo = aTbaleMetaData->getColExtsInfo(colStructList[i].dataOid); ColExtsInfo::iterator it = aColExtsInfo.begin(); @@ -4665,6 +4699,8 @@ int WriteEngineWrapper::writeColumnRec(const TxnID& txnid, newColStructList[i].colDataType, newColStructList[i].colType, newColStructList[i].dataOid, newColStructList[i].fCompressionType, newColStructList[i].fColDbRoot, newColStructList[i].fColPartition, newColStructList[i].fColSegment); + colOp->findTypeHandler(newColStructList[i].colWidth, + newColStructList[i].colDataType); ColExtsInfo aColExtsInfo = aTbaleMetaData->getColExtsInfo(newColStructList[i].dataOid); ColExtsInfo::iterator it = aColExtsInfo.begin(); @@ -4784,6 +4820,8 @@ int WriteEngineWrapper::writeColumnRec(const TxnID& txnid, colStructList[i].colDataType, colStructList[i].colType, colStructList[i].dataOid, colStructList[i].fCompressionType, colStructList[i].fColDbRoot, colStructList[i].fColPartition, colStructList[i].fColSegment); + colOp->findTypeHandler(colStructList[i].colWidth, + colStructList[i].colDataType); rc = colOp->openColumnFile(curCol, segFile, useTmpSuffix, IO_BUFF_SIZE); // @bug 5572 HDFS tmp file @@ -4957,6 +4995,8 @@ int WriteEngineWrapper::writeColumnRecBinary(const TxnID& txnid, colStructList[i].colDataType, colStructList[i].colType, colStructList[i].dataOid, colStructList[i].fCompressionType, colStructList[i].fColDbRoot, colStructList[i].fColPartition, colStructList[i].fColSegment); + colOp->findTypeHandler(colStructList[i].colWidth, + colStructList[i].colDataType); ColExtsInfo aColExtsInfo = aTbaleMetaData->getColExtsInfo(colStructList[i].dataOid); ColExtsInfo::iterator it = aColExtsInfo.begin(); @@ -5106,6 +5146,8 @@ int WriteEngineWrapper::writeColumnRecBinary(const TxnID& txnid, newColStructList[i].colDataType, newColStructList[i].colType, newColStructList[i].dataOid, newColStructList[i].fCompressionType, newColStructList[i].fColDbRoot, newColStructList[i].fColPartition, newColStructList[i].fColSegment); + colOp->findTypeHandler(newColStructList[i].colWidth, + newColStructList[i].colDataType); ColExtsInfo aColExtsInfo = aTbaleMetaData->getColExtsInfo(newColStructList[i].dataOid); ColExtsInfo::iterator it = aColExtsInfo.begin(); @@ -5321,6 +5363,8 @@ int WriteEngineWrapper::writeColumnRec(const TxnID& txnid, curColStruct.colDataType, curColStruct.colType, curColStruct.dataOid, curColStruct.fCompressionType, curColStruct.fColDbRoot, curColStruct.fColPartition, curColStruct.fColSegment); + colOp->findTypeHandler(curColStruct.colWidth, + curColStruct.colDataType); ColExtsInfo aColExtsInfo = aTbaleMetaData->getColExtsInfo(curColStruct.dataOid);