Skip to content

Commit

Permalink
Formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
mohsaka committed Jun 21, 2024
1 parent 78950bb commit 22f8e70
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 112 deletions.
3 changes: 1 addition & 2 deletions velox/expression/tests/CustomTypeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,7 @@ TEST_F(CustomTypeTest, getCustomTypeNames) {
"TIMESTAMP WITH TIME ZONE",
"UUID",
"IPADDRESS",
"IPPREFIX"
}),
"IPPREFIX"}),
names);

ASSERT_TRUE(registerCustomType(
Expand Down
46 changes: 24 additions & 22 deletions velox/functions/prestosql/IPAddressFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@

#include "velox/functions/Macros.h"
#include "velox/functions/Registerer.h"
#include "velox/functions/prestosql/types/UuidType.h"
#include "velox/functions/lib/string/StringImpl.h"
#include "velox/functions/prestosql/types/IPAddressType.h"
#include "velox/functions/prestosql/types/IPPrefixType.h"
#include "velox/functions/lib/string/StringImpl.h"
#include "velox/functions/prestosql/types/UuidType.h"

#include <iostream>

Expand All @@ -43,51 +43,53 @@ struct IPAddressFunction {
boost::uuids::random_generator generator_;
};


template <typename T>
struct IPPrefixFunction {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE void call(out_type<TheIPPrefix>& result,
const arg_type<IPAddress>& ip,
const arg_type<int8_t> prefixBits) {

FOLLY_ALWAYS_INLINE void call(
out_type<TheIPPrefix>& result,
const arg_type<IPAddress>& ip,
const arg_type<int8_t> prefixBits) {
boost::asio::ip::address_v6::bytes_type addrBytes;
memcpy(&addrBytes, &ip, 16);

// All IPs are stored as V6
auto v6Addr = boost::asio::ip::make_address_v6(addrBytes);
boost::asio::ip::address_v6 v6CanonicalAddr;

//For return
// For return
int128_t canonicalAddrInt;

// Presto stores prefixBits in one byte. Cast to unsigned
// Convert to V4/V6 respectively and create network to get canonical
// address as well as check validity of the prefix.
if(v6Addr.is_v4_mapped()){
auto v4Addr = boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, v6Addr);
auto v4Network = boost::asio::ip::make_network_v4(v4Addr, (uint8_t)prefixBits);
v6CanonicalAddr = boost::asio::ip::make_address_v6(boost::asio::ip::v4_mapped, v4Network.canonical().address());
}else{
auto v6Network = boost::asio::ip::make_network_v6(v6Addr, (uint8_t)prefixBits);
v6CanonicalAddr = v6Network.canonical().address();
if (v6Addr.is_v4_mapped()) {
auto v4Addr =
boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, v6Addr);
auto v4Network =
boost::asio::ip::make_network_v4(v4Addr, (uint8_t)prefixBits);
v6CanonicalAddr = boost::asio::ip::make_address_v6(
boost::asio::ip::v4_mapped, v4Network.canonical().address());
} else {
auto v6Network =
boost::asio::ip::make_network_v6(v6Addr, (uint8_t)prefixBits);
v6CanonicalAddr = v6Network.canonical().address();
}

auto canonicalBytes = v6CanonicalAddr.to_bytes();
memcpy(&canonicalAddrInt, &canonicalBytes, 16);

result = std::make_shared<IPPrefix>(canonicalAddrInt, (uint8_t)prefixBits);
}
};

result = std::make_shared<IPPrefix>(canonicalAddrInt, (uint8_t)prefixBits);
}
};

inline void registerIPAddressFunctions(const std::string& prefix) {
registerIPAddressType();
registerIPPrefixType();
registerFunction<IPAddressFunction, IPAddress>({prefix + "ipaddress"});
registerFunction<IPPrefixFunction, TheIPPrefix, IPAddress, int8_t>({prefix + "ip_prefix"});

registerFunction<IPPrefixFunction, TheIPPrefix, IPAddress, int8_t>(
{prefix + "ip_prefix"});
}

} // namespace facebook::velox::functions
7 changes: 3 additions & 4 deletions velox/functions/prestosql/TypeOf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
*/
#include "velox/expression/VectorFunction.h"
#include "velox/functions/prestosql/types/HyperLogLogType.h"
#include "velox/functions/prestosql/types/IPAddressType.h"
#include "velox/functions/prestosql/types/IPPrefixType.h"
#include "velox/functions/prestosql/types/JsonType.h"
#include "velox/functions/prestosql/types/TimestampWithTimeZoneType.h"
#include "velox/functions/prestosql/types/UuidType.h"
#include "velox/functions/prestosql/types/IPAddressType.h"
#include "velox/functions/prestosql/types/IPPrefixType.h"

