[
https://issues.apache.org/jira/browse/SPARK-57926?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
jiangxintong updated SPARK-57926:
---------------------------------
Description:
h2. Problem
Spark SQL currently has no built-in functions for IPv4 address manipulation.
This is a common
requirement in network log analysis, security auditing, and IP geolocation
workloads.
Users currently need database-specific functions, UDFs, or application-side
conversion. A native
Spark SQL implementation would keep the operation visible to analysis and
whole-stage codegen,
and would provide consistent SQL, Scala, PySpark, and Spark Connect APIs.
h2. Proposed Functions
||Function||Signature||Description||
|inet_aton|inet_aton(STRING) -> LONG|Converts IPv4 text to an unsigned 32-bit
value represented as LONG. Invalid input returns NULL when ANSI mode is
disabled and raises a structured error when ANSI mode is enabled.|
|inet_ntoa|inet_ntoa(LONG) -> STRING|Converts an unsigned 32-bit value
represented as LONG to canonical four-part IPv4 text. Values outside [0,
4294967295] return NULL when ANSI mode is disabled and raise a structured error
when ANSI mode is enabled.|
|try_inet_aton|try_inet_aton(STRING) -> LONG|The non-throwing variant of
inet_aton. Invalid IPv4 text always produces NULL.|
|try_inet_ntoa|try_inet_ntoa(LONG) -> STRING|The non-throwing variant of
inet_ntoa. Values outside the valid IPv4 range always produce NULL.|
h2. IPv4 Semantics
* IPv4 text accepts one to four dot-separated parts.
* Each part must contain decimal digits and have a value between 0 and 255.
* Leading zeroes are interpreted as decimal digits.
* Short forms follow the existing IPv4 conversion convention: {{a}} maps to
{{0.0.0.a}},
{{a.b}} maps to {{a.0.0.b}}, and {{a.b.c}} maps to {{a.b.0.c}}.
* Empty parts, whitespace, signs, non-ASCII characters, more than four parts,
and out-of-range
parts are invalid.
* inet_ntoa always returns canonical four-part text.
* The implementation supports IPv4 only. IPv6, CIDR operations, host name
resolution, and new
binary IP types are outside the scope of this issue.
h2. ANSI, NULL, and Type Conversion Behavior
inet_aton and inet_ntoa follow Spark's ANSI mode convention. The try_* variants
always return NULL
for invalid IPv4 content or out-of-range values, regardless of ANSI mode. SQL
NULL inputs follow
Spark's normal nullable expression semantics.
The documented argument types are STRING for inet_aton and LONG for inet_ntoa.
As with other Spark
expressions using implicit input types, analyzer coercion may accept additional
coercible inputs.
For example, inet_aton(1.5D) is analyzed through a STRING cast, while
inet_ntoa(1.5D) is analyzed
through a BIGINT cast. Cast failures retain Spark's CAST_INVALID_INPUT behavior
and precedence;
they are not reported as IPv4 range errors.
h2. Examples
{code:sql}
SELECT inet_aton('192.168.1.1');
-- 3232235777
SELECT inet_aton('127.1');
-- 2130706433
SELECT inet_ntoa(3232235777);
-- 192.168.1.1
SELECT try_inet_aton('not_an_ip');
-- NULL
SELECT try_inet_ntoa(-1);
-- NULL
{code}
h2. Why Built-in Functions Instead of UDFs
IPv4 conversion is a scalar operation used in projections, filters, conditional
expressions, and
joins. Implementing it as native functions provides analyzer-visible types and
errors, whole-stage
codegen support, and consistent behavior across Spark SQL, Scala, PySpark, and
Spark Connect without
requiring users to maintain UDFs.
The function names follow established database conventions, but the behavior is
defined by the
Spark contract above rather than by a promise of complete compatibility with
any other database.
was:
h2. Problem
Spark SQL has no built-in functions for IP address manipulation. This is a
common need in network log analysis, security auditing, and IP geolocation
scenarios.
Other databases have this capability:
* MySQL: INET_ATON() / INET_NTOA()
* ClickHouse: IPv4StringToNum() / IPv4NumToString()
* Doris: inet_aton() / inet_ntoa()
* Databend: inet_aton() / inet_ntoa() / try_inet_aton()
* VoltDB: INET_ATON() / INET_NTOA()
* SingleStore: INET_ATON() / INET_NTOA()
h2. Proposed Functions
||Function||Signature||Description||
|inet_aton|inet_aton(STRING) -> LONG|Convert IPv4 address string to 32-bit
integer. Throws on invalid input when ANSI mode is on; returns null when ANSI
mode is off.|
|inet_ntoa|inet_ntoa(LONG) -> STRING|Convert 32-bit integer to IPv4 address
string. Throws on out-of-range input ([0, 2^32-1]) when ANSI mode is on;
returns null when ANSI mode is off.|
|try_inet_aton|try_inet_aton(STRING) -> LONG|Same as inet_aton, but always
returns null on invalid input regardless of ANSI mode.|
h2. Examples
{code:sql}
> SELECT inet_aton('192.168.1.1');
3232235777
> SELECT inet_ntoa(3232235777);
192.168.1.1
> SELECT try_inet_aton('not_an_ip');
null
{code}
h2. ANSI Semantics
inet_aton and inet_ntoa follow Spark's ANSI mode convention:
* ANSI mode ON: throws QueryExecutionErrors on invalid/out-of-range input
* ANSI mode OFF: returns null on invalid/out-of-range input
try_inet_aton always returns null on error, following the try_* family pattern
(25 existing try_ functions in the registry).
This is consistent with cast/to_number/to_timestamp behavior.
h2. Notes
* IPv4 only (32-bit). IPv6 (128-bit) does not fit in LONG and requires
BINARY/STRING representation — deferred to a separate issue.
* Naming follows MySQL convention (inet_aton/inet_ntoa).
* Return type is LONG (not INT) because 3232235777 > 2^31-1.
h2. Why Built-in Instead of UDF
IP address functions are:
* Standard in major databases (MySQL, ClickHouse, Doris, Databend, VoltDB,
SingleStore)
* Performance-critical for network log analysis (millions of rows)
* Used in WHERE clauses (benefit from whole-stage codegen)
Summary: Add IPv4 address functions (inet_aton, inet_ntoa,
try_inet_aton, try_inet_ntoa) (was: Add IPv4 address functions (inet_aton,
inet_ntoa, try_inet_aton))
> Add IPv4 address functions (inet_aton, inet_ntoa, try_inet_aton,
> try_inet_ntoa)
> -------------------------------------------------------------------------------
>
> Key: SPARK-57926
> URL: https://issues.apache.org/jira/browse/SPARK-57926
> Project: Spark
> Issue Type: Improvement
> Components: SQL
> Affects Versions: 4.2.0
> Reporter: jiangxintong
> Priority: Major
> Labels: pull-request-available
>
> h2. Problem
> Spark SQL currently has no built-in functions for IPv4 address manipulation.
> This is a common
> requirement in network log analysis, security auditing, and IP geolocation
> workloads.
> Users currently need database-specific functions, UDFs, or application-side
> conversion. A native
> Spark SQL implementation would keep the operation visible to analysis and
> whole-stage codegen,
> and would provide consistent SQL, Scala, PySpark, and Spark Connect APIs.
> h2. Proposed Functions
> ||Function||Signature||Description||
> |inet_aton|inet_aton(STRING) -> LONG|Converts IPv4 text to an unsigned 32-bit
> value represented as LONG. Invalid input returns NULL when ANSI mode is
> disabled and raises a structured error when ANSI mode is enabled.|
> |inet_ntoa|inet_ntoa(LONG) -> STRING|Converts an unsigned 32-bit value
> represented as LONG to canonical four-part IPv4 text. Values outside [0,
> 4294967295] return NULL when ANSI mode is disabled and raise a structured
> error when ANSI mode is enabled.|
> |try_inet_aton|try_inet_aton(STRING) -> LONG|The non-throwing variant of
> inet_aton. Invalid IPv4 text always produces NULL.|
> |try_inet_ntoa|try_inet_ntoa(LONG) -> STRING|The non-throwing variant of
> inet_ntoa. Values outside the valid IPv4 range always produce NULL.|
> h2. IPv4 Semantics
> * IPv4 text accepts one to four dot-separated parts.
> * Each part must contain decimal digits and have a value between 0 and 255.
> * Leading zeroes are interpreted as decimal digits.
> * Short forms follow the existing IPv4 conversion convention: {{a}} maps to
> {{0.0.0.a}},
> {{a.b}} maps to {{a.0.0.b}}, and {{a.b.c}} maps to {{a.b.0.c}}.
> * Empty parts, whitespace, signs, non-ASCII characters, more than four parts,
> and out-of-range
> parts are invalid.
> * inet_ntoa always returns canonical four-part text.
> * The implementation supports IPv4 only. IPv6, CIDR operations, host name
> resolution, and new
> binary IP types are outside the scope of this issue.
> h2. ANSI, NULL, and Type Conversion Behavior
> inet_aton and inet_ntoa follow Spark's ANSI mode convention. The try_*
> variants always return NULL
> for invalid IPv4 content or out-of-range values, regardless of ANSI mode. SQL
> NULL inputs follow
> Spark's normal nullable expression semantics.
> The documented argument types are STRING for inet_aton and LONG for
> inet_ntoa. As with other Spark
> expressions using implicit input types, analyzer coercion may accept
> additional coercible inputs.
> For example, inet_aton(1.5D) is analyzed through a STRING cast, while
> inet_ntoa(1.5D) is analyzed
> through a BIGINT cast. Cast failures retain Spark's CAST_INVALID_INPUT
> behavior and precedence;
> they are not reported as IPv4 range errors.
> h2. Examples
> {code:sql}
> SELECT inet_aton('192.168.1.1');
> -- 3232235777
> SELECT inet_aton('127.1');
> -- 2130706433
> SELECT inet_ntoa(3232235777);
> -- 192.168.1.1
> SELECT try_inet_aton('not_an_ip');
> -- NULL
> SELECT try_inet_ntoa(-1);
> -- NULL
> {code}
> h2. Why Built-in Functions Instead of UDFs
> IPv4 conversion is a scalar operation used in projections, filters,
> conditional expressions, and
> joins. Implementing it as native functions provides analyzer-visible types
> and errors, whole-stage
> codegen support, and consistent behavior across Spark SQL, Scala, PySpark,
> and Spark Connect without
> requiring users to maintain UDFs.
> The function names follow established database conventions, but the behavior
> is defined by the
> Spark contract above rather than by a promise of complete compatibility with
> any other database.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]