1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-04-18 21:44:02 +03:00
2023-03-02 15:59:42 +00:00

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