mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-04-18 21:44:02 +03:00
276 lines
9.9 KiB
C++
276 lines
9.9 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: func_inet_ntoa.cpp 3495 2013-01-21 14:09:51Z rdempsey $
|
|
*
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include <arpa/inet.h>
|
|
#include <netinet/in.h>
|
|
#include <iostream> // included when debugging
|
|
#include <sstream>
|
|
#include <climits>
|
|
|
|
#include "functor_str.h"
|
|
|
|
#include "calpontsystemcatalog.h"
|
|
#include "functioncolumn.h"
|
|
#include "joblisttypes.h"
|
|
#include "rowgroup.h"
|
|
|
|
namespace funcexp
|
|
{
|
|
//------------------------------------------------------------------------------
|
|
// The only accessor function that appears to make sense in conjunction with
|
|
// inet_ntoa() is getStrVal(). I tested in MySQL (outside infinidb), and
|
|
// comparing inet_ntoa(col) to anything other than a string "seemed" to return
|
|
// an empty set. So I implemented the other get functions to return a null.
|
|
//
|
|
// Later, Daniel found that if you compare inet_ntoa(col) to an integer (ex: 1)
|
|
// or a double (ex: 1.1), that the getDoubleVal() version of inet_ntoa(col),
|
|
// will get called. As stated in previous paragraph, I thought I tested this,
|
|
// but I apparently overlooked something. So getIntVal() and getDoubleVal()
|
|
// are now implemented.
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Return input argument type.
|
|
// See mcs_add in udfsdk.h for explanation of this function.
|
|
//------------------------------------------------------------------------------
|
|
execplan::CalpontSystemCatalog::ColType Func_inet_ntoa::operationType(
|
|
FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType)
|
|
{
|
|
return fp[0]->data()->resultType(); // input type
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Return IP address as a long long int value.
|
|
// Not sure this is ever called, but emulated getDoubleVal() implementation,
|
|
// to be safe. (See getDoubleVal() description)
|
|
//------------------------------------------------------------------------------
|
|
int64_t Func_inet_ntoa::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
|
|
execplan::CalpontSystemCatalog::ColType& op_ct)
|
|
{
|
|
// std::cout << "In Func_inet_ntoa::getIntVal" << std::endl;
|
|
|
|
std::string sValue = getStrVal(row, fp, isNull, op_ct);
|
|
int64_t iValue = joblist::NULL_INT64;
|
|
|
|
if (!isNull)
|
|
{
|
|
unsigned int newLength = sValue.length();
|
|
std::string::size_type dot1 = sValue.find('.');
|
|
|
|
if (dot1 != std::string::npos)
|
|
{
|
|
newLength = dot1;
|
|
}
|
|
|
|
if (newLength != sValue.length())
|
|
sValue.resize(newLength);
|
|
|
|
std::istringstream iss(sValue);
|
|
iss >> iValue;
|
|
}
|
|
|
|
return iValue;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Return IP address as a double value.
|
|
// SELECT ... WHERE inet_ntoa(ipstring) = 1.1 will call getDoubleVal()
|
|
// SELECT ... WHERE inet_ntoa(ipstring) = 1 will also call getDoubleVal()
|
|
//------------------------------------------------------------------------------
|
|
double Func_inet_ntoa::getDoubleVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
|
|
execplan::CalpontSystemCatalog::ColType& op_ct)
|
|
{
|
|
// std::cout << "In Func_inet_ntoa::getDoubleVal" << std::endl;
|
|
|
|
std::string sValue = getStrVal(row, fp, isNull, op_ct);
|
|
double dValue = doubleNullVal();
|
|
|
|
if (!isNull)
|
|
{
|
|
unsigned int newLength = sValue.length();
|
|
std::string::size_type dot1 = sValue.find('.');
|
|
|
|
if ((dot1 != std::string::npos) && (sValue.length() > dot1 + 1))
|
|
{
|
|
std::string::size_type dot2 = sValue.find('.', dot1 + 1);
|
|
|
|
if (dot2 != std::string::npos)
|
|
{
|
|
newLength = dot2;
|
|
}
|
|
}
|
|
|
|
if (newLength != sValue.length())
|
|
sValue.resize(newLength);
|
|
|
|
std::istringstream iss(sValue);
|
|
iss >> dValue;
|
|
}
|
|
|
|
return dValue;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Return IP address as a string value.
|
|
// This is the get function that makes sense to use.
|
|
//------------------------------------------------------------------------------
|
|
std::string Func_inet_ntoa::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
|
|
execplan::CalpontSystemCatalog::ColType& op_ct)
|
|
{
|
|
// std::cout << "In Func_inet_ntoa::getStrVal" << std::endl;
|
|
|
|
std::string sValue;
|
|
|
|
int64_t iValue = 0;
|
|
|
|
// @bug 3628 reopened: get double and round up, if necessary;
|
|
// else just get integer value
|
|
if ((fp[0]->data()->resultType().colDataType == execplan::CalpontSystemCatalog::DECIMAL) ||
|
|
(fp[0]->data()->resultType().colDataType == execplan::CalpontSystemCatalog::UDECIMAL) ||
|
|
(fp[0]->data()->resultType().colDataType == execplan::CalpontSystemCatalog::FLOAT) ||
|
|
(fp[0]->data()->resultType().colDataType == execplan::CalpontSystemCatalog::DOUBLE))
|
|
{
|
|
double d = fp[0]->data()->getDoubleVal(row, isNull);
|
|
|
|
if (d >= 0.0)
|
|
iValue = (int64_t)(d + 0.5);
|
|
else
|
|
iValue = (int64_t)(d - 0.5);
|
|
}
|
|
else
|
|
{
|
|
iValue = fp[0]->data()->getIntVal(row, isNull);
|
|
}
|
|
|
|
if (!isNull)
|
|
{
|
|
// @bug 3628 reopened: add check for out of range values
|
|
if ((iValue < 0) || (iValue > UINT_MAX))
|
|
isNull = true;
|
|
else
|
|
convertNtoa(iValue, sValue);
|
|
}
|
|
|
|
return sValue;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Return IP address as a boolean.
|
|
// N/A so returning null. See explanation at the top of this source file.
|
|
//------------------------------------------------------------------------------
|
|
bool Func_inet_ntoa::getBoolVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
|
|
execplan::CalpontSystemCatalog::ColType& op_ct)
|
|
{
|
|
// std::cout << "In Func_inet_ntoa::getBoolVal" << std::endl;
|
|
bool bValue = false;
|
|
isNull = true;
|
|
|
|
return bValue;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Return IP address as a decimal value.
|
|
// N/A so returning null. See explanation at the top of this source file.
|
|
//------------------------------------------------------------------------------
|
|
execplan::IDB_Decimal Func_inet_ntoa::getDecimalVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
|
|
execplan::CalpontSystemCatalog::ColType& op_ct)
|
|
{
|
|
// IDB_Decimal dValue = fp[0]->data()->getDecimalVal(row, isNull);
|
|
execplan::IDB_Decimal dValue(joblist::NULL_INT64, 0, 0);
|
|
isNull = true;
|
|
|
|
return dValue;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Return IP address as a date.
|
|
// N/A so returning null. See explanation at the top of this source file.
|
|
//------------------------------------------------------------------------------
|
|
int32_t Func_inet_ntoa::getDateIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
|
|
execplan::CalpontSystemCatalog::ColType& op_ct)
|
|
{
|
|
// std::cout << "In Func_inet_ntoa::getDateIntVal" << std::endl;
|
|
|
|
// int32_t iValue = fp[0]->data()->getDateIntVal(row, isNull);
|
|
int32_t iValue = joblist::DATENULL;
|
|
isNull = true;
|
|
|
|
return iValue;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Return IP address as a date/time.
|
|
// N/A so returning null. See explanation at the top of this source file.
|
|
//------------------------------------------------------------------------------
|
|
int64_t Func_inet_ntoa::getDatetimeIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
|
|
execplan::CalpontSystemCatalog::ColType& op_ct)
|
|
{
|
|
// std::cout << "In Func_inet_ntoa::getDatetimeVal" << std::endl;
|
|
|
|
// int64t iValue = fp[0]->data()->getDatetimeIntVal(row, isNull);
|
|
int64_t iValue = joblist::DATETIMENULL;
|
|
isNull = true;
|
|
|
|
return iValue;
|
|
}
|
|
|
|
int64_t Func_inet_ntoa::getTimestampIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
|
|
execplan::CalpontSystemCatalog::ColType& op_ct)
|
|
{
|
|
// std::cout << "In Func_inet_ntoa::getTimestampVal" << std::endl;
|
|
|
|
// int64t iValue = fp[0]->data()->getTimestampIntVal(row, isNull);
|
|
int64_t iValue = joblist::TIMESTAMPNULL;
|
|
isNull = true;
|
|
|
|
return iValue;
|
|
}
|
|
|
|
int64_t Func_inet_ntoa::getTimeIntVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull,
|
|
execplan::CalpontSystemCatalog::ColType& op_ct)
|
|
{
|
|
// std::cout << "In Func_inet_ntoa::getTimeVal" << std::endl;
|
|
|
|
// int64t iValue = fp[0]->data()->getTimeIntVal(row, isNull);
|
|
int64_t iValue = joblist::TIMENULL;
|
|
isNull = true;
|
|
|
|
return iValue;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Convert an integer IP address to its equivalent IP address string.
|
|
// Source code based on MySQL source (Item_func_inet_ntoa() in item_strfunc.cc).
|
|
//------------------------------------------------------------------------------
|
|
void Func_inet_ntoa::convertNtoa(int64_t ipNum, std::string& ipString)
|
|
{
|
|
struct sockaddr_in sa;
|
|
sa.sin_addr.s_addr = htonl(ipNum);
|
|
|
|
// now get it back and print it
|
|
char str[INET_ADDRSTRLEN];
|
|
ipString = inet_ntop(AF_INET, &(sa.sin_addr), str, INET_ADDRSTRLEN);
|
|
}
|
|
|
|
} // namespace funcexp
|