diff --git a/datatypes/mcs_datatype.cpp b/datatypes/mcs_datatype.cpp index c33269dbb..59bc2bf21 100644 --- a/datatypes/mcs_datatype.cpp +++ b/datatypes/mcs_datatype.cpp @@ -592,7 +592,7 @@ string TypeHandlerDatetime::format(const SimpleValue& v, const SystemCatalog::Ty string TypeHandlerTimestamp::format(const SimpleValue& v, const SystemCatalog::TypeAttributesStd& attr) const { - return DataConvert::timestampToString(v.toSInt64(), v.tzname()); + return DataConvert::timestampToString(v.toSInt64(), v.timeZone()); } string TypeHandlerTime::format(const SimpleValue& v, const SystemCatalog::TypeAttributesStd& attr) const @@ -893,8 +893,8 @@ class SimpleConverter : public boost::any public: SimpleConverter(const SessionParam& sp, const TypeHandler* h, const SystemCatalog::TypeAttributesStd& attr, const char* str) - : boost::any( - h->convertFromString(attr, ConvertFromStringParam(sp.tzname(), true, false), str, initPushWarning())) + : boost::any(h->convertFromString(attr, ConvertFromStringParam(sp.timeZone(), true, false), str, + initPushWarning())) { } round_style_t roundStyle() const @@ -1059,7 +1059,7 @@ SimpleValue TypeHandlerTimestamp::toSimpleValue(const SessionParam& sp, { idbassert(attr.colWidth <= SystemCatalog::EIGHT_BYTE); SimpleConverter anyVal(sp, this, attr, str); - return SimpleValueTimestamp(anyVal.to_uint64(), sp.tzname()); + return SimpleValueTimestamp(anyVal.to_uint64(), sp.timeZone()); } SimpleValue TypeHandlerTime::toSimpleValue(const SessionParam& sp, diff --git a/datatypes/mcs_datatype.h b/datatypes/mcs_datatype.h index 38a113db4..a2686b45e 100644 --- a/datatypes/mcs_datatype.h +++ b/datatypes/mcs_datatype.h @@ -561,30 +561,30 @@ enum class round_style_t : uint8_t class SessionParam { - const char* m_tzname; + long m_timeZone; public: - SessionParam(const char* tzname) : m_tzname(tzname) + SessionParam(long timeZone) : m_timeZone(timeZone) { } - const char* tzname() const + long timeZone() const { - return m_tzname; + return m_timeZone; } }; class ConvertFromStringParam { - const std::string& m_timeZone; + const long m_timeZone; const bool m_noRoundup; const bool m_isUpdate; public: - ConvertFromStringParam(const std::string& timeZone, bool noRoundup, bool isUpdate) + ConvertFromStringParam(long timeZone, bool noRoundup, bool isUpdate) : m_timeZone(timeZone), m_noRoundup(noRoundup), m_isUpdate(isUpdate) { } - const std::string& timeZone() const + long timeZone() const { return m_timeZone; } @@ -602,14 +602,14 @@ class SimpleValue { int64_t m_sint64; int128_t m_sint128; - const char* m_tzname; + long m_timeZone; public: - SimpleValue(const int64_t sint64, const int128_t& sint128, const char* tzname) - : m_sint64(sint64), m_sint128(sint128), m_tzname(tzname) + SimpleValue(const int64_t sint64, const int128_t& sint128, long timeZone) + : m_sint64(sint64), m_sint128(sint128), m_timeZone(timeZone) { } - SimpleValue() : m_sint64(0), m_sint128(0), m_tzname(0) + SimpleValue() : m_sint64(0), m_sint128(0), m_timeZone(0) { } int64_t toSInt64() const @@ -624,16 +624,16 @@ class SimpleValue { return m_sint128; } - const char* tzname() const + long timeZone() const { - return m_tzname; + return m_timeZone; } }; class SimpleValueSInt64 : public SimpleValue { public: - SimpleValueSInt64(int64_t value) : SimpleValue(value, 0, NULL) + SimpleValueSInt64(int64_t value) : SimpleValue(value, 0, 0) { } }; @@ -641,7 +641,7 @@ class SimpleValueSInt64 : public SimpleValue class SimpleValueUInt64 : public SimpleValue { public: - SimpleValueUInt64(uint64_t value) : SimpleValue(static_cast(value), 0, NULL) + SimpleValueUInt64(uint64_t value) : SimpleValue(static_cast(value), 0, 0) { } }; @@ -649,7 +649,7 @@ class SimpleValueUInt64 : public SimpleValue class SimpleValueSInt128 : public SimpleValue { public: - SimpleValueSInt128(int128_t value) : SimpleValue(0, value, NULL) + SimpleValueSInt128(int128_t value) : SimpleValue(0, value, 0) { } }; @@ -657,8 +657,7 @@ class SimpleValueSInt128 : public SimpleValue class SimpleValueTimestamp : public SimpleValue { public: - SimpleValueTimestamp(uint64_t value, const char* tzname) - : SimpleValue(static_cast(value), 0, tzname) + SimpleValueTimestamp(uint64_t value, long timeZone) : SimpleValue(static_cast(value), 0, timeZone) { } }; diff --git a/dbcon/ddlpackage/ddlpkg.h b/dbcon/ddlpackage/ddlpkg.h index d780c2a6d..7ad8f273c 100644 --- a/dbcon/ddlpackage/ddlpkg.h +++ b/dbcon/ddlpackage/ddlpkg.h @@ -1308,9 +1308,20 @@ struct AlterTableStatement : public SqlStatement return fTableName->fSchema; } + long getTimeZone() const + { + return fTimeZone; + } + void setTimeZone(long timeZone) + { + fTimeZone = timeZone; + } + QualifiedName* fTableName; AlterTableActionList fActions; - std::string fTimeZone; + private: + long fTimeZone; + public: }; /** @brief This is used during parsing when constraint attributes diff --git a/dbcon/ddlpackage/serialize.cpp b/dbcon/ddlpackage/serialize.cpp index c719e8f96..796b57cd0 100644 --- a/dbcon/ddlpackage/serialize.cpp +++ b/dbcon/ddlpackage/serialize.cpp @@ -118,7 +118,9 @@ int AlterTableStatement::unserialize(ByteStream& bytestream) // read table name fTableName->unserialize(bytestream); - bytestream >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + bytestream >> timeZone; + fTimeZone = timeZone; // read alter action list quadbyte action_count; @@ -225,7 +227,8 @@ int AlterTableStatement::serialize(ByteStream& bytestream) // write table name fTableName->serialize(bytestream); - bytestream << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + bytestream << timeZone; write_vec(fActions, bytestream); diff --git a/dbcon/ddlpackageproc/altertableprocessor.cpp b/dbcon/ddlpackageproc/altertableprocessor.cpp index 0e321e063..aca76bf4b 100644 --- a/dbcon/ddlpackageproc/altertableprocessor.cpp +++ b/dbcon/ddlpackageproc/altertableprocessor.cpp @@ -1023,7 +1023,8 @@ void AlterTableProcessor::addColumn(uint32_t sessionID, execplan::CalpontSystemC bs << (ByteStream::byte)column_iterator->colType.colDataType; bs << (uint32_t)column_iterator->colType.colWidth; bs << (ByteStream::byte)column_iterator->colType.compressionType; - bs << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + bs << timeZone; // cout << "sending command fillcolumn " << endl; uint32_t msgRecived = 0; fWEClient->write_to_all(bs); diff --git a/dbcon/ddlpackageproc/altertableprocessor.h b/dbcon/ddlpackageproc/altertableprocessor.h index 9ee0bd50f..7a7f708ad 100644 --- a/dbcon/ddlpackageproc/altertableprocessor.h +++ b/dbcon/ddlpackageproc/altertableprocessor.h @@ -148,7 +148,7 @@ class AlterTableProcessor : public DDLPackageProcessor ddlpackage::AtaTableComment& ataTableComment, ddlpackage::QualifiedName& fTableName, const uint64_t uniqueId); - std::string fTimeZone; + long fTimeZone; protected: void rollBackAlter(const std::string& error, BRM::TxnID txnID, int sessionId, DDLResult& result, diff --git a/dbcon/dmlpackage/calpontdmlpackage.h b/dbcon/dmlpackage/calpontdmlpackage.h index 650dd75a1..651c151a7 100644 --- a/dbcon/dmlpackage/calpontdmlpackage.h +++ b/dbcon/dmlpackage/calpontdmlpackage.h @@ -222,14 +222,14 @@ class CalpontDMLPackage * * @param the timezone to set */ - void set_TimeZone(const std::string& timeZone) + void set_TimeZone(const long timeZone) { fTimeZone = timeZone; } /** @brief get the timezone */ - const std::string get_TimeZone() const + long get_TimeZone() const { return fTimeZone; } @@ -367,7 +367,7 @@ class CalpontDMLPackage void initializeTable(); std::string fSchemaName; - std::string fTimeZone; + long fTimeZone; std::string fTableName; std::string fDMLStatement; std::string fSQLStatement; diff --git a/dbcon/dmlpackage/commanddmlpackage.cpp b/dbcon/dmlpackage/commanddmlpackage.cpp index cf9847396..16c435008 100644 --- a/dbcon/dmlpackage/commanddmlpackage.cpp +++ b/dbcon/dmlpackage/commanddmlpackage.cpp @@ -60,7 +60,8 @@ int CommandDMLPackage::write(messageqcpp::ByteStream& bytestream) bytestream << fSQLStatement; // for cleartablelock, this is table lockID bytestream << (uint8_t)fLogging; bytestream << fSchemaName; - bytestream << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + bytestream << timeZone; bytestream << fTableName; bytestream << fTableOid; bytestream << static_cast(fIsAutocommitOn); @@ -83,7 +84,9 @@ int CommandDMLPackage::read(messageqcpp::ByteStream& bytestream) bytestream >> logging; fLogging = (logging != 0); bytestream >> fSchemaName; - bytestream >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + bytestream >> timeZone; + fTimeZone = timeZone; bytestream >> fTableName; bytestream >> fTableOid; bytestream >> reinterpret_cast(fIsAutocommitOn); diff --git a/dbcon/dmlpackage/deletedmlpackage.cpp b/dbcon/dmlpackage/deletedmlpackage.cpp index 2ab6c6f2a..cdbce4a94 100644 --- a/dbcon/dmlpackage/deletedmlpackage.cpp +++ b/dbcon/dmlpackage/deletedmlpackage.cpp @@ -69,7 +69,8 @@ int DeleteDMLPackage::write(messageqcpp::ByteStream& bytestream) bytestream << fDMLStatement; bytestream << fSQLStatement; bytestream << fSchemaName; - bytestream << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + bytestream << timeZone; if (fTable != 0) { @@ -105,7 +106,9 @@ int DeleteDMLPackage::read(messageqcpp::ByteStream& bytestream) bytestream >> fDMLStatement; bytestream >> fSQLStatement; bytestream >> fSchemaName; - bytestream >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + bytestream >> timeZone; + fTimeZone = timeZone; fTable = new DMLTable(); retval = fTable->read(bytestream); diff --git a/dbcon/dmlpackage/insertdmlpackage.cpp b/dbcon/dmlpackage/insertdmlpackage.cpp index 6d4693d4d..ef8024590 100644 --- a/dbcon/dmlpackage/insertdmlpackage.cpp +++ b/dbcon/dmlpackage/insertdmlpackage.cpp @@ -64,7 +64,8 @@ int InsertDMLPackage::write(messageqcpp::ByteStream& bytestream) bytestream << fDMLStatement; bytestream << fDMLStatement; bytestream << fSchemaName; - bytestream << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + bytestream << timeZone; bytestream << (uint8_t)fLogging; bytestream << (uint8_t)fLogending; @@ -95,7 +96,9 @@ int InsertDMLPackage::read(messageqcpp::ByteStream& bytestream) bytestream >> fDMLStatement; bytestream >> fSQLStatement; bytestream >> fSchemaName; - bytestream >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + bytestream >> timeZone; + fTimeZone = timeZone; uint8_t logging; bytestream >> logging; fLogging = (logging != 0); @@ -125,7 +128,9 @@ void InsertDMLPackage::readMetaData(messageqcpp::ByteStream& bytestream) bytestream >> fDMLStatement; bytestream >> fSQLStatement; bytestream >> fSchemaName; - bytestream >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + bytestream >> timeZone; + fTimeZone = timeZone; uint8_t logging; bytestream >> logging; fLogging = (logging != 0); diff --git a/dbcon/dmlpackage/updatedmlpackage.cpp b/dbcon/dmlpackage/updatedmlpackage.cpp index 2400e6b5a..d2096b689 100644 --- a/dbcon/dmlpackage/updatedmlpackage.cpp +++ b/dbcon/dmlpackage/updatedmlpackage.cpp @@ -68,7 +68,8 @@ int UpdateDMLPackage::write(messageqcpp::ByteStream& bytestream) bytestream << fDMLStatement; bytestream << fSQLStatement; bytestream << fSchemaName; - bytestream << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + bytestream << timeZone; bytestream << (uint8_t)fIsFromCol; if (fTable != 0) @@ -105,7 +106,9 @@ int UpdateDMLPackage::read(messageqcpp::ByteStream& bytestream) bytestream >> fDMLStatement; bytestream >> fSQLStatement; bytestream >> fSchemaName; - bytestream >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + bytestream >> timeZone; + fTimeZone = timeZone; uint8_t isFromCol; bytestream >> isFromCol; fIsFromCol = (isFromCol != 0); diff --git a/dbcon/execplan/aggregatecolumn.cpp b/dbcon/execplan/aggregatecolumn.cpp index c3919b893..e94588955 100644 --- a/dbcon/execplan/aggregatecolumn.cpp +++ b/dbcon/execplan/aggregatecolumn.cpp @@ -183,7 +183,8 @@ void AggregateColumn::serialize(messageqcpp::ByteStream& b) const (*rcit)->serialize(b); b << fData; - b << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + b << timeZone; // b << fAlias; b << fTableAlias; b << static_cast(fAsc); @@ -236,7 +237,9 @@ void AggregateColumn::unserialize(messageqcpp::ByteStream& b) } b >> fData; - b >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + b >> timeZone; + fTimeZone = timeZone; // b >> fAlias; b >> fTableAlias; b >> reinterpret_cast(fAsc); diff --git a/dbcon/execplan/aggregatecolumn.h b/dbcon/execplan/aggregatecolumn.h index 4ab0e1a3c..9b0a75c93 100644 --- a/dbcon/execplan/aggregatecolumn.h +++ b/dbcon/execplan/aggregatecolumn.h @@ -313,12 +313,12 @@ class AggregateColumn : public ReturnedColumn return false; } - inline const std::string timeZone() const + inline long timeZone() const { return fTimeZone; } - inline void timeZone(const std::string& timeZone) + inline void timeZone(const long timeZone) { fTimeZone = timeZone; } @@ -346,7 +346,7 @@ class AggregateColumn : public ReturnedColumn ColumnList fGroupByColList; ColumnList fProjectColList; SRCP fConstCol; - std::string fTimeZone; + long fTimeZone; public: /*********************************************************** diff --git a/dbcon/execplan/arithmeticoperator.cpp b/dbcon/execplan/arithmeticoperator.cpp index f3e235f14..56280e891 100644 --- a/dbcon/execplan/arithmeticoperator.cpp +++ b/dbcon/execplan/arithmeticoperator.cpp @@ -72,7 +72,8 @@ ostream& operator<<(ostream& output, const ArithmeticOperator& rhs) void ArithmeticOperator::serialize(messageqcpp::ByteStream& b) const { b << (ObjectReader::id_t)ObjectReader::ARITHMETICOPERATOR; - b << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + b << timeZone; const messageqcpp::ByteStream::byte tmp = fDecimalOverflowCheck; b << tmp; Operator::serialize(b); @@ -81,7 +82,9 @@ void ArithmeticOperator::serialize(messageqcpp::ByteStream& b) const void ArithmeticOperator::unserialize(messageqcpp::ByteStream& b) { ObjectReader::checkType(b, ObjectReader::ARITHMETICOPERATOR); - b >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + b >> timeZone; + fTimeZone = timeZone; messageqcpp::ByteStream::byte tmp; b >> tmp; fDecimalOverflowCheck = tmp; diff --git a/dbcon/execplan/arithmeticoperator.h b/dbcon/execplan/arithmeticoperator.h index aa07fbc9b..8a433361b 100644 --- a/dbcon/execplan/arithmeticoperator.h +++ b/dbcon/execplan/arithmeticoperator.h @@ -59,11 +59,11 @@ class ArithmeticOperator : public Operator return new ArithmeticOperator(*this); } - inline const std::string& timeZone() const + inline long timeZone() const { return fTimeZone; } - inline void timeZone(const std::string& timeZone) + inline void timeZone(const long timeZone) { fTimeZone = timeZone; } @@ -207,7 +207,7 @@ class ArithmeticOperator : public Operator template inline result_t execute(result_t op1, result_t op2, bool& isNull); inline void execute(IDB_Decimal& result, IDB_Decimal op1, IDB_Decimal op2, bool& isNull); - std::string fTimeZone; + long fTimeZone; bool fDecimalOverflowCheck; }; diff --git a/dbcon/execplan/calpontselectexecutionplan.cpp b/dbcon/execplan/calpontselectexecutionplan.cpp index de4291c0e..c53cd86ab 100644 --- a/dbcon/execplan/calpontselectexecutionplan.cpp +++ b/dbcon/execplan/calpontselectexecutionplan.cpp @@ -500,7 +500,8 @@ void CalpontSelectExecutionPlan::serialize(messageqcpp::ByteStream& b) const b << fDJSPartitionSize; b << fUMMemLimit; b << (uint8_t)fIsDML; - b << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + b << timeZone; } void CalpontSelectExecutionPlan::unserialize(messageqcpp::ByteStream& b) @@ -695,7 +696,9 @@ void CalpontSelectExecutionPlan::unserialize(messageqcpp::ByteStream& b) b >> fUMMemLimit; b >> tmp8; fIsDML = tmp8; - b >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + b >> timeZone; + fTimeZone = timeZone; } bool CalpontSelectExecutionPlan::operator==(const CalpontSelectExecutionPlan& t) const diff --git a/dbcon/execplan/calpontselectexecutionplan.h b/dbcon/execplan/calpontselectexecutionplan.h index 91a6d627c..e870cf661 100644 --- a/dbcon/execplan/calpontselectexecutionplan.h +++ b/dbcon/execplan/calpontselectexecutionplan.h @@ -706,11 +706,11 @@ class CalpontSelectExecutionPlan : public CalpontExecutionPlan return fIsDML; } - void timeZone(const std::string& timezone) + void timeZone(const long timezone) { fTimeZone = timezone; } - const std::string timeZone() const + long timeZone() const { return fTimeZone; } @@ -923,7 +923,7 @@ class CalpontSelectExecutionPlan : public CalpontExecutionPlan int64_t fUMMemLimit; bool fIsDML; - std::string fTimeZone; + long fTimeZone; std::vector fDynamicParseTreeVec; }; diff --git a/dbcon/execplan/calpontsystemcatalog.cpp b/dbcon/execplan/calpontsystemcatalog.cpp index a2f5ea525..500f78119 100644 --- a/dbcon/execplan/calpontsystemcatalog.cpp +++ b/dbcon/execplan/calpontsystemcatalog.cpp @@ -6105,8 +6105,8 @@ const string CalpontSystemCatalog::ColType::toString() const } boost::any CalpontSystemCatalog::ColType::convertColumnData(const std::string& data, bool& pushWarning, - const std::string& timeZone, bool nulFlag, - bool noRoundup, bool isUpdate) const + long timeZone, bool nulFlag, bool noRoundup, + bool isUpdate) const { pushWarning = false; const datatypes::TypeHandler* h = typeHandler(); diff --git a/dbcon/execplan/calpontsystemcatalog.h b/dbcon/execplan/calpontsystemcatalog.h index 352758aaa..f4c69f803 100644 --- a/dbcon/execplan/calpontsystemcatalog.h +++ b/dbcon/execplan/calpontsystemcatalog.h @@ -205,7 +205,6 @@ class CalpontSystemCatalog : public datatypes::SystemCatalog */ struct ColType : public datatypes::SystemCatalog::TypeHolderStd { - ColType(); ConstraintType constraintType; DictOID ddn; std::string defaultValue; @@ -216,11 +215,25 @@ class CalpontSystemCatalog : public datatypes::SystemCatalog uint64_t nextvalue; // next autoincrement value uint32_t charsetNumber; const CHARSET_INFO* cs; + private: + long timeZone; + public: + ColType(); ColType(const ColType& rhs); ColType& operator=(const ColType& rhs); CHARSET_INFO* getCharset(); + + long getTimeZone() const + { + return timeZone; + } + void setTimeZone(long timeZone_) + { + timeZone = timeZone_; + } + // for F&E use. only serialize necessary info for now void serialize(messageqcpp::ByteStream& b) const { @@ -254,7 +267,7 @@ class CalpontSystemCatalog : public datatypes::SystemCatalog * @param nRoundtrip * @param isUpdate */ - boost::any convertColumnData(const std::string& data, bool& bSaturate, const std::string& timeZone, + boost::any convertColumnData(const std::string& data, bool& bSaturate, long timeZone, bool nulFlag = false, bool noRoundup = false, bool isUpdate = false) const; const std::string toString() const; diff --git a/dbcon/execplan/constantcolumn.cpp b/dbcon/execplan/constantcolumn.cpp index 65406b108..a3094285c 100644 --- a/dbcon/execplan/constantcolumn.cpp +++ b/dbcon/execplan/constantcolumn.cpp @@ -254,7 +254,8 @@ void ConstantColumn::serialize(messageqcpp::ByteStream& b) const b << (uint32_t)fType; // b << fAlias; b << fData; - b << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + b << timeZone; b << static_cast(fReturnAll); b << (uint64_t)fResult.intVal; b << fResult.uintVal; @@ -278,7 +279,9 @@ void ConstantColumn::unserialize(messageqcpp::ByteStream& b) b >> fConstval; b >> (uint32_t&)fType; b >> fData; - b >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + b >> timeZone; + fTimeZone = timeZone; b >> reinterpret_cast(fReturnAll); b >> (uint64_t&)fResult.intVal; b >> fResult.uintVal; diff --git a/dbcon/execplan/constantcolumn.h b/dbcon/execplan/constantcolumn.h index e246eb390..970ffd2a4 100644 --- a/dbcon/execplan/constantcolumn.h +++ b/dbcon/execplan/constantcolumn.h @@ -113,14 +113,14 @@ class ConstantColumn : public ReturnedColumn /** * accessor */ - inline const std::string& timeZone() const + inline long timeZone() const { return fTimeZone; } /** * mutator */ - inline void timeZone(const std::string& timeZone) + inline void timeZone(const long timeZone) { fTimeZone = timeZone; } @@ -204,7 +204,7 @@ class ConstantColumn : public ReturnedColumn std::string fConstval; int fType; std::string fData; - std::string fTimeZone; + long fTimeZone; /*********************************************************** * F&E framework * diff --git a/dbcon/execplan/functioncolumn.cpp b/dbcon/execplan/functioncolumn.cpp index 6aa153528..9740a82aa 100644 --- a/dbcon/execplan/functioncolumn.cpp +++ b/dbcon/execplan/functioncolumn.cpp @@ -272,7 +272,8 @@ void FunctionColumn::serialize(messageqcpp::ByteStream& b) const b << fTableAlias; b << fData; - b << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + b << timeZone; } void FunctionColumn::unserialize(messageqcpp::ByteStream& b) @@ -303,10 +304,11 @@ void FunctionColumn::unserialize(messageqcpp::ByteStream& b) b >> fTableAlias; b >> fData; - b >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + b >> timeZone; + fTimeZone = timeZone; FuncExp* funcExp = FuncExp::instance(); fFunctor = funcExp->getFunctor(fFunctionName); - fFunctor->timeZone(fTimeZone); fFunctor->fix(*this); // @bug 3506. Special treatment for rand() function. reset the seed diff --git a/dbcon/execplan/functioncolumn.h b/dbcon/execplan/functioncolumn.h index 887352021..e0b73dae3 100644 --- a/dbcon/execplan/functioncolumn.h +++ b/dbcon/execplan/functioncolumn.h @@ -121,12 +121,12 @@ class FunctionColumn : public ReturnedColumn fTableAlias = tableAlias; } - inline const std::string timeZone() const + inline long timeZone() const { return fTimeZone; } - inline void timeZone(const std::string& timeZone) + inline void timeZone(const long timeZone) { fTimeZone = timeZone; } @@ -181,7 +181,7 @@ class FunctionColumn : public ReturnedColumn std::string fFunctionName; /// function name std::string fTableAlias; /// table alias which has the column std::string fData; /// SQL representation - std::string fTimeZone; + long fTimeZone; /** @brief Do a deep, strict (as opposed to semantic) equivalence test * @@ -217,31 +217,38 @@ class FunctionColumn : public ReturnedColumn public: virtual const std::string& getStrVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); fResult.strVal = fFunctor->getStrVal(row, fFunctionParms, isNull, fOperationType); return fResult.strVal; } virtual int64_t getIntVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); return fFunctor->getIntVal(row, fFunctionParms, isNull, fOperationType); } virtual uint64_t getUintVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); return fFunctor->getUintVal(row, fFunctionParms, isNull, fOperationType); } virtual float getFloatVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); return fFunctor->getFloatVal(row, fFunctionParms, isNull, fOperationType); } virtual double getDoubleVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); return fFunctor->getDoubleVal(row, fFunctionParms, isNull, fOperationType); } virtual long double getLongDoubleVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); return fFunctor->getLongDoubleVal(row, fFunctionParms, isNull, fOperationType); } virtual IDB_Decimal getDecimalVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); IDB_Decimal decimal = fFunctor->getDecimalVal(row, fFunctionParms, isNull, fOperationType); if (UNLIKELY(fResultType.colWidth == utils::MAXLEGACYWIDTH && fResultType.scale == decimal.scale)) @@ -276,10 +283,9 @@ class FunctionColumn : public ReturnedColumn if (fResultType.scale > decimal.scale) decimal.value *= IDB_pow[fResultType.scale - decimal.scale]; else - decimal.value = - (int64_t)(decimal.value > 0 - ? (double)decimal.value / IDB_pow[decimal.scale - fResultType.scale] + 0.5 - : (double)decimal.value / IDB_pow[decimal.scale - fResultType.scale] - 0.5); + decimal.value = (int64_t)( + decimal.value > 0 ? (double)decimal.value / IDB_pow[decimal.scale - fResultType.scale] + 0.5 + : (double)decimal.value / IDB_pow[decimal.scale - fResultType.scale] - 0.5); } decimal.scale = fResultType.scale; @@ -288,22 +294,27 @@ class FunctionColumn : public ReturnedColumn } virtual bool getBoolVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); return fFunctor->getBoolVal(row, fFunctionParms, isNull, fOperationType); } virtual int32_t getDateIntVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); return fFunctor->getDateIntVal(row, fFunctionParms, isNull, fOperationType); } virtual int64_t getDatetimeIntVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); return fFunctor->getDatetimeIntVal(row, fFunctionParms, isNull, fOperationType); } virtual int64_t getTimestampIntVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); return fFunctor->getTimestampIntVal(row, fFunctionParms, isNull, fOperationType); } virtual int64_t getTimeIntVal(rowgroup::Row& row, bool& isNull) { + fOperationType.setTimeZone(fTimeZone); return fFunctor->getTimeIntVal(row, fFunctionParms, isNull, fOperationType); } diff --git a/dbcon/execplan/mcsanalyzetableexecutionplan.cpp b/dbcon/execplan/mcsanalyzetableexecutionplan.cpp index 982135ed9..d548c8245 100644 --- a/dbcon/execplan/mcsanalyzetableexecutionplan.cpp +++ b/dbcon/execplan/mcsanalyzetableexecutionplan.cpp @@ -97,7 +97,8 @@ void MCSAnalyzeTableExecutionPlan::serialize(messageqcpp::ByteStream& bs) const bs << fSchemaName; bs << fTableName; bs << fLocalQuery; - bs << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + bs << timeZone; bs << fTraceFlags; } @@ -149,7 +150,9 @@ void MCSAnalyzeTableExecutionPlan::unserialize(messageqcpp::ByteStream& bs) bs >> fSchemaName; bs >> fTableName; bs >> fLocalQuery; - bs >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + bs >> timeZone; + fTimeZone = timeZone; bs >> fTraceFlags; } } // namespace execplan diff --git a/dbcon/execplan/mcsanalyzetableexecutionplan.h b/dbcon/execplan/mcsanalyzetableexecutionplan.h index ce95809f4..5dc6d8270 100644 --- a/dbcon/execplan/mcsanalyzetableexecutionplan.h +++ b/dbcon/execplan/mcsanalyzetableexecutionplan.h @@ -169,12 +169,12 @@ class MCSAnalyzeTableExecutionPlan : public CalpontExecutionPlan return fUuid; } - void timeZone(const std::string& timezone) + void timeZone(long timezone) { fTimeZone = timezone; } - const std::string timeZone() const + long timeZone() const { return fTimeZone; } @@ -256,7 +256,7 @@ class MCSAnalyzeTableExecutionPlan : public CalpontExecutionPlan std::string fTableName; uint32_t fTraceFlags; boost::uuids::uuid fUuid; - std::string fTimeZone; + long fTimeZone; uint32_t fStatementID; uint64_t fStringScanThreshold; std::string fData; diff --git a/dbcon/execplan/simplecolumn.cpp b/dbcon/execplan/simplecolumn.cpp index d08144d75..6ecb8b1cb 100644 --- a/dbcon/execplan/simplecolumn.cpp +++ b/dbcon/execplan/simplecolumn.cpp @@ -345,7 +345,8 @@ void SimpleColumn::serialize(messageqcpp::ByteStream& b) const b << fColumnName; b << fIndexName; b << fViewName; - b << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + b << timeZone; b << (uint32_t)fOid; b << fData; b << fTableAlias; @@ -362,7 +363,9 @@ void SimpleColumn::unserialize(messageqcpp::ByteStream& b) b >> fColumnName; b >> fIndexName; b >> fViewName; - b >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + b >> timeZone; + fTimeZone = timeZone; b >> (uint32_t&)fOid; b >> fData; b >> fTableAlias; diff --git a/dbcon/execplan/simplecolumn.h b/dbcon/execplan/simplecolumn.h index a7bcaa80a..8f35d3f1f 100644 --- a/dbcon/execplan/simplecolumn.h +++ b/dbcon/execplan/simplecolumn.h @@ -151,11 +151,11 @@ class SimpleColumn : public ReturnedColumn if (lower_case_table_names) boost::algorithm::to_lower(fViewName); } - inline const std::string& timeZone() const + inline long timeZone() const { return fTimeZone; } - inline void timeZone(const std::string& timeZone) + inline void timeZone(const long timeZone) { fTimeZone = timeZone; } @@ -259,7 +259,7 @@ class SimpleColumn : public ReturnedColumn std::string fIndexName; // if belong to view, view name is non-empty std::string fViewName; - std::string fTimeZone; + long fTimeZone; bool fisColumnStore; /** @brief parse SimpleColumn text @@ -349,7 +349,7 @@ class SimpleColumn : public ReturnedColumn inline int64_t getDatetimeIntVal(rowgroup::Row& row, bool& isNull) { evaluate(row, isNull); - return TreeNode::getDatetimeIntVal(); + return TreeNode::getDatetimeIntVal(fTimeZone); } inline int64_t getTimestampIntVal(rowgroup::Row& row, bool& isNull) diff --git a/dbcon/execplan/simplefilter.cpp b/dbcon/execplan/simplefilter.cpp index ed1459b25..4d48ad212 100644 --- a/dbcon/execplan/simplefilter.cpp +++ b/dbcon/execplan/simplefilter.cpp @@ -55,7 +55,7 @@ SimpleFilter::SimpleFilter(const string& sql) : Filter(sql) parse(sql); } -SimpleFilter::SimpleFilter(const SOP& op, ReturnedColumn* lhs, ReturnedColumn* rhs, const string& timeZone) +SimpleFilter::SimpleFilter(const SOP& op, ReturnedColumn* lhs, ReturnedColumn* rhs, const long timeZone) : fOp(op), fLhs(lhs), fRhs(rhs), fIndexFlag(NOINDEX), fJoinFlag(EQUA), fTimeZone(timeZone) { convertConstant(); @@ -314,7 +314,8 @@ void SimpleFilter::serialize(messageqcpp::ByteStream& b) const b << static_cast(fIndexFlag); b << static_cast(fJoinFlag); - b << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + b << timeZone; } void SimpleFilter::unserialize(messageqcpp::ByteStream& b) @@ -330,7 +331,9 @@ void SimpleFilter::unserialize(messageqcpp::ByteStream& b) fRhs = dynamic_cast(ObjectReader::createTreeNode(b)); b >> reinterpret_cast(fIndexFlag); b >> reinterpret_cast(fJoinFlag); - b >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + b >> timeZone; + fTimeZone = timeZone; fSimpleColumnList.clear(); fAggColumnList.clear(); diff --git a/dbcon/execplan/simplefilter.h b/dbcon/execplan/simplefilter.h index 900afec2d..85d2a06c9 100644 --- a/dbcon/execplan/simplefilter.h +++ b/dbcon/execplan/simplefilter.h @@ -67,7 +67,7 @@ class SimpleFilter : public Filter SimpleFilter(); SimpleFilter(const std::string& sql); - SimpleFilter(const SOP& op, ReturnedColumn* lhs, ReturnedColumn* rhs, const std::string& timeZone = ""); + SimpleFilter(const SOP& op, ReturnedColumn* lhs, ReturnedColumn* rhs, const long timeZone = 0); SimpleFilter(const SimpleFilter& rhs); virtual ~SimpleFilter(); @@ -92,12 +92,12 @@ class SimpleFilter : public Filter return fLhs; } - inline const std::string& timeZone() const + inline long timeZone() const { return fTimeZone; } - inline void timeZone(const std::string& timeZone) + inline void timeZone(const long timeZone) { fTimeZone = timeZone; } @@ -220,7 +220,7 @@ class SimpleFilter : public Filter ReturnedColumn* fRhs; /// right operand int fIndexFlag; /// which side col is index int fJoinFlag; /// hash join type - std::string fTimeZone; + long fTimeZone; void parse(std::string); diff --git a/dbcon/execplan/treenode.h b/dbcon/execplan/treenode.h index 496a6436f..105765aed 100644 --- a/dbcon/execplan/treenode.h +++ b/dbcon/execplan/treenode.h @@ -325,7 +325,7 @@ class TreeNode } inline bool getBoolVal(); - inline const std::string& getStrVal(const std::string& timeZone); + inline const std::string& getStrVal(const long timeZone); inline int64_t getIntVal(); inline uint64_t getUintVal(); inline float getFloatVal(); @@ -333,7 +333,7 @@ class TreeNode inline long double getLongDoubleVal(); inline IDB_Decimal getDecimalVal(); inline int32_t getDateIntVal(); - inline int64_t getDatetimeIntVal(); + inline int64_t getDatetimeIntVal(long timeZone = 0); inline int64_t getTimestampIntVal(); inline int64_t getTimeIntVal(); @@ -457,7 +457,7 @@ inline bool TreeNode::getBoolVal() return fResult.boolVal; } -inline const std::string& TreeNode::getStrVal(const std::string& timeZone) +inline const std::string& TreeNode::getStrVal(const long timeZone) { switch (fResultType.colDataType) { @@ -1052,7 +1052,7 @@ inline IDB_Decimal TreeNode::getDecimalVal() return fResult.decimalVal; } -inline int64_t TreeNode::getDatetimeIntVal() +inline int64_t TreeNode::getDatetimeIntVal(long timeZone) { if (fResultType.colDataType == execplan::CalpontSystemCatalog::DATE) return (fResult.intVal & 0x00000000FFFFFFC0LL) << 32; @@ -1083,6 +1083,17 @@ inline int64_t TreeNode::getDatetimeIntVal() else if (fResultType.colDataType == execplan::CalpontSystemCatalog::DATETIME) // return (fResult.intVal & 0xFFFFFFFFFFF00000LL); return (fResult.intVal); + else if (fResultType.colDataType == execplan::CalpontSystemCatalog::TIMESTAMP) + { + dataconvert::TimeStamp timestamp(fResult.intVal); + int64_t seconds = timestamp.second; + dataconvert::MySQLTime m_time; + dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone); + dataconvert::DateTime dt(m_time.year, m_time.month, m_time.day, m_time.hour, m_time.minute, m_time.second, + timestamp.msecond); + memcpy(&fResult.intVal, &dt, 8); + return fResult.intVal; + } else return getIntVal(); } diff --git a/dbcon/execplan/windowfunctioncolumn.cpp b/dbcon/execplan/windowfunctioncolumn.cpp index 00b2e9ac5..dc39677d8 100644 --- a/dbcon/execplan/windowfunctioncolumn.cpp +++ b/dbcon/execplan/windowfunctioncolumn.cpp @@ -288,7 +288,8 @@ void WindowFunctionColumn::serialize(messageqcpp::ByteStream& b) const fOrderBy.serialize(b); udafContext.serialize(b); - b << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + b << timeZone; } void WindowFunctionColumn::unserialize(messageqcpp::ByteStream& b) @@ -320,7 +321,9 @@ void WindowFunctionColumn::unserialize(messageqcpp::ByteStream& b) fOrderBy.unserialize(b); udafContext.unserialize(b); - b >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + b >> timeZone; + fTimeZone = timeZone; } void WindowFunctionColumn::addToPartition(vector& groupByList) diff --git a/dbcon/execplan/windowfunctioncolumn.h b/dbcon/execplan/windowfunctioncolumn.h index 5f2b21294..b40c2dd27 100644 --- a/dbcon/execplan/windowfunctioncolumn.h +++ b/dbcon/execplan/windowfunctioncolumn.h @@ -146,12 +146,12 @@ class WindowFunctionColumn : public ReturnedColumn return udafContext; } - inline const std::string timeZone() const + inline long timeZone() const { return fTimeZone; } - inline void timeZone(const std::string& timeZone) + inline void timeZone(const long timeZone) { fTimeZone = timeZone; } @@ -180,7 +180,7 @@ class WindowFunctionColumn : public ReturnedColumn // UDAnF support mcsv1sdk::mcsv1Context udafContext; - std::string fTimeZone; + long fTimeZone; /*********************************************************** * F&E framework * ***********************************************************/ diff --git a/dbcon/joblist/groupconcat.h b/dbcon/joblist/groupconcat.h index 24f14348d..6db944b57 100644 --- a/dbcon/joblist/groupconcat.h +++ b/dbcon/joblist/groupconcat.h @@ -127,7 +127,7 @@ class GroupConcator int64_t fGroupConcatLen; int64_t fConstantLen; boost::scoped_array fOutputString; - std::string fTimeZone; + long fTimeZone; }; // For GROUP_CONCAT withour distinct or orderby diff --git a/dbcon/joblist/jlf_common.h b/dbcon/joblist/jlf_common.h index 19984cbdc..d85c40a4f 100644 --- a/dbcon/joblist/jlf_common.h +++ b/dbcon/joblist/jlf_common.h @@ -372,7 +372,7 @@ struct JobInfo int64_t largeSideLimit; uint64_t partitionSize; bool isDML; - std::string timeZone; + long timeZone; // This is for tracking any dynamically allocated ParseTree objects // in simpleScalarFilterToParseTree() for later deletion in diff --git a/dbcon/joblist/jlf_execplantojoblist.cpp b/dbcon/joblist/jlf_execplantojoblist.cpp index a9c0c254b..4ba29aa56 100644 --- a/dbcon/joblist/jlf_execplantojoblist.cpp +++ b/dbcon/joblist/jlf_execplantojoblist.cpp @@ -132,7 +132,7 @@ const JobStepVector doSimpleFilter(SimpleFilter* sf, JobInfo& jobInfo); /* This looks like an inefficient way to get NULL values. Much easier ways to do it. */ template -void valueNullNum(const CalpontSystemCatalog::ColType& ct, const string& timeZone, T& val) +void valueNullNum(const CalpontSystemCatalog::ColType& ct, const long timeZone, T& val) { T& n = val; bool pushWarning = false; @@ -274,7 +274,7 @@ void valueNullNum(const CalpontSystemCatalog::ColType& ct, const string& timeZon template void convertValueNum(const string& str, const CalpontSystemCatalog::ColType& ct, bool isNull, uint8_t& rf, - const string& timeZone, T& v) + const long timeZone, T& v) { if (str.size() == 0 || isNull) { diff --git a/dbcon/joblist/jlf_subquery.cpp b/dbcon/joblist/jlf_subquery.cpp index 5b612d4ae..91d8a5de3 100644 --- a/dbcon/joblist/jlf_subquery.cpp +++ b/dbcon/joblist/jlf_subquery.cpp @@ -64,7 +64,7 @@ using namespace joblist; namespace { -void getColumnValue(ConstantColumn** cc, uint64_t i, const Row& row, const string& timeZone) +void getColumnValue(ConstantColumn** cc, uint64_t i, const Row& row, const long timeZone) { ostringstream oss; int64_t data = 0; diff --git a/dbcon/joblist/jobstep.h b/dbcon/joblist/jobstep.h index d9e95992e..ce051dcaf 100644 --- a/dbcon/joblist/jobstep.h +++ b/dbcon/joblist/jobstep.h @@ -417,11 +417,11 @@ class JobStep fOnClauseFilter = b; } - void timeZone(const std::string& timezone) + void timeZone(const long timezone) { fTimeZone = timezone; } - const std::string timeZone() const + long timeZone() const { return fTimeZone; } @@ -496,7 +496,7 @@ class JobStep uint64_t fProgress; int64_t fStartTime; int64_t fLastStepTeleTime; - std::string fTimeZone; + long fTimeZone; private: static boost::mutex fLogMutex; diff --git a/dbcon/joblist/tupleunion.h b/dbcon/joblist/tupleunion.h index 2ac031381..23a00b273 100644 --- a/dbcon/joblist/tupleunion.h +++ b/dbcon/joblist/tupleunion.h @@ -199,7 +199,7 @@ class TupleUnion : public JobStep, public TupleDeliveryStep bool runRan, joinRan; boost::shared_ptr sessionMemLimit; - std::string fTimeZone; + long fTimeZone; }; } // namespace joblist diff --git a/dbcon/mysql/ha_exists_sub.cpp b/dbcon/mysql/ha_exists_sub.cpp index 36c44f13d..da934318d 100644 --- a/dbcon/mysql/ha_exists_sub.cpp +++ b/dbcon/mysql/ha_exists_sub.cpp @@ -96,7 +96,7 @@ execplan::ParseTree* ExistsSub::transform() csep->subType(CalpontSelectExecutionPlan::EXISTS_SUBS); // gwi for the sub query - gp_walk_info gwi; + gp_walk_info gwi(fGwip.timeZone); gwi.thd = fGwip.thd; gwi.subQuery = this; diff --git a/dbcon/mysql/ha_from_sub.cpp b/dbcon/mysql/ha_from_sub.cpp index a3065d6c9..c836a5cd6 100644 --- a/dbcon/mysql/ha_from_sub.cpp +++ b/dbcon/mysql/ha_from_sub.cpp @@ -44,7 +44,7 @@ using namespace execplan; namespace cal_impl_if { -void derivedTableOptimization(THD* thd, SCSEP& csep) +void derivedTableOptimization(gp_walk_info* gwip, SCSEP& csep) { // @bug5634. replace the unused column with ConstantColumn from derived table column list, // ExeMgr will not project ConstantColumn. Only count for local derived column. @@ -135,8 +135,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) else { cols[i].reset(new ConstantColumn(val)); - (reinterpret_cast(cols[i].get())) - ->timeZone(thd->variables.time_zone->get_name()->ptr()); + (reinterpret_cast(cols[i].get()))->timeZone(gwip->timeZone); } for (uint j = 0; j < unionColVec.size(); j++) @@ -156,8 +155,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) else { unionColVec[j][i].reset(new ConstantColumn(val)); - (reinterpret_cast(unionColVec[j][i].get())) - ->timeZone(thd->variables.time_zone->get_name()->ptr()); + (reinterpret_cast(unionColVec[j][i].get()))->timeZone(gwip->timeZone); } } } @@ -173,15 +171,13 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) if (!cols.empty()) { cols[0].reset(new ConstantColumn(val)); - (reinterpret_cast(cols[0].get())) - ->timeZone(thd->variables.time_zone->get_name()->ptr()); + (reinterpret_cast(cols[0].get()))->timeZone(gwip->timeZone); nonConstCols.push_back(cols[0]); for (uint j = 0; j < unionColVec.size(); j++) { unionColVec[j][0].reset(new ConstantColumn(val)); - (reinterpret_cast(unionColVec[j][0].get())) - ->timeZone(thd->variables.time_zone->get_name()->ptr()); + (reinterpret_cast(unionColVec[j][0].get()))->timeZone(gwip->timeZone); nonConstUnionColVec[j].push_back(unionColVec[j][0]); } } @@ -229,7 +225,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) if (horizontalOptimization && pt) { pt->walk(setDerivedTable); - setDerivedFilter(thd, pt, derivedTbFilterMap, derivedTbList); + setDerivedFilter(gwip, pt, derivedTbFilterMap, derivedTbList); csep->filters(pt); } @@ -301,7 +297,7 @@ void derivedTableOptimization(THD* thd, SCSEP& csep) for (uint i = 0; i < csep->subSelectList().size(); i++) { SCSEP subselect(boost::dynamic_pointer_cast(csep->subSelectList()[i])); - derivedTableOptimization(thd, subselect); + derivedTableOptimization(gwip, subselect); } } @@ -339,7 +335,7 @@ void setDerivedTable(execplan::ParseTree* n) } } -ParseTree* setDerivedFilter(THD* thd, ParseTree*& n, map& filterMap, +ParseTree* setDerivedFilter(gp_walk_info* gwip, ParseTree*& n, map& filterMap, CalpontSelectExecutionPlan::SelectList& derivedTbList) { if (!(n->derivedTable().empty())) @@ -381,7 +377,7 @@ ParseTree* setDerivedFilter(THD* thd, ParseTree*& n, map& fi int64_t val = 1; n = new ParseTree(new ConstantColumn(val)); - (dynamic_cast(n->data()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(n->data()))->timeZone(gwip->timeZone); } else { @@ -397,10 +393,10 @@ ParseTree* setDerivedFilter(THD* thd, ParseTree*& n, map& fi ParseTree* rhs = n->right(); if (lhs) - n->left(setDerivedFilter(thd, lhs, filterMap, derivedTbList)); + n->left(setDerivedFilter(gwip, lhs, filterMap, derivedTbList)); if (rhs) - n->right(setDerivedFilter(thd, rhs, filterMap, derivedTbList)); + n->right(setDerivedFilter(gwip, rhs, filterMap, derivedTbList)); } } @@ -428,7 +424,7 @@ SCSEP FromSubQuery::transform() csep->subType(CalpontSelectExecutionPlan::FROM_SUBS); // gwi for the sub query - gp_walk_info gwi; + gp_walk_info gwi(fGwip.timeZone); gwi.thd = fGwip.thd; gwi.subQuery = this; gwi.viewName = fGwip.viewName; diff --git a/dbcon/mysql/ha_in_sub.cpp b/dbcon/mysql/ha_in_sub.cpp index cfb4fb3be..df4017165 100644 --- a/dbcon/mysql/ha_in_sub.cpp +++ b/dbcon/mysql/ha_in_sub.cpp @@ -151,7 +151,7 @@ execplan::ParseTree* InSub::transform() csep->subType(CalpontSelectExecutionPlan::IN_SUBS); // gwi for the sub query - gp_walk_info gwi; + gp_walk_info gwi(fGwip.timeZone); gwi.thd = fGwip.thd; gwi.subQuery = this; diff --git a/dbcon/mysql/ha_mcs.cpp b/dbcon/mysql/ha_mcs.cpp index dd10c9f36..a061c5abb 100644 --- a/dbcon/mysql/ha_mcs.cpp +++ b/dbcon/mysql/ha_mcs.cpp @@ -163,6 +163,8 @@ ha_mcs::ha_mcs(handlerton* hton, TABLE_SHARE* table_arg) HA_CAN_TABLE_CONDITION_PUSHDOWN | HA_CAN_DIRECT_UPDATE_AND_DELETE) , m_lock_type(F_UNLCK) { + const char* timeZone = current_thd->variables.time_zone->get_name()->ptr(); + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &time_zone); } /** @@ -318,7 +320,7 @@ int ha_mcs::write_row(const uchar* buf) int rc; try { - rc = ha_mcs_impl_write_row(buf, table, rows_changed); + rc = ha_mcs_impl_write_row(buf, table, rows_changed, time_zone); } catch (std::runtime_error& e) { @@ -652,7 +654,7 @@ int ha_mcs::rnd_next(uchar* buf) int rc; try { - rc = ha_mcs_impl_rnd_next(buf, table); + rc = ha_mcs_impl_rnd_next(buf, table, time_zone); } catch (std::runtime_error& e) { diff --git a/dbcon/mysql/ha_mcs.h b/dbcon/mysql/ha_mcs.h index b87414d81..6e6301564 100644 --- a/dbcon/mysql/ha_mcs.h +++ b/dbcon/mysql/ha_mcs.h @@ -51,6 +51,7 @@ class ha_mcs : public handler // call on Ubuntu18. std::vector condStack; int m_lock_type; + long time_zone; int impl_external_lock(THD* thd, TABLE* table, int lock_type); int impl_rnd_init(TABLE* table, const std::vector& condStack); diff --git a/dbcon/mysql/ha_mcs_datatype.h b/dbcon/mysql/ha_mcs_datatype.h index 1e9079530..c0390877e 100644 --- a/dbcon/mysql/ha_mcs_datatype.h +++ b/dbcon/mysql/ha_mcs_datatype.h @@ -29,9 +29,11 @@ class StoreFieldMariaDB : public StoreField { Field* m_field; const CalpontSystemCatalog::ColType& m_type; + long m_timeZone; public: - StoreFieldMariaDB(Field* f, const CalpontSystemCatalog::ColType& type) : m_field(f), m_type(type) + StoreFieldMariaDB(Field* f, const CalpontSystemCatalog::ColType& type, const long timeZone) + : m_field(f), m_type(type), m_timeZone(timeZone) { } @@ -76,8 +78,7 @@ class StoreFieldMariaDB : public StoreField 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); + DataConvert::timestampToString(val, tmp, sizeof(tmp), m_timeZone, m_type.precision); return store_string(tmp, strlen(tmp)); } @@ -212,8 +213,10 @@ class WriteBatchFieldMariaDB : public WriteBatchField Field* m_field; const CalpontSystemCatalog::ColType& m_type; uint32_t m_mbmaxlen; - WriteBatchFieldMariaDB(Field* field, const CalpontSystemCatalog::ColType& type, uint32_t mbmaxlen) - : m_field(field), m_type(type), m_mbmaxlen(mbmaxlen) + long m_timeZone; + WriteBatchFieldMariaDB(Field* field, const CalpontSystemCatalog::ColType& type, uint32_t mbmaxlen, + const long timeZone) + : m_field(field), m_type(type), m_mbmaxlen(mbmaxlen), m_timeZone(timeZone) { } size_t ColWriteBatchDate(const uchar* buf, bool nullVal, ColBatchWriter& ci) override @@ -325,7 +328,7 @@ class WriteBatchFieldMariaDB : public WriteBatchField my_timestamp_from_binary(&tm, buf, m_field->decimals()); MySQLTime time; - gmtSecToMySQLTime(tm.tv_sec, time, current_thd->variables.time_zone->get_name()->ptr()); + gmtSecToMySQLTime(tm.tv_sec, time, m_timeZone); if (!tm.tv_usec) { diff --git a/dbcon/mysql/ha_mcs_ddl.cpp b/dbcon/mysql/ha_mcs_ddl.cpp index 465fdf47d..54ee97a17 100644 --- a/dbcon/mysql/ha_mcs_ddl.cpp +++ b/dbcon/mysql/ha_mcs_ddl.cpp @@ -649,11 +649,14 @@ bool anyNullInTheColumn(THD* thd, string& schema, string& table, string& columnN csep.returnedCols(returnedColumnList); SimpleFilter* sf = new SimpleFilter(); - sf->timeZone(thd->variables.time_zone->get_name()->ptr()); + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + sf->timeZone(timeZoneOffset); boost::shared_ptr sop(new PredicateOperator("isnull")); sf->op(sop); ConstantColumn* rhs = new ConstantColumn("", ConstantColumn::NULLDATA); - rhs->timeZone(thd->variables.time_zone->get_name()->ptr()); + rhs->timeZone(timeZoneOffset); sf->lhs(col[0]->clone()); sf->rhs(rhs); @@ -799,6 +802,10 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl if (valConfig.compare("YES") == 0) isVarbinaryAllowed = true; + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + //@Bug 1771. error out for not supported feature. if (typeid(stmt) == typeid(CreateTableStatement)) { @@ -901,9 +908,9 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl try { - convertedVal = colType.convertColumnData( - 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, timeZoneOffset, false, false, false); } catch (std::exception&) { @@ -1143,7 +1150,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl algorithm::to_lower(alterTable->fTableName->fName); } - alterTable->fTimeZone.assign(thd->variables.time_zone->get_name()->ptr()); + alterTable->setTimeZone(timeZoneOffset); if (schema.length() == 0) { @@ -1313,9 +1320,8 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl try { - convertedVal = colType.convertColumnData( - addColumnPtr->fColumnDef->fDefaultValue->fValue, pushWarning, - thd->variables.time_zone->get_name()->ptr(), false, false, false); + convertedVal = colType.convertColumnData(addColumnPtr->fColumnDef->fDefaultValue->fValue, + pushWarning, timeZoneOffset, false, false, false); } catch (std::exception&) { @@ -1698,9 +1704,8 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl try { - convertedVal = colType.convertColumnData( - 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, timeZoneOffset, false, false, false); } catch (std::exception&) { diff --git a/dbcon/mysql/ha_mcs_dml.cpp b/dbcon/mysql/ha_mcs_dml.cpp index 05cbaad07..554e03bba 100644 --- a/dbcon/mysql/ha_mcs_dml.cpp +++ b/dbcon/mysql/ha_mcs_dml.cpp @@ -337,7 +337,10 @@ int doProcessInsertValues(TABLE* table, uint32_t size, cal_connection_info& ci, pDMLPackage->set_TableName(name); name = table->s->db.str; pDMLPackage->set_SchemaName(name); - pDMLPackage->set_TimeZone(thd->variables.time_zone->get_name()->ptr()); + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + pDMLPackage->set_TimeZone(timeZoneOffset); if (thd->lex->sql_command == SQLCOM_INSERT_SELECT) pDMLPackage->set_isInsertSelect(true); @@ -676,7 +679,8 @@ 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) +int ha_mcs_impl_write_batch_row_(const uchar* buf, TABLE* table, cal_impl_if::cal_connection_info& ci, + long timeZone) { ByteStream rowData; int rc = 0; @@ -746,7 +750,7 @@ int ha_mcs_impl_write_batch_row_(const uchar* buf, TABLE* table, cal_impl_if::ca Field* fieldPtr = table->field[colpos]; uint32_t mbmaxlen = (fieldPtr->charset() && fieldPtr->charset()->mbmaxlen) ? fieldPtr->charset()->mbmaxlen : 0; - datatypes::WriteBatchFieldMariaDB field(fieldPtr, colType, mbmaxlen); + datatypes::WriteBatchFieldMariaDB field(fieldPtr, colType, mbmaxlen, timeZone); idbassert(table == table->field[colpos]->table); buf += h->ColWriteBatch(&field, buf, nullVal, writer); } diff --git a/dbcon/mysql/ha_mcs_execplan.cpp b/dbcon/mysql/ha_mcs_execplan.cpp index 7a7a8978b..7b396360e 100644 --- a/dbcon/mysql/ha_mcs_execplan.cpp +++ b/dbcon/mysql/ha_mcs_execplan.cpp @@ -1509,7 +1509,7 @@ uint32_t buildJoin(gp_walk_info& gwi, List& join_list, return 0; } -ParseTree* buildRowPredicate(THD* thd, RowColumn* lhs, RowColumn* rhs, string predicateOp) +ParseTree* buildRowPredicate(gp_walk_info* gwip, RowColumn* lhs, RowColumn* rhs, string predicateOp) { PredicateOperator* po = new PredicateOperator(predicateOp); boost::shared_ptr sop(po); @@ -1523,7 +1523,7 @@ ParseTree* buildRowPredicate(THD* thd, RowColumn* lhs, RowColumn* rhs, string pr ParseTree* pt = new ParseTree(lo); sop->setOpType(lhs->columnVec()[0]->resultType(), rhs->columnVec()[0]->resultType()); SimpleFilter* sf = new SimpleFilter(sop, lhs->columnVec()[0].get(), rhs->columnVec()[0].get()); - sf->timeZone(thd->variables.time_zone->get_name()->ptr()); + sf->timeZone(gwip->timeZone); pt->left(new ParseTree(sf)); for (uint32_t i = 1; i < lhs->columnVec().size(); i++) @@ -1531,7 +1531,7 @@ ParseTree* buildRowPredicate(THD* thd, RowColumn* lhs, RowColumn* rhs, string pr sop.reset(po->clone()); sop->setOpType(lhs->columnVec()[i]->resultType(), rhs->columnVec()[i]->resultType()); SimpleFilter* sf = new SimpleFilter(sop, lhs->columnVec()[i].get(), rhs->columnVec()[i].get()); - sf->timeZone(thd->variables.time_zone->get_name()->ptr()); + sf->timeZone(gwip->timeZone); pt->right(new ParseTree(sf)); if (i + 1 < lhs->columnVec().size()) @@ -1551,7 +1551,7 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It { // (c1,c2,..) = (v1,v2,...) transform to: c1=v1 and c2=v2 and ... assert(!lhs->columnVec().empty() && lhs->columnVec().size() == rhs->columnVec().size()); - gwip->ptWorkStack.push(buildRowPredicate(gwip->thd, rhs, lhs, ifp->func_name())); + gwip->ptWorkStack.push(buildRowPredicate(gwip, rhs, lhs, ifp->func_name())); } else if (ifp->functype() == Item_func::IN_FUNC) { @@ -1595,7 +1595,7 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It RowColumn* vals = dynamic_cast(tmpStack.top()); valVec.push_back(vals); tmpStack.pop(); - ParseTree* pt = buildRowPredicate(gwip->thd, columns, vals, predicateOp); + ParseTree* pt = buildRowPredicate(gwip, columns, vals, predicateOp); while (!tmpStack.empty()) { @@ -1604,7 +1604,7 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It vals = dynamic_cast(tmpStack.top()); valVec.push_back(vals); tmpStack.pop(); - pt1->right(buildRowPredicate(gwip->thd, columns->clone(), vals, predicateOp)); + pt1->right(buildRowPredicate(gwip, columns->clone(), vals, predicateOp)); pt = pt1; } @@ -1646,8 +1646,8 @@ bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It break; sop->setOpType(sc->resultType(), valVec[j]->columnVec()[i]->resultType()); - cf->pushFilter(new SimpleFilter(sop, sc->clone(), valVec[j]->columnVec()[i]->clone(), - gwip->thd->variables.time_zone->get_name()->ptr())); + cf->pushFilter( + new SimpleFilter(sop, sc->clone(), valVec[j]->columnVec()[i]->clone(), gwip->timeZone)); } if (j < valVec.size()) @@ -1792,7 +1792,7 @@ bool buildEqualityPredicate(execplan::ReturnedColumn* lhs, execplan::ReturnedCol } SimpleFilter* sf = new SimpleFilter(); - sf->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + sf->timeZone(gwip->timeZone); //@bug 2101 for when there are only constants in a delete or update where clause (eg "where 5 < 6"). // There will be no field column and it will get here only if the comparison is true. @@ -1906,11 +1906,11 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) sop.reset(new PredicateOperator(">")); sop->setOpType(filterCol->resultType(), rhs->resultType()); sfr = new SimpleFilter(sop, filterCol, rhs); - sfr->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + sfr->timeZone(gwip->timeZone); sop.reset(new PredicateOperator("<")); sop->setOpType(filterCol->resultType(), lhs->resultType()); sfl = new SimpleFilter(sop, filterCol->clone(), lhs); - sfl->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + sfl->timeZone(gwip->timeZone); ParseTree* ptp = new ParseTree(new LogicOperator("or")); ptp->left(sfr); ptp->right(sfl); @@ -1921,11 +1921,11 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) sop.reset(new PredicateOperator("<=")); sop->setOpType(filterCol->resultType(), rhs->resultType()); sfr = new SimpleFilter(sop, filterCol, rhs); - sfr->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + sfr->timeZone(gwip->timeZone); sop.reset(new PredicateOperator(">=")); sop->setOpType(filterCol->resultType(), lhs->resultType()); sfl = new SimpleFilter(sop, filterCol->clone(), lhs); - sfl->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + sfl->timeZone(gwip->timeZone); ParseTree* ptp = new ParseTree(new LogicOperator("and")); ptp->left(sfr); ptp->right(sfl); @@ -1985,8 +1985,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) cf->op(sop); sop.reset(new PredicateOperator(eqop)); sop->setOpType(gwip->scsp->resultType(), lhs->resultType()); - cf->pushFilter( - new SimpleFilter(sop, gwip->scsp->clone(), lhs, gwip->thd->variables.time_zone->get_name()->ptr())); + cf->pushFilter(new SimpleFilter(sop, gwip->scsp->clone(), lhs, gwip->timeZone)); while (!gwip->rcWorkStack.empty()) { @@ -1998,8 +1997,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) gwip->rcWorkStack.pop(); sop.reset(new PredicateOperator(eqop)); sop->setOpType(gwip->scsp->resultType(), lhs->resultType()); - cf->pushFilter( - new SimpleFilter(sop, gwip->scsp->clone(), lhs, gwip->thd->variables.time_zone->get_name()->ptr())); + cf->pushFilter(new SimpleFilter(sop, gwip->scsp->clone(), lhs, gwip->timeZone)); } if (!gwip->rcWorkStack.empty()) @@ -2065,8 +2063,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) { gwip->rcWorkStack.push(new ConstantColumn((int64_t)udf->val_int())); } - (dynamic_cast(gwip->rcWorkStack.top())) - ->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(gwip->rcWorkStack.top()))->timeZone(gwip->timeZone); } else { @@ -2088,8 +2085,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) { gwip->rcWorkStack.push(new ConstantColumn(buf.ptr(), ConstantColumn::NUM)); } - (dynamic_cast(gwip->rcWorkStack.top())) - ->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(gwip->rcWorkStack.top()))->timeZone(gwip->timeZone); return false; } @@ -2265,19 +2261,19 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) SimpleFilter* sfo = 0; // b IS NULL ConstantColumn* nlhs1 = new ConstantColumn("", ConstantColumn::NULLDATA); - nlhs1->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + nlhs1->timeZone(gwip->timeZone); sop.reset(new PredicateOperator("isnull")); sop->setOpType(lhs->resultType(), rhs->resultType()); sfn1 = new SimpleFilter(sop, rhs, nlhs1); - sfn1->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + sfn1->timeZone(gwip->timeZone); ParseTree* ptpl = new ParseTree(sfn1); // a IS NULL ConstantColumn* nlhs2 = new ConstantColumn("", ConstantColumn::NULLDATA); - nlhs2->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + nlhs2->timeZone(gwip->timeZone); sop.reset(new PredicateOperator("isnull")); sop->setOpType(lhs->resultType(), rhs->resultType()); sfn2 = new SimpleFilter(sop, lhs, nlhs2); - sfn2->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + sfn2->timeZone(gwip->timeZone); ParseTree* ptpr = new ParseTree(sfn2); // AND them both ParseTree* ptpn = new ParseTree(new LogicOperator("and")); @@ -2287,7 +2283,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) sop.reset(new PredicateOperator("=")); sop->setOpType(lhs->resultType(), rhs->resultType()); sfo = new SimpleFilter(sop, lhs->clone(), rhs->clone()); - sfo->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + sfo->timeZone(gwip->timeZone); // OR with the NULL comparison tree ParseTree* ptp = new ParseTree(new LogicOperator("or")); ptp->left(sfo); @@ -2337,7 +2333,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) bool buildConstPredicate(Item_func* ifp, ReturnedColumn* rhs, gp_walk_info* gwip) { SimpleFilter* sf = new SimpleFilter(); - sf->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + sf->timeZone(gwip->timeZone); boost::shared_ptr sop(new PredicateOperator(ifp->func_name())); ConstantColumn* lhs = 0; @@ -2356,7 +2352,7 @@ bool buildConstPredicate(Item_func* ifp, ReturnedColumn* rhs, gp_walk_info* gwip lhs = new ConstantColumn((int64_t)0, ConstantColumn::NUM); sop.reset(new PredicateOperator("=")); } - lhs->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + lhs->timeZone(gwip->timeZone); CalpontSystemCatalog::ColType opType = rhs->resultType(); @@ -2431,7 +2427,7 @@ SimpleColumn* buildSimpleColFromDerivedTable(gp_walk_info& gwi, Item_field* ifp) sc->tableAlias(gwi.tbList[i].alias); sc->viewName(viewName, lower_case_table_names); sc->resultType(ct); - sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + sc->timeZone(gwi.timeZone); break; } } @@ -2490,7 +2486,7 @@ SimpleColumn* buildSimpleColFromDerivedTable(gp_walk_info& gwi, Item_field* ifp) sc->tableName(csep->derivedTbAlias()); sc->colPosition(j); sc->tableAlias(csep->derivedTbAlias()); - sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + sc->timeZone(gwi.timeZone); if (!viewName.empty()) { sc->viewName(viewName, lower_case_table_names); @@ -2613,7 +2609,7 @@ void collectAllCols(gp_walk_info& gwi, Item_field* ifp) sc->tableAlias(csep->derivedTbAlias()); sc->viewName(gwi.tbList[i].view); sc->resultType(cols[j]->resultType()); - sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + sc->timeZone(gwi.timeZone); // @bug5634 derived table optimization cols[j]->incRefCount(); @@ -2661,7 +2657,7 @@ void collectAllCols(gp_walk_info& gwi, Item_field* ifp) sc->resultType(ct); sc->tableAlias(gwi.tbList[i].alias, lower_case_table_names); sc->viewName(viewName, lower_case_table_names); - sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + sc->timeZone(gwi.timeZone); srcp.reset(sc); gwi.returnedCols.push_back(srcp); gwi.columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(sc->columnName(), srcp)); @@ -2994,7 +2990,7 @@ SimpleColumn* getSmallestColumn(boost::shared_ptr csc, sc->columnName(rc->alias()); sc->sequence(0); sc->tableAlias(tan.alias); - sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + sc->timeZone(gwi.timeZone); sc->derivedTable(csep->derivedTbAlias()); sc->derivedRefCol(rc); return sc; @@ -3013,7 +3009,7 @@ SimpleColumn* getSmallestColumn(boost::shared_ptr csc, tan.fisColumnStore, gwi.sessionid, lower_case_table_names); sc->tableAlias(table->alias.ptr(), lower_case_table_names); sc->isColumnStore(false); - sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + sc->timeZone(gwi.timeZone); sc->resultType(fieldType_MysqlToIDB(field)); sc->oid(field->field_index + 1); return sc; @@ -3043,7 +3039,7 @@ SimpleColumn* getSmallestColumn(boost::shared_ptr csc, SimpleColumn* sc = new SimpleColumn(tcn.schema, tcn.table, tcn.column, csc->sessionID()); sc->tableAlias(tan.alias); sc->viewName(tan.view); - sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + sc->timeZone(gwi.timeZone); sc->resultType(csc->colType(oidlist[minWidthColOffset].objnum)); sc->charsetNumber(table->field[minWidthColOffset]->charset()->number); return sc; @@ -3209,7 +3205,7 @@ ReturnedColumn* buildReturnedColumnNull(gp_walk_info& gwi) return new SimpleColumn("noop"); ConstantColumn* rc = new ConstantColumnNull(); if (rc) - rc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + rc->timeZone(gwi.timeZone); return rc; } @@ -3346,7 +3342,7 @@ static ConstantColumn* buildConstantColumnMaybeNullFromValStr(const Item* item, { ConstantColumn* rc = newConstantColumnMaybeNullFromValStrNoTz(item, valStr, gwi); if (rc) - rc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + rc->timeZone(gwi.timeZone); return rc; } @@ -3365,7 +3361,7 @@ static ConstantColumn* buildConstantColumnNotNullUsingValNative(Item* item, gp_w { ConstantColumn* rc = newConstantColumnNotNullUsingValNativeNoTz(item, gwi); if (rc) - rc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + rc->timeZone(gwi.timeZone); return rc; } @@ -3565,7 +3561,7 @@ ArithmeticColumn* buildArithmeticColumn(Item_func* item, gp_walk_info& gwi, bool ArithmeticColumn* ac = new ArithmeticColumn(); Item** sfitempp = item->arguments(); ArithmeticOperator* aop = new ArithmeticOperator(item->func_name()); - aop->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + aop->timeZone(gwi.timeZone); aop->setOverflowCheck(get_decimal_overflow_check(gwi.thd)); ParseTree* pt = new ParseTree(aop); // ReturnedColumn *lhs = 0, *rhs = 0; @@ -3692,7 +3688,7 @@ ArithmeticColumn* buildArithmeticColumn(Item_func* item, gp_walk_info& gwi, bool else { ConstantColumn* cc = new ConstantColumn(string("0"), (int64_t)0); - cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + cc->timeZone(gwi.timeZone); if (gwi.clauseType == SELECT || gwi.clauseType == HAVING || gwi.clauseType == GROUP_BY) // select clause { @@ -4065,15 +4061,14 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non THD* thd = current_thd; sptp.reset( new ParseTree(new ConstantColumn(static_cast(thd->variables.default_week_format)))); - (dynamic_cast(sptp->data())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwi.timeZone); funcParms.push_back(sptp); } // add the keyword unit argument for interval function if (funcName == "date_add_interval" || funcName == "extract" || funcName == "timestampdiff") { - addIntervalArgs(gwi.thd, ifp, funcParms); + addIntervalArgs(&gwi, ifp, funcParms); } // check for unsupported arguments add the keyword unit argument for extract functions @@ -4123,19 +4118,19 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non // add the keyword unit argument and char length for cast functions if (funcName == "cast_as_char") { - castCharArgs(gwi.thd, ifp, funcParms); + castCharArgs(&gwi, ifp, funcParms); } // add the length and scale arguments if (funcName == "decimal_typecast") { - castDecimalArgs(gwi.thd, ifp, funcParms); + castDecimalArgs(&gwi, ifp, funcParms); } // add the type argument if (funcName == "get_format") { - castTypeArgs(gwi.thd, ifp, funcParms); + castTypeArgs(&gwi, ifp, funcParms); } // add my_time_zone @@ -4150,8 +4145,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non // FIXME: Get GMT offset (in seconds east of GMT) in Windows... sptp.reset(new ParseTree(new ConstantColumn(static_cast(0), ConstantColumn::NUM))); #endif - (dynamic_cast(sptp->data())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwi.timeZone); funcParms.push_back(sptp); } @@ -4161,12 +4155,10 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non if (funcParms.size() == 0) { sptp.reset(new ParseTree(new ConstantColumn((int64_t)gwi.thd->rand.seed1, ConstantColumn::NUM))); - (dynamic_cast(sptp->data())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwi.timeZone); funcParms.push_back(sptp); sptp.reset(new ParseTree(new ConstantColumn((int64_t)gwi.thd->rand.seed2, ConstantColumn::NUM))); - (dynamic_cast(sptp->data())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwi.timeZone); funcParms.push_back(sptp); gwi.no_parm_func_list.push_back(fc); } @@ -4220,8 +4212,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non tzinfo = string((char*)buf, length); } sptp.reset(new ParseTree(new ConstantColumn(tzinfo))); - (dynamic_cast(sptp->data())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwi.timeZone); funcParms.push_back(sptp); tzinfo.clear(); if (to_tzinfo) @@ -4233,8 +4224,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non tzinfo = string((char*)buf, length); } sptp.reset(new ParseTree(new ConstantColumn(tzinfo))); - (dynamic_cast(sptp->data())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwi.timeZone); funcParms.push_back(sptp); tzinfo.clear(); } @@ -4253,8 +4243,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non sign = -1; } sptp.reset(new ParseTree(new ConstantColumn(sign))); - (dynamic_cast(sptp->data())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwi.timeZone); funcParms.push_back(sptp); } @@ -4327,16 +4316,23 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non #endif - fc->operationType(functor->operationType(funcParms, fc->resultType())); - // For some reason, MDB has MYSQL_TYPE_DATETIME2 for functions on a TIMESTAMP - if (fc->operationType().colDataType == CalpontSystemCatalog::TIMESTAMP) + execplan::CalpontSystemCatalog::ColType& resultType = fc->resultType(); + resultType.setTimeZone(gwi.timeZone); + fc->operationType(functor->operationType(funcParms, resultType)); + + // For floor/ceiling/truncate/round functions applied on TIMESTAMP columns, set the + // function result type to TIMESTAMP + if ((funcName == "floor" || funcName == "ceiling" || funcName == "truncate" || funcName == "round") && + fc->operationType().colDataType == CalpontSystemCatalog::TIMESTAMP) { CalpontSystemCatalog::ColType ct = fc->resultType(); ct.colDataType = CalpontSystemCatalog::TIMESTAMP; ct.colWidth = 8; fc->resultType(ct); } + fc->expressionId(ci->expressionId++); + // A few functions use a different collation than that found in // the base ifp class if (funcName == "locate" || funcName == "find_in_set" || funcName == "strcmp") @@ -4409,7 +4405,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non } } - fc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + fc->timeZone(gwi.timeZone); return fc; } @@ -4549,11 +4545,13 @@ FunctionColumn* buildCaseFunction(Item_func* item, gp_walk_info& gwi, bool& nonS Func* functor = funcexp->getFunctor(funcName); fc->resultType(colType_MysqlToIDB(item)); - fc->operationType(functor->operationType(funcParms, fc->resultType())); + execplan::CalpontSystemCatalog::ColType& resultType = fc->resultType(); + resultType.setTimeZone(gwi.timeZone); + fc->operationType(functor->operationType(funcParms, resultType)); fc->functionName(funcName); fc->functionParms(funcParms); fc->expressionId(ci->expressionId++); - fc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + fc->timeZone(gwi.timeZone); // For function join. If any argument has non-zero joininfo, set it to the function. fc->setSimpleColumnList(); @@ -4695,7 +4693,7 @@ SimpleColumn* buildSimpleColumn(Item_field* ifp, gp_walk_info& gwi) sc->alias(ifp->name.str); sc->isColumnStore(prm.columnStore()); - sc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + sc->timeZone(gwi.timeZone); if (!prm.columnStore() && ifp->field) sc->oid(ifp->field->field_index + 1); // ExeMgr requires offset started from 1 @@ -4803,7 +4801,7 @@ static void processAggregateColumnConstArg(gp_walk_info& gwi, SRCP& parm, Aggreg { // Explicit NULL or a const function that evaluated to NULL cc = new ConstantColumnNull(); - cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + cc->timeZone(gwi.timeZone); parm.reset(cc); ac->constCol(SRCP(rt)); return; @@ -4878,7 +4876,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) ac = new AggregateColumn(gwi.sessionid); } - ac->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + ac->timeZone(gwi.timeZone); if (isp->name.length) ac->alias(isp->name.str); @@ -5397,7 +5395,7 @@ because it has multiple arguments."; return ac; } -void addIntervalArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms) +void addIntervalArgs(gp_walk_info* gwip, Item_func* ifp, FunctionParm& functionParms) { string funcName = ifp->func_name(); int interval_type = -1; @@ -5409,7 +5407,7 @@ void addIntervalArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms) else if (funcName == "extract") interval_type = ((Item_extract*)ifp)->int_type; - functionParms.push_back(getIntervalType(thd, interval_type)); + functionParms.push_back(getIntervalType(gwip, interval_type)); SPTP sptp; if (funcName == "date_add_interval") @@ -5417,42 +5415,42 @@ void addIntervalArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms) if (((Item_date_add_interval*)ifp)->date_sub_interval) { sptp.reset(new ParseTree(new ConstantColumn((int64_t)OP_SUB))); - (dynamic_cast(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwip->timeZone); functionParms.push_back(sptp); } else { sptp.reset(new ParseTree(new ConstantColumn((int64_t)OP_ADD))); - (dynamic_cast(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwip->timeZone); functionParms.push_back(sptp); } } } -SPTP getIntervalType(THD* thd, int interval_type) +SPTP getIntervalType(gp_walk_info* gwip, int interval_type) { SPTP sptp; sptp.reset(new ParseTree(new ConstantColumn((int64_t)interval_type))); - (dynamic_cast(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwip->timeZone); return sptp; } -void castCharArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms) +void castCharArgs(gp_walk_info* gwip, Item_func* ifp, FunctionParm& functionParms) { Item_char_typecast* idai = (Item_char_typecast*)ifp; SPTP sptp; sptp.reset(new ParseTree(new ConstantColumn((int64_t)idai->get_cast_length()))); - (dynamic_cast(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwip->timeZone); functionParms.push_back(sptp); } -void castDecimalArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms) +void castDecimalArgs(gp_walk_info* gwip, Item_func* ifp, FunctionParm& functionParms) { Item_decimal_typecast* idai = (Item_decimal_typecast*)ifp; SPTP sptp; sptp.reset(new ParseTree(new ConstantColumn((int64_t)idai->decimals))); - (dynamic_cast(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwip->timeZone); functionParms.push_back(sptp); // max length including sign and/or decimal points @@ -5460,12 +5458,12 @@ void castDecimalArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms) sptp.reset(new ParseTree(new ConstantColumn((int64_t)idai->max_length - 1))); else sptp.reset(new ParseTree(new ConstantColumn((int64_t)idai->max_length - 2))); - (dynamic_cast(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwip->timeZone); functionParms.push_back(sptp); } -void castTypeArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms) +void castTypeArgs(gp_walk_info* gwip, Item_func* ifp, FunctionParm& functionParms) { Item_func_get_format* get_format = (Item_func_get_format*)ifp; SPTP sptp; @@ -5474,7 +5472,7 @@ void castTypeArgs(THD* thd, Item_func* ifp, FunctionParm& functionParms) sptp.reset(new ParseTree(new ConstantColumn("DATE"))); else sptp.reset(new ParseTree(new ConstantColumn("DATETIME"))); - (dynamic_cast(sptp->data()))->timeZone(thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwip->timeZone); functionParms.push_back(sptp); } @@ -5575,7 +5573,7 @@ void gp_walk(const Item* item, void* arg) Item_hex_hybrid* hip = reinterpret_cast(const_cast(item)); gwip->rcWorkStack.push(new ConstantColumn((int64_t)hip->val_int(), ConstantColumn::NUM)); ConstantColumn* cc = dynamic_cast(gwip->rcWorkStack.top()); - cc->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + cc->timeZone(gwip->timeZone); break; } @@ -5594,8 +5592,7 @@ void gp_walk(const Item* item, void* arg) } gwip->rcWorkStack.push(new ConstantColumn(cval)); - (dynamic_cast(gwip->rcWorkStack.top())) - ->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(gwip->rcWorkStack.top()))->timeZone(gwip->timeZone); break; } @@ -5630,7 +5627,7 @@ void gp_walk(const Item* item, void* arg) { // push noop for unhandled item SimpleColumn* rc = new SimpleColumn("noop"); - rc->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + rc->timeZone(gwip->timeZone); gwip->rcWorkStack.push(rc); break; } @@ -5650,14 +5647,13 @@ void gp_walk(const Item* item, void* arg) { // push noop for unhandled item SimpleColumn* rc = new SimpleColumn("noop"); - rc->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + rc->timeZone(gwip->timeZone); gwip->rcWorkStack.push(rc); break; } gwip->rcWorkStack.push(new ConstantColumn("", ConstantColumn::NULLDATA)); - (dynamic_cast(gwip->rcWorkStack.top())) - ->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(gwip->rcWorkStack.top()))->timeZone(gwip->timeZone); break; } @@ -6175,7 +6171,7 @@ void gp_walk(const Item* item, void* arg) { // push noop for unhandled item SimpleColumn* rc = new SimpleColumn("noop"); - rc->timeZone(gwip->thd->variables.time_zone->get_name()->ptr()); + rc->timeZone(gwip->timeZone); gwip->rcWorkStack.push(rc); break; } @@ -6664,7 +6660,7 @@ int processFrom(bool& isUnion, SELECT_LEX& select_lex, gp_walk_info& gwi, SCSEP& plan->data(csep->data()); // gwi for the union unit - gp_walk_info union_gwi; + gp_walk_info union_gwi(gwi.timeZone); union_gwi.thd = gwi.thd; uint32_t err = 0; @@ -6777,8 +6773,7 @@ int processWhere(SELECT_LEX& select_lex, gp_walk_info& gwi, SCSEP& csep, const s else if (join && join->zero_result_cause) { gwi.rcWorkStack.push(new ConstantColumn((int64_t)0, ConstantColumn::NUM)); - (dynamic_cast(gwi.rcWorkStack.top())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(gwi.rcWorkStack.top()))->timeZone(gwi.timeZone); } for (Item* item : gwi.condList) @@ -7226,7 +7221,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i gwi.sessionid = sessionID; boost::shared_ptr csc = CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID); csc->identity(CalpontSystemCatalog::FE); - csep->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + csep->timeZone(gwi.timeZone); gwi.csc = csc; CalpontSelectExecutionPlan::SelectList derivedTbList; @@ -7607,7 +7602,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i selectSubList.push_back(ssub); SimpleColumn* rc = new SimpleColumn(); rc->colSource(rc->colSource() | SELECT_SUB); - rc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + rc->timeZone(gwi.timeZone); if (sub->get_select_lex()->get_table_list()) { @@ -8414,7 +8409,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i sc1->tableAlias(sc->tableAlias()); sc1->viewName(sc->viewName()); sc1->colPosition(0); - sc1->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + sc1->timeZone(gwi.timeZone); minSc.reset(sc1); } } @@ -8473,12 +8468,12 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i return 0; } -int cp_get_table_plan(THD* thd, SCSEP& csep, cal_table_info& ti) +int cp_get_table_plan(THD* thd, SCSEP& csep, cal_table_info& ti, long timeZone) { gp_walk_info* gwi = ti.condInfo; if (!gwi) - gwi = new gp_walk_info(); + gwi = new gp_walk_info(timeZone); gwi->thd = thd; LEX* lex = thd->lex; @@ -8506,7 +8501,7 @@ int cp_get_table_plan(THD* thd, SCSEP& csep, cal_table_info& ti) boost::algorithm::to_lower(alias); } sc->tableAlias(alias); - sc->timeZone(gwi->thd->variables.time_zone->get_name()->ptr()); + sc->timeZone(gwi->timeZone); assert(sc); boost::shared_ptr spsc(sc); gwi->returnedCols.push_back(spsc); @@ -8581,7 +8576,10 @@ int cp_get_table_plan(THD* thd, SCSEP& csep, cal_table_info& ti) int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi) { SELECT_LEX* select_lex = gi.groupByTables->select_lex; - gp_walk_info gwi; + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + gp_walk_info gwi(timeZoneOffset); gwi.thd = thd; gwi.isGroupByHandler = true; int status = getGroupPlan(gwi, *select_lex, csep, gi); @@ -8597,7 +8595,7 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi) else if (status < 0) return status; // Derived table projection and filter optimization. - derivedTableOptimization(thd, csep); + derivedTableOptimization(&gwi, csep); return 0; } @@ -8618,7 +8616,7 @@ int cs_get_derived_plan(ha_columnstore_derived_handler* handler, THD* thd, SCSEP cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; #endif // Derived table projection and filter optimization. - derivedTableOptimization(thd, csep); + derivedTableOptimization(&gwi, csep); return 0; } @@ -8649,7 +8647,7 @@ int cs_get_select_plan(ha_columnstore_select_handler* handler, THD* thd, SCSEP& cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; #endif // Derived table projection and filter optimization. - derivedTableOptimization(thd, csep); + derivedTableOptimization(&gwi, csep); return 0; } @@ -8954,8 +8952,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro else if (join && join->zero_result_cause) { gwi.rcWorkStack.push(new ConstantColumn((int64_t)0, ConstantColumn::NUM)); - (dynamic_cast(gwi.rcWorkStack.top())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(gwi.rcWorkStack.top()))->timeZone(gwi.timeZone); } SELECT_LEX tmp_select_lex; @@ -9443,7 +9440,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro selectSubList.push_back(ssub); SimpleColumn* rc = new SimpleColumn(); rc->colSource(rc->colSource() | SELECT_SUB); - rc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + rc->timeZone(gwi.timeZone); if (sub->get_select_lex()->get_table_list()) { @@ -10401,7 +10398,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro sc1->tableName(sc->tableName()); sc1->tableAlias(sc->tableAlias()); sc1->viewName(sc->viewName()); - sc1->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + sc1->timeZone(gwi.timeZone); sc1->colPosition(0); minSc.reset(sc1); } diff --git a/dbcon/mysql/ha_mcs_impl.cpp b/dbcon/mysql/ha_mcs_impl.cpp index 5ef57cf43..9e7292949 100644 --- a/dbcon/mysql/ha_mcs_impl.cpp +++ b/dbcon/mysql/ha_mcs_impl.cpp @@ -295,7 +295,8 @@ 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 fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, long timeZone, + bool handler_flag = false) { int rc = HA_ERR_END_OF_FILE; int num_attr = ti.msTablePtr->s->fields; @@ -436,7 +437,7 @@ int fetchNextRow(uchar* buf, cal_table_info& ti, cal_connection_info* ci, bool h { // fetch and store data (*f)->set_notnull(); - datatypes::StoreFieldMariaDB mf(*f, colType); + datatypes::StoreFieldMariaDB mf(*f, colType, timeZone); h->storeValueToField(row, s, &mf); } } @@ -891,6 +892,10 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector& c bool isFromSameTable = true; execplan::SCSEP updateCP(new execplan::CalpontSelectExecutionPlan()); + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + updateCP->isDML(true); //@Bug 2753. the memory already freed by destructor of UpdateSqlStatement @@ -1014,9 +1019,9 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector& c // sysdate() etc. if (!hasNonSupportItem && !cal_impl_if::nonConstFunc(ifp) && tmpVec.size() == 0) { - gp_walk_info gwi; - gwi.thd = thd; - SRCP srcp(buildReturnedColumn(value, gwi, gwi.fatalParseError)); + gp_walk_info gwi2(gwi.timeZone); + gwi2.thd = thd; + SRCP srcp(buildReturnedColumn(value, gwi2, gwi2.fatalParseError)); ConstantColumn* constCol = dynamic_cast(srcp.get()); if (constCol) @@ -1163,7 +1168,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector& c char buf[64]; gettimeofday(&tv, 0); MySQLTime time; - gmtSecToMySQLTime(tv.tv_sec, time, thd->variables.time_zone->get_name()->ptr()); + gmtSecToMySQLTime(tv.tv_sec, time, timeZoneOffset); sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d.%06ld", time.year, time.month, time.day, time.hour, time.minute, time.second, tv.tv_usec); columnAssignmentPtr->fScalarExpression = buf; @@ -1314,7 +1319,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector& c pDMLPackage->set_TableName(tableName); pDMLPackage->set_SchemaName(schemaName); - pDMLPackage->set_TimeZone(thd->variables.time_zone->get_name()->ptr()); + pDMLPackage->set_TimeZone(timeZoneOffset); pDMLPackage->set_IsFromCol(true); // cout << " setting isFromCol to " << isFromCol << endl; @@ -1516,7 +1521,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector& c CalpontSystemCatalog::TableColName tcn = csc->colName(colrids[minWidthColOffset].objnum); SimpleColumn* sc = new SimpleColumn(tcn.schema, tcn.table, tcn.column, csc->sessionID()); sc->tableAlias(aliasName); - sc->timeZone(thd->variables.time_zone->get_name()->ptr()); + sc->timeZone(timeZoneOffset); sc->resultType(csc->colType(colrids[minWidthColOffset].objnum)); SRCP srcp; srcp.reset(sc); @@ -1660,7 +1665,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector& c // << endl; VendorDMLStatement cmdStmt("CTRL+C", DML_COMMAND, sessionID); CalpontDMLPackage* pDMLPackage = CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(cmdStmt); - pDMLPackage->set_TimeZone(thd->variables.time_zone->get_name()->ptr()); + pDMLPackage->set_TimeZone(timeZoneOffset); ByteStream bytestream; bytestream << static_cast(sessionID); pDMLPackage->write(bytestream); @@ -1783,7 +1788,7 @@ uint32_t doUpdateDelete(THD* thd, gp_walk_info& gwi, const std::vector& c { VendorDMLStatement cmdStmt(command, DML_COMMAND, sessionID); CalpontDMLPackage* pDMLPackage = CalpontDMLFactory::makeCalpontDMLPackageFromMysqlBuffer(cmdStmt); - pDMLPackage->set_TimeZone(thd->variables.time_zone->get_name()->ptr()); + pDMLPackage->set_TimeZone(timeZoneOffset); pDMLPackage->setTableOid(ci->tableOid); ByteStream bytestream; bytestream << static_cast(sessionID); @@ -2008,6 +2013,10 @@ int ha_mcs_impl_analyze(THD* thd, TABLE* table) execplan::MCSAnalyzeTableExecutionPlan::ReturnedColumnList returnedColumnList; execplan::MCSAnalyzeTableExecutionPlan::ColumnMap columnMap; + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + // Iterate over table oid list and create a `SimpleColumn` for every column with supported type. for (uint32_t i = 0, e = oidlist.size(); i < e; ++i) { @@ -2026,7 +2035,7 @@ int ha_mcs_impl_analyze(THD* thd, TABLE* table) simpleColumn->oid(objNum); simpleColumn->alias(tableColName.column); simpleColumn->resultType(colType); - simpleColumn->timeZone(thd->variables.time_zone->get_name()->ptr()); + simpleColumn->timeZone(timeZoneOffset); returnedColumn.reset(simpleColumn); returnedColumnList.push_back(returnedColumn); @@ -2040,7 +2049,7 @@ int ha_mcs_impl_analyze(THD* thd, TABLE* table) caep->schemaName(table->s->db.str, lower_case_table_names); caep->tableName(table->s->table_name.str, lower_case_table_names); - caep->timeZone(thd->variables.time_zone->get_name()->ptr()); + caep->timeZone(timeZoneOffset); SessionManager sm; BRM::TxnID txnID; @@ -2160,7 +2169,10 @@ int ha_mcs_impl_direct_update_delete_rows(bool execute, ha_rows* affected_rows, const std::vector& condStack) { THD* thd = current_thd; - cal_impl_if::gp_walk_info gwi; + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + cal_impl_if::gp_walk_info gwi(timeZoneOffset); gwi.thd = thd; int rc = 0; @@ -2189,8 +2201,10 @@ int ha_mcs::impl_rnd_init(TABLE* table, const std::vector& condStack) { IDEBUG(cout << "rnd_init for table " << table->s->table_name.str << endl); THD* thd = current_thd; - - gp_walk_info gwi; + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + gp_walk_info gwi(timeZoneOffset); gwi.thd = thd; if (thd->slave_thread && !get_replication_slave(thd) && isDMLStatement(thd->lex->sql_command)) @@ -2333,7 +2347,7 @@ int ha_mcs::impl_rnd_init(TABLE* table, const std::vector& condStack) ti.msTablePtr = table; // send plan whenever rnd_init is called - cp_get_table_plan(thd, ti.csep, ti); + cp_get_table_plan(thd, ti.csep, ti, timeZoneOffset); } IDEBUG(cerr << table->s->table_name.str << " send plan:" << endl); @@ -2563,7 +2577,7 @@ internal_error: return ER_INTERNAL_ERROR; } -int ha_mcs_impl_rnd_next(uchar* buf, TABLE* table) +int ha_mcs_impl_rnd_next(uchar* buf, TABLE* table, long timeZone) { THD* thd = current_thd; @@ -2606,7 +2620,7 @@ int ha_mcs_impl_rnd_next(uchar* buf, TABLE* table) try { - rc = fetchNextRow(buf, ti, ci); + rc = fetchNextRow(buf, ti, ci, timeZone); } catch (std::exception& e) { @@ -2846,7 +2860,7 @@ int ha_mcs_impl_delete_table(const char* name) int rc = ha_mcs_impl_delete_table_(dbName, name, *ci); return rc; } -int ha_mcs_impl_write_row(const uchar* buf, TABLE* table, uint64_t rows_changed) +int ha_mcs_impl_write_row(const uchar* buf, TABLE* table, uint64_t rows_changed, long timeZone) { THD* thd = current_thd; @@ -2893,7 +2907,7 @@ int ha_mcs_impl_write_row(const uchar* buf, TABLE* table, uint64_t rows_changed) ((thd->lex)->sql_command == SQLCOM_LOAD) || ((thd->lex)->sql_command == SQLCOM_INSERT_SELECT) || ci->isCacheInsert)) { - rc = ha_mcs_impl_write_batch_row_(buf, table, *ci); + rc = ha_mcs_impl_write_batch_row_(buf, table, *ci, timeZone); } else { @@ -3894,7 +3908,10 @@ COND* ha_mcs_impl_cond_push(COND* cond, TABLE* table, std::vector& condSt #ifdef DEBUG_WALK_COND { - gp_walk_info gwi; + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + gp_walk_info gwi(timeZoneOffset); gwi.condPush = true; gwi.sessionid = tid2sid(thd->thread_id); cout << "------------------ cond push -----------------------" << endl; @@ -3906,7 +3923,12 @@ COND* ha_mcs_impl_cond_push(COND* cond, TABLE* table, std::vector& condSt if (!ti.csep) { if (!ti.condInfo) - ti.condInfo = new gp_walk_info(); + { + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + ti.condInfo = new gp_walk_info(timeZoneOffset); + } gp_walk_info* gwi = ti.condInfo; gwi->dropCond = false; @@ -4554,7 +4576,7 @@ internal_error: * HA_ERR_END_OF_FILE if the record set has come to an end * others if something went wrong whilst getting the result set ***********************************************************/ -int ha_mcs_impl_group_by_next(TABLE* table) +int ha_mcs_impl_group_by_next(TABLE* table, long timeZone) { THD* thd = current_thd; @@ -4594,7 +4616,7 @@ int ha_mcs_impl_group_by_next(TABLE* table) { // fetchNextRow interface forces to use buf. unsigned char buf; - rc = fetchNextRow(&buf, ti, ci, true); + rc = fetchNextRow(&buf, ti, ci, timeZone, true); } catch (std::exception& e) { @@ -4801,7 +4823,10 @@ int ha_mcs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table) if (thd->slave_thread && !get_replication_slave(thd) && isDMLStatement(thd->lex->sql_command)) return 0; - gp_walk_info gwi; + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + gp_walk_info gwi(timeZoneOffset); gwi.thd = thd; bool err = false; @@ -5237,7 +5262,7 @@ internal_error: return ER_INTERNAL_ERROR; } -int ha_mcs_impl_select_next(uchar* buf, TABLE* table) +int ha_mcs_impl_select_next(uchar* buf, TABLE* table, long timeZone) { THD* thd = current_thd; @@ -5336,7 +5361,7 @@ int ha_mcs_impl_select_next(uchar* buf, TABLE* table) try { - rc = fetchNextRow(buf, ti, ci); + rc = fetchNextRow(buf, ti, ci, timeZone); } catch (std::exception& e) { diff --git a/dbcon/mysql/ha_mcs_impl.h b/dbcon/mysql/ha_mcs_impl.h index a776c783a..dc8da092d 100644 --- a/dbcon/mysql/ha_mcs_impl.h +++ b/dbcon/mysql/ha_mcs_impl.h @@ -29,9 +29,9 @@ extern int ha_mcs_impl_delete_table(const char* name); extern int ha_mcs_impl_analyze(THD* thd, TABLE* table); extern int ha_mcs_impl_open(const char* name, int mode, uint32_t test_if_locked); extern int ha_mcs_impl_close(void); -extern int ha_mcs_impl_rnd_next(uchar* buf, TABLE* table); +extern int ha_mcs_impl_rnd_next(uchar* buf, TABLE* table, long timeZone); extern int ha_mcs_impl_rnd_end(TABLE* table, bool is_derived_hand = false); -extern int ha_mcs_impl_write_row(const uchar* buf, TABLE* table, uint64_t rows_changed); +extern int ha_mcs_impl_write_row(const uchar* buf, TABLE* table, uint64_t rows_changed, long timeZone); extern void ha_mcs_impl_start_bulk_insert(ha_rows rows, TABLE* table, bool is_cache_insert = false); extern int ha_mcs_impl_end_bulk_insert(bool abort, TABLE* table); extern int ha_mcs_impl_rename_table(const char* from, const char* to); @@ -45,9 +45,9 @@ extern int ha_mcs_impl_direct_update_delete_rows(bool execute, ha_rows* affected extern int ha_mcs_impl_delete_row(); extern int ha_mcs_impl_rnd_pos(uchar* buf, uchar* pos); extern int ha_mcs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table); -extern int ha_mcs_impl_select_next(uchar* buf, TABLE* table); +extern int ha_mcs_impl_select_next(uchar* buf, TABLE* table, long timeZone); extern int ha_mcs_impl_group_by_init(mcs_handler_info* handler_info, TABLE* table); -extern int ha_mcs_impl_group_by_next(TABLE* table); +extern int ha_mcs_impl_group_by_next(TABLE* table, long timeZone); extern int ha_mcs_impl_group_by_end(TABLE* table); #endif @@ -59,7 +59,8 @@ extern int ha_mcs_impl_group_by_end(TABLE* table); extern int ha_mcs_impl_rename_table_(const char* from, const char* to, cal_impl_if::cal_connection_info& ci); extern int ha_mcs_impl_write_row_(const uchar* buf, TABLE* table, cal_impl_if::cal_connection_info& ci, ha_rows& rowsInserted); -extern int ha_mcs_impl_write_batch_row_(const uchar* buf, TABLE* table, cal_impl_if::cal_connection_info& ci); +extern int ha_mcs_impl_write_batch_row_(const uchar* buf, TABLE* table, cal_impl_if::cal_connection_info& ci, + long timeZone); extern int ha_mcs_impl_write_last_batch(TABLE* table, cal_impl_if::cal_connection_info& ci, bool abort); extern int ha_mcs_impl_commit_(handlerton* hton, THD* thd, bool all, cal_impl_if::cal_connection_info& ci); extern int ha_mcs_impl_rollback_(handlerton* hton, THD* thd, bool all, cal_impl_if::cal_connection_info& ci); diff --git a/dbcon/mysql/ha_mcs_impl_if.h b/dbcon/mysql/ha_mcs_impl_if.h index e3ac09932..f3ebd7f42 100644 --- a/dbcon/mysql/ha_mcs_impl_if.h +++ b/dbcon/mysql/ha_mcs_impl_if.h @@ -165,6 +165,7 @@ struct gp_walk_info bool cs_vtable_impossible_where_on_union; bool isGroupByHandler; + long timeZone; // MCOL-4617 The below 2 fields are used for in-to-exists // predicate creation and injection. See usage in InSub::transform() @@ -176,7 +177,7 @@ struct gp_walk_info TableOnExprList tableOnExprList; std::vector condList; - gp_walk_info() + gp_walk_info(long timeZone_) : sessionid(0) , fatalParseError(false) , condPush(false) @@ -197,6 +198,7 @@ struct gp_walk_info , cs_vtable_is_update_with_derive(false) , cs_vtable_impossible_where_on_union(false) , isGroupByHandler(false) + , timeZone(timeZone_) , inSubQueryLHS(nullptr) , inSubQueryLHSItem(nullptr) { @@ -391,7 +393,7 @@ const std::string infinidb_err_msg = "distributed syntax or consider changing the MariaDB Columnstore Operating Mode (infinidb_vtable_mode)."; int cp_get_plan(THD* thd, execplan::SCSEP& csep); -int cp_get_table_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_table_info& ti); +int cp_get_table_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_table_info& ti, long timeZone); int cp_get_group_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_group_info& gi); int cs_get_derived_plan(ha_columnstore_derived_handler* handler, THD* thd, execplan::SCSEP& csep, gp_walk_info& gwi); @@ -428,14 +430,14 @@ execplan::ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi); execplan::ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& nonSupport); execplan::ReturnedColumn* buildPseudoColumn(Item* item, gp_walk_info& gwi, bool& nonSupport, uint32_t pseudoType); -void addIntervalArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms); -void castCharArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms); -void castDecimalArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms); -void castTypeArgs(THD* thd, Item_func* ifp, funcexp::FunctionParm& functionParms); +void addIntervalArgs(gp_walk_info* gwip, Item_func* ifp, funcexp::FunctionParm& functionParms); +void castCharArgs(gp_walk_info* gwip, Item_func* ifp, funcexp::FunctionParm& functionParms); +void castDecimalArgs(gp_walk_info* gwip, Item_func* ifp, funcexp::FunctionParm& functionParms); +void castTypeArgs(gp_walk_info* gwip, Item_func* ifp, funcexp::FunctionParm& functionParms); // void parse_item (Item* item, std::vector& field_vec, bool& hasNonSupportItem, uint16& // parseInfo); bool isPredicateFunction(Item* item, gp_walk_info* gwip); -execplan::ParseTree* buildRowPredicate(THD* thd, execplan::RowColumn* lhs, execplan::RowColumn* rhs, +execplan::ParseTree* buildRowPredicate(gp_walk_info* gwip, execplan::RowColumn* lhs, execplan::RowColumn* rhs, std::string predicateOp); bool buildRowColumnFilter(gp_walk_info* gwip, execplan::RowColumn* rhs, execplan::RowColumn* lhs, Item_func* ifp); @@ -448,13 +450,13 @@ std::string getViewName(TABLE_LIST* table_ptr); bool buildConstPredicate(Item_func* ifp, execplan::ReturnedColumn* rhs, gp_walk_info* gwip); execplan::CalpontSystemCatalog::ColType fieldType_MysqlToIDB(const Field* field); execplan::CalpontSystemCatalog::ColType colType_MysqlToIDB(const Item* item); -execplan::SPTP getIntervalType(THD* thd, int interval_type); +execplan::SPTP getIntervalType(gp_walk_info* gwip, int interval_type); uint32_t isPseudoColumn(std::string funcName); void setDerivedTable(execplan::ParseTree* n); -execplan::ParseTree* setDerivedFilter(THD* thd, execplan::ParseTree*& n, +execplan::ParseTree* setDerivedFilter(gp_walk_info* gwip, execplan::ParseTree*& n, std::map& obj, execplan::CalpontSelectExecutionPlan::SelectList& derivedTbList); -void derivedTableOptimization(THD* thd, execplan::SCSEP& csep); +void derivedTableOptimization(gp_walk_info* gwip, execplan::SCSEP& csep); bool buildEqualityPredicate(execplan::ReturnedColumn* lhs, execplan::ReturnedColumn* rhs, gp_walk_info* gwip, boost::shared_ptr& sop, const Item_func::Functype& funcType, const std::vector& itemList, bool isInSubs = false); diff --git a/dbcon/mysql/ha_mcs_partition.cpp b/dbcon/mysql/ha_mcs_partition.cpp index 8ed8c59f3..c65c79f46 100644 --- a/dbcon/mysql/ha_mcs_partition.cpp +++ b/dbcon/mysql/ha_mcs_partition.cpp @@ -385,7 +385,10 @@ void partitionByValue_common(UDF_ARGS* args, // inp csc->identity(CalpontSystemCatalog::FE); OID_t oid = csc->lookupOID(tcn); CalpontSystemCatalog::ColType ct = csc->colType(oid); - datatypes::SessionParam sp(current_thd->variables.time_zone->get_name()->ptr()); + const char* timeZone = current_thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + datatypes::SessionParam sp(timeZoneOffset); datatypes::SimpleValue startVal; datatypes::SimpleValue endVal; datatypes::round_style_t rfMin = datatypes::round_style_t::NONE; @@ -1252,7 +1255,10 @@ extern "C" string schema, table, column; CalpontSystemCatalog::ColType ct; string errMsg; - datatypes::SessionParam sp(current_thd->variables.time_zone->get_name()->ptr()); + const char* timeZone = current_thd->variables.time_zone->get_name()->ptr(); + long timeZoneOffset; + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &timeZoneOffset); + datatypes::SessionParam sp(timeZoneOffset); datatypes::SimpleValue startVal; datatypes::SimpleValue endVal; datatypes::round_style_t rfMin = datatypes::round_style_t::NONE; diff --git a/dbcon/mysql/ha_mcs_pushdown.cpp b/dbcon/mysql/ha_mcs_pushdown.cpp index cefe23986..619caff4c 100644 --- a/dbcon/mysql/ha_mcs_pushdown.cpp +++ b/dbcon/mysql/ha_mcs_pushdown.cpp @@ -581,6 +581,8 @@ ha_columnstore_derived_handler::ha_columnstore_derived_handler(THD* thd, TABLE_L : derived_handler(thd, mcs_hton) { derived = dt; + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &time_zone); } /*********************************************************** @@ -625,7 +627,7 @@ int ha_columnstore_derived_handler::next_row() { DBUG_ENTER("ha_columnstore_derived_handler::next_row"); - int rc = ha_mcs_impl_rnd_next(table->record[0], table); + int rc = ha_mcs_impl_rnd_next(table->record[0], table, time_zone); DBUG_RETURN(rc); } @@ -670,6 +672,8 @@ ha_mcs_group_by_handler::ha_mcs_group_by_handler(THD* thd_arg, Query* query) , order_by(query->order_by) , having(query->having) { + const char* timeZone = thd_arg->variables.time_zone->get_name()->ptr(); + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &time_zone); } /*********************************************************** @@ -705,7 +709,7 @@ int ha_mcs_group_by_handler::init_scan() int ha_mcs_group_by_handler::next_row() { DBUG_ENTER("ha_mcs_group_by_handler::next_row"); - int rc = ha_mcs_impl_group_by_next(table); + int rc = ha_mcs_impl_group_by_next(table, time_zone); DBUG_RETURN(rc); } @@ -985,6 +989,8 @@ ha_columnstore_select_handler::ha_columnstore_select_handler(THD* thd, SELECT_LE , pushdown_init_rc(0) { select = select_lex; + const char* timeZone = thd->variables.time_zone->get_name()->ptr(); + dataconvert::timeZoneToOffset(timeZone, strlen(timeZone), &time_zone); } /*********************************************************** @@ -1028,7 +1034,7 @@ int ha_columnstore_select_handler::next_row() { DBUG_ENTER("ha_columnstore_select_handler::next_row"); - int rc = ha_mcs_impl_select_next(table->record[0], table); + int rc = ha_mcs_impl_select_next(table->record[0], table, time_zone); DBUG_RETURN(rc); } diff --git a/dbcon/mysql/ha_mcs_pushdown.h b/dbcon/mysql/ha_mcs_pushdown.h index dc127bb2e..80ca3cff8 100644 --- a/dbcon/mysql/ha_mcs_pushdown.h +++ b/dbcon/mysql/ha_mcs_pushdown.h @@ -76,6 +76,9 @@ struct mcs_handler_info ***********************************************************/ class ha_mcs_group_by_handler : public group_by_handler { + private: + long time_zone; + public: ha_mcs_group_by_handler(THD* thd_arg, Query* query); ~ha_mcs_group_by_handler(); @@ -109,6 +112,7 @@ class ha_columnstore_derived_handler : public derived_handler { private: COLUMNSTORE_SHARE* share; + long time_zone; public: ha_columnstore_derived_handler(THD* thd_arg, TABLE_LIST* tbl); @@ -138,6 +142,7 @@ class ha_columnstore_select_handler : public select_handler COLUMNSTORE_SHARE* share; bool prepared; bool scan_ended; + long time_zone; public: bool scan_initialized; diff --git a/dbcon/mysql/ha_pseudocolumn.cpp b/dbcon/mysql/ha_pseudocolumn.cpp index fb87a76cc..26fb82264 100644 --- a/dbcon/mysql/ha_pseudocolumn.cpp +++ b/dbcon/mysql/ha_pseudocolumn.cpp @@ -494,7 +494,7 @@ execplan::ReturnedColumn* buildPseudoColumn(Item* item, gp_walk_info& gwi, bool& cc = new ConstantColumn(localPm); else cc = new ConstantColumn("", ConstantColumn::NULLDATA); - cc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + cc->timeZone(gwi.timeZone); cc->alias(ifp->full_name() ? ifp->full_name() : ""); return cc; @@ -556,7 +556,7 @@ execplan::ReturnedColumn* buildPseudoColumn(Item* item, gp_walk_info& gwi, bool& parms.push_back(sptp); fc->functionParms(parms); fc->expressionId(ci->expressionId++); - fc->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + fc->timeZone(gwi.timeZone); // string result type CalpontSystemCatalog::ColType ct; diff --git a/dbcon/mysql/ha_scalar_sub.cpp b/dbcon/mysql/ha_scalar_sub.cpp index 4a4f08fca..b12ea4791 100644 --- a/dbcon/mysql/ha_scalar_sub.cpp +++ b/dbcon/mysql/ha_scalar_sub.cpp @@ -109,8 +109,7 @@ execplan::ParseTree* ScalarSub::transform() { fSub = (Item_subselect*)(fFunc->arguments()[0]); fColumn.reset(new ConstantColumn("", ConstantColumn::NULLDATA)); - (dynamic_cast(fColumn.get())) - ->timeZone(fGwip.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(fColumn.get()))->timeZone(fGwip.timeZone); delete rhs; return buildParseTree(op); } @@ -176,7 +175,7 @@ execplan::ParseTree* ScalarSub::transform_between() SOP sop; sop.reset(op_LE); rhs = new ParseTree(new SimpleFilter(sop, fColumn.get(), op3)); - (dynamic_cast(rhs->data()))->timeZone(fGwip.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(rhs->data()))->timeZone(fGwip.timeZone); } SubSelect* sub1 = dynamic_cast(op2); @@ -192,7 +191,7 @@ execplan::ParseTree* ScalarSub::transform_between() SOP sop; sop.reset(op_GE); lhs = new ParseTree(new SimpleFilter(sop, fColumn.get(), op2)); - (dynamic_cast(lhs->data()))->timeZone(fGwip.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(lhs->data()))->timeZone(fGwip.timeZone); } if (!rhs || !lhs) @@ -245,7 +244,7 @@ execplan::ParseTree* ScalarSub::buildParseTree(PredicateOperator* op) csep->subType(CalpontSelectExecutionPlan::SINGLEROW_SUBS); // gwi for the sub query - gp_walk_info gwi; + gp_walk_info gwi(fGwip.timeZone); gwi.thd = fGwip.thd; gwi.subQuery = this; diff --git a/dbcon/mysql/ha_select_sub.cpp b/dbcon/mysql/ha_select_sub.cpp index 897da428e..2bce37765 100644 --- a/dbcon/mysql/ha_select_sub.cpp +++ b/dbcon/mysql/ha_select_sub.cpp @@ -67,7 +67,7 @@ SCSEP SelectSubQuery::transform() csep->subType(CalpontSelectExecutionPlan::SELECT_SUBS); // gwi for the sub query - gp_walk_info gwi; + gp_walk_info gwi(fGwip.timeZone); gwi.thd = fGwip.thd; gwi.subQuery = this; diff --git a/dbcon/mysql/ha_view.cpp b/dbcon/mysql/ha_view.cpp index c37907e98..4912fd71d 100644 --- a/dbcon/mysql/ha_view.cpp +++ b/dbcon/mysql/ha_view.cpp @@ -65,7 +65,7 @@ void View::transform() csep->sessionID(fParentGwip->sessionid); // gwi for the sub query - gp_walk_info gwi; + gp_walk_info gwi(fParentGwip->timeZone); gwi.thd = fParentGwip->thd; uint32_t sessionID = csep->sessionID(); diff --git a/dbcon/mysql/ha_window_function.cpp b/dbcon/mysql/ha_window_function.cpp index 8111e14b0..e94372cea 100644 --- a/dbcon/mysql/ha_window_function.cpp +++ b/dbcon/mysql/ha_window_function.cpp @@ -145,27 +145,25 @@ ReturnedColumn* buildBoundExp(WF_Boundary& bound, SRCP& order, gp_walk_info& gwi // put interval val column to bound (dynamic_cast(rc))->functionName(funcName); - (dynamic_cast(rc))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(rc))->timeZone(gwi.timeZone); sptp.reset(new ParseTree(order->clone())); funcParms.push_back(sptp); sptp.reset(new ParseTree(intervalCol->val()->clone())); funcParms.push_back(sptp); - funcParms.push_back(getIntervalType(gwi.thd, intervalCol->intervalType())); + funcParms.push_back(getIntervalType(&gwi, intervalCol->intervalType())); SRCP srcp(intervalCol->val()); bound.fVal = srcp; if (addOp) { sptp.reset(new ParseTree(new ConstantColumn("ADD"))); - (dynamic_cast(sptp->data())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwi.timeZone); funcParms.push_back(sptp); } else { sptp.reset(new ParseTree(new ConstantColumn("SUB"))); - (dynamic_cast(sptp->data())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(sptp->data()))->timeZone(gwi.timeZone); funcParms.push_back(sptp); } @@ -187,7 +185,7 @@ ReturnedColumn* buildBoundExp(WF_Boundary& bound, SRCP& order, gp_walk_info& gwi else aop = new ArithmeticOperator("-"); - aop->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + aop->timeZone(gwi.timeZone); ParseTree* pt = new ParseTree(aop); ParseTree *lhs = 0, *rhs = 0; lhs = new ParseTree(order->clone()); @@ -314,7 +312,7 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n Item_sum* item_sum = wf->window_func(); string funcName = ConvertFuncName(item_sum); WindowFunctionColumn* ac = new WindowFunctionColumn(funcName); - ac->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + ac->timeZone(gwi.timeZone); ac->distinct(item_sum->has_with_distinct()); Window_spec* win_spec = wf->window_spec; SRCP srcp; @@ -407,45 +405,45 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n sprintf(sRespectNulls, "%lu", bRespectNulls); srcp.reset(new ConstantColumn(sRespectNulls, (uint64_t)bRespectNulls, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); break; } case Item_sum::FIRST_VALUE_FUNC: srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // OFFSET (always one) - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // FROM_FIRST - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); srcp.reset( new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); break; case Item_sum::LAST_VALUE_FUNC: srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // OFFSET (always one) - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); srcp.reset(new ConstantColumn("0", (uint64_t)0, ConstantColumn::NUM)); // FROM_LAST - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); srcp.reset( new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); break; case Item_sum::NTH_VALUE_FUNC: // When the front end supports these paramters, this needs modification srcp.reset(new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // FROM FIRST/LAST 1 => FIRST - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); srcp.reset( new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); break; @@ -453,11 +451,11 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n case Item_sum::LAG_FUNC: // When the front end supports these paramters, this needs modification srcp.reset(new ConstantColumn("", ConstantColumn::NULLDATA)); // Default to fill in for NULL values - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); srcp.reset( new ConstantColumn("1", (uint64_t)1, ConstantColumn::NUM)); // IGNORE/RESPECT NULLS. 1 => RESPECT - (dynamic_cast(srcp.get()))->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); funcParms.push_back(srcp); break; @@ -802,8 +800,7 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n bound = 1; srcp.reset(new ConstantColumn((int64_t)bound)); - (dynamic_cast(srcp.get())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); frm.fStart.fVal = srcp; frm.fStart.fBound.reset(buildBoundExp(frm.fStart, srcp, gwi)); @@ -819,8 +816,7 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n bound = 1; srcp.reset(new ConstantColumn((int64_t)bound)); - (dynamic_cast(srcp.get())) - ->timeZone(gwi.thd->variables.time_zone->get_name()->ptr()); + (dynamic_cast(srcp.get()))->timeZone(gwi.timeZone); frm.fEnd.fVal = srcp; frm.fEnd.fBound.reset(buildBoundExp(frm.fEnd, srcp, gwi)); diff --git a/ddlproc/ddlprocessor.cpp b/ddlproc/ddlprocessor.cpp index de9f0fc1e..eb6f3d09b 100644 --- a/ddlproc/ddlprocessor.cpp +++ b/ddlproc/ddlprocessor.cpp @@ -541,7 +541,7 @@ class PackageHandler qts.schema_name = alterTableStmt.schemaName(); fQtc.postQueryTele(qts); - processor->fTimeZone = alterTableStmt.fTimeZone; + processor->fTimeZone = alterTableStmt.getTimeZone(); result = processor->processPackage(alterTableStmt); diff --git a/mysql-test/columnstore/basic/r/type_timestamp.result b/mysql-test/columnstore/basic/r/type_timestamp.result new file mode 100644 index 000000000..e56cb083f --- /dev/null +++ b/mysql-test/columnstore/basic/r/type_timestamp.result @@ -0,0 +1,141 @@ +# +# Test cases for the TIMESTAMP datatype +# +DROP DATABASE IF EXISTS timestamp_test; +CREATE DATABASE timestamp_test; +USE timestamp_test; +CREATE TABLE ctimestamp (a timestamp); +SET time_zone='-5:00'; +INSERT INTO ctimestamp VALUES ('2019-01-01 01:02:03'), ('2019-05-05 01:01:01'); +SET time_zone='+1:00'; +SELECT a FROM ctimestamp ORDER BY a; +a +2019-01-01 07:02:03 +2019-05-05 07:01:01 +SET time_zone='-2:00'; +SELECT a FROM ctimestamp ORDER BY a; +a +2019-01-01 04:02:03 +2019-05-05 04:01:01 +CREATE TABLE ctimestamp2 (a timestamp DEFAULT 0); +INSERT INTO ctimestamp2 SELECT * FROM ctimestamp; +SELECT a FROM ctimestamp2 ORDER BY a; +a +2019-01-01 04:02:03 +2019-05-05 04:01:01 +CREATE TABLE ctimestamp3 (a timestamp); +INSERT INTO ctimestamp3 VALUES (19940101), (940101), +(19940101010203), (940101010203), ('1994-01-01T01:02:03'); +SELECT a FROM ctimestamp3 ORDER BY a; +a +1994-01-01 00:00:00 +1994-01-01 00:00:00 +1994-01-01 01:02:03 +1994-01-01 01:02:03 +1994-01-01 01:02:03 +CREATE TABLE ctimestamp4 (a timestamp(6) default 0); +INSERT INTO ctimestamp4 VALUES (0), ('2019-01-01 01:01:01.123456'); +SELECT a, microsecond(a) FROM ctimestamp4 ORDER BY a; +a microsecond(a) +0000-00-00 00:00:00.000000 0 +2019-01-01 01:01:01.123456 123456 +DROP DATABASE IF EXISTS timestamp_test; +CREATE DATABASE timestamp_test; +USE timestamp_test; +CREATE TABLE ctimestamp (a timestamp); +SET time_zone='+0:00'; +INSERT INTO ctimestamp VALUES ('2019-01-02 00:02:03'), +('2019-01-02 01:02:03'), ('2019-01-02 10:11:12'); +SET time_zone='+1:00'; +SELECT a, a BETWEEN '2019-01-02 02:00:00' AND '2019-01-02 13:00:00' +FROM ctimestamp ORDER BY a; +a a BETWEEN '2019-01-02 02:00:00' AND '2019-01-02 13:00:00' +2019-01-02 01:02:03 0 +2019-01-02 02:02:03 1 +2019-01-02 11:11:12 1 +SELECT a, IF(a < '2019-01-02 02:00:00', 'yes', 'no'), +ADDTIME(a, '1:1:1'), STR_TO_DATE(a, '%Y-%m-%d %H:%i:%s'), +EXTRACT(DAY_HOUR FROM a), EXTRACT(MINUTE_SECOND FROM a), +TIME_FORMAT(a, '%H:\%i:\%s'), a RLIKE '02:03', IFNULL(NULL, a), +CASE a WHEN '2019-01-02 01:02:03' THEN 'found' WHEN '2019-01-02 11:11:12' +THEN 'found2' ELSE 'notfound' END, CHAR_LENGTH(a), +CAST(a AS UNSIGNED INT), CAST(a AS CHAR), CAST(a AS DATE), +TIME(CAST(a AS DATETIME)), TIME(COALESCE(NULL, a)), HEX(a), +NULLIF(a, '2019-01-02 01:02:03'), TIMEDIFF(a, '2019-01-01 01:02:03') +FROM ctimestamp ORDER BY a; +a IF(a < '2019-01-02 02:00:00', 'yes', 'no') ADDTIME(a, '1:1:1') STR_TO_DATE(a, '%Y-%m-%d %H:%i:%s') EXTRACT(DAY_HOUR FROM a) EXTRACT(MINUTE_SECOND FROM a) TIME_FORMAT(a, '%H:\%i:\%s') a RLIKE '02:03' IFNULL(NULL, a) CASE a WHEN '2019-01-02 01:02:03' THEN 'found' WHEN '2019-01-02 11:11:12' +THEN 'found2' ELSE 'notfound' END CHAR_LENGTH(a) CAST(a AS UNSIGNED INT) CAST(a AS CHAR) CAST(a AS DATE) TIME(CAST(a AS DATETIME)) TIME(COALESCE(NULL, a)) HEX(a) NULLIF(a, '2019-01-02 01:02:03') TIMEDIFF(a, '2019-01-01 01:02:03') +2019-01-02 01:02:03 yes 2019-01-02 02:03:04 2019-01-02 01:02:03 201 203 01:\02:\03 1 2019-01-02 01:02:03 found 19 20190102010203 2019-01-02 01:02:03 2019-01-02 01:02:03 01:02:03 323031392D30312D30322030313A30323A3033 NULL 24:00:00 +2019-01-02 02:02:03 no 2019-01-02 03:03:04 2019-01-02 02:02:03 202 203 02:\02:\03 1 2019-01-02 02:02:03 notfound 19 20190102020203 2019-01-02 02:02:03 2019-01-02 02:02:03 02:02:03 323031392D30312D30322030323A30323A3033 2019-01-02 02:02:03 25:00:00 +2019-01-02 11:11:12 no 2019-01-02 12:12:13 2019-01-02 11:11:12 211 1112 11:\11:\12 0 2019-01-02 11:11:12 found2 19 20190102111112 2019-01-02 11:11:12 2019-01-02 11:11:12 11:11:12 323031392D30312D30322031313A31313A3132 2019-01-02 11:11:12 34:09:09 +INSERT INTO ctimestamp VALUES ('2020-01-03 12:12:12'), +('2020-05-06 12:12:12'), ('2020-10-28 12:12:12'); +SELECT a, DAYNAME(a), DAYOFWEEK(a), DATE_FORMAT(a, '%W %M %Y'), +MONTHNAME(a), DATE(a), YEARWEEK(a), DAYOFYEAR(a), YEAR(a), +a + INTERVAL 1 DAY, TIMESTAMPDIFF(DAY, a, '2020-01-01'), +LAST_DAY(a), TRUNCATE(a, -2), a IN ('2019-01-02 01:02:03', a), +TO_DAYS(a), DAY(a), WEEK(a), WEEKDAY(a), GREATEST(a, '2020-07-01'), +MONTH(a), QUARTER(a), DATE_ADD(a, INTERVAL 1 SECOND) +FROM ctimestamp WHERE a > '2020-01-01' ORDER BY a; +a DAYNAME(a) DAYOFWEEK(a) DATE_FORMAT(a, '%W %M %Y') MONTHNAME(a) DATE(a) YEARWEEK(a) DAYOFYEAR(a) YEAR(a) a + INTERVAL 1 DAY TIMESTAMPDIFF(DAY, a, '2020-01-01') LAST_DAY(a) TRUNCATE(a, -2) a IN ('2019-01-02 01:02:03', a) TO_DAYS(a) DAY(a) WEEK(a) WEEKDAY(a) GREATEST(a, '2020-07-01') MONTH(a) QUARTER(a) DATE_ADD(a, INTERVAL 1 SECOND) +2020-01-03 12:12:12 Friday 6 Friday January 2020 January 2020-01-03 201952 3 2020 2020-01-04 12:12:12 -2 2020-01-31 2020-01-03 12:12:12 1 737792 3 0 4 2020-07-01 00:00:00 1 1 2020-01-03 12:12:13 +2020-05-06 12:12:12 Wednesday 4 Wednesday May 2020 May 2020-05-06 202018 127 2020 2020-05-07 12:12:12 -126 2020-05-31 2020-05-06 12:12:12 1 737916 6 18 2 2020-07-01 00:00:00 5 2 2020-05-06 12:12:13 +2020-10-28 12:12:12 Wednesday 4 Wednesday October 2020 October 2020-10-28 202043 302 2020 2020-10-29 12:12:12 -301 2020-10-31 2020-10-28 12:12:12 1 738091 28 43 2 2020-10-28 12:12:12 10 4 2020-10-28 12:12:13 +SELECT UNIX_TIMESTAMP(a), TIME_TO_SEC(a), CEIL(a), +CAST(LEAST(a, '2019-03-03 00:00:00') AS DATETIME), +ROUND(a), SECOND(a), MINUTE(a), HOUR(a), FLOOR(a) +FROM ctimestamp ORDER BY a; +UNIX_TIMESTAMP(a) TIME_TO_SEC(a) CEIL(a) CAST(LEAST(a, '2019-03-03 00:00:00') AS DATETIME) ROUND(a) SECOND(a) MINUTE(a) HOUR(a) FLOOR(a) +1546387323 3723 2019-01-02 01:02:03 2019-01-02 01:02:03 2019-01-02 01:02:03 3 2 1 2019-01-02 01:02:03 +1546390923 7323 2019-01-02 02:02:03 2019-01-02 02:02:03 2019-01-02 02:02:03 3 2 2 2019-01-02 02:02:03 +1546423872 40272 2019-01-02 11:11:12 2019-01-02 11:11:12 2019-01-02 11:11:12 12 11 11 2019-01-02 11:11:12 +1578049932 43932 2020-01-03 12:12:12 2019-03-03 00:00:00 2020-01-03 12:12:12 12 12 12 2020-01-03 12:12:12 +1588763532 43932 2020-05-06 12:12:12 2019-03-03 00:00:00 2020-05-06 12:12:12 12 12 12 2020-05-06 12:12:12 +1603883532 43932 2020-10-28 12:12:12 2019-03-03 00:00:00 2020-10-28 12:12:12 12 12 12 2020-10-28 12:12:12 +DROP DATABASE IF EXISTS timestamp_test; +CREATE DATABASE timestamp_test; +USE timestamp_test; +CREATE TABLE ctimestamp (a timestamp, b int); +SET time_zone='+0:00'; +INSERT INTO ctimestamp VALUES ('2019-01-03 12:12:12', 1), +('2019-01-04 12:12:12', 2), ('2019-01-03 12:12:12', 4), +('2019-01-03 12:12:12', 2), ('2019-01-04 12:12:12', 1); +SELECT a, b, SUM(b) over (PARTITION BY a ORDER BY a, b +ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) c +FROM ctimestamp; +a b c +2019-01-03 12:12:12 1 1 +2019-01-03 12:12:12 2 3 +2019-01-03 12:12:12 4 7 +2019-01-04 12:12:12 1 1 +2019-01-04 12:12:12 2 3 +SELECT a, b, MAX(a) over (PARTITION BY b ORDER BY a desc +ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) c +FROM ctimestamp; +a b c +2019-01-04 12:12:12 1 2019-01-04 12:12:12 +2019-01-03 12:12:12 1 2019-01-04 12:12:12 +2019-01-04 12:12:12 2 2019-01-04 12:12:12 +2019-01-03 12:12:12 2 2019-01-04 12:12:12 +2019-01-03 12:12:12 4 2019-01-03 12:12:12 +DROP DATABASE IF EXISTS timestamp_test; +CREATE DATABASE timestamp_test; +USE timestamp_test; +CREATE TABLE ctimestamp (a int, b timestamp); +INSERT INTO ctimestamp VALUES (1, 20190101), (1, 20200202), +(2, 20190202), (2, 20200202), (2, 20190101); +SELECT b, count(*) FROM ctimestamp GROUP BY b ORDER BY b; +b count(*) +2019-01-01 00:00:00 2 +2019-02-02 00:00:00 1 +2020-02-02 00:00:00 2 +SELECT b, max(a), min(a) FROM ctimestamp GROUP BY b ORDER BY b; +b max(a) min(a) +2019-01-01 00:00:00 2 1 +2019-02-02 00:00:00 2 2 +2020-02-02 00:00:00 2 1 +SELECT a, max(b), min(b) FROM ctimestamp GROUP BY a ORDER BY a; +a max(b) min(b) +1 2020-02-02 00:00:00 2019-01-01 00:00:00 +2 2020-02-02 00:00:00 2019-01-01 00:00:00 +DROP DATABASE timestamp_test; diff --git a/mysql-test/columnstore/basic/t/type_timestamp.test b/mysql-test/columnstore/basic/t/type_timestamp.test new file mode 100644 index 000000000..2789f6e7c --- /dev/null +++ b/mysql-test/columnstore/basic/t/type_timestamp.test @@ -0,0 +1,131 @@ +--source ../include/have_columnstore.inc +--source ../include/combinations.myisam-columnstore.inc + +--echo # +--echo # Test cases for the TIMESTAMP datatype +--echo # + +# Test bulk insert/literals/microseconds +--disable_warnings +DROP DATABASE IF EXISTS timestamp_test; +--enable_warnings + +CREATE DATABASE timestamp_test; +USE timestamp_test; + +## Test the effect of changing timezones on timestamp values +CREATE TABLE ctimestamp (a timestamp); +SET time_zone='-5:00'; +INSERT INTO ctimestamp VALUES ('2019-01-01 01:02:03'), ('2019-05-05 01:01:01'); +SET time_zone='+1:00'; +SELECT a FROM ctimestamp ORDER BY a; +SET time_zone='-2:00'; +SELECT a FROM ctimestamp ORDER BY a; + +## Test bulk insert using cpimport +CREATE TABLE ctimestamp2 (a timestamp DEFAULT 0); +INSERT INTO ctimestamp2 SELECT * FROM ctimestamp; +SELECT a FROM ctimestamp2 ORDER BY a; + +## Test literals +CREATE TABLE ctimestamp3 (a timestamp); +INSERT INTO ctimestamp3 VALUES (19940101), (940101), +(19940101010203), (940101010203), ('1994-01-01T01:02:03'); +SELECT a FROM ctimestamp3 ORDER BY a; + +## Test microseconds +CREATE TABLE ctimestamp4 (a timestamp(6) default 0); +INSERT INTO ctimestamp4 VALUES (0), ('2019-01-01 01:01:01.123456'); +SELECT a, microsecond(a) FROM ctimestamp4 ORDER BY a; + +# Test distributed functions +--disable_warnings +DROP DATABASE IF EXISTS timestamp_test; +--enable_warnings + +CREATE DATABASE timestamp_test; +USE timestamp_test; + +CREATE TABLE ctimestamp (a timestamp); +SET time_zone='+0:00'; +INSERT INTO ctimestamp VALUES ('2019-01-02 00:02:03'), +('2019-01-02 01:02:03'), ('2019-01-02 10:11:12'); +SET time_zone='+1:00'; + +SELECT a, a BETWEEN '2019-01-02 02:00:00' AND '2019-01-02 13:00:00' +FROM ctimestamp ORDER BY a; + +SELECT a, IF(a < '2019-01-02 02:00:00', 'yes', 'no'), +ADDTIME(a, '1:1:1'), STR_TO_DATE(a, '%Y-%m-%d %H:%i:%s'), +EXTRACT(DAY_HOUR FROM a), EXTRACT(MINUTE_SECOND FROM a), +TIME_FORMAT(a, '%H:\%i:\%s'), a RLIKE '02:03', IFNULL(NULL, a), +CASE a WHEN '2019-01-02 01:02:03' THEN 'found' WHEN '2019-01-02 11:11:12' +THEN 'found2' ELSE 'notfound' END, CHAR_LENGTH(a), +CAST(a AS UNSIGNED INT), CAST(a AS CHAR), CAST(a AS DATE), +TIME(CAST(a AS DATETIME)), TIME(COALESCE(NULL, a)), HEX(a), +NULLIF(a, '2019-01-02 01:02:03'), TIMEDIFF(a, '2019-01-01 01:02:03') +FROM ctimestamp ORDER BY a; + +INSERT INTO ctimestamp VALUES ('2020-01-03 12:12:12'), +('2020-05-06 12:12:12'), ('2020-10-28 12:12:12'); + +SELECT a, DAYNAME(a), DAYOFWEEK(a), DATE_FORMAT(a, '%W %M %Y'), +MONTHNAME(a), DATE(a), YEARWEEK(a), DAYOFYEAR(a), YEAR(a), +a + INTERVAL 1 DAY, TIMESTAMPDIFF(DAY, a, '2020-01-01'), +LAST_DAY(a), TRUNCATE(a, -2), a IN ('2019-01-02 01:02:03', a), +TO_DAYS(a), DAY(a), WEEK(a), WEEKDAY(a), GREATEST(a, '2020-07-01'), +MONTH(a), QUARTER(a), DATE_ADD(a, INTERVAL 1 SECOND) +FROM ctimestamp WHERE a > '2020-01-01' ORDER BY a; + +SELECT UNIX_TIMESTAMP(a), TIME_TO_SEC(a), CEIL(a), +CAST(LEAST(a, '2019-03-03 00:00:00') AS DATETIME), +ROUND(a), SECOND(a), MINUTE(a), HOUR(a), FLOOR(a) +FROM ctimestamp ORDER BY a; + +# Test window functions +--disable_warnings +DROP DATABASE IF EXISTS timestamp_test; +--enable_warnings + +CREATE DATABASE timestamp_test; +USE timestamp_test; + +CREATE TABLE ctimestamp (a timestamp, b int); +SET time_zone='+0:00'; +INSERT INTO ctimestamp VALUES ('2019-01-03 12:12:12', 1), +('2019-01-04 12:12:12', 2), ('2019-01-03 12:12:12', 4), +('2019-01-03 12:12:12', 2), ('2019-01-04 12:12:12', 1); + +## Test SUM + +SELECT a, b, SUM(b) over (PARTITION BY a ORDER BY a, b +ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) c +FROM ctimestamp; + +## Test MAX + +SELECT a, b, MAX(a) over (PARTITION BY b ORDER BY a desc +ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) c +FROM ctimestamp; + +# Test aggregate functions +--disable_warnings +DROP DATABASE IF EXISTS timestamp_test; +--enable_warnings + +CREATE DATABASE timestamp_test; +USE timestamp_test; + +CREATE TABLE ctimestamp (a int, b timestamp); +INSERT INTO ctimestamp VALUES (1, 20190101), (1, 20200202), +(2, 20190202), (2, 20200202), (2, 20190101); + +# Test count(*) +SELECT b, count(*) FROM ctimestamp GROUP BY b ORDER BY b; + +# Test max/min +SELECT b, max(a), min(a) FROM ctimestamp GROUP BY b ORDER BY b; +SELECT a, max(b), min(b) FROM ctimestamp GROUP BY a ORDER BY a; + +# Cleanup +DROP DATABASE timestamp_test; diff --git a/utils/dataconvert/dataconvert.cpp b/utils/dataconvert/dataconvert.cpp index 5d5e9d346..141954333 100644 --- a/utils/dataconvert/dataconvert.cpp +++ b/utils/dataconvert/dataconvert.cpp @@ -1193,7 +1193,7 @@ bool stringToTimeStruct(const string& data, Time& dtime, long decimals) return true; } -bool stringToTimestampStruct(const string& data, TimeStamp& timeStamp, const string& timeZone) +bool stringToTimestampStruct(const string& data, TimeStamp& timeStamp, long timeZone) { // special handling for 0000-00-00 00:00:00 // "0" is sent by the server when checking for default value @@ -1879,10 +1879,11 @@ int64_t DataConvert::convertColumnDatetime(const char* dataOrg, CalpontDateTimeF // Most of this code is taken from DataConvert::convertColumnDatetime //------------------------------------------------------------------------------ int64_t DataConvert::convertColumnTimestamp(const char* dataOrg, CalpontDateTimeFormat datetimeFormat, - int& status, unsigned int dataOrgLen, const std::string& timeZone) + int& status, unsigned int dataOrgLen, long timeZone) { char tmbuf[64]; std::string dataOrgTemp = dataOrg; + status = 0; if (dataOrgTemp.substr(0, 19) == "0000-00-00 00:00:00") { return 0; @@ -1902,7 +1903,6 @@ int64_t DataConvert::convertColumnTimestamp(const char* dataOrg, CalpontDateTime dataOrgLen = strlen(tmbuf); } - status = 0; const char* p; p = dataOrg; char fld[10]; @@ -2258,8 +2258,7 @@ std::string DataConvert::datetimeToString(long long datetimevalue, long decimals return buf; } -std::string DataConvert::timestampToString(long long timestampvalue, const std::string& timezone, - long decimals) +std::string DataConvert::timestampToString(long long timestampvalue, long timezone, long decimals) { // 10 is default which means we don't need microseconds if (decimals > 6 || decimals < 0) @@ -2343,7 +2342,7 @@ std::string DataConvert::datetimeToString1(long long datetimevalue) return buf; } -std::string DataConvert::timestampToString1(long long timestampvalue, const std::string& timezone) +std::string DataConvert::timestampToString1(long long timestampvalue, long timezone) { const int TIMESTAMPTOSTRING1_LEN = 22; // YYYYMMDDHHMMSSmmmmmm\0 char buf[TIMESTAMPTOSTRING1_LEN]; @@ -2381,7 +2380,7 @@ int64_t DataConvert::datetimeToInt(const string& datetime) return stringToDatetime(datetime); } -int64_t DataConvert::timestampToInt(const string& timestamp, const string& timeZone) +int64_t DataConvert::timestampToInt(const string& timestamp, long timeZone) { return stringToTimestamp(timestamp, timeZone); } @@ -2414,7 +2413,7 @@ int64_t DataConvert::stringToDatetime(const string& data, bool* date) return -1; } -int64_t DataConvert::stringToTimestamp(const string& data, const string& timeZone) +int64_t DataConvert::stringToTimestamp(const string& data, long timeZone) { TimeStamp aTimestamp; diff --git a/utils/dataconvert/dataconvert.h b/utils/dataconvert/dataconvert.h index 1df077670..5653f59a7 100644 --- a/utils/dataconvert/dataconvert.h +++ b/utils/dataconvert/dataconvert.h @@ -289,6 +289,14 @@ inline void unserializeTimezoneInfo(messageqcpp::ByteStream& bs, TIME_ZONE_INFO* bs >> (uint&)tz->revcnt; }; +inline long systemTimeZoneOffset() +{ + time_t t = time(NULL); + struct tm lt; + localtime_r(&t, <); + return lt.tm_gmtoff; +} + /** * This function converts the timezone represented as a string * in the format "+HH:MM" or "-HH:MM" to a signed offset in seconds @@ -296,20 +304,32 @@ inline void unserializeTimezoneInfo(messageqcpp::ByteStream& bs, TIME_ZONE_INFO* */ inline bool timeZoneToOffset(const char* str, std::string::size_type length, long* offset) { + if (strcmp(str, "SYSTEM") == 0) + { + *offset = systemTimeZoneOffset(); + return 0; + } + const char* end = str + length; bool negative; unsigned long number_tmp; long offset_tmp; if (length < 4) + { + *offset = 0; return 1; + } if (*str == '+') negative = 0; else if (*str == '-') negative = 1; else + { + *offset = 0; return 1; + } str++; number_tmp = 0; @@ -321,7 +341,10 @@ inline bool timeZoneToOffset(const char* str, std::string::size_type length, lon } if (str + 1 >= end || *str != ':') + { + *offset = 0; return 1; + } str++; offset_tmp = number_tmp * 60L; @@ -334,7 +357,10 @@ inline bool timeZoneToOffset(const char* str, std::string::size_type length, lon } if (str != end) + { + *offset = 0; return 1; + } offset_tmp = (offset_tmp + number_tmp) * 60L; @@ -347,10 +373,12 @@ inline bool timeZoneToOffset(const char* str, std::string::size_type length, lon */ if (number_tmp > 59 || offset_tmp < -13 * 3600L + 1 || offset_tmp > 13 * 3600L) + { + *offset = 0; return 1; + } *offset = offset_tmp; - return 0; } @@ -483,10 +511,10 @@ inline bool isTimestampValid(uint64_t second, uint64_t microsecond) * * @param seconds the value to be converted * @param time the broken-down representation of the timestamp - * @param timeZone a string with the server timezone of the machine - * which initiated the query + @param offset a timeZone offset (in seconds) relative to UTC. + For example, for EST which is UTC-5:00, offset will be -18000s. */ -inline void gmtSecToMySQLTime(int64_t seconds, MySQLTime& time, const std::string& timeZone) +inline void gmtSecToMySQLTime(int64_t seconds, MySQLTime& time, long offset) { if (seconds == 0) { @@ -494,78 +522,52 @@ inline void gmtSecToMySQLTime(int64_t seconds, MySQLTime& time, const std::strin return; } - if (timeZone == "SYSTEM") + int64_t days; + int32_t rem; + int32_t y; + int32_t yleap; + const unsigned int* ip; + + days = (int64_t)(seconds / SECS_PER_DAY); + rem = (int32_t)(seconds % SECS_PER_DAY); + + rem += offset; + while (rem < 0) { - struct tm tmp_tm; - time_t tmp_t = (time_t)seconds; - localtime_r(&tmp_t, &tmp_tm); - time.second_part = 0; - time.year = (int)((tmp_tm.tm_year + 1900) % 10000); - time.month = (int)tmp_tm.tm_mon + 1; - time.day = (int)tmp_tm.tm_mday; - time.hour = (int)tmp_tm.tm_hour; - time.minute = (int)tmp_tm.tm_min; - time.second = (int)tmp_tm.tm_sec; - time.time_type = CALPONTDATETIME_ENUM; - if (time.second == 60 || time.second == 61) - time.second = 59; + rem += SECS_PER_DAY; + days--; } - else + while (rem >= SECS_PER_DAY) { - long offset; - if (timeZoneToOffset(timeZone.c_str(), timeZone.size(), &offset)) - { - time.reset(); - return; - } - - int64_t days; - int32_t rem; - int32_t y; - int32_t yleap; - const unsigned int* ip; - - days = (int64_t)(seconds / SECS_PER_DAY); - rem = (int32_t)(seconds % SECS_PER_DAY); - - rem += offset; - while (rem < 0) - { - rem += SECS_PER_DAY; - days--; - } - while (rem >= SECS_PER_DAY) - { - rem -= SECS_PER_DAY; - days++; - } - time.hour = (unsigned int)(rem / SECS_PER_HOUR); - rem = rem % SECS_PER_HOUR; - time.minute = (unsigned int)(rem / SECS_PER_MIN); - time.second = (unsigned int)(rem % SECS_PER_MIN); - - y = EPOCH_YEAR; - while (days < 0 || days >= (int64_t)(year_lengths[yleap = isLeapYear(y)])) - { - int32_t newy; - - newy = y + days / DAYS_PER_NYEAR; - if (days < 0) - newy--; - days -= (newy - y) * DAYS_PER_NYEAR + leapsThruEndOf(newy - 1) - leapsThruEndOf(y - 1); - y = newy; - } - time.year = y; - - ip = mon_lengths[yleap]; - for (time.month = 0; days >= (int64_t)ip[time.month]; time.month++) - days -= (int64_t)ip[time.month]; - time.month++; - time.day = (unsigned int)(days + 1); - - time.second_part = 0; - time.time_type = CALPONTDATETIME_ENUM; + rem -= SECS_PER_DAY; + days++; } + time.hour = (unsigned int)(rem / SECS_PER_HOUR); + rem = rem % SECS_PER_HOUR; + time.minute = (unsigned int)(rem / SECS_PER_MIN); + time.second = (unsigned int)(rem % SECS_PER_MIN); + + y = EPOCH_YEAR; + while (days < 0 || days >= (int64_t)(year_lengths[yleap = isLeapYear(y)])) + { + int32_t newy; + + newy = y + days / DAYS_PER_NYEAR; + if (days < 0) + newy--; + days -= (newy - y) * DAYS_PER_NYEAR + leapsThruEndOf(newy - 1) - leapsThruEndOf(y - 1); + y = newy; + } + time.year = y; + + ip = mon_lengths[yleap]; + for (time.month = 0; days >= (int64_t)ip[time.month]; time.month++) + days -= (int64_t)ip[time.month]; + time.month++; + time.day = (unsigned int)(days + 1); + + time.second_part = 0; + time.time_type = CALPONTDATETIME_ENUM; } /** @@ -593,41 +595,15 @@ inline int64_t secSinceEpoch(int year, int month, int day, int hour, int min, in return ((days * HOURS_PER_DAY + hour) * MINS_PER_HOUR + min) * SECS_PER_MIN + sec; } -// This is duplicate of funchelpers.h:calc_mysql_daynr, -// with one additional function parameter -inline uint32_t calc_mysql_daynr(uint32_t year, uint32_t month, uint32_t day, bool& isValid) -{ - int temp; - int y = year; - long delsum; - - if (!isDateValid(day, month, year)) - { - isValid = false; - return 0; - } - - delsum = (long)(365 * y + 31 * ((int)month - 1) + (int)day); - - if (month <= 2) - y--; - else - delsum -= (long)((int)month * 4 + 23) / 10; - - temp = (int)((y / 100 + 1) * 3) / 4; - - return delsum + (int)y / 4 - temp; -} - /** * @brief converts a timestamp from broken-down representation * to seconds since UTC epoch * * @param time the broken-down representation of the timestamp - @param timeZone a string with the server timezone of the machine - which initiated the query + @param offset a timeZone offset (in seconds) relative to UTC. + For example, for EST which is UTC-5:00, offset will be -18000s. */ -inline int64_t mySQLTimeToGmtSec(const MySQLTime& time, const std::string& timeZone, bool& isValid) +inline int64_t mySQLTimeToGmtSec(const MySQLTime& time, long offset, bool& isValid) { int64_t seconds; @@ -637,88 +613,7 @@ inline int64_t mySQLTimeToGmtSec(const MySQLTime& time, const std::string& timeZ return 0; } - if (timeZone == "SYSTEM") - { - // This is mirror of code in func_unix_timestamp.cpp - uint32_t loop; - time_t tmp_t = 0; - int shift = 0; - struct tm *l_time, tm_tmp; - int64_t diff; - localtime_r(&tmp_t, &tm_tmp); - // Get the system timezone offset at 0 seconds since epoch - int64_t my_time_zone = tm_tmp.tm_gmtoff; - int day = time.day; - - if ((time.year == MAX_TIMESTAMP_YEAR) && (time.month == 1) && (day > 4)) - { - day -= 2; - shift = 2; - } - - tmp_t = (time_t)(((calc_mysql_daynr(time.year, time.month, day, isValid) - 719528) * 86400L + - (int64_t)time.hour * 3600L + (int64_t)(time.minute * 60 + time.second)) - - (time_t)my_time_zone); - if (!isValid) - return 0; - - localtime_r(&tmp_t, &tm_tmp); - l_time = &tm_tmp; - - for (loop = 0; - loop < 2 && (time.hour != (uint32_t)l_time->tm_hour || time.minute != (uint32_t)l_time->tm_min || - time.second != (uint32_t)l_time->tm_sec); - loop++) - { - int days = day - l_time->tm_mday; - - if (days < -1) - days = 1; /* Month has wrapped */ - else if (days > 1) - days = -1; - - diff = (3600L * (int64_t)(days * 24 + ((int)time.hour - (int)l_time->tm_hour)) + - (int64_t)(60 * ((int)time.minute - (int)l_time->tm_min)) + - (int64_t)((int)time.second - (int)l_time->tm_sec)); - tmp_t += (time_t)diff; - localtime_r(&tmp_t, &tm_tmp); - l_time = &tm_tmp; - } - - if (loop == 2 && time.hour != (uint32_t)l_time->tm_hour) - { - int days = day - l_time->tm_mday; - - if (days < -1) - days = 1; /* Month has wrapped */ - else if (days > 1) - days = -1; - - diff = (3600L * (int64_t)(days * 24 + ((int)time.hour - (int)l_time->tm_hour)) + - (int64_t)(60 * ((int)time.minute - (int)l_time->tm_min)) + - (int64_t)((int)time.second - (int)l_time->tm_sec)); - - if (diff == 3600) - tmp_t += 3600 - time.minute * 60 - time.second; /* Move to next hour */ - else if (diff == -3600) - tmp_t -= time.minute * 60 + time.second; /* Move to previous hour */ - } - - /* shift back, if we were dealing with boundary dates */ - tmp_t += shift * 86400L; - - seconds = (int64_t)tmp_t; - } - else - { - long offset; - if (timeZoneToOffset(timeZone.c_str(), timeZone.size(), &offset)) - { - isValid = false; - return -1; - } - seconds = secSinceEpoch(time.year, time.month, time.day, time.hour, time.minute, time.second) - offset; - } + seconds = secSinceEpoch(time.year, time.month, time.day, time.hour, time.minute, time.second) - offset; /* make sure we have legit timestamps (i.e. we didn't over/underflow anywhere above) */ if (seconds >= MIN_TIMESTAMP_VALUE && seconds <= MAX_TIMESTAMP_VALUE) return seconds; @@ -1151,11 +1046,11 @@ struct TimeStamp { } - int64_t convertToMySQLint(const std::string& timeZone) const; + int64_t convertToMySQLint(long timeZone) const; void reset(); }; -inline int64_t TimeStamp::convertToMySQLint(const std::string& timeZone) const +inline int64_t TimeStamp::convertToMySQLint(long timeZone) const { const int TIMESTAMPTOSTRING1_LEN = 22; // YYYYMMDDHHMMSSmmmmmm\0 char buf[TIMESTAMPTOSTRING1_LEN]; @@ -1262,10 +1157,9 @@ class DataConvert * @param type the columns database type * @param data the columns string representation of it's data */ - EXPORT static std::string timestampToString(long long timestampvalue, const std::string& timezone, - long decimals = 0); + EXPORT static std::string timestampToString(long long timestampvalue, long timezone, long decimals = 0); static inline void timestampToString(long long timestampvalue, char* buf, unsigned int buflen, - const std::string& timezone, long decimals = 0); + long timezone, long decimals = 0); /** * @brief convert a columns data from native format to a string @@ -1300,9 +1194,9 @@ class DataConvert * @param type the columns database type * @param data the columns string representation of it's data */ - EXPORT static std::string timestampToString1(long long timestampvalue, const std::string& timezone); + EXPORT static std::string timestampToString1(long long timestampvalue, long timezone); static inline void timestampToString1(long long timestampvalue, char* buf, unsigned int buflen, - const std::string& timezone); + long timezone); /** * @brief convert a columns data from native format to a string @@ -1352,11 +1246,11 @@ class DataConvert * @param datetimeFormat the format the date value in * @param status 0 - success, -1 - fail * @param dataOrgLen length specification of dataOrg - * @param timeZone the timezone used for conversion to native format + * @param timeZone an offset (in seconds) relative to UTC. + For example, for EST which is UTC-5:00, offset will be -18000s. */ EXPORT static int64_t convertColumnTimestamp(const char* dataOrg, CalpontDateTimeFormat datetimeFormat, - int& status, unsigned int dataOrgLen, - const std::string& timeZone); + int& status, unsigned int dataOrgLen, long timeZone); /** * @brief convert a time column data, represented as a string, @@ -1385,7 +1279,7 @@ class DataConvert // convert string to datetime EXPORT static int64_t stringToDatetime(const std::string& data, bool* isDate = NULL); // convert string to timestamp - EXPORT static int64_t stringToTimestamp(const std::string& data, const std::string& timeZone); + EXPORT static int64_t stringToTimestamp(const std::string& data, long timeZone); // convert integer to date EXPORT static int64_t intToDate(int64_t data); // convert integer to datetime @@ -1396,7 +1290,7 @@ class DataConvert EXPORT static int64_t dateToInt(const std::string& date); // convert string to datetime. alias to datetimeToInt EXPORT static int64_t datetimeToInt(const std::string& datetime); - EXPORT static int64_t timestampToInt(const std::string& timestamp, const std::string& timeZone); + EXPORT static int64_t timestampToInt(const std::string& timestamp, long timeZone); EXPORT static int64_t timeToInt(const std::string& time); EXPORT static int64_t stringToTime(const std::string& data); // bug4388, union type conversion @@ -1467,7 +1361,7 @@ inline void DataConvert::datetimeToString(long long datetimevalue, char* buf, un } inline void DataConvert::timestampToString(long long timestampvalue, char* buf, unsigned int buflen, - const std::string& timezone, long decimals) + long timezone, long decimals) { // 10 is default which means we don't need microseconds if (decimals > 6 || decimals < 0) @@ -1545,7 +1439,7 @@ inline void DataConvert::datetimeToString1(long long datetimevalue, char* buf, u } inline void DataConvert::timestampToString1(long long timestampvalue, char* buf, unsigned int buflen, - const std::string& timezone) + long timezone) { TimeStamp timestamp(timestampvalue); int64_t seconds = timestamp.second; diff --git a/utils/funcexp/func_add_time.cpp b/utils/funcexp/func_add_time.cpp index 09b1d2d0c..5a2506b3f 100644 --- a/utils/funcexp/func_add_time.cpp +++ b/utils/funcexp/func_add_time.cpp @@ -171,7 +171,7 @@ int64_t Func_add_time::getTimestampIntVal(rowgroup::Row& row, FunctionParm& parm TimeStamp timestamp(val1); int64_t seconds = timestamp.second; MySQLTime m_time; - gmtSecToMySQLTime(seconds, m_time, timeZone()); + gmtSecToMySQLTime(seconds, m_time, ct.getTimeZone()); dt1.year = m_time.year; dt1.month = m_time.month; dt1.day = m_time.day; diff --git a/utils/funcexp/func_between.cpp b/utils/funcexp/func_between.cpp index 3bd2b907b..3ce66eb60 100644 --- a/utils/funcexp/func_between.cpp +++ b/utils/funcexp/func_between.cpp @@ -328,7 +328,7 @@ CalpontSystemCatalog::ColType Func_between::operationType(FunctionParm& fp, if (cc) { Result result = cc->result(); - result.intVal = dataconvert::DataConvert::timestampToInt(result.strVal, timeZone()); + result.intVal = dataconvert::DataConvert::timestampToInt(result.strVal, resultType.getTimeZone()); cc->result(result); } } diff --git a/utils/funcexp/func_bitwise.cpp b/utils/funcexp/func_bitwise.cpp index 76d09b9bd..c10030b98 100644 --- a/utils/funcexp/func_bitwise.cpp +++ b/utils/funcexp/func_bitwise.cpp @@ -105,7 +105,8 @@ static datatypes::TUInt64Null DecimalToBitOperand(Row& row, const execplan::SPTP // and could be extracted into a utility class with its own header // if that is the case - this is left as future exercise datatypes::TUInt64Null GenericToBitOperand(Row& row, const execplan::SPTP& parm, - const funcexp::Func& thisFunc, bool temporalRounding) + const funcexp::Func& thisFunc, bool temporalRounding, + long timeZone) { switch (parm->data()->resultType().colDataType) { @@ -186,7 +187,7 @@ datatypes::TUInt64Null GenericToBitOperand(Row& row, const execplan::SPTP& parm, return datatypes::TUInt64Null(); TimeStamp dt(time); - int64_t value = dt.convertToMySQLint(thisFunc.timeZone()); + int64_t value = dt.convertToMySQLint(timeZone); if (temporalRounding && dt.msecond >= 500000) value++; return datatypes::TUInt64Null((uint64_t)value); @@ -222,8 +223,8 @@ class BitOperandGeneric : public datatypes::TUInt64Null BitOperandGeneric() { } - BitOperandGeneric(Row& row, const execplan::SPTP& parm, const funcexp::Func& thisFunc) - : TUInt64Null(GenericToBitOperand(row, parm, thisFunc, true)) + BitOperandGeneric(Row& row, const execplan::SPTP& parm, const funcexp::Func& thisFunc, long timeZone) + : TUInt64Null(GenericToBitOperand(row, parm, thisFunc, true, timeZone)) { } }; @@ -236,8 +237,9 @@ class BitOperandGenericShiftAmount : public datatypes::TUInt64Null BitOperandGenericShiftAmount() { } - BitOperandGenericShiftAmount(Row& row, const execplan::SPTP& parm, const funcexp::Func& thisFunc) - : TUInt64Null(GenericToBitOperand(row, parm, thisFunc, false)) + BitOperandGenericShiftAmount(Row& row, const execplan::SPTP& parm, const funcexp::Func& thisFunc, + long timeZone) + : TUInt64Null(GenericToBitOperand(row, parm, thisFunc, false, timeZone)) { } }; @@ -327,7 +329,7 @@ class Func_bitand_return_uint64 : public Func_bitand CalpontSystemCatalog::ColType& operationColType) override { idbassert(parm.size() == 2); - Arg2Lazy args(row, parm, *this); + Arg2Lazy args(row, parm, *this, operationColType.getTimeZone()); return (int64_t)(args.a & args.b).nullSafeValue(isNull); } }; @@ -353,7 +355,7 @@ class Func_leftshift_return_uint64 : public Func_leftshift CalpontSystemCatalog::ColType& operationColType) override { idbassert(parm.size() == 2); - Arg2Eager args(row, parm, *this); + Arg2Eager args(row, parm, *this, operationColType.getTimeZone()); return (int64_t)args.a.MariaDBShiftLeft(args.b).nullSafeValue(isNull); } }; @@ -378,7 +380,7 @@ class Func_rightshift_return_uint64 : public Func_rightshift CalpontSystemCatalog::ColType& operationColType) override { idbassert(parm.size() == 2); - Arg2Eager args(row, parm, *this); + Arg2Eager args(row, parm, *this, operationColType.getTimeZone()); return (int64_t)args.a.MariaDBShiftRight(args.b).nullSafeValue(isNull); } }; @@ -409,7 +411,7 @@ class Func_bitor_return_uint64 : public Func_bitor CalpontSystemCatalog::ColType& operationColType) override { idbassert(parm.size() == 2); - Arg2Lazy args(row, parm, *this); + Arg2Lazy args(row, parm, *this, operationColType.getTimeZone()); return (int64_t)(args.a | args.b).nullSafeValue(isNull); } }; @@ -435,7 +437,7 @@ class Func_bitxor_return_uint64 : public Func_bitxor CalpontSystemCatalog::ColType& operationColType) override { idbassert(parm.size() == 2); - Arg2Eager args(row, parm, *this); + Arg2Eager args(row, parm, *this, operationColType.getTimeZone()); return (int64_t)(args.a ^ args.b).nullSafeValue(isNull); } }; @@ -475,7 +477,7 @@ class Func_bit_count_return_uint64 : public Func_bit_count CalpontSystemCatalog::ColType& operationColType) override { idbassert(parm.size() == 1); - return bitCount((uint64_t)TA(row, parm[0], *this).nullSafeValue(isNull)); + return bitCount((uint64_t)TA(row, parm[0], *this, operationColType.getTimeZone()).nullSafeValue(isNull)); } }; diff --git a/utils/funcexp/func_cast.cpp b/utils/funcexp/func_cast.cpp index b3917b2a5..4b224c6d9 100644 --- a/utils/funcexp/func_cast.cpp +++ b/utils/funcexp/func_cast.cpp @@ -186,7 +186,7 @@ int64_t Func_cast_signed::getIntVal(Row& row, FunctionParm& parm, bool& isNull, int64_t time = parm[0]->data()->getTimestampIntVal(row, isNull); TimeStamp dt(time); - return dt.convertToMySQLint(timeZone()); + return dt.convertToMySQLint(operationColType.getTimeZone()); } break; @@ -304,7 +304,7 @@ uint64_t Func_cast_unsigned::getUintVal(Row& row, FunctionParm& parm, bool& isNu int64_t time = parm[0]->data()->getTimestampIntVal(row, isNull); TimeStamp dt(time); - return dt.convertToMySQLint(timeZone()); + return dt.convertToMySQLint(operationColType.getTimeZone()); } break; @@ -433,7 +433,7 @@ string Func_cast_char::getStrVal(Row& row, FunctionParm& parm, bool& isNull, case execplan::CalpontSystemCatalog::TIMESTAMP: { return dataconvert::DataConvert::timestampToString(parm[0]->data()->getTimestampIntVal(row, isNull), - timeZone()) + operationColType.getTimeZone()) .substr(0, length); } break; @@ -568,7 +568,7 @@ int32_t Func_cast_date::getDateIntVal(rowgroup::Row& row, FunctionParm& parm, bo case execplan::CalpontSystemCatalog::TIMESTAMP: { int64_t val1 = parm[0]->data()->getTimestampIntVal(row, isNull); - string value = dataconvert::DataConvert::timestampToString(val1, timeZone()); + string value = dataconvert::DataConvert::timestampToString(val1, op_ct.getTimeZone()); value = value.substr(0, 10); return dataconvert::DataConvert::stringToDate(value); } @@ -691,7 +691,7 @@ int64_t Func_cast_date::getDatetimeIntVal(rowgroup::Row& row, FunctionParm& parm TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; MySQLTime m_time; - gmtSecToMySQLTime(seconds, m_time, timeZone()); + gmtSecToMySQLTime(seconds, m_time, operationColType.getTimeZone()); DateTime dt; dt.year = m_time.year; dt.month = m_time.month; @@ -847,7 +847,7 @@ int64_t Func_cast_datetime::getDatetimeIntVal(rowgroup::Row& row, FunctionParm& TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; MySQLTime m_time; - gmtSecToMySQLTime(seconds, m_time, timeZone()); + gmtSecToMySQLTime(seconds, m_time, operationColType.getTimeZone()); DateTime dt; dt.year = m_time.year; dt.month = m_time.month; @@ -958,7 +958,7 @@ int64_t Func_cast_datetime::getTimeIntVal(rowgroup::Row& row, FunctionParm& parm TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; MySQLTime m_time; - gmtSecToMySQLTime(seconds, m_time, timeZone()); + gmtSecToMySQLTime(seconds, m_time, operationColType.getTimeZone()); Time time; time.hour = m_time.hour; time.minute = m_time.minute; @@ -1362,7 +1362,7 @@ IDB_Decimal Func_cast_decimal::getDecimalVal(Row& row, FunctionParm& parm, bool& int32_t s = 0; string value = dataconvert::DataConvert::timestampToString1( - parm[0]->data()->getTimestampIntVal(row, isNull), timeZone()); + parm[0]->data()->getTimestampIntVal(row, isNull), operationColType.getTimeZone()); // strip off micro seconds string date = value.substr(0, 14); @@ -1475,8 +1475,8 @@ double Func_cast_double::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull case execplan::CalpontSystemCatalog::TIMESTAMP: { - string str = - DataConvert::timestampToString1(parm[0]->data()->getTimestampIntVal(row, isNull), timeZone()); + string str = DataConvert::timestampToString1(parm[0]->data()->getTimestampIntVal(row, isNull), + operationColType.getTimeZone()); // strip off micro seconds str = str.substr(0, 14); diff --git a/utils/funcexp/func_ceil.cpp b/utils/funcexp/func_ceil.cpp index f0c016847..dc559a5db 100644 --- a/utils/funcexp/func_ceil.cpp +++ b/utils/funcexp/func_ceil.cpp @@ -571,7 +571,7 @@ IDB_Decimal Func_ceil::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull, TimeStamp dt(parm[0]->data()->getTimestampIntVal(row, isNull)); if (!isNull) - ret.value = dt.convertToMySQLint(timeZone()); + ret.value = dt.convertToMySQLint(op_ct.getTimeZone()); } break; diff --git a/utils/funcexp/func_char_length.cpp b/utils/funcexp/func_char_length.cpp index 749914188..553d54399 100644 --- a/utils/funcexp/func_char_length.cpp +++ b/utils/funcexp/func_char_length.cpp @@ -99,7 +99,7 @@ int64_t Func_char_length::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool case execplan::CalpontSystemCatalog::TIMESTAMP: { string date = dataconvert::DataConvert::timestampToString( - parm[0]->data()->getTimestampIntVal(row, isNull), timeZone()); + parm[0]->data()->getTimestampIntVal(row, isNull), op_ct.getTimeZone()); return (int64_t)date.size(); } diff --git a/utils/funcexp/func_convert_tz.cpp b/utils/funcexp/func_convert_tz.cpp index 424b7494c..03efdad88 100644 --- a/utils/funcexp/func_convert_tz.cpp +++ b/utils/funcexp/func_convert_tz.cpp @@ -154,7 +154,9 @@ int64_t Func_convert_tz::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& } else { - seconds = dataconvert::mySQLTimeToGmtSec(my_start_time, from_tz, valid); + long from_tz_offset; + dataconvert::timeZoneToOffset(from_tz.c_str(), from_tz.size(), &from_tz_offset); + seconds = dataconvert::mySQLTimeToGmtSec(my_start_time, from_tz_offset, valid); if (!valid) { if (seconds != 0) @@ -196,7 +198,9 @@ int64_t Func_convert_tz::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& } else { - dataconvert::gmtSecToMySQLTime(seconds, my_time_tmp, to_tz); + long to_tz_offset; + dataconvert::timeZoneToOffset(to_tz.c_str(), to_tz.size(), &to_tz_offset); + dataconvert::gmtSecToMySQLTime(seconds, my_time_tmp, to_tz_offset); } dataconvert::DateTime result_datetime(my_time_tmp.year, my_time_tmp.month, my_time_tmp.day, diff --git a/utils/funcexp/func_date.cpp b/utils/funcexp/func_date.cpp index 8ebbd2250..5544e8b31 100644 --- a/utils/funcexp/func_date.cpp +++ b/utils/funcexp/func_date.cpp @@ -47,7 +47,7 @@ CalpontSystemCatalog::ColType Func_date::operationType(FunctionParm& fp, } int64_t Func_date::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, - CalpontSystemCatalog::ColType&) + CalpontSystemCatalog::ColType& ct) { CalpontSystemCatalog::ColDataType type = parm[0]->data()->resultType().colDataType; @@ -75,7 +75,7 @@ int64_t Func_date::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNul case execplan::CalpontSystemCatalog::TIMESTAMP: { int64_t val1 = parm[0]->data()->getTimestampIntVal(row, isNull); - value = dataconvert::DataConvert::timestampToString(val1, timeZone()); + value = dataconvert::DataConvert::timestampToString(val1, ct.getTimeZone()); value = value.substr(0, 10); break; } diff --git a/utils/funcexp/func_date_add.cpp b/utils/funcexp/func_date_add.cpp index c98d54581..2e715acc7 100644 --- a/utils/funcexp/func_date_add.cpp +++ b/utils/funcexp/func_date_add.cpp @@ -759,7 +759,7 @@ int64_t Func_date_add::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& i TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; MySQLTime m_time; - gmtSecToMySQLTime(seconds, m_time, timeZone()); + gmtSecToMySQLTime(seconds, m_time, ct.getTimeZone()); DateTime dt; dt.year = m_time.year; dt.month = m_time.month; diff --git a/utils/funcexp/func_date_format.cpp b/utils/funcexp/func_date_format.cpp index 0aff75d9e..962fc811d 100644 --- a/utils/funcexp/func_date_format.cpp +++ b/utils/funcexp/func_date_format.cpp @@ -242,7 +242,7 @@ CalpontSystemCatalog::ColType Func_date_format::operationType(FunctionParm& fp, } string Func_date_format::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, - CalpontSystemCatalog::ColType&) + CalpontSystemCatalog::ColType& ct) { int64_t val = 0; DateTime dt = 0; @@ -273,7 +273,7 @@ string Func_date_format::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& TimeStamp timestamp(val); int64_t seconds = timestamp.second; MySQLTime time; - gmtSecToMySQLTime(seconds, time, timeZone()); + gmtSecToMySQLTime(seconds, time, ct.getTimeZone()); dt.year = time.year; dt.month = time.month; dt.day = time.day; @@ -412,7 +412,7 @@ int64_t Func_date_format::getDatetimeIntVal(rowgroup::Row& row, FunctionParm& pa int64_t Func_date_format::getTimestampIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& ct) { - return dataconvert::DataConvert::timestampToInt(getStrVal(row, parm, isNull, ct), timeZone()); + return dataconvert::DataConvert::timestampToInt(getStrVal(row, parm, isNull, ct), ct.getTimeZone()); } } // namespace funcexp diff --git a/utils/funcexp/func_day.cpp b/utils/funcexp/func_day.cpp index 29baf4466..bd4a484d8 100644 --- a/utils/funcexp/func_day.cpp +++ b/utils/funcexp/func_day.cpp @@ -64,7 +64,7 @@ int64_t Func_day::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); return m_time.day; } diff --git a/utils/funcexp/func_dayname.cpp b/utils/funcexp/func_dayname.cpp index 9a94882c6..07078a25f 100644 --- a/utils/funcexp/func_dayname.cpp +++ b/utils/funcexp/func_dayname.cpp @@ -76,7 +76,7 @@ int64_t Func_dayname::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& is dataconvert::TimeStamp timestamp(val); int64_t seconds = timestamp.second; dataconvert::MySQLTime time; - dataconvert::gmtSecToMySQLTime(seconds, time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, time, op_ct.getTimeZone()); year = time.year; month = time.month; day = time.day; diff --git a/utils/funcexp/func_dayofweek.cpp b/utils/funcexp/func_dayofweek.cpp index 64f04bcf3..441bfeebc 100644 --- a/utils/funcexp/func_dayofweek.cpp +++ b/utils/funcexp/func_dayofweek.cpp @@ -75,7 +75,7 @@ int64_t Func_dayofweek::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& dataconvert::TimeStamp timestamp(val); int64_t seconds = timestamp.second; dataconvert::MySQLTime time; - dataconvert::gmtSecToMySQLTime(seconds, time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, time, ct.getTimeZone()); year = time.year; month = time.month; day = time.day; diff --git a/utils/funcexp/func_dayofyear.cpp b/utils/funcexp/func_dayofyear.cpp index 487635c7c..fb9d97428 100644 --- a/utils/funcexp/func_dayofyear.cpp +++ b/utils/funcexp/func_dayofyear.cpp @@ -74,7 +74,7 @@ int64_t Func_dayofyear::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& dataconvert::TimeStamp timestamp(parm[0]->data()->getIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, ct.getTimeZone()); year = m_time.year; month = m_time.month; day = m_time.day; diff --git a/utils/funcexp/func_extract.cpp b/utils/funcexp/func_extract.cpp index 066151aa3..a6f8d6353 100644 --- a/utils/funcexp/func_extract.cpp +++ b/utils/funcexp/func_extract.cpp @@ -202,7 +202,7 @@ int64_t Func_extract::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& is dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, ct.getTimeZone()); dataconvert::DateTime dt; dt.year = m_time.year; dt.month = m_time.month; diff --git a/utils/funcexp/func_floor.cpp b/utils/funcexp/func_floor.cpp index c212d19c0..7c0dacc82 100644 --- a/utils/funcexp/func_floor.cpp +++ b/utils/funcexp/func_floor.cpp @@ -225,7 +225,7 @@ uint64_t Func_floor::getUintVal(Row& row, FunctionParm& parm, bool& isNull, case execplan::CalpontSystemCatalog::TIMESTAMP: { string str = - DataConvert::timestampToString1(parm[0]->data()->getTimestampIntVal(row, isNull), timeZone()); + DataConvert::timestampToString1(parm[0]->data()->getTimestampIntVal(row, isNull), op_ct.getTimeZone()); // strip off micro seconds str = str.substr(0, 14); @@ -519,7 +519,7 @@ IDB_Decimal Func_floor::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull case execplan::CalpontSystemCatalog::TIMESTAMP: { string str = - DataConvert::timestampToString1(parm[0]->data()->getTimestampIntVal(row, isNull), timeZone()); + DataConvert::timestampToString1(parm[0]->data()->getTimestampIntVal(row, isNull), op_ct.getTimeZone()); // strip off micro seconds str = str.substr(0, 14); diff --git a/utils/funcexp/func_hour.cpp b/utils/funcexp/func_hour.cpp index b9ef7f823..7d2da7411 100644 --- a/utils/funcexp/func_hour.cpp +++ b/utils/funcexp/func_hour.cpp @@ -117,7 +117,7 @@ int64_t Func_hour::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNul dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); return m_time.hour; } diff --git a/utils/funcexp/func_if.cpp b/utils/funcexp/func_if.cpp index 3e208dc7d..98fe8a334 100644 --- a/utils/funcexp/func_if.cpp +++ b/utils/funcexp/func_if.cpp @@ -35,7 +35,7 @@ using namespace rowgroup; namespace { -bool boolVal(SPTP& parm, Row& row, const string& timeZone) +bool boolVal(SPTP& parm, Row& row, long timeZone) { bool ret = true; bool isNull = false; // Keep it local. We don't want to mess with the global one here. @@ -122,9 +122,9 @@ CalpontSystemCatalog::ColType Func_if::operationType(FunctionParm& fp, return ct; } -int64_t Func_if::getIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&) +int64_t Func_if::getIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& ct) { - if (boolVal(parm[0], row, timeZone())) + if (boolVal(parm[0], row, ct.getTimeZone())) { return parm[1]->data()->getIntVal(row, isNull); } @@ -134,9 +134,9 @@ int64_t Func_if::getIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSy } } -string Func_if::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&) +string Func_if::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& ct) { - if (boolVal(parm[0], row, timeZone())) + if (boolVal(parm[0], row, ct.getTimeZone())) { return parm[1]->data()->getStrVal(row, isNull); } @@ -146,9 +146,10 @@ string Func_if::getStrVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSys } } -IDB_Decimal Func_if::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&) +IDB_Decimal Func_if::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull, + CalpontSystemCatalog::ColType& ct) { - if (boolVal(parm[0], row, timeZone())) + if (boolVal(parm[0], row, ct.getTimeZone())) { return parm[1]->data()->getDecimalVal(row, isNull); } @@ -158,9 +159,9 @@ IDB_Decimal Func_if::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull, C } } -double Func_if::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&) +double Func_if::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& ct) { - if (boolVal(parm[0], row, timeZone())) + if (boolVal(parm[0], row, ct.getTimeZone())) { return parm[1]->data()->getDoubleVal(row, isNull); } @@ -171,9 +172,9 @@ double Func_if::getDoubleVal(Row& row, FunctionParm& parm, bool& isNull, Calpont } long double Func_if::getLongDoubleVal(Row& row, FunctionParm& parm, bool& isNull, - CalpontSystemCatalog::ColType&) + CalpontSystemCatalog::ColType& ct) { - if (boolVal(parm[0], row, timeZone())) + if (boolVal(parm[0], row, ct.getTimeZone())) { return parm[1]->data()->getLongDoubleVal(row, isNull); } @@ -183,9 +184,9 @@ long double Func_if::getLongDoubleVal(Row& row, FunctionParm& parm, bool& isNull } } -int32_t Func_if::getDateIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&) +int32_t Func_if::getDateIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& ct) { - if (boolVal(parm[0], row, timeZone())) + if (boolVal(parm[0], row, ct.getTimeZone())) { return parm[1]->data()->getDateIntVal(row, isNull); } @@ -195,9 +196,10 @@ int32_t Func_if::getDateIntVal(Row& row, FunctionParm& parm, bool& isNull, Calpo } } -int64_t Func_if::getDatetimeIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&) +int64_t Func_if::getDatetimeIntVal(Row& row, FunctionParm& parm, bool& isNull, + CalpontSystemCatalog::ColType& ct) { - if (boolVal(parm[0], row, timeZone())) + if (boolVal(parm[0], row, ct.getTimeZone())) { return parm[1]->data()->getDatetimeIntVal(row, isNull); } @@ -208,9 +210,9 @@ int64_t Func_if::getDatetimeIntVal(Row& row, FunctionParm& parm, bool& isNull, C } int64_t Func_if::getTimestampIntVal(Row& row, FunctionParm& parm, bool& isNull, - CalpontSystemCatalog::ColType&) + CalpontSystemCatalog::ColType& ct) { - if (boolVal(parm[0], row, timeZone())) + if (boolVal(parm[0], row, ct.getTimeZone())) { return parm[1]->data()->getTimestampIntVal(row, isNull); } @@ -220,9 +222,9 @@ int64_t Func_if::getTimestampIntVal(Row& row, FunctionParm& parm, bool& isNull, } } -int64_t Func_if::getTimeIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType&) +int64_t Func_if::getTimeIntVal(Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& ct) { - if (boolVal(parm[0], row, timeZone())) + if (boolVal(parm[0], row, ct.getTimeZone())) { return parm[1]->data()->getTimeIntVal(row, isNull); } diff --git a/utils/funcexp/func_last_day.cpp b/utils/funcexp/func_last_day.cpp index 9040c47d2..89f173a77 100644 --- a/utils/funcexp/func_last_day.cpp +++ b/utils/funcexp/func_last_day.cpp @@ -74,7 +74,7 @@ int64_t Func_last_day::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& i TimeStamp timestamp(parm[0]->data()->getIntVal(row, isNull)); int64_t seconds = timestamp.second; MySQLTime m_time; - gmtSecToMySQLTime(seconds, m_time, timeZone()); + gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); year = m_time.year; month = m_time.month; day = m_time.day; diff --git a/utils/funcexp/func_math.cpp b/utils/funcexp/func_math.cpp index 5f822d539..7d60ae507 100644 --- a/utils/funcexp/func_math.cpp +++ b/utils/funcexp/func_math.cpp @@ -1786,7 +1786,7 @@ string Func_format::getStrVal(Row& row, FunctionParm& parm, bool& isNull, case execplan::CalpontSystemCatalog::TIMESTAMP: { value = dataconvert::DataConvert::timestampToString1(parm[0]->data()->getTimestampIntVal(row, isNull), - timeZone()); + operationColType.getTimeZone()); } break; diff --git a/utils/funcexp/func_minute.cpp b/utils/funcexp/func_minute.cpp index 4a5f594a7..af310c876 100644 --- a/utils/funcexp/func_minute.cpp +++ b/utils/funcexp/func_minute.cpp @@ -117,7 +117,7 @@ int64_t Func_minute::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isN dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); return m_time.minute; } diff --git a/utils/funcexp/func_month.cpp b/utils/funcexp/func_month.cpp index 3f9136a04..50ee3600e 100644 --- a/utils/funcexp/func_month.cpp +++ b/utils/funcexp/func_month.cpp @@ -63,7 +63,7 @@ int64_t Func_month::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNu dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); return m_time.month; } diff --git a/utils/funcexp/func_monthname.cpp b/utils/funcexp/func_monthname.cpp index 3f76db8ca..8ea7c3e37 100644 --- a/utils/funcexp/func_monthname.cpp +++ b/utils/funcexp/func_monthname.cpp @@ -97,7 +97,7 @@ int64_t Func_monthname::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& dataconvert::TimeStamp timestamp(val); int64_t seconds = timestamp.second; dataconvert::MySQLTime time; - dataconvert::gmtSecToMySQLTime(seconds, time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, time, op_ct.getTimeZone()); return time.month; } diff --git a/utils/funcexp/func_nullif.cpp b/utils/funcexp/func_nullif.cpp index 77c07c674..ba4ab740f 100644 --- a/utils/funcexp/func_nullif.cpp +++ b/utils/funcexp/func_nullif.cpp @@ -955,7 +955,8 @@ execplan::IDB_Decimal Func_nullif::getDecimalVal(rowgroup::Row& row, FunctionPar string value; if (parm[1]->data()->resultType().colDataType == execplan::CalpontSystemCatalog::TIMESTAMP) - value = DataConvert::timestampToString1(parm[1]->data()->getTimestampIntVal(row, isNull), timeZone()); + value = + DataConvert::timestampToString1(parm[1]->data()->getTimestampIntVal(row, isNull), op_ct.getTimeZone()); else value = DataConvert::datetimeToString1(parm[1]->data()->getDatetimeIntVal(row, isNull)); diff --git a/utils/funcexp/func_quarter.cpp b/utils/funcexp/func_quarter.cpp index c4417497f..04c4babb5 100644 --- a/utils/funcexp/func_quarter.cpp +++ b/utils/funcexp/func_quarter.cpp @@ -67,7 +67,7 @@ int64_t Func_quarter::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& is dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); month = m_time.month; break; } diff --git a/utils/funcexp/func_regexp.cpp b/utils/funcexp/func_regexp.cpp index f918aa7b4..cb495c8c1 100644 --- a/utils/funcexp/func_regexp.cpp +++ b/utils/funcexp/func_regexp.cpp @@ -48,7 +48,7 @@ using namespace logging; namespace { inline bool getBool(rowgroup::Row& row, funcexp::FunctionParm& pm, bool& isNull, - CalpontSystemCatalog::ColType& ct, const string& timeZone) + CalpontSystemCatalog::ColType& ct, long timeZone) { string expr; string pattern; @@ -244,7 +244,7 @@ CalpontSystemCatalog::ColType Func_regexp::operationType(FunctionParm& fp, bool Func_regexp::getBoolVal(rowgroup::Row& row, FunctionParm& pm, bool& isNull, CalpontSystemCatalog::ColType& ct) { - return getBool(row, pm, isNull, ct, timeZone()) && !isNull; + return getBool(row, pm, isNull, ct, ct.getTimeZone()) && !isNull; } } // namespace funcexp diff --git a/utils/funcexp/func_round.cpp b/utils/funcexp/func_round.cpp index 293159570..16855324e 100644 --- a/utils/funcexp/func_round.cpp +++ b/utils/funcexp/func_round.cpp @@ -569,7 +569,7 @@ IDB_Decimal Func_round::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull string value; if (op_ct.colDataType == execplan::CalpontSystemCatalog::TIMESTAMP) value = dataconvert::DataConvert::timestampToString1(parm[0]->data()->getTimestampIntVal(row, isNull), - timeZone()); + op_ct.getTimeZone()); else value = dataconvert::DataConvert::datetimeToString1(parm[0]->data()->getDatetimeIntVal(row, isNull)); @@ -709,5 +709,11 @@ int64_t Func_round::getDatetimeIntVal(Row& row, FunctionParm& parm, bool& isNull return parm[0]->data()->getIntVal(row, isNull); } +int64_t Func_round::getTimestampIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct) +{ + return parm[0]->data()->getTimestampIntVal(row, isNull); +} + } // namespace funcexp // vim:ts=4 sw=4: diff --git a/utils/funcexp/func_second.cpp b/utils/funcexp/func_second.cpp index e07d29176..7731ea66c 100644 --- a/utils/funcexp/func_second.cpp +++ b/utils/funcexp/func_second.cpp @@ -116,7 +116,7 @@ int64_t Func_second::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isN dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); return m_time.second; } diff --git a/utils/funcexp/func_str_to_date.cpp b/utils/funcexp/func_str_to_date.cpp index ff1f53356..0580021ff 100644 --- a/utils/funcexp/func_str_to_date.cpp +++ b/utils/funcexp/func_str_to_date.cpp @@ -42,7 +42,7 @@ namespace using namespace funcexp; dataconvert::DateTime getDateTime(rowgroup::Row& row, FunctionParm& parm, bool& isNull, - CalpontSystemCatalog::ColType& ct, const string& timeZone) + CalpontSystemCatalog::ColType& ct, long timeZone) { TimeExtractor extractor; dataconvert::DateTime dateTime; @@ -186,7 +186,7 @@ string Func_str_to_date::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& CalpontSystemCatalog::ColType& ct) { dataconvert::DateTime dateTime; - dateTime = getDateTime(row, parm, isNull, ct, timeZone()); + dateTime = getDateTime(row, parm, isNull, ct, ct.getTimeZone()); string convertedDate = dataconvert::DataConvert::datetimeToString(*((long long*)&dateTime)); return convertedDate; } @@ -195,7 +195,7 @@ int32_t Func_str_to_date::getDateIntVal(rowgroup::Row& row, FunctionParm& parm, CalpontSystemCatalog::ColType& ct) { dataconvert::DateTime dateTime; - dateTime = getDateTime(row, parm, isNull, ct, timeZone()); + dateTime = getDateTime(row, parm, isNull, ct, ct.getTimeZone()); int64_t time = *(reinterpret_cast(&dateTime)); return ((((int32_t)(time >> 32)) & 0xFFFFFFC0) | 0x3E); } @@ -204,7 +204,7 @@ int64_t Func_str_to_date::getDatetimeIntVal(rowgroup::Row& row, FunctionParm& pa CalpontSystemCatalog::ColType& ct) { dataconvert::DateTime dateTime; - dateTime = getDateTime(row, parm, isNull, ct, timeZone()); + dateTime = getDateTime(row, parm, isNull, ct, ct.getTimeZone()); int64_t time = *(reinterpret_cast(&dateTime)); return time; } @@ -213,7 +213,7 @@ int64_t Func_str_to_date::getTimestampIntVal(rowgroup::Row& row, FunctionParm& p CalpontSystemCatalog::ColType& ct) { dataconvert::DateTime dateTime; - dateTime = getDateTime(row, parm, isNull, ct, timeZone()); + dateTime = getDateTime(row, parm, isNull, ct, ct.getTimeZone()); dataconvert::TimeStamp timestamp; dataconvert::MySQLTime m_time; m_time.year = dateTime.year; @@ -223,7 +223,7 @@ int64_t Func_str_to_date::getTimestampIntVal(rowgroup::Row& row, FunctionParm& p m_time.minute = dateTime.minute; m_time.second = dateTime.second; bool isValid = true; - int64_t seconds = mySQLTimeToGmtSec(m_time, timeZone(), isValid); + int64_t seconds = mySQLTimeToGmtSec(m_time, ct.getTimeZone(), isValid); if (!isValid) { timestamp = -1; @@ -243,7 +243,7 @@ int64_t Func_str_to_date::getTimeIntVal(rowgroup::Row& row, FunctionParm& parm, { dataconvert::DateTime dateTime; dataconvert::Time retTime; - dateTime = getDateTime(row, parm, isNull, ct, timeZone()); + dateTime = getDateTime(row, parm, isNull, ct, ct.getTimeZone()); retTime.day = 0; retTime.is_neg = false; retTime.hour = dateTime.hour; @@ -258,7 +258,7 @@ int64_t Func_str_to_date::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool CalpontSystemCatalog::ColType& ct) { dataconvert::DateTime dateTime; - dateTime = getDateTime(row, parm, isNull, ct, timeZone()); + dateTime = getDateTime(row, parm, isNull, ct, ct.getTimeZone()); int64_t time = *(reinterpret_cast(&dateTime)); return time; } diff --git a/utils/funcexp/func_time.cpp b/utils/funcexp/func_time.cpp index a859c4843..14d2246ae 100644 --- a/utils/funcexp/func_time.cpp +++ b/utils/funcexp/func_time.cpp @@ -45,7 +45,7 @@ CalpontSystemCatalog::ColType Func_time::operationType(FunctionParm& fp, } string Func_time::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, - CalpontSystemCatalog::ColType&) + CalpontSystemCatalog::ColType& ct) { int64_t val = 0; @@ -126,7 +126,7 @@ string Func_time::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, ct.getTimeZone()); dataconvert::Time time; time.hour = m_time.hour; time.minute = m_time.minute; diff --git a/utils/funcexp/func_time_format.cpp b/utils/funcexp/func_time_format.cpp index 5b971b958..d075658b0 100644 --- a/utils/funcexp/func_time_format.cpp +++ b/utils/funcexp/func_time_format.cpp @@ -45,7 +45,7 @@ CalpontSystemCatalog::ColType Func_time_format::operationType(FunctionParm& fp, } string Func_time_format::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, - CalpontSystemCatalog::ColType&) + CalpontSystemCatalog::ColType& ct) { // assume 256 is enough. assume not allowing incomplete date char buf[256]; @@ -72,7 +72,7 @@ string Func_time_format::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& dataconvert::TimeStamp timestamp(parm[0]->data()->getIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, ct.getTimeZone()); hour = m_time.hour; min = m_time.minute; sec = m_time.second; diff --git a/utils/funcexp/func_time_to_sec.cpp b/utils/funcexp/func_time_to_sec.cpp index d6b5de7cf..388ef2ca6 100644 --- a/utils/funcexp/func_time_to_sec.cpp +++ b/utils/funcexp/func_time_to_sec.cpp @@ -70,7 +70,7 @@ int64_t Func_time_to_sec::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool dataconvert::TimeStamp timestamp(val); int64_t seconds = timestamp.second; dataconvert::MySQLTime time; - dataconvert::gmtSecToMySQLTime(seconds, time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, time, op_ct.getTimeZone()); hour = time.hour; min = time.minute; sec = time.second; diff --git a/utils/funcexp/func_timediff.cpp b/utils/funcexp/func_timediff.cpp index 2477943ab..d3f891397 100644 --- a/utils/funcexp/func_timediff.cpp +++ b/utils/funcexp/func_timediff.cpp @@ -142,16 +142,11 @@ string Func_timediff::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& is case execplan::CalpontSystemCatalog::TIMESTAMP: { - if (type1 != type2) - { - isNull = true; - break; - } int64_t temp = parm[0]->data()->getTimestampIntVal(row, isNull); dataconvert::TimeStamp timestamp(temp); int64_t seconds = timestamp.second; dataconvert::MySQLTime time; - dataconvert::gmtSecToMySQLTime(seconds, time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, time, ct.getTimeZone()); dataconvert::DateTime dt; dt.year = time.year; dt.month = time.month; @@ -239,7 +234,7 @@ string Func_timediff::getStrVal(rowgroup::Row& row, FunctionParm& parm, bool& is dataconvert::TimeStamp timestamp(temp); int64_t seconds = timestamp.second; dataconvert::MySQLTime time; - dataconvert::gmtSecToMySQLTime(seconds, time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, time, ct.getTimeZone()); dataconvert::DateTime dt; dt.year = time.year; dt.month = time.month; @@ -328,7 +323,7 @@ int64_t Func_timediff::getDatetimeIntVal(rowgroup::Row& row, FunctionParm& parm, int64_t Func_timediff::getTimestampIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, CalpontSystemCatalog::ColType& ct) { - return dataconvert::DataConvert::timestampToInt(getStrVal(row, parm, isNull, ct), timeZone()); + return dataconvert::DataConvert::timestampToInt(getStrVal(row, parm, isNull, ct), ct.getTimeZone()); } int64_t Func_timediff::getTimeIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, diff --git a/utils/funcexp/func_timestampdiff.cpp b/utils/funcexp/func_timestampdiff.cpp index 83024c069..07e7eda73 100644 --- a/utils/funcexp/func_timestampdiff.cpp +++ b/utils/funcexp/func_timestampdiff.cpp @@ -55,7 +55,7 @@ int64_t Func_timestampdiff::getIntVal(rowgroup::Row& row, FunctionParm& parm, bo TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; MySQLTime m_time; - gmtSecToMySQLTime(seconds, m_time, timeZone()); + gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); dt1.year = m_time.year; dt1.month = m_time.month; dt1.day = m_time.day; @@ -82,7 +82,7 @@ int64_t Func_timestampdiff::getIntVal(rowgroup::Row& row, FunctionParm& parm, bo TimeStamp timestamp(parm[1]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; MySQLTime m_time; - gmtSecToMySQLTime(seconds, m_time, timeZone()); + gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); dt2.year = m_time.year; dt2.month = m_time.month; dt2.day = m_time.day; diff --git a/utils/funcexp/func_to_days.cpp b/utils/funcexp/func_to_days.cpp index 79fc165b4..f597c5fd7 100644 --- a/utils/funcexp/func_to_days.cpp +++ b/utils/funcexp/func_to_days.cpp @@ -85,7 +85,7 @@ int64_t Func_to_days::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& is dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); year = m_time.year; month = m_time.month; day = m_time.day; diff --git a/utils/funcexp/func_truncate.cpp b/utils/funcexp/func_truncate.cpp index f9b7826d0..87f045af0 100644 --- a/utils/funcexp/func_truncate.cpp +++ b/utils/funcexp/func_truncate.cpp @@ -560,7 +560,7 @@ IDB_Decimal Func_truncate::getDecimalVal(Row& row, FunctionParm& parm, bool& isN int64_t x = 0; string value = - DataConvert::timestampToString1(parm[0]->data()->getTimestampIntVal(row, isNull), timeZone()); + DataConvert::timestampToString1(parm[0]->data()->getTimestampIntVal(row, isNull), op_ct.getTimeZone()); s = parm[1]->data()->getIntVal(row, isNull); @@ -714,5 +714,11 @@ string Func_truncate::getStrVal(Row& row, FunctionParm& parm, bool& isNull, return x.toString(true); } +int64_t Func_truncate::getTimestampIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct) +{ + return parm[0]->data()->getTimestampIntVal(row, isNull); +} + } // namespace funcexp // vim:ts=4 sw=4: diff --git a/utils/funcexp/func_week.cpp b/utils/funcexp/func_week.cpp index f0fe91afc..8f7a3af08 100644 --- a/utils/funcexp/func_week.cpp +++ b/utils/funcexp/func_week.cpp @@ -76,7 +76,7 @@ int64_t Func_week::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNul dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); year = m_time.year; month = m_time.month; day = m_time.day; diff --git a/utils/funcexp/func_weekday.cpp b/utils/funcexp/func_weekday.cpp index a6fbbcceb..302293b8e 100644 --- a/utils/funcexp/func_weekday.cpp +++ b/utils/funcexp/func_weekday.cpp @@ -73,7 +73,7 @@ int64_t Func_weekday::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& is dataconvert::TimeStamp timestamp(parm[0]->data()->getTimestampIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); year = m_time.year; month = m_time.month; day = m_time.day; diff --git a/utils/funcexp/func_year.cpp b/utils/funcexp/func_year.cpp index 0b64c2534..2f4fc827b 100644 --- a/utils/funcexp/func_year.cpp +++ b/utils/funcexp/func_year.cpp @@ -63,7 +63,7 @@ int64_t Func_year::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& isNul dataconvert::TimeStamp timestamp(parm[0]->data()->getIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); return m_time.year; } diff --git a/utils/funcexp/func_yearweek.cpp b/utils/funcexp/func_yearweek.cpp index 3e59dd120..3b85692bf 100644 --- a/utils/funcexp/func_yearweek.cpp +++ b/utils/funcexp/func_yearweek.cpp @@ -78,7 +78,7 @@ int64_t Func_yearweek::getIntVal(rowgroup::Row& row, FunctionParm& parm, bool& i dataconvert::TimeStamp timestamp(parm[0]->data()->getIntVal(row, isNull)); int64_t seconds = timestamp.second; dataconvert::MySQLTime m_time; - dataconvert::gmtSecToMySQLTime(seconds, m_time, timeZone()); + dataconvert::gmtSecToMySQLTime(seconds, m_time, op_ct.getTimeZone()); year = m_time.year; month = m_time.month; day = m_time.day; diff --git a/utils/funcexp/functor.cpp b/utils/funcexp/functor.cpp index ce83903cb..4eed16886 100644 --- a/utils/funcexp/functor.cpp +++ b/utils/funcexp/functor.cpp @@ -105,9 +105,9 @@ uint64_t Func::stringToDatetime(const string str) return ret; } -uint64_t Func::stringToTimestamp(const string str) +uint64_t Func::stringToTimestamp(const std::string& str, long timeZone) { - int64_t ret = DataConvert::stringToTimestamp(str, timeZone()); + int64_t ret = DataConvert::stringToTimestamp(str, timeZone); if (ret == -1) { diff --git a/utils/funcexp/functor.h b/utils/funcexp/functor.h index 26b7d04c7..1cc73879f 100644 --- a/utils/funcexp/functor.h +++ b/utils/funcexp/functor.h @@ -73,17 +73,6 @@ class Func fFuncName = funcName; } - const std::string timeZone() const - { - std::unique_lock l(tzMutex); - return fTimeZone; - } - void timeZone(const std::string timeZone) - { - std::unique_lock l(tzMutex); - fTimeZone = timeZone; - } - void raiseIllegalParameterDataTypeError(const execplan::CalpontSystemCatalog::ColType& colType) const { std::ostringstream oss; @@ -177,7 +166,7 @@ class Func protected: virtual uint32_t stringToDate(std::string); virtual uint64_t stringToDatetime(std::string); - virtual uint64_t stringToTimestamp(std::string); + virtual uint64_t stringToTimestamp(const std::string&, long); virtual int64_t stringToTime(std::string); virtual uint32_t intToDate(int64_t); @@ -205,9 +194,6 @@ class Func float fFloatNullVal; double fDoubleNullVal; long double fLongDoubleNullVal; - - std::string fTimeZone; - mutable std::mutex tzMutex; }; class ParmTSInt64 : public datatypes::TSInt64Null @@ -216,7 +202,7 @@ class ParmTSInt64 : public datatypes::TSInt64Null ParmTSInt64() { } - ParmTSInt64(rowgroup::Row& row, const execplan::SPTP& parm, const funcexp::Func& thisFunc) + ParmTSInt64(rowgroup::Row& row, const execplan::SPTP& parm, const funcexp::Func& thisFunc, long timeZone) : TSInt64Null(parm->data()->toTSInt64Null(row)) { } @@ -228,7 +214,7 @@ class ParmTUInt64 : public datatypes::TUInt64Null ParmTUInt64() { } - ParmTUInt64(rowgroup::Row& row, const execplan::SPTP& parm, const funcexp::Func& thisFunc) + ParmTUInt64(rowgroup::Row& row, const execplan::SPTP& parm, const funcexp::Func& thisFunc, long timeZone) : TUInt64Null(parm->data()->toTUInt64Null(row)) { } @@ -240,8 +226,8 @@ class Arg2Lazy public: TA a; TB b; - Arg2Lazy(rowgroup::Row& row, FunctionParm& parm, const Func& thisFunc) - : a(row, parm[0], thisFunc), b(a.isNull() ? TB() : TB(row, parm[1], thisFunc)) + Arg2Lazy(rowgroup::Row& row, FunctionParm& parm, const Func& thisFunc, long timeZone) + : a(row, parm[0], thisFunc, timeZone), b(a.isNull() ? TB() : TB(row, parm[1], thisFunc, timeZone)) { } }; @@ -252,8 +238,8 @@ class Arg2Eager public: TA a; TB b; - Arg2Eager(rowgroup::Row& row, FunctionParm& parm, const Func& thisFunc) - : a(row, parm[0], thisFunc), b(row, parm[1], thisFunc) + Arg2Eager(rowgroup::Row& row, FunctionParm& parm, const Func& thisFunc, long timeZone) + : a(row, parm[0], thisFunc, timeZone), b(row, parm[1], thisFunc, timeZone) { } }; diff --git a/utils/funcexp/functor_real.h b/utils/funcexp/functor_real.h index 59d4a05ab..60ccbe5e0 100644 --- a/utils/funcexp/functor_real.h +++ b/utils/funcexp/functor_real.h @@ -180,6 +180,9 @@ class Func_round : public Func_Real int64_t getDatetimeIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); + + int64_t getTimestampIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct); }; /** @brief Func_truncate class @@ -214,6 +217,9 @@ class Func_truncate : public Func_Real execplan::IDB_Decimal getDecimalVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& op_ct); + + int64_t getTimestampIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct); }; /** @brief Func_ceil class diff --git a/utils/funcexp/functor_str.h b/utils/funcexp/functor_str.h index 4ed4abc95..1287cfd64 100644 --- a/utils/funcexp/functor_str.h +++ b/utils/funcexp/functor_str.h @@ -94,7 +94,7 @@ class Func_Str : public Func execplan::CalpontSystemCatalog::ColType& op_ct) { std::string str = getStrVal(row, fp, isNull, op_ct); - return (isNull ? 0 : stringToTimestamp(str)); + return (isNull ? 0 : stringToTimestamp(str, op_ct.getTimeZone())); } int64_t getTimeIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, diff --git a/utils/rowgroup/rowaggregation.cpp b/utils/rowgroup/rowaggregation.cpp index 7c64358ea..4fd94b6c3 100644 --- a/utils/rowgroup/rowaggregation.cpp +++ b/utils/rowgroup/rowaggregation.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2014 InfiniDB, Inc. - Copyright (c) 2019-2020 MariaDB Corporation + Copyright (c) 2019-2021 MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -1567,7 +1567,8 @@ void RowAggregation::serialize(messageqcpp::ByteStream& bs) const for (uint64_t i = 0; i < functionCount; i++) fFunctionCols[i]->serialize(bs); - bs << fTimeZone; + messageqcpp::ByteStream::octbyte timeZone = fTimeZone; + bs << timeZone; } //------------------------------------------------------------------------------ @@ -1612,7 +1613,9 @@ void RowAggregation::deserialize(messageqcpp::ByteStream& bs) fFunctionCols.push_back(funct); } - bs >> fTimeZone; + messageqcpp::ByteStream::octbyte timeZone; + bs >> timeZone; + fTimeZone = timeZone; } //------------------------------------------------------------------------------ diff --git a/utils/rowgroup/rowaggregation.h b/utils/rowgroup/rowaggregation.h index 360f08128..a5abc4b40 100644 --- a/utils/rowgroup/rowaggregation.h +++ b/utils/rowgroup/rowaggregation.h @@ -338,7 +338,7 @@ struct GroupConcat std::vector> fOrderCond; // position to order by [asc/desc] joblist::ResourceManager* fRm; // resource manager boost::shared_ptr fSessionMemLimit; - std::string fTimeZone; + long fTimeZone; GroupConcat() : fRm(nullptr) { @@ -505,11 +505,11 @@ class RowAggregation : public messageqcpp::Serializeable return fAggMapKeyCount; } - inline void timeZone(const std::string& timeZone) + inline void timeZone(long timeZone) { fTimeZone = timeZone; } - inline const std::string& timeZone() const + inline long timeZone() const { return fTimeZone; } @@ -598,7 +598,7 @@ class RowAggregation : public messageqcpp::Serializeable bool fKeyOnHeap = false; - std::string fTimeZone; + long fTimeZone; // We need a separate copy for each thread. mcsv1sdk::mcsv1Context fRGContext; diff --git a/writeengine/bulk/cpimport.cpp b/writeengine/bulk/cpimport.cpp index bd7a62ea5..4b1fbac8d 100644 --- a/writeengine/bulk/cpimport.cpp +++ b/writeengine/bulk/cpimport.cpp @@ -648,12 +648,12 @@ void parseCmdLineArgs(int argc, char** argv, BulkLoad& curJob, std::string& sJob std::string timeZone = optarg; long offset; - if (timeZone != "SYSTEM" && dataconvert::timeZoneToOffset(timeZone.c_str(), timeZone.size(), &offset)) + if (dataconvert::timeZoneToOffset(timeZone.c_str(), timeZone.size(), &offset)) { startupError(std::string("Value for option -T is invalid"), true); } - curJob.setTimeZone(timeZone); + curJob.setTimeZone(offset); break; } diff --git a/writeengine/bulk/we_bulkload.cpp b/writeengine/bulk/we_bulkload.cpp index 566b99759..ebec84dc2 100644 --- a/writeengine/bulk/we_bulkload.cpp +++ b/writeengine/bulk/we_bulkload.cpp @@ -159,7 +159,7 @@ BulkLoad::BulkLoad() , fbContinue(false) , fDisableTimeOut(false) , fUUID(boost::uuids::nil_generator()()) - , fTimeZone("SYSTEM") + , fTimeZone(dataconvert::systemTimeZoneOffset()) , fUsername("mysql") // MCOL-4328 default file owner { fTableInfo.clear(); diff --git a/writeengine/bulk/we_bulkload.h b/writeengine/bulk/we_bulkload.h index cd800dd9e..ccc362ca4 100644 --- a/writeengine/bulk/we_bulkload.h +++ b/writeengine/bulk/we_bulkload.h @@ -107,7 +107,7 @@ class BulkLoad : public FileOp void addToCmdLineImportFileList(const std::string& importFile); const std::string& getAlternateImportDir() const; const std::string& getErrorDir() const; - const std::string& getTimeZone() const; + long getTimeZone() const; const std::string& getJobDir() const; const std::string& getSchema() const; const std::string& getTempJobDir() const; @@ -145,7 +145,7 @@ class BulkLoad : public FileOp void setTruncationAsError(bool bTruncationAsError); void setJobUUID(const std::string& jobUUID); void setErrorDir(const std::string& errorDir); - void setTimeZone(const std::string& timeZone); + void setTimeZone(long timeZone); void setS3Key(const std::string& key); void setS3Secret(const std::string& secret); void setS3Bucket(const std::string& bucket); @@ -229,7 +229,9 @@ class BulkLoad : public FileOp bool fDisableTimeOut; // disable timeout when waiting for table lock boost::uuids::uuid fUUID; // job UUID static bool fNoConsoleOutput; // disable output to console - std::string fTimeZone; // Timezone to use for TIMESTAMP data type + long fTimeZone; // Timezone offset (in seconds) relative to UTC, + // to use for TIMESTAMP data type. For example, + // for EST which is UTC-5:00, offset will be -18000s. std::string fS3Key; // S3 Key std::string fS3Secret; // S3 Secret std::string fS3Host; // S3 Host @@ -318,7 +320,7 @@ inline const std::string& BulkLoad::getErrorDir() const return fErrorDir; } -inline const std::string& BulkLoad::getTimeZone() const +inline long BulkLoad::getTimeZone() const { return fTimeZone; } @@ -486,7 +488,7 @@ inline void BulkLoad::setErrorDir(const std::string& errorDir) fErrorDir = errorDir; } -inline void BulkLoad::setTimeZone(const std::string& timeZone) +inline void BulkLoad::setTimeZone(long timeZone) { fTimeZone = timeZone; } diff --git a/writeengine/bulk/we_bulkloadbuffer.cpp b/writeengine/bulk/we_bulkloadbuffer.cpp index 9f26a161f..ef1792a09 100644 --- a/writeengine/bulk/we_bulkloadbuffer.cpp +++ b/writeengine/bulk/we_bulkloadbuffer.cpp @@ -139,7 +139,7 @@ BulkLoadBuffer::BulkLoadBuffer(unsigned numberOfCols, unsigned bufferSize, Log* , fTableName(tableName) , fbTruncationAsError(false) , fImportDataMode(IMPORT_DATA_TEXT) - , fTimeZone("SYSTEM") + , fTimeZone(dataconvert::systemTimeZoneOffset()) , fFixedBinaryRecLen(0) { fData = new char[bufferSize]; diff --git a/writeengine/bulk/we_bulkloadbuffer.h b/writeengine/bulk/we_bulkloadbuffer.h index ea0625e39..9aa32cc1e 100644 --- a/writeengine/bulk/we_bulkloadbuffer.h +++ b/writeengine/bulk/we_bulkloadbuffer.h @@ -152,7 +152,9 @@ class BulkLoadBuffer // for db cols (omits default cols) bool fbTruncationAsError; // Treat string truncation as error ImportDataMode fImportDataMode; // Import data in text or binary mode - std::string fTimeZone; // Timezone used by TIMESTAMP datatype + long fTimeZone; // Timezone offset (in seconds) relative to UTC, + // to use for TIMESTAMP data type. For example, + // for EST which is UTC-5:00, offset will be -18000s. unsigned int fFixedBinaryRecLen; // Fixed rec len used in binary mode //-------------------------------------------------------------------------- @@ -388,7 +390,7 @@ class BulkLoadBuffer /** @brief set timezone. */ - void setTimeZone(const std::string& timeZone) + void setTimeZone(long timeZone) { fTimeZone = timeZone; } diff --git a/writeengine/bulk/we_tableinfo.cpp b/writeengine/bulk/we_tableinfo.cpp index 29dc7b202..cdda59c17 100644 --- a/writeengine/bulk/we_tableinfo.cpp +++ b/writeengine/bulk/we_tableinfo.cpp @@ -146,7 +146,7 @@ TableInfo::TableInfo(Log* logger, const BRM::TxnID txnID, const string& processN , fKeepRbMetaFile(bKeepRbMetaFile) , fbTruncationAsError(false) , fImportDataMode(IMPORT_DATA_TEXT) - , fTimeZone("SYSTEM") + , fTimeZone(dataconvert::systemTimeZoneOffset()) , fTableLocked(false) , fReadFromStdin(false) , fReadFromS3(false) diff --git a/writeengine/bulk/we_tableinfo.h b/writeengine/bulk/we_tableinfo.h index 522760fe7..bba15d97d 100644 --- a/writeengine/bulk/we_tableinfo.h +++ b/writeengine/bulk/we_tableinfo.h @@ -127,7 +127,9 @@ class TableInfo : public WeUIDGID // data file bool fbTruncationAsError; // Treat string truncation as error ImportDataMode fImportDataMode; // Import data in text or binary mode - std::string fTimeZone; // Timezone used by TIMESTAMP data type + long fTimeZone; // Timezone offset (in seconds) relative to UTC, + // to use for TIMESTAMP data type. For example, + // for EST which is UTC-5:00, offset will be -18000s. volatile bool fTableLocked; // Do we have db table lock @@ -254,7 +256,7 @@ class TableInfo : public WeUIDGID /** @brief Get timezone. */ - const std::string& getTimeZone() const; + long getTimeZone() const; /** @brief Get number of buffers */ @@ -315,7 +317,7 @@ class TableInfo : public WeUIDGID /** @brief Set timezone. */ - void setTimeZone(const std::string& timeZone); + void setTimeZone(long timeZone); /** @brief Enable distributed mode, saving BRM updates in rptFileName */ @@ -481,7 +483,7 @@ inline ImportDataMode TableInfo::getImportDataMode() const return fImportDataMode; } -inline const std::string& TableInfo::getTimeZone() const +inline long TableInfo::getTimeZone() const { return fTimeZone; } @@ -582,7 +584,7 @@ inline void TableInfo::setImportDataMode(ImportDataMode importMode) fImportDataMode = importMode; } -inline void TableInfo::setTimeZone(const std::string& timeZone) +inline void TableInfo::setTimeZone(long timeZone) { fTimeZone = timeZone; } diff --git a/writeengine/server/we_ddlcommandproc.cpp b/writeengine/server/we_ddlcommandproc.cpp index 69373fff6..1d832f9e0 100644 --- a/writeengine/server/we_ddlcommandproc.cpp +++ b/writeengine/server/we_ddlcommandproc.cpp @@ -3552,7 +3552,7 @@ uint8_t WE_DDLCommandProc::fillNewColumn(ByteStream& bs, std::string& err) int dataWidth, scale, precision, compressionType, refColWidth, refCompressionType; string defaultValStr; ColTuple defaultVal; - string timeZone; + long timeZone; bs >> tmp32; txnID = tmp32; @@ -3581,7 +3581,9 @@ uint8_t WE_DDLCommandProc::fillNewColumn(ByteStream& bs, std::string& err) refColWidth = tmp32; bs >> tmp8; refCompressionType = tmp8; - bs >> timeZone; + messageqcpp::ByteStream::octbyte timeZoneTemp; + bs >> timeZoneTemp; + timeZone = timeZoneTemp; // Find the fill in value bool isNULL = false; diff --git a/writeengine/server/we_dmlcommandproc.cpp b/writeengine/server/we_dmlcommandproc.cpp index d183e3b0f..ec4aff7bc 100644 --- a/writeengine/server/we_dmlcommandproc.cpp +++ b/writeengine/server/we_dmlcommandproc.cpp @@ -2681,7 +2681,7 @@ uint8_t WE_DMLCommandProc::processUpdate(messageqcpp::ByteStream& bs, std::strin CalpontSystemCatalog::OID oid = 0; CalpontSystemCatalog::ROPair tableRO; - std::string timeZone = cpackages[txnId].get_TimeZone(); + long timeZone = cpackages[txnId].get_TimeZone(); try { diff --git a/writeengine/xml/we_xmljob.cpp b/writeengine/xml/we_xmljob.cpp index 0cd44b458..f4f5662d7 100644 --- a/writeengine/xml/we_xmljob.cpp +++ b/writeengine/xml/we_xmljob.cpp @@ -71,7 +71,11 @@ const long long columnstore_precision[19] = {0, //------------------------------------------------------------------------------ // Constructor //------------------------------------------------------------------------------ -XMLJob::XMLJob() : fDebugLevel(DEBUG_0), fDeleteTempFile(false), fValidateColList(true), fTimeZone("SYSTEM") +XMLJob::XMLJob() + : fDebugLevel(DEBUG_0) + , fDeleteTempFile(false) + , fValidateColList(true) + , fTimeZone(dataconvert::systemTimeZoneOffset()) { } diff --git a/writeengine/xml/we_xmljob.h b/writeengine/xml/we_xmljob.h index 61aae0f94..ba33cd4a7 100644 --- a/writeengine/xml/we_xmljob.h +++ b/writeengine/xml/we_xmljob.h @@ -116,7 +116,7 @@ class XMLJob : public XMLOp /** * @brief Set timezone */ - void setTimeZone(const std::string& timeZone) + void setTimeZone(long timeZone) { fTimeZone = timeZone; } @@ -144,7 +144,9 @@ class XMLJob : public XMLOp JobColList fDefaultColumns; // temporary list of default cols // for table node being processed bool fValidateColList; // Validate all cols have XML tag - std::string fTimeZone; // Timezone used for TIMESTAMP datatype + long fTimeZone; // Timezone offset (in seconds) relative to UTC, + // to use for TIMESTAMP data type. For example, + // for EST which is UTC-5:00, offset will be -18000s. }; } // namespace WriteEngine