Skip to content

Commit 4dc995b

Browse files
mswapnilGHackerpilot
authored andcommitted
Add RDIFF and LDIFF udf with RANGE datetypes. (GoogleCloudPlatform#520)
1 parent 37302c6 commit 4dc995b

8 files changed

Lines changed: 397 additions & 0 deletions

udfs/community/README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@ SELECT bqutil.fn.int(1.684)
7272
* [cw_parse_timestamp](#cw_parse_timestamptimeString-string-formatString-string)
7373
* [cw_period_intersection](#cw_period_intersectionp1-structlower-timestamp-upper-timestamp-p2-structlower-timestamp-upper-timestamp)
7474
* [cw_period_ldiff](#cw_period_ldiffp1-structlower-timestamp-upper-timestamp-p2-structlower-timestamp-upper-timestamp)
75+
* [cw_range_date_ldiff](#cw_range_date_ldiffp1-range-p2-range)
76+
* [cw_range_datetime_ldiff](#cw_range_datetime_ldiffp1-range-p2-range)
77+
* [cw_range_timestamp_ldiff](#cw_range_timestamp_ldiffp1-range-p2-range)
7578
* [cw_period_rdiff](#cw_period_rdiffp1-structlower-timestamp-upper-timestamp-p2-structlower-timestamp-upper-timestamp)
79+
* [cw_range_date_rdiff](#cw_range_date_rdiffp1-range-p2-range)
80+
* [cw_range_datetime_rdiff](#cw_range_datetime_rdiffp1-range-p2-range)
81+
* [cw_range_timestamp_rdiff](#cw_range_timestamp_rdiffp1-range-p2-range)
7682
* [cw_regex_mode](#cw_regex_modemode-string)
7783
* [cw_regexp_extract](#cw_regexp_extractstr-string-regexp-string)
7884
* [cw_regexp_extract_all](#cw_regexp_extract_allstr-string-regexp-string)
@@ -784,6 +790,33 @@ SELECT bqutil.fn.cw_period_ldiff(
784790
STRUCT(TIMESTAMP '2001-11-12 00:00:00' AS lower, TIMESTAMP '2001-11-13 00:00:00' AS upper)
785791
```
786792

793+
### [cw_range_date_ldiff(p1 RANGE<DATE>, p2 RANGE<DATE>)](cw_range_date_ldiff.sqlx)
794+
```sql
795+
SELECT cw_udf.cw_range_date_ldiff(
796+
RANGE(DATE '2001-11-12', DATE '2001-11-14'),
797+
RANGE(DATE '2001-11-13', DATE '2001-11-15'))
798+
799+
RANGE(DATE '2001-11-12', DATE '2001-11-13')
800+
```
801+
802+
### [cw_range_datetime_ldiff(p1 RANGE<DATETIME>, p2 RANGE<DATETIME>)](cw_range_datetime_ldiff.sqlx)
803+
```sql
804+
SELECT cw_udf.cw_range_datetime_ldiff(
805+
RANGE(DATETIME '2001-11-12 00:00:00', DATETIME '2001-11-14 00:00:00'),
806+
RANGE(DATETIME '2001-11-13 00:00:00', DATETIME '2001-11-15 00:00:00'))
807+
808+
RANGE(DATETIME '2001-11-12 00:00:00', DATETIME '2001-11-13 00:00:00')
809+
```
810+
811+
### [cw_range_timestamp_ldiff(p1 RANGE<TIMESTAMP>, p2 RANGE<TIMESTAMP>)](cw_range_timestamp_ldiff.sqlx)
812+
```sql
813+
SELECT cw_udf.cw_range_timestamp_ldiff(
814+
RANGE(TIMESTAMP '2001-11-12 00:00:00', TIMESTAMP '2001-11-14 00:00:00'),
815+
RANGE(TIMESTAMP '2001-11-13 00:00:00', TIMESTAMP '2001-11-15 00:00:00'))
816+
817+
RANGE(TIMESTAMP '2001-11-12 00:00:00', TIMESTAMP '2001-11-13 00:00:00')
818+
```
819+
787820
### [cw_period_rdiff(p1 STRUCT<lower TIMESTAMP, upper TIMESTAMP>, p2 STRUCT<lower TIMESTAMP, upper TIMESTAMP>)](cw_period_rdiff.sqlx)
788821
```sql
789822
SELECT bqutil.fn.cw_period_rdiff(
@@ -793,6 +826,34 @@ SELECT bqutil.fn.cw_period_rdiff(
793826
STRUCT(TIMESTAMP '2001-11-14 00:00:00' AS lower, TIMESTAMP '2001-11-15 00:00:00' AS upper)
794827
```
795828

829+
### [cw_range_date_rdiff(p1 RANGE<DATE>, p2 RANGE<DATE>)](cw_range_date_rdiff.sqlx)
830+
```sql
831+
SELECT cw_udf.cw_range_date_rdiff(
832+
RANGE(DATE '2001-11-13', DATE '2001-11-15'),
833+
RANGE(DATE '2001-11-12', DATE '2001-11-14'))
834+
835+
RANGE(DATE '2001-11-14', DATE '2001-11-15')
836+
```
837+
838+
### [cw_range_datetime_rdiff(p1 RANGE<DATETIME>, p2 RANGE<DATETIME>)](cw_range_datetime_rdiff.sqlx)
839+
```sql
840+
SELECT cw_udf.cw_range_datetime_rdiff(
841+
RANGE(DATETIME '2001-11-13 00:00:00', DATETIME '2001-11-15 00:00:00'),
842+
RANGE(DATETIME '2001-11-12 00:00:00', DATETIME '2001-11-14 00:00:00'))
843+
844+
RANGE(DATETIME '2001-11-14 00:00:00', DATETIME '2001-11-15 00:00:00')
845+
```
846+
847+
848+
### [cw_range_timestamp_rdiff(p1 RANGE<TIMESTAMP>, p2 RANGE<TIMESTAMP>)](cw_range_timestamp_rdiff.sqlx)
849+
```sql
850+
SELECT cw_udf.cw_range_timestamp_rdiff(
851+
RANGE(TIMESTAMP '2001-11-13 00:00:00', TIMESTAMP '2001-11-15 00:00:00'),
852+
RANGE(TIMESTAMP '2001-11-12 00:00:00', TIMESTAMP '2001-11-14 00:00:00'))
853+
854+
RANGE(TIMESTAMP '2001-11-14 00:00:00', TIMESTAMP '2001-11-15 00:00:00')
855+
```
856+
796857
### [cw_regex_mode(mode STRING)](cw_regex_mode.sqlx)
797858
Retrieve mode.
798859
```sql
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
config { hasOutput: true }
2+
/*
3+
* Copyright 2026 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
CREATE OR REPLACE FUNCTION ${self()}(p1 RANGE<DATE>, p2 RANGE<DATE>) RETURNS RANGE<DATE>
19+
OPTIONS(description="Emulates Teradata's LDIFF operator with RANGE<DATE> inputs.")
20+
AS (
21+
CASE
22+
WHEN RANGE_OVERLAPS(p1, p2) AND RANGE_START(p1) < RANGE_START(p2) THEN
23+
RANGE(RANGE_START(p1), RANGE_START(p2))
24+
ELSE NULL
25+
END
26+
);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
config { hasOutput: true }
2+
/*
3+
* Copyright 2026 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
CREATE OR REPLACE FUNCTION ${self()}(p1 RANGE<DATE>, p2 RANGE<DATE>) RETURNS RANGE<DATE>
19+
OPTIONS(description="Emulates Teradata's RDIFF operator with RANGE<DATE> inputs.")
20+
AS (
21+
CASE
22+
WHEN RANGE_OVERLAPS(p1, p2) AND RANGE_END(p1) > RANGE_END(p2) THEN
23+
RANGE(RANGE_END(p2), RANGE_END(p1))
24+
ELSE NULL
25+
END
26+
);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
config { hasOutput: true }
2+
/*
3+
* Copyright 2026 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
CREATE OR REPLACE FUNCTION ${self()}(p1 RANGE<DATETIME>, p2 RANGE<DATETIME>) RETURNS RANGE<DATETIME>
19+
OPTIONS(description="Emulates Teradata's LDIFF operator with RANGE<DATETIME> inputs.")
20+
AS (
21+
CASE
22+
WHEN RANGE_OVERLAPS(p1, p2) AND RANGE_START(p1) < RANGE_START(p2) THEN
23+
RANGE(RANGE_START(p1), RANGE_START(p2))
24+
ELSE NULL
25+
END
26+
);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
config { hasOutput: true }
2+
/*
3+
* Copyright 2026 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
CREATE OR REPLACE FUNCTION ${self()}(p1 RANGE<DATETIME>, p2 RANGE<DATETIME>) RETURNS RANGE<DATETIME>
19+
OPTIONS(description="Emulates Teradata's RDIFF operator with RANGE<DATETIME> inputs.")
20+
AS (
21+
CASE
22+
WHEN RANGE_OVERLAPS(p1, p2) AND RANGE_END(p1) > RANGE_END(p2) THEN
23+
RANGE(RANGE_END(p2), RANGE_END(p1))
24+
ELSE NULL
25+
END
26+
);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
config { hasOutput: true }
2+
/*
3+
* Copyright 2026 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
CREATE OR REPLACE FUNCTION ${self()}(p1 RANGE<TIMESTAMP>, p2 RANGE<TIMESTAMP>) RETURNS RANGE<TIMESTAMP>
19+
OPTIONS(description="Emulates Teradata's LDIFF operator with RANGE<TIMESTAMP> inputs.")
20+
AS (
21+
CASE
22+
WHEN RANGE_OVERLAPS(p1, p2) AND RANGE_START(p1) < RANGE_START(p2) THEN
23+
RANGE(RANGE_START(p1), RANGE_START(p2))
24+
ELSE NULL
25+
END
26+
);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
config { hasOutput: true }
2+
/*
3+
* Copyright 2026 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
CREATE OR REPLACE FUNCTION ${self()}(p1 RANGE<TIMESTAMP>, p2 RANGE<TIMESTAMP>) RETURNS RANGE<TIMESTAMP>
19+
OPTIONS(description="Emulates Teradata's RDIFF operator with RANGE<TIMESTAMP> inputs.")
20+
AS (
21+
CASE
22+
WHEN RANGE_OVERLAPS(p1, p2) AND RANGE_END(p1) > RANGE_END(p2) THEN
23+
RANGE(RANGE_END(p2), RANGE_END(p1))
24+
ELSE NULL
25+
END
26+
);

0 commit comments

Comments
 (0)