From 973e5024d8690d7cd17e237b59f8d15bc143668c Mon Sep 17 00:00:00 2001 From: Gagan Goel Date: Wed, 9 Feb 2022 19:03:00 -0500 Subject: [PATCH] MCOL-4957 Fix performance slowdown for processing TIMESTAMP columns. Part 1: As part of MCOL-3776 to address synchronization issue while accessing the fTimeZone member of the Func class, mutex locks were added to the accessor and mutator methods. However, this slows down processing of TIMESTAMP columns in PrimProc significantly as all threads across all concurrently running queries would serialize on the mutex. This is because PrimProc only has a single global object for the functor class (class derived from Func in utils/funcexp/functor.h) for a given function name. To fix this problem: (1) We remove the fTimeZone as a member of the Func derived classes (hence removing the mutexes) and instead use the fOperationType member of the FunctionColumn class to propagate the timezone values down to the individual functor processing functions such as FunctionColumn::getStrVal(), FunctionColumn::getIntVal(), etc. (2) To achieve (1), a timezone member is added to the execplan::CalpontSystemCatalog::ColType class. Part 2: Several functors in the Funcexp code call dataconvert::gmtSecToMySQLTime() and dataconvert::mySQLTimeToGmtSec() functions for conversion between seconds since unix epoch and broken-down representation. These functions in turn call the C library function localtime_r() which currently has a known bug of holding a global lock via a call to __tz_convert. This significantly reduces performance in multi-threaded applications where multiple threads concurrently call localtime_r(). More details on the bug: https://sourceware.org/bugzilla/show_bug.cgi?id=16145 This bug in localtime_r() caused processing of the Functors in PrimProc to slowdown significantly since a query execution causes Functors code to be processed in a multi-threaded manner. As a fix, we remove the calls to localtime_r() from gmtSecToMySQLTime() and mySQLTimeToGmtSec() by performing the timezone-to-offset conversion (done in dataconvert::timeZoneToOffset()) during the execution plan creation in the plugin. Note that localtime_r() is only called when the time_zone system variable is set to "SYSTEM". This fix also required changing the timezone type from a std::string to a long across the system. --- datatypes/mcs_datatype.cpp | 8 +- datatypes/mcs_datatype.h | 35 ++- dbcon/ddlpackage/ddlpkg.h | 13 +- dbcon/ddlpackage/serialize.cpp | 7 +- dbcon/ddlpackageproc/altertableprocessor.cpp | 3 +- dbcon/ddlpackageproc/altertableprocessor.h | 2 +- dbcon/dmlpackage/calpontdmlpackage.h | 6 +- dbcon/dmlpackage/commanddmlpackage.cpp | 7 +- dbcon/dmlpackage/deletedmlpackage.cpp | 7 +- dbcon/dmlpackage/insertdmlpackage.cpp | 11 +- dbcon/dmlpackage/updatedmlpackage.cpp | 7 +- dbcon/execplan/aggregatecolumn.cpp | 7 +- dbcon/execplan/aggregatecolumn.h | 6 +- dbcon/execplan/arithmeticoperator.cpp | 7 +- dbcon/execplan/arithmeticoperator.h | 6 +- dbcon/execplan/calpontselectexecutionplan.cpp | 7 +- dbcon/execplan/calpontselectexecutionplan.h | 6 +- dbcon/execplan/calpontsystemcatalog.cpp | 4 +- dbcon/execplan/calpontsystemcatalog.h | 17 +- dbcon/execplan/constantcolumn.cpp | 7 +- dbcon/execplan/constantcolumn.h | 6 +- dbcon/execplan/functioncolumn.cpp | 8 +- dbcon/execplan/functioncolumn.h | 25 +- .../execplan/mcsanalyzetableexecutionplan.cpp | 7 +- dbcon/execplan/mcsanalyzetableexecutionplan.h | 6 +- dbcon/execplan/simplecolumn.cpp | 7 +- dbcon/execplan/simplecolumn.h | 8 +- dbcon/execplan/simplefilter.cpp | 9 +- dbcon/execplan/simplefilter.h | 8 +- dbcon/execplan/treenode.h | 19 +- dbcon/execplan/windowfunctioncolumn.cpp | 7 +- dbcon/execplan/windowfunctioncolumn.h | 6 +- dbcon/joblist/groupconcat.h | 2 +- dbcon/joblist/jlf_common.h | 2 +- dbcon/joblist/jlf_execplantojoblist.cpp | 4 +- dbcon/joblist/jlf_subquery.cpp | 2 +- dbcon/joblist/jobstep.h | 6 +- dbcon/joblist/tupleunion.h | 2 +- dbcon/mysql/ha_exists_sub.cpp | 2 +- dbcon/mysql/ha_from_sub.cpp | 28 +- dbcon/mysql/ha_in_sub.cpp | 2 +- dbcon/mysql/ha_mcs.cpp | 6 +- dbcon/mysql/ha_mcs.h | 1 + dbcon/mysql/ha_mcs_datatype.h | 15 +- dbcon/mysql/ha_mcs_ddl.cpp | 29 +- dbcon/mysql/ha_mcs_dml.cpp | 10 +- dbcon/mysql/ha_mcs_execplan.cpp | 207 +++++++------ dbcon/mysql/ha_mcs_impl.cpp | 79 +++-- dbcon/mysql/ha_mcs_impl.h | 11 +- dbcon/mysql/ha_mcs_impl_if.h | 22 +- dbcon/mysql/ha_mcs_partition.cpp | 10 +- dbcon/mysql/ha_mcs_pushdown.cpp | 12 +- dbcon/mysql/ha_mcs_pushdown.h | 5 + dbcon/mysql/ha_pseudocolumn.cpp | 4 +- dbcon/mysql/ha_scalar_sub.cpp | 9 +- dbcon/mysql/ha_select_sub.cpp | 2 +- dbcon/mysql/ha_view.cpp | 2 +- dbcon/mysql/ha_window_function.cpp | 42 ++- ddlproc/ddlprocessor.cpp | 2 +- .../columnstore/basic/r/type_timestamp.result | 141 +++++++++ .../columnstore/basic/t/type_timestamp.test | 131 ++++++++ utils/dataconvert/dataconvert.cpp | 15 +- utils/dataconvert/dataconvert.h | 288 ++++++------------ utils/funcexp/func_add_time.cpp | 2 +- utils/funcexp/func_between.cpp | 2 +- utils/funcexp/func_bitwise.cpp | 26 +- utils/funcexp/func_cast.cpp | 20 +- utils/funcexp/func_ceil.cpp | 2 +- utils/funcexp/func_char_length.cpp | 2 +- utils/funcexp/func_convert_tz.cpp | 8 +- utils/funcexp/func_date.cpp | 4 +- utils/funcexp/func_date_add.cpp | 2 +- utils/funcexp/func_date_format.cpp | 6 +- utils/funcexp/func_day.cpp | 2 +- utils/funcexp/func_dayname.cpp | 2 +- utils/funcexp/func_dayofweek.cpp | 2 +- utils/funcexp/func_dayofyear.cpp | 2 +- utils/funcexp/func_extract.cpp | 2 +- utils/funcexp/func_floor.cpp | 4 +- utils/funcexp/func_hour.cpp | 2 +- utils/funcexp/func_if.cpp | 40 +-- utils/funcexp/func_last_day.cpp | 2 +- utils/funcexp/func_math.cpp | 2 +- utils/funcexp/func_minute.cpp | 2 +- utils/funcexp/func_month.cpp | 2 +- utils/funcexp/func_monthname.cpp | 2 +- utils/funcexp/func_nullif.cpp | 3 +- utils/funcexp/func_quarter.cpp | 2 +- utils/funcexp/func_regexp.cpp | 4 +- utils/funcexp/func_round.cpp | 8 +- utils/funcexp/func_second.cpp | 2 +- utils/funcexp/func_str_to_date.cpp | 16 +- utils/funcexp/func_time.cpp | 4 +- utils/funcexp/func_time_format.cpp | 4 +- utils/funcexp/func_time_to_sec.cpp | 2 +- utils/funcexp/func_timediff.cpp | 11 +- utils/funcexp/func_timestampdiff.cpp | 4 +- utils/funcexp/func_to_days.cpp | 2 +- utils/funcexp/func_truncate.cpp | 8 +- utils/funcexp/func_week.cpp | 2 +- utils/funcexp/func_weekday.cpp | 2 +- utils/funcexp/func_year.cpp | 2 +- utils/funcexp/func_yearweek.cpp | 2 +- utils/funcexp/functor.cpp | 4 +- utils/funcexp/functor.h | 28 +- utils/funcexp/functor_real.h | 6 + utils/funcexp/functor_str.h | 2 +- utils/rowgroup/rowaggregation.cpp | 9 +- utils/rowgroup/rowaggregation.h | 8 +- writeengine/bulk/cpimport.cpp | 4 +- writeengine/bulk/we_bulkload.cpp | 2 +- writeengine/bulk/we_bulkload.h | 12 +- writeengine/bulk/we_bulkloadbuffer.cpp | 2 +- writeengine/bulk/we_bulkloadbuffer.h | 6 +- writeengine/bulk/we_tableinfo.cpp | 2 +- writeengine/bulk/we_tableinfo.h | 12 +- writeengine/server/we_ddlcommandproc.cpp | 6 +- writeengine/server/we_dmlcommandproc.cpp | 2 +- writeengine/xml/we_xmljob.cpp | 6 +- writeengine/xml/we_xmljob.h | 6 +- 120 files changed, 1022 insertions(+), 695 deletions(-) create mode 100644 mysql-test/columnstore/basic/r/type_timestamp.result create mode 100644 mysql-test/columnstore/basic/t/type_timestamp.test 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