You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-10-31 18:30:33 +03:00 
			
		
		
		
	* MSan added with fixes for libc++ * libc++ sepatare build * add libc++ to ci * libstdc++ in CI * libcpp and msan to external projects * std::sqrt * awful_hack(ci): install whole llvm instead of libc++ in terrible way for test containers * Adding ddeb packages for teststages and repos * libc++ more for test container * save some money on debug * colored coredumps * revert ci * chore(ci): collect asan ubsan and libc++ build with mtr and regression status ignored
		
			
				
	
	
		
			1190 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1190 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* Copyright (C) 2014 InfiniDB, Inc.
 | |
|    Copyright (C) 2019 MariaDB Corporation
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU General Public License
 | |
|    as published by the Free Software Foundation; version 2 of
 | |
|    the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 | |
|    MA 02110-1301, USA. */
 | |
| 
 | |
| //   $Id: treenode.h 9635 2013-06-19 21:42:30Z bwilkinson $
 | |
| 
 | |
| /** @file */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <ostream>
 | |
| #include <string>
 | |
| #include <iostream>
 | |
| #include <cmath>
 | |
| #include <boost/shared_ptr.hpp>
 | |
| #include <vector>
 | |
| #include <unordered_set>
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <unistd.h>
 | |
| 
 | |
| #include "calpontsystemcatalog.h"
 | |
| #include "exceptclasses.h"
 | |
| #include "dataconvert.h"
 | |
| #include "columnwidth.h"
 | |
| #include "mcs_decimal.h"
 | |
| #include "mcs_int64.h"
 | |
| #include "numericliteral.h"
 | |
| #include "nullstring.h"
 | |
| 
 | |
| namespace messageqcpp
 | |
| {
 | |
| class ByteStream;
 | |
| }
 | |
| 
 | |
| namespace rowgroup
 | |
