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 
			
		
		
		
	
		
			
				
	
	
		
			242 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* Copyright (C) 2022, 2023 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. */
 | 
						|
 | 
						|
// nullstring.h
 | 
						|
//
 | 
						|
// A class that can reprpesent string-with-NULL (special value not representable by a string value).
 | 
						|
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include <algorithm>
 | 
						|
#include <iostream>
 | 
						|
#include <memory>
 | 
						|
#include "exceptclasses.h"
 | 
						|
#include "conststring.h"
 | 
						|
#include "mcs_datatype_basic.h"
 | 
						|
 | 
						|
namespace utils
 | 
						|
{
 | 
						|
// A class for striings that can hold NULL values - a value that is separate from all possible string.
 | 
						|
class NullString
 | 
						|
{
 | 
						|
 protected:
 | 
						|
  std::shared_ptr<std::string> mStrPtr;
 | 
						|
 | 
						|
 public:
 | 
						|
  NullString() : mStrPtr(nullptr)
 | 
						|
  {
 | 
						|
  }
 | 
						|
  NullString(const char* str, size_t length)
 | 
						|
  {
 | 
						|
    idbassert(str != nullptr || length == 0);
 | 
						|
 | 
						|
    if (str)
 | 
						|
    {
 | 
						|
      mStrPtr.reset(new std::string((const char*)str, length));
 | 
						|
    }
 | 
						|
  }
 | 
						|
  // XXX: this constructor is used to construct NullString from char*. Please be
 | 
						|
  //      aware of that - std::string(nullptr) throws exception and you should check
 | 
						|
  //      for nullptr.
 | 
						|
  explicit NullString(const std::string& str) : mStrPtr(new std::string(str))
 | 
						|
  {
 | 
						|
  }
 | 
						|
  explicit NullString(const ConstString& str) : mStrPtr()
 | 
						|
  {
 | 
						|
    assign((const uint8_t*)str.str(), str.length());
 | 
						|
  }
 | 
						|
  ConstString toConstString() const
 | 
						|
  {
 | 
						|
    if (isNull())
 | 
						|
    {
 | 
						|
      return ConstString(nullptr, 0);
 | 
						|
    }
 | 
						|
    return ConstString(mStrPtr->c_str(), mStrPtr->length());
 | 
						|
  }
 | 
						|
  uint64_t toMCSUInt64() const
 | 
						|
  {
 | 
						|
    if (isNull())
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    const uint64_t val = static_cast<uint64_t>(strtoul(str(), 0, 0));
 | 
						|
    //@Bug 4632 and 4648: Don't return marker value for NULL, but allow return of marker value for EMPTYROW.
 | 
						|
    return val == joblist::UBIGINTNULL ? MAX_UBIGINT : val;
 | 
						|
  }
 | 
						|
  int64_t toMCSInt64() const
 | 
						|
  {
 | 
						|
    if (isNull())
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    const int64_t val = static_cast<int64_t>(atoll(str()));
 | 
						|
    //@Bug 4632 and 4648: Don't return marker value for NULL, but allow return of marker value for EMPTYROW.
 | 
						|
    return std::max(val, static_cast<int64_t>(joblist::BIGINTEMPTYROW));
 | 
						|
  }
 | 
						|
  const char* str() const
 | 
						|
  {
 | 
						|
    if (!mStrPtr)
 | 
						|
    {
 | 
						|
      return nullptr;
 | 
						|
    }
 | 
						|
    return mStrPtr->c_str();
 | 
						|
  }
 | 
						|
  const char* end() const
 | 
						|
  {
 | 
						|
    if (!mStrPtr)
 | 
						|
    {
 | 
						|
      return nullptr;
 | 
						|
    }
 | 
						|
    return str() + length();
 | 
						|
  }
 | 
						|
  size_t length() const
 | 
						|
  {
 | 
						|
    if (!mStrPtr)
 | 
						|
    {
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
    return mStrPtr->length();
 | 
						|
  }
 | 
						|
  std::string toString() const
 | 
						|
  {
 | 
						|
    idbassert(mStrPtr);
 | 
						|
    return std::string(*mStrPtr);
 | 
						|
  }
 | 
						|
  // "unsafe" means we do not check for NULL.
 | 
						|
  // it should be used after we know there is data in NullString.
 | 
						|
  const std::string& unsafeStringRef() const
 | 
						|
  {
 | 
						|
    idbassert(mStrPtr);
 | 
						|
    return (*mStrPtr);
 | 
						|
  }
 | 
						|
  bool eq(char ch) const
 | 
						|
  {
 | 
						|
    return length() == 1 && str()[0] == ch;
 | 
						|
  }
 | 
						|
  // this is SQL-like NULL handling equality. NULL will not be equal to anything, including NULL.
 | 
						|
  bool eq(const NullString& rhs) const
 | 
						|
  {
 | 
						|
    if (!rhs.mStrPtr)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    if (!mStrPtr)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    return *mStrPtr == *(rhs.mStrPtr);
 | 
						|
  }
 | 
						|
  NullString& rtrimZero()
 | 
						|
  {
 | 
						|
    return *this;  // TODO
 | 
						|
  }
 | 
						|
  // this can be used to safely get a string value, with default value for NULL substitution.
 | 
						|
  // it does not raise anything and provides some nonsensical default value for you that will be
 | 
						|
  // easy to find.
 | 
						|
  std::string safeString(const char* defaultValue = "<<<no default value for null provided>>>") const
 | 
						|
  {
 | 
						|
    if (!mStrPtr)
 | 
						|
    {
 | 
						|
      return std::string(defaultValue);
 | 
						|
    }
 | 
						|
    return std::string(*mStrPtr);
 | 
						|
  }
 | 
						|
  bool isNull() const
 | 
						|
  {
 | 
						|
    return !mStrPtr;
 | 
						|
  }
 | 
						|
  void resize(size_t newSize, char pad)
 | 
						|
  {
 | 
						|
    if (mStrPtr)
 | 
						|
    {
 | 
						|
      mStrPtr->resize(newSize, pad);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  NullString& dropString()
 | 
						|
  {
 | 
						|
    mStrPtr.reset();
 | 
						|
    return (*this);
 | 
						|
  }
 | 
						|
  void assign(const uint8_t* p, size_t len)
 | 
						|
  {
 | 
						|
    if (!p)
 | 
						|
    {
 | 
						|
      mStrPtr.reset();
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    mStrPtr.reset(new std::string((const char*)p, len));
 | 
						|
  }
 | 
						|
  void assign(const std::string& newVal)
 | 
						|
  {
 | 
						|
    mStrPtr.reset(new std::string(newVal));
 | 
						|
  }
 | 
						|
  // XXX: here we implement what Row::equals expects.
 | 
						|
  //      It is not SQL-NULL-handling compatible, please beware.
 | 
						|
  bool operator==(const NullString& a) const
 | 
						|
  {
 | 
						|
    if (!mStrPtr && !a.mStrPtr)
 | 
						|
    {
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
    if (!mStrPtr)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    if (!a.mStrPtr)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    // fall to std::string equality.
 | 
						|
    return (*mStrPtr) == (*a.mStrPtr);
 | 
						|
  }
 | 
						|
  bool operator==(const std::string& a) const
 | 
						|
  {
 | 
						|
    if (!mStrPtr)
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    // fall to std::string equality.
 | 
						|
    return (*mStrPtr) == a;
 | 
						|
  }
 | 
						|
  bool operator<(const NullString& a) const
 | 
						|
  {
 | 
						|
    // order NULLs first.
 | 
						|
    if (isNull() > a.isNull())
 | 
						|
    {
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
    if (isNull() < a.isNull())
 | 
						|
    {
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
    if (!isNull())
 | 
						|
    {
 | 
						|
      // fall to std::string equality.
 | 
						|
      return (*mStrPtr) < (*a.mStrPtr);
 | 
						|
    }
 | 
						|
    return false;  // both are NULLs.
 | 
						|
  }
 | 
						|
  bool operator>(const NullString& a) const
 | 
						|
  {
 | 
						|
    return a < (*this);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace utils.
 |