namespace facebook::velox::functions {
namespace {
Expand Down Expand Up @@ -56,8 +56,7 @@ std::string typeName(const TypePtr& type) {
case TypeKind::HUGEINT: {
if (isUuidType(type)) {
return "uuid";
}
else if (isIPAddressType(type)) {
} else if (isIPAddressType(type)) {
return "ipaddress";
}
VELOX_USER_CHECK(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* limitations under the License.
*/
#include <string>
#include "velox/functions/prestosql/UuidFunctions.h"
#include "velox/functions/prestosql/IPAddressFunctions.h"
#include "velox/functions/prestosql/UuidFunctions.h"

namespace facebook::velox::functions {

Expand Down
102 changes: 60 additions & 42 deletions velox/functions/prestosql/tests/IPAddressFunctionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ namespace facebook::velox::functions::prestosql {
namespace {

class IPAddressTest : public functions::test::FunctionBaseTest {
protected:
std::optional<std::string> getIPPrefix(const std::optional<std::string> input, std::optional<int8_t> mask) {
auto result = evaluateOnce<std::string>("cast(ip_prefix(cast(c0 as ipaddress), c1) as varchar)", input, mask);
protected:
std::optional<std::string> getIPPrefix(
const std::optional<std::string> input,
std::optional<int8_t> mask) {
auto result = evaluateOnce<std::string>(
"cast(ip_prefix(cast(c0 as ipaddress), c1) as varchar)", input, mask);
return result;
}
};
Expand All @@ -43,65 +46,80 @@ TEST_F(IPAddressTest, castAsVarchar) {
}

TEST_F(IPAddressTest, castRoundTrip) {
auto strings = makeFlatVector<std::string>({
"87a0:ce14:8989:44c9:826e:b4d8:73f9:1542",
"7cd6:bcec:1216:5c20:4b67:b1bd:173:ced",
"192.128.0.0"
});

auto ipaddresses = evaluate("cast(c0 as ipaddress)", makeRowVector({strings}));
auto stringsCopy = evaluate("cast(c0 as varchar)", makeRowVector({ipaddresses}));
auto ipaddressesCopy = evaluate("cast(c0 as ipaddress)", makeRowVector({stringsCopy}));
auto strings = makeFlatVector<std::string>(
{"87a0:ce14:8989:44c9:826e:b4d8:73f9:1542",
"7cd6:bcec:1216:5c20:4b67:b1bd:173:ced",
"192.128.0.0"});

auto ipaddresses =
evaluate("cast(c0 as ipaddress)", makeRowVector({strings}));
auto stringsCopy =
evaluate("cast(c0 as varchar)", makeRowVector({ipaddresses}));
auto ipaddressesCopy =
evaluate("cast(c0 as ipaddress)", makeRowVector({stringsCopy}));

velox::test::assertEqualVectors(strings, stringsCopy);
velox::test::assertEqualVectors(ipaddresses, ipaddressesCopy);
}

TEST_F(IPAddressTest, IPPrefixv4) {

EXPECT_EQ("10.0.0.0/8", getIPPrefix("10.135.23.12",8));
EXPECT_EQ("10.0.0.0/8", getIPPrefix("10.135.23.12", 8));
EXPECT_EQ("192.128.0.0/9", getIPPrefix("192.168.255.255", 9));
EXPECT_EQ("192.168.255.255/32", getIPPrefix("192.168.255.255",32));
EXPECT_EQ("0.0.0.0/0", getIPPrefix("192.168.255.255",0));

EXPECT_THROW(getIPPrefix("12.483.09.1",8), VeloxUserError);
EXPECT_THROW(getIPPrefix("10.135.23.12.12",8), VeloxUserError);
EXPECT_THROW(getIPPrefix("10.135.23",8), VeloxUserError);
EXPECT_THROW(getIPPrefix("12.135.23.12",-1), VeloxUserError);
EXPECT_THROW(getIPPrefix("10.135.23.12",33), VeloxUserError);
EXPECT_EQ("192.168.255.255/32", getIPPrefix("192.168.255.255", 32));
EXPECT_EQ("0.0.0.0/0", getIPPrefix("192.168.255.255", 0));

EXPECT_THROW(getIPPrefix("12.483.09.1", 8), VeloxUserError);
EXPECT_THROW(getIPPrefix("10.135.23.12.12", 8), VeloxUserError);
EXPECT_THROW(getIPPrefix("10.135.23", 8), VeloxUserError);
EXPECT_THROW(getIPPrefix("12.135.23.12", -1), VeloxUserError);
EXPECT_THROW(getIPPrefix("10.135.23.12", 33), VeloxUserError);
}

TEST_F(IPAddressTest, IPPrefixv6) {
EXPECT_EQ("2001:db8:85a3::/48", getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", 48));
EXPECT_EQ("2001:db8:85a3::/52", getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", 52));
EXPECT_EQ("2001:db8:85a3:1:1:8a2e:370:7334/128", getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", 128));
EXPECT_EQ(
"2001:db8:85a3::/48",
getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", 48));
EXPECT_EQ(
"2001:db8:85a3::/52",
getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", 52));
EXPECT_EQ(
"2001:db8:85a3:1:1:8a2e:370:7334/128",
getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", 128));
EXPECT_EQ("::/0", getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", 0));

EXPECT_THROW(getIPPrefix("q001:0db8:85a3:0001:0001:8a2e:0370:7334", 8), VeloxUserError);
EXPECT_THROW(getIPPrefix("2001:0db8:85a3:542e:0001:0001:8a2e:0370:7334", 8), VeloxUserError);
EXPECT_THROW(getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370", 8), VeloxUserError);
EXPECT_THROW(getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", -1), VeloxUserError);
EXPECT_THROW(getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", 140), VeloxUserError);

EXPECT_THROW(
getIPPrefix("q001:0db8:85a3:0001:0001:8a2e:0370:7334", 8),
VeloxUserError);
EXPECT_THROW(
getIPPrefix("2001:0db8:85a3:542e:0001:0001:8a2e:0370:7334", 8),
VeloxUserError);
EXPECT_THROW(
getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370", 8), VeloxUserError);
EXPECT_THROW(
getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", -1),
VeloxUserError);
EXPECT_THROW(
getIPPrefix("2001:0db8:85a3:0001:0001:8a2e:0370:7334", 140),
VeloxUserError);
}

TEST_F(IPAddressTest, castRoundTripPrefix) {
auto strings = makeFlatVector<std::string>({
"87a0:ce14:8989:44c9:826e:b4d8:73f9:1542/48",
"7cd6:bcec:1216:5c20:4b67:b1bd:173:ced/5",
"192.128.0.0/5"
});
auto strings = makeFlatVector<std::string>(
{"87a0:ce14:8989:44c9:826e:b4d8:73f9:1542/48",
"7cd6:bcec:1216:5c20:4b67:b1bd:173:ced/5",
"192.128.0.0/5"});

auto ipprefixes = evaluate("cast(c0 as ipprefix)", makeRowVector({strings}));
auto stringsCopy = evaluate("cast(c0 as varchar)", makeRowVector({ipprefixes}));
auto ipprefixesCopy = evaluate("cast(c0 as ipprefix)", makeRowVector({stringsCopy}));
auto stringsCopy =
evaluate("cast(c0 as varchar)", makeRowVector({ipprefixes}));
auto ipprefixesCopy =
evaluate("cast(c0 as ipprefix)", makeRowVector({stringsCopy}));

// assertEqualVectors are comparing the shared pointers so cannot compare
// assertEqualVectors are comparing the shared pointers so cannot compare
// ipprefixes and ipprefixesCopy
velox::test::assertEqualVectors(strings, stringsCopy);

}

}
} // namespace

}
} // namespace facebook::velox::functions::prestosql
3 changes: 2 additions & 1 deletion velox/functions/prestosql/tests/ProbabilityTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,8 @@ TEST_F(ProbabilityTest, inverseNormalCDF) {
VELOX_ASSERT_THROW(inverseNormalCDF(0, 1, kDoubleMax), "p must be 0 > p > 1");
VELOX_ASSERT_THROW(
inverseNormalCDF(0, 1, kDoubleMin),
"Error in function boost::math::erf_inv<double>(double, double): Overflow Error");
"Error in function boost::math::erf_inv<double>(double, double): Overflow
Error");
VELOX_ASSERT_THROW(
inverseNormalCDF(0, 0, 0.1985), "standardDeviation must be > 0");
Expand Down
26 changes: 16 additions & 10 deletions velox/functions/prestosql/types/IPAddressType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class IPAddressCastOperator : public exec::CastOperator {
castFromString(input, context, rows, *result);
} else {
VELOX_UNSUPPORTED(
"Cast from {} to IPAddress not yet supported", resultType->toString());
"Cast from {} to IPAddress not yet supported",
resultType->toString());
}
}

Expand All @@ -59,7 +60,8 @@ class IPAddressCastOperator : public exec::CastOperator {
castToString(input, context, rows, *result);
} else {
VELOX_UNSUPPORTED(
"Cast from IPAddress to {} not yet supported", resultType->toString());
"Cast from IPAddress to {} not yet supported",
resultType->toString());
}
}

Expand All @@ -80,10 +82,11 @@ class IPAddressCastOperator : public exec::CastOperator {

auto v6Addr = boost::asio::ip::make_address_v6(addrBytes);

if(v6Addr.is_v4_mapped()){
auto v4Addr = boost::asio::ip::make_address_v4(boost::asio::ip::v4_mapped, v6Addr);
if (v6Addr.is_v4_mapped()) {
auto v4Addr = boost::asio::ip::make_address_v4(
boost::asio::ip::v4_mapped, v6Addr);
s = boost::lexical_cast<std::string>(v4Addr);
}else{
} else {
s = boost::lexical_cast<std::string>(v6Addr);
}

Expand All @@ -104,11 +107,13 @@ class IPAddressCastOperator : public exec::CastOperator {
context.applyToSelectedNoThrow(rows, [&](auto row) {
const auto ipAddressString = ipAddressStrings->valueAt(row);
boost::asio::ip::address_v6::bytes_type addrBytes;
auto addr = boost::asio::ip::make_address(ipAddressString);
auto addr = boost::asio::ip::make_address(ipAddressString);
int128_t intAddr;
if(addr.is_v4()){
addrBytes = boost::asio::ip::make_address_v6(boost::asio::ip::v4_mapped, addr.to_v4()).to_bytes();
}else{
if (addr.is_v4()) {
addrBytes = boost::asio::ip::make_address_v6(
boost::asio::ip::v4_mapped, addr.to_v4())
.to_bytes();
} else {
addrBytes = addr.to_v6().to_bytes();
}

Expand All @@ -135,7 +140,8 @@ class IPAddressTypeFactories : public CustomTypeFactories {
} // namespace

void registerIPAddressType() {
registerCustomType("ipaddress", std::make_unique<const IPAddressTypeFactories>());
registerCustomType(
"ipaddress", std::make_unique<const IPAddressTypeFactories>());
}

} // namespace facebook::velox
13 changes: 7 additions & 6 deletions velox/functions/prestosql/types/IPAddressType.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
*/
#pragma once

#include "velox/expression/CastExpr.h"
#include "velox/type/SimpleFunctionApi.h"
#include "velox/type/Type.h"
#include <folly/IPAddress.h>
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/network_v4.hpp>
#include <boost/asio/ip/network_v6.hpp>
#include <boost/asio/ip/address.hpp>
#include <boost/lexical_cast.hpp>
#include <folly/IPAddress.h>
#include "velox/expression/CastExpr.h"
#include "velox/type/SimpleFunctionApi.h"
#include "velox/type/Type.h"

namespace facebook::velox {

Expand All @@ -35,7 +35,8 @@ class IPAddressType : public HugeintType {

public:
static const std::shared_ptr<const IPAddressType>& get() {
static const std::shared_ptr<const IPAddressType> instance{new IPAddressType()};
static const std::shared_ptr<const IPAddressType> instance{
new IPAddressType()};

return instance;
}
Expand Down
Loading

0 comments on commit 22f8e70

Please sign in to comment.