summaryrefslogtreecommitdiffstats
path: root/yql/essentials/udfs
diff options
context:
space:
mode:
authorlambda-delta <[email protected]>2025-08-04 19:40:46 +0300
committerlambda-delta <[email protected]>2025-08-04 20:05:53 +0300
commitb5c31e9554edee086eed97d94e7908d6d6ef3ec2 (patch)
tree06f2ac35cc4d8aa62f3c64f023e56a0e7256352c /yql/essentials/udfs
parentc0bc4e708e27a153b958eed0f42d2a67f245b288 (diff)
YQL-19784: Implement Ipv4FromUint32 and Ipv4ToUint32 functions in IP UDF
Implement Ipv4FromUint32 and Ipv4ToUint32 functions in IP UDF commit_hash:ac21513d59acaf686ad0ab1482753863eb2d9a12
Diffstat (limited to 'yql/essentials/udfs')
-rw-r--r--yql/essentials/udfs/common/ip_base/lib/ip_base_udf.h25
-rw-r--r--yql/essentials/udfs/common/ip_base/lib/ya.make2
-rw-r--r--yql/essentials/udfs/common/ip_base/test/canondata/result.json10
-rw-r--r--yql/essentials/udfs/common/ip_base/test/canondata/test.test_Ipv4Uint32_/results.txt133
-rw-r--r--yql/essentials/udfs/common/ip_base/test/canondata/test.test_Ipv4Uint32_2025_02_/extracted23
-rw-r--r--yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32.cfg2
-rw-r--r--yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32.sql8
-rw-r--r--yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32_2025_02.cfg2
-rw-r--r--yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32_2025_02.sql3
-rw-r--r--yql/essentials/udfs/common/ip_base/ya.make4
10 files changed, 209 insertions, 3 deletions
diff --git a/yql/essentials/udfs/common/ip_base/lib/ip_base_udf.h b/yql/essentials/udfs/common/ip_base/lib/ip_base_udf.h
index 3644207f8b3..2bb4f987190 100644
--- a/yql/essentials/udfs/common/ip_base/lib/ip_base_udf.h
+++ b/yql/essentials/udfs/common/ip_base/lib/ip_base_udf.h
@@ -1,6 +1,7 @@
#pragma once
#include <yql/essentials/public/udf/udf_helpers.h>
+#include <yql/essentials/public/langver/yql_langver.h>
#include <library/cpp/ipv6_address/ipv6_address.h>
#include <library/cpp/ipmath/ipmath.h>
@@ -8,7 +9,9 @@
namespace {
using TAutoMapString = NKikimr::NUdf::TAutoMap<char*>;
+ using TAutoMapUint32 = NKikimr::NUdf::TAutoMap<ui32>;
using TOptionalString = NKikimr::NUdf::TOptional<char*>;
+ using TOptionalUint32 = NKikimr::NUdf::TOptional<ui32>;
using TOptionalByte = NKikimr::NUdf::TOptional<ui8>;
using TStringRef = NKikimr::NUdf::TStringRef;
using TUnboxedValue = NKikimr::NUdf::TUnboxedValue;
@@ -229,6 +232,13 @@ namespace {
return valueBuilder->NewString(SerializeAddress(addr));
}
+ SIMPLE_STRICT_UDF_OPTIONS(TIpv4FromUint32, char*(TAutoMapUint32), builder.SetMinLangVer(NYql::MakeLangVersion(2025, 3))) {
+ // in_addr expects bytes in network byte order.
+ in_addr addr;
+ addr.s_addr = htonl(args[0].Get<ui32>());
+ return valueBuilder->NewString(SerializeAddress(TIpv6Address{addr}));
+ }
+
SIMPLE_STRICT_UDF(TSubnetFromString, TOptionalString(TAutoMapString)) {
TIpAddressRange range = TIpAddressRange::FromCompactString(args[0].AsStringRef());
auto res = SerializeSubnet(range);
@@ -239,6 +249,19 @@ namespace {
return valueBuilder->NewString(DeserializeAddress(args[0].AsStringRef()).ToString(false));
}
+ SIMPLE_UDF_OPTIONS(TIpv4ToUint32, TOptionalUint32(TAutoMapString), builder.SetMinLangVer(NYql::MakeLangVersion(2025, 3))) {
+ Y_UNUSED(valueBuilder);
+ TIpv6Address addr = DeserializeAddress(args[0].AsStringRef());
+ if (addr.Type() != TIpv6Address::Ipv4) {
+ return TUnboxedValue();
+ }
+
+ in_addr tmp;
+ addr.ToInAddr(tmp);
+ ui32 ret = ntohl(tmp.s_addr);
+ return TUnboxedValuePod(ret);
+ }
+
SIMPLE_UDF(TSubnetToString, char*(TAutoMapString)) {
TStringBuilder result;
auto range = DeserializeSubnet(args[0].AsStringRef());
@@ -345,8 +368,10 @@ namespace {
#define EXPORTED_IP_BASE_UDF \
TFromString, \
+ TIpv4FromUint32, \
TSubnetFromString, \
TToString, \
+ TIpv4ToUint32, \
TSubnetToString, \
TIsIPv4, \
TIsIPv6, \
diff --git a/yql/essentials/udfs/common/ip_base/lib/ya.make b/yql/essentials/udfs/common/ip_base/lib/ya.make
index 72633514771..ab9b2bce8e2 100644
--- a/yql/essentials/udfs/common/ip_base/lib/ya.make
+++ b/yql/essentials/udfs/common/ip_base/lib/ya.make
@@ -2,7 +2,7 @@ LIBRARY()
YQL_ABI_VERSION(
2
- 28
+ 43
0
)
diff --git a/yql/essentials/udfs/common/ip_base/test/canondata/result.json b/yql/essentials/udfs/common/ip_base/test/canondata/result.json
index a9602f6bf0c..59a83495eac 100644
--- a/yql/essentials/udfs/common/ip_base/test/canondata/result.json
+++ b/yql/essentials/udfs/common/ip_base/test/canondata/result.json
@@ -4,6 +4,16 @@
"uri": "file://test.test_Basic_/results.txt"
}
],
+ "test.test[Ipv4Uint32]": [
+ {
+ "uri": "file://test.test_Ipv4Uint32_/results.txt"
+ }
+ ],
+ "test.test[Ipv4Uint32_2025_02]": [
+ {
+ "uri": "file://test.test_Ipv4Uint32_2025_02_/extracted"
+ }
+ ],
"test.test[Subnets]": [
{
"uri": "file://test.test_Subnets_/results.txt"
diff --git a/yql/essentials/udfs/common/ip_base/test/canondata/test.test_Ipv4Uint32_/results.txt b/yql/essentials/udfs/common/ip_base/test/canondata/test.test_Ipv4Uint32_/results.txt
new file mode 100644
index 00000000000..c572880165f
--- /dev/null
+++ b/yql/essentials/udfs/common/ip_base/test/canondata/test.test_Ipv4Uint32_/results.txt
@@ -0,0 +1,133 @@
+[
+ {
+ "Write" = [
+ {
+ "Type" = [
+ "ListType";
+ [
+ "StructType";
+ [
+ [
+ "internal_representation";
+ [
+ "OptionalType";
+ [
+ "DataType";
+ "String"
+ ]
+ ]
+ ];
+ [
+ "uint32_repr";
+ [
+ "OptionalType";
+ [
+ "DataType";
+ "Uint32"
+ ]
+ ]
+ ];
+ [
+ "internal_repr_uint32";
+ [
+ "OptionalType";
+ [
+ "DataType";
+ "String"
+ ]
+ ]
+ ]
+ ]
+ ]
+ ];
+ "Data" = [
+ [
+ [
+ "\x7F\0\0\1"
+ ];
+ [
+ "2130706433"
+ ];
+ [
+ "\x7F\0\0\1"
+ ]
+ ];
+ [
+ [
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1"
+ ];
+ #;
+ #
+ ];
+ [
+ [
+ [
+ "1bTBAw=="
+ ]
+ ];
+ [
+ "3585392899"
+ ];
+ [
+ [
+ "1bTBAw=="
+ ]
+ ]
+ ];
+ [
+ [
+ [
+ "KgIGuAAAAAAAAAAAAAAAAw=="
+ ]
+ ];
+ #;
+ #
+ ];
+ [
+ [
+ [
+ "JADLACBIAAEAAAAAaBwbZQ=="
+ ]
+ ];
+ #;
+ #
+ ];
+ [
+ [
+ [
+ "/oAAAAAAAAACFbL//qlnzg=="
+ ]
+ ];
+ #;
+ #
+ ];
+ [
+ [
+ [
+ "AAAAAAAAAAAAAP//TUubAw=="
+ ]
+ ];
+ #;
+ #
+ ];
+ [
+ #;
+ #;
+ #
+ ];
+ [
+ [
+ "\0\0\0\0"
+ ];
+ [
+ "0"
+ ];
+ [
+ "\0\0\0\0"
+ ]
+ ]
+ ]
+ }
+ ]
+ }
+] \ No newline at end of file
diff --git a/yql/essentials/udfs/common/ip_base/test/canondata/test.test_Ipv4Uint32_2025_02_/extracted b/yql/essentials/udfs/common/ip_base/test/canondata/test.test_Ipv4Uint32_2025_02_/extracted
new file mode 100644
index 00000000000..16a3af0eebe
--- /dev/null
+++ b/yql/essentials/udfs/common/ip_base/test/canondata/test.test_Ipv4Uint32_2025_02_/extracted
@@ -0,0 +1,23 @@
+<tmp_path>/program.sql:<main>: Error: Type annotation
+
+ <tmp_path>/program.sql:<main>:2:1: Error: At function: RemovePrefixMembers, At function: Unordered, At function: PersistableRepr, At function: OrderedSqlProject, At tuple
+ SELECT
+ ^
+ <tmp_path>/program.sql:<main>:2:1: Error: At function: SqlProjectItem, At lambda
+ SELECT
+ ^
+ <tmp_path>/program.sql:<main>:4:9: Error: At function: Apply, At function: Udf
+ Ip::Ipv4ToUint32(Ip::FromString("127.0.0.1")) AS uint32_repr,
+ ^
+ <tmp_path>/program.sql:<main>:4:9: Error: UDF 'Ip.Ipv4ToUint32' is not available before version 2025.03
+ Ip::Ipv4ToUint32(Ip::FromString("127.0.0.1")) AS uint32_repr,
+ ^
+ <tmp_path>/program.sql:<main>:2:1: Error: At function: SqlProjectItem, At lambda
+ SELECT
+ ^
+ <tmp_path>/program.sql:<main>:6:9: Error: At function: Apply, At function: Udf
+ Ip::Ipv4FromUint32(0x7F000001U) AS internal_repr_uint32;
+ ^
+ <tmp_path>/program.sql:<main>:6:9: Error: UDF 'Ip.Ipv4FromUint32' is not available before version 2025.03
+ Ip::Ipv4FromUint32(0x7F000001U) AS internal_repr_uint32;
+ ^ \ No newline at end of file
diff --git a/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32.cfg b/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32.cfg
new file mode 100644
index 00000000000..a0eb39c67fd
--- /dev/null
+++ b/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32.cfg
@@ -0,0 +1,2 @@
+langver 2025.03
+in plato.Input Basic.in
diff --git a/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32.sql b/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32.sql
new file mode 100644
index 00000000000..a11aa895173
--- /dev/null
+++ b/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32.sql
@@ -0,0 +1,8 @@
+/* syntax version 1 */
+SELECT
+ internal_representation AS internal_representation,
+ Ip::Ipv4ToUint32(internal_representation) AS uint32_repr,
+ Ip::Ipv4FromUint32(Ip::Ipv4ToUint32(internal_representation)) AS internal_repr_uint32,
+FROM (
+ SELECT Ip::FromString(key) AS internal_representation FROM Input
+);
diff --git a/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32_2025_02.cfg b/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32_2025_02.cfg
new file mode 100644
index 00000000000..989226cf3d4
--- /dev/null
+++ b/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32_2025_02.cfg
@@ -0,0 +1,2 @@
+xfail
+langver 2025.02
diff --git a/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32_2025_02.sql b/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32_2025_02.sql
new file mode 100644
index 00000000000..66681990156
--- /dev/null
+++ b/yql/essentials/udfs/common/ip_base/test/cases/Ipv4Uint32_2025_02.sql
@@ -0,0 +1,3 @@
+SELECT
+ Ip::Ipv4ToUint32(Ip::FromString("127.0.0.1")) AS uint32_repr,
+ Ip::Ipv4FromUint32(0x7F000001U) AS internal_repr_uint32;
diff --git a/yql/essentials/udfs/common/ip_base/ya.make b/yql/essentials/udfs/common/ip_base/ya.make
index 0e5537607a2..0a2859c0af2 100644
--- a/yql/essentials/udfs/common/ip_base/ya.make
+++ b/yql/essentials/udfs/common/ip_base/ya.make
@@ -2,7 +2,7 @@ YQL_UDF_CONTRIB(ip_udf)
YQL_ABI_VERSION(
2
- 28
+ 43
0
)
@@ -18,4 +18,4 @@ YQL_UDF_CONTRIB(ip_udf)
RECURSE_FOR_TESTS(
test
-) \ No newline at end of file
+)