You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-11-03 17:13:17 +03:00 
			
		
		
		
	a workaround for something that looks like a bug in a compiler.
Fixes errors like
In file included from /usr/include/c++/12/string:40,
                 from /mnt/server/storage/columnstore/columnstore/utils/funcexp/func_math.cpp:26:
In static member function ‘static constexpr std::char_traits<char>::char_type* std::char_traits<char>::copy(char_type*, const char_type*, std::size_t)’,
    inlined from ‘static constexpr void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_S_copy(_CharT*, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:423:21,
    inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Allocator>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_M_replace(size_type, size_type, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.tcc:532:22,
    inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::replace(size_type, size_type, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:2171:19,
    inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::insert(size_type, const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ at /usr/include/c++/12/bits/basic_string.h:1928:22,
    inlined from ‘virtual std::string funcexp::Func_format::getStrVal(rowgroup::Row&, funcexp::FunctionParm&, bool&, execplan::CalpontSystemCatalog::ColType&)’ at /mnt/server/storage/columnstore/columnstore/utils/funcexp/func_math.cpp:2008:17:
/usr/include/c++/12/bits/char_traits.h:431:56: error: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ accessing 9223372036854775810 or more bytes at offsets 3 and [2, 2147483645] may overlap up to 9223372036854775813 bytes at offset -3 [-Werror=restrict]
  431 |         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n );
$ gcc --version
gcc (Ubuntu 12.2.0-3ubuntu1) 12.2.0
		
	
		
			
				
	
	
		
			354 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			354 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* Copyright (C) 2014 InfiniDB, Inc.
 | 
						|
 | 
						|
   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: operator.cpp 9210 2013-01-21 14:10:42Z rdempsey $
 | 
						|
 *
 | 
						|
 *
 | 
						|
 ***********************************************************************/
 | 
						|
#include <iostream>
 | 
						|
#include <sstream>
 | 
						|
 | 
						|
#include "bytestream.h"
 | 
						|
#include "operator.h"
 | 
						|
#include "objectreader.h"
 | 
						|
 | 
						|
using namespace std;
 | 
						|
 | 
						|
namespace
 | 
						|
{
 | 
						|
/**@brief util struct for converting string to lower case */
 | 
						|
struct to_lower
 | 
						|
{
 | 
						|
  char operator()(char c) const
 | 
						|
  {
 | 
						|
    return tolower(c);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
// Trim any leading/trailing ws
 | 
						|
const string lrtrim(const string& in)
 | 
						|
{
 | 
						|
  string::size_type p1;
 | 
						|
  p1 = in.find_first_not_of(" \t\n");
 | 
						|
 | 
						|
  if (p1 == string::npos)
 | 
						|
    p1 = 0;
 | 
						|
 | 
						|
  string::size_type p2;
 | 
						|
  p2 = in.find_last_not_of(" \t\n");
 | 
						|
 | 
						|
  if (p2 == string::npos)
 | 
						|
    p2 = in.size() - 1;
 | 
						|
 | 
						|
  return string(in, p1, (p2 - p1 + 1));
 | 
						|
}
 | 
						|
 | 
						|
}  // namespace
 | 
						|
 | 
						|
namespace execplan
 | 
						|
{
 | 
						|
/**
 | 
						|
 * Constructors/Destructors
 | 
						|
 */
 | 
						|
Operator::Operator()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
Operator::Operator(const string& operatorName)
 | 
						|
{
 | 
						|
  data(operatorName);
 | 
						|
}
 | 
						|
 | 
						|
Operator::Operator(const Operator& rhs) : TreeNode(rhs), fOp(rhs.op())
 | 
						|
{
 | 
						|
  data(rhs.fData);
 | 
						|
}
 | 
						|
 | 
						|
Operator::~Operator()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Operations
 | 
						|
 */
 | 
						|
void Operator::data(const string data)
 | 
						|
{
 | 
						|
  fData = lrtrim(data);
 | 
						|
  transform(fData.begin(), fData.end(), fData.begin(), to_lower());
 | 
						|
 | 
						|
  if (fData == "+")
 | 
						|
  {
 | 
						|
    fOp = OP_ADD;
 | 
						|
  }
 | 
						|
  else if (fData == "-")
 | 
						|
  {
 | 
						|
    fOp = OP_SUB;
 | 
						|
  }
 | 
						|
  else if (fData == "*")
 | 
						|
  {
 | 
						|
    fOp = OP_MUL;
 | 
						|
  }
 | 
						|
  else if (fData == "/")
 | 
						|
  {
 | 
						|
    fOp = OP_DIV;
 | 
						|
  }
 | 
						|
  else if (fData == "=")
 | 
						|
  {
 | 
						|
    fOp = OP_EQ;
 | 
						|
  }
 | 
						|
  else if (fData == "!=" || fData == "<>")
 | 
						|
  {
 | 
						|
    fOp = OP_NE;
 | 
						|
  }
 | 
						|
  else if (fData == ">")
 | 
						|
  {
 | 
						|
    fOp = OP_GT;
 | 
						|
  }
 | 
						|
  else if (fData == ">=")
 | 
						|
  {
 | 
						|
    fOp = OP_GE;
 | 
						|
  }
 | 
						|
  else if (fData == "<")
 | 
						|
  {
 | 
						|
    fOp = OP_LT;
 | 
						|
  }
 | 
						|
  else if (fData == "<=")
 | 
						|
  {
 | 
						|
    fOp = OP_LE;
 | 
						|
  }
 | 
						|
  else if (fData == "and")
 | 
						|
  {
 | 
						|
    fOp = OP_AND;
 | 
						|
  }
 | 
						|
  else if (fData == "or")
 | 
						|
  {
 | 
						|
    fOp = OP_OR;
 | 
						|
  }
 | 
						|
  else if (fData == "like")
 | 
						|
  {
 | 
						|
    fOp = OP_LIKE;
 | 
						|
  }
 | 
						|
  else if (fData == "not like")
 | 
						|
  {
 | 
						|
    fOp = OP_NOTLIKE;
 | 
						|
    fData = "not like";
 | 
						|
  }
 | 
						|
  else if (fData == "isnull")
 | 
						|
  {
 | 
						|
    fOp = OP_ISNULL;
 | 
						|
    fData = "is null";
 | 
						|
  }
 | 
						|
  else if (fData == "isnotnull")
 | 
						|
  {
 | 
						|
    fOp = OP_ISNOTNULL;
 | 
						|
    fData = "is not null";
 | 
						|
  }
 | 
						|
  else if (fData == "xor")
 | 
						|
  {
 | 
						|
    fOp = OP_XOR;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    fOp = OP_UNKNOWN;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
const string Operator::toString() const
 | 
						|
{
 | 
						|
  ostringstream oss;
 | 
						|
  oss << string("Operator: " + fData) << " fOp=" << fOp;
 | 
						|
  oss << " "
 | 
						|
      << "opType=" << fOperationType.colDataType;
 | 
						|
  return oss.str();
 | 
						|
}
 | 
						|
 | 
						|
string Operator::toCppCode(IncludeSet& includes) const
 | 
						|
{
 | 
						|
  includes.insert("operator.h");
 | 
						|
  stringstream ss;
 | 
						|
  ss << "Operator(" << std::quoted(fData) << ")";
 | 
						|
 | 
						|
  return ss.str();
 | 
						|
}
 | 
						|
 | 
						|
Operator* Operator::opposite() const
 | 
						|
{
 | 
						|
  if (fData.compare(">") == 0)
 | 
						|
    return new Operator("<");
 | 
						|
 | 
						|
  if (fData.compare("<") == 0)
 | 
						|
    return new Operator(">");
 | 
						|
 | 
						|
  if (fData.compare(">=") == 0)
 | 
						|
    return new Operator("<=");
 | 
						|
 | 
						|
  if (fData.compare("<=") == 0)
 | 
						|
    return new Operator(">=");
 | 
						|
 | 
						|
  return this->clone();
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * friend function
 | 
						|
 */
 | 
						|
ostream& operator<<(ostream& output, const Operator& rhs)
 | 
						|
{
 | 
						|
  output << rhs.toString();
 | 
						|
  return output;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * The serialization interface
 | 
						|
 */
 | 
						|
void Operator::serialize(messageqcpp::ByteStream& b) const
 | 
						|
{
 | 
						|
  b << (ObjectReader::id_t)ObjectReader::OPERATOR;
 | 
						|
  b << fData;
 | 
						|
  fResultType.serialize(b);
 | 
						|
  fOperationType.serialize(b);
 | 
						|
  b << (uint32_t)fOp;
 | 
						|
}
 | 
						|
 | 
						|
void Operator::unserialize(messageqcpp::ByteStream& b)
 | 
						|
{
 | 
						|
  uint32_t val;
 | 
						|
  ObjectReader::checkType(b, ObjectReader::OPERATOR);
 | 
						|
  b >> fData;
 | 
						|
  fResultType.unserialize(b);
 | 
						|
  fOperationType.unserialize(b);
 | 
						|
 | 
						|
  b >> (uint32_t&)val;
 | 
						|
  fOp = (OpType)val;
 | 
						|
 | 
						|
  fResult.decimalVal.scale = fResultType.scale;
 | 
						|
  fResult.decimalVal.precision = fResultType.precision;
 | 
						|
}
 | 
						|
 | 
						|
bool Operator::operator==(const Operator& t) const
 | 
						|
{
 | 
						|
  if (fOp == t.fOp)
 | 
						|
    return true;
 | 
						|
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
bool Operator::operator==(const TreeNode* t) const
 | 
						|
{
 | 
						|
  const Operator* o;
 | 
						|
 | 
						|
  o = dynamic_cast<const Operator*>(t);
 | 
						|
 | 
						|
  if (o == NULL)
 | 
						|
    return false;
 | 
						|
 | 
						|
  return *this == *o;
 | 
						|
}
 | 
						|
 | 
						|
bool Operator::operator!=(const Operator& t) const
 | 
						|
{
 | 
						|
  return (!(*this == t));
 | 
						|
}
 | 
						|
 | 
						|
bool Operator::operator!=(const TreeNode* t) const
 | 
						|
{
 | 
						|
  return (!(*this == t));
 | 
						|
}
 | 
						|
 | 
						|
void Operator::reverseOp()
 | 
						|
{
 | 
						|
  switch (fOp)
 | 
						|
  {
 | 
						|
    case OP_EQ:
 | 
						|
      fOp = OP_NE;
 | 
						|
      fData = "!=";
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_NE:
 | 
						|
      fOp = OP_EQ;
 | 
						|
      fData = '=';
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_GT:
 | 
						|
      fOp = OP_LT;
 | 
						|
      fData = '<';
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_GE:
 | 
						|
      fOp = OP_LE;
 | 
						|
      fData = "<=";
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_LT:
 | 
						|
      fOp = OP_GT;
 | 
						|
      fData = '>';
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_LE:
 | 
						|
      fOp = OP_GE;
 | 
						|
      fData = ">=";
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_LIKE:
 | 
						|
      fOp = OP_NOTLIKE;
 | 
						|
      fData = "not like";
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_NOTLIKE:
 | 
						|
      fOp = OP_LIKE;
 | 
						|
      fData = "like";
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_ISNULL:
 | 
						|
      fOp = OP_ISNOTNULL;
 | 
						|
      fData = "isnotnull";
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_ISNOTNULL:
 | 
						|
      fOp = OP_ISNULL;
 | 
						|
      fData = "isnull";
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_BETWEEN:
 | 
						|
      fOp = OP_NOTBETWEEN;
 | 
						|
      fData = "not between";
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_NOTBETWEEN:
 | 
						|
      fOp = OP_BETWEEN;
 | 
						|
      fData = "between";
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_IN:
 | 
						|
      fOp = OP_NOTIN;
 | 
						|
      fData = "not in";
 | 
						|
      break;
 | 
						|
 | 
						|
    case OP_NOTIN:
 | 
						|
      fOp = OP_IN;
 | 
						|
      fData = "in";
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      fOp = OP_UNKNOWN;
 | 
						|
      fData = "unknown";
 | 
						|
      break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
}  // namespace execplan
 |