Skip to content

Commit 47384c7

Browse files
feat: support function alias (#6917)
* feat: udf alias Signed-off-by: luofucong <[email protected]> * trying to fix sqlness Signed-off-by: luofucong <[email protected]> * x Signed-off-by: luofucong <[email protected]> --------- Signed-off-by: luofucong <[email protected]>
1 parent c9377e7 commit 47384c7

File tree

8 files changed

+108
-40
lines changed

8 files changed

+108
-40
lines changed

src/common/function/src/function.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ pub trait Function: fmt::Display + Sync + Send {
7070

7171
/// Evaluate the function, e.g. run/execute the function.
7272
fn eval(&self, ctx: &FunctionContext, columns: &[VectorRef]) -> Result<VectorRef>;
73+
74+
fn aliases(&self) -> &[String] {
75+
&[]
76+
}
7377
}
7478

7579
pub type FunctionRef = Arc<dyn Function>;

src/common/function/src/function_registry.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,18 @@ impl FunctionRegistry {
6464

6565
/// Register a scalar function in the registry.
6666
pub fn register_scalar(&self, func: impl Function + 'static) {
67-
self.register(Arc::new(func) as FunctionRef);
67+
let func = Arc::new(func) as FunctionRef;
68+
69+
for alias in func.aliases() {
70+
let func: ScalarFunctionFactory = func.clone().into();
71+
let alias = ScalarFunctionFactory {
72+
name: alias.to_string(),
73+
..func
74+
};
75+
self.register(alias);
76+
}
77+
78+
self.register(func)
6879
}
6980

7081
/// Register an aggregate function in the registry.

src/common/function/src/scalars/ip.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub(crate) struct IpFunctions;
2929
impl IpFunctions {
3030
pub fn register(registry: &FunctionRegistry) {
3131
// Register IPv4 functions
32-
registry.register_scalar(Ipv4NumToString);
32+
registry.register_scalar(Ipv4NumToString::default());
3333
registry.register_scalar(Ipv4StringToNum);
3434
registry.register_scalar(Ipv4ToCidr);
3535
registry.register_scalar(Ipv4InRange);

src/common/function/src/scalars/ip/ipv4.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,19 @@ use crate::function::{Function, FunctionContext};
3434
/// For example:
3535
/// - 167772160 (0x0A000000) returns "10.0.0.0"
3636
/// - 3232235521 (0xC0A80001) returns "192.168.0.1"
37-
#[derive(Clone, Debug, Default, Display)]
37+
#[derive(Clone, Debug, Display)]
3838
#[display("{}", self.name())]
39-
pub struct Ipv4NumToString;
39+
pub struct Ipv4NumToString {
40+
aliases: [String; 1],
41+
}
42+
43+
impl Default for Ipv4NumToString {
44+
fn default() -> Self {
45+
Self {
46+
aliases: ["inet_ntoa".to_string()],
47+
}
48+
}
49+
}
4050

4151
impl Function for Ipv4NumToString {
4252
fn name(&self) -> &str {
@@ -85,6 +95,10 @@ impl Function for Ipv4NumToString {
8595

8696
Ok(results.to_vector())
8797
}
98+
99+
fn aliases(&self) -> &[String] {
100+
&self.aliases
101+
}
88102
}
89103

90104
/// Function that converts a string representation of an IPv4 address to a UInt32 number.
@@ -156,7 +170,7 @@ mod tests {
156170

157171
#[test]
158172
fn test_ipv4_num_to_string() {
159-
let func = Ipv4NumToString;
173+
let func = Ipv4NumToString::default();
160174
let ctx = FunctionContext::default();
161175

162176
// Test data
@@ -193,7 +207,7 @@ mod tests {
193207
#[test]
194208
fn test_ipv4_conversions_roundtrip() {
195209
let to_num = Ipv4StringToNum;
196-
let to_string = Ipv4NumToString;
210+
let to_string = Ipv4NumToString::default();
197211
let ctx = FunctionContext::default();
198212

199213
// Test data for string to num to string

src/common/function/src/scalars/udf.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ impl ScalarUDFImpl for ScalarUdf {
5050
self.function.name()
5151
}
5252

53+
fn aliases(&self) -> &[String] {
54+
self.function.aliases()
55+
}
56+
5357
fn signature(&self) -> &datafusion_expr::Signature {
5458
&self.signature
5559
}

src/common/function/src/system/database.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ impl Function for DatabaseFunction {
6868
}
6969
}
7070

71+
// Though "current_schema" can be aliased to "database", to not cause any breaking changes,
72+
// we are not doing it: not until https://github.com/apache/datafusion/issues/17469 is resolved.
7173
impl Function for CurrentSchemaFunction {
7274
fn name(&self) -> &str {
7375
CURRENT_SCHEMA_FUNCTION_NAME

tests/cases/standalone/common/function/ip.result

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ CREATE TABLE network_traffic (
3232
`time` TIMESTAMP DEFAULT 0,
3333
source_ip STRING,
3434
dest_ip STRING,
35-
bytes_sent UINT64,
35+
bytes_sent UINT64,
3636
PRIMARY KEY(`id`),
3737
TIME INDEX(`time`)
3838
);
@@ -78,9 +78,9 @@ Affected Rows: 8
7878

7979
-- Test IPv4 string/number conversion functions
8080
-- SQLNESS SORT_RESULT 3 1
81-
SELECT
82-
`id`,
83-
ip_addr,
81+
SELECT
82+
`id`,
83+
ip_addr,
8484
ip_numeric,
8585
ipv4_string_to_num(ip_addr) AS computed_numeric,
8686
ipv4_num_to_string(ip_numeric) AS computed_addr
@@ -99,9 +99,32 @@ FROM ip_v4_data;
9999
| 8 | 0.0.0.0 | 0 | 0 | 0.0.0.0 |
100100
+----+-----------------+------------+------------------+-----------------+
101101

102+
-- Test IPv4 string/number conversion functions, by the function alias
103+
-- SQLNESS SORT_RESULT 3 1
104+
SELECT
105+
`id`,
106+
ip_addr,
107+
ip_numeric,
108+
ipv4_string_to_num(ip_addr) AS computed_numeric,
109+
inet_ntoa(ip_numeric) AS computed_addr
110+
FROM ip_v4_data;
111+
112+
+----+-----------------+------------+------------------+-----------------+
113+
| id | ip_addr | ip_numeric | computed_numeric | computed_addr |
114+
+----+-----------------+------------+------------------+-----------------+
115+
| 1 | 192.168.1.1 | 3232235777 | 3232235777 | 192.168.1.1 |
116+
| 2 | 10.0.0.1 | 167772161 | 167772161 | 10.0.0.1 |
117+
| 3 | 172.16.0.1 | 2886729729 | 2886729729 | 172.16.0.1 |
118+
| 4 | 127.0.0.1 | 2130706433 | 2130706433 | 127.0.0.1 |
119+
| 5 | 8.8.8.8 | 134744072 | 134744072 | 8.8.8.8 |
120+
| 6 | 192.168.0.1 | 3232235521 | 3232235521 | 192.168.0.1 |
121+
| 7 | 255.255.255.255 | 4294967295 | 4294967295 | 255.255.255.255 |
122+
| 8 | 0.0.0.0 | 0 | 0 | 0.0.0.0 |
123+
+----+-----------------+------------+------------------+-----------------+
124+
102125
-- Test IPv4 CIDR functions
103126
-- SQLNESS SORT_RESULT 3 1
104-
SELECT
127+
SELECT
105128
`id`,
106129
ip_addr,
107130
subnet_mask,
@@ -126,7 +149,7 @@ FROM ip_v4_data;
126149
-- Test IPv4 range checks
127150
-- SQLNESS SORT_RESULT 3 1
128151
-- Only get IPv4 records
129-
SELECT
152+
SELECT
130153
t.`id`,
131154
t.source_ip,
132155
t.dest_ip,
@@ -159,9 +182,9 @@ WHERE t.source_ip NOT LIKE '%:%';
159182

160183
-- Test IPv6 string/hex conversion functions
161184
-- SQLNESS SORT_RESULT 3 1
162-
SELECT
163-
`id`,
164-
ip_addr,
185+
SELECT
186+
`id`,
187+
ip_addr,
165188
ip_hex,
166189
ipv6_num_to_string(ip_hex) AS computed_addr
167190
FROM ip_v6_data;
@@ -179,7 +202,7 @@ FROM ip_v6_data;
179202

180203
-- Test IPv6 CIDR functions
181204
-- SQLNESS SORT_RESULT 3 1
182-
SELECT
205+
SELECT
183206
`id`,
184207
ip_addr,
185208
subnet_mask,
@@ -202,7 +225,7 @@ FROM ip_v6_data;
202225
-- Test IPv6 range checks
203226
-- SQLNESS SORT_RESULT 3 1
204227
-- Only get IPv6 records
205-
SELECT
228+
SELECT
206229
t.`id`,
207230
t.source_ip,
208231
t.dest_ip,
@@ -227,14 +250,14 @@ WHERE t.source_ip LIKE '%:%';
227250
-- Combined IPv4/IPv6 example - Security analysis
228251
-- Find all traffic from the same network to specific IPs
229252
-- SQLNESS SORT_RESULT 3 1
230-
SELECT
253+
SELECT
231254
source_ip,
232255
dest_ip,
233256
bytes_sent,
234-
CASE
235-
WHEN source_ip LIKE '%:%' THEN
257+
CASE
258+
WHEN source_ip LIKE '%:%' THEN
236259
ipv6_to_cidr(source_ip, arrow_cast(64, 'UInt8'))
237-
ELSE
260+
ELSE
238261
ipv4_to_cidr(source_ip, arrow_cast(24, 'UInt8'))
239262
END AS source_network,
240263
CASE
@@ -261,7 +284,7 @@ ORDER BY bytes_sent DESC;
261284

262285
-- Subnet analysis - IPv4
263286
-- SQLNESS SORT_RESULT 3 1
264-
SELECT
287+
SELECT
265288
ipv4_to_cidr(source_ip, arrow_cast(24,'UInt8')) AS subnet,
266289
COUNT(*) AS device_count,
267290
SUM(bytes_sent) AS total_bytes
@@ -280,7 +303,7 @@ ORDER BY total_bytes DESC;
280303

281304
-- Subnet analysis - IPv6
282305
-- SQLNESS SORT_RESULT 3 1
283-
SELECT
306+
SELECT
284307
ipv6_to_cidr(source_ip, arrow_cast(48,'UInt8')) AS subnet,
285308
COUNT(*) AS device_count,
286309
SUM(bytes_sent) AS total_bytes

tests/cases/standalone/common/function/ip.sql

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ CREATE TABLE network_traffic (
2828
`time` TIMESTAMP DEFAULT 0,
2929
source_ip STRING,
3030
dest_ip STRING,
31-
bytes_sent UINT64,
31+
bytes_sent UINT64,
3232
PRIMARY KEY(`id`),
3333
TIME INDEX(`time`)
3434
);
@@ -66,17 +66,27 @@ INSERT INTO network_traffic (`id`, source_ip, dest_ip, bytes_sent) VALUES
6666

6767
-- Test IPv4 string/number conversion functions
6868
-- SQLNESS SORT_RESULT 3 1
69-
SELECT
70-
`id`,
71-
ip_addr,
69+
SELECT
70+
`id`,
71+
ip_addr,
7272
ip_numeric,
7373
ipv4_string_to_num(ip_addr) AS computed_numeric,
7474
ipv4_num_to_string(ip_numeric) AS computed_addr
7575
FROM ip_v4_data;
7676

77+
-- Test IPv4 string/number conversion functions, by the function alias
78+
-- SQLNESS SORT_RESULT 3 1
79+
SELECT
80+
`id`,
81+
ip_addr,
82+
ip_numeric,
83+
ipv4_string_to_num(ip_addr) AS computed_numeric,
84+
inet_ntoa(ip_numeric) AS computed_addr
85+
FROM ip_v4_data;
86+
7787
-- Test IPv4 CIDR functions
7888
-- SQLNESS SORT_RESULT 3 1
79-
SELECT
89+
SELECT
8090
`id`,
8191
ip_addr,
8292
subnet_mask,
@@ -87,7 +97,7 @@ FROM ip_v4_data;
8797

8898
-- Test IPv4 range checks
8999
-- SQLNESS SORT_RESULT 3 1
90-
SELECT
100+
SELECT
91101
t.`id`,
92102
t.source_ip,
93103
t.dest_ip,
@@ -102,16 +112,16 @@ WHERE t.source_ip NOT LIKE '%:%';
102112

103113
-- Test IPv6 string/hex conversion functions
104114
-- SQLNESS SORT_RESULT 3 1
105-
SELECT
106-
`id`,
107-
ip_addr,
115+
SELECT
116+
`id`,
117+
ip_addr,
108118
ip_hex,
109119
ipv6_num_to_string(ip_hex) AS computed_addr
110120
FROM ip_v6_data;
111121

112122
-- Test IPv6 CIDR functions
113123
-- SQLNESS SORT_RESULT 3 1
114-
SELECT
124+
SELECT
115125
`id`,
116126
ip_addr,
117127
subnet_mask,
@@ -122,7 +132,7 @@ FROM ip_v6_data;
122132

123133
-- Test IPv6 range checks
124134
-- SQLNESS SORT_RESULT 3 1
125-
SELECT
135+
SELECT
126136
t.`id`,
127137
t.source_ip,
128138
t.dest_ip,
@@ -138,14 +148,14 @@ WHERE t.source_ip LIKE '%:%';
138148
-- Combined IPv4/IPv6 example - Security analysis
139149
-- Find all traffic from the same network to specific IPs
140150
-- SQLNESS SORT_RESULT 3 1
141-
SELECT
151+
SELECT
142152
source_ip,
143153
dest_ip,
144154
bytes_sent,
145-
CASE
146-
WHEN source_ip LIKE '%:%' THEN
155+
CASE
156+
WHEN source_ip LIKE '%:%' THEN
147157
ipv6_to_cidr(source_ip, arrow_cast(64, 'UInt8'))
148-
ELSE
158+
ELSE
149159
ipv4_to_cidr(source_ip, arrow_cast(24, 'UInt8'))
150160
END AS source_network,
151161
CASE
@@ -159,7 +169,7 @@ ORDER BY bytes_sent DESC;
159169

160170
-- Subnet analysis - IPv4
161171
-- SQLNESS SORT_RESULT 3 1
162-
SELECT
172+
SELECT
163173
ipv4_to_cidr(source_ip, arrow_cast(24,'UInt8')) AS subnet,
164174
COUNT(*) AS device_count,
165175
SUM(bytes_sent) AS total_bytes
@@ -170,7 +180,7 @@ ORDER BY total_bytes DESC;
170180

171181
-- Subnet analysis - IPv6
172182
-- SQLNESS SORT_RESULT 3 1
173-
SELECT
183+
SELECT
174184
ipv6_to_cidr(source_ip, arrow_cast(48,'UInt8')) AS subnet,
175185
COUNT(*) AS device_count,
176186
SUM(bytes_sent) AS total_bytes

0 commit comments

Comments
 (0)