Skip to content

Commit

Permalink
Translation Engine UDF for signed 128bit bitshift. (#356)
Browse files Browse the repository at this point in the history
  • Loading branch information
damian-compilerworks authored May 17, 2023
1 parent fa66760 commit 1a335ed
Show file tree
Hide file tree
Showing 4 changed files with 250 additions and 0 deletions.
30 changes: 30 additions & 0 deletions udfs/community/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ SELECT bqutil.fn.int(1.684)
* [cw_round_half_even_bignumeric](#cw_round_half_even_bignumericn-bignumeric-d-int64)
* [cw_runtime_parse_interval_seconds](#cw_runtime_parse_interval_secondsival-string)
* [cw_setbit](#cw_setbitbits-int64-index-int64)
* [cw_signed_leftshift_128bit](#cw_signed_leftshift_128bitvalue-bignumeric-n-bignumeric)
* [cw_signed_rightshift_128bit](#cw_signed_rightshift_128bitvalue-bignumeric-n-bignumeric)
* [cw_stringify_interval](#cw_stringify_intervalx-int64)
* [cw_strtok](#cw_strtoktext-string-delim-string)
* [cw_substrb](#cw_substrbstr-string-startpos-int64-extent-int64)
Expand Down Expand Up @@ -905,6 +907,34 @@ SELECT bqutil.fn.cw_setbit(1001, 2);
1005
```

### [cw_signed_leftshift_128bit(value BIGNUMERIC, n BIGNUMERIC)](cw_signed_leftshift_128bit.sqlx)
Performs a signed shift left on BIGNUMERIC as if it was a 128 bit integer.
```sql
- SELECT bqutil.fn.cw_signed_leftshift_128bit(NUMERIC '1', NUMERIC '3');
- SELECT bqutil.fn.cw_signed_leftshift_128bit(NUMERIC '1', NUMERIC '127');
- SELECT bqutil.fn.cw_signed_leftshift_128bit(NUMERIC '-5', NUMERIC '2');

- 8
- -170141183460469231731687303715884105728
- -20
```

### [cw_signed_rightshift_128bit(value BIGNUMERIC, n BIGNUMERIC)](cw_signed_rightshift_128bit.sqlx)
Performs a signed shift right on BIGNUMERIC as if it was a 128 bit integer.
```sql
- SELECT bqutil.fn.cw_signed_rightshift_128bit(NUMERIC '32', NUMERIC '3');
- SELECT bqutil.fn.cw_signed_rightshift_128bit(NUMERIC '7', NUMERIC '1');
- SELECT bqutil.fn.cw_signed_rightshift_128bit(NUMERIC '-7', NUMERIC '1');
- SELECT bqutil.fn.cw_signed_rightshift_128bit(NUMERIC '-1', NUMERIC '1');
- SELECT bqutil.fn.cw_signed_rightshift_128bit(NUMERIC '-1', NUMERIC '100');

- 4
- 3
- -4
- -1
- -1
```

### [cw_stringify_interval(x INT64)](cw_stringify_interval.sqlx)
Formats the interval as 'day hour:minute:second
```sql
Expand Down
35 changes: 35 additions & 0 deletions udfs/community/cw_signed_leftshift_128bit.sqlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
config { hasOutput: true }
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
* Performs a signed shift left on BIGNUMERIC as if it was a 128 bit integer.
*/
CREATE OR REPLACE FUNCTION ${self()}(value BIGNUMERIC, n BIGNUMERIC)
RETURNS BIGNUMERIC
OPTIONS(description="Performs a signed shift right on BIGNUMERIC as if it was a 128 bit integer.")
AS (
(WITH consts AS (
SELECT
BIGNUMERIC '340282366920938463463374607431768211456' as _128bits,
BIGNUMERIC '170141183460469231731687303715884105728' as _127bits,
CASE
WHEN n >= 0 THEN CAST(POW(2, LEAST(n, 128)) as BIGNUMERIC)
ELSE ERROR('Shift parameter must be greater or equal to zero, but was: ' || n)
END AS shift
)
SELECT MOD(MOD(MOD(value + _128bits, _128bits), _128bits / shift) * shift + _127bits, _128bits) - _127bits FROM consts
));
33 changes: 33 additions & 0 deletions udfs/community/cw_signed_rightshift_128bit.sqlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
config { hasOutput: true }
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
* Performs a signed shift right on BIGNUMERIC as if it was a 128 bit integer.
*/
CREATE OR REPLACE FUNCTION ${self()}(value BIGNUMERIC, n BIGNUMERIC)
RETURNS BIGNUMERIC
OPTIONS(description="Performs a signed shift left on BIGNUMERIC as if it was a 128 bit integer.")
AS (
(WITH consts AS (
SELECT
CASE
WHEN n >= 0 THEN CAST(POW(2, LEAST(n, 127)) as BIGNUMERIC)
ELSE ERROR('Shift parameter must be greater or equal to zero, but was: ' || n)
END AS shift
)
SELECT FLOOR(value/shift) FROM consts
));
152 changes: 152 additions & 0 deletions udfs/community/test_cases.js
Original file line number Diff line number Diff line change
Expand Up @@ -2079,6 +2079,158 @@ generate_udf_test("cw_setbit", [
expected_output: `CAST(1005 AS INT64)`
},
]);
generate_udf_test("cw_signed_leftshift_128bit", [
{
inputs: [
`BIGNUMERIC '1'`, `BIGNUMERIC '3'`
],
expected_output: `BIGNUMERIC '8'`
},
{
inputs: [
`BIGNUMERIC '1'`, `BIGNUMERIC '127'`
],
expected_output: `BIGNUMERIC '-170141183460469231731687303715884105728'`
},
{
inputs: [
`BIGNUMERIC '1'`, `BIGNUMERIC '300'`
],
expected_output: `BIGNUMERIC '0'`
},
{
inputs: [
`BIGNUMERIC '-5'`, `BIGNUMERIC '2'`
],
expected_output: `BIGNUMERIC '-20'`
},
{
inputs: [
`BIGNUMERIC '7'`, `BIGNUMERIC '0'`
],
expected_output: `BIGNUMERIC '7'`
},
{
inputs: [
`BIGNUMERIC '0'`, `BIGNUMERIC '10'`
],
expected_output: `BIGNUMERIC '0'`
},
{
inputs: [
`BIGNUMERIC '56713727820156410577229101238628035242'`,
`BIGNUMERIC '1'`
],
expected_output: `BIGNUMERIC '113427455640312821154458202477256070484'`
},
{
inputs: [
`BIGNUMERIC '56713727820156410577229101238628035242'`,
`BIGNUMERIC '2'`
],
expected_output: `BIGNUMERIC '-113427455640312821154458202477256070488'`
},
{
inputs: [
`BIGNUMERIC '56713727820156410577229101238628035242'`,
`BIGNUMERIC '3'`
],
expected_output: `BIGNUMERIC '113427455640312821154458202477256070480'`
},
{
inputs: [
`BIGNUMERIC '56713727820156410577229101238628035242'`,
`BIGNUMERIC '4'`
],
expected_output: `BIGNUMERIC '-113427455640312821154458202477256070496'`
},
{
inputs: [
`BIGNUMERIC '56713727820156410577229101238628035242'`,
`BIGNUMERIC '5'`
],
expected_output: `BIGNUMERIC '113427455640312821154458202477256070464'`
},
{
inputs: [
`BIGNUMERIC '56713727820156410577229101238628035242'`,
`BIGNUMERIC '6'`
],
expected_output: `BIGNUMERIC '-113427455640312821154458202477256070528'`
},
{
inputs: [
`BIGNUMERIC '56713727820156410577229101238628035242'`,
`BIGNUMERIC '7'`
],
expected_output: `BIGNUMERIC '113427455640312821154458202477256070400'`
}
]);
generate_udf_test("cw_signed_rightshift_128bit", [
{
inputs: [
`BIGNUMERIC '32'`,
`BIGNUMERIC '3'`
],
expected_output: `BIGNUMERIC '4'`
},
{
inputs: [
`BIGNUMERIC '7'`,
`BIGNUMERIC '1'`
],
expected_output: `BIGNUMERIC '3'`
},
{
inputs: [
`BIGNUMERIC '-7'`,
`BIGNUMERIC '1'`
],
expected_output: `BIGNUMERIC '-4'`
},
{
inputs: [
`BIGNUMERIC '-1'`,
`BIGNUMERIC '1'`
],
expected_output: `BIGNUMERIC '-1'`
},
{
inputs: [
`BIGNUMERIC '-1'`,
`BIGNUMERIC '100'`
],
expected_output: `BIGNUMERIC '-1'`
},
{
inputs: [
`BIGNUMERIC '-1'`,
`BIGNUMERIC '300'`
],
expected_output: `BIGNUMERIC '-1'`
},
{
inputs: [
`BIGNUMERIC '1'`,
`BIGNUMERIC '1'`
],
expected_output: `BIGNUMERIC '0'`
},
{
inputs: [
`BIGNUMERIC '7'`,
`BIGNUMERIC '0'`
],
expected_output: `BIGNUMERIC '7'`
},
{
inputs: [
`BIGNUMERIC '0'`,
`BIGNUMERIC '10'`
],
expected_output: `BIGNUMERIC '0'`
}
]);
generate_udf_test("cw_lower_case_ascii_only", [
{
inputs: [
Expand Down

0 comments on commit 1a335ed

Please sign in to comment.