| {
 | |
| class Row;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Namespace
 | |
|  */
 | |
| namespace execplan
 | |
| {
 | |
| typedef execplan::CalpontSystemCatalog::ColType Type;
 | |
| typedef datatypes::Decimal IDB_Decimal;
 | |
| 
 | |
| using IncludeSet = std::unordered_set<std::string>;
 | |
| /**
 | |
|  * @brief IDB_Regex struct
 | |
|  *
 | |
|  */
 | |
| #ifdef POSIX_REGEX
 | |
| typedef regex_t IDB_Regex;
 | |
| #else
 | |
| typedef std::regex IDB_Regex;
 | |
| #endif
 | |
| 
 | |
| typedef IDB_Regex CNX_Regex;
 | |
| 
 | |
| typedef boost::shared_ptr<IDB_Regex> SP_IDB_Regex;
 | |
| typedef SP_IDB_Regex SP_CNX_Regex;
 | |
| 
 | |
| /** Trim trailing 0 from val. All insignificant zeroes to the right of the
 | |
|  *  decimal point are removed. Also, the decimal point is not included on
 | |
|  *  whole numbers. It works like %g flag with printf, but always print
 | |
|  *  double value in fixed-point notation.
 | |
|  *
 | |
|  *  @parm val valid double value in fixed-point notation from printf %f.
 | |
|  *            No format validation is perfomed in this function.
 | |
|  *  @parm length length of the buffer val
 | |
|  */
 | |
| inline std::string removeTrailing0(char* val, uint32_t length)
 | |
| {
 | |
|   char* ptr = val;
 | |
|   int64_t i = 0;
 | |
|   bool decimal_point = false;
 | |
| 
 | |
|   for (; i < length; i++, ptr++)
 | |
|   {
 | |
|     if (*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9'))
 | |
|     {
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     if (*ptr == '.')
 | |
|     {
 | |
|       decimal_point = true;
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     *ptr = 0;
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   if (decimal_point)
 | |
|   {
 | |
|     for (i = i - 1; i >= 0; i--)
 | |
|     {
 | |
|       if (val[i] == '0')
 | |
|       {
 | |
|         val[i] = 0;
 | |
|       }
 | |
|       else if (val[i] == '.')
 | |
|       {
 | |
|         val[i] = 0;
 | |
|         break;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return std::string(val);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief Result type added for F&E framework
 | |
|  *
 | |
|  */
 | |
| struct Result
 | |
| {
 | |
|   Result()
 | |
|    : intVal(0)
 | |
|    , uintVal(0)
 | |
|    , origIntVal(0)
 | |
|    , dummy(0)
 | |
|    , doubleVal(0)
 | |
|    , longDoubleVal(0)
 | |
|    , floatVal(0)
 | |
|    , boolVal(false)
 | |
|    , strVal()
 | |
|    , decimalVal(IDB_Decimal())
 | |
|    , valueConverted(false)
 | |
|   {
 | |
|   }
 | |
|   int64_t intVal;
 | |
|   uint64_t uintVal;
 | |
|   uint64_t origIntVal;
 | |
|   // clear up the memory following origIntVal to make sure null terminated string
 | |
|   // when converting origIntVal
 | |
|   uint64_t dummy;
 | |
|   double doubleVal;
 | |
|   long double longDoubleVal;
 | |
|   float floatVal;
 | |
|   bool boolVal;
 | |
|   utils::NullString strVal;
 | |
|   IDB_Decimal decimalVal;
 | |
|   bool valueConverted;
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * @brief An abstract class to represent a node data on the expression tree
 | |
|  *
 | |
|  */
 | |
| class TreeNode
 | |
| {
 | |
|  public:
 | |
|   TreeNode();
 | |
|   TreeNode(const TreeNode& rhs);
 | |
|   virtual ~TreeNode();
 | |
|   virtual const std::string data() const = 0;
 | |
|   virtual void data(const std::string data) = 0;
 | |
|   virtual const std::string toString() const = 0;
 | |
|   virtual TreeNode* clone() const = 0;
 | |
| 
 | |
|   /**
 | |
|    * Interface for serialization
 | |
|    */
 | |
| 
 | |
|   /** @brief Convert *this to a stream of bytes
 | |
|    *
 | |
|    * Convert *this to a stream of bytes.
 | |
|    * @param b The ByteStream to add *this to.
 | |
|    */
 | |
|   virtual void serialize(messageqcpp::ByteStream& b) const = 0;
 | |
| 
 | |
|   /** @brief Construct a TreeNode from a stream of bytes
 | |
|    *
 | |
|    * Construct a TreeNode from a stream of bytes.
 | |
|    * @param b The ByteStream to parse
 | |
|    * @return The newly allocated TreeNode
 | |
|    */
 | |
|   virtual void unserialize(messageqcpp::ByteStream& b) = 0;
 | |
| 
 | |
|   /** @brief Do a deep, strict (as opposed to semantic) equivalence test
 | |
|    *
 | |
|    * Do a deep, strict (as opposed to semantic) equivalence test.
 | |
|    * @return true iff every member of t is a duplicate copy of every member of this; false otherwise
 | |
|    */
 | |
|   virtual bool operator==(const TreeNode* t) const = 0;
 | |
| 
 | |
|   /** @brief Do a deep, strict (as opposed to semantic) equivalence test
 | |
|    *
 | |
|    * Do a deep, strict (as opposed to semantic) equivalence test.
 | |
|    * @return false iff every member of t is a duplicate copy of every member of this; true otherwise
 | |
|    */
 | |
|   virtual bool operator!=(const TreeNode* t) const = 0;
 | |
| 
 | |
|   virtual std::string toCppCode(IncludeSet& includes) const = 0;
 | |
|   // derivedTable mutator and accessor
 | |
|   virtual const std::string& derivedTable() const
 | |
|   {
 | |
|     return fDerivedTable;
 | |
|   }
 | |
| 
 | |
|   virtual void derivedTable(const std::string& derivedTable)
 | |
|   {
 | |
|     fDerivedTable = derivedTable;
 | |
|   }
 | |
| 
 | |
|   // must to be implented by treenode that could potentially belong to
 | |
|   // one single derived table
 | |
|   virtual void setDerivedTable()
 | |
|   {
 | |
|     fDerivedTable = "";
 | |
|   }
 | |
| 
 | |
|   virtual TreeNode* derivedRefCol() const
 | |
|   {
 | |
|     return fDerivedRefCol;
 | |
|   }
 | |
| 
 | |
|   virtual void derivedRefCol(TreeNode* derivedRefCol)
 | |
|   {
 | |
|     fDerivedRefCol = derivedRefCol;
 | |
|   }
 | |
| 
 | |
|   virtual uint64_t refCount() const
 | |
|   {
 | |
|     return fRefCount;
 | |
|   }
 | |
| 
 | |
|   virtual void refCount(const uint64_t refCount)
 | |
|   {
 | |
|     fRefCount = refCount;
 | |
|   }
 | |
| 
 | |
|   // the inc and dec functions areparm[n]->data() used by connector single thread.
 | |
|   virtual void decRefCount()
 | |
|   {
 | |
|     fRefCount--;
 | |
|   }
 | |
| 
 | |
|   virtual void incRefCount()
 | |
|   {
 | |
|     fRefCount++;
 | |
|   }
 | |
| 
 | |
|   /***********************************************************************
 | |
|    *                     F&E framework                                   *
 | |
|    ***********************************************************************/
 | |
|   virtual const utils::NullString& getStrVal(rowgroup::Row& /*row*/, bool& isNull)
 | |
|   {
 | |
|     isNull = isNull ||
 | |
|              fResult.strVal
 | |
|                  .isNull();  // XXX: NullString returns isNull, we should remove that parameter altogether.
 | |
|     return fResult.strVal;
 | |
|   }
 | |
|   virtual int64_t getIntVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.intVal;
 | |
|   }
 | |
|   virtual uint64_t getUintVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.uintVal;
 | |
|   }
 | |
|   datatypes::TUInt64Null toTUInt64Null(rowgroup::Row& row)
 | |
|   {
 | |
|     bool isNull = false;
 | |
|     uint64_t val = getUintVal(row, isNull);
 | |
|     return datatypes::TUInt64Null(val, isNull);
 | |
|   }
 | |
|   datatypes::TSInt64Null toTSInt64Null(rowgroup::Row& row)
 | |
|   {
 | |
|     bool isNull = false;
 | |
|     int64_t val = getIntVal(row, isNull);
 | |
|     return datatypes::TSInt64Null(val, isNull);
 | |
|   }
 | |
|   virtual float getFloatVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.floatVal;
 | |
|   }
 | |
|   virtual double getDoubleVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.doubleVal;
 | |
|   }
 | |
|   virtual long double getLongDoubleVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.longDoubleVal;
 | |
|   }
 | |
|   virtual IDB_Decimal getDecimalVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.decimalVal;
 | |
|   }
 | |
|   virtual bool getBoolVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.boolVal;
 | |
|   }
 | |
|   virtual int32_t getDateIntVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.intVal;
 | |
|   }
 | |
|   virtual int64_t getDatetimeIntVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.intVal;
 | |
|   }
 | |
|   virtual int64_t getTimestampIntVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.intVal;
 | |
|   }
 | |
|   virtual int64_t getTimeIntVal(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|     return fResult.intVal;
 | |
|   }
 | |
|   virtual void evaluate(rowgroup::Row& /*row*/, bool& /*isNull*/)
 | |
|   {
 | |
|   }
 | |
| 
 | |
|   inline bool getBoolVal();
 | |
|   inline const utils::NullString& getStrVal(const long timeZone);
 | |
|   inline int64_t getIntVal();
 | |
|   inline uint64_t getUintVal();
 | |
|   inline float getFloatVal();
 | |
|   inline double getDoubleVal();
 | |
|   inline long double getLongDoubleVal();
 | |
|   inline IDB_Decimal getDecimalVal();
 | |
|   inline int32_t getDateIntVal();
 | |
|   inline int64_t getDatetimeIntVal(long timeZone = 0);
 | |
|   inline int64_t getTimestampIntVal();
 | |
|   inline int64_t getTimeIntVal();
 | |
| 
 | |
|   virtual const execplan::CalpontSystemCatalog::ColType& resultType() const
 | |
|   {
 | |
|     return fResultType;
 | |
|   }
 | |
|   virtual execplan::CalpontSystemCatalog::ColType& resultType()
 | |
|   {
 | |
|     return fResultType;
 | |
|   }
 | |
|   virtual void resultType(const execplan::CalpontSystemCatalog::ColType& resultType);
 | |
|   virtual void operationType(const Type& type)
 | |
|   {
 | |
|     fOperationType = type;
 | |
|   }
 | |
|   virtual const execplan::CalpontSystemCatalog::ColType& operationType() const
 | |
|   {
 | |
|     return fOperationType;
 | |
|   }
 | |
| 
 | |
|   // result mutator and accessor. for speical functor to set for optimization.
 | |
|   virtual void result(const Result& result)
 | |
|   {
 | |
|     fResult = result;
 | |
|   }
 | |
|   virtual const Result& result() const
 | |
|   {
 | |
|     return fResult;
 | |
|   }
 | |
| 
 | |
|   uint32_t charsetNumber() const
 | |
|   {
 | |
|     return fResultType.charsetNumber;
 | |
|   }
 | |
|   void charsetNumber(uint32_t cnum)
 | |
|   {
 | |
|     fResultType.charsetNumber = cnum;
 | |
|     fOperationType.charsetNumber = cnum;
 | |
|   }
 | |
| 
 | |
|  protected:
 | |
|   Result fResult;
 | |
|   execplan::CalpontSystemCatalog::ColType fResultType;  // mapped from mysql data type
 | |
|   execplan::CalpontSystemCatalog::ColType
 | |
|       fOperationType;  // operator type, could be different from the result type
 | |
| 
 | |
|   // double's range is +/-1.7E308 with at least 15 digits of precision
 | |
|   char tmp[312];  // for conversion use
 | |
| 
 | |
|   // @bug5635 If any item involved in this filter belongs to a derived table,
 | |
|   // the derived table alias is added to the reference vector.
 | |
|   std::string fDerivedTable;
 | |
|   uint64_t fRefCount;
 | |
|   TreeNode* fDerivedRefCol;
 | |
| 
 | |
|  private:
 | |
|   // default okay
 | |
|   // TreeNode& operator=(const TreeNode& rhs);
 | |
| };
 | |
| 
 | |
| inline bool TreeNode::getBoolVal()
 | |
| {
 | |
|   switch (fResultType.colDataType)
 | |
|   {
 | |
|     case CalpontSystemCatalog::CHAR:
 | |
|       if (fResultType.colWidth <= 8)
 | |
|         return (atoi((char*)(&fResult.origIntVal)) != 0);
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return (atoi(fResult.strVal.str()) != 0);
 | |
| 
 | |
|     case CalpontSystemCatalog::VARCHAR:
 | |
|       if (fResultType.colWidth <= 7)
 | |
|         return (atoi((char*)(&fResult.origIntVal)) != 0);
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return (atoi(fResult.strVal.str()) != 0);
 | |
| 
 | |
|     // FIXME: Huh???
 | |
|     case CalpontSystemCatalog::VARBINARY:
 | |
|     case CalpontSystemCatalog::BLOB:
 | |
|     case CalpontSystemCatalog::TEXT:
 | |
|       if (fResultType.colWidth <= 7)
 | |
|         return (atoi((char*)(&fResult.origIntVal)) != 0);
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return (atoi(fResult.strVal.str()) != 0);
 | |
| 
 | |
|     case CalpontSystemCatalog::BIGINT:
 | |
|     case CalpontSystemCatalog::SMALLINT:
 | |
|     case CalpontSystemCatalog::MEDINT:
 | |
|     case CalpontSystemCatalog::TINYINT:
 | |
|     case CalpontSystemCatalog::INT:
 | |
|     case CalpontSystemCatalog::DATE:
 | |
|     case CalpontSystemCatalog::DATETIME:
 | |
|     case CalpontSystemCatalog::TIMESTAMP:
 | |
|     case CalpontSystemCatalog::TIME: return (fResult.intVal != 0);
 | |
| 
 | |
|     case CalpontSystemCatalog::UBIGINT:
 | |
|     case CalpontSystemCatalog::USMALLINT:
 | |
|     case CalpontSystemCatalog::UMEDINT:
 | |
|     case CalpontSystemCatalog::UTINYINT:
 | |
|     case CalpontSystemCatalog::UINT: return (fResult.uintVal != 0);
 | |
| 
 | |
|     case CalpontSystemCatalog::FLOAT:
 | |
|     case CalpontSystemCatalog::UFLOAT: return (fResult.floatVal != 0);
 | |
| 
 | |
|     case CalpontSystemCatalog::DOUBLE:
 | |
|     case CalpontSystemCatalog::UDOUBLE: return (fResult.doubleVal != 0);
 | |
| 
 | |
|     case CalpontSystemCatalog::LONGDOUBLE: return (fResult.longDoubleVal != 0);
 | |
| 
 | |
|     case CalpontSystemCatalog::DECIMAL:
 | |
|     case CalpontSystemCatalog::UDECIMAL:
 | |
|       if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
 | |
|         return (fResult.decimalVal.s128Value != 0);
 | |
|       else
 | |
|         return (fResult.decimalVal.value != 0);
 | |
| 
 | |
|     default: throw logging::InvalidConversionExcept("TreeNode::getBoolVal: Invalid conversion.");
 | |
|   }
 | |
| 
 | |
|   return fResult.boolVal;
 | |
| }
 | |
| 
 | |
| inline const utils::NullString& TreeNode::getStrVal(const long timeZone)
 | |
| {
 | |
|   switch (fResultType.colDataType)
 | |
|   {
 | |
|     case CalpontSystemCatalog::VARCHAR:
 | |
|       if (fResultType.colWidth <= 7)
 | |
|       {
 | |
|         const char* intAsChar = (const char*)(&fResult.origIntVal);
 | |
|         fResult.strVal.assign((const uint8_t*)intAsChar, strlen(intAsChar));
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case CalpontSystemCatalog::CHAR:
 | |
|     case CalpontSystemCatalog::VARBINARY:  // XXX: TODO: we don't have varbinary support now, but it may be
 | |
|                                            // handled just like varchar.
 | |
|     case CalpontSystemCatalog::BLOB:
 | |
|     case CalpontSystemCatalog::TEXT:
 | |
|       if (fResultType.colWidth <= 8)
 | |
|       {
 | |
|         const char* intAsChar = (const char*)(&fResult.origIntVal);
 | |
|         fResult.strVal.assign((const uint8_t*)intAsChar, strlen(intAsChar));
 | |
|       }
 | |
| 
 | |
|       break;
 | |
| 
 | |
|     case CalpontSystemCatalog::BIGINT:
 | |
|     case CalpontSystemCatalog::SMALLINT:
 | |
|     case CalpontSystemCatalog::MEDINT:
 | |
|     case CalpontSystemCatalog::TINYINT:
 | |
|     case CalpontSystemCatalog::INT:
 | |
|     {
 | |
| #ifndef __LP64__
 | |
|       snprintf(tmp, 20, "%lld", fResult.intVal);
 | |
| #else
 | |
|       snprintf(tmp, 20, "%ld", fResult.intVal);
 | |
| #endif
 | |
|       fResult.strVal.assign(std::string(tmp));
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::UBIGINT:
 | |
|     case CalpontSystemCatalog::USMALLINT:
 | |
|     case CalpontSystemCatalog::UMEDINT:
 | |
|     case CalpontSystemCatalog::UTINYINT:
 | |
|     case CalpontSystemCatalog::UINT:
 | |
|     {
 | |
| #ifndef __LP64__
 | |
|       snprintf(tmp, 20, "%llu", fResult.uintVal);
 | |
| #else
 | |
|       snprintf(tmp, 20, "%lu", fResult.uintVal);
 | |
| #endif
 | |
|       fResult.strVal.assign(std::string(tmp));
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::FLOAT:
 | |
|     case CalpontSystemCatalog::UFLOAT:
 | |
|     {
 | |
|       if ((fabs(fResult.floatVal) > (1.0 / IDB_pow[4])) && (fabs(fResult.floatVal) < (float)IDB_pow[6]))
 | |
|       {
 | |
|         snprintf(tmp, 312, "%f", fResult.floatVal);
 | |
|         fResult.strVal.assign(removeTrailing0(tmp, 312));
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         // MCOL-299 Print scientific with 5 mantissa and no + sign for exponent
 | |
|         int exponent = (int)floor(log10(fabs(fResult.floatVal)));  // This will round down the exponent
 | |
|         double base = fResult.floatVal * pow(10, -1.0 * exponent);
 | |
| 
 | |
|         if (std::isnan(exponent) || std::isnan(base))
 | |
|         {
 | |
|           snprintf(tmp, 312, "%f", fResult.floatVal);
 | |
|           fResult.strVal.assign(removeTrailing0(tmp, 312));
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           snprintf(tmp, 312, "%.5f", base);
 | |
|           std::string tmpCat(removeTrailing0(tmp, 312));
 | |
|           snprintf(tmp, 312, "e%02d", exponent);
 | |
|           tmpCat += tmp;
 | |
|           fResult.strVal.assign(tmpCat);
 | |
|         }
 | |
| 
 | |
|         //				snprintf(tmp, 312, "%e.5", fResult.floatVal);
 | |
|         //				fResult.strVal = tmp;
 | |
|       }
 | |
| 
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::DOUBLE:
 | |
|     case CalpontSystemCatalog::UDOUBLE:
 | |
|     {
 | |
|       if ((fabs(fResult.doubleVal) > (1.0 / IDB_pow[13])) && (fabs(fResult.doubleVal) < (float)IDB_pow[15]))
 | |
|       {
 | |
|         snprintf(tmp, 312, "%f", fResult.doubleVal);
 | |
|         fResult.strVal.assign(removeTrailing0(tmp, 312));
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         // MCOL-299 Print scientific with 9 mantissa and no + sign for exponent
 | |
|         int exponent = (int)floor(log10(fabs(fResult.doubleVal)));  // This will round down the exponent
 | |
|         double base = fResult.doubleVal * pow(10, -1.0 * exponent);
 | |
| 
 | |
|         if (std::isnan(exponent) || std::isnan(base))
 | |
|         {
 | |
|           snprintf(tmp, 312, "%f", fResult.doubleVal);
 | |
|           fResult.strVal.assign(removeTrailing0(tmp, 312));
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           snprintf(tmp, 312, "%.9f", base);
 | |
|           std::string tmpCat(removeTrailing0(tmp, 312));
 | |
|           snprintf(tmp, 312, "e%02d", exponent);
 | |
|           tmpCat += tmp;
 | |
|           fResult.strVal.assign(tmpCat);
 | |
|         }
 | |
| 
 | |
|         //				snprintf(tmp, 312, "%e", fResult.doubleVal);
 | |
|         //				fResult.strVal = tmp;
 | |
|       }
 | |
| 
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::LONGDOUBLE:
 | |
|     {
 | |
|       if ((fabsl(fResult.longDoubleVal) > (1.0 / IDB_pow[13])) &&
 | |
|           (fabsl(fResult.longDoubleVal) < (float)IDB_pow[15]))
 | |
|       {
 | |
|         snprintf(tmp, 312, "%Lf", fResult.longDoubleVal);
 | |
|         fResult.strVal.assign(removeTrailing0(tmp, 312));
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         // MCOL-299 Print scientific with 9 mantissa and no + sign for exponent
 | |
|         int exponent = (int)floorl(log10(fabsl(fResult.longDoubleVal)));  // This will round down the exponent
 | |
|         long double base = fResult.longDoubleVal * pow(10, -1.0 * exponent);
 | |
| 
 | |
|         if (std::isnan(exponent) || std::isnan(base))
 | |
|         {
 | |
|           snprintf(tmp, 312, "%Lf", fResult.longDoubleVal);
 | |
|           fResult.strVal.assign(removeTrailing0(tmp, 312));
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           snprintf(tmp, 312, "%.14Lf", base);
 | |
|           std::string tmpCat = removeTrailing0(tmp, 312);
 | |
|           snprintf(tmp, 312, "e%02d", exponent);
 | |
|           tmpCat += tmp;
 | |
|           fResult.strVal.assign(tmpCat);
 | |
|         }
 | |
| 
 | |
|         //				snprintf(tmp, 312, "%e", fResult.doubleVal);
 | |
|         //				fResult.strVal = tmp;
 | |
|       }
 | |
| 
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::DECIMAL:
 | |
|     case CalpontSystemCatalog::UDECIMAL:
 | |
|     {
 | |
|       if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
 | |
|       {
 | |
|         // Explicit path for TSInt128 decimals with low precision
 | |
|         fResult.strVal = fResult.decimalVal.toNullString(true);
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         fResult.strVal = fResult.decimalVal.toNullString(false);
 | |
|       }
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::DATE:
 | |
|     {
 | |
|       dataconvert::DataConvert::dateToString(fResult.intVal, tmp, 255);
 | |
|       fResult.strVal.assign(std::string(tmp));
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::DATETIME:
 | |
|     {
 | |
|       dataconvert::DataConvert::datetimeToString(fResult.intVal, tmp, 255, fResultType.precision);
 | |
|       fResult.strVal.assign(std::string(tmp));
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::TIMESTAMP:
 | |
|     {
 | |
|       dataconvert::DataConvert::timestampToString(fResult.intVal, tmp, 255, timeZone, fResultType.precision);
 | |
|       fResult.strVal.assign(std::string(tmp));
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::TIME:
 | |
|     {
 | |
|       dataconvert::DataConvert::timeToString(fResult.intVal, tmp, 255, fResultType.precision);
 | |
|       fResult.strVal.assign(std::string(tmp));
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     default: throw logging::InvalidConversionExcept("TreeNode::getStrVal: Invalid conversion.");
 | |
|   }
 | |
| 
 | |
|   return fResult.strVal;
 | |
| }
 | |
| 
 | |
| inline int64_t TreeNode::getIntVal()
 | |
| {
 | |
|   switch (fResultType.colDataType)
 | |
|   {
 | |
|     case CalpontSystemCatalog::CHAR:
 | |
|     {
 | |
|       if (fResultType.colWidth <= 8)
 | |
|       {
 | |
|         return fResult.intVal;
 | |
|       }
 | |
|       datatypes::DataCondition cnverr;
 | |
|       literal::Converter<literal::SignedInteger> cnv(fResult.strVal.safeString(""), cnverr);
 | |
|       return cnv.toSInt<int64_t>(cnverr);
 | |
|     }
 | |
|     case CalpontSystemCatalog::VARCHAR:
 | |
|     case CalpontSystemCatalog::VARBINARY:
 | |
|     case CalpontSystemCatalog::BLOB:
 | |
|     case CalpontSystemCatalog::TEXT:
 | |
|     {
 | |
|       if (fResultType.colWidth <= 7)
 | |
|         return fResult.intVal;
 | |
| 
 | |
|       datatypes::DataCondition cnverr;
 | |
|       literal::Converter<literal::SignedInteger> cnv(fResult.strVal.safeString(""), cnverr);
 | |
|       return cnv.toSInt<int64_t>(cnverr);
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::BIGINT:
 | |
|     case CalpontSystemCatalog::TINYINT:
 | |
|     case CalpontSystemCatalog::SMALLINT:
 | |
|     case CalpontSystemCatalog::MEDINT:
 | |
|     case CalpontSystemCatalog::INT: return fResult.intVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::UBIGINT:
 | |
|     case CalpontSystemCatalog::UTINYINT:
 | |
|     case CalpontSystemCatalog::USMALLINT:
 | |
|     case CalpontSystemCatalog::UMEDINT:
 | |
|     case CalpontSystemCatalog::UINT: return fResult.uintVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::FLOAT:
 | |
|     case CalpontSystemCatalog::UFLOAT: return (int64_t)std::llround(fResult.floatVal);
 | |
| 
 | |
|     case CalpontSystemCatalog::DOUBLE:
 | |
|     case CalpontSystemCatalog::UDOUBLE: return (int64_t)std::llround(fResult.doubleVal);
 | |
| 
 | |
|     case CalpontSystemCatalog::LONGDOUBLE: return (int64_t)std::llround(fResult.longDoubleVal);
 | |
| 
 | |
|     case CalpontSystemCatalog::DECIMAL:
 | |
|     case CalpontSystemCatalog::UDECIMAL: return fResult.decimalVal.toSInt64Round();
 | |
| 
 | |
|     case CalpontSystemCatalog::DATE:
 | |
|     case CalpontSystemCatalog::DATETIME:
 | |
|     case CalpontSystemCatalog::TIMESTAMP:
 | |
|     case CalpontSystemCatalog::TIME: return fResult.intVal;
 | |
| 
 | |
|     default: throw logging::InvalidConversionExcept("TreeNode::getIntVal: Invalid conversion.");
 | |
|   }
 | |
| 
 | |
|   return fResult.intVal;
 | |
| }
 | |
| inline uint64_t TreeNode::getUintVal()
 | |
| {
 | |
|   switch (fResultType.colDataType)
 | |
|   {
 | |
|     case CalpontSystemCatalog::CHAR:
 | |
|     case CalpontSystemCatalog::VARCHAR:
 | |
|     case CalpontSystemCatalog::VARBINARY:
 | |
|     case CalpontSystemCatalog::BLOB:
 | |
|     case CalpontSystemCatalog::TEXT:
 | |
|     {
 | |
|       datatypes::DataCondition cnverr;
 | |
|       literal::Converter<literal::UnsignedInteger> cnv(fResult.strVal.safeString(""), cnverr);
 | |
|       if (datatypes::DataCondition::Code(cnverr) != 0)
 | |
|       {
 | |
|         std::cerr << "error in unsigned int conversion from '" << fResult.strVal.safeString() << "'";
 | |
|       }
 | |
|       return cnv.toXIntPositive<uint64_t>(cnverr);
 | |
|     }
 | |
|     case CalpontSystemCatalog::BIGINT:
 | |
|     case CalpontSystemCatalog::TINYINT:
 | |
|     case CalpontSystemCatalog::SMALLINT:
 | |
|     case CalpontSystemCatalog::MEDINT:
 | |
|     case CalpontSystemCatalog::INT: return fResult.intVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::UBIGINT:
 | |
|     case CalpontSystemCatalog::UTINYINT:
 | |
|     case CalpontSystemCatalog::USMALLINT:
 | |
|     case CalpontSystemCatalog::UMEDINT:
 | |
|     case CalpontSystemCatalog::UINT: return fResult.uintVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::FLOAT:
 | |
|     case CalpontSystemCatalog::UFLOAT: return (uint64_t)std::llround(fResult.floatVal);
 | |
| 
 | |
|     case CalpontSystemCatalog::DOUBLE:
 | |
|     case CalpontSystemCatalog::UDOUBLE: return (uint64_t)std::llround(fResult.doubleVal);
 | |
| 
 | |
|     case CalpontSystemCatalog::LONGDOUBLE: return (uint64_t)std::llround(fResult.longDoubleVal);
 | |
| 
 | |
|     case CalpontSystemCatalog::DECIMAL:
 | |
|     case CalpontSystemCatalog::UDECIMAL: return fResult.decimalVal.toUInt64Round();
 | |
| 
 | |
|     case CalpontSystemCatalog::DATE:
 | |
|     case CalpontSystemCatalog::DATETIME:
 | |
|     case CalpontSystemCatalog::TIMESTAMP:
 | |
|     case CalpontSystemCatalog::TIME: return fResult.intVal;
 | |
| 
 | |
|     default: throw logging::InvalidConversionExcept("TreeNode::getIntVal: Invalid conversion.");
 | |
|   }
 | |
| 
 | |
|   return fResult.intVal;
 | |
| }
 | |
| inline float TreeNode::getFloatVal()
 | |
| {
 | |
|   switch (fResultType.colDataType)
 | |
|   {
 | |
|     case CalpontSystemCatalog::CHAR:
 | |
|       if (fResultType.colWidth <= 8)
 | |
|         return atof((char*)(&fResult.origIntVal));
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return atof(fResult.strVal.str());
 | |
| 
 | |
|     case CalpontSystemCatalog::VARCHAR:
 | |
|       if (fResultType.colWidth <= 7)
 | |
|         return atof((char*)(&fResult.origIntVal));
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return atof(fResult.strVal.str());
 | |
| 
 | |
|     // FIXME: ???
 | |
|     case CalpontSystemCatalog::VARBINARY:
 | |
|     case CalpontSystemCatalog::BLOB:
 | |
|     case CalpontSystemCatalog::TEXT:
 | |
|       if (fResultType.colWidth <= 7)
 | |
|         return atof((char*)(&fResult.origIntVal));
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return atof(fResult.strVal.str());
 | |
| 
 | |
|     case CalpontSystemCatalog::BIGINT:
 | |
|     case CalpontSystemCatalog::TINYINT:
 | |
|     case CalpontSystemCatalog::SMALLINT:
 | |
|     case CalpontSystemCatalog::MEDINT:
 | |
|     case CalpontSystemCatalog::INT: return (float)fResult.intVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::UBIGINT:
 | |
|     case CalpontSystemCatalog::UTINYINT:
 | |
|     case CalpontSystemCatalog::USMALLINT:
 | |
|     case CalpontSystemCatalog::UMEDINT:
 | |
|     case CalpontSystemCatalog::UINT: return (float)fResult.uintVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::FLOAT:
 | |
|     case CalpontSystemCatalog::UFLOAT: return fResult.floatVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::DOUBLE:
 | |
|     case CalpontSystemCatalog::UDOUBLE: return (float)fResult.doubleVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::LONGDOUBLE: return (float)fResult.doubleVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::DECIMAL:
 | |
|     case CalpontSystemCatalog::UDECIMAL:
 | |
|     {
 | |
|       if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
 | |
|       {
 | |
|         return static_cast<float>(fResult.decimalVal);
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         return (float)fResult.decimalVal.decimal64ToXFloat<double>();
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::DATE:
 | |
|     case CalpontSystemCatalog::DATETIME:
 | |
|     case CalpontSystemCatalog::TIMESTAMP:
 | |
|     case CalpontSystemCatalog::TIME: return (float)fResult.intVal;
 | |
| 
 | |
|     default: throw logging::InvalidConversionExcept("TreeNode::getFloatVal: Invalid conversion.");
 | |
|   }
 | |
| 
 | |
|   return fResult.floatVal;
 | |
| }
 | |
| inline double TreeNode::getDoubleVal()
 | |
| {
 | |
|   switch (fResultType.colDataType)
 | |
|   {
 | |
|     case CalpontSystemCatalog::CHAR:
 | |
|       if (fResultType.colWidth <= 8)
 | |
|         return strtod((char*)(&fResult.origIntVal), nullptr);
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return strtod(fResult.strVal.str(), nullptr);
 | |
| 
 | |
|     case CalpontSystemCatalog::VARCHAR:
 | |
|       if (fResultType.colWidth <= 7)
 | |
|         return strtod((char*)(&fResult.origIntVal), nullptr);
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return strtod(fResult.strVal.str(), nullptr);
 | |
| 
 | |
|     // FIXME: ???
 | |
|     case CalpontSystemCatalog::VARBINARY:
 | |
|     case CalpontSystemCatalog::BLOB:
 | |
|     case CalpontSystemCatalog::TEXT:
 | |
|       if (fResultType.colWidth <= 7)
 | |
|         return strtod((char*)(&fResult.origIntVal), nullptr);
 | |
| 
 | |
|       // idbassert(fResult.strVal.str());
 | |
|       return strtod(fResult.strVal.safeString("").c_str(), nullptr);
 | |
| 
 | |
|     case CalpontSystemCatalog::BIGINT:
 | |
|     case CalpontSystemCatalog::TINYINT:
 | |
|     case CalpontSystemCatalog::SMALLINT:
 | |
|     case CalpontSystemCatalog::MEDINT:
 | |
|     case CalpontSystemCatalog::INT: return (double)fResult.intVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::UBIGINT:
 | |
|     case CalpontSystemCatalog::UTINYINT:
 | |
|     case CalpontSystemCatalog::USMALLINT:
 | |
|     case CalpontSystemCatalog::UMEDINT:
 | |
|     case CalpontSystemCatalog::UINT: return (double)fResult.uintVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::FLOAT:
 | |
|     case CalpontSystemCatalog::UFLOAT: return (double)fResult.floatVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::DOUBLE:
 | |
|     case CalpontSystemCatalog::UDOUBLE: return fResult.doubleVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::LONGDOUBLE: return (double)fResult.longDoubleVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::DECIMAL:
 | |
|     case CalpontSystemCatalog::UDECIMAL:
 | |
|     {
 | |
|       if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
 | |
|       {
 | |
|         return static_cast<double>(fResult.decimalVal);
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         return fResult.decimalVal.decimal64ToXFloat<double>();
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::DATE:
 | |
|     case CalpontSystemCatalog::DATETIME:
 | |
|     case CalpontSystemCatalog::TIMESTAMP:
 | |
|     case CalpontSystemCatalog::TIME: return (double)fResult.intVal;
 | |
| 
 | |
|     default: throw logging::InvalidConversionExcept("TreeNode::getDoubleVal: Invalid conversion.");
 | |
|   }
 | |
| 
 | |
|   return fResult.doubleVal;
 | |
| }
 | |
| inline long double TreeNode::getLongDoubleVal()
 | |
| {
 | |
|   switch (fResultType.colDataType)
 | |
|   {
 | |
|     case CalpontSystemCatalog::CHAR:
 | |
|       if (fResultType.colWidth <= 8)
 | |
|         return strtold((char*)(&fResult.origIntVal), nullptr);
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return strtold(fResult.strVal.str(), nullptr);
 | |
| 
 | |
|     case CalpontSystemCatalog::VARCHAR:
 | |
|       if (fResultType.colWidth <= 7)
 | |
|         return strtold((char*)(&fResult.origIntVal), nullptr);
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return strtold(fResult.strVal.str(), nullptr);
 | |
| 
 | |
|     // FIXME: ???
 | |
|     case CalpontSystemCatalog::VARBINARY:
 | |
|     case CalpontSystemCatalog::BLOB:
 | |
|     case CalpontSystemCatalog::TEXT:
 | |
|       if (fResultType.colWidth <= 7)
 | |
|         return strtold((char*)(&fResult.origIntVal), nullptr);
 | |
| 
 | |
|       idbassert(fResult.strVal.str());
 | |
|       return strtold(fResult.strVal.str(), nullptr);
 | |
| 
 | |
|     case CalpontSystemCatalog::BIGINT:
 | |
|     case CalpontSystemCatalog::TINYINT:
 | |
|     case CalpontSystemCatalog::SMALLINT:
 | |
|     case CalpontSystemCatalog::MEDINT:
 | |
|     case CalpontSystemCatalog::INT: return (long double)fResult.intVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::UBIGINT:
 | |
|     case CalpontSystemCatalog::UTINYINT:
 | |
|     case CalpontSystemCatalog::USMALLINT:
 | |
|     case CalpontSystemCatalog::UMEDINT:
 | |
|     case CalpontSystemCatalog::UINT: return (long double)fResult.uintVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::FLOAT:
 | |
|     case CalpontSystemCatalog::UFLOAT: return (long double)fResult.floatVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::DOUBLE:
 | |
|     case CalpontSystemCatalog::UDOUBLE: return (long double)fResult.doubleVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::LONGDOUBLE: return (long double)fResult.longDoubleVal;
 | |
| 
 | |
|     case CalpontSystemCatalog::DECIMAL:
 | |
|     case CalpontSystemCatalog::UDECIMAL:
 | |
|     {
 | |
|       if (fResultType.colWidth == datatypes::MAXDECIMALWIDTH)
 | |
|       {
 | |
|         return static_cast<long double>(fResult.decimalVal);
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         return fResult.decimalVal.decimal64ToXFloat<long double>();
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::DATE:
 | |
|     case CalpontSystemCatalog::DATETIME:
 | |
|     case CalpontSystemCatalog::TIME: return (long double)fResult.intVal;
 | |
| 
 | |
|     default: throw logging::InvalidConversionExcept("TreeNode::getDoubleVal: Invalid conversion.");
 | |
|   }
 | |
| 
 | |
|   return fResult.doubleVal;
 | |
| }
 | |
| inline IDB_Decimal TreeNode::getDecimalVal()
 | |
| {
 | |
|   switch (fResultType.colDataType)
 | |
|   {
 | |
|     case CalpontSystemCatalog::CHAR:
 | |
|     case CalpontSystemCatalog::VARCHAR:
 | |
|     case CalpontSystemCatalog::TEXT:
 | |
|       throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: non-support conversion from string");
 | |
| 
 | |
|     case CalpontSystemCatalog::VARBINARY:
 | |
|     case CalpontSystemCatalog::BLOB:
 | |
|       throw logging::InvalidConversionExcept(
 | |
|           "TreeNode::getDecimalVal: non-support conversion from binary string");
 | |
| 
 | |
|     case CalpontSystemCatalog::BIGINT:
 | |
|     case CalpontSystemCatalog::MEDINT:
 | |
|     case CalpontSystemCatalog::INT:
 | |
|     case CalpontSystemCatalog::SMALLINT:
 | |
|     case CalpontSystemCatalog::TINYINT:
 | |
|     {
 | |
|       idbassert(fResultType.scale == 0);
 | |
|       fResult.decimalVal = IDB_Decimal(fResult.intVal, 0, fResultType.precision, fResult.intVal);
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::UBIGINT:
 | |
|     case CalpontSystemCatalog::UMEDINT:
 | |
|     case CalpontSystemCatalog::UINT:
 | |
|     case CalpontSystemCatalog::USMALLINT:
 | |
|     case CalpontSystemCatalog::UTINYINT:
 | |
|     {
 | |
|       idbassert(fResultType.scale == 0);
 | |
|       fResult.decimalVal = IDB_Decimal((int64_t)fResult.uintVal, 0, fResultType.precision, fResult.uintVal);
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::LONGDOUBLE:
 | |
|     {
 | |
|       long double dlScaled = fResult.longDoubleVal;
 | |
| 
 | |
|       if (fResultType.scale > 0)
 | |
|       {
 | |
|         dlScaled = fResult.longDoubleVal * pow((double)10.0, fResultType.scale);
 | |
|       }
 | |
| 
 | |
|       if ((dlScaled > (long double)INT64_MAX) || (dlScaled < (long double)(INT64_MIN)))
 | |
|       {
 | |
|         datatypes::TFloat128 temp((float128_t)dlScaled);
 | |
|         fResult.decimalVal =
 | |
|             IDB_Decimal(0, fResultType.scale, fResultType.precision, static_cast<int128_t>(temp));
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         int64_t val = (int64_t)lroundl(dlScaled);
 | |
|         fResult.decimalVal = IDB_Decimal(val, fResultType.scale, fResultType.precision, val);
 | |
|       }
 | |
| 
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     case CalpontSystemCatalog::DATE:
 | |
|       throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: Invalid conversion from date.");
 | |
| 
 | |
|     case CalpontSystemCatalog::DATETIME:
 | |
|       throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: Invalid conversion from datetime.");
 | |
| 
 | |
|     case CalpontSystemCatalog::TIMESTAMP:
 | |
|       throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: Invalid conversion from timestamp.");
 | |
| 
 | |
|     case CalpontSystemCatalog::TIME:
 | |
|       throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: Invalid conversion from time.");
 | |
| 
 | |
|     case CalpontSystemCatalog::FLOAT:
 | |
|       throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: non-support conversion from float");
 | |
| 
 | |
|     case CalpontSystemCatalog::UFLOAT:
 | |
|       throw logging::InvalidConversionExcept(
 | |
|           "TreeNode::getDecimalVal: non-support conversion from float unsigned");
 | |
| 
 | |
|     case CalpontSystemCatalog::DOUBLE:
 | |
|       throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: non-support conversion from double");
 | |
| 
 | |
|     case CalpontSystemCatalog::UDOUBLE:
 | |
|       throw logging::InvalidConversionExcept(
 | |
|           "TreeNode::getDecimalVal: non-support conversion from double unsigned");
 | |
| 
 | |
|     case CalpontSystemCatalog::DECIMAL:
 | |
|     case CalpontSystemCatalog::UDECIMAL: return fResult.decimalVal;
 | |
| 
 | |
|     default: throw logging::InvalidConversionExcept("TreeNode::getDecimalVal: Invalid conversion.");
 | |
|   }
 | |
| 
 | |
|   return fResult.decimalVal;
 | |
| }
 | |
| 
 | |
| inline int64_t TreeNode::getDatetimeIntVal(long timeZone)
 | |
| {
 | |
|   if (fResultType.colDataType == execplan::CalpontSystemCatalog::DATE)
 | |
|     return (fResult.intVal & 0x00000000FFFFFFC0LL) << 32;
 | |
|   else if (fResultType.colDataType == execplan::CalpontSystemCatalog::TIME)
 | |
|   {
 | |
|     dataconvert::Time tt;
 | |
|     int day = 0;
 | |
| 
 | |
|     void* ttp = static_cast<void*>(&tt);
 | |
| 
 | |
|     memcpy(ttp, &fResult.intVal, 8);
 | |
| 
 | |
|     // Note, this should probably be current date +/- time
 | |
|     if ((tt.hour > 23) && (!tt.is_neg))
 | |
|     {
 | |
|       day = tt.hour / 24;
 | |
|       tt.hour = tt.hour % 24;
 | |
|     }
 | |
|     else if ((tt.hour < 0) || (tt.is_neg))
 | |
|     {
 | |
|       tt.hour = 0;
 | |
|     }
 | |
| 
 | |
|     dataconvert::DateTime dt(0, 0, day, tt.hour, tt.minute, tt.second, tt.msecond);
 | |
|     memcpy(&fResult.intVal, &dt, 8);
 | |
|     return fResult.intVal;
 | |
|   }
 | |
|   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();
 | |
| }
 | |
| 
 | |
| inline int64_t TreeNode::getTimestampIntVal()
 | |
| {
 | |
|   if (fResultType.colDataType == execplan::CalpontSystemCatalog::TIMESTAMP)
 | |
|     return fResult.intVal;
 | |
|   else
 | |
|     return getIntVal();
 | |
| }
 | |
| 
 | |
| inline int64_t TreeNode::getTimeIntVal()
 | |
| {
 | |
|   if (fResultType.colDataType == execplan::CalpontSystemCatalog::DATETIME)
 | |
|   {
 | |
|     dataconvert::DateTime dt;
 | |
| 
 | |
|     memcpy((int64_t*)(&dt), &fResult.intVal, 8);
 | |
|     dataconvert::Time tt(0, dt.hour, dt.minute, dt.second, dt.msecond, false);
 | |
|     memcpy(&fResult.intVal, &tt, 8);
 | |
|     return fResult.intVal;
 | |
|   }
 | |
|   else if (fResultType.colDataType == execplan::CalpontSystemCatalog::TIME)
 | |
|     return (fResult.intVal);
 | |
|   else
 | |
|     return getIntVal();
 | |
| }
 | |
| 
 | |
| inline int32_t TreeNode::getDateIntVal()
 | |
| {
 | |
|   if (fResultType.colDataType == execplan::CalpontSystemCatalog::DATETIME)
 | |
|     return (((int32_t)(fResult.intVal >> 32) & 0xFFFFFFC0) | 0x3E);
 | |
|   else if (fResultType.colDataType == execplan::CalpontSystemCatalog::DATE)
 | |
|     return ((fResult.intVal & 0xFFFFFFC0) | 0x3E);
 | |
|   else
 | |
|     return getIntVal();
 | |
| }
 | |
| 
 | |
| typedef boost::shared_ptr<TreeNode> STNP;
 | |
| 
 | |
| /**
 | |
|  * Operations
 | |
|  */
 | |
| std::ostream& operator<<(std::ostream& output, const TreeNode& rhs);
 | |
| 
 | |
| }  // namespace execplan
